test_pmksa_cache.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. # WPA2-Enterprise PMKSA caching 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. from wpasupplicant import WpaSupplicant
  12. from utils import alloc_fail
  13. from test_ap_eap import eap_connect
  14. def test_pmksa_cache_on_roam_back(dev, apdev):
  15. """PMKSA cache to skip EAP on reassociation back to same AP"""
  16. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  17. hostapd.add_ap(apdev[0]['ifname'], params)
  18. bssid = apdev[0]['bssid']
  19. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  20. eap="GPSK", identity="gpsk user",
  21. password="abcdefghijklmnop0123456789abcdef",
  22. scan_freq="2412")
  23. pmksa = dev[0].get_pmksa(bssid)
  24. if pmksa is None:
  25. raise Exception("No PMKSA cache entry created")
  26. if pmksa['opportunistic'] != '0':
  27. raise Exception("Unexpected opportunistic PMKSA cache entry")
  28. hostapd.add_ap(apdev[1]['ifname'], params)
  29. bssid2 = apdev[1]['bssid']
  30. dev[0].dump_monitor()
  31. logger.info("Roam to AP2")
  32. # It can take some time for the second AP to become ready to reply to Probe
  33. # Request frames especially under heavy CPU load, so allow couple of rounds
  34. # of scanning to avoid reporting errors incorrectly just because of scans
  35. # not having seen the target AP.
  36. for i in range(0, 10):
  37. dev[0].scan(freq="2412")
  38. if dev[0].get_bss(bssid2) is not None:
  39. break
  40. logger.info("Scan again to find target AP")
  41. dev[0].request("ROAM " + bssid2)
  42. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=10)
  43. if ev is None:
  44. raise Exception("EAP success timed out")
  45. dev[0].wait_connected(timeout=10, error="Roaming timed out")
  46. pmksa2 = dev[0].get_pmksa(bssid2)
  47. if pmksa2 is None:
  48. raise Exception("No PMKSA cache entry found")
  49. if pmksa2['opportunistic'] != '0':
  50. raise Exception("Unexpected opportunistic PMKSA cache entry")
  51. dev[0].dump_monitor()
  52. logger.info("Roam back to AP1")
  53. dev[0].scan(freq="2412")
  54. dev[0].request("ROAM " + bssid)
  55. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  56. "CTRL-EVENT-CONNECTED"], timeout=10)
  57. if ev is None:
  58. raise Exception("Roaming with the AP timed out")
  59. if "CTRL-EVENT-EAP-STARTED" in ev:
  60. raise Exception("Unexpected EAP exchange")
  61. pmksa1b = dev[0].get_pmksa(bssid)
  62. if pmksa1b is None:
  63. raise Exception("No PMKSA cache entry found")
  64. if pmksa['pmkid'] != pmksa1b['pmkid']:
  65. raise Exception("Unexpected PMKID change for AP1")
  66. dev[0].dump_monitor()
  67. if "FAIL" in dev[0].request("PMKSA_FLUSH"):
  68. raise Exception("PMKSA_FLUSH failed")
  69. if dev[0].get_pmksa(bssid) is not None or dev[0].get_pmksa(bssid2) is not None:
  70. raise Exception("PMKSA_FLUSH did not remove PMKSA entries")
  71. dev[0].wait_disconnected(timeout=5)
  72. dev[0].wait_connected(timeout=15, error="Reconnection timed out")
  73. def test_pmksa_cache_and_reauth(dev, apdev):
  74. """PMKSA caching and EAPOL reauthentication"""
  75. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  76. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  77. bssid = apdev[0]['bssid']
  78. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  79. eap="GPSK", identity="gpsk user",
  80. password="abcdefghijklmnop0123456789abcdef",
  81. scan_freq="2412")
  82. hostapd.add_ap(apdev[1]['ifname'], params)
  83. bssid2 = apdev[1]['bssid']
  84. dev[0].dump_monitor()
  85. logger.info("Roam to AP2")
  86. # It can take some time for the second AP to become ready to reply to Probe
  87. # Request frames especially under heavy CPU load, so allow couple of rounds
  88. # of scanning to avoid reporting errors incorrectly just because of scans
  89. # not having seen the target AP.
  90. for i in range(0, 10):
  91. dev[0].scan(freq="2412")
  92. if dev[0].get_bss(bssid2) is not None:
  93. break
  94. logger.info("Scan again to find target AP")
  95. dev[0].request("ROAM " + bssid2)
  96. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=10)
  97. if ev is None:
  98. raise Exception("EAP success timed out")
  99. dev[0].wait_connected(timeout=10, error="Roaming timed out")
  100. dev[0].dump_monitor()
  101. logger.info("Roam back to AP1")
  102. dev[0].scan(freq="2412")
  103. dev[0].request("ROAM " + bssid)
  104. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  105. "CTRL-EVENT-CONNECTED"], timeout=10)
  106. if ev is None:
  107. raise Exception("Roaming with the AP timed out")
  108. if "CTRL-EVENT-EAP-STARTED" in ev:
  109. raise Exception("Unexpected EAP exchange")
  110. # Verify EAPOL reauthentication after PMKSA caching
  111. hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
  112. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  113. if ev is None:
  114. raise Exception("EAP authentication did not start")
  115. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  116. if ev is None:
  117. raise Exception("EAP authentication did not succeed")
  118. def test_pmksa_cache_opportunistic_only_on_sta(dev, apdev):
  119. """Opportunistic PMKSA caching enabled only on station"""
  120. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  121. hostapd.add_ap(apdev[0]['ifname'], params)
  122. bssid = apdev[0]['bssid']
  123. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  124. eap="GPSK", identity="gpsk user",
  125. password="abcdefghijklmnop0123456789abcdef", okc=True,
  126. scan_freq="2412")
  127. pmksa = dev[0].get_pmksa(bssid)
  128. if pmksa is None:
  129. raise Exception("No PMKSA cache entry created")
  130. if pmksa['opportunistic'] != '0':
  131. raise Exception("Unexpected opportunistic PMKSA cache entry")
  132. hostapd.add_ap(apdev[1]['ifname'], params)
  133. bssid2 = apdev[1]['bssid']
  134. dev[0].dump_monitor()
  135. logger.info("Roam to AP2")
  136. dev[0].scan(freq="2412")
  137. dev[0].request("ROAM " + bssid2)
  138. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=10)
  139. if ev is None:
  140. raise Exception("EAP success timed out")
  141. dev[0].wait_connected(timeout=10, error="Roaming timed out")
  142. pmksa2 = dev[0].get_pmksa(bssid2)
  143. if pmksa2 is None:
  144. raise Exception("No PMKSA cache entry found")
  145. if pmksa2['opportunistic'] != '0':
  146. raise Exception("Unexpected opportunistic PMKSA cache entry")
  147. dev[0].dump_monitor()
  148. logger.info("Roam back to AP1")
  149. dev[0].scan(freq="2412")
  150. dev[0].request("ROAM " + bssid)
  151. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  152. "CTRL-EVENT-CONNECTED"], timeout=10)
  153. if ev is None:
  154. raise Exception("Roaming with the AP timed out")
  155. if "CTRL-EVENT-EAP-STARTED" in ev:
  156. raise Exception("Unexpected EAP exchange")
  157. pmksa1b = dev[0].get_pmksa(bssid)
  158. if pmksa1b is None:
  159. raise Exception("No PMKSA cache entry found")
  160. if pmksa['pmkid'] != pmksa1b['pmkid']:
  161. raise Exception("Unexpected PMKID change for AP1")
  162. def test_pmksa_cache_opportunistic(dev, apdev):
  163. """Opportunistic PMKSA caching"""
  164. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  165. params['okc'] = "1"
  166. hostapd.add_ap(apdev[0]['ifname'], params)
  167. bssid = apdev[0]['bssid']
  168. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  169. eap="GPSK", identity="gpsk user",
  170. password="abcdefghijklmnop0123456789abcdef", okc=True,
  171. scan_freq="2412")
  172. pmksa = dev[0].get_pmksa(bssid)
  173. if pmksa is None:
  174. raise Exception("No PMKSA cache entry created")
  175. if pmksa['opportunistic'] != '0':
  176. raise Exception("Unexpected opportunistic PMKSA cache entry")
  177. hostapd.add_ap(apdev[1]['ifname'], params)
  178. bssid2 = apdev[1]['bssid']
  179. dev[0].dump_monitor()
  180. logger.info("Roam to AP2")
  181. dev[0].scan(freq="2412")
  182. dev[0].request("ROAM " + bssid2)
  183. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  184. "CTRL-EVENT-CONNECTED"], timeout=10)
  185. if ev is None:
  186. raise Exception("Roaming with the AP timed out")
  187. if "CTRL-EVENT-EAP-STARTED" in ev:
  188. raise Exception("Unexpected EAP exchange")
  189. pmksa2 = dev[0].get_pmksa(bssid2)
  190. if pmksa2 is None:
  191. raise Exception("No PMKSA cache entry created")
  192. dev[0].dump_monitor()
  193. logger.info("Roam back to AP1")
  194. dev[0].scan(freq="2412")
  195. dev[0].request("ROAM " + bssid)
  196. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  197. "CTRL-EVENT-CONNECTED"], timeout=10)
  198. if ev is None:
  199. raise Exception("Roaming with the AP timed out")
  200. if "CTRL-EVENT-EAP-STARTED" in ev:
  201. raise Exception("Unexpected EAP exchange")
  202. pmksa1b = dev[0].get_pmksa(bssid)
  203. if pmksa1b is None:
  204. raise Exception("No PMKSA cache entry found")
  205. if pmksa['pmkid'] != pmksa1b['pmkid']:
  206. raise Exception("Unexpected PMKID change for AP1")
  207. def test_pmksa_cache_opportunistic_connect(dev, apdev):
  208. """Opportunistic PMKSA caching with connect API"""
  209. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  210. params['okc'] = "1"
  211. hostapd.add_ap(apdev[0]['ifname'], params)
  212. bssid = apdev[0]['bssid']
  213. wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
  214. wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
  215. wpas.connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  216. eap="GPSK", identity="gpsk user",
  217. password="abcdefghijklmnop0123456789abcdef", okc=True,
  218. scan_freq="2412")
  219. pmksa = wpas.get_pmksa(bssid)
  220. if pmksa is None:
  221. raise Exception("No PMKSA cache entry created")
  222. if pmksa['opportunistic'] != '0':
  223. raise Exception("Unexpected opportunistic PMKSA cache entry")
  224. hostapd.add_ap(apdev[1]['ifname'], params)
  225. bssid2 = apdev[1]['bssid']
  226. wpas.dump_monitor()
  227. logger.info("Roam to AP2")
  228. wpas.scan_for_bss(bssid2, freq="2412")
  229. wpas.request("ROAM " + bssid2)
  230. ev = wpas.wait_event(["CTRL-EVENT-EAP-STARTED",
  231. "CTRL-EVENT-CONNECTED"], timeout=10)
  232. if ev is None:
  233. raise Exception("Roaming with the AP timed out")
  234. if "CTRL-EVENT-EAP-STARTED" in ev:
  235. raise Exception("Unexpected EAP exchange")
  236. pmksa2 = wpas.get_pmksa(bssid2)
  237. if pmksa2 is None:
  238. raise Exception("No PMKSA cache entry created")
  239. wpas.dump_monitor()
  240. logger.info("Roam back to AP1")
  241. wpas.scan(freq="2412")
  242. wpas.request("ROAM " + bssid)
  243. ev = wpas.wait_event(["CTRL-EVENT-EAP-STARTED",
  244. "CTRL-EVENT-CONNECTED"], timeout=10)
  245. if ev is None:
  246. raise Exception("Roaming with the AP timed out")
  247. if "CTRL-EVENT-EAP-STARTED" in ev:
  248. raise Exception("Unexpected EAP exchange")
  249. pmksa1b = wpas.get_pmksa(bssid)
  250. if pmksa1b is None:
  251. raise Exception("No PMKSA cache entry found")
  252. if pmksa['pmkid'] != pmksa1b['pmkid']:
  253. raise Exception("Unexpected PMKID change for AP1")
  254. def test_pmksa_cache_expiration(dev, apdev):
  255. """PMKSA cache entry expiration"""
  256. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  257. hostapd.add_ap(apdev[0]['ifname'], params)
  258. bssid = apdev[0]['bssid']
  259. dev[0].request("SET dot11RSNAConfigPMKLifetime 10")
  260. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  261. eap="GPSK", identity="gpsk user",
  262. password="abcdefghijklmnop0123456789abcdef",
  263. scan_freq="2412")
  264. pmksa = dev[0].get_pmksa(bssid)
  265. if pmksa is None:
  266. raise Exception("No PMKSA cache entry created")
  267. logger.info("Wait for PMKSA cache entry to expire")
  268. ev = dev[0].wait_event(["WPA: Key negotiation completed",
  269. "CTRL-EVENT-DISCONNECTED"], timeout=15)
  270. if ev is None:
  271. raise Exception("No EAP reauthentication seen")
  272. if "CTRL-EVENT-DISCONNECTED" in ev:
  273. raise Exception("Unexpected disconnection")
  274. pmksa2 = dev[0].get_pmksa(bssid)
  275. if pmksa['pmkid'] == pmksa2['pmkid']:
  276. raise Exception("PMKID did not change")
  277. def test_pmksa_cache_expiration_disconnect(dev, apdev):
  278. """PMKSA cache entry expiration (disconnect)"""
  279. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  280. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  281. bssid = apdev[0]['bssid']
  282. dev[0].request("SET dot11RSNAConfigPMKLifetime 2")
  283. dev[0].request("SET dot11RSNAConfigPMKReauthThreshold 100")
  284. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  285. eap="GPSK", identity="gpsk user",
  286. password="abcdefghijklmnop0123456789abcdef",
  287. scan_freq="2412")
  288. pmksa = dev[0].get_pmksa(bssid)
  289. if pmksa is None:
  290. raise Exception("No PMKSA cache entry created")
  291. hapd.request("SET auth_server_shared_secret incorrect")
  292. logger.info("Wait for PMKSA cache entry to expire")
  293. ev = dev[0].wait_event(["WPA: Key negotiation completed",
  294. "CTRL-EVENT-DISCONNECTED"], timeout=15)
  295. if ev is None:
  296. raise Exception("No EAP reauthentication seen")
  297. if "CTRL-EVENT-DISCONNECTED" not in ev:
  298. raise Exception("Missing disconnection")
  299. hapd.request("SET auth_server_shared_secret radius")
  300. ev = dev[0].wait_event(["WPA: Key negotiation completed"], timeout=15)
  301. if ev is None:
  302. raise Exception("No EAP reauthentication seen")
  303. pmksa2 = dev[0].get_pmksa(bssid)
  304. if pmksa['pmkid'] == pmksa2['pmkid']:
  305. raise Exception("PMKID did not change")
  306. def test_pmksa_cache_and_cui(dev, apdev):
  307. """PMKSA cache and Chargeable-User-Identity"""
  308. params = hostapd.wpa2_eap_params(ssid="cui")
  309. params['radius_request_cui'] = '1'
  310. params['acct_server_addr'] = "127.0.0.1"
  311. params['acct_server_port'] = "1813"
  312. params['acct_server_shared_secret'] = "radius"
  313. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  314. bssid = apdev[0]['bssid']
  315. dev[0].connect("cui", proto="RSN", key_mgmt="WPA-EAP",
  316. eap="GPSK", identity="gpsk-cui",
  317. password="abcdefghijklmnop0123456789abcdef",
  318. scan_freq="2412")
  319. pmksa = dev[0].get_pmksa(bssid)
  320. if pmksa is None:
  321. raise Exception("No PMKSA cache entry created")
  322. ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
  323. if ev is None:
  324. raise Exception("No connection event received from hostapd")
  325. dev[0].dump_monitor()
  326. logger.info("Disconnect and reconnect to the same AP")
  327. dev[0].request("DISCONNECT")
  328. dev[0].wait_disconnected()
  329. dev[0].request("RECONNECT")
  330. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  331. "CTRL-EVENT-CONNECTED"], timeout=10)
  332. if ev is None:
  333. raise Exception("Reconnect timed out")
  334. if "CTRL-EVENT-EAP-STARTED" in ev:
  335. raise Exception("Unexpected EAP exchange")
  336. pmksa1b = dev[0].get_pmksa(bssid)
  337. if pmksa1b is None:
  338. raise Exception("No PMKSA cache entry found")
  339. if pmksa['pmkid'] != pmksa1b['pmkid']:
  340. raise Exception("Unexpected PMKID change for AP1")
  341. dev[0].request("REAUTHENTICATE")
  342. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=10)
  343. if ev is None:
  344. raise Exception("EAP success timed out")
  345. for i in range(0, 20):
  346. state = dev[0].get_status_field("wpa_state")
  347. if state == "COMPLETED":
  348. break
  349. time.sleep(0.1)
  350. if state != "COMPLETED":
  351. raise Exception("Reauthentication did not complete")
  352. def test_pmksa_cache_preauth(dev, apdev):
  353. """RSN pre-authentication to generate PMKSA cache entry"""
  354. try:
  355. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  356. params['bridge'] = 'ap-br0'
  357. hostapd.add_ap(apdev[0]['ifname'], params)
  358. subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
  359. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
  360. eap_connect(dev[0], apdev[0], "PAX", "pax.user@example.com",
  361. password_hex="0123456789abcdef0123456789abcdef")
  362. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  363. params['bridge'] = 'ap-br0'
  364. params['rsn_preauth'] = '1'
  365. params['rsn_preauth_interfaces'] = 'ap-br0'
  366. hostapd.add_ap(apdev[1]['ifname'], params)
  367. bssid1 = apdev[1]['bssid']
  368. dev[0].scan(freq="2412")
  369. success = False
  370. status_seen = False
  371. for i in range(0, 50):
  372. if not status_seen:
  373. status = dev[0].request("STATUS")
  374. if "Pre-authentication EAPOL state machines:" in status:
  375. status_seen = True
  376. time.sleep(0.1)
  377. pmksa = dev[0].get_pmksa(bssid1)
  378. if pmksa:
  379. success = True
  380. break
  381. if not success:
  382. raise Exception("No PMKSA cache entry created from pre-authentication")
  383. if not status_seen:
  384. raise Exception("Pre-authentication EAPOL status was not available")
  385. dev[0].scan(freq="2412")
  386. if "[WPA2-EAP-CCMP-preauth]" not in dev[0].request("SCAN_RESULTS"):
  387. raise Exception("Scan results missing RSN element info")
  388. dev[0].request("ROAM " + bssid1)
  389. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  390. "CTRL-EVENT-CONNECTED"], timeout=10)
  391. if ev is None:
  392. raise Exception("Roaming with the AP timed out")
  393. if "CTRL-EVENT-EAP-STARTED" in ev:
  394. raise Exception("Unexpected EAP exchange")
  395. pmksa2 = dev[0].get_pmksa(bssid1)
  396. if pmksa2 is None:
  397. raise Exception("No PMKSA cache entry")
  398. if pmksa['pmkid'] != pmksa2['pmkid']:
  399. raise Exception("Unexpected PMKID change")
  400. finally:
  401. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
  402. subprocess.call(['brctl', 'delbr', 'ap-br0'])
  403. def test_pmksa_cache_preauth_vlan_enabled(dev, apdev):
  404. """RSN pre-authentication to generate PMKSA cache entry (dynamic_vlan optional but station without VLAN set)"""
  405. try:
  406. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  407. params['bridge'] = 'ap-br0'
  408. params['dynamic_vlan'] = '1'
  409. hostapd.add_ap(apdev[0]['ifname'], params)
  410. subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
  411. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
  412. eap_connect(dev[0], apdev[0], "PAX", "pax.user@example.com",
  413. password_hex="0123456789abcdef0123456789abcdef")
  414. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  415. params['bridge'] = 'ap-br0'
  416. params['rsn_preauth'] = '1'
  417. params['rsn_preauth_interfaces'] = 'ap-br0'
  418. params['dynamic_vlan'] = '1'
  419. hostapd.add_ap(apdev[1]['ifname'], params)
  420. bssid1 = apdev[1]['bssid']
  421. dev[0].scan(freq="2412")
  422. success = False
  423. status_seen = False
  424. for i in range(0, 50):
  425. if not status_seen:
  426. status = dev[0].request("STATUS")
  427. if "Pre-authentication EAPOL state machines:" in status:
  428. status_seen = True
  429. time.sleep(0.1)
  430. pmksa = dev[0].get_pmksa(bssid1)
  431. if pmksa:
  432. success = True
  433. break
  434. if not success:
  435. raise Exception("No PMKSA cache entry created from pre-authentication")
  436. if not status_seen:
  437. raise Exception("Pre-authentication EAPOL status was not available")
  438. dev[0].scan(freq="2412")
  439. if "[WPA2-EAP-CCMP-preauth]" not in dev[0].request("SCAN_RESULTS"):
  440. raise Exception("Scan results missing RSN element info")
  441. dev[0].request("ROAM " + bssid1)
  442. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  443. "CTRL-EVENT-CONNECTED"], timeout=10)
  444. if ev is None:
  445. raise Exception("Roaming with the AP timed out")
  446. if "CTRL-EVENT-EAP-STARTED" in ev:
  447. raise Exception("Unexpected EAP exchange")
  448. pmksa2 = dev[0].get_pmksa(bssid1)
  449. if pmksa2 is None:
  450. raise Exception("No PMKSA cache entry")
  451. if pmksa['pmkid'] != pmksa2['pmkid']:
  452. raise Exception("Unexpected PMKID change")
  453. finally:
  454. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
  455. subprocess.call(['brctl', 'delbr', 'ap-br0'])
  456. def test_pmksa_cache_preauth_vlan_used(dev, apdev):
  457. """RSN pre-authentication to generate PMKSA cache entry (station with VLAN set)"""
  458. try:
  459. subprocess.call(['brctl', 'addbr', 'brvlan1'])
  460. subprocess.call(['brctl', 'setfd', 'brvlan1', '0'])
  461. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  462. params['bridge'] = 'ap-br0'
  463. params['dynamic_vlan'] = '1'
  464. params['vlan_file'] = 'hostapd.wlan3.vlan'
  465. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  466. subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
  467. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
  468. eap_connect(dev[0], apdev[0], "PAX", "vlan1",
  469. password_hex="0123456789abcdef0123456789abcdef")
  470. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  471. params['bridge'] = 'ap-br0'
  472. params['rsn_preauth'] = '1'
  473. params['rsn_preauth_interfaces'] = 'brvlan1'
  474. params['dynamic_vlan'] = '1'
  475. params['vlan_file'] = 'hostapd.wlan4.vlan'
  476. hostapd.add_ap(apdev[1]['ifname'], params)
  477. bssid1 = apdev[1]['bssid']
  478. dev[0].scan(freq="2412")
  479. success = False
  480. status_seen = False
  481. for i in range(0, 50):
  482. if not status_seen:
  483. status = dev[0].request("STATUS")
  484. if "Pre-authentication EAPOL state machines:" in status:
  485. status_seen = True
  486. time.sleep(0.1)
  487. pmksa = dev[0].get_pmksa(bssid1)
  488. if pmksa:
  489. success = True
  490. break
  491. if not success:
  492. raise Exception("No PMKSA cache entry created from pre-authentication")
  493. if not status_seen:
  494. raise Exception("Pre-authentication EAPOL status was not available")
  495. dev[0].scan(freq="2412")
  496. if "[WPA2-EAP-CCMP-preauth]" not in dev[0].request("SCAN_RESULTS"):
  497. raise Exception("Scan results missing RSN element info")
  498. dev[0].request("ROAM " + bssid1)
  499. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  500. "CTRL-EVENT-CONNECTED"], timeout=10)
  501. if ev is None:
  502. raise Exception("Roaming with the AP timed out")
  503. if "CTRL-EVENT-EAP-STARTED" in ev:
  504. raise Exception("Unexpected EAP exchange")
  505. pmksa2 = dev[0].get_pmksa(bssid1)
  506. if pmksa2 is None:
  507. raise Exception("No PMKSA cache entry")
  508. if pmksa['pmkid'] != pmksa2['pmkid']:
  509. raise Exception("Unexpected PMKID change")
  510. # Disconnect the STA from both APs to avoid forceful ifdown by the
  511. # test script on a VLAN that this has an associated STA. That used to
  512. # trigger a mac80211 warning.
  513. dev[0].request("DISCONNECT")
  514. hapd.request("DISABLE")
  515. finally:
  516. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
  517. stderr=open('/dev/null', 'w'))
  518. subprocess.call(['ip', 'link', 'set', 'dev', 'brvlan1', 'down'])
  519. subprocess.call(['ip', 'link', 'set', 'dev', 'wlan3.1', 'down'],
  520. stderr=open('/dev/null', 'w'))
  521. subprocess.call(['ip', 'link', 'set', 'dev', 'wlan4.1', 'down'],
  522. stderr=open('/dev/null', 'w'))
  523. subprocess.call(['brctl', 'delif', 'brvlan1', 'wlan3.1'],
  524. stderr=open('/dev/null', 'w'))
  525. subprocess.call(['brctl', 'delif', 'brvlan1', 'wlan4.1'],
  526. stderr=open('/dev/null', 'w'))
  527. subprocess.call(['brctl', 'delbr', 'ap-br0'],
  528. stderr=open('/dev/null', 'w'))
  529. subprocess.call(['brctl', 'delbr', 'brvlan1'])
  530. def test_pmksa_cache_disabled(dev, apdev):
  531. """PMKSA cache disabling on AP"""
  532. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  533. params['disable_pmksa_caching'] = '1'
  534. hostapd.add_ap(apdev[0]['ifname'], params)
  535. bssid = apdev[0]['bssid']
  536. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  537. eap="GPSK", identity="gpsk user",
  538. password="abcdefghijklmnop0123456789abcdef",
  539. scan_freq="2412")
  540. hostapd.add_ap(apdev[1]['ifname'], params)
  541. bssid2 = apdev[1]['bssid']
  542. dev[0].dump_monitor()
  543. logger.info("Roam to AP2")
  544. dev[0].scan_for_bss(bssid2, freq="2412")
  545. dev[0].request("ROAM " + bssid2)
  546. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=10)
  547. if ev is None:
  548. raise Exception("EAP success timed out")
  549. dev[0].wait_connected(timeout=10, error="Roaming timed out")
  550. dev[0].dump_monitor()
  551. logger.info("Roam back to AP1")
  552. dev[0].scan(freq="2412")
  553. dev[0].request("ROAM " + bssid)
  554. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  555. "CTRL-EVENT-CONNECTED"], timeout=20)
  556. if ev is None:
  557. raise Exception("Roaming with the AP timed out")
  558. if "CTRL-EVENT-CONNECTED" in ev:
  559. raise Exception("EAP exchange missing")
  560. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=20)
  561. if ev is None:
  562. raise Exception("Roaming with the AP timed out")
  563. def test_pmksa_cache_ap_expiration(dev, apdev):
  564. """PMKSA cache entry expiring on AP"""
  565. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  566. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  567. bssid = apdev[0]['bssid']
  568. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  569. eap="GPSK", identity="gpsk-user-session-timeout",
  570. password="abcdefghijklmnop0123456789abcdef",
  571. scan_freq="2412")
  572. ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
  573. if ev is None:
  574. raise Exception("No connection event received from hostapd")
  575. dev[0].request("DISCONNECT")
  576. time.sleep(5)
  577. dev[0].dump_monitor()
  578. dev[0].request("RECONNECT")
  579. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  580. "CTRL-EVENT-CONNECTED"], timeout=20)
  581. if ev is None:
  582. raise Exception("Roaming with the AP timed out")
  583. if "CTRL-EVENT-CONNECTED" in ev:
  584. raise Exception("EAP exchange missing")
  585. dev[0].wait_connected(timeout=20, error="Reconnect timed out")
  586. dev[0].dump_monitor()
  587. dev[0].wait_disconnected(timeout=20)
  588. dev[0].wait_connected(timeout=20, error="Reassociation timed out")
  589. def test_pmksa_cache_multiple_sta(dev, apdev):
  590. """PMKSA cache with multiple stations"""
  591. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  592. hostapd.add_ap(apdev[0]['ifname'], params)
  593. bssid = apdev[0]['bssid']
  594. dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  595. eap="GPSK", identity="gpsk-user-session-timeout",
  596. password="abcdefghijklmnop0123456789abcdef",
  597. scan_freq="2412")
  598. dev[1].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  599. eap="GPSK", identity="gpsk user",
  600. password="abcdefghijklmnop0123456789abcdef",
  601. scan_freq="2412")
  602. dev[2].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  603. eap="GPSK", identity="gpsk-user-session-timeout",
  604. password="abcdefghijklmnop0123456789abcdef",
  605. scan_freq="2412")
  606. wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
  607. wpas.interface_add("wlan5")
  608. wpas.connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  609. eap="GPSK", identity="gpsk user",
  610. password="abcdefghijklmnop0123456789abcdef",
  611. scan_freq="2412")
  612. hostapd.add_ap(apdev[1]['ifname'], params)
  613. bssid2 = apdev[1]['bssid']
  614. logger.info("Roam to AP2")
  615. for sta in [ dev[1], dev[0], dev[2], wpas ]:
  616. sta.dump_monitor()
  617. sta.scan_for_bss(bssid2, freq="2412")
  618. sta.request("ROAM " + bssid2)
  619. ev = sta.wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=10)
  620. if ev is None:
  621. raise Exception("EAP success timed out")
  622. sta.wait_connected(timeout=10, error="Roaming timed out")
  623. logger.info("Roam back to AP1")
  624. for sta in [ dev[1], wpas, dev[0], dev[2] ]:
  625. sta.dump_monitor()
  626. sta.scan(freq="2412")
  627. sta.dump_monitor()
  628. sta.request("ROAM " + bssid)
  629. sta.wait_connected(timeout=10, error="Roaming timed out")
  630. sta.dump_monitor()
  631. time.sleep(4)
  632. logger.info("Roam back to AP2")
  633. for sta in [ dev[1], wpas, dev[0], dev[2] ]:
  634. sta.dump_monitor()
  635. sta.scan(freq="2412")
  636. sta.dump_monitor()
  637. sta.request("ROAM " + bssid2)
  638. sta.wait_connected(timeout=10, error="Roaming timed out")
  639. sta.dump_monitor()
  640. def test_pmksa_cache_opportunistic_multiple_sta(dev, apdev):
  641. """Opportunistic PMKSA caching with multiple stations"""
  642. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  643. params['okc'] = "1"
  644. hostapd.add_ap(apdev[0]['ifname'], params)
  645. bssid = apdev[0]['bssid']
  646. wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
  647. wpas.interface_add("wlan5")
  648. for sta in [ dev[0], dev[1], dev[2], wpas ]:
  649. sta.connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  650. eap="GPSK", identity="gpsk user",
  651. password="abcdefghijklmnop0123456789abcdef", okc=True,
  652. scan_freq="2412")
  653. hostapd.add_ap(apdev[1]['ifname'], params)
  654. bssid2 = apdev[1]['bssid']
  655. logger.info("Roam to AP2")
  656. for sta in [ dev[2], dev[0], wpas, dev[1] ]:
  657. sta.dump_monitor()
  658. sta.scan_for_bss(bssid2, freq="2412")
  659. if "OK" not in sta.request("ROAM " + bssid2):
  660. raise Exception("ROAM command failed")
  661. ev = sta.wait_event(["CTRL-EVENT-EAP-STARTED",
  662. "CTRL-EVENT-CONNECTED"], timeout=10)
  663. if ev is None:
  664. raise Exception("Roaming with the AP timed out")
  665. if "CTRL-EVENT-EAP-STARTED" in ev:
  666. raise Exception("Unexpected EAP exchange")
  667. pmksa2 = sta.get_pmksa(bssid2)
  668. if pmksa2 is None:
  669. raise Exception("No PMKSA cache entry created")
  670. logger.info("Roam back to AP1")
  671. for sta in [ dev[0], dev[1], dev[2], wpas ]:
  672. sta.dump_monitor()
  673. sta.scan_for_bss(bssid, freq="2412")
  674. sta.request("ROAM " + bssid)
  675. ev = sta.wait_event(["CTRL-EVENT-EAP-STARTED",
  676. "CTRL-EVENT-CONNECTED"], timeout=10)
  677. if ev is None:
  678. raise Exception("Roaming with the AP timed out")
  679. if "CTRL-EVENT-EAP-STARTED" in ev:
  680. raise Exception("Unexpected EAP exchange")
  681. def test_pmksa_cache_preauth_oom(dev, apdev):
  682. """RSN pre-authentication to generate PMKSA cache entry and OOM"""
  683. try:
  684. _test_pmksa_cache_preauth_oom(dev, apdev)
  685. finally:
  686. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
  687. subprocess.call(['brctl', 'delbr', 'ap-br0'])
  688. def _test_pmksa_cache_preauth_oom(dev, apdev):
  689. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  690. params['bridge'] = 'ap-br0'
  691. hostapd.add_ap(apdev[0]['ifname'], params)
  692. subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
  693. subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
  694. eap_connect(dev[0], apdev[0], "PAX", "pax.user@example.com",
  695. password_hex="0123456789abcdef0123456789abcdef",
  696. bssid=apdev[0]['bssid'])
  697. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  698. params['bridge'] = 'ap-br0'
  699. params['rsn_preauth'] = '1'
  700. params['rsn_preauth_interfaces'] = 'ap-br0'
  701. hapd = hostapd.add_ap(apdev[1]['ifname'], params)
  702. bssid1 = apdev[1]['bssid']
  703. tests = [ (1, "rsn_preauth_receive"),
  704. (2, "rsn_preauth_receive"),
  705. (1, "rsn_preauth_send") ]
  706. for test in tests:
  707. with alloc_fail(hapd, test[0], test[1]):
  708. dev[0].scan_for_bss(bssid1, freq="2412")
  709. if "OK" not in dev[0].request("PREAUTH " + bssid1):
  710. raise Exception("PREAUTH failed")
  711. success = False
  712. count = 0
  713. for i in range(50):
  714. time.sleep(0.1)
  715. pmksa = dev[0].get_pmksa(bssid1)
  716. if pmksa:
  717. success = True
  718. break
  719. state = hapd.request('GET_ALLOC_FAIL')
  720. if state.startswith('0:'):
  721. count += 1
  722. if count > 2:
  723. break
  724. logger.info("PMKSA cache success: " + str(success))
  725. dev[0].request("PMKSA_FLUSH")
  726. dev[0].wait_disconnected()
  727. dev[0].wait_connected()
  728. dev[0].dump_monitor()
  729. def test_pmksa_cache_size_limit(dev, apdev):
  730. """PMKSA cache size limit in wpa_supplicant"""
  731. try:
  732. _test_pmksa_cache_size_limit(dev, apdev)
  733. finally:
  734. try:
  735. hapd = hostapd.HostapdGlobal()
  736. hapd.flush()
  737. hapd.remove(apdev[0]['ifname'])
  738. except:
  739. pass
  740. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  741. bssid = apdev[0]['bssid']
  742. params['bssid'] = bssid
  743. hostapd.add_ap(apdev[0]['ifname'], params)
  744. def _test_pmksa_cache_size_limit(dev, apdev):
  745. params = hostapd.wpa2_eap_params(ssid="test-pmksa-cache")
  746. id = dev[0].connect("test-pmksa-cache", proto="RSN", key_mgmt="WPA-EAP",
  747. eap="GPSK", identity="gpsk user",
  748. password="abcdefghijklmnop0123456789abcdef",
  749. scan_freq="2412", only_add_network=True)
  750. for i in range(33):
  751. bssid = apdev[0]['bssid'][0:15] + "%02x" % i
  752. logger.info("Iteration with BSSID " + bssid)
  753. params['bssid'] = bssid
  754. hostapd.add_ap(apdev[0]['ifname'], params)
  755. dev[0].request("BSS_FLUSH 0")
  756. dev[0].scan_for_bss(bssid, freq=2412, only_new=True)
  757. dev[0].select_network(id)
  758. dev[0].wait_connected()
  759. dev[0].request("DISCONNECT")
  760. dev[0].wait_disconnected()
  761. dev[0].dump_monitor()
  762. entries = len(dev[0].request("PMKSA").splitlines()) - 1
  763. if i == 32:
  764. if entries != 32:
  765. raise Exception("Unexpected number of PMKSA entries after expected removal of the oldest entry")
  766. elif i + 1 != entries:
  767. raise Exception("Unexpected number of PMKSA entries")
  768. hapd = hostapd.HostapdGlobal()
  769. hapd.flush()
  770. hapd.remove(apdev[0]['ifname'])
  771. def test_pmksa_cache_preauth_timeout(dev, apdev):
  772. """RSN pre-authentication timing out"""
  773. try:
  774. _test_pmksa_cache_preauth_timeout(dev, apdev)
  775. finally:
  776. dev[0].request("SET dot11RSNAConfigSATimeout 60")
  777. def _test_pmksa_cache_preauth_timeout(dev, apdev):
  778. dev[0].request("SET dot11RSNAConfigSATimeout 1")
  779. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  780. hostapd.add_ap(apdev[0]['ifname'], params)
  781. eap_connect(dev[0], apdev[0], "PAX", "pax.user@example.com",
  782. password_hex="0123456789abcdef0123456789abcdef",
  783. bssid=apdev[0]['bssid'])
  784. if "OK" not in dev[0].request("PREAUTH f2:11:22:33:44:55"):
  785. raise Exception("PREAUTH failed")
  786. ev = dev[0].wait_event(["RSN: pre-authentication with"], timeout=5)
  787. if ev is None:
  788. raise Exception("No timeout event seen")
  789. if "timed out" not in ev:
  790. raise Exception("Unexpected event: " + ev)
  791. def test_pmksa_cache_preauth_wpas_oom(dev, apdev):
  792. """RSN pre-authentication OOM in wpa_supplicant"""
  793. params = hostapd.wpa2_eap_params(ssid="test-wpa2-eap")
  794. hostapd.add_ap(apdev[0]['ifname'], params)
  795. eap_connect(dev[0], apdev[0], "PAX", "pax.user@example.com",
  796. password_hex="0123456789abcdef0123456789abcdef",
  797. bssid=apdev[0]['bssid'])
  798. for i in range(1, 11):
  799. with alloc_fail(dev[0], i, "rsn_preauth_init"):
  800. res = dev[0].request("PREAUTH f2:11:22:33:44:55").strip()
  801. logger.info("Iteration %d - PREAUTH command results: %s" % (i, res))
  802. for j in range(10):
  803. state = dev[0].request('GET_ALLOC_FAIL')
  804. if state.startswith('0:'):
  805. break
  806. time.sleep(0.05)