def setUp(self): logger = logging.getLogger() logger.level = logging.DEBUG self.log_file = tempfile.NamedTemporaryFile() logger.addHandler(logging.FileHandler(self.log_file.name)) logger.addHandler(logging.StreamHandler(sys.stdout)) self.chewie = Chewie('lo', logger, auth_handler, failure_handler, logoff_handler, '127.0.0.1', 1812, 'SECRET', '44:44:44:44:44:44') self.fake_scheduler = FakeTimerScheduler() self.chewie.timer_scheduler = self.fake_scheduler global FROM_SUPPLICANT # pylint: disable=global-statement global TO_SUPPLICANT # pylint: disable=global-statement global FROM_RADIUS # pylint: disable=global-statement global TO_RADIUS # pylint: disable=global-statement global FROM_SUPPLICANT_ACTIVITY # pylint: disable=global-statement FROM_SUPPLICANT = Queue() FROM_SUPPLICANT_ACTIVITY = Queue() TO_SUPPLICANT = Queue() FROM_RADIUS = Queue() TO_RADIUS = Queue()
def start_chewie(self): """Start Chewie Server""" self.chewie_pid = os.fork() if self.chewie_pid == 0: file = open(os.path.join(self.current_log_dir + "chewie.log"), 'w+') logger = get_logger('CHEWIE', file) logger.info('Starting chewie.') chewie = Chewie(CHEWIE_SUPPLICANT.name, logger, auth_handler, failure_handler, logoff_handler, radius_server_ip=RADIUS_IP, radius_server_secret=RADIUS_SECRET) chewie.run()
def _create_dot1x_speaker(self, dot1x_intf, chewie_id, radius_ip, radius_port, radius_secret): chewie = Chewie( # pylint: disable=too-many-function-args dot1x_intf, self.logger, self.auth_handler, self.failure_handler, self.logoff_handler, radius_ip, radius_port, radius_secret, chewie_id) hub.spawn(chewie.run) return chewie
def main(): """Chewie main function, configure and start a chewie process""" parser = argparse.ArgumentParser( description='Run Chewie 802.1x Authenticator independently of ' 'Faucet SDN Controller') parser.add_argument( '-i', '--interface', dest='interface', help='Set the interface for Chewie to listen on - Default: eth0', default="eth0") parser.add_argument( '-ri', '--radius_ip', dest='radius_ip', help= 'Set the IP Address for the RADIUS Server that Chewie will forward requests to ' '- DEFAULT: 127.0.0.1', default='127.0.0.1') parser.add_argument( '-rs', '--radius_secret', dest='radius_secret', help= 'Set the Secret used for connecting to the RADIUS Server - Default: SECRET', default='SECRET') args = parser.parse_args() logger = get_logger("CHEWIE") logger.info('Starting Chewie...') chewie = Chewie(args.interface, logger, auth_handler, failure_handler, logoff_handler, radius_server_ip=args.radius_ip, radius_server_secret=args.radius_secret) chewie.run()
def setUp(self): self.chewie = Chewie('lo', FakeLogger('logger name'), None, None, None, '127.0.0.1', 1812, 'SECRET', '44:44:44:44:44:44')
class ChewieWithMocksTestCase(unittest.TestCase): """Main chewie.py test class""" def setUp(self): self.chewie = Chewie('lo', FakeLogger('logger name'), None, None, None, '127.0.0.1', 1812, 'SECRET', '44:44:44:44:44:44') @patch("chewie.chewie.Chewie.running", Mock(side_effect=[True, False])) @patch("chewie.chewie.MessageParser.ethernet_parse") @patch("chewie.chewie.FullEAPStateMachine") @patch("chewie.chewie.sleep", Mock()) def test_eap_packet_in_goes_to_new_state_machine(self, state_machine, ethernet_parse): #pylint: disable=invalid-name """test EAP packet creates a new state machine and is sent on""" self.chewie.eap_socket = Mock(**{'receive.return_value': 'message from socket'}) ethernet_parse.side_effect = return_if( ('message from socket',), (FakeEapMessage('fake src mac'), 'fake dst mac') ) self.chewie.receive_eap_messages() state_machine().event.assert_called_with( EventMessageReceived(FakeEapMessage('fake src mac'), 'fake dst mac') ) @patch("chewie.chewie.Chewie.running", Mock(side_effect=[True, False])) @patch("chewie.chewie.MessagePacker.ethernet_pack") @patch("chewie.chewie.sleep", Mock()) def test_eap_output_packet_gets_packed_and_sent(self, ethernet_pack): #pylint: disable=invalid-name """test EAP packet creates a new state machine and is sent on""" self.chewie.eap_socket = Mock() ethernet_pack.return_value = "packed ethernet" self.chewie.eap_output_messages.put_nowait( EapQueueMessage("output eap message", "src mac", "port mac")) self.chewie.send_eap_messages() self.chewie.eap_socket.send.assert_called_with("packed ethernet") @patch("chewie.chewie.Chewie.running", Mock(side_effect=[True, False])) @patch("chewie.chewie.MessageParser.radius_parse") @patch("chewie.chewie.Chewie.get_state_machine_from_radius_packet_id") @patch("chewie.chewie.sleep", Mock()) def test_radius_packet_in_goes_to_state_machine(self, state_machine, radius_parse): #pylint: disable=invalid-name """test radius packet goes to a state machine""" # note that the state machine has to exist already - if not then we blow up fake_radius = namedtuple('Radius', ('packet_id',))('fake packet id') self.chewie.radius_socket = Mock(**{'receive.return_value': 'message from socket'}) self.chewie.radius_lifecycle = Mock(**{'build_event_radius_message_received.side_effect': return_if( (fake_radius,), 'fake event' )}) radius_parse.side_effect = return_if( ('message from socket', 'SECRET', self.chewie.radius_lifecycle), fake_radius ) # not checking args as we can't mock the callback self.chewie.receive_radius_messages() state_machine().event.assert_called_with( 'fake event' ) @patch("chewie.chewie.Chewie.running", Mock(side_effect=[True, False])) @patch("chewie.chewie.sleep", Mock()) def test_radius_output_packet_gets_packed_and_sent(self): #pylint: disable=invalid-name """test EAP packet creates a new state machine and is sent on""" self.chewie.radius_socket = Mock() self.chewie.radius_output_messages.put_nowait('fake radius output bits') self.chewie.radius_lifecycle = Mock(**{'process_outbound.side_effect': return_if( ('fake radius output bits',), 'packed radius' )}) self.chewie.send_radius_messages() self.chewie.radius_socket.send.assert_called_with("packed radius")
class ChewieTestCase(unittest.TestCase): """Main chewie.py test class""" no_radius_replies = [] header = "0000000000010242ac17006f888e" sup_replies_success = [ bytes.fromhex(header + "01000009027400090175736572"), bytes.fromhex(header + "010000160275001604103abcadc86714b2d75d09dd7ff53edf6b") ] radius_replies_success = [ bytes.fromhex( "0b000050066300262c8ee8a33f43ad4e837e63c54f180175001604101a16a3baa37a0238f33384f6c" "11067425012a3bf83bea0eeb69645088527dc491eed18126aa866456add628e3a55a4737872cad6" ), bytes.fromhex( "02010032ec22830bb2fbde37f635e91690410b334" "f060375000450129a08d246ec3da2f371ec4ff16eed9310010675736572") ] radius_replies_success_mab = [ bytes.fromhex( "02000034187d6f5dc540a24efa738d2ba242ac5c50128f4b859e01a85b919b848421d0d369" "ad010e303234326163313730303666") ] radius_replies_failure_mab = [ bytes.fromhex( "030000340b0a0f4ec71ebd0573180eb45161c2b7010e303234326163313730303666" ) ] sup_replies_logoff = [ bytes.fromhex(header + "01000009027400090175736572"), bytes.fromhex(header + "010000160275001604103abcadc86714b2d75d09dd7ff53edf6b"), bytes.fromhex("0000000000010242ac17006f888e01020000") ] # packet id (0x84 is incorrect) sup_replies_failure_message_id = [ bytes.fromhex(header + "01000009028400090175736572"), bytes.fromhex(header + "01000009029400090175736572"), bytes.fromhex(header + "01000009026400090175736572"), bytes.fromhex(header + "01000009025400090175736572") ] # the first response has correct code, second is wrong and will be dropped by radius sup_replies_failure2_response_code = [ bytes.fromhex(header + "01000009027400090175736572"), bytes.fromhex(header + "01000009037400090175736572") ] def setUp(self): logger = logging.getLogger() logger.level = logging.DEBUG self.log_file = tempfile.NamedTemporaryFile() logger.addHandler(logging.FileHandler(self.log_file.name)) logger.addHandler(logging.StreamHandler(sys.stdout)) self.chewie = Chewie('lo', logger, auth_handler, failure_handler, logoff_handler, '127.0.0.1', 1812, 'SECRET', '44:44:44:44:44:44') self.fake_scheduler = FakeTimerScheduler() self.chewie.timer_scheduler = self.fake_scheduler global FROM_SUPPLICANT # pylint: disable=global-statement global TO_SUPPLICANT # pylint: disable=global-statement global FROM_RADIUS # pylint: disable=global-statement global TO_RADIUS # pylint: disable=global-statement global FROM_SUPPLICANT_ACTIVITY # pylint: disable=global-statement FROM_SUPPLICANT = Queue() FROM_SUPPLICANT_ACTIVITY = Queue() TO_SUPPLICANT = Queue() FROM_RADIUS = Queue() TO_RADIUS = Queue() def tearDown(self): self.chewie.shutdown() def test_get_state_machine(self): """Tests Chewie.get_state_machine()""" self.assertEqual(len(self.chewie.state_machines), 0) # creates the state_machine if it doesn't exist state_machine = self.chewie.get_state_machine( '12:34:56:78:9a:bc', # pylint: disable=invalid-name '00:00:00:00:00:01') self.assertEqual(len(self.chewie.state_machines), 1) self.assertIs( state_machine, self.chewie.get_state_machine('12:34:56:78:9a:bc', '00:00:00:00:00:01')) self.assertIsNot( state_machine, self.chewie.get_state_machine('12:34:56:78:9a:bc', '00:00:00:00:00:02')) self.assertIsNot( state_machine, self.chewie.get_state_machine('ab:cd:ef:12:34:56', '00:00:00:00:00:01')) # 2 ports self.assertEqual(len(self.chewie.state_machines), 2) # port 1 has 2 macs self.assertEqual(len(self.chewie.state_machines['00:00:00:00:00:01']), 2) # port 2 has 1 mac self.assertEqual(len(self.chewie.state_machines['00:00:00:00:00:02']), 1) # TODO Stop Test from touching internal get_state_machine_from_radius_packet def test_get_state_machine_by_packet_id(self): """Tests Chewie.get_state_machine_by_packet_id()""" self.chewie.radius_lifecycle.packet_id_to_mac[56] = { 'src_mac': '12:34:56:78:9a:bc', 'port_id': '00:00:00:00:00:01' } state_machine = self.chewie.get_state_machine( '12:34:56:78:9a:bc', # pylint: disable=invalid-name '00:00:00:00:00:01') self.assertIs(self.chewie._get_state_machine_from_radius_packet_id(56), state_machine) with self.assertRaises(KeyError): self.chewie._get_state_machine_from_radius_packet_id(20) @patch_things @setup_generators(sup_replies_success, radius_replies_success) def test_success_dot1x(self): """Test success api""" FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(1) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.SUCCESS2) @patch_things @setup_generators(sup_replies_success, radius_replies_success) def test_chewie_identity_response_dot1x(self): """test port status api and that identity request is sent after port up""" global TO_SUPPLICANT pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(1) self.chewie.port_down("00:00:00:00:00:01") self.chewie.port_up("00:00:00:00:00:01") while not self.fake_scheduler.jobs: eventlet.sleep(SHORT_SLEEP) self.fake_scheduler.run_jobs(num_jobs=1) # check preemptive sent directly after port up out_packet = TO_SUPPLICANT.get() self.assertEqual( out_packet, bytes.fromhex('0180C2000003000000000001888e010000050167000501')) # Send a response to the request FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e010000050167000501")) eventlet.sleep(2) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.AAA_IDLE) @patch_things def test_port_status_changes(self): """test port status api and that identity request is sent after port up""" global TO_SUPPLICANT pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(1) self.chewie.port_down("00:00:00:00:00:01") self.chewie.port_up("00:00:00:00:00:01") while not self.fake_scheduler.jobs: eventlet.sleep(SHORT_SLEEP) self.fake_scheduler.run_jobs(num_jobs=1) # check preemptive sent directly after port up out_packet = TO_SUPPLICANT.get() self.assertEqual( out_packet, bytes.fromhex('0180C2000003000000000001888e010000050167000501')) # check there is a new job in the queue for sending the next id request. # This will keep adding jobs forever. self.assertEqual(len(self.fake_scheduler.jobs), 1) self.assertEqual(self.fake_scheduler.jobs[0].function.__name__, ManagedPort.send_preemptive_identity_request.__name__) @patch_things def test_delete_state_on_port_down(self): """test port status api and that identity request is sent after port up""" self.test_chewie_identity_response_dot1x() self.chewie.port_down("00:00:00:00:00:01") self.assertIsNone(self.chewie.state_machines.get("00:00:00:00:00:01"), "Not Removing state machines on port_down") @patch_things @setup_generators(sup_replies_logoff, radius_replies_success) def test_logoff_dot1x(self): """Test logoff""" self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01')) FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(SHORT_SLEEP) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.LOGOFF2) @patch_things @setup_generators(sup_replies_failure_message_id, no_radius_replies) def test_failure_message_id_dot1x(self): """Test incorrect message id results in timeout_failure""" # TODO not convinced this is transitioning through the correct states. # (should be discarding all packets) # But end result is correct (both packets sent/received, and end state) # self.chewie.get_state_machine(MacAddress.from_string('02:42:ac:17:00:6f'), self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01')).DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) while not self.fake_scheduler.jobs: eventlet.sleep(SHORT_SLEEP) self.fake_scheduler.run_jobs() self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.TIMEOUT_FAILURE) @patch_things @setup_generators(sup_replies_failure2_response_code, no_radius_replies) def test_failure2_resp_code_dot1x(self): """Test incorrect eap.code results in timeout_failure2. RADIUS Server drops it. It is up to the supplicant to send another request - this supplicant doesnt""" self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01')).DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) while not self.fake_scheduler.jobs: eventlet.sleep(SHORT_SLEEP) self.fake_scheduler.run_jobs() self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.TIMEOUT_FAILURE2) @patch_things def test_mab_receive(self): """Test ETH Receive Ability of MAB Functionality""" mab_sm = self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01'), -2) mab_sm.DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT_ACTIVITY.put_nowait( bytes.fromhex( "0000000000010242ac17006f08004500001c0001000040117cce7f0000017f0000010044004300080155" )) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(SHORT_SLEEP) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, MacAuthenticationBypassStateMachine.AAA_IDLE) @patch_things @setup_generators(None, radius_replies_success_mab) def test_mab_success_auth(self): """Test Successful MAB Attempt""" mab_sm = self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01'), -2) mab_sm.DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT_ACTIVITY.put_nowait( bytes.fromhex( "0000000000010242ac17006f08004500001c0001000040117cce7f0000017f0000010044004300080155" )) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(SHORT_SLEEP) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, MacAuthenticationBypassStateMachine.AAA_SUCCESS) @patch_things @setup_generators(None, radius_replies_failure_mab) def test_mab_failure_auth(self): """Test unsuccessful MAB Attempt""" mab_sm = self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01'), -2) mab_sm.DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT_ACTIVITY.put_nowait( bytes.fromhex( "0000000000010242ac17006f08004500001c0001000040117cce7f0000017f0000010044004300080155" )) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(SHORT_SLEEP) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, MacAuthenticationBypassStateMachine.AAA_FAILURE) @patch_things @setup_generators(sup_replies_success, radius_replies_success) def test_smoke_test_clients(self): """Test success api""" FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(1) self.assertIsNotNone(self.chewie.clients) self.assertEqual(len(self.chewie.clients), 1)
def _create_dot1x_speaker(self): chewie = Chewie(self.dot1x_intf, self.CREDENTIALS, self.logger, self.auth_handler, MacAddress.from_string('00:00:00:00:00:01')) hub.spawn(chewie.run) return chewie
class ChewieTestCase(unittest.TestCase): """Main chewie.py test class""" no_radius_replies = [] header = "0000000000010242ac17006f888e" sup_replies_success = [ bytes.fromhex(header + "01000009027400090175736572"), bytes.fromhex(header + "010000160275001604103abcadc86714b2d75d09dd7ff53edf6b") ] radius_replies_success = [ bytes.fromhex( "0b000050066300262c8ee8a33f43ad4e837e63c54f180175001604101a16a3baa37a0238f33384f6c11067425012a3bf83bea0eeb69645088527dc491eed18126aa866456add628e3a55a4737872cad6" ), bytes.fromhex( "02010032ec22830bb2fbde37f635e91690410b334f060375000450129a08d246ec3da2f371ec4ff16eed9310010675736572" ) ] sup_replies_logoff = [ bytes.fromhex(header + "01000009027400090175736572"), bytes.fromhex(header + "010000160275001604103abcadc86714b2d75d09dd7ff53edf6b"), bytes.fromhex("0000000000010242ac17006f888e01020000") ] # packet id (0x84 is incorrect) sup_replies_failure_message_id = [ bytes.fromhex(header + "01000009028400090175736572"), bytes.fromhex(header + "01000009029400090175736572"), bytes.fromhex(header + "01000009026400090175736572"), bytes.fromhex(header + "01000009025400090175736572") ] # the first response has correct code, second is wrong and will be dropped by radius sup_replies_failure2_response_code = [ bytes.fromhex(header + "01000009027400090175736572"), bytes.fromhex(header + "01000009037400090175736572") ] def setUp(self): logger = logging.getLogger() logger.level = logging.DEBUG self.log_file = tempfile.NamedTemporaryFile() logger.addHandler(logging.FileHandler(self.log_file.name)) logger.addHandler(logging.StreamHandler(sys.stdout)) self.chewie = Chewie('lo', logger, auth_handler, failure_handler, logoff_handler, '127.0.0.1', 1812, 'SECRET', '44:44:44:44:44:44') self.fake_scheduler = FakeTimerScheduler() self.chewie.timer_scheduler = self.fake_scheduler global FROM_SUPPLICANT # pylint: disable=global-statement global TO_SUPPLICANT # pylint: disable=global-statement global FROM_RADIUS # pylint: disable=global-statement global TO_RADIUS # pylint: disable=global-statement FROM_SUPPLICANT = Queue() TO_SUPPLICANT = Queue() FROM_RADIUS = Queue() TO_RADIUS = Queue() def tearDown(self): self.chewie.shutdown() def test_get_state_machine(self): """Tests Chewie.get_state_machine()""" self.assertEqual(len(self.chewie.state_machines), 0) # creates the state_machine if it doesn't exist state_machine = self.chewie.get_state_machine( '12:34:56:78:9a:bc', # pylint: disable=invalid-name '00:00:00:00:00:01') self.assertEqual(len(self.chewie.state_machines), 1) self.assertIs( state_machine, self.chewie.get_state_machine('12:34:56:78:9a:bc', '00:00:00:00:00:01')) self.assertIsNot( state_machine, self.chewie.get_state_machine('12:34:56:78:9a:bc', '00:00:00:00:00:02')) self.assertIsNot( state_machine, self.chewie.get_state_machine('ab:cd:ef:12:34:56', '00:00:00:00:00:01')) # 2 ports self.assertEqual(len(self.chewie.state_machines), 2) # port 1 has 2 macs self.assertEqual(len(self.chewie.state_machines['00:00:00:00:00:01']), 2) # port 2 has 1 mac self.assertEqual(len(self.chewie.state_machines['00:00:00:00:00:02']), 1) def test_get_state_machine_by_packet_id(self): """Tests Chewie.get_state_machine_by_packet_id()""" self.chewie.radius_lifecycle.packet_id_to_mac[56] = { 'src_mac': '12:34:56:78:9a:bc', 'port_id': '00:00:00:00:00:01' } state_machine = self.chewie.get_state_machine( '12:34:56:78:9a:bc', # pylint: disable=invalid-name '00:00:00:00:00:01') self.assertIs(self.chewie.get_state_machine_from_radius_packet_id(56), state_machine) with self.assertRaises(KeyError): self.chewie.get_state_machine_from_radius_packet_id(20) @patch_things @setup_generators(sup_replies_success, radius_replies_success) def test_success_dot1x(self): """Test success api""" FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(1) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.SUCCESS2) def test_port_status_changes(self): """test port status api""" # TODO what can actually be checked here? # the state machine tests already check the statemachine # could check that the preemptive identity request packet is sent. (once implemented) # for now just check api works under python version. self.chewie.port_down("00:00:00:00:00:01") self.chewie.port_up("00:00:00:00:00:01") self.chewie.port_down("00:00:00:00:00:01") @patch_things @setup_generators(sup_replies_logoff, radius_replies_success) def test_logoff_dot1x(self): """Test logoff""" self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01')) FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) eventlet.sleep(0.1) self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.LOGOFF2) @patch_things @setup_generators(sup_replies_failure_message_id, no_radius_replies) def test_failure_message_id_dot1x(self): """Test incorrect message id results in timeout_failure""" # TODO not convinced this is transitioning through the correct states. # (should be discarding all packets) # But end result is correct (both packets sent/received, and end state)self.chewie.get_state_machine(MacAddress.from_string('02:42:ac:17:00:6f'), self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01')).DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) while not self.fake_scheduler.jobs: eventlet.sleep(0.1) self.fake_scheduler.run_jobs() self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.TIMEOUT_FAILURE) @patch_things @setup_generators(sup_replies_failure2_response_code, no_radius_replies) def test_failure2_resp_code_dot1x(self): """Test incorrect eap.code results in timeout_failure2. RADIUS Server drops it. It is up to the supplicant to send another request - this supplicant doesnt""" self.chewie.get_state_machine( MacAddress.from_string('02:42:ac:17:00:6f'), MacAddress.from_string('00:00:00:00:00:01')).DEFAULT_TIMEOUT = 0.5 FROM_SUPPLICANT.put_nowait( bytes.fromhex("0000000000010242ac17006f888e01010000")) pool = eventlet.GreenPool() pool.spawn(self.chewie.run) while not self.fake_scheduler.jobs: eventlet.sleep(0.1) self.fake_scheduler.run_jobs() self.assertEqual( self.chewie.get_state_machine('02:42:ac:17:00:6f', '00:00:00:00:00:01').state, FullEAPStateMachine.TIMEOUT_FAILURE2)
import socket import struct from select import select from fcntl import ioctl from netils import build_byte_string from chewie.chewie import Chewie class Logger: def info(self, message): print("INFO: %s" % message) def warning(self, message): print("WARNING: %s" % message) def auth_handler(address, group_address): print("Authed address %s on port %s" % (str(address), str(group_address))) credentials = {"*****@*****.**": "microphone"} chewie = Chewie("eth0", credentials, Logger(), auth_handler) chewie.run()
ch.setFormatter(formatter) logger.addHandler(ch) return logger def auth_handler(address, group_address): print("Authed address %s on port %s" % (str(address), str(group_address))) def failure_handler(address, group_address): print("failure of address %s on port %s" % (str(address), str(group_address))) def logoff_handler(address, group_address): print("logoff of address %s on port %s" % (str(address), str(group_address))) logger = get_logger("CHEWIE") logger.info('starting chewieeeee.') chewie = Chewie("eth1", logger, auth_handler, failure_handler, logoff_handler, radius_server_ip="172.24.0.113", radius_server_secret="SECRET") chewie.run()