コード例 #1
0
ファイル: test_chewie.py プロジェクト: MichaelWasher/chewie
    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()
コード例 #2
0
ファイル: base_test.py プロジェクト: faucetsdn/chewie
    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()
コード例 #3
0
 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
コード例 #4
0
ファイル: __main__.py プロジェクト: cglewis/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()
コード例 #5
0
 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')
コード例 #6
0
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")
コード例 #7
0
ファイル: test_chewie.py プロジェクト: MichaelWasher/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(
            "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)
コード例 #8
0
 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
コード例 #9
0
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)
コード例 #10
0
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()
コード例 #11
0
        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()