#!/usr/bin/python ################################ # Configuration starts here cert_path = '/home/sven/ssl/cert' key_path = '/home/sven/ssl/private' # Configuration ends here ################################ import socket, ssl, select, math def remove_from_list(ls, val): return [value for value in ls if value is not val] def to_numeric(identifier): return ((ord(identifier[:1]) - 1) * 255) + (ord(identifier[1:]) - 1) def to_identifier(numeric): return chr(int(math.floor(numeric / 255) + 1)) + chr((numeric % 255) + 1) client_list = [] client_map = {} select_inputs = [] select_outputs = [] class Client: buff = "" channel_map = {} def __init__(self, connstream): self.stream = connstream self.channel_map[0] = Channel() def process_data(self, data): self.buff += data stack = self.buff.split("\0") self.buff = stack.pop() for chunk in stack: self.process_chunk(chunk) def process_chunk(self, chunk): if len(chunk) > 2: channel_identifier = chunk[:2] data = chunk[2:] channel_numeric = to_numeric(channel_identifier) if channel_numeric in self.channel_map: print "Received data on channel %d: %s" % (channel_numeric, data) else: print "Received data on NON-EXISTENT channel %d" % channel_numeric class Channel: numeric = 0 binary = False handler = None def __init__(self, handler, binary=False): self.handler = handler self.binary = binary def process_chunk(self, chunk): self.handler.process(chunk) class Handler: def process(chunk): pass bindsocket = socket.socket() bindsocket.bind(('0.0.0.0', 9151)) bindsocket.listen(5) select_inputs = [ bindsocket ] while select_inputs: readable, writable, error = select.select(select_inputs, select_outputs, select_inputs) for sock in readable: if sock is bindsocket: try: newsocket, fromaddr = bindsocket.accept() connstream = ssl.wrap_socket(newsocket, server_side=True, certfile=cert_path, keyfile=key_path, ssl_version=ssl.PROTOCOL_TLSv1) new_client = Client(connstream) select_inputs.append(connstream) client_map[connstream.fileno()] = new_client client_list.append(new_client) except ssl.SSLError: # todo: handle exception, SSL initialization failed? pass else: data = sock.recv(1024) if data: cur_client = client_map[sock.fileno()] cur_client.process_data(data) else: select_inputs = remove_from_list(select_inputs, sock) print "NOTICE: Client disconnected" print "Server socket closed, exiting..."