test_ieee8021x.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. # IEEE 802.1X tests
  2. # Copyright (c) 2013-2015, 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 binascii
  7. import hmac
  8. import logging
  9. import time
  10. import hostapd
  11. import hwsim_utils
  12. logger = logging.getLogger()
  13. def test_ieee8021x_wep104(dev, apdev):
  14. """IEEE 802.1X connection using dynamic WEP104"""
  15. params = hostapd.radius_params()
  16. params["ssid"] = "ieee8021x-wep"
  17. params["ieee8021x"] = "1"
  18. params["wep_key_len_broadcast"] = "13"
  19. params["wep_key_len_unicast"] = "13"
  20. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  21. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="PSK",
  22. identity="psk.user@example.com",
  23. password_hex="0123456789abcdef0123456789abcdef",
  24. scan_freq="2412")
  25. hwsim_utils.test_connectivity(dev[0], hapd)
  26. def test_ieee8021x_wep40(dev, apdev):
  27. """IEEE 802.1X connection using dynamic WEP40"""
  28. params = hostapd.radius_params()
  29. params["ssid"] = "ieee8021x-wep"
  30. params["ieee8021x"] = "1"
  31. params["wep_key_len_broadcast"] = "5"
  32. params["wep_key_len_unicast"] = "5"
  33. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  34. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="PSK",
  35. identity="psk.user@example.com",
  36. password_hex="0123456789abcdef0123456789abcdef",
  37. scan_freq="2412")
  38. hwsim_utils.test_connectivity(dev[0], hapd)
  39. def test_ieee8021x_open(dev, apdev):
  40. """IEEE 802.1X connection using open network"""
  41. params = hostapd.radius_params()
  42. params["ssid"] = "ieee8021x-open"
  43. params["ieee8021x"] = "1"
  44. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  45. id = dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  46. eap="PSK", identity="psk.user@example.com",
  47. password_hex="0123456789abcdef0123456789abcdef",
  48. scan_freq="2412")
  49. hwsim_utils.test_connectivity(dev[0], hapd)
  50. logger.info("Test EAPOL-Logoff")
  51. dev[0].request("LOGOFF")
  52. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
  53. if ev is None:
  54. raise Exception("Did not get disconnected")
  55. if "reason=23" not in ev:
  56. raise Exception("Unexpected disconnection reason")
  57. dev[0].request("LOGON")
  58. dev[0].connect_network(id)
  59. hwsim_utils.test_connectivity(dev[0], hapd)
  60. def test_ieee8021x_static_wep40(dev, apdev):
  61. """IEEE 802.1X connection using static WEP40"""
  62. params = hostapd.radius_params()
  63. params["ssid"] = "ieee8021x-wep"
  64. params["ieee8021x"] = "1"
  65. params["wep_key0"] = '"hello"'
  66. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  67. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="PSK",
  68. identity="psk.user@example.com",
  69. password_hex="0123456789abcdef0123456789abcdef",
  70. wep_key0='"hello"', eapol_flags="0",
  71. scan_freq="2412")
  72. hwsim_utils.test_connectivity(dev[0], hapd)
  73. def test_ieee8021x_proto(dev, apdev):
  74. """IEEE 802.1X and EAPOL supplicant protocol testing"""
  75. params = hostapd.radius_params()
  76. params["ssid"] = "ieee8021x-open"
  77. params["ieee8021x"] = "1"
  78. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  79. bssid = apdev[0]['bssid']
  80. dev[1].request("SET ext_eapol_frame_io 1")
  81. dev[1].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  82. eap="PSK", identity="psk.user@example.com",
  83. password_hex="0123456789abcdef0123456789abcdef",
  84. scan_freq="2412", wait_connect=False)
  85. id = dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  86. eap="PSK", identity="psk.user@example.com",
  87. password_hex="0123456789abcdef0123456789abcdef",
  88. scan_freq="2412")
  89. ev = dev[1].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  90. start = dev[0].get_mib()
  91. tests = [ "11",
  92. "11223344",
  93. "020000050a93000501",
  94. "020300050a93000501",
  95. "0203002c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  96. "0203002c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  97. "0203002c0100050000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  98. "02aa00050a93000501" ]
  99. for frame in tests:
  100. res = dev[0].request("EAPOL_RX " + bssid + " " + frame)
  101. if "OK" not in res:
  102. raise Exception("EAPOL_RX to wpa_supplicant failed")
  103. dev[1].request("EAPOL_RX " + bssid + " " + frame)
  104. stop = dev[0].get_mib()
  105. logger.info("MIB before test frames: " + str(start))
  106. logger.info("MIB after test frames: " + str(stop))
  107. vals = [ 'dot1xSuppInvalidEapolFramesRx',
  108. 'dot1xSuppEapLengthErrorFramesRx' ]
  109. for val in vals:
  110. if int(stop[val]) <= int(start[val]):
  111. raise Exception(val + " did not increase")
  112. def test_ieee8021x_eapol_start(dev, apdev):
  113. """IEEE 802.1X and EAPOL-Start retransmissions"""
  114. params = hostapd.radius_params()
  115. params["ssid"] = "ieee8021x-open"
  116. params["ieee8021x"] = "1"
  117. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  118. bssid = apdev[0]['bssid']
  119. addr0 = dev[0].own_addr()
  120. hapd.set("ext_eapol_frame_io", "1")
  121. try:
  122. dev[0].request("SET EAPOL::startPeriod 1")
  123. dev[0].request("SET EAPOL::maxStart 1")
  124. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  125. eap="PSK", identity="psk.user@example.com",
  126. password_hex="0123456789abcdef0123456789abcdef",
  127. scan_freq="2412", wait_connect=False)
  128. held = False
  129. for i in range(30):
  130. pae = dev[0].get_status_field('Supplicant PAE state')
  131. if pae == "HELD":
  132. mib = hapd.get_sta(addr0, info="eapol")
  133. if mib['auth_pae_state'] != 'AUTHENTICATING':
  134. raise Exception("Unexpected Auth PAE state: " + mib['auth_pae_state'])
  135. held = True
  136. break
  137. time.sleep(0.25)
  138. if not held:
  139. raise Exception("PAE state HELD not reached")
  140. dev[0].wait_disconnected()
  141. finally:
  142. dev[0].request("SET EAPOL::startPeriod 30")
  143. dev[0].request("SET EAPOL::maxStart 3")
  144. def test_ieee8021x_held(dev, apdev):
  145. """IEEE 802.1X and HELD state"""
  146. params = hostapd.radius_params()
  147. params["ssid"] = "ieee8021x-open"
  148. params["ieee8021x"] = "1"
  149. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  150. bssid = apdev[0]['bssid']
  151. hapd.set("ext_eapol_frame_io", "1")
  152. try:
  153. dev[0].request("SET EAPOL::startPeriod 1")
  154. dev[0].request("SET EAPOL::maxStart 0")
  155. dev[0].request("SET EAPOL::heldPeriod 1")
  156. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  157. eap="PSK", identity="psk.user@example.com",
  158. password_hex="0123456789abcdef0123456789abcdef",
  159. scan_freq="2412", wait_connect=False)
  160. held = False
  161. for i in range(30):
  162. pae = dev[0].get_status_field('Supplicant PAE state')
  163. if pae == "HELD":
  164. held = True
  165. break
  166. time.sleep(0.25)
  167. if not held:
  168. raise Exception("PAE state HELD not reached")
  169. hapd.set("ext_eapol_frame_io", "0")
  170. for i in range(30):
  171. pae = dev[0].get_status_field('Supplicant PAE state')
  172. if pae != "HELD":
  173. held = False
  174. break
  175. time.sleep(0.25)
  176. if held:
  177. raise Exception("PAE state HELD not left")
  178. ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED",
  179. "CTRL-EVENT-DISCONNECTED" ], timeout=10)
  180. if ev is None:
  181. raise Exception("Connection timed out")
  182. if "CTRL-EVENT-DISCONNECTED" in ev:
  183. raise Exception("Unexpected disconnection")
  184. finally:
  185. dev[0].request("SET EAPOL::startPeriod 30")
  186. dev[0].request("SET EAPOL::maxStart 3")
  187. dev[0].request("SET EAPOL::heldPeriod 60")
  188. def send_eapol_key(dev, bssid, signkey, frame_start, frame_end):
  189. zero_sign = "00000000000000000000000000000000"
  190. frame = frame_start + zero_sign + frame_end
  191. hmac_obj = hmac.new(binascii.unhexlify(signkey))
  192. hmac_obj.update(binascii.unhexlify(frame))
  193. sign = hmac_obj.digest()
  194. frame = frame_start + binascii.hexlify(sign) + frame_end
  195. dev.request("EAPOL_RX " + bssid + " " + frame)
  196. def test_ieee8021x_eapol_key(dev, apdev):
  197. """IEEE 802.1X connection and EAPOL-Key protocol tests"""
  198. params = hostapd.radius_params()
  199. params["ssid"] = "ieee8021x-wep"
  200. params["ieee8021x"] = "1"
  201. params["wep_key_len_broadcast"] = "5"
  202. params["wep_key_len_unicast"] = "5"
  203. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  204. bssid = apdev[0]['bssid']
  205. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="VENDOR-TEST",
  206. identity="vendor-test", scan_freq="2412")
  207. # Hardcoded MSK from VENDOR-TEST
  208. encrkey = "1111111111111111111111111111111111111111111111111111111111111111"
  209. signkey = "2222222222222222222222222222222222222222222222222222222222222222"
  210. # EAPOL-Key replay counter does not increase
  211. send_eapol_key(dev[0], bssid, signkey,
  212. "02030031" + "010005" + "0000000000000000" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  213. "1c636a30a4")
  214. # EAPOL-Key too large Key Length field value
  215. send_eapol_key(dev[0], bssid, signkey,
  216. "02030031" + "010021" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  217. "1c636a30a4")
  218. # EAPOL-Key too much key data
  219. send_eapol_key(dev[0], bssid, signkey,
  220. "0203004d" + "010005" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  221. 33*"ff")
  222. # EAPOL-Key too little key data
  223. send_eapol_key(dev[0], bssid, signkey,
  224. "02030030" + "010005" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  225. "1c636a30")
  226. # EAPOL-Key with no key data and too long WEP key length
  227. send_eapol_key(dev[0], bssid, signkey,
  228. "0203002c" + "010020" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  229. "")
  230. def test_ieee8021x_reauth(dev, apdev):
  231. """IEEE 802.1X and EAPOL_REAUTH request"""
  232. params = hostapd.radius_params()
  233. params["ssid"] = "ieee8021x-open"
  234. params["ieee8021x"] = "1"
  235. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  236. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  237. eap="PSK", identity="psk.user@example.com",
  238. password_hex="0123456789abcdef0123456789abcdef",
  239. scan_freq="2412")
  240. hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
  241. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  242. if ev is None:
  243. raise Exception("EAP authentication did not start")
  244. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  245. if ev is None:
  246. raise Exception("EAP authentication did not succeed")
  247. time.sleep(0.1)
  248. hwsim_utils.test_connectivity(dev[0], hapd)
  249. def test_ieee8021x_set_conf(dev, apdev):
  250. """IEEE 802.1X and EAPOL_SET command"""
  251. params = hostapd.radius_params()
  252. params["ssid"] = "ieee8021x-open"
  253. params["ieee8021x"] = "1"
  254. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  255. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  256. eap="PSK", identity="psk.user@example.com",
  257. password_hex="0123456789abcdef0123456789abcdef",
  258. scan_freq="2412")
  259. addr0 = dev[0].own_addr()
  260. tests = [ "EAPOL_SET 1",
  261. "EAPOL_SET %sfoo bar" % addr0,
  262. "EAPOL_SET %s foo" % addr0,
  263. "EAPOL_SET %s foo bar" % addr0,
  264. "EAPOL_SET %s AdminControlledDirections bar" % addr0,
  265. "EAPOL_SET %s AdminControlledPortControl bar" % addr0,
  266. "EAPOL_SET %s reAuthEnabled bar" % addr0,
  267. "EAPOL_SET %s KeyTransmissionEnabled bar" % addr0,
  268. "EAPOL_SET 11:22:33:44:55:66 AdminControlledDirections Both" ]
  269. for t in tests:
  270. if "FAIL" not in hapd.request(t):
  271. raise Exception("Invalid EAPOL_SET command accepted: " + t)
  272. tests = [ ("AdminControlledDirections", "adminControlledDirections", "In"),
  273. ("AdminControlledDirections", "adminControlledDirections",
  274. "Both"),
  275. ("quietPeriod", "quietPeriod", "13"),
  276. ("serverTimeout", "serverTimeout", "7"),
  277. ("reAuthPeriod", "reAuthPeriod", "1234"),
  278. ("reAuthEnabled", "reAuthEnabled", "FALSE"),
  279. ("reAuthEnabled", "reAuthEnabled", "TRUE"),
  280. ("KeyTransmissionEnabled", "keyTxEnabled", "TRUE"),
  281. ("KeyTransmissionEnabled", "keyTxEnabled", "FALSE"),
  282. ("AdminControlledPortControl", "portControl", "ForceAuthorized"),
  283. ("AdminControlledPortControl", "portControl",
  284. "ForceUnauthorized"),
  285. ("AdminControlledPortControl", "portControl", "Auto") ]
  286. for param,mibparam,val in tests:
  287. if "OK" not in hapd.request("EAPOL_SET %s %s %s" % (addr0, param, val)):
  288. raise Exception("Failed to set %s %s" % (param, val))
  289. mib = hapd.get_sta(addr0, info="eapol")
  290. if mib[mibparam] != val:
  291. raise Exception("Unexpected %s value: %s (expected %s)" % (param, mib[mibparam], val))
  292. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  293. if ev is None:
  294. raise Exception("EAP authentication did not succeed")
  295. time.sleep(0.1)
  296. hwsim_utils.test_connectivity(dev[0], hapd)
  297. def test_ieee8021x_auth_awhile(dev, apdev):
  298. """IEEE 802.1X and EAPOL Authenticator aWhile handling"""
  299. params = hostapd.radius_params()
  300. params["ssid"] = "ieee8021x-open"
  301. params["ieee8021x"] = "1"
  302. params['auth_server_port'] = "18129"
  303. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  304. bssid = apdev[0]['bssid']
  305. addr0 = dev[0].own_addr()
  306. params = {}
  307. params['ssid'] = 'as'
  308. params['beacon_int'] = '2000'
  309. params['radius_server_clients'] = 'auth_serv/radius_clients.conf'
  310. params['radius_server_auth_port'] = '18129'
  311. params['eap_server'] = '1'
  312. params['eap_user_file'] = 'auth_serv/eap_user.conf'
  313. params['ca_cert'] = 'auth_serv/ca.pem'
  314. params['server_cert'] = 'auth_serv/server.pem'
  315. params['private_key'] = 'auth_serv/server.key'
  316. hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
  317. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  318. eap="PSK", identity="psk.user@example.com",
  319. password_hex="0123456789abcdef0123456789abcdef",
  320. scan_freq="2412")
  321. hapd1.disable()
  322. if "OK" not in hapd.request("EAPOL_SET %s serverTimeout 1" % addr0):
  323. raise Exception("Failed to set serverTimeout")
  324. hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
  325. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  326. for i in range(40):
  327. mib = hapd.get_sta(addr0, info="eapol")
  328. val = int(mib['aWhile'])
  329. if val > 0:
  330. break
  331. time.sleep(1)
  332. if val == 0:
  333. raise Exception("aWhile did not increase")
  334. hapd.dump_monitor()
  335. for i in range(40):
  336. mib = hapd.get_sta(addr0, info="eapol")
  337. val = int(mib['aWhile'])
  338. if val < 5:
  339. break
  340. time.sleep(1)
  341. ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED"], timeout=10)
  342. if ev is None:
  343. raise Exception("Authentication restart not seen")