test_radius.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. # RADIUS tests
  2. # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. import logging
  7. logger = logging.getLogger()
  8. import subprocess
  9. import time
  10. import hostapd
  11. def connect(dev, ssid, wait_connect=True):
  12. dev.connect(ssid, key_mgmt="WPA-EAP", scan_freq="2412",
  13. eap="PSK", identity="psk.user@example.com",
  14. password_hex="0123456789abcdef0123456789abcdef",
  15. wait_connect=wait_connect)
  16. def test_radius_auth_unreachable(dev, apdev):
  17. """RADIUS Authentication server unreachable"""
  18. params = hostapd.wpa2_eap_params(ssid="radius-auth")
  19. params['auth_server_port'] = "18139"
  20. hostapd.add_ap(apdev[0]['ifname'], params)
  21. hapd = hostapd.Hostapd(apdev[0]['ifname'])
  22. connect(dev[0], "radius-auth", wait_connect=False)
  23. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"])
  24. if ev is None:
  25. raise Exception("Timeout on EAP start")
  26. logger.info("Checking for RADIUS retries")
  27. time.sleep(4)
  28. mib = hapd.get_mib()
  29. if "radiusAuthClientAccessRequests" not in mib:
  30. raise Exception("Missing MIB fields")
  31. if int(mib["radiusAuthClientAccessRetransmissions"]) < 1:
  32. raise Exception("Missing RADIUS Authentication retransmission")
  33. if int(mib["radiusAuthClientPendingRequests"]) < 1:
  34. raise Exception("Missing pending RADIUS Authentication request")
  35. def test_radius_auth_unreachable2(dev, apdev):
  36. """RADIUS Authentication server unreachable (2)"""
  37. subprocess.call(['sudo', 'ip', 'ro', 'replace', '192.168.213.17', 'dev',
  38. 'lo'])
  39. params = hostapd.wpa2_eap_params(ssid="radius-auth")
  40. params['auth_server_addr'] = "192.168.213.17"
  41. params['auth_server_port'] = "18139"
  42. hostapd.add_ap(apdev[0]['ifname'], params)
  43. hapd = hostapd.Hostapd(apdev[0]['ifname'])
  44. subprocess.call(['sudo', 'ip', 'ro', 'del', '192.168.213.17', 'dev', 'lo'])
  45. connect(dev[0], "radius-auth", wait_connect=False)
  46. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"])
  47. if ev is None:
  48. raise Exception("Timeout on EAP start")
  49. logger.info("Checking for RADIUS retries")
  50. time.sleep(4)
  51. mib = hapd.get_mib()
  52. if "radiusAuthClientAccessRequests" not in mib:
  53. raise Exception("Missing MIB fields")
  54. if int(mib["radiusAuthClientAccessRetransmissions"]) < 1:
  55. raise Exception("Missing RADIUS Authentication retransmission")
  56. def test_radius_acct_unreachable(dev, apdev):
  57. """RADIUS Accounting server unreachable"""
  58. params = hostapd.wpa2_eap_params(ssid="radius-acct")
  59. params['acct_server_addr'] = "127.0.0.1"
  60. params['acct_server_port'] = "18139"
  61. params['acct_server_shared_secret'] = "radius"
  62. hostapd.add_ap(apdev[0]['ifname'], params)
  63. hapd = hostapd.Hostapd(apdev[0]['ifname'])
  64. connect(dev[0], "radius-acct")
  65. logger.info("Checking for RADIUS retries")
  66. time.sleep(4)
  67. mib = hapd.get_mib()
  68. if "radiusAccClientRetransmissions" not in mib:
  69. raise Exception("Missing MIB fields")
  70. if int(mib["radiusAccClientRetransmissions"]) < 2:
  71. raise Exception("Missing RADIUS Accounting retransmissions")
  72. if int(mib["radiusAccClientPendingRequests"]) < 2:
  73. raise Exception("Missing pending RADIUS Accounting requests")
  74. def test_radius_acct_unreachable2(dev, apdev):
  75. """RADIUS Accounting server unreachable(2)"""
  76. subprocess.call(['sudo', 'ip', 'ro', 'replace', '192.168.213.17', 'dev',
  77. 'lo'])
  78. params = hostapd.wpa2_eap_params(ssid="radius-acct")
  79. params['acct_server_addr'] = "192.168.213.17"
  80. params['acct_server_port'] = "18139"
  81. params['acct_server_shared_secret'] = "radius"
  82. hostapd.add_ap(apdev[0]['ifname'], params)
  83. hapd = hostapd.Hostapd(apdev[0]['ifname'])
  84. subprocess.call(['sudo', 'ip', 'ro', 'del', '192.168.213.17', 'dev', 'lo'])
  85. connect(dev[0], "radius-acct")
  86. logger.info("Checking for RADIUS retries")
  87. time.sleep(4)
  88. mib = hapd.get_mib()
  89. if "radiusAccClientRetransmissions" not in mib:
  90. raise Exception("Missing MIB fields")
  91. if int(mib["radiusAccClientRetransmissions"]) < 1 and int(mib["radiusAccClientPendingRequests"]) < 1:
  92. raise Exception("Missing pending or retransmitted RADIUS Accounting requests")
  93. def test_radius_acct(dev, apdev):
  94. """RADIUS Accounting"""
  95. as_hapd = hostapd.Hostapd("as")
  96. as_mib_start = as_hapd.get_mib(param="radius_server")
  97. params = hostapd.wpa2_eap_params(ssid="radius-acct")
  98. params['acct_server_addr'] = "127.0.0.1"
  99. params['acct_server_port'] = "1813"
  100. params['acct_server_shared_secret'] = "radius"
  101. params['radius_auth_req_attr'] = [ "126:s:Operator", "77:s:testing" ]
  102. params['radius_acct_req_attr'] = [ "126:s:Operator", "77:s:testing" ]
  103. hostapd.add_ap(apdev[0]['ifname'], params)
  104. hapd = hostapd.Hostapd(apdev[0]['ifname'])
  105. connect(dev[0], "radius-acct")
  106. dev[1].connect("radius-acct", key_mgmt="WPA-EAP", scan_freq="2412",
  107. eap="PAX", identity="test-class",
  108. password_hex="0123456789abcdef0123456789abcdef")
  109. dev[2].connect("radius-acct", key_mgmt="WPA-EAP",
  110. eap="GPSK", identity="gpsk-cui",
  111. password="abcdefghijklmnop0123456789abcdef",
  112. scan_freq="2412")
  113. logger.info("Checking for RADIUS counters")
  114. count = 0
  115. while True:
  116. mib = hapd.get_mib()
  117. if int(mib['radiusAccClientResponses']) >= 3:
  118. break
  119. time.sleep(0.1)
  120. count += 1
  121. if count > 10:
  122. raise Exception("Did not receive Accounting-Response packets")
  123. if int(mib['radiusAccClientRetransmissions']) > 0:
  124. raise Exception("Unexpected Accounting-Request retransmission")
  125. as_mib_end = as_hapd.get_mib(param="radius_server")
  126. req_s = int(as_mib_start['radiusAccServTotalRequests'])
  127. req_e = int(as_mib_end['radiusAccServTotalRequests'])
  128. if req_e < req_s + 2:
  129. raise Exception("Unexpected RADIUS server acct MIB value")
  130. acc_s = int(as_mib_start['radiusAuthServAccessAccepts'])
  131. acc_e = int(as_mib_end['radiusAuthServAccessAccepts'])
  132. if acc_e < acc_s + 1:
  133. raise Exception("Unexpected RADIUS server auth MIB value")
  134. def test_radius_acct_interim(dev, apdev):
  135. """RADIUS Accounting interim update"""
  136. as_hapd = hostapd.Hostapd("as")
  137. params = hostapd.wpa2_eap_params(ssid="radius-acct")
  138. params['acct_server_addr'] = "127.0.0.1"
  139. params['acct_server_port'] = "1813"
  140. params['acct_server_shared_secret'] = "radius"
  141. params['radius_acct_interim_interval'] = "1"
  142. hostapd.add_ap(apdev[0]['ifname'], params)
  143. hapd = hostapd.Hostapd(apdev[0]['ifname'])
  144. connect(dev[0], "radius-acct")
  145. logger.info("Checking for RADIUS counters")
  146. as_mib_start = as_hapd.get_mib(param="radius_server")
  147. time.sleep(3.1)
  148. as_mib_end = as_hapd.get_mib(param="radius_server")
  149. req_s = int(as_mib_start['radiusAccServTotalRequests'])
  150. req_e = int(as_mib_end['radiusAccServTotalRequests'])
  151. if req_e < req_s + 3:
  152. raise Exception("Unexpected RADIUS server acct MIB value")
  153. def test_radius_das_disconnect(dev, apdev):
  154. """RADIUS Dynamic Authorization Extensions - Disconnect"""
  155. try:
  156. import pyrad.client
  157. import pyrad.packet
  158. import pyrad.dictionary
  159. import radius_das
  160. except ImportError:
  161. return "skip"
  162. params = hostapd.wpa2_eap_params(ssid="radius-das")
  163. params['radius_das_port'] = "3799"
  164. params['radius_das_client'] = "127.0.0.1 secret"
  165. params['radius_das_require_event_timestamp'] = "1"
  166. params['own_ip_addr'] = "127.0.0.1"
  167. params['nas_identifier'] = "nas.example.com"
  168. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  169. connect(dev[0], "radius-das")
  170. addr = dev[0].p2p_interface_addr()
  171. sta = hapd.get_sta(addr)
  172. id = sta['dot1xAuthSessionId']
  173. dict = pyrad.dictionary.Dictionary("dictionary.radius")
  174. srv = pyrad.client.Client(server="127.0.0.1", acctport=3799,
  175. secret="secret", dict=dict)
  176. srv.retries = 1
  177. srv.timeout = 1
  178. logger.info("Disconnect-Request with incorrect secret")
  179. req = radius_das.DisconnectPacket(dict=dict, secret="incorrect",
  180. User_Name="foo",
  181. NAS_Identifier="localhost",
  182. Event_Timestamp=int(time.time()))
  183. logger.debug(req)
  184. try:
  185. reply = srv.SendPacket(req)
  186. raise Exception("Unexpected response to Disconnect-Request")
  187. except pyrad.client.Timeout:
  188. logger.info("Disconnect-Request with incorrect secret properly ignored")
  189. logger.info("Disconnect-Request without Event-Timestamp")
  190. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  191. User_Name="psk.user@example.com")
  192. logger.debug(req)
  193. try:
  194. reply = srv.SendPacket(req)
  195. raise Exception("Unexpected response to Disconnect-Request")
  196. except pyrad.client.Timeout:
  197. logger.info("Disconnect-Request without Event-Timestamp properly ignored")
  198. logger.info("Disconnect-Request with non-matching Event-Timestamp")
  199. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  200. User_Name="psk.user@example.com",
  201. Event_Timestamp=123456789)
  202. logger.debug(req)
  203. try:
  204. reply = srv.SendPacket(req)
  205. raise Exception("Unexpected response to Disconnect-Request")
  206. except pyrad.client.Timeout:
  207. logger.info("Disconnect-Request with non-matching Event-Timestamp properly ignored")
  208. logger.info("Disconnect-Request with unsupported attribute")
  209. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  210. User_Name="foo",
  211. User_Password="foo",
  212. Event_Timestamp=int(time.time()))
  213. reply = srv.SendPacket(req)
  214. logger.debug("RADIUS response from hostapd")
  215. for i in reply.keys():
  216. logger.debug("%s: %s" % (i, reply[i]))
  217. if reply.code != pyrad.packet.DisconnectNAK:
  218. raise Exception("Unexpected response code")
  219. if 'Error-Cause' not in reply:
  220. raise Exception("Missing Error-Cause")
  221. if reply['Error-Cause'][0] != 401:
  222. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  223. logger.info("Disconnect-Request with invalid Calling-Station-Id")
  224. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  225. User_Name="foo",
  226. Calling_Station_Id="foo",
  227. Event_Timestamp=int(time.time()))
  228. reply = srv.SendPacket(req)
  229. logger.debug("RADIUS response from hostapd")
  230. for i in reply.keys():
  231. logger.debug("%s: %s" % (i, reply[i]))
  232. if reply.code != pyrad.packet.DisconnectNAK:
  233. raise Exception("Unexpected response code")
  234. if 'Error-Cause' not in reply:
  235. raise Exception("Missing Error-Cause")
  236. if reply['Error-Cause'][0] != 407:
  237. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  238. logger.info("Disconnect-Request with mismatching User-Name")
  239. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  240. User_Name="foo",
  241. Event_Timestamp=int(time.time()))
  242. reply = srv.SendPacket(req)
  243. logger.debug("RADIUS response from hostapd")
  244. for i in reply.keys():
  245. logger.debug("%s: %s" % (i, reply[i]))
  246. if reply.code != pyrad.packet.DisconnectNAK:
  247. raise Exception("Unexpected response code")
  248. if 'Error-Cause' not in reply:
  249. raise Exception("Missing Error-Cause")
  250. if reply['Error-Cause'][0] != 503:
  251. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  252. logger.info("Disconnect-Request with mismatching Calling-Station-Id")
  253. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  254. Calling_Station_Id="12:34:56:78:90:aa",
  255. Event_Timestamp=int(time.time()))
  256. reply = srv.SendPacket(req)
  257. logger.debug("RADIUS response from hostapd")
  258. for i in reply.keys():
  259. logger.debug("%s: %s" % (i, reply[i]))
  260. if reply.code != pyrad.packet.DisconnectNAK:
  261. raise Exception("Unexpected response code")
  262. if 'Error-Cause' not in reply:
  263. raise Exception("Missing Error-Cause")
  264. if reply['Error-Cause'][0] != 503:
  265. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  266. logger.info("Disconnect-Request with mismatching Acct-Session-Id")
  267. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  268. Acct_Session_Id="12345678-87654321",
  269. Event_Timestamp=int(time.time()))
  270. reply = srv.SendPacket(req)
  271. logger.debug("RADIUS response from hostapd")
  272. for i in reply.keys():
  273. logger.debug("%s: %s" % (i, reply[i]))
  274. if reply.code != pyrad.packet.DisconnectNAK:
  275. raise Exception("Unexpected response code")
  276. if 'Error-Cause' not in reply:
  277. raise Exception("Missing Error-Cause")
  278. if reply['Error-Cause'][0] != 503:
  279. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  280. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
  281. if ev is not None:
  282. raise Exception("Unexpected disconnection")
  283. logger.info("Disconnect-Request with mismatching NAS-IP-Address")
  284. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  285. NAS_IP_Address="192.168.3.4",
  286. Acct_Session_Id=id,
  287. Event_Timestamp=int(time.time()))
  288. reply = srv.SendPacket(req)
  289. logger.debug("RADIUS response from hostapd")
  290. for i in reply.keys():
  291. logger.debug("%s: %s" % (i, reply[i]))
  292. if reply.code != pyrad.packet.DisconnectNAK:
  293. raise Exception("Unexpected response code")
  294. if 'Error-Cause' not in reply:
  295. raise Exception("Missing Error-Cause")
  296. if reply['Error-Cause'][0] != 403:
  297. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  298. logger.info("Disconnect-Request with mismatching NAS-Identifier")
  299. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  300. NAS_Identifier="unknown.example.com",
  301. Acct_Session_Id=id,
  302. Event_Timestamp=int(time.time()))
  303. reply = srv.SendPacket(req)
  304. logger.debug("RADIUS response from hostapd")
  305. for i in reply.keys():
  306. logger.debug("%s: %s" % (i, reply[i]))
  307. if reply.code != pyrad.packet.DisconnectNAK:
  308. raise Exception("Unexpected response code")
  309. if 'Error-Cause' not in reply:
  310. raise Exception("Missing Error-Cause")
  311. if reply['Error-Cause'][0] != 403:
  312. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  313. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
  314. if ev is not None:
  315. raise Exception("Unexpected disconnection")
  316. logger.info("Disconnect-Request with matching Acct-Session-Id")
  317. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  318. NAS_IP_Address="127.0.0.1",
  319. NAS_Identifier="nas.example.com",
  320. Acct_Session_Id=id,
  321. Event_Timestamp=int(time.time()))
  322. reply = srv.SendPacket(req)
  323. logger.debug("RADIUS response from hostapd")
  324. for i in reply.keys():
  325. logger.debug("%s: %s" % (i, reply[i]))
  326. if reply.code != pyrad.packet.DisconnectACK:
  327. raise Exception("Unexpected response code")
  328. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
  329. if ev is None:
  330. raise Exception("Timeout while waiting for disconnection")
  331. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"])
  332. if ev is None:
  333. raise Exception("Timeout while waiting for re-connection")
  334. logger.info("Disconnect-Request with matching User-Name")
  335. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  336. NAS_Identifier="nas.example.com",
  337. User_Name="psk.user@example.com",
  338. Event_Timestamp=int(time.time()))
  339. reply = srv.SendPacket(req)
  340. logger.debug("RADIUS response from hostapd")
  341. for i in reply.keys():
  342. logger.debug("%s: %s" % (i, reply[i]))
  343. if reply.code != pyrad.packet.DisconnectACK:
  344. raise Exception("Unexpected response code")
  345. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
  346. if ev is None:
  347. raise Exception("Timeout while waiting for disconnection")
  348. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"])
  349. if ev is None:
  350. raise Exception("Timeout while waiting for re-connection")
  351. logger.info("Disconnect-Request with matching Calling-Station-Id")
  352. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  353. NAS_IP_Address="127.0.0.1",
  354. Calling_Station_Id=addr,
  355. Event_Timestamp=int(time.time()))
  356. reply = srv.SendPacket(req)
  357. logger.debug("RADIUS response from hostapd")
  358. for i in reply.keys():
  359. logger.debug("%s: %s" % (i, reply[i]))
  360. if reply.code != pyrad.packet.DisconnectACK:
  361. raise Exception("Unexpected response code")
  362. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
  363. if ev is None:
  364. raise Exception("Timeout while waiting for disconnection")
  365. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED", "CTRL-EVENT-CONNECTED"])
  366. if ev is None:
  367. raise Exception("Timeout while waiting for re-connection")
  368. if "CTRL-EVENT-EAP-STARTED" not in ev:
  369. raise Exception("Unexpected skipping of EAP authentication in reconnection")
  370. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"])
  371. if ev is None:
  372. raise Exception("Timeout while waiting for re-connection to complete")
  373. logger.info("Disconnect-Request with matching Calling-Station-Id and non-matching CUI")
  374. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  375. Calling_Station_Id=addr,
  376. Chargeable_User_Identity="foo@example.com",
  377. Event_Timestamp=int(time.time()))
  378. reply = srv.SendPacket(req)
  379. logger.debug("RADIUS response from hostapd")
  380. for i in reply.keys():
  381. logger.debug("%s: %s" % (i, reply[i]))
  382. if reply.code != pyrad.packet.DisconnectACK:
  383. raise Exception("Unexpected response code")
  384. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
  385. if ev is None:
  386. raise Exception("Timeout while waiting for disconnection")
  387. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"])
  388. if ev is None:
  389. raise Exception("Timeout while waiting for re-connection")
  390. logger.info("Disconnect-Request with matching CUI")
  391. dev[1].connect("radius-das", key_mgmt="WPA-EAP",
  392. eap="GPSK", identity="gpsk-cui",
  393. password="abcdefghijklmnop0123456789abcdef",
  394. scan_freq="2412")
  395. req = radius_das.DisconnectPacket(dict=dict, secret="secret",
  396. Chargeable_User_Identity="gpsk-chargeable-user-identity",
  397. Event_Timestamp=int(time.time()))
  398. reply = srv.SendPacket(req)
  399. logger.debug("RADIUS response from hostapd")
  400. for i in reply.keys():
  401. logger.debug("%s: %s" % (i, reply[i]))
  402. if reply.code != pyrad.packet.DisconnectACK:
  403. raise Exception("Unexpected response code")
  404. ev = dev[1].wait_event(["CTRL-EVENT-DISCONNECTED"])
  405. if ev is None:
  406. raise Exception("Timeout while waiting for disconnection")
  407. ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"])
  408. if ev is None:
  409. raise Exception("Timeout while waiting for re-connection")
  410. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=1)
  411. if ev is not None:
  412. raise Exception("Unexpected disconnection")
  413. def test_radius_das_coa(dev, apdev):
  414. """RADIUS Dynamic Authorization Extensions - CoA"""
  415. try:
  416. import pyrad.client
  417. import pyrad.packet
  418. import pyrad.dictionary
  419. import radius_das
  420. except ImportError:
  421. return "skip"
  422. params = hostapd.wpa2_eap_params(ssid="radius-das")
  423. params['radius_das_port'] = "3799"
  424. params['radius_das_client'] = "127.0.0.1 secret"
  425. params['radius_das_require_event_timestamp'] = "1"
  426. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  427. connect(dev[0], "radius-das")
  428. addr = dev[0].p2p_interface_addr()
  429. sta = hapd.get_sta(addr)
  430. id = sta['dot1xAuthSessionId']
  431. dict = pyrad.dictionary.Dictionary("dictionary.radius")
  432. srv = pyrad.client.Client(server="127.0.0.1", acctport=3799,
  433. secret="secret", dict=dict)
  434. srv.retries = 1
  435. srv.timeout = 1
  436. # hostapd does not currently support CoA-Request, so NAK is expected
  437. logger.info("CoA-Request with matching Acct-Session-Id")
  438. req = radius_das.CoAPacket(dict=dict, secret="secret",
  439. Acct_Session_Id=id,
  440. Event_Timestamp=int(time.time()))
  441. reply = srv.SendPacket(req)
  442. logger.debug("RADIUS response from hostapd")
  443. for i in reply.keys():
  444. logger.debug("%s: %s" % (i, reply[i]))
  445. if reply.code != pyrad.packet.CoANAK:
  446. raise Exception("Unexpected response code")
  447. if 'Error-Cause' not in reply:
  448. raise Exception("Missing Error-Cause")
  449. if reply['Error-Cause'][0] != 405:
  450. raise Exception("Unexpected Error-Cause: {}".format(reply['Error-Cause']))
  451. def test_radius_ipv6(dev, apdev):
  452. """RADIUS connection over IPv6"""
  453. params = {}
  454. params['ssid'] = 'as'
  455. params['beacon_int'] = '2000'
  456. params['radius_server_clients'] = 'auth_serv/radius_clients_ipv6.conf'
  457. params['radius_server_ipv6'] = '1'
  458. params['radius_server_auth_port'] = '18129'
  459. params['radius_server_acct_port'] = '18139'
  460. params['eap_server'] = '1'
  461. params['eap_user_file'] = 'auth_serv/eap_user.conf'
  462. params['ca_cert'] = 'auth_serv/ca.pem'
  463. params['server_cert'] = 'auth_serv/server.pem'
  464. params['private_key'] = 'auth_serv/server.key'
  465. hostapd.add_ap(apdev[1]['ifname'], params)
  466. params = hostapd.wpa2_eap_params(ssid="radius-ipv6")
  467. params['auth_server_addr'] = "::0"
  468. params['auth_server_port'] = "18129"
  469. params['acct_server_addr'] = "::0"
  470. params['acct_server_port'] = "18139"
  471. params['acct_server_shared_secret'] = "radius"
  472. params['own_ip_addr'] = "::0"
  473. hostapd.add_ap(apdev[0]['ifname'], params)
  474. connect(dev[0], "radius-ipv6")
  475. def test_radius_macacl(dev, apdev):
  476. """RADIUS MAC ACL"""
  477. params = hostapd.radius_params()
  478. params["ssid"] = "radius"
  479. params["macaddr_acl"] = "2"
  480. hostapd.add_ap(apdev[0]['ifname'], params)
  481. dev[0].connect("radius", key_mgmt="NONE", scan_freq="2412")