2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
11 logger = logging.getLogger()
20 from utils import HwsimSkip, require_under_vm, skip_with_fips
21 from test_ap_hs20 import build_dhcp_ack
22 from test_ap_ft import ft_params1
24 def connect(dev, ssid, wait_connect=True):
25 dev.connect(ssid, key_mgmt="WPA-EAP", scan_freq="2412",
26 eap="PSK", identity="psk.user@example.com",
27 password_hex="0123456789abcdef0123456789abcdef",
28 wait_connect=wait_connect)
30 def test_radius_auth_unreachable(dev, apdev):
31 """RADIUS Authentication server unreachable"""
32 params = hostapd.wpa2_eap_params(ssid="radius-auth")
33 params['auth_server_port'] = "18139"
34 hostapd.add_ap(apdev[0], params)
35 hapd = hostapd.Hostapd(apdev[0]['ifname'])
36 connect(dev[0], "radius-auth", wait_connect=False)
37 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"])
39 raise Exception("Timeout on EAP start")
40 logger.info("Checking for RADIUS retries")
43 if "radiusAuthClientAccessRequests" not in mib:
44 raise Exception("Missing MIB fields")
45 if int(mib["radiusAuthClientAccessRetransmissions"]) < 1:
46 raise Exception("Missing RADIUS Authentication retransmission")
47 if int(mib["radiusAuthClientPendingRequests"]) < 1:
48 raise Exception("Missing pending RADIUS Authentication request")
50 def test_radius_auth_unreachable2(dev, apdev):
51 """RADIUS Authentication server unreachable (2)"""
52 subprocess.call(['ip', 'ro', 'replace', '192.168.213.17', 'dev', 'lo'])
53 params = hostapd.wpa2_eap_params(ssid="radius-auth")
54 params['auth_server_addr'] = "192.168.213.17"
55 params['auth_server_port'] = "18139"
56 hostapd.add_ap(apdev[0], params)
57 hapd = hostapd.Hostapd(apdev[0]['ifname'])
58 subprocess.call(['ip', 'ro', 'del', '192.168.213.17', 'dev', 'lo'])
59 connect(dev[0], "radius-auth", wait_connect=False)
60 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"])
62 raise Exception("Timeout on EAP start")
63 logger.info("Checking for RADIUS retries")
66 if "radiusAuthClientAccessRequests" not in mib:
67 raise Exception("Missing MIB fields")
68 if int(mib["radiusAuthClientAccessRetransmissions"]) < 1:
69 raise Exception("Missing RADIUS Authentication retransmission")
71 def test_radius_auth_unreachable3(dev, apdev):
72 """RADIUS Authentication server initially unreachable, but then available"""
73 subprocess.call(['ip', 'ro', 'replace', 'blackhole', '192.168.213.18'])
74 params = hostapd.wpa2_eap_params(ssid="radius-auth")
75 params['auth_server_addr'] = "192.168.213.18"
76 hostapd.add_ap(apdev[0], params)
77 hapd = hostapd.Hostapd(apdev[0]['ifname'])
78 connect(dev[0], "radius-auth", wait_connect=False)
79 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"])
81 raise Exception("Timeout on EAP start")
82 subprocess.call(['ip', 'ro', 'del', 'blackhole', '192.168.213.18'])
84 dev[0].request("DISCONNECT")
85 hapd.set('auth_server_addr_replace', '127.0.0.1')
86 dev[0].request("RECONNECT")
88 dev[0].wait_connected()
90 def test_radius_acct_unreachable(dev, apdev):
91 """RADIUS Accounting server unreachable"""
92 params = hostapd.wpa2_eap_params(ssid="radius-acct")
93 params['acct_server_addr'] = "127.0.0.1"
94 params['acct_server_port'] = "18139"
95 params['acct_server_shared_secret'] = "radius"
96 hostapd.add_ap(apdev[0], params)
97 hapd = hostapd.Hostapd(apdev[0]['ifname'])
98 connect(dev[0], "radius-acct")
99 logger.info("Checking for RADIUS retries")
102 if "radiusAccClientRetransmissions" not in mib:
103 raise Exception("Missing MIB fields")
104 if int(mib["radiusAccClientRetransmissions"]) < 2:
105 raise Exception("Missing RADIUS Accounting retransmissions")
106 if int(mib["radiusAccClientPendingRequests"]) < 2:
107 raise Exception("Missing pending RADIUS Accounting requests")
109 def test_radius_acct_unreachable2(dev, apdev):
110 """RADIUS Accounting server unreachable(2)"""
111 subprocess.call(['ip', 'ro', 'replace', '192.168.213.17', 'dev', 'lo'])
112 params = hostapd.wpa2_eap_params(ssid="radius-acct")
113 params['acct_server_addr'] = "192.168.213.17"
114 params['acct_server_port'] = "18139"
115 params['acct_server_shared_secret'] = "radius"
116 hostapd.add_ap(apdev[0], params)
117 hapd = hostapd.Hostapd(apdev[0]['ifname'])
118 subprocess.call(['ip', 'ro', 'del', '192.168.213.17', 'dev', 'lo'])
119 connect(dev[0], "radius-acct")
120 logger.info("Checking for RADIUS retries")
123 if "radiusAccClientRetransmissions" not in mib:
124 raise Exception("Missing MIB fields")
125 if int(mib["radiusAccClientRetransmissions"]) < 1 and int(mib["radiusAccClientPendingRequests"]) < 1:
126 raise Exception("Missing pending or retransmitted RADIUS Accounting requests")
128 def test_radius_acct_unreachable3(dev, apdev):
129 """RADIUS Accounting server initially unreachable, but then available"""
131 subprocess.call(['ip', 'ro', 'replace', 'blackhole', '192.168.213.18'])
132 as_hapd = hostapd.Hostapd("as")
133 as_mib_start = as_hapd.get_mib(param="radius_server")
134 params = hostapd.wpa2_eap_params(ssid="radius-acct")
135 params['acct_server_addr'] = "192.168.213.18"
136 params['acct_server_port'] = "1813"
137 params['acct_server_shared_secret'] = "radius"
138 hostapd.add_ap(apdev[0], params)
139 hapd = hostapd.Hostapd(apdev[0]['ifname'])
140 connect(dev[0], "radius-acct")
141 subprocess.call(['ip', 'ro', 'del', 'blackhole', '192.168.213.18'])
143 dev[0].request("DISCONNECT")
144 hapd.set('acct_server_addr_replace', '127.0.0.1')
145 dev[0].request("RECONNECT")
146 dev[0].wait_connected()
148 as_mib_end = as_hapd.get_mib(param="radius_server")
149 req_s = int(as_mib_start['radiusAccServTotalResponses'])
150 req_e = int(as_mib_end['radiusAccServTotalResponses'])
152 raise Exception("Unexpected RADIUS server acct MIB value")
154 def test_radius_acct_unreachable4(dev, apdev):
155 """RADIUS Accounting server unreachable and multiple STAs"""
156 params = hostapd.wpa2_eap_params(ssid="radius-acct")
157 params['acct_server_addr'] = "127.0.0.1"
158 params['acct_server_port'] = "18139"
159 params['acct_server_shared_secret'] = "radius"
160 hostapd.add_ap(apdev[0], params)
161 hapd = hostapd.Hostapd(apdev[0]['ifname'])
163 connect(dev[0], "radius-acct")
164 dev[0].request("REMOVE_NETWORK all")
165 dev[0].wait_disconnected()
167 def test_radius_acct(dev, apdev):
168 """RADIUS Accounting"""
169 as_hapd = hostapd.Hostapd("as")
170 as_mib_start = as_hapd.get_mib(param="radius_server")
171 params = hostapd.wpa2_eap_params(ssid="radius-acct")
172 params['acct_server_addr'] = "127.0.0.1"
173 params['acct_server_port'] = "1813"
174 params['acct_server_shared_secret'] = "radius"
175 params['radius_auth_req_attr'] = [ "126:s:Operator", "77:s:testing" ]
176 params['radius_acct_req_attr'] = [ "126:s:Operator", "77:s:testing" ]
177 hostapd.add_ap(apdev[0], params)
178 hapd = hostapd.Hostapd(apdev[0]['ifname'])
179 connect(dev[0], "radius-acct")
180 dev[1].connect("radius-acct", key_mgmt="WPA-EAP", scan_freq="2412",
181 eap="PAX", identity="test-class",
182 password_hex="0123456789abcdef0123456789abcdef")
183 dev[2].connect("radius-acct", key_mgmt="WPA-EAP",
184 eap="GPSK", identity="gpsk-cui",
185 password="abcdefghijklmnop0123456789abcdef",
187 logger.info("Checking for RADIUS counters")
191 if int(mib['radiusAccClientResponses']) >= 3:
196 raise Exception("Did not receive Accounting-Response packets")
198 if int(mib['radiusAccClientRetransmissions']) > 0:
199 raise Exception("Unexpected Accounting-Request retransmission")
201 as_mib_end = as_hapd.get_mib(param="radius_server")
203 req_s = int(as_mib_start['radiusAccServTotalRequests'])
204 req_e = int(as_mib_end['radiusAccServTotalRequests'])
205 if req_e < req_s + 2:
206 raise Exception("Unexpected RADIUS server acct MIB value")
208 acc_s = int(as_mib_start['radiusAuthServAccessAccepts'])
209 acc_e = int(as_mib_end['radiusAuthServAccessAccepts'])
210 if acc_e < acc_s + 1:
211 raise Exception("Unexpected RADIUS server auth MIB value")
213 def test_radius_acct_non_ascii_ssid(dev, apdev):
214 """RADIUS Accounting and non-ASCII SSID"""
215 params = hostapd.wpa2_eap_params()
216 params['acct_server_addr'] = "127.0.0.1"
217 params['acct_server_port'] = "1813"
218 params['acct_server_shared_secret'] = "radius"
219 ssid2 = "740665007374"
220 params['ssid2'] = ssid2
221 hostapd.add_ap(apdev[0], params)
222 dev[0].connect(ssid2=ssid2, key_mgmt="WPA-EAP", scan_freq="2412",
223 eap="PSK", identity="psk.user@example.com",
224 password_hex="0123456789abcdef0123456789abcdef")
226 def test_radius_acct_pmksa_caching(dev, apdev):
227 """RADIUS Accounting with PMKSA caching"""
228 as_hapd = hostapd.Hostapd("as")
229 as_mib_start = as_hapd.get_mib(param="radius_server")
230 params = hostapd.wpa2_eap_params(ssid="radius-acct")
231 params['acct_server_addr'] = "127.0.0.1"
232 params['acct_server_port'] = "1813"
233 params['acct_server_shared_secret'] = "radius"
234 hapd = hostapd.add_ap(apdev[0], params)
235 connect(dev[0], "radius-acct")
236 dev[1].connect("radius-acct", key_mgmt="WPA-EAP", scan_freq="2412",
237 eap="PAX", identity="test-class",
238 password_hex="0123456789abcdef0123456789abcdef")
239 for d in [ dev[0], dev[1] ]:
240 d.request("REASSOCIATE")
241 d.wait_connected(timeout=15, error="Reassociation timed out")
246 if int(mib['radiusAccClientResponses']) >= 4:
251 raise Exception("Did not receive Accounting-Response packets")
253 if int(mib['radiusAccClientRetransmissions']) > 0:
254 raise Exception("Unexpected Accounting-Request retransmission")
256 as_mib_end = as_hapd.get_mib(param="radius_server")
258 req_s = int(as_mib_start['radiusAccServTotalRequests'])
259 req_e = int(as_mib_end['radiusAccServTotalRequests'])
260 if req_e < req_s + 2:
261 raise Exception("Unexpected RADIUS server acct MIB value")
263 acc_s = int(as_mib_start['radiusAuthServAccessAccepts'])
264 acc_e = int(as_mib_end['radiusAuthServAccessAccepts'])
265 if acc_e < acc_s + 1:
266 raise Exception("Unexpected RADIUS server auth MIB value")
268 def test_radius_acct_interim(dev, apdev):
269 """RADIUS Accounting interim update"""
270 as_hapd = hostapd.Hostapd("as")
271 params = hostapd.wpa2_eap_params(ssid="radius-acct")
272 params['acct_server_addr'] = "127.0.0.1"
273 params['acct_server_port'] = "1813"
274 params['acct_server_shared_secret'] = "radius"
275 params['radius_acct_interim_interval'] = "1"
276 hostapd.add_ap(apdev[0], params)
277 hapd = hostapd.Hostapd(apdev[0]['ifname'])
278 connect(dev[0], "radius-acct")
279 logger.info("Checking for RADIUS counters")
280 as_mib_start = as_hapd.get_mib(param="radius_server")
282 as_mib_end = as_hapd.get_mib(param="radius_server")
283 req_s = int(as_mib_start['radiusAccServTotalRequests'])
284 req_e = int(as_mib_end['radiusAccServTotalRequests'])
285 if req_e < req_s + 3:
286 raise Exception("Unexpected RADIUS server acct MIB value")
288 def test_radius_acct_interim_unreachable(dev, apdev):
289 """RADIUS Accounting interim update with unreachable server"""
290 params = hostapd.wpa2_eap_params(ssid="radius-acct")
291 params['acct_server_addr'] = "127.0.0.1"
292 params['acct_server_port'] = "18139"
293 params['acct_server_shared_secret'] = "radius"
294 params['radius_acct_interim_interval'] = "1"
295 hapd = hostapd.add_ap(apdev[0], params)
296 start = hapd.get_mib()
297 connect(dev[0], "radius-acct")
298 logger.info("Waiting for interium accounting updates")
301 req_s = int(start['radiusAccClientTimeouts'])
302 req_e = int(end['radiusAccClientTimeouts'])
303 if req_e < req_s + 2:
304 raise Exception("Unexpected RADIUS server acct MIB value")
306 def test_radius_acct_interim_unreachable2(dev, apdev):
307 """RADIUS Accounting interim update with unreachable server (retry)"""
308 params = hostapd.wpa2_eap_params(ssid="radius-acct")
309 params['acct_server_addr'] = "127.0.0.1"
310 params['acct_server_port'] = "18139"
311 params['acct_server_shared_secret'] = "radius"
312 # Use long enough interim update interval to allow RADIUS retransmission
313 # case (3 seconds) to trigger first.
314 params['radius_acct_interim_interval'] = "4"
315 hapd = hostapd.add_ap(apdev[0], params)
316 start = hapd.get_mib()
317 connect(dev[0], "radius-acct")
318 logger.info("Waiting for interium accounting updates")
321 req_s = int(start['radiusAccClientTimeouts'])
322 req_e = int(end['radiusAccClientTimeouts'])
323 if req_e < req_s + 2:
324 raise Exception("Unexpected RADIUS server acct MIB value")
326 def test_radius_acct_ipaddr(dev, apdev):
327 """RADIUS Accounting and Framed-IP-Address"""
329 _test_radius_acct_ipaddr(dev, apdev)
331 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
332 stderr=open('/dev/null', 'w'))
333 subprocess.call(['brctl', 'delbr', 'ap-br0'],
334 stderr=open('/dev/null', 'w'))
336 def _test_radius_acct_ipaddr(dev, apdev):
337 params = { "ssid": "radius-acct-open",
338 'acct_server_addr': "127.0.0.1",
339 'acct_server_port': "1813",
340 'acct_server_shared_secret': "radius",
344 hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
348 # For now, do not report failures due to missing kernel support
349 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
350 bssid = apdev[0]['bssid']
352 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
353 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
355 dev[0].connect("radius-acct-open", key_mgmt="NONE", scan_freq="2412")
356 addr0 = dev[0].own_addr()
358 pkt = build_dhcp_ack(dst_ll="ff:ff:ff:ff:ff:ff", src_ll=bssid,
359 ip_src="192.168.1.1", ip_dst="255.255.255.255",
360 yiaddr="192.168.1.123", chaddr=addr0)
361 if "OK" not in hapd.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii.hexlify(pkt)):
362 raise Exception("DATA_TEST_FRAME failed")
364 dev[0].request("DISCONNECT")
365 dev[0].wait_disconnected()
368 def send_and_check_reply(srv, req, code, error_cause=0):
369 reply = srv.SendPacket(req)
370 logger.debug("RADIUS response from hostapd")
371 for i in reply.keys():
372 logger.debug("%s: %s" % (i, reply[i]))
373 if reply.code != code:
374 raise Exception("Unexpected response code")
376 if 'Error-Cause' not in reply:
377 raise Exception("Missing Error-Cause")
378 if reply['Error-Cause'][0] != error_cause:
379 raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
381 def test_radius_acct_psk(dev, apdev):
382 """RADIUS Accounting - PSK"""
383 as_hapd = hostapd.Hostapd("as")
384 params = hostapd.wpa2_params(ssid="radius-acct", passphrase="12345678")
385 params['acct_server_addr'] = "127.0.0.1"
386 params['acct_server_port'] = "1813"
387 params['acct_server_shared_secret'] = "radius"
388 hapd = hostapd.add_ap(apdev[0], params)
389 dev[0].connect("radius-acct", psk="12345678", scan_freq="2412")
391 def test_radius_acct_psk_sha256(dev, apdev):
392 """RADIUS Accounting - PSK SHA256"""
393 as_hapd = hostapd.Hostapd("as")
394 params = hostapd.wpa2_params(ssid="radius-acct", passphrase="12345678")
395 params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
396 params['acct_server_addr'] = "127.0.0.1"
397 params['acct_server_port'] = "1813"
398 params['acct_server_shared_secret'] = "radius"
399 hapd = hostapd.add_ap(apdev[0], params)
400 dev[0].connect("radius-acct", key_mgmt="WPA-PSK-SHA256",
401 psk="12345678", scan_freq="2412")
403 def test_radius_acct_ft_psk(dev, apdev):
404 """RADIUS Accounting - FT-PSK"""
405 as_hapd = hostapd.Hostapd("as")
406 params = ft_params1(ssid="radius-acct", passphrase="12345678")
407 params['acct_server_addr'] = "127.0.0.1"
408 params['acct_server_port'] = "1813"
409 params['acct_server_shared_secret'] = "radius"
410 hapd = hostapd.add_ap(apdev[0], params)
411 dev[0].connect("radius-acct", key_mgmt="FT-PSK",
412 psk="12345678", scan_freq="2412")
414 def test_radius_acct_ieee8021x(dev, apdev):
415 """RADIUS Accounting - IEEE 802.1X"""
416 skip_with_fips(dev[0])
417 as_hapd = hostapd.Hostapd("as")
418 params = hostapd.radius_params()
419 params["ssid"] = "radius-acct-1x"
420 params["ieee8021x"] = "1"
421 params["wep_key_len_broadcast"] = "13"
422 params["wep_key_len_unicast"] = "13"
423 params['acct_server_addr'] = "127.0.0.1"
424 params['acct_server_port'] = "1813"
425 params['acct_server_shared_secret'] = "radius"
426 hapd = hostapd.add_ap(apdev[0], params)
427 dev[0].connect("radius-acct-1x", key_mgmt="IEEE8021X", eap="PSK",
428 identity="psk.user@example.com",
429 password_hex="0123456789abcdef0123456789abcdef",
432 def test_radius_das_disconnect(dev, apdev):
433 """RADIUS Dynamic Authorization Extensions - Disconnect"""
437 import pyrad.dictionary
440 raise HwsimSkip("No pyrad modules available")
442 params = hostapd.wpa2_eap_params(ssid="radius-das")
443 params['radius_das_port'] = "3799"
444 params['radius_das_client'] = "127.0.0.1 secret"
445 params['radius_das_require_event_timestamp'] = "1"
446 params['own_ip_addr'] = "127.0.0.1"
447 params['nas_identifier'] = "nas.example.com"
448 hapd = hostapd.add_ap(apdev[0], params)
449 connect(dev[0], "radius-das")
450 addr = dev[0].p2p_interface_addr()
451 sta = hapd.get_sta(addr)
452 id = sta['dot1xAuthSessionId']
454 dict = pyrad.dictionary.Dictionary("dictionary.radius")
456 srv = pyrad.client.Client(server="127.0.0.1", acctport=3799,
457 secret="secret", dict=dict)
461 logger.info("Disconnect-Request with incorrect secret")
462 req = radius_das.DisconnectPacket(dict=dict, secret="incorrect",
464 NAS_Identifier="localhost",
465 Event_Timestamp=int(time.time()))
468 reply = srv.SendPacket(req)
469 raise Exception("Unexpected response to Disconnect-Request")
470 except pyrad.client.Timeout:
471 logger.info("Disconnect-Request with incorrect secret properly ignored")
473 logger.info("Disconnect-Request without Event-Timestamp")
474 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
475 User_Name="psk.user@example.com")
478 reply = srv.SendPacket(req)
479 raise Exception("Unexpected response to Disconnect-Request")
480 except pyrad.client.Timeout:
481 logger.info("Disconnect-Request without Event-Timestamp properly ignored")
483 logger.info("Disconnect-Request with non-matching Event-Timestamp")
484 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
485 User_Name="psk.user@example.com",
486 Event_Timestamp=123456789)
489 reply = srv.SendPacket(req)
490 raise Exception("Unexpected response to Disconnect-Request")
491 except pyrad.client.Timeout:
492 logger.info("Disconnect-Request with non-matching Event-Timestamp properly ignored")
494 logger.info("Disconnect-Request with unsupported attribute")
495 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
498 Event_Timestamp=int(time.time()))
499 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 401)
501 logger.info("Disconnect-Request with invalid Calling-Station-Id")
502 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
504 Calling_Station_Id="foo",
505 Event_Timestamp=int(time.time()))
506 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 407)
508 logger.info("Disconnect-Request with mismatching User-Name")
509 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
511 Event_Timestamp=int(time.time()))
512 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
514 logger.info("Disconnect-Request with mismatching Calling-Station-Id")
515 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
516 Calling_Station_Id="12:34:56:78:90:aa",
517 Event_Timestamp=int(time.time()))
518 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
520 logger.info("Disconnect-Request with mismatching Acct-Session-Id")
521 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
522 Acct_Session_Id="12345678-87654321",
523 Event_Timestamp=int(time.time()))
524 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
526 logger.info("Disconnect-Request with mismatching Acct-Session-Id (len)")
527 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
528 Acct_Session_Id="12345678",
529 Event_Timestamp=int(time.time()))
530 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
532 logger.info("Disconnect-Request with mismatching Acct-Multi-Session-Id")
533 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
534 Acct_Multi_Session_Id="12345678+87654321",
535 Event_Timestamp=int(time.time()))
536 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
538 logger.info("Disconnect-Request with mismatching Acct-Multi-Session-Id (len)")
539 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
540 Acct_Multi_Session_Id="12345678",
541 Event_Timestamp=int(time.time()))
542 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
544 logger.info("Disconnect-Request with no session identification attributes")
545 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
546 Event_Timestamp=int(time.time()))
547 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 503)
549 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
551 raise Exception("Unexpected disconnection")
553 logger.info("Disconnect-Request with mismatching NAS-IP-Address")
554 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
555 NAS_IP_Address="192.168.3.4",
557 Event_Timestamp=int(time.time()))
558 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 403)
560 logger.info("Disconnect-Request with mismatching NAS-Identifier")
561 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
562 NAS_Identifier="unknown.example.com",
564 Event_Timestamp=int(time.time()))
565 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, 403)
567 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
569 raise Exception("Unexpected disconnection")
571 logger.info("Disconnect-Request with matching Acct-Session-Id")
572 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
573 NAS_IP_Address="127.0.0.1",
574 NAS_Identifier="nas.example.com",
576 Event_Timestamp=int(time.time()))
577 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
579 dev[0].wait_disconnected(timeout=10)
580 dev[0].wait_connected(timeout=10, error="Re-connection timed out")
582 logger.info("Disconnect-Request with matching Acct-Multi-Session-Id")
583 sta = hapd.get_sta(addr)
584 multi_sess_id = sta['authMultiSessionId']
585 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
586 NAS_IP_Address="127.0.0.1",
587 NAS_Identifier="nas.example.com",
588 Acct_Multi_Session_Id=multi_sess_id,
589 Event_Timestamp=int(time.time()))
590 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
592 dev[0].wait_disconnected(timeout=10)
593 dev[0].wait_connected(timeout=10, error="Re-connection timed out")
595 logger.info("Disconnect-Request with matching User-Name")
596 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
597 NAS_Identifier="nas.example.com",
598 User_Name="psk.user@example.com",
599 Event_Timestamp=int(time.time()))
600 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
602 dev[0].wait_disconnected(timeout=10)
603 dev[0].wait_connected(timeout=10, error="Re-connection timed out")
605 logger.info("Disconnect-Request with matching Calling-Station-Id")
606 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
607 NAS_IP_Address="127.0.0.1",
608 Calling_Station_Id=addr,
609 Event_Timestamp=int(time.time()))
610 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
612 dev[0].wait_disconnected(timeout=10)
613 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"])
615 raise Exception("Timeout while waiting for re-connection")
616 if "CTRL-EVENT-EAP-STARTED" not in ev:
617 raise Exception("Unexpected skipping of EAP authentication in reconnection")
618 dev[0].wait_connected(timeout=10, error="Re-connection timed out")
620 logger.info("Disconnect-Request with matching Calling-Station-Id and non-matching CUI")
621 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
622 Calling_Station_Id=addr,
623 Chargeable_User_Identity="foo@example.com",
624 Event_Timestamp=int(time.time()))
625 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, error_cause=503)
627 logger.info("Disconnect-Request with matching CUI")
628 dev[1].connect("radius-das", key_mgmt="WPA-EAP",
629 eap="GPSK", identity="gpsk-cui",
630 password="abcdefghijklmnop0123456789abcdef",
632 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
633 Chargeable_User_Identity="gpsk-chargeable-user-identity",
634 Event_Timestamp=int(time.time()))
635 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
637 dev[1].wait_disconnected(timeout=10)
638 dev[1].wait_connected(timeout=10, error="Re-connection timed out")
640 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
642 raise Exception("Unexpected disconnection")
644 connect(dev[2], "radius-das")
646 logger.info("Disconnect-Request with matching User-Name - multiple sessions matching")
647 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
648 NAS_Identifier="nas.example.com",
649 User_Name="psk.user@example.com",
650 Event_Timestamp=int(time.time()))
651 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, error_cause=508)
653 logger.info("Disconnect-Request with User-Name matching multiple sessions, Calling-Station-Id only one")
654 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
655 NAS_Identifier="nas.example.com",
656 Calling_Station_Id=addr,
657 User_Name="psk.user@example.com",
658 Event_Timestamp=int(time.time()))
659 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
661 dev[0].wait_disconnected(timeout=10)
662 dev[0].wait_connected(timeout=10, error="Re-connection timed out")
664 ev = dev[2].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
666 raise Exception("Unexpected disconnection")
668 logger.info("Disconnect-Request with matching Acct-Multi-Session-Id after disassociation")
669 sta = hapd.get_sta(addr)
670 multi_sess_id = sta['authMultiSessionId']
671 dev[0].request("DISCONNECT")
672 dev[0].wait_disconnected(timeout=10)
673 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
674 NAS_IP_Address="127.0.0.1",
675 NAS_Identifier="nas.example.com",
676 Acct_Multi_Session_Id=multi_sess_id,
677 Event_Timestamp=int(time.time()))
678 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
680 dev[0].request("RECONNECT")
681 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
683 raise Exception("Timeout on EAP start")
684 dev[0].wait_connected(timeout=15)
686 logger.info("Disconnect-Request with matching User-Name after disassociation")
687 dev[0].request("DISCONNECT")
688 dev[0].wait_disconnected(timeout=10)
689 dev[2].request("DISCONNECT")
690 dev[2].wait_disconnected(timeout=10)
691 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
692 NAS_IP_Address="127.0.0.1",
693 NAS_Identifier="nas.example.com",
694 User_Name="psk.user@example.com",
695 Event_Timestamp=int(time.time()))
696 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
698 logger.info("Disconnect-Request with matching CUI after disassociation")
699 dev[1].request("DISCONNECT")
700 dev[1].wait_disconnected(timeout=10)
701 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
702 NAS_IP_Address="127.0.0.1",
703 NAS_Identifier="nas.example.com",
704 Chargeable_User_Identity="gpsk-chargeable-user-identity",
705 Event_Timestamp=int(time.time()))
706 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
708 logger.info("Disconnect-Request with matching Calling-Station-Id after disassociation")
709 dev[0].request("RECONNECT")
710 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
712 raise Exception("Timeout on EAP start")
713 dev[0].wait_connected(timeout=15)
714 dev[0].request("DISCONNECT")
715 dev[0].wait_disconnected(timeout=10)
716 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
717 NAS_IP_Address="127.0.0.1",
718 NAS_Identifier="nas.example.com",
719 Calling_Station_Id=addr,
720 Event_Timestamp=int(time.time()))
721 send_and_check_reply(srv, req, pyrad.packet.DisconnectACK)
723 logger.info("Disconnect-Request with mismatching Calling-Station-Id after disassociation")
724 req = radius_das.DisconnectPacket(dict=dict, secret="secret",
725 NAS_IP_Address="127.0.0.1",
726 NAS_Identifier="nas.example.com",
727 Calling_Station_Id=addr,
728 Event_Timestamp=int(time.time()))
729 send_and_check_reply(srv, req, pyrad.packet.DisconnectNAK, error_cause=503)
731 def test_radius_das_coa(dev, apdev):
732 """RADIUS Dynamic Authorization Extensions - CoA"""
736 import pyrad.dictionary
739 raise HwsimSkip("No pyrad modules available")
741 params = hostapd.wpa2_eap_params(ssid="radius-das")
742 params['radius_das_port'] = "3799"
743 params['radius_das_client'] = "127.0.0.1 secret"
744 params['radius_das_require_event_timestamp'] = "1"
745 hapd = hostapd.add_ap(apdev[0], params)
746 connect(dev[0], "radius-das")
747 addr = dev[0].p2p_interface_addr()
748 sta = hapd.get_sta(addr)
749 id = sta['dot1xAuthSessionId']
751 dict = pyrad.dictionary.Dictionary("dictionary.radius")
753 srv = pyrad.client.Client(server="127.0.0.1", acctport=3799,
754 secret="secret", dict=dict)
758 # hostapd does not currently support CoA-Request, so NAK is expected
759 logger.info("CoA-Request with matching Acct-Session-Id")
760 req = radius_das.CoAPacket(dict=dict, secret="secret",
762 Event_Timestamp=int(time.time()))
763 send_and_check_reply(srv, req, pyrad.packet.CoANAK, error_cause=405)
765 def test_radius_ipv6(dev, apdev):
766 """RADIUS connection over IPv6"""
768 params['ssid'] = 'as'
769 params['beacon_int'] = '2000'
770 params['radius_server_clients'] = 'auth_serv/radius_clients_ipv6.conf'
771 params['radius_server_ipv6'] = '1'
772 params['radius_server_auth_port'] = '18129'
773 params['radius_server_acct_port'] = '18139'
774 params['eap_server'] = '1'
775 params['eap_user_file'] = 'auth_serv/eap_user.conf'
776 params['ca_cert'] = 'auth_serv/ca.pem'
777 params['server_cert'] = 'auth_serv/server.pem'
778 params['private_key'] = 'auth_serv/server.key'
779 hostapd.add_ap(apdev[1], params)
781 params = hostapd.wpa2_eap_params(ssid="radius-ipv6")
782 params['auth_server_addr'] = "::0"
783 params['auth_server_port'] = "18129"
784 params['acct_server_addr'] = "::0"
785 params['acct_server_port'] = "18139"
786 params['acct_server_shared_secret'] = "radius"
787 params['own_ip_addr'] = "::0"
788 hostapd.add_ap(apdev[0], params)
789 connect(dev[0], "radius-ipv6")
791 def test_radius_macacl(dev, apdev):
793 params = hostapd.radius_params()
794 params["ssid"] = "radius"
795 params["macaddr_acl"] = "2"
796 hostapd.add_ap(apdev[0], params)
797 dev[0].connect("radius", key_mgmt="NONE", scan_freq="2412")
799 def test_radius_macacl_acct(dev, apdev):
800 """RADIUS MAC ACL and accounting enabled"""
801 params = hostapd.radius_params()
802 params["ssid"] = "radius"
803 params["macaddr_acl"] = "2"
804 params['acct_server_addr'] = "127.0.0.1"
805 params['acct_server_port'] = "1813"
806 params['acct_server_shared_secret'] = "radius"
807 hostapd.add_ap(apdev[0], params)
808 dev[0].connect("radius", key_mgmt="NONE", scan_freq="2412")
809 dev[1].connect("radius", key_mgmt="NONE", scan_freq="2412")
810 dev[1].request("DISCONNECT")
811 dev[1].wait_disconnected()
812 dev[1].request("RECONNECT")
814 def test_radius_failover(dev, apdev):
815 """RADIUS Authentication and Accounting server failover"""
816 subprocess.call(['ip', 'ro', 'replace', '192.168.213.17', 'dev', 'lo'])
817 as_hapd = hostapd.Hostapd("as")
818 as_mib_start = as_hapd.get_mib(param="radius_server")
819 params = hostapd.wpa2_eap_params(ssid="radius-failover")
820 params["auth_server_addr"] = "192.168.213.17"
821 params["auth_server_port"] = "1812"
822 params["auth_server_shared_secret"] = "testing"
823 params['acct_server_addr'] = "192.168.213.17"
824 params['acct_server_port'] = "1813"
825 params['acct_server_shared_secret'] = "testing"
826 params['radius_retry_primary_interval'] = "20"
827 hapd = hostapd.add_ap(apdev[0], params, no_enable=True)
828 hapd.set("auth_server_addr", "127.0.0.1")
829 hapd.set("auth_server_port", "1812")
830 hapd.set("auth_server_shared_secret", "radius")
831 hapd.set('acct_server_addr', "127.0.0.1")
832 hapd.set('acct_server_port', "1813")
833 hapd.set('acct_server_shared_secret', "radius")
835 ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=30)
837 raise Exception("AP startup timed out")
838 if "AP-ENABLED" not in ev:
839 raise Exception("AP startup failed")
840 start = os.times()[4]
843 subprocess.call(['ip', 'ro', 'replace', 'prohibit', '192.168.213.17'])
844 dev[0].request("SET EAPOL::authPeriod 5")
845 connect(dev[0], "radius-failover", wait_connect=False)
846 dev[0].wait_connected(timeout=20)
848 dev[0].request("SET EAPOL::authPeriod 30")
849 subprocess.call(['ip', 'ro', 'del', '192.168.213.17'])
851 as_mib_end = as_hapd.get_mib(param="radius_server")
852 req_s = int(as_mib_start['radiusAccServTotalRequests'])
853 req_e = int(as_mib_end['radiusAccServTotalRequests'])
855 raise Exception("Unexpected RADIUS server acct MIB value")
859 subprocess.call(['ip', 'ro', 'replace', 'prohibit', '192.168.213.17'])
860 dev[1].request("SET EAPOL::authPeriod 5")
862 time.sleep(21 - (end - start))
863 connect(dev[1], "radius-failover", wait_connect=False)
864 dev[1].wait_connected(timeout=20)
866 dev[1].request("SET EAPOL::authPeriod 30")
867 subprocess.call(['ip', 'ro', 'del', '192.168.213.17'])
869 def run_pyrad_server(srv, t_events):
870 srv.RunWithStop(t_events)
872 def test_radius_protocol(dev, apdev):
873 """RADIUS Authentication protocol tests with a fake server"""
877 import pyrad.dictionary
879 raise HwsimSkip("No pyrad modules available")
881 class TestServer(pyrad.server.Server):
882 def _HandleAuthPacket(self, pkt):
883 pyrad.server.Server._HandleAuthPacket(self, pkt)
884 logger.info("Received authentication request")
885 reply = self.CreateReplyPacket(pkt)
886 reply.code = pyrad.packet.AccessAccept
887 if self.t_events['msg_auth'].is_set():
888 logger.info("Add Message-Authenticator")
889 if self.t_events['wrong_secret'].is_set():
890 logger.info("Use incorrect RADIUS shared secret")
894 hmac_obj = hmac.new(pw)
895 hmac_obj.update(struct.pack("B", reply.code))
896 hmac_obj.update(struct.pack("B", reply.id))
899 reply.AddAttribute("Message-Authenticator",
900 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
901 attrs = reply._PktEncodeAttributes()
904 flen = 4 + 16 + len(attrs)
905 hmac_obj.update(struct.pack(">H", flen))
906 hmac_obj.update(pkt.authenticator)
907 hmac_obj.update(attrs)
908 if self.t_events['double_msg_auth'].is_set():
909 logger.info("Include two Message-Authenticator attributes")
912 reply.AddAttribute("Message-Authenticator", hmac_obj.digest())
913 self.SendReplyPacket(pkt.fd, reply)
915 def RunWithStop(self, t_events):
916 self._poll = select.poll()
918 self._PrepareSockets()
919 self.t_events = t_events
921 while not t_events['stop'].is_set():
922 for (fd, event) in self._poll.poll(1000):
923 if event == select.POLLIN:
925 fdo = self._fdmap[fd]
926 self._ProcessInput(fdo)
927 except ServerPacketError as err:
928 logger.info("pyrad server dropping packet: " + str(err))
929 except pyrad.packet.PacketError as err:
930 logger.info("pyrad server received invalid packet: " + str(err))
932 logger.error("Unexpected event in pyrad server main loop")
934 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"),
935 authport=18138, acctport=18139)
936 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1",
939 srv.BindToAddress("")
941 t_events['stop'] = threading.Event()
942 t_events['msg_auth'] = threading.Event()
943 t_events['wrong_secret'] = threading.Event()
944 t_events['double_msg_auth'] = threading.Event()
945 t = threading.Thread(target=run_pyrad_server, args=(srv, t_events))
949 params = hostapd.wpa2_eap_params(ssid="radius-test")
950 params['auth_server_port'] = "18138"
951 hapd = hostapd.add_ap(apdev[0], params)
952 connect(dev[0], "radius-test", wait_connect=False)
953 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
955 raise Exception("Timeout on EAP start")
957 dev[0].request("REMOVE_NETWORK all")
959 dev[0].dump_monitor()
960 t_events['msg_auth'].set()
961 t_events['wrong_secret'].set()
962 connect(dev[0], "radius-test", wait_connect=False)
964 dev[0].request("REMOVE_NETWORK all")
966 dev[0].dump_monitor()
967 t_events['wrong_secret'].clear()
968 connect(dev[0], "radius-test", wait_connect=False)
970 dev[0].request("REMOVE_NETWORK all")
972 dev[0].dump_monitor()
973 t_events['double_msg_auth'].set()
974 connect(dev[0], "radius-test", wait_connect=False)
977 t_events['stop'].set()
980 def test_radius_psk(dev, apdev):
981 """WPA2 with PSK from RADIUS"""
985 import pyrad.dictionary
987 raise HwsimSkip("No pyrad modules available")
989 class TestServer(pyrad.server.Server):
990 def _HandleAuthPacket(self, pkt):
991 pyrad.server.Server._HandleAuthPacket(self, pkt)
992 logger.info("Received authentication request")
993 reply = self.CreateReplyPacket(pkt)
994 reply.code = pyrad.packet.AccessAccept
996 secret = reply.secret
997 if self.t_events['long'].is_set():
998 p = b'\x10' + "0123456789abcdef" + 15 * b'\x00'
999 b = hashlib.md5(secret + pkt.authenticator + a).digest()
1000 pp = bytearray(p[0:16])
1002 cc = bytearray(pp[i] ^ bb[i] for i in range(len(bb)))
1004 b = hashlib.md5(reply.secret + bytes(cc)).digest()
1005 pp = bytearray(p[16:32])
1007 cc += bytearray(pp[i] ^ bb[i] for i in range(len(bb)))
1009 data = '\x00' + a + bytes(cc)
1011 p = b'\x08' + "12345678" + 7 * b'\x00'
1012 b = hashlib.md5(secret + pkt.authenticator + a).digest()
1015 cc = bytearray(pp[i] ^ bb[i] for i in range(len(bb)))
1016 data = '\x00' + a + bytes(cc)
1017 reply.AddAttribute("Tunnel-Password", data)
1018 self.SendReplyPacket(pkt.fd, reply)
1020 def RunWithStop(self, t_events):
1021 self._poll = select.poll()
1023 self._PrepareSockets()
1024 self.t_events = t_events
1026 while not t_events['stop'].is_set():
1027 for (fd, event) in self._poll.poll(1000):
1028 if event == select.POLLIN:
1030 fdo = self._fdmap[fd]
1031 self._ProcessInput(fdo)
1032 except ServerPacketError as err:
1033 logger.info("pyrad server dropping packet: " + str(err))
1034 except pyrad.packet.PacketError as err:
1035 logger.info("pyrad server received invalid packet: " + str(err))
1037 logger.error("Unexpected event in pyrad server main loop")
1039 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"),
1040 authport=18138, acctport=18139)
1041 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1",
1044 srv.BindToAddress("")
1046 t_events['stop'] = threading.Event()
1047 t_events['long'] = threading.Event()
1048 t = threading.Thread(target=run_pyrad_server, args=(srv, t_events))
1052 ssid = "test-wpa2-psk"
1053 params = hostapd.radius_params()
1054 params['ssid'] = ssid
1056 params["wpa_key_mgmt"] = "WPA-PSK"
1057 params["rsn_pairwise"] = "CCMP"
1058 params['macaddr_acl'] = '2'
1059 params['wpa_psk_radius'] = '2'
1060 params['auth_server_port'] = "18138"
1061 hapd = hostapd.add_ap(apdev[0], params)
1062 dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1063 t_events['long'].set()
1064 dev[1].connect(ssid, psk="0123456789abcdef", scan_freq="2412")
1066 t_events['stop'].set()
1069 def test_radius_auth_force_client_addr(dev, apdev):
1070 """RADIUS client address specified"""
1071 params = hostapd.wpa2_eap_params(ssid="radius-auth")
1072 params['radius_client_addr'] = "127.0.0.1"
1073 hapd = hostapd.add_ap(apdev[0], params)
1074 connect(dev[0], "radius-auth")
1076 def test_radius_auth_force_invalid_client_addr(dev, apdev):
1077 """RADIUS client address specified and invalid address"""
1078 params = hostapd.wpa2_eap_params(ssid="radius-auth")
1079 #params['radius_client_addr'] = "10.11.12.14"
1080 params['radius_client_addr'] = "1::2"
1081 hapd = hostapd.add_ap(apdev[0], params)
1082 connect(dev[0], "radius-auth", wait_connect=False)
1083 ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"])
1085 raise Exception("Timeout on EAP start")
1086 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
1088 raise Exception("Unexpected connection")
1090 def add_message_auth(req):
1091 req.authenticator = req.CreateAuthenticator()
1092 hmac_obj = hmac.new(req.secret)
1093 hmac_obj.update(struct.pack("B", req.code))
1094 hmac_obj.update(struct.pack("B", req.id))
1096 # request attributes
1097 req.AddAttribute("Message-Authenticator",
1098 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
1099 attrs = req._PktEncodeAttributes()
1102 flen = 4 + 16 + len(attrs)
1103 hmac_obj.update(struct.pack(">H", flen))
1104 hmac_obj.update(req.authenticator)
1105 hmac_obj.update(attrs)
1107 req.AddAttribute("Message-Authenticator", hmac_obj.digest())
1109 def test_radius_server_failures(dev, apdev):
1110 """RADIUS server failure cases"""
1114 import pyrad.dictionary
1116 raise HwsimSkip("No pyrad modules available")
1118 dict = pyrad.dictionary.Dictionary("dictionary.radius")
1119 client = pyrad.client.Client(server="127.0.0.1", authport=1812,
1120 secret="radius", dict=dict)
1125 req = client.CreateAuthPacket(code=pyrad.packet.AccessRequest,
1127 req['State'] = 'foo-state'
1128 add_message_auth(req)
1129 reply = client.SendPacket(req)
1130 if reply.code != pyrad.packet.AccessReject:
1131 raise Exception("Unexpected RADIUS response code " + str(reply.code))
1134 req = client.CreateAuthPacket(code=pyrad.packet.AccessRequest,
1136 add_message_auth(req)
1138 reply = client.SendPacket(req)
1139 raise Exception("Unexpected response")
1140 except pyrad.client.Timeout:
1143 def test_ap_vlan_wpa2_psk_radius_required(dev, apdev):
1144 """AP VLAN with WPA2-PSK and RADIUS attributes required"""
1148 import pyrad.dictionary
1150 raise HwsimSkip("No pyrad modules available")
1152 class TestServer(pyrad.server.Server):
1153 def _HandleAuthPacket(self, pkt):
1154 pyrad.server.Server._HandleAuthPacket(self, pkt)
1155 logger.info("Received authentication request")
1156 reply = self.CreateReplyPacket(pkt)
1157 reply.code = pyrad.packet.AccessAccept
1158 secret = reply.secret
1159 if self.t_events['extra'].is_set():
1160 reply.AddAttribute("Chargeable-User-Identity", "test-cui")
1161 reply.AddAttribute("User-Name", "test-user")
1162 if self.t_events['long'].is_set():
1163 reply.AddAttribute("Tunnel-Type", 13)
1164 reply.AddAttribute("Tunnel-Medium-Type", 6)
1165 reply.AddAttribute("Tunnel-Private-Group-ID", "1")
1166 self.SendReplyPacket(pkt.fd, reply)
1168 def RunWithStop(self, t_events):
1169 self._poll = select.poll()
1171 self._PrepareSockets()
1172 self.t_events = t_events
1174 while not t_events['stop'].is_set():
1175 for (fd, event) in self._poll.poll(1000):
1176 if event == select.POLLIN:
1178 fdo = self._fdmap[fd]
1179 self._ProcessInput(fdo)
1180 except ServerPacketError as err:
1181 logger.info("pyrad server dropping packet: " + str(err))
1182 except pyrad.packet.PacketError as err:
1183 logger.info("pyrad server received invalid packet: " + str(err))
1185 logger.error("Unexpected event in pyrad server main loop")
1187 srv = TestServer(dict=pyrad.dictionary.Dictionary("dictionary.radius"),
1188 authport=18138, acctport=18139)
1189 srv.hosts["127.0.0.1"] = pyrad.server.RemoteHost("127.0.0.1",
1192 srv.BindToAddress("")
1194 t_events['stop'] = threading.Event()
1195 t_events['long'] = threading.Event()
1196 t_events['extra'] = threading.Event()
1197 t = threading.Thread(target=run_pyrad_server, args=(srv, t_events))
1201 ssid = "test-wpa2-psk"
1202 params = hostapd.radius_params()
1203 params['ssid'] = ssid
1205 params["wpa_key_mgmt"] = "WPA-PSK"
1206 params["rsn_pairwise"] = "CCMP"
1207 params['macaddr_acl'] = '2'
1208 params['dynamic_vlan'] = "2"
1209 params['wpa_passphrase'] = '0123456789abcdefghi'
1210 params['auth_server_port'] = "18138"
1211 hapd = hostapd.add_ap(apdev[0], params)
1213 logger.info("connecting without VLAN")
1214 dev[0].connect(ssid, psk="0123456789abcdefghi", scan_freq="2412",
1216 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1217 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=20)
1219 raise Exception("Timeout on connection attempt")
1220 if "CTRL-EVENT-CONNECTED" in ev:
1221 raise Exception("Unexpected success without vlan parameters")
1222 logger.info("connecting without VLAN failed as expected")
1224 logger.info("connecting without VLAN (CUI/User-Name)")
1225 t_events['extra'].set()
1226 dev[1].connect(ssid, psk="0123456789abcdefghi", scan_freq="2412",
1228 ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED",
1229 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=20)
1231 raise Exception("Timeout on connection attempt")
1232 if "CTRL-EVENT-CONNECTED" in ev:
1233 raise Exception("Unexpected success without vlan parameters(2)")
1234 logger.info("connecting without VLAN failed as expected(2)")
1235 t_events['extra'].clear()
1237 t_events['long'].set()
1238 logger.info("connecting with VLAN")
1239 dev[2].connect(ssid, psk="0123456789abcdefghi", scan_freq="2412",
1241 ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED",
1242 "CTRL-EVENT-SSID-TEMP-DISABLED"], timeout=20)
1244 raise Exception("Timeout on connection attempt")
1245 if "CTRL-EVENT-SSID-TEMP-DISABLED" in ev:
1246 raise Exception("Unexpected failure with vlan parameters")
1247 logger.info("connecting with VLAN succeeded as expected")
1249 t_events['stop'].set()