From f4c378b4325dd696fc1f75e28193d6d84f9fc872 Mon Sep 17 00:00:00 2001 From: Josh Bailey Date: Mon, 3 Sep 2018 19:00:45 +1200 Subject: [PATCH] Revert "Merge pull request #2377 from Bairdo/chewie-radius" This reverts commit b252afef7cd55b9c0f47f1cf75054d84a7bb6c65, reversing changes made to a76f710e1cf0317549307bb56114a8e8cd330fcb. --- faucet/faucet_dot1x.py | 19 +++-- faucet/valve.py | 2 +- tests/integration/mininet_tests.py | 115 +++++------------------------ 3 files changed, 31 insertions(+), 105 deletions(-) diff --git a/faucet/faucet_dot1x.py b/faucet/faucet_dot1x.py index 737d90382a..5573ad1e2a 100644 --- a/faucet/faucet_dot1x.py +++ b/faucet/faucet_dot1x.py @@ -29,6 +29,11 @@ class FaucetDot1x: """Wrapper for experimental Chewie 802.1x authenticator.""" + # TODO: support other credentials. + CREDENTIALS = { + 'gary': 'microphone', + } + def __init__(self, logger, metrics, send_flow_msgs): self.logger = logger self.metrics = metrics @@ -39,10 +44,10 @@ def __init__(self, logger, metrics, send_flow_msgs): self.dot1x_port = None def _create_dot1x_speaker(self): - chewie = Chewie( # pylint: disable=too-many-function-args - self.dot1x_intf, self.logger, - self.auth_handler, self.failure_handler, self.logoff_handler, - '127.0.0.1') + 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 @@ -59,17 +64,17 @@ def auth_handler(self, address, _group_address): if flowmods: self._send_flow_msgs(self._valve, flowmods) - def logoff_handler(self, address, _): + def logoff_handler(self, address): """Callback for when an EAP logoff happens.""" self.logger.info('Logoff from MAC %s on %s', str(address), self.dot1x_port) self.metrics.inc_var('dp_dot1x_logoff', self._valve.base_prom_labels) self.metrics.inc_var('port_dot1x_logoff', self._valve.port_labels(self.dot1x_port)) - flowmods = self._valve.del_authed_mac(self.dot1x_port.number, str(address)) + flowmods = self._valve.del_authed_mac(self.dot1x_port.number, address) if flowmods: self._send_flow_msgs(self._valve, flowmods) - def failure_handler(self, address, _): + def failure_handler(self, address): """Callback for when a EAP failure happens.""" self.logger.info('Failure from MAC %s on %s', str(address), self.dot1x_port) diff --git a/faucet/valve.py b/faucet/valve.py index 5b6180012b..a4c353a847 100644 --- a/faucet/valve.py +++ b/faucet/valve.py @@ -1476,7 +1476,7 @@ def del_authed_mac(self, port_num, mac): priority=self.dp.highest_priority, strict=True ) - return ofmsg + return [ofmsg] def add_route(self, vlan, ip_gw, ip_dst): """Add route to VLAN routing table.""" diff --git a/tests/integration/mininet_tests.py b/tests/integration/mininet_tests.py index 5f612d3cd1..e8fcd8e376 100644 --- a/tests/integration/mininet_tests.py +++ b/tests/integration/mininet_tests.py @@ -13,7 +13,6 @@ import os import random import re -import shutil import socket import threading import time @@ -156,7 +155,7 @@ def test_untagged(self): self.verify_events_log(event_log) -class FaucetSingle8021XSuccessTest(FaucetUntaggedTest): +class FaucetUntagged8021XSuccessTest(FaucetUntaggedTest): SOFTWARE_ONLY = True @@ -223,7 +222,7 @@ class FaucetSingle8021XSuccessTest(FaucetUntaggedTest): network={ key_mgmt=IEEE8021X eap=MD5 - identity="user" + identity="user@example.com" password="microphone" } """ @@ -248,19 +247,11 @@ def _write_faucet_config(self): self.CONFIG = self.CONFIG.replace('NFV_INTF', str(nfv_intf)) self.CONFIG_GLOBAL = self.CONFIG_GLOBAL.replace("NFV_MAC", nfv_intf.MAC()) - super(FaucetSingle8021XSuccessTest, self)._write_faucet_config() + super(FaucetUntagged8021XSuccessTest, self)._write_faucet_config() def setUp(self): - super(FaucetSingle8021XSuccessTest, self).setUp() + super(FaucetUntagged8021XSuccessTest, self).setUp() self.host_drop_all_ips(self.nfv_host) - self.radius_port = 1812 - # self.radius_port = mininet_test_util.find_free_port( - # self.ports_sock, self._test_name()) - self.start_freeradius() - - def tearDown(self): - self.nfv_host.cmd('kill %d' % self.freeradius_pid) - super(FaucetSingle8021XSuccessTest, self).tearDown() def try_8021x(self, and_logff=False): tcpdump_filter = 'ether proto 0x888e' @@ -272,28 +263,22 @@ def try_8021x(self, and_logff=False): def test_untagged(self): tcpdump_txt = self.try_8021x(and_logff=True) - self.assertIn('Success', tcpdump_txt) self.assertEqual( 1, - self.scrape_prometheus_var('dp_dot1x_success', default=0)) - self.assertEqual( - 1, - self.scrape_prometheus_var('port_dot1x_success', labels={'port': 1}, default=0)) + self.scrape_prometheus_var('dp_dot1x_success', any_labels=True, default=0)) self.assertEqual( 0, - self.scrape_prometheus_var('dp_dot1x_failure', default=0)) - self.assertEqual( - 0, - self.scrape_prometheus_var('port_dot1x_failure', labels={'port': 1}, default=0)) + self.scrape_prometheus_var('dp_dot1x_failure', any_labels=True, default=0)) self.assertEqual( 1, - self.scrape_prometheus_var('dp_dot1x_logoff', default=0)) + self.scrape_prometheus_var('port_dot1x_success', any_labels=True, default=0)) self.assertEqual( - 1, - self.scrape_prometheus_var('port_dot1x_logoff', labels={'port': 1}, default=0)) + 0, + self.scrape_prometheus_var('port_dot1x_failure', any_labels=True, default=0)) self.assertIn('Success', tcpdump_txt) self.assertIn('logoff', tcpdump_txt) + # TODO check prometheus dp/port_dot1x_logoff once logoff_handler implemented on chewie side. def wpa_supplicant_callback(self, and_logoff): wpa_ctrl_path = os.path.join( @@ -314,67 +299,10 @@ def wpa_supplicant_callback(self, and_logoff): break time.sleep(1) self.assertEqual(eap_state, 'SUCCESS') - self.wait_until_matching_flow( - {'eth_src': self.eapol_host.MAC(), 'in_port': 1}, table_id=0) - self.eapol_host.cmd('wpa_cli -p %s logoff' % wpa_ctrl_path) - for i in range(10): - if not self.matching_flow_present( - {'eth_src': self.eapol_host.MAC(), 'in_port': 1}, table_id=0): - break - time.sleep(1) - else: - self.fail('authentication flow was not removed.') - - def wait_for_radius(self, radius_log_path, timeout=10): - for i in range(timeout): - if os.path.exists(radius_log_path): - break - time.sleep(1) - else: - self.fail('could not open radius log after %d seconds' % timeout) - - with open(radius_log_path, 'r') as log: - while True: - line = log.readline() - if not line: - time.sleep(1) - continue - if line.strip() == 'Ready to process requests.': - return - - def start_freeradius(self): - with open('/etc/freeradius/users', 'w') as f: - f.write('user Cleartext-Password := "microphone"') - - with open('/etc/freeradius/clients.conf', 'w') as f: - f.write('''client localhost { - ipaddr = 127.0.0.1 - secret = SECRET -}''') - - radius_log_path = '%s/radius.log' % self.tmpdir - shutil.copytree('/etc/freeradius/', '%s/freeradius' % self.tmpdir) - os.system('chmod o+rx %s' % self.root_tmpdir) - os.system('chown -R root:freerad %s/freeradius/*' % self.tmpdir) - os.system('chown root:freerad %s/freeradius' % self.tmpdir) - - with open('%s/freeradius/radiusd.conf' % self.tmpdir, 'r+') as radiusd_file: - config = radiusd_file.read() - radiusd_file.seek(0) - radiusd_file.truncate() - new_config = config.replace('port = 0', 'port = %d' % self.radius_port, 2) - radiusd_file.write(new_config) - self.nfv_host.cmd('freeradius -sxx -l %s -d %s/freeradius &' % (radius_log_path, self.tmpdir)) - - self.freeradius_pid = self.nfv_host.lastPid - self.wait_for_radius(radius_log_path) - return radius_log_path - - -class FaucetSingle8021XFailureTest(FaucetSingle8021XSuccessTest): +class FaucetUntagged8021XFailureTest(FaucetUntagged8021XSuccessTest): """Failure due to incorrect identity/password""" wpasupplicant_conf = """ @@ -382,7 +310,7 @@ class FaucetSingle8021XFailureTest(FaucetSingle8021XSuccessTest): network={ key_mgmt=IEEE8021X eap=MD5 - identity="user" + identity="user@example.com" password="wrongpassword" } """ @@ -390,24 +318,17 @@ class FaucetSingle8021XFailureTest(FaucetSingle8021XSuccessTest): def test_untagged(self): tcpdump_txt = self.try_8021x(and_logff=False) self.assertIn('Failure', tcpdump_txt) + faucet_log = self.env['faucet']['FAUCET_LOG'] + with open(faucet_log, 'r') as log: + faucet_log_txt = log.read() + self.assertNotIn('Successful auth', faucet_log_txt) self.assertEqual( 0, - self.scrape_prometheus_var('dp_dot1x_success', default=0)) + self.scrape_prometheus_var('dp_dot1x_success', labels={'port': 1}, default=0)) self.assertEqual( 0, self.scrape_prometheus_var('port_dot1x_success', labels={'port': 1}, default=0)) - self.assertEqual( - 0, - self.scrape_prometheus_var('dp_dot1x_logoff', default=0)) - self.assertEqual( - 0, - self.scrape_prometheus_var('port_dot1x_logoff', labels={'port': 1}, default=0)) - self.assertEqual( - 1, - self.scrape_prometheus_var('dp_dot1x_failure', default=0)) - self.assertEqual( - 1, - self.scrape_prometheus_var('port_dot1x_failure', labels={'port': 1}, default=0)) + # TODO add prometheus dp/port_dot1x_failure check once failure handler is implemented on chewie side. class FaucetUntaggedRandomVidTest(FaucetUntaggedTest):