class SignalServer(Thread): sock = None logger = None sender_id = 0 buf_size = 2000 # TODO This is not nice connection_list = [] # List of established connections exit_flag = False received_packet = None fsystem = None polltime = 0.5 updatetime = 5.0 # update time. send update messages to all peers. # TODO Throw error in case bind fails (Might do it already...) def __init__(self, fsystem, dataserver, ip = "0.0.0.0", port = 5500, sender_id = random.randint(0, 65535), q = 0.0, p = 0.0, passwd = ''): Thread.__init__(self) # TODO Think trough how the program should exit #signal.signal(signal.SIGINT, self.signal_handler) self.fsystem = fsystem self.dataserver = dataserver self.sender_id = sender_id self.logger = logging.getLogger("Signal server") self.logger.info("Initializing signal server id: %d at %s" % (self.sender_id, str(time.time()))) #self.logger.setLevel(logging.WARNING) self.sock = LossySocket(socket.AF_INET, socket.SOCK_DGRAM, q = q, p = p) self.sock.bind((ip, port)) self.sock.settimeout(self.polltime) # So we can exit and wont block forever in recvfrom self.received_packet = InPacket() self.connection_list_lock = thread.allocate_lock() self.passwd = passwd if len(passwd) != 0: self.use_enc = True self.security = Security() self.privateKey,self.publicKey = self.security.generate_keys(1024) self.publicKey_plaintext = self.security.export_key(self.publicKey) self.key_hash = self.security.calculate_key_hash(self.publicKey_plaintext, passwd) else: self.use_enc = False self.security = None self.privateKey,self.publicKey = None, None self.publicKey_plaintext = '' self.key_hash = '' def run(self): self.logger.info("Server started at %s" % (str(time.time()))) while self.exit_flag == False: try: data, addr = self.sock.recvfrom(self.buf_size) except socket.error: errno, errstr = sys.exc_info()[:2] if errno == socket.timeout: for i, connection in enumerate(self.connection_list): # Check if the connection should send an update message # Also remove broken connections if not connection.check_send_update(): connection.stop() del self.connection_list[i] #self.logger.info("socket timeout") continue else: self.logger.alarm("error with socket") if self.use_enc: packet_ok = self.received_packet.packetize_header(data) else: packet_ok = self.received_packet.packetize_raw(data) self.received_packet.receive_time = time.time() found = False self.connection_list_lock.acquire() for connection in self.connection_list: if self.received_packet.txremoteID == connection.local_session_id: self.logger.info("packet belongs to existing connection. processing...") found = True if self.use_enc and connection.state == SignalConnection.State.CONNECTED and 'CRY' in self.received_packet.get_flags(): data = self.security.decrypt_AES_bin(connection.aes_key, data, 8) #PacketManager.hex_data(data) packet_ok = self.received_packet.packetize_raw(data) self.logger.info("received packet:\n%s" % str(self.received_packet)) if not packet_ok: self.logger.warning("Decrypted packet is not valid.") break connection.handle(self.received_packet) break if not found: if self.use_enc: packet_ok = self.received_packet.packetize_raw(data) self.logger.info("received packet:\n%s" % str(self.received_packet)) if packet_ok and self.received_packet.otype == OPERATION['HELLO'] and \ self.received_packet.ocode == CODE['REQUEST']: connection = SignalConnection(server = self, remote_ip = addr[0], remote_port = addr[1], local_session_id = self.get_new_session_id(random.randint(0, 65535)), remote_session_id = self.received_packet.txlocalID, version = self.received_packet.version, send_ack_no = self.received_packet.sequence, seq_no = random.randint(0, 65535), updatetime = self.updatetime) #def __init__(self, server, remote_ip, remote_port, local_session_id, remote_session_id = 0, # version = 1, send_ack_no = random.randint(0, 65534), seq_no = random.randint(0, 65535)): connection.hello_recv(self.received_packet) self.connection_list.append(connection) self.logger.info("hello packet received, new connection established\ (local id %d, remote id %d) and HELLO sent" % (connection.local_session_id, connection.remote_session_id)) elif not packet_ok: self.logger.warning("Packet is not valid.") elif not found and packet_ok: self.logger.info("Packet does not belong to any connection and not a valid HELLO. Discarding.") self.logger.info("done with packet.\n") for i, connection in enumerate(self.connection_list): # Check if the connection should send an update message # Also remove broken connections if not connection.check_send_update(): connection.stop() del self.connection_list[i] self.connection_list_lock.release() # destination list should contain (ip, port) tuples def init_connections(self, destination_list): # todo create hello packet #self.packetmanager.create_packet(2, 15, 43962, 52428, 56797, 3150765550, 286331153, 85, 102, None, None) for destination in destination_list: self.logger.info('connecting to ' + destination[0] + ', ' + destination [1]) #self.sock.sendto("daddaa", (destination[0], int(destination[1])) ) connection = SignalConnection(self, destination[0], int(destination[1]), self.get_new_session_id(random.randint(0, 65535))) connection.connect() self.connection_list.append(connection) # Returns an unigue local session_id. Takes a random number from 0 to 65535 as a parameter. def get_new_session_id(self, rand_no): for connection in self.connection_list: if rand_no == connection.local_session_id: return get_new_session_id(random.randint(0, 65535)) return rand_no def stop(self): for connection in self.connection_list: connection.stop() self.logger.info("server should stop") self.exit_flag = True
class SyncCFT: def __init__(self): signal.signal(signal.SIGINT, self.signal_handler) self.logger = logging.getLogger("SyncCFT 1.0") self.logger.info("Starting SyncCFT 1.0 at %s" % (str(time.time()))) self.exit_flag = 0 config = Configuration(sys.argv) conf_values = config.load_configuration() self.local_password = config.load_password() if not conf_values: self.logger.error("An error occurred while loading the configuration!") return (self.port, self.folder, self.p_prob, self.q_prob, self.peers) = conf_values #Logging of configuration self.logger.info("Listening on UDP port %s" % (str(self.port))) self.logger.info("Synchronizing folder %s" % (str(self.folder))) self.logger.info("'p' parameter: %s" % (str(self.p_prob))) self.logger.info("'q' parameter: %s" % (str(self.q_prob))) i=1 for item in self.peers: self.logger.info("Peer %d: %s:%s" % (i,str(item[0]),str(item[1]))) i+=1 def start_SyncCFT(self): self.packetmanager = PacketManager() self.security = Security() self.fsystem = FileSystem(self.folder, '.private') (self.privateKey,self.publicKey) = self.security.generate_keys(1024) self.publicKey_plaintext = self.security.export_key(self.publicKey) self.fsystem.start_thread(timeout=1) try: while not self.exit_flag: time.sleep(5) except Exception: pass print self.fsystem.current_dic self.fsystem.terminate_thread() ''' print "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" print "Here comes our new coding!!\n" mylist = ['FIL?f1?5?1330560662?5310dab750cabf7e2d1f307554874f9a','RMF?f3?11?1339999999?a73c45107081c08dd4560206b8ef8205'] print "The difference of the manifests are..." print self.fsystem.get_diff_manifest_remote(mylist) print "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" print self.fsystem.current_dic self.fsystem.terminate_thread() pwdA= 'passwordA' (privateKA,publicKA) = self.security.generate_keys(1024) exp_publicKA = self.security.export_key(publicKA) hash_A = self.security.calculate_key_hash(exp_publicKA, pwdA) #(privateKB,publicKB) = self.security.generate_keys(1024) print "Creating the packet..." self.packetmanager.create_packet(2, ['SEC'], 0xabcd,0xfeea, 0xfee0, 3150765550, 286331153, "HELLO", "REQUEST", None, None) self.packetmanager.append_entry_to_TLVlist('SECURITY', exp_publicKA+'?'+hash_A) packet = self.packetmanager.build_packet() #self.packetmanager.append_list_to_TLVlist('DATA', ['oneeeeee','twoooooooo','threeeeeeee', 'fourrrrrrr']) #self.packetmanager.append_entry_to_TLVlist('DATA', 'data_test') #self.packetmanager.append_entry_to_TLVlist('CONTROL', 'control_test') #self.packetmanager.append_entry_to_TLVlist('SECURITY', 'security_test') #packet = self.packetmanager.build_packet() print "This is the packet dump" self.packetmanager.hex_packet() #raw_data = '\x29\x02\xAB\xCD\xFE\xEA\xFE\xE0\xBB\xCC\xDD\xEE\x11\x11\x11\x11\x01\x01\x4C\xA9\x02\x30\x30\x30\x38\x6F\x6E\x65\x65\x65\x65\x65\x65\x02\x30\x30\x31\x30\x74\x77\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\xFF\x30\x30\x31\x31\x74\x68\x72\x65\x65\x65\x65\x65\x65\x65\x65' #raw_packet = self.packetmanager.create_packet(rawdata = raw_data) print "\n\n\n" print self.packetmanager.get_version() print self.packetmanager.get_flags() print self.packetmanager.get_senderID() print self.packetmanager.get_txlocalID() print self.packetmanager.get_txremoteID() print self.packetmanager.get_sequence() print self.packetmanager.get_ack() print self.packetmanager.get_otype() print self.packetmanager.get_ocode() print "This is the TLV_List" print self.packetmanager.get_TLVlist() print "This is the get_TLVlist_typevalue" print self.packetmanager.get_TLVlist_typevalue() print "self.packetmanager.get_TLVlist('SECURITY')" print self.packetmanager.get_TLVlist('SECURITY') security_payload = self.packetmanager.get_TLVlist('SECURITY') recovered_plaintextkey = security_payload[0].split('?')[0] recovered_hash = security_payload[0].split('?')[1] recovered_key = self.security.import_key(recovered_plaintextkey) print recovered_key if self.security.calculate_key_hash(recovered_plaintextkey, pwdA) == recovered_hash: print "Access granted!" ''' ''' original_packet = packet[:] print "\n\n\n*********************************************************\n\n\n" print "The following reprensents a communication between 2 peers" password_A= 'ProtocolDesign' password_B= 'ProtocolDesig' (privateKA,publicKA) = self.security.generate_keys(1024) (privateKB,publicKB) = self.security.generate_keys(1024) print "Peer-A wants to send" self.print_hex(original_packet) print "Peer-A encrypts with Public_Key_B" encrypted_packet = self.security.encrypt(publicKB, original_packet) self.print_hex(encrypted_packet) print "Peer-B decrypts with Private_Key_B" decrypted_packet = self.security.decrypt(privateKB, encrypted_packet) self.print_hex(decrypted_packet) if original_packet == decrypted_packet: print "Both packets are the same after the crypto!!!" #This is the hash sent by A exp_publicKA = self.security.export_key(publicKA) hash_A = self.security.calculate_key_hash(exp_publicKA, password_A) #B calculates the following hash_B = self.security.calculate_key_hash(exp_publicKA, password_A) if hash_A == hash_B: print "Access granted!" else: print "Wrong password!" ''' return def signal_handler(self, signal, frame): self.logger.warning("You pressed Ctrl+C") print "\nYou pressed Ctrl+C!\n" self.exit_flag = 1 #sys.exit(1) def print_hex(self, text): l = len(text) i = 0 while i < l: print "%04x " % i, for j in range(16): if i+j < l: print "%02X" % ord(text[i+j]), else: print " ", if j%16 == 7: print "", print " ", ascii = text[i:i+16] r="" for i2 in ascii: j2 = ord(i2) if (j2 < 32) or (j2 >= 127): r=r+"." else: r=r+i2 print r i += 16