Пример #1
0
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
Пример #2
0
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