#!/usr/bin/env python3
import sys
import subprocess
from collections import Counter
import re

def get_geo(ip):
    if not ip or ip == "ismeretlen": return "ISMERETLEN"
    try:
        # Futtatjuk a whois-t és keressük az országkódot többféleképpen
        # cmd = f"whois {ip}"
        cmd = f"whois {ip} | grep -iE '^country:' | head -1"
        
        #result = subprocess.check_output(cmd, shell=True).decode("utf-8").strip()
        #if ":" in result:
        #    return result.split(":").strip().upper()
        
        # Különböző formátumok keresése (country: HU vagy Country: HU)
        output = subprocess.check_output(cmd, shell=True, timeout=5).decode("utf-8", errors='ignore')
        match = re.search(r'(?i)country:\s*([A-Z]{2})', output)
        if match:
            return match.group(1).upper()
            
    except Exception as e:
        # Ha nincs whois telepítve vagy hiba van
        pass
    return "ISMERETLEN"


def ban_ip(ip, country):
    if country != "HU" and country != "ISMERETLEN":
        try:
            # Ellenőrizzük, hogy tiltva van-e már
            check = f"sudo ufw status | grep -w '{ip}'"
            if subprocess.call(check, shell=True, stdout=subprocess.DEVNULL) == 0:
                return "MÁR TILTVA"
            
            # Új tiltás hozzáadása
            subprocess.check_output(["sudo", "ufw", "deny", "from", ip])
            return "ÚJ TILTÁS"
        except: return "HIBA"
    return "NEM TILTOTT (HU)"

def process_sasl_log(limit=None):
    log_path = '/var/log/mail.sasl.log'
    stats = Counter()
    
    try:
        with open(log_path, 'r', errors='ignore') as f:
            for line in f:
                # Csak a hibaágakat nézzük (SASL failure)
                if "authentication failed" in line.lower() or "sasl login" in line.lower():
                    # IP kinyerése: megkeressük az utolsó nyitó [ és záró ] karaktert
                    if "[" in line and "]" in line:
                        ip = line.split("[")[-1].split("]")[0]
                        # Tisztítás (ha lenne benne IPv6 prefix)
                        ip = ip.replace("::ffff:", "")
                        if ip:
                            stats[ip] += 1

        if not stats:
            print(f"Nincs adat itt: {log_path}")
            return

        # Ha van limit, csak az első X elemet vesszük a toplistából
        items_to_process = stats.most_common(limit) if limit else stats.most_common()

        print(f"\nFeldolgozás: {len(items_to_process)} egyedi IP cím...")
        print(f"{'IP Cím':<15} | {'GEO':<4} | {'Db':<4} | {'Művelet'}")
        print("-" * 65)

        for ip, count in items_to_process:
            country = get_geo(ip)
            action = ban_ip(ip, country)
            print(f"{ip:<15} | {country:<4} | {count:<4} | {action}")

    except Exception as e:
        print(f"Hiba: {e}")

if __name__ == "__main__":
    # Megnézzük, adtál-e meg számot paraméterként
    limit_val = None
    if len(sys.argv) > 1:
        try:
            limit_val = int(sys.argv[1])
        except ValueError:
            print("A paraméter csak szám lehet! (Pl: sudo python3 mail_sasl.py 10)")
            sys.exit(1)

    process_sasl_log(limit=limit_val)
    