#!/usr/bin/env python3 import socket import time import threading def connect_client(nickname): """Connect a client and return the socket""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', 6667)) # Send initial IRC commands sock.send(f"NICK {nickname}\r\n".encode()) sock.send(f"USER {nickname} 0 * :Test User\r\n".encode()) # Wait for welcome messages time.sleep(0.5) return sock except Exception as e: print(f"Error connecting {nickname}: {e}") return None def read_responses(sock, name, duration=2): """Read responses from server for a duration""" try: sock.settimeout(0.1) responses = [] start_time = time.time() while time.time() - start_time < duration: try: data = sock.recv(4096).decode() if data: responses.append(data.strip()) print(f"[{name}] {data.strip()}") except socket.timeout: continue except: break return responses except Exception as e: print(f"Error reading from {name}: {e}") return [] def test_gline_enforcement(): print("\n=== TESTING GLINE ENFORCEMENT ===") # Connect admin client admin = connect_client("AdminUser") if not admin: print("Failed to connect admin") return read_responses(admin, "Admin", 1) # Give admin operator privileges (OPER) admin.send("OPER admin adminpass\r\n".encode()) read_responses(admin, "Admin", 1) # Connect a test user first print("\n1. Connecting test user before GLINE...") test_user = connect_client("TestUser") if test_user: read_responses(test_user, "TestUser", 1) print(" ✓ TestUser connected successfully") # Issue GLINE command print("\n2. Issuing GLINE for TestUser...") admin.send("GLINE TestUser 1h Testing GLINE enforcement\r\n".encode()) read_responses(admin, "Admin", 1) # Try to send a message as the existing user print("\n3. TestUser trying to send message after GLINE...") if test_user: test_user.send("PRIVMSG #test :This should work, GLINE only affects new connections\r\n".encode()) read_responses(test_user, "TestUser", 1) # Try to connect a new user with same nick pattern print("\n4. Trying to connect new TestUser after GLINE...") new_test_user = connect_client("TestUser2") if new_test_user: read_responses(new_test_user, "TestUser2", 2) new_test_user.close() # Cleanup if test_user: test_user.close() admin.close() def test_shun_enforcement(): print("\n\n=== TESTING SHUN ENFORCEMENT ===") # Connect admin client admin = connect_client("AdminUser") if not admin: print("Failed to connect admin") return read_responses(admin, "Admin", 1) # Give admin operator privileges admin.send("OPER admin adminpass\r\n".encode()) read_responses(admin, "Admin", 1) # Connect test user print("\n1. Connecting test user...") test_user = connect_client("ShunUser") if not test_user: print("Failed to connect test user") admin.close() return read_responses(test_user, "ShunUser", 1) # Test user sends a message before SHUN print("\n2. ShunUser sending message before SHUN...") test_user.send("PRIVMSG #test :This message should work\r\n".encode()) read_responses(test_user, "ShunUser", 1) # Issue SHUN command print("\n3. Issuing SHUN for ShunUser...") admin.send("SHUN ShunUser 1h Testing SHUN enforcement\r\n".encode()) read_responses(admin, "Admin", 1) # Test user tries to send message after SHUN print("\n4. ShunUser trying to send message after SHUN (should be ignored)...") test_user.send("PRIVMSG #test :This message should be silently ignored\r\n".encode()) read_responses(test_user, "ShunUser", 2) # Test user tries other commands print("\n5. ShunUser trying other commands after SHUN...") test_user.send("JOIN #testchan\r\n".encode()) read_responses(test_user, "ShunUser", 1) test_user.send("NOTICE #test :This notice should also be ignored\r\n".encode()) read_responses(test_user, "ShunUser", 1) # Cleanup test_user.close() admin.close() if __name__ == "__main__": print("Testing TechIRCd Ban Enforcement") print("Make sure TechIRCd server is running on localhost:6667") time.sleep(1) test_gline_enforcement() test_shun_enforcement() print("\n=== TEST COMPLETE ===")