#!/usr/bin/python3 import socket import threading import select def forward(source, destination): try: while True: ready, _, _ = select.select([source], [], [], 1) if ready: data = source.recv(4096) if not data: break destination.sendall(data) except (OSError, socket.error) as e: print(f"Connection error: {e}") finally: try: source.shutdown(socket.SHUT_RD) except OSError: pass try: destination.shutdown(socket.SHUT_WR) except OSError: pass def handle(client_socket, remote_host, remote_port): try: remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote_socket.connect((remote_host, remote_port)) thread1 = threading.Thread(target=forward, args=(client_socket, remote_socket)) thread2 = threading.Thread(target=forward, args=(remote_socket, client_socket)) thread1.start() thread2.start() thread1.join() thread2.join() except Exception as e: print(f"Error in handle: {e}") finally: client_socket.close() remote_socket.close() def create_forwarder(local_host, local_port, remote_host, remote_port): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind((local_host, local_port)) server_socket.listen(5) print(f"Forwarding {local_host}:{local_port} to {remote_host}:{remote_port}") while True: try: client_socket, address = server_socket.accept() print(f"Received connection from {address}") threading.Thread(target=handle, args=(client_socket, remote_host, remote_port)).start() except Exception as e: print(f"Error accepting connection: {e}") def main(): listen_ip = '0.0.0.0' imap_thread = threading.Thread(target=create_forwarder, args=(listen_ip, 1143, '127.0.0.1', 1142)) imap_thread.start() smtp_thread = threading.Thread(target=create_forwarder, args=(listen_ip, 1025, '127.0.0.1', 1024)) smtp_thread.start() imap_thread.join() smtp_thread.join() if __name__ == "__main__": main()