class Listener(threading.Thread): server_str = "SERVER" #TODO find better place for this def __init__(self, socket, shared_key, server, connected_callback, app): threading.Thread.__init__(self) self.keep_alive = True self.socket = socket self.shared_key = shared_key self.server = server self.connected_callback = connected_callback self.app = app self.auth = None def run(self): self.socket.setblocking(0) self.server.authenticated = False while (self.keep_alive and self.server.authenticated == False): try: client_socket, addr = self.socket.accept() self.server.waiting = False self.auth = Authentication(self.shared_key, self.server, self.app, debug=True, is_server=True) self.server.bind(client_socket) self.app.debug_continue.disabled = False if (self.auth.mutualauth()): print "Client Authenticated!" self.server.authenticated = True self.server.auth = self.auth self.connected_callback(addr[0], addr[1]) self.server.clear_queues() else: print "Unable to authenticate" self.server.authenticated=False self.auth=False self.server.broken_conn_callback() except socket.error: pass if not self.keep_alive: self.socket.close() def broken_conn(self): self.authenticated = False self.auth=None if self.server is not None: self.server.auth = None def close(self): self.keep_alive = False self.server.authenticated = False self.auth=None if self.server is not None: self.server.auth = None
class VpnClient(object): def __init__(self, ip_addr, port, shared_key, broken_conn_callback, app): self.ip_addr = ip_addr self.port = port self.shared_key = shared_key self.broken_conn_callback = broken_conn_callback self.send_queue = Queue() self.receive_queue = Queue() self.waiting = True self.is_server=False self.authenticated=False self.sender = None self.receiver = None self.app = app def connect(self): try: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) except socket.error: return (-1, "Could not create socket") try: self.socket.settimeout(10) self.socket.connect((self.ip_addr, self.port)) self.waiting = False self.auth = Authentication(self.shared_key, self, self.app, debug=True, is_server=False) self.bind() # Added because we need the send/recv threads running for authentication if (self.auth.mutualauth()): print "Server Authenticated!" Logger.log("Connected to Server", self.is_server) self.authenticated = True self.sessionkey = self.auth.get_sessionkey() self.clear_queues() return (0, "Connected to (%s, %i)" % (self.ip_addr, self.port)) else: print "Could not authenticate" self.authenticated = False self.broken_conn_callback() return (-1, "Authentication failed") except socket.error: self.authenticated = False self.broken_conn_callback() return (-1, "Could not connect to (%s, %i)" % (self.ip_addr, self.port)) return (-1, "Could not connect to (%s, %i)" % (self.ip_addr, self.port)) def clear_queues(self): self.receive_queue.queue.clear() self.send_queue.queue.clear() def send(self, msg): if (self.authenticated): emsg = self.auth.encrypt_message(msg, self.auth.get_sessionkey()) self.send_queue.put(emsg) Logger.log("Put message on send queue: " + msg, self.is_server) else: self.send_queue.put(msg) Logger.log("Put message on send queue: " + msg, self.is_server) def bind(self): self.sender = Sender(self.socket, self.send_queue, self) self.receiver = Receiver(self.socket, self.receive_queue, self) self.sender.start() self.receiver.start() def close(self): Logger.log("Connection closing", self.is_server) self.send_queue.queue.clear() self.receive_queue.queue.clear() if self.sender: self.sender.close() if self.receiver: self.receiver.close() self.waiting = True self.authenticated = False self.auth = None def receive(self): if (not self.receive_queue.empty()): msg = self.receive_queue.get() Logger.log("Received decrypted msg: "+ msg, self.is_server) if (self.authenticated): msg, valid = self.auth.decrypt_message(msg, self.auth.get_sessionkey()) if valid is False: return None # ignore failed CBC authentication message Logger.log("Decrypted msg: "+ msg, self.is_server) return msg else: return None