Пример #1
0
class CryptikChaosTestApp(App):

    "Test sever application."

    def build(self):

        self.test_win = ConsoleScrollView()

        # Display initial text
        self.test_win.display_text(
            """
=========================
CryptikChaos Test_ Server
=========================
:PeerID: {}\n
:PeerIP: {}\n
:Date: {}\n
------------\n
""".format(
                constants.LOCAL_TEST_PEER_ID, constants.LOCAL_TEST_HOST, get_time()
            )
        )

        return self.test_win

    def on_start(self):
        """Event handler for the on_start event, which is fired after
        initialization (after build() has been called), and before the
        application is being run.
        """

        Logger.info("TESTSERVER: Cryptikchaos Test server started.")

        # Initiate Twisted Server
        self.comm_service = CommService(
            peerid=constants.LOCAL_TEST_PEER_ID,
            host=constants.LOCAL_TEST_HOST,
            port=constants.LOCAL_TEST_PORT,
            clientinit=False,
            printer=self.print_message,
        )

        self.device_service = DeviceService()

        # Register device service with comm service
        self.comm_service.register_device_service(self.device_service)

    def on_stop(self):
        """Event handler for the on_stop event, which is fired when the
        application has finished running (e.g. the window is about to be
        closed).
        """

        Logger.info("TESTSERVER: Closing services.")

        # Close services
        try:
            self.comm_service.__del__()
        except AttributeError:
            pass

        Logger.info("TESTSERVER: Successfully closed services.")
        Logger.info("TESTSERVER: Closing Cryptikchaos Test Server.")

    def print_message(self, msg, peerid=None, intermediate=False):
        "Print a message in the output window."

        # Indicates multiline output required
        if intermediate:
            text = "{}{}".format(constants.GUI_LABEL_LEFT_PADDING, msg)
        else:
            # One line print
            if not peerid:
                peerid = self.comm_service.peerid

            # If local pid, substitute with peer name
            if peerid == self.comm_service.peerid:
                peerid = constants.PEER_NAME

            # Get peer message color
            rcc = self.comm_service.swarm_manager.get_peerid_color(peerid)

            # Single line output with peer id
            text = "{}{}[color={}]{}[/color] : {}".format(
                constants.GUI_LABEL_LEFT_PADDING, constants.GUI_LABEL_PROMPT_SYM, rcc, str(peerid), msg
            )

        text = "\n{}".format(text)

        # Send text to console
        self.display_text("\n" + text)

        # Print in log
        if constants.ENABLE_CMD_LOG:
            # Get peer id for log
            if not peerid:
                logger_peerid = constants.PEER_NAME
            else:
                logger_peerid = peerid

            Logger.debug("TESTSERVER: [{}] => {}".format(logger_peerid, msg))

    def display_text(self, text):

        # Append line to label
        self.test_win.text += "\n[color={}]{}[/color]".format(constants.GUI_FONT_COLOR, text)
Пример #2
0
class OuroborosTestCase(unittest.TestCase):
    """
    Cyclical testing with the client talking to server 
    through `proto_helpers.StringTransport`."""
    
    client_peer_id = "V_CLIENT"
    server_peer_id = "V_SERVER"
    peer_ip = "192.168.1.1"
    peer_port = 1597
    
    def setUp(self):
        
        # Start device service
        self.device_service = DeviceService()
        
        # Communications service, contains both client & server
        self.comm_service = CommService(
            peerid=self.server_peer_id,
            host=self.peer_ip,
            port=self.peer_port,
            printer=test_logger
        )
        
        # Register device service
        self.comm_service.register_device_service(self.device_service)
        
        # Start server protocol factory
        self.factory = CommCoreServerFactory(self.comm_service)
        self.proto = self.factory.buildProtocol((self.peer_ip, self.peer_port))
        self.tr = proto_helpers.StringTransport()
        self.proto.makeConnection(self.tr)
        
        # Test streams
        self.auth_stream = None
        self.aack_stream = None
        self.dcon_stream = None
        self.bulk_stream = None
        self.mack_stream = None
        
        # Get auth request ID
        self.request_transaction_id = None
        
    def tearDown(self):
           
        # Stop listener
        self.comm_service._stop_listener() 
        
    def _get_auth_transaction(self):
        
        # Get auth request ID
        self.request_transaction_id = generate_auth_token()
        
        #REQUEST
        # Pack auth content
        auth_content = self.comm_service._pack_auth_content(
                            self.client_peer_id, self.request_transaction_id)

        # Pack authentication data into stream
        auth_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_AUTH_TYPE,
            stream_content=auth_content,
            stream_flag=STREAM_TYPES.UNAUTH,
            stream_host=self.peer_ip
        )
        
        #ACKNOWLEDGE
        # Get ack content 
        aack_content = self.comm_service._pack_auth_content(
                          self.server_peer_id, self.request_transaction_id)
        
        # Send current peer info
        aack_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_AACK_TYPE,
            stream_content=aack_content,
            stream_flag=STREAM_TYPES.UNAUTH,
            stream_host=self.peer_ip
        )
        
        log_stream(
            constants.PROTO_AACK_TYPE, 
            aack_content, 
            self.comm_service.peerkey,
            len(aack_stream)
        )
        
        #DISCONNECT  
        dcon_content = self.comm_service._pack_auth_content(
                                self.client_peer_id, self.request_transaction_id)
        
        dcon_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_DCON_TYPE,
            stream_content=dcon_content,
            stream_flag=STREAM_TYPES.UNAUTH,
            stream_host=self.peer_ip
        )
        
        return (auth_stream, aack_stream, dcon_stream)
        
    def _get_bulk_transaction(self):
        
        ## stream packing for single transaction
        
        #BULK MESSAGE
        shared_key = self.comm_service.comsec_core.generate_shared_key(self.comm_service.peerkey)
        # Pack data into stream
        bulk_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_BULK_TYPE,
            stream_content=random_stream(),
            stream_host=self.peer_ip,
            shared_key=shared_key
        )
        
        #BULK MESSAGE ACK
        mack_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_MACK_TYPE,
            stream_content='',
            stream_host=self.peer_ip,
            shared_key=shared_key
        )
        
        return (bulk_stream, mack_stream)
    
    def _get_fake_transaction(self):
        
        #INVALID BULK MESSAGE
        shared_key = self.comm_service.comsec_core.generate_shared_key(self.comm_service.peerkey)
        # Pack data into stream
        fake_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_BULK_TYPE, 
            stream_content=random_stream(), 
            stream_host=self.peer_ip, 
            shared_key=md5hash("INVALID KEY!!!")
        )
        
        #INVALID MESSAGE ACK
        fmack_stream = self.comm_service.stream_manager.pack_stream(
            stream_type=constants.PROTO_MACK_TYPE,
            stream_content='',
            stream_host=self.peer_ip,
            shared_key=shared_key
        )      
        
        return (fake_stream, fmack_stream)
    
    def unpack_stream(self, stream, shared_key=None):
        
        (header, content, pkey) = self.comm_service.stream_manager.unpack_stream(
           stream=stream, 
           shared_key=shared_key
        )
        
        log_stream(header, content, pkey, len(stream), True)  
        
        return (header, content, pkey)
        
    def _start_transaction(self, transactions=1):
        
        # Get auth transaction
        test_logger("AUTHENTICATION TEST.")
        test_logger("====================")
        (auth_stream, aack_stream, dcon_stream) = self._get_auth_transaction()
        
        test_logger("CLIENT ----[AUTH]----> SERVER")
        # send simulated auth request from virtual client
        self.proto.dataReceived('{}\r\n'.format(auth_stream))
        
        test_logger("CLIENT <----[AACK]---- SERVER")
        # Get auth response from sim
        aack_response = self.tr.value().rstrip('\r\n')
                
        # Check if ack is expected
        test_logger("Match received AACK with expected AACK.")        
        self.assertEqual(len(aack_response), len(aack_stream), "Responses of different length")
        self.assertEqual(aack_response, aack_stream)
        test_logger("RECEIVED AACK == EXPECTED AACK.")        

        # Unpack sim ack from auth req
        test_logger("Extrack SERVER public key from AACK.")        
        (_, _, pkey) = self.unpack_stream(stream=aack_response)
        
        # Get shared key from recieved public key
        test_logger("Generate Shared Secret from SERVER's Public Key.")        
        shared_key = self.comm_service.comsec_core.generate_shared_key(pkey)
        
        # Add the peer in to the swarm
        test_logger("Add SERVER into CLIENT Swarm.")        
        self.comm_service.swarm_manager.add_peer(
            self.server_peer_id, 
            shared_key, 
            self.peer_ip, 
            self.peer_port
        )
        
        # remove connection
        test_logger("Update SERVER connection status.")        
        self.comm_service._update_peer_connection_status(
            self.peer_ip,
            self.peer_port,
            False,
            None
        )
        
        # send sim disconnect
        test_logger("CLIENT ----[DCON]----> SERVER")
        test_logger("For disconnection of AUTH connection.")
        self.proto.dataReceived('{}\r\n'.format(dcon_stream))
                
        # check if request id is still valid
        test_logger("Checking if Request ID for AUTH Transaction is invalidated.")
        self.assertFalse(
            self.request_transaction_id in self.comm_service.valid_auth_req_tokens,
            msg='Transaction ID was not deleted from memory at the server side on DCON.')

        # DCON success, Del transaction id
        test_logger("Reset Client Side Request token.")
        self.request_transaction_id = None
        
        # Reset connection 
        test_logger("Reset connection after AUTH.")
        self.tr.loseConnection()
        self.tr = proto_helpers.StringTransport()
        self.proto.makeConnection(self.tr)
        
        # Run transactions
        for i in range(1, transactions+1):
            
            test_logger("Bulk Message Test Iteration : {}".format(i))
            test_logger("BULK STREAM TEST FOR VALID STREAM.")
            test_logger("==================================")
            (bulk_stream, mack_stream) = self._get_bulk_transaction()

            # send simulated bulk msg from virtual client
            test_logger("CLIENT ----[BULK]----> SERVER")
            self.proto.dataReceived('{}\r\n'.format(bulk_stream))
            
            # Get msg ack response from sim
            test_logger("CLIENT <----[MACK]---- SERVER")
            mack_response = self.tr.value().rstrip('\r\n')
            
            # Unpack sim mack from msg txn
            test_logger("Unpack MACK response from SERVER with shared key.")
            self.unpack_stream(stream=mack_response, shared_key=shared_key)
            
            # Check if mack is expected
            test_logger("Match received MACK with expected MACK.")
            self.assertEqual(len(mack_response), len(mack_stream), "Responses of different length")
            self.assertEqual(mack_response, mack_stream)
            test_logger("RECEIVED MACK == EXPECTED MACK.")        
            
            # Reset connection to clear test transport buffer
            test_logger("Reset connection after BULK.")
            self.tr.loseConnection()
            self.tr = proto_helpers.StringTransport()
            self.proto.makeConnection(self.tr)
            
            #Check for invalid bulk msg stream
            test_logger("BULK STREAM TEST FOR INVALID STREAM.")
            test_logger("====================================")
            (fake_stream, fmack_stream) = self._get_fake_transaction()
            
            # Send fake stream to server
            test_logger("CLIENT ----[INVALID BULK STREAM]----> SERVER")
            self.proto.dataReceived('{}\r\n'.format(fake_stream))
            
            test_logger("CLIENT <----[INVALID MACK RESPONSE]---- SERVER")
            fmack_response = self.tr.value().rstrip('\r\n')

            test_logger("Match received invalid MACK with expected MACK.")
            self.assertNotEqual(fmack_response, fmack_stream, "Fake request got a valid mack.")
            test_logger("RECEIVED MACK != EXPECTED MACK.")        
            test_logger("Invalid BULK Stream was rejected.")
    
    def test_transaction(self):
        
        # Test the auth transaction
        self._start_transaction(1)