Skip to content

Commit 6220b57

Browse files
authored
Merge pull request #2417 from anarkiwi/master
Revert "Merge pull request #2377 from Bairdo/chewie-radius"
2 parents 2a8bddf + f4c378b commit 6220b57

File tree

3 files changed

+31
-105
lines changed

3 files changed

+31
-105
lines changed

faucet/faucet_dot1x.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
class FaucetDot1x:
3030
"""Wrapper for experimental Chewie 802.1x authenticator."""
3131

32+
# TODO: support other credentials.
33+
CREDENTIALS = {
34+
'gary': 'microphone',
35+
}
36+
3237
def __init__(self, logger, metrics, send_flow_msgs):
3338
self.logger = logger
3439
self.metrics = metrics
@@ -39,10 +44,10 @@ def __init__(self, logger, metrics, send_flow_msgs):
3944
self.dot1x_port = None
4045

4146
def _create_dot1x_speaker(self):
42-
chewie = Chewie( # pylint: disable=too-many-function-args
43-
self.dot1x_intf, self.logger,
44-
self.auth_handler, self.failure_handler, self.logoff_handler,
45-
'127.0.0.1')
47+
chewie = Chewie(
48+
self.dot1x_intf, self.CREDENTIALS,
49+
self.logger, self.auth_handler,
50+
MacAddress.from_string('00:00:00:00:00:01'))
4651
hub.spawn(chewie.run)
4752
return chewie
4853

@@ -59,17 +64,17 @@ def auth_handler(self, address, _group_address):
5964
if flowmods:
6065
self._send_flow_msgs(self._valve, flowmods)
6166

62-
def logoff_handler(self, address, _):
67+
def logoff_handler(self, address):
6368
"""Callback for when an EAP logoff happens."""
6469
self.logger.info('Logoff from MAC %s on %s',
6570
str(address), self.dot1x_port)
6671
self.metrics.inc_var('dp_dot1x_logoff', self._valve.base_prom_labels)
6772
self.metrics.inc_var('port_dot1x_logoff', self._valve.port_labels(self.dot1x_port))
68-
flowmods = self._valve.del_authed_mac(self.dot1x_port.number, str(address))
73+
flowmods = self._valve.del_authed_mac(self.dot1x_port.number, address)
6974
if flowmods:
7075
self._send_flow_msgs(self._valve, flowmods)
7176

72-
def failure_handler(self, address, _):
77+
def failure_handler(self, address):
7378
"""Callback for when a EAP failure happens."""
7479
self.logger.info('Failure from MAC %s on %s',
7580
str(address), self.dot1x_port)

faucet/valve.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ def del_authed_mac(self, port_num, mac):
14761476
priority=self.dp.highest_priority,
14771477
strict=True
14781478
)
1479-
return ofmsg
1479+
return [ofmsg]
14801480

14811481
def add_route(self, vlan, ip_gw, ip_dst):
14821482
"""Add route to VLAN routing table."""

tests/integration/mininet_tests.py

+18-97
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import os
1414
import random
1515
import re
16-
import shutil
1716
import socket
1817
import threading
1918
import time
@@ -156,7 +155,7 @@ def test_untagged(self):
156155
self.verify_events_log(event_log)
157156

158157

159-
class FaucetSingle8021XSuccessTest(FaucetUntaggedTest):
158+
class FaucetUntagged8021XSuccessTest(FaucetUntaggedTest):
160159

161160
SOFTWARE_ONLY = True
162161

@@ -223,7 +222,7 @@ class FaucetSingle8021XSuccessTest(FaucetUntaggedTest):
223222
network={
224223
key_mgmt=IEEE8021X
225224
eap=MD5
226-
identity="user"
225+
identity="user@example.com"
227226
password="microphone"
228227
}
229228
"""
@@ -248,19 +247,11 @@ def _write_faucet_config(self):
248247

249248
self.CONFIG = self.CONFIG.replace('NFV_INTF', str(nfv_intf))
250249
self.CONFIG_GLOBAL = self.CONFIG_GLOBAL.replace("NFV_MAC", nfv_intf.MAC())
251-
super(FaucetSingle8021XSuccessTest, self)._write_faucet_config()
250+
super(FaucetUntagged8021XSuccessTest, self)._write_faucet_config()
252251

253252
def setUp(self):
254-
super(FaucetSingle8021XSuccessTest, self).setUp()
253+
super(FaucetUntagged8021XSuccessTest, self).setUp()
255254
self.host_drop_all_ips(self.nfv_host)
256-
self.radius_port = 1812
257-
# self.radius_port = mininet_test_util.find_free_port(
258-
# self.ports_sock, self._test_name())
259-
self.start_freeradius()
260-
261-
def tearDown(self):
262-
self.nfv_host.cmd('kill %d' % self.freeradius_pid)
263-
super(FaucetSingle8021XSuccessTest, self).tearDown()
264255

265256
def try_8021x(self, and_logff=False):
266257
tcpdump_filter = 'ether proto 0x888e'
@@ -272,28 +263,22 @@ def try_8021x(self, and_logff=False):
272263

273264
def test_untagged(self):
274265
tcpdump_txt = self.try_8021x(and_logff=True)
275-
276266
self.assertIn('Success', tcpdump_txt)
277267
self.assertEqual(
278268
1,
279-
self.scrape_prometheus_var('dp_dot1x_success', default=0))
280-
self.assertEqual(
281-
1,
282-
self.scrape_prometheus_var('port_dot1x_success', labels={'port': 1}, default=0))
269+
self.scrape_prometheus_var('dp_dot1x_success', any_labels=True, default=0))
283270
self.assertEqual(
284271
0,
285-
self.scrape_prometheus_var('dp_dot1x_failure', default=0))
286-
self.assertEqual(
287-
0,
288-
self.scrape_prometheus_var('port_dot1x_failure', labels={'port': 1}, default=0))
272+
self.scrape_prometheus_var('dp_dot1x_failure', any_labels=True, default=0))
289273
self.assertEqual(
290274
1,
291-
self.scrape_prometheus_var('dp_dot1x_logoff', default=0))
275+
self.scrape_prometheus_var('port_dot1x_success', any_labels=True, default=0))
292276
self.assertEqual(
293-
1,
294-
self.scrape_prometheus_var('port_dot1x_logoff', labels={'port': 1}, default=0))
277+
0,
278+
self.scrape_prometheus_var('port_dot1x_failure', any_labels=True, default=0))
295279
self.assertIn('Success', tcpdump_txt)
296280
self.assertIn('logoff', tcpdump_txt)
281+
# TODO check prometheus dp/port_dot1x_logoff once logoff_handler implemented on chewie side.
297282

298283
def wpa_supplicant_callback(self, and_logoff):
299284
wpa_ctrl_path = os.path.join(
@@ -314,100 +299,36 @@ def wpa_supplicant_callback(self, and_logoff):
314299
break
315300
time.sleep(1)
316301
self.assertEqual(eap_state, 'SUCCESS')
317-
self.wait_until_matching_flow(
318-
{'eth_src': self.eapol_host.MAC(), 'in_port': 1}, table_id=0)
319-
320302
self.eapol_host.cmd('wpa_cli -p %s logoff' % wpa_ctrl_path)
321303

322-
for i in range(10):
323-
if not self.matching_flow_present(
324-
{'eth_src': self.eapol_host.MAC(), 'in_port': 1}, table_id=0):
325-
break
326-
time.sleep(1)
327-
else:
328-
self.fail('authentication flow was not removed.')
329-
330-
def wait_for_radius(self, radius_log_path, timeout=10):
331-
for i in range(timeout):
332-
if os.path.exists(radius_log_path):
333-
break
334-
time.sleep(1)
335-
else:
336-
self.fail('could not open radius log after %d seconds' % timeout)
337-
338-
with open(radius_log_path, 'r') as log:
339-
while True:
340-
line = log.readline()
341-
if not line:
342-
time.sleep(1)
343-
continue
344-
if line.strip() == 'Ready to process requests.':
345-
return
346-
347-
def start_freeradius(self):
348-
with open('/etc/freeradius/users', 'w') as f:
349-
f.write('user Cleartext-Password := "microphone"')
350-
351-
with open('/etc/freeradius/clients.conf', 'w') as f:
352-
f.write('''client localhost {
353-
ipaddr = 127.0.0.1
354-
secret = SECRET
355-
}''')
356-
357-
radius_log_path = '%s/radius.log' % self.tmpdir
358-
shutil.copytree('/etc/freeradius/', '%s/freeradius' % self.tmpdir)
359-
os.system('chmod o+rx %s' % self.root_tmpdir)
360-
os.system('chown -R root:freerad %s/freeradius/*' % self.tmpdir)
361-
os.system('chown root:freerad %s/freeradius' % self.tmpdir)
362-
363-
with open('%s/freeradius/radiusd.conf' % self.tmpdir, 'r+') as radiusd_file:
364-
config = radiusd_file.read()
365-
radiusd_file.seek(0)
366-
radiusd_file.truncate()
367-
new_config = config.replace('port = 0', 'port = %d' % self.radius_port, 2)
368-
radiusd_file.write(new_config)
369304

370-
self.nfv_host.cmd('freeradius -sxx -l %s -d %s/freeradius &' % (radius_log_path, self.tmpdir))
371-
372-
self.freeradius_pid = self.nfv_host.lastPid
373-
self.wait_for_radius(radius_log_path)
374-
return radius_log_path
375-
376-
377-
class FaucetSingle8021XFailureTest(FaucetSingle8021XSuccessTest):
305+
class FaucetUntagged8021XFailureTest(FaucetUntagged8021XSuccessTest):
378306
"""Failure due to incorrect identity/password"""
379307

380308
wpasupplicant_conf = """
381309
ap_scan=0
382310
network={
383311
key_mgmt=IEEE8021X
384312
eap=MD5
385-
identity="user"
313+
identity="user@example.com"
386314
password="wrongpassword"
387315
}
388316
"""
389317

390318
def test_untagged(self):
391319
tcpdump_txt = self.try_8021x(and_logff=False)
392320
self.assertIn('Failure', tcpdump_txt)
321+
faucet_log = self.env['faucet']['FAUCET_LOG']
322+
with open(faucet_log, 'r') as log:
323+
faucet_log_txt = log.read()
324+
self.assertNotIn('Successful auth', faucet_log_txt)
393325
self.assertEqual(
394326
0,
395-
self.scrape_prometheus_var('dp_dot1x_success', default=0))
327+
self.scrape_prometheus_var('dp_dot1x_success', labels={'port': 1}, default=0))
396328
self.assertEqual(
397329
0,
398330
self.scrape_prometheus_var('port_dot1x_success', labels={'port': 1}, default=0))
399-
self.assertEqual(
400-
0,
401-
self.scrape_prometheus_var('dp_dot1x_logoff', default=0))
402-
self.assertEqual(
403-
0,
404-
self.scrape_prometheus_var('port_dot1x_logoff', labels={'port': 1}, default=0))
405-
self.assertEqual(
406-
1,
407-
self.scrape_prometheus_var('dp_dot1x_failure', default=0))
408-
self.assertEqual(
409-
1,
410-
self.scrape_prometheus_var('port_dot1x_failure', labels={'port': 1}, default=0))
331+
# TODO add prometheus dp/port_dot1x_failure check once failure handler is implemented on chewie side.
411332

412333

413334
class FaucetUntaggedRandomVidTest(FaucetUntaggedTest):

0 commit comments

Comments
 (0)