Example #1
0
    def _set_port_sequestered(self, mac):
        """Set port to sequester vlan"""
        operational_behavior = (self._static_device_behaviors.get(mac)
                                or self._dynamic_device_behaviors.get(mac))

        if self._device_state_reporter:
            assert operational_behavior, f'No operational device behavior available for {mac}'
            operational_vlan = self._get_vlan_from_segment(
                operational_behavior.segment)
            assert operational_vlan, f'No operational vlan available for device {mac}'
            self._device_state_reporter.process_port_assign(
                mac, operational_vlan)

        device_behavior = DeviceBehavior(
            segment=self._sequester_segment,
            assigned_segment=operational_behavior.segment)
        self._process_device_behavior(mac, device_behavior, static=False)
        self._update_device_state_varz(mac, DVAState.sequestered)
        if self._sequester_timeout:

            def handler():
                self._handle_sequestering_timeout(mac.lower())

            timeout = datetime.now() + timedelta(
                seconds=self._sequester_timeout)
            self._logger.info('Setting device %s sequester timeout at %s', mac,
                              timeout)
            self._sequester_timer[mac.lower()] = threading.Timer(
                self._sequester_timeout, handler)
            self._sequester_timer[mac.lower()].start()
Example #2
0
    def process_device_behavior(self, eth_src, behavior, static=False):
        """Process device behavior"""
        eth_src = eth_src.lower()
        device_type = STATIC_DEVICE if static else DYNAMIC_DEVICE

        with self._lock:
            if behavior.segment:
                behavior_map = self._device_behaviors.setdefault(eth_src, {})
                behavior_map[DEVICE_TYPE] = device_type
                device_behavior = behavior_map.setdefault(
                    DEVICE_BEHAVIOR, DeviceBehavior())
                device_behavior.CopyFrom(behavior)
                self._logger.info(
                    'Received %s behavior: %s, %s (assigned: %s), %s',
                    device_type, eth_src, device_behavior.segment,
                    device_behavior.assigned_segment, device_behavior.role)
            else:
                removed = self._device_behaviors.pop(eth_src, None)
                if removed:
                    removed_behavior = removed[DEVICE_BEHAVIOR]
                    self._logger.info('Removed %s behavior: %s, %s, %s',
                                      device_type, eth_src,
                                      removed_behavior.segment,
                                      removed_behavior.role)

            self.flush_behavioral_config()
Example #3
0
 def _set_port_sequestered(self, mac):
     """Set port to sequester vlan"""
     if not self._process_device_behavior:
         return
     device_behavior = DeviceBehavior(segment=self._testing_segment)
     self._process_device_behavior(mac, device_behavior, static=False)
     self._update_device_state_varz(mac, DVAState.sequestered)
Example #4
0
 def handle_auth_result(self, mac, access, segment, role):
     """Method passed as callback to authenticator to forward auth results"""
     self._faucet_collector.update_radius_result(mac, access, segment, role)
     with self._lock:
         if self._should_ignore_auth_result:
             LOGGER.warning('Ingoring authentication result for device %s', mac)
         else:
             device_behavior = DeviceBehavior(segment=segment, role=role)
             self._port_state_manager.handle_device_behavior(mac, device_behavior)
Example #5
0
 def _handle_auth_result(self, mac, access, segment, role):
     self._faucet_collector.update_radius_result(mac, access, segment, role)
     with self._states_lock:
         if self._should_ignore_auth_result:
             self._logger.warning(
                 'Ingoring authentication result for device %s', mac)
         else:
             device_behavior = DeviceBehavior(segment=segment, role=role)
             self._port_state_manager.handle_device_behavior(
                 mac, device_behavior)
Example #6
0
    def _unauthenticate_devices(self, unauthenticated_devices, expected_device_behaviors):
        for mac in unauthenticated_devices:
            self._port_state_manager.handle_device_behavior(mac, DeviceBehavior())

        expected_states = {
            '00:0Y:00:00:00:02': self.UNAUTHENTICATED,
            '00:0Z:00:00:00:03': self.INFRACTED,
            '00:0A:00:00:00:04': self.UNAUTHENTICATED
        }
        self._verify_ports_states(expected_states)

        expected_device_behaviors.extend([('00:0A:00:00:00:04', '', False)])
        self._verify_received_device_behaviors(expected_device_behaviors)
Example #7
0
    def _handle_unauthenticated_device(self, mac, static):
        """Handle an unauthenticated device"""
        with self._lock:
            try:
                device_behaviors = (
                    self._static_device_behaviors if static else self._dynamic_device_behaviors)
                device_behaviors.pop(mac)

                if static or mac not in self._static_device_behaviors:
                    self._state_machines.pop(mac)
                    self._process_device_behavior(mac, DeviceBehavior(), static=static)
            except KeyError as error:
                LOGGER.warning('MAC %s does not exist: %s', mac, error)
Example #8
0
    def _handle_authenticated_device(self, mac, device_behavior, static):
        """Initialize or update the state machine for an authenticated device"""
        with self._lock:
            device_behaviors = (self._static_device_behaviors
                                if static else self._dynamic_device_behaviors)
            device_behaviors.setdefault(
                mac, DeviceBehavior()).CopyFrom(device_behavior)

            auto_sequester = self._auto_sequester.get(
                mac, self._default_auto_sequestering)
            sequester_enabled = auto_sequester == PortBehavior.AutoSequestering.enabled
            if not self._sequester_segment or not sequester_enabled:
                port_behavior = PortBehavior.cleared
            else:
                port_behavior = PortBehavior.sequestered

            if mac in self._state_machines:
                self._state_machines[mac].handle_port_behavior(port_behavior)
Example #9
0
    def _handle_authenticated_device(self, mac, device_behavior, static):
        """Initialize or update the state machine for an authenticated device"""
        with self._lock:
            device_behaviors = (
                self._static_device_behaviors if static else self._dynamic_device_behaviors)
            device_behaviors.setdefault(mac, DeviceBehavior()).CopyFrom(device_behavior)

            static_port_behavior = self._static_port_behaviors.get(mac)
            if not self._testing_segment or static_port_behavior == PortBehavior.cleared:
                port_behavior = PortBehavior.cleared
            else:
                port_behavior = PortBehavior.sequestered

            new_state_machine = PortStateMachine(
                mac, PortStateMachine.AUTHENTICATED, self._set_port_sequestered,
                self._set_port_operational)
            state_machine = self._state_machines.setdefault(mac, new_state_machine)
            state_machine.handle_port_behavior(port_behavior)
Example #10
0
    def _handle_authenticated_device(self, mac, device_behavior, static):
        """Initialize or update the state machine for an authenticated device"""
        if not self._process_device_behavior:
            return

        with self._lock:
            device_behaviors = (self._static_device_behaviors
                                if static else self._dynamic_device_behaviors)
            device_behaviors.setdefault(
                mac, DeviceBehavior()).CopyFrom(device_behavior)

            static_port_behavior = self._static_port_behaviors.get(mac)
            if not self._testing_segment or static_port_behavior == PortBehavior.cleared:
                port_behavior = PortBehavior.cleared
            else:
                port_behavior = PortBehavior.sequestered

            if mac in self._state_machines:
                self._state_machines[mac].handle_port_behavior(port_behavior)
Example #11
0
    def _handle_deauthenticated_device(self, mac, static):
        """Handle an deauthenticated device"""
        with self._lock:
            device_behaviors = (self._static_device_behaviors
                                if static else self._dynamic_device_behaviors)
            if mac in device_behaviors:
                device_behaviors.pop(mac)
            else:
                self._logger.warning('%s behavior does not exist for %s',
                                     'static' if static else 'dynamic', mac)

            # ignore dynamic behavior for device that has static behavior defined
            if not static and mac in self._static_device_behaviors:
                return

            if mac in self._state_machines:
                port_behavior = PortBehavior.deauthenticated
                self._state_machines[mac].handle_port_behavior(port_behavior)
                self._process_device_behavior(mac,
                                              DeviceBehavior(),
                                              static=static)
Example #12
0
    def _set_port_sequestered(self, mac):
        """Set port to sequester vlan"""
        operational_behavior = (self._static_device_behaviors.get(mac)
                                or self._dynamic_device_behaviors.get(mac))

        device_behavior = DeviceBehavior(
            segment=self._sequester_segment,
            assigned_segment=operational_behavior.segment)
        self._process_device_behavior(mac, device_behavior, static=False)
        self._update_device_state_varz(mac, DVAState.sequestered)
        if self._sequester_timeout > 0:

            def handler():
                self._handle_sequestering_timeout(mac.lower())

            timeout = datetime.now() + timedelta(
                seconds=self._sequester_timeout)
            self._logger.info('Setting device %s sequester timeout at %s', mac,
                              timeout)
            self._sequester_timer[mac.lower()] = threading.Timer(
                self._sequester_timeout, handler)
            self._sequester_timer[mac.lower()].start()
Example #13
0
 def handle_auth_result(src_mac, access, segment, role):
     device_behavior = DeviceBehavior(segment=segment, role=role)
     self._forchestrator._port_state_manager.handle_device_behavior(
         src_mac, device_behavior)
Example #14
0
 def _handle_infracted_state(self, mac):
     static = mac in self._static_device_behaviors
     self._process_device_behavior(mac, DeviceBehavior(), static=static)
     self._update_device_state_varz(mac, DVAState.infracted)
Example #15
0
    def test_ports_states(self):
        """Test the port states with different signals"""
        static_device_behaviors = {
            '00:0X:00:00:00:01': {'segment': 'SEG_A', 'port_behavior': 'cleared'},
            '00:0Y:00:00:00:02': {'port_behavior': 'cleared'}
        }
        authentication_results = {
            '00:0X:00:00:00:01': {'segment': 'SEG_X'},
            '00:0Z:00:00:00:03': {'segment': 'SEG_C'},
            '00:0A:00:00:00:04': {'segment': 'SEG_D'},
            '00:0B:00:00:00:05': {'segment': 'SEG_E'}
        }
        testing_results = [
            ('00:0X:00:00:00:01', 'failed'),
            ('00:0Y:00:00:00:02', 'passed'),
            ('00:0Z:00:00:00:03', 'failed'),
            ('00:0A:00:00:00:04', 'passed')
        ]
        unauthenticated_devices = ['00:0X:00:00:00:01', '00:0A:00:00:00:04']
        expired_device_vlans = [
            ('00:0B:00:00:00:05', 600),
            ('00:0B:00:00:00:05', 500),
        ]

        # load static device behaviors
        for mac, device_behavior_map in static_device_behaviors.items():
            self._port_state_manager.handle_static_device_behavior(
                mac, dict_proto(device_behavior_map, DeviceBehavior))

        # devices are authenticated
        for mac, device_behavior_map in authentication_results.items():
            self._port_state_manager.handle_device_behavior(
                mac, dict_proto(device_behavior_map, DeviceBehavior))

        expected_states = {
            '00:0X:00:00:00:01': self.OPERATIONAL,
            '00:0Z:00:00:00:03': self.SEQUESTERED,
            '00:0A:00:00:00:04': self.SEQUESTERED,
            '00:0B:00:00:00:05': self.SEQUESTERED
        }
        self._verify_ports_states(expected_states)

        expected_received_device_behaviors = [
            ('00:0X:00:00:00:01', 'SEG_A', True),
            ('00:0X:00:00:00:01', 'SEG_A', True),
            ('00:0Z:00:00:00:03', 'TESTING', False),
            ('00:0A:00:00:00:04', 'TESTING', False),
            ('00:0B:00:00:00:05', 'TESTING', False)
        ]
        self._verify_received_device_behaviors(expected_received_device_behaviors)

        # received testing results for devices
        for testing_result in testing_results:
            self._port_state_manager.handle_testing_result(
                self._encapsulate_testing_result(*testing_result))

        expected_states = {
            '00:0X:00:00:00:01': self.OPERATIONAL,
            '00:0Z:00:00:00:03': self.INFRACTED,
            '00:0A:00:00:00:04': self.OPERATIONAL,
            '00:0B:00:00:00:05': self.SEQUESTERED
        }
        self._verify_ports_states(expected_states)

        expected_received_device_behaviors.extend([('00:0A:00:00:00:04', 'SEG_D', False)])
        self._verify_received_device_behaviors(expected_received_device_behaviors)

        # devices are unauthenticated
        for mac in unauthenticated_devices:
            self._port_state_manager.handle_device_behavior(mac, DeviceBehavior())

        expected_states = {
            '00:0X:00:00:00:01': self.OPERATIONAL,
            '00:0Z:00:00:00:03': self.INFRACTED,
            '00:0B:00:00:00:05': self.SEQUESTERED
        }
        self._verify_ports_states(expected_states)

        expected_received_device_behaviors.extend([('00:0A:00:00:00:04', '', False)])
        self._verify_received_device_behaviors(expected_received_device_behaviors)

        # devices are expired
        for expired_device_vlan in expired_device_vlans:
            mac = expired_device_vlan[0]
            expired_vlan = expired_device_vlan[1]
            self._port_state_manager.handle_device_placement(
                mac, DevicePlacement(switch='switch', port=1), False, expired_vlan)

        expired_received_device_placements = [('00:0B:00:00:00:05', False, False)]
        self._verify_received_device_placements(expired_received_device_placements)
Example #16
0
 def _set_port_sequestered(self, mac):
     """Set port to sequester vlan"""
     device_behavior = DeviceBehavior(segment=self._testing_segment)
     self._process_device_behavior(mac, device_behavior, static=False)