test_fils.py 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114
  1. # Test cases for FILS
  2. # Copyright (c) 2015-2017, Qualcomm Atheros, Inc.
  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 hashlib
  8. import logging
  9. logger = logging.getLogger()
  10. import os
  11. import socket
  12. import struct
  13. import time
  14. import hostapd
  15. from wpasupplicant import WpaSupplicant
  16. import hwsim_utils
  17. from utils import HwsimSkip, alloc_fail
  18. from test_erp import check_erp_capa, start_erp_as
  19. from test_ap_hs20 import ip_checksum
  20. def check_fils_capa(dev):
  21. capa = dev.get_capability("fils")
  22. if capa is None or "FILS" not in capa:
  23. raise HwsimSkip("FILS not supported")
  24. def test_fils_sk_full_auth(dev, apdev):
  25. """FILS SK full authentication"""
  26. check_fils_capa(dev[0])
  27. check_erp_capa(dev[0])
  28. start_erp_as(apdev[1])
  29. bssid = apdev[0]['bssid']
  30. params = hostapd.wpa2_eap_params(ssid="fils")
  31. params['wpa_key_mgmt'] = "FILS-SHA256"
  32. params['auth_server_port'] = "18128"
  33. params['erp_send_reauth_start'] = '1'
  34. params['erp_domain'] = 'example.com'
  35. params['fils_realm'] = 'example.com'
  36. params['wpa_group_rekey'] = '1'
  37. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  38. dev[0].scan_for_bss(bssid, freq=2412)
  39. bss = dev[0].get_bss(bssid)
  40. logger.debug("BSS: " + str(bss))
  41. if "[FILS]" not in bss['flags']:
  42. raise Exception("[FILS] flag not indicated")
  43. if "[WPA2-FILS-SHA256-CCMP]" not in bss['flags']:
  44. raise Exception("[WPA2-FILS-SHA256-CCMP] flag not indicated")
  45. res = dev[0].request("SCAN_RESULTS")
  46. logger.debug("SCAN_RESULTS: " + res)
  47. if "[FILS]" not in res:
  48. raise Exception("[FILS] flag not indicated")
  49. if "[WPA2-FILS-SHA256-CCMP]" not in res:
  50. raise Exception("[WPA2-FILS-SHA256-CCMP] flag not indicated")
  51. dev[0].request("ERP_FLUSH")
  52. dev[0].connect("fils", key_mgmt="FILS-SHA256",
  53. eap="PSK", identity="psk.user@example.com",
  54. password_hex="0123456789abcdef0123456789abcdef",
  55. erp="1", scan_freq="2412")
  56. hwsim_utils.test_connectivity(dev[0], hapd)
  57. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  58. if ev is None:
  59. raise Exception("GTK rekey timed out")
  60. hwsim_utils.test_connectivity(dev[0], hapd)
  61. conf = hapd.get_config()
  62. if conf['key_mgmt'] != 'FILS-SHA256':
  63. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  64. def test_fils_sk_sha384_full_auth(dev, apdev):
  65. """FILS SK full authentication (SHA384)"""
  66. check_fils_capa(dev[0])
  67. check_erp_capa(dev[0])
  68. start_erp_as(apdev[1])
  69. bssid = apdev[0]['bssid']
  70. params = hostapd.wpa2_eap_params(ssid="fils")
  71. params['wpa_key_mgmt'] = "FILS-SHA384"
  72. params['auth_server_port'] = "18128"
  73. params['erp_send_reauth_start'] = '1'
  74. params['erp_domain'] = 'example.com'
  75. params['fils_realm'] = 'example.com'
  76. params['wpa_group_rekey'] = '1'
  77. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  78. dev[0].scan_for_bss(bssid, freq=2412)
  79. bss = dev[0].get_bss(bssid)
  80. logger.debug("BSS: " + str(bss))
  81. if "[FILS]" not in bss['flags']:
  82. raise Exception("[FILS] flag not indicated")
  83. if "[WPA2-FILS-SHA384-CCMP]" not in bss['flags']:
  84. raise Exception("[WPA2-FILS-SHA384-CCMP] flag not indicated")
  85. res = dev[0].request("SCAN_RESULTS")
  86. logger.debug("SCAN_RESULTS: " + res)
  87. if "[FILS]" not in res:
  88. raise Exception("[FILS] flag not indicated")
  89. if "[WPA2-FILS-SHA384-CCMP]" not in res:
  90. raise Exception("[WPA2-FILS-SHA384-CCMP] flag not indicated")
  91. dev[0].request("ERP_FLUSH")
  92. dev[0].connect("fils", key_mgmt="FILS-SHA384",
  93. eap="PSK", identity="psk.user@example.com",
  94. password_hex="0123456789abcdef0123456789abcdef",
  95. erp="1", scan_freq="2412")
  96. hwsim_utils.test_connectivity(dev[0], hapd)
  97. ev = dev[0].wait_event(["WPA: Group rekeying completed"], timeout=2)
  98. if ev is None:
  99. raise Exception("GTK rekey timed out")
  100. hwsim_utils.test_connectivity(dev[0], hapd)
  101. conf = hapd.get_config()
  102. if conf['key_mgmt'] != 'FILS-SHA384':
  103. raise Exception("Unexpected config key_mgmt: " + conf['key_mgmt'])
  104. def test_fils_sk_pmksa_caching(dev, apdev):
  105. """FILS SK and PMKSA caching"""
  106. check_fils_capa(dev[0])
  107. check_erp_capa(dev[0])
  108. start_erp_as(apdev[1])
  109. bssid = apdev[0]['bssid']
  110. params = hostapd.wpa2_eap_params(ssid="fils")
  111. params['wpa_key_mgmt'] = "FILS-SHA256"
  112. params['auth_server_port'] = "18128"
  113. params['erp_domain'] = 'example.com'
  114. params['fils_realm'] = 'example.com'
  115. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  116. dev[0].scan_for_bss(bssid, freq=2412)
  117. dev[0].request("ERP_FLUSH")
  118. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  119. eap="PSK", identity="psk.user@example.com",
  120. password_hex="0123456789abcdef0123456789abcdef",
  121. erp="1", scan_freq="2412")
  122. pmksa = dev[0].get_pmksa(bssid)
  123. if pmksa is None:
  124. raise Exception("No PMKSA cache entry created")
  125. dev[0].request("DISCONNECT")
  126. dev[0].wait_disconnected()
  127. dev[0].dump_monitor()
  128. dev[0].select_network(id, freq=2412)
  129. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  130. "CTRL-EVENT-CONNECTED"], timeout=10)
  131. if ev is None:
  132. raise Exception("Connection using PMKSA caching timed out")
  133. if "CTRL-EVENT-EAP-STARTED" in ev:
  134. raise Exception("Unexpected EAP exchange")
  135. hwsim_utils.test_connectivity(dev[0], hapd)
  136. pmksa2 = dev[0].get_pmksa(bssid)
  137. if pmksa2 is None:
  138. raise Exception("No PMKSA cache entry found")
  139. if pmksa['pmkid'] != pmksa2['pmkid']:
  140. raise Exception("Unexpected PMKID change")
  141. # Verify EAPOL reauthentication after FILS authentication
  142. hapd.request("EAPOL_REAUTH " + dev[0].own_addr())
  143. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  144. if ev is None:
  145. raise Exception("EAP authentication did not start")
  146. ev = dev[0].wait_event(["CTRL-EVENT-EAP-SUCCESS"], timeout=5)
  147. if ev is None:
  148. raise Exception("EAP authentication did not succeed")
  149. time.sleep(0.1)
  150. hwsim_utils.test_connectivity(dev[0], hapd)
  151. def test_fils_sk_pmksa_caching_and_cache_id(dev, apdev):
  152. """FILS SK and PMKSA caching with Cache Identifier"""
  153. check_fils_capa(dev[0])
  154. check_erp_capa(dev[0])
  155. bssid = apdev[0]['bssid']
  156. params = hostapd.wpa2_eap_params(ssid="fils")
  157. params['wpa_key_mgmt'] = "FILS-SHA256"
  158. params['auth_server_port'] = "18128"
  159. params['erp_domain'] = 'example.com'
  160. params['fils_realm'] = 'example.com'
  161. params['fils_cache_id'] = "abcd"
  162. params["radius_server_clients"] = "auth_serv/radius_clients.conf"
  163. params["radius_server_auth_port"] = '18128'
  164. params["eap_server"] = "1"
  165. params["eap_user_file"] = "auth_serv/eap_user.conf"
  166. params["ca_cert"] = "auth_serv/ca.pem"
  167. params["server_cert"] = "auth_serv/server.pem"
  168. params["private_key"] = "auth_serv/server.key"
  169. params["eap_sim_db"] = "unix:/tmp/hlr_auc_gw.sock"
  170. params["dh_file"] = "auth_serv/dh.conf"
  171. params["pac_opaque_encr_key"] = "000102030405060708090a0b0c0d0e0f"
  172. params["eap_fast_a_id"] = "101112131415161718191a1b1c1d1e1f"
  173. params["eap_fast_a_id_info"] = "test server"
  174. params["eap_server_erp"] = "1"
  175. params["erp_domain"] = "example.com"
  176. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  177. dev[0].scan_for_bss(bssid, freq=2412)
  178. dev[0].request("ERP_FLUSH")
  179. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  180. eap="PSK", identity="psk.user@example.com",
  181. password_hex="0123456789abcdef0123456789abcdef",
  182. erp="1", scan_freq="2412")
  183. res = dev[0].request("PMKSA")
  184. if "FILS Cache Identifier" not in res:
  185. raise Exception("PMKSA list does not include FILS Cache Identifier")
  186. pmksa = dev[0].get_pmksa(bssid)
  187. if pmksa is None:
  188. raise Exception("No PMKSA cache entry created")
  189. if "cache_id" not in pmksa:
  190. raise Exception("No FILS Cache Identifier listed")
  191. if pmksa["cache_id"] != "abcd":
  192. raise Exception("The configured FILS Cache Identifier not seen in PMKSA")
  193. bssid2 = apdev[1]['bssid']
  194. params = hostapd.wpa2_eap_params(ssid="fils")
  195. params['wpa_key_mgmt'] = "FILS-SHA256"
  196. params['auth_server_port'] = "18128"
  197. params['erp_domain'] = 'example.com'
  198. params['fils_realm'] = 'example.com'
  199. params['fils_cache_id'] = "abcd"
  200. hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
  201. dev[0].scan_for_bss(bssid2, freq=2412)
  202. dev[0].dump_monitor()
  203. if "OK" not in dev[0].request("ROAM " + bssid2):
  204. raise Exception("ROAM failed")
  205. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  206. "CTRL-EVENT-CONNECTED"], timeout=10)
  207. if ev is None:
  208. raise Exception("Connection using PMKSA caching timed out")
  209. if "CTRL-EVENT-EAP-STARTED" in ev:
  210. raise Exception("Unexpected EAP exchange")
  211. if bssid2 not in ev:
  212. raise Exception("Failed to connect to the second AP")
  213. hwsim_utils.test_connectivity(dev[0], hapd2)
  214. pmksa2 = dev[0].get_pmksa(bssid2)
  215. if pmksa2:
  216. raise Exception("Unexpected extra PMKSA cache added")
  217. pmksa2 = dev[0].get_pmksa(bssid)
  218. if not pmksa2:
  219. raise Exception("Original PMKSA cache entry removed")
  220. if pmksa['pmkid'] != pmksa2['pmkid']:
  221. raise Exception("Unexpected PMKID change")
  222. def test_fils_sk_erp(dev, apdev):
  223. """FILS SK using ERP"""
  224. run_fils_sk_erp(dev, apdev, "FILS-SHA256")
  225. def test_fils_sk_erp_sha384(dev, apdev):
  226. """FILS SK using ERP and SHA384"""
  227. run_fils_sk_erp(dev, apdev, "FILS-SHA384")
  228. def run_fils_sk_erp(dev, apdev, key_mgmt):
  229. check_fils_capa(dev[0])
  230. check_erp_capa(dev[0])
  231. start_erp_as(apdev[1])
  232. bssid = apdev[0]['bssid']
  233. params = hostapd.wpa2_eap_params(ssid="fils")
  234. params['wpa_key_mgmt'] = key_mgmt
  235. params['auth_server_port'] = "18128"
  236. params['erp_domain'] = 'example.com'
  237. params['fils_realm'] = 'example.com'
  238. params['disable_pmksa_caching'] = '1'
  239. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  240. dev[0].scan_for_bss(bssid, freq=2412)
  241. dev[0].request("ERP_FLUSH")
  242. id = dev[0].connect("fils", key_mgmt=key_mgmt,
  243. eap="PSK", identity="psk.user@example.com",
  244. password_hex="0123456789abcdef0123456789abcdef",
  245. erp="1", scan_freq="2412")
  246. dev[0].request("DISCONNECT")
  247. dev[0].wait_disconnected()
  248. dev[0].dump_monitor()
  249. dev[0].select_network(id, freq=2412)
  250. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  251. "EVENT-ASSOC-REJECT",
  252. "CTRL-EVENT-CONNECTED"], timeout=10)
  253. if ev is None:
  254. raise Exception("Connection using FILS/ERP timed out")
  255. if "CTRL-EVENT-EAP-STARTED" in ev:
  256. raise Exception("Unexpected EAP exchange")
  257. if "EVENT-ASSOC-REJECT" in ev:
  258. raise Exception("Association failed")
  259. hwsim_utils.test_connectivity(dev[0], hapd)
  260. def test_fils_sk_erp_another_ssid(dev, apdev):
  261. """FILS SK using ERP and roam to another SSID"""
  262. check_fils_capa(dev[0])
  263. check_erp_capa(dev[0])
  264. start_erp_as(apdev[1])
  265. bssid = apdev[0]['bssid']
  266. params = hostapd.wpa2_eap_params(ssid="fils")
  267. params['wpa_key_mgmt'] = "FILS-SHA256"
  268. params['auth_server_port'] = "18128"
  269. params['erp_domain'] = 'example.com'
  270. params['fils_realm'] = 'example.com'
  271. params['disable_pmksa_caching'] = '1'
  272. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  273. dev[0].scan_for_bss(bssid, freq=2412)
  274. dev[0].request("ERP_FLUSH")
  275. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  276. eap="PSK", identity="psk.user@example.com",
  277. password_hex="0123456789abcdef0123456789abcdef",
  278. erp="1", scan_freq="2412")
  279. dev[0].request("DISCONNECT")
  280. dev[0].wait_disconnected()
  281. hapd.disable()
  282. dev[0].flush_scan_cache()
  283. if "FAIL" in dev[0].request("PMKSA_FLUSH"):
  284. raise Exception("PMKSA_FLUSH failed")
  285. params = hostapd.wpa2_eap_params(ssid="fils2")
  286. params['wpa_key_mgmt'] = "FILS-SHA256"
  287. params['auth_server_port'] = "18128"
  288. params['erp_domain'] = 'example.com'
  289. params['fils_realm'] = 'example.com'
  290. params['disable_pmksa_caching'] = '1'
  291. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  292. dev[0].scan_for_bss(bssid, freq=2412)
  293. dev[0].dump_monitor()
  294. id = dev[0].connect("fils2", key_mgmt="FILS-SHA256",
  295. eap="PSK", identity="psk.user@example.com",
  296. password_hex="0123456789abcdef0123456789abcdef",
  297. erp="1", scan_freq="2412", wait_connect=False)
  298. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  299. "EVENT-ASSOC-REJECT",
  300. "CTRL-EVENT-CONNECTED"], timeout=10)
  301. if ev is None:
  302. raise Exception("Connection using FILS/ERP timed out")
  303. if "CTRL-EVENT-EAP-STARTED" in ev:
  304. raise Exception("Unexpected EAP exchange")
  305. if "EVENT-ASSOC-REJECT" in ev:
  306. raise Exception("Association failed")
  307. hwsim_utils.test_connectivity(dev[0], hapd)
  308. def test_fils_sk_multiple_realms(dev, apdev):
  309. """FILS SK and multiple realms"""
  310. check_fils_capa(dev[0])
  311. check_erp_capa(dev[0])
  312. start_erp_as(apdev[1])
  313. bssid = apdev[0]['bssid']
  314. params = hostapd.wpa2_eap_params(ssid="fils")
  315. params['wpa_key_mgmt'] = "FILS-SHA256"
  316. params['auth_server_port'] = "18128"
  317. params['erp_domain'] = 'example.com'
  318. fils_realms = [ 'r1.example.org', 'r2.EXAMPLE.org', 'r3.example.org',
  319. 'r4.example.org', 'r5.example.org', 'r6.example.org',
  320. 'r7.example.org', 'r8.example.org',
  321. 'example.com',
  322. 'r9.example.org', 'r10.example.org', 'r11.example.org',
  323. 'r12.example.org', 'r13.example.org', 'r14.example.org',
  324. 'r15.example.org', 'r16.example.org' ]
  325. params['fils_realm'] = fils_realms
  326. params['fils_cache_id'] = "1234"
  327. params['hessid'] = bssid
  328. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  329. dev[0].scan_for_bss(bssid, freq=2412)
  330. if "OK" not in dev[0].request("ANQP_GET " + bssid + " 275"):
  331. raise Exception("ANQP_GET command failed")
  332. ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10)
  333. if ev is None:
  334. raise Exception("GAS query timed out")
  335. bss = dev[0].get_bss(bssid)
  336. if 'fils_info' not in bss:
  337. raise Exception("FILS Indication element information missing")
  338. if bss['fils_info'] != '02b8':
  339. raise Exception("Unexpected FILS Information: " + bss['fils_info'])
  340. if 'fils_cache_id' not in bss:
  341. raise Exception("FILS Cache Identifier missing")
  342. if bss['fils_cache_id'] != '1234':
  343. raise Exception("Unexpected FILS Cache Identifier: " + bss['fils_cache_id'])
  344. if 'fils_realms' not in bss:
  345. raise Exception("FILS Realm Identifiers missing")
  346. expected = ''
  347. count = 0
  348. for realm in fils_realms:
  349. hash = hashlib.sha256(realm.lower()).digest()
  350. expected += binascii.hexlify(hash[0:2])
  351. count += 1
  352. if count == 7:
  353. break
  354. if bss['fils_realms'] != expected:
  355. raise Exception("Unexpected FILS Realm Identifiers: " + bss['fils_realms'])
  356. if 'anqp_fils_realm_info' not in bss:
  357. raise Exception("FILS Realm Information ANQP-element not seen")
  358. info = bss['anqp_fils_realm_info'];
  359. expected = ''
  360. for realm in fils_realms:
  361. hash = hashlib.sha256(realm.lower()).digest()
  362. expected += binascii.hexlify(hash[0:2])
  363. if info != expected:
  364. raise Exception("Unexpected FILS Realm Info ANQP-element: " + info)
  365. dev[0].request("ERP_FLUSH")
  366. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  367. eap="PSK", identity="psk.user@example.com",
  368. password_hex="0123456789abcdef0123456789abcdef",
  369. erp="1", scan_freq="2412")
  370. dev[0].request("DISCONNECT")
  371. dev[0].wait_disconnected()
  372. dev[0].dump_monitor()
  373. dev[0].select_network(id, freq=2412)
  374. ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED",
  375. "EVENT-ASSOC-REJECT",
  376. "CTRL-EVENT-CONNECTED"], timeout=10)
  377. if ev is None:
  378. raise Exception("Connection using FILS/ERP timed out")
  379. if "CTRL-EVENT-EAP-STARTED" in ev:
  380. raise Exception("Unexpected EAP exchange")
  381. if "EVENT-ASSOC-REJECT" in ev:
  382. raise Exception("Association failed")
  383. hwsim_utils.test_connectivity(dev[0], hapd)
  384. # DHCP message op codes
  385. BOOTREQUEST=1
  386. BOOTREPLY=2
  387. OPT_PAD=0
  388. OPT_DHCP_MESSAGE_TYPE=53
  389. OPT_RAPID_COMMIT=80
  390. OPT_END=255
  391. DHCPDISCOVER=1
  392. DHCPOFFER=2
  393. DHCPREQUEST=3
  394. DHCPDECLINE=4
  395. DHCPACK=5
  396. DHCPNAK=6
  397. DHCPRELEASE=7
  398. DHCPINFORM=8
  399. def build_dhcp(req, dhcp_msg, chaddr, giaddr="0.0.0.0",
  400. ip_src="0.0.0.0", ip_dst="255.255.255.255",
  401. rapid_commit=True, override_op=None, magic_override=None,
  402. opt_end=True, extra_op=None):
  403. proto = '\x08\x00' # IPv4
  404. _ip_src = socket.inet_pton(socket.AF_INET, ip_src)
  405. _ip_dst = socket.inet_pton(socket.AF_INET, ip_dst)
  406. _ciaddr = '\x00\x00\x00\x00'
  407. _yiaddr = '\x00\x00\x00\x00'
  408. _siaddr = '\x00\x00\x00\x00'
  409. _giaddr = socket.inet_pton(socket.AF_INET, giaddr)
  410. _chaddr = binascii.unhexlify(chaddr.replace(':','')) + 10*'\x00'
  411. htype = 1 # Hardware address type; 1 = Ethernet
  412. hlen = 6 # Hardware address length
  413. hops = 0
  414. xid = 123456
  415. secs = 0
  416. flags = 0
  417. if req:
  418. op = BOOTREQUEST
  419. src_port = 68
  420. dst_port = 67
  421. else:
  422. op = BOOTREPLY
  423. src_port = 67
  424. dst_port = 68
  425. if override_op is not None:
  426. op = override_op
  427. payload = struct.pack('>BBBBLHH', op, htype, hlen, hops, xid, secs, flags)
  428. sname = 64*'\x00'
  429. file = 128*'\x00'
  430. payload += _ciaddr + _yiaddr + _siaddr + _giaddr + _chaddr + sname + file
  431. # magic - DHCP
  432. if magic_override is not None:
  433. payload += magic_override
  434. else:
  435. payload += '\x63\x82\x53\x63'
  436. # Option: DHCP Message Type
  437. if dhcp_msg is not None:
  438. payload += struct.pack('BBB', OPT_DHCP_MESSAGE_TYPE, 1, dhcp_msg)
  439. if rapid_commit:
  440. # Option: Rapid Commit
  441. payload += struct.pack('BB', OPT_RAPID_COMMIT, 0)
  442. if extra_op:
  443. payload += extra_op
  444. # End Option
  445. if opt_end:
  446. payload += struct.pack('B', OPT_END)
  447. udp = struct.pack('>HHHH', src_port, dst_port,
  448. 8 + len(payload), 0) + payload
  449. tot_len = 20 + len(udp)
  450. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  451. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  452. csum = ip_checksum(ipv4)
  453. ipv4 = start + csum + _ip_src + _ip_dst
  454. return proto + ipv4 + udp
  455. def fils_hlp_config(fils_hlp_wait_time=10000):
  456. params = hostapd.wpa2_eap_params(ssid="fils")
  457. params['wpa_key_mgmt'] = "FILS-SHA256"
  458. params['auth_server_port'] = "18128"
  459. params['erp_domain'] = 'example.com'
  460. params['fils_realm'] = 'example.com'
  461. params['disable_pmksa_caching'] = '1'
  462. params['own_ip_addr'] = '127.0.0.3'
  463. params['dhcp_server'] = '127.0.0.2'
  464. params['fils_hlp_wait_time'] = str(fils_hlp_wait_time)
  465. return params
  466. def test_fils_sk_hlp(dev, apdev):
  467. """FILS SK HLP (rapid commit server)"""
  468. run_fils_sk_hlp(dev, apdev, True)
  469. def test_fils_sk_hlp_no_rapid_commit(dev, apdev):
  470. """FILS SK HLP (no rapid commit server)"""
  471. run_fils_sk_hlp(dev, apdev, False)
  472. def run_fils_sk_hlp(dev, apdev, rapid_commit_server):
  473. check_fils_capa(dev[0])
  474. check_erp_capa(dev[0])
  475. start_erp_as(apdev[1])
  476. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  477. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  478. sock.settimeout(5)
  479. sock.bind(("127.0.0.2", 67))
  480. bssid = apdev[0]['bssid']
  481. params = fils_hlp_config()
  482. params['fils_hlp_wait_time'] = '10000'
  483. if not rapid_commit_server:
  484. params['dhcp_rapid_commit_proxy'] = '1'
  485. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  486. dev[0].scan_for_bss(bssid, freq=2412)
  487. dev[0].request("ERP_FLUSH")
  488. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  489. raise Exception("Failed to flush pending FILS HLP requests")
  490. tests = [ "",
  491. "q",
  492. "ff:ff:ff:ff:ff:ff",
  493. "ff:ff:ff:ff:ff:ff q" ]
  494. for t in tests:
  495. if "FAIL" not in dev[0].request("FILS_HLP_REQ_ADD " + t):
  496. raise Exception("Invalid FILS_HLP_REQ_ADD accepted: " + t)
  497. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  498. chaddr=dev[0].own_addr())
  499. tests = [ "ff:ff:ff:ff:ff:ff aabb",
  500. "ff:ff:ff:ff:ff:ff " + 255*'cc',
  501. hapd.own_addr() + " ddee010203040506070809",
  502. "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc) ]
  503. for t in tests:
  504. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + t):
  505. raise Exception("FILS_HLP_REQ_ADD failed: " + t)
  506. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  507. eap="PSK", identity="psk.user@example.com",
  508. password_hex="0123456789abcdef0123456789abcdef",
  509. erp="1", scan_freq="2412")
  510. dev[0].request("DISCONNECT")
  511. dev[0].wait_disconnected()
  512. dev[0].dump_monitor()
  513. dev[0].select_network(id, freq=2412)
  514. (msg,addr) = sock.recvfrom(1000)
  515. logger.debug("Received DHCP message from %s" % str(addr))
  516. if rapid_commit_server:
  517. # TODO: Proper rapid commit response
  518. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  519. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  520. sock.sendto(dhcpdisc[2+20+8:], addr)
  521. else:
  522. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  523. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  524. sock.sendto(dhcpdisc[2+20+8:], addr)
  525. (msg,addr) = sock.recvfrom(1000)
  526. logger.debug("Received DHCP message from %s" % str(addr))
  527. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK, rapid_commit=False,
  528. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  529. sock.sendto(dhcpdisc[2+20+8:], addr)
  530. ev = dev[0].wait_event(["FILS-HLP-RX"], timeout=10)
  531. if ev is None:
  532. raise Exception("FILS HLP response not reported")
  533. vals = ev.split(' ')
  534. frame = binascii.unhexlify(vals[3].split('=')[1])
  535. proto, = struct.unpack('>H', frame[0:2])
  536. if proto != 0x0800:
  537. raise Exception("Unexpected ethertype in HLP response: %d" % proto)
  538. frame = frame[2:]
  539. ip = frame[0:20]
  540. if ip_checksum(ip) != '\x00\x00':
  541. raise Exception("IP header checksum mismatch in HLP response")
  542. frame = frame[20:]
  543. udp = frame[0:8]
  544. frame = frame[8:]
  545. sport, dport, ulen, ucheck = struct.unpack('>HHHH', udp)
  546. if sport != 67 or dport != 68:
  547. raise Exception("Unexpected UDP port in HLP response")
  548. dhcp = frame[0:28]
  549. frame = frame[28:]
  550. op,htype,hlen,hops,xid,secs,flags,ciaddr,yiaddr,siaddr,giaddr = struct.unpack('>4BL2H4L', dhcp)
  551. chaddr = frame[0:16]
  552. frame = frame[16:]
  553. sname = frame[0:64]
  554. frame = frame[64:]
  555. file = frame[0:128]
  556. frame = frame[128:]
  557. options = frame
  558. if options[0:4] != '\x63\x82\x53\x63':
  559. raise Exception("No DHCP magic seen in HLP response")
  560. options = options[4:]
  561. # TODO: fully parse and validate DHCPACK options
  562. if struct.pack('BBB', OPT_DHCP_MESSAGE_TYPE, 1, DHCPACK) not in options:
  563. raise Exception("DHCPACK not in HLP response")
  564. dev[0].wait_connected()
  565. dev[0].request("FILS_HLP_REQ_FLUSH")
  566. def test_fils_sk_hlp_timeout(dev, apdev):
  567. """FILS SK HLP (rapid commit server timeout)"""
  568. check_fils_capa(dev[0])
  569. check_erp_capa(dev[0])
  570. start_erp_as(apdev[1])
  571. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  572. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  573. sock.settimeout(5)
  574. sock.bind(("127.0.0.2", 67))
  575. bssid = apdev[0]['bssid']
  576. params = fils_hlp_config(fils_hlp_wait_time=30)
  577. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  578. dev[0].scan_for_bss(bssid, freq=2412)
  579. dev[0].request("ERP_FLUSH")
  580. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  581. raise Exception("Failed to flush pending FILS HLP requests")
  582. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  583. chaddr=dev[0].own_addr())
  584. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  585. raise Exception("FILS_HLP_REQ_ADD failed")
  586. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  587. eap="PSK", identity="psk.user@example.com",
  588. password_hex="0123456789abcdef0123456789abcdef",
  589. erp="1", scan_freq="2412")
  590. dev[0].request("DISCONNECT")
  591. dev[0].wait_disconnected()
  592. dev[0].dump_monitor()
  593. dev[0].select_network(id, freq=2412)
  594. (msg,addr) = sock.recvfrom(1000)
  595. logger.debug("Received DHCP message from %s" % str(addr))
  596. # Wait for HLP wait timeout to hit
  597. # FILS: HLP response timeout - continue with association response
  598. dev[0].wait_connected()
  599. dev[0].request("FILS_HLP_REQ_FLUSH")
  600. def test_fils_sk_hlp_oom(dev, apdev):
  601. """FILS SK HLP and hostapd OOM"""
  602. check_fils_capa(dev[0])
  603. check_erp_capa(dev[0])
  604. start_erp_as(apdev[1])
  605. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  606. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  607. sock.settimeout(5)
  608. sock.bind(("127.0.0.2", 67))
  609. bssid = apdev[0]['bssid']
  610. params = fils_hlp_config(fils_hlp_wait_time=500)
  611. params['dhcp_rapid_commit_proxy'] = '1'
  612. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  613. dev[0].scan_for_bss(bssid, freq=2412)
  614. dev[0].request("ERP_FLUSH")
  615. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  616. raise Exception("Failed to flush pending FILS HLP requests")
  617. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  618. chaddr=dev[0].own_addr())
  619. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  620. raise Exception("FILS_HLP_REQ_ADD failed")
  621. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  622. eap="PSK", identity="psk.user@example.com",
  623. password_hex="0123456789abcdef0123456789abcdef",
  624. erp="1", scan_freq="2412")
  625. dev[0].request("DISCONNECT")
  626. dev[0].wait_disconnected()
  627. dev[0].dump_monitor()
  628. with alloc_fail(hapd, 1, "fils_process_hlp"):
  629. dev[0].select_network(id, freq=2412)
  630. dev[0].wait_connected()
  631. dev[0].request("DISCONNECT")
  632. dev[0].wait_disconnected()
  633. dev[0].dump_monitor()
  634. with alloc_fail(hapd, 1, "fils_process_hlp_dhcp"):
  635. dev[0].select_network(id, freq=2412)
  636. dev[0].wait_connected()
  637. dev[0].request("DISCONNECT")
  638. dev[0].wait_disconnected()
  639. dev[0].dump_monitor()
  640. with alloc_fail(hapd, 1, "wpabuf_alloc;fils_process_hlp_dhcp"):
  641. dev[0].select_network(id, freq=2412)
  642. dev[0].wait_connected()
  643. dev[0].request("DISCONNECT")
  644. dev[0].wait_disconnected()
  645. dev[0].dump_monitor()
  646. with alloc_fail(hapd, 1, "wpabuf_alloc;fils_dhcp_handler"):
  647. dev[0].select_network(id, freq=2412)
  648. (msg,addr) = sock.recvfrom(1000)
  649. logger.debug("Received DHCP message from %s" % str(addr))
  650. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  651. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  652. sock.sendto(dhcpdisc[2+20+8:], addr)
  653. dev[0].wait_connected()
  654. dev[0].request("DISCONNECT")
  655. dev[0].wait_disconnected()
  656. dev[0].dump_monitor()
  657. with alloc_fail(hapd, 1, "wpabuf_resize;fils_dhcp_handler"):
  658. dev[0].select_network(id, freq=2412)
  659. (msg,addr) = sock.recvfrom(1000)
  660. logger.debug("Received DHCP message from %s" % str(addr))
  661. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  662. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  663. sock.sendto(dhcpdisc[2+20+8:], addr)
  664. dev[0].wait_connected()
  665. dev[0].request("DISCONNECT")
  666. dev[0].wait_disconnected()
  667. dev[0].dump_monitor()
  668. dev[0].select_network(id, freq=2412)
  669. (msg,addr) = sock.recvfrom(1000)
  670. logger.debug("Received DHCP message from %s" % str(addr))
  671. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  672. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  673. with alloc_fail(hapd, 1, "wpabuf_resize;fils_dhcp_request"):
  674. sock.sendto(dhcpoffer[2+20+8:], addr)
  675. dev[0].wait_connected()
  676. dev[0].request("DISCONNECT")
  677. dev[0].wait_disconnected()
  678. dev[0].request("FILS_HLP_REQ_FLUSH")
  679. def test_fils_sk_hlp_req_parsing(dev, apdev):
  680. """FILS SK HLP request parsing"""
  681. check_fils_capa(dev[0])
  682. check_erp_capa(dev[0])
  683. start_erp_as(apdev[1])
  684. bssid = apdev[0]['bssid']
  685. params = fils_hlp_config(fils_hlp_wait_time=30)
  686. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  687. dev[0].scan_for_bss(bssid, freq=2412)
  688. dev[0].request("ERP_FLUSH")
  689. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  690. raise Exception("Failed to flush pending FILS HLP requests")
  691. tot_len = 20 + 1
  692. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  693. _ip_src = '\x00\x00\x00\x00'
  694. _ip_dst = '\x00\x00\x00\x00'
  695. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  696. csum = ip_checksum(ipv4)
  697. ipv4_overflow = start + csum + _ip_src + _ip_dst
  698. tot_len = 20
  699. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 123)
  700. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  701. csum = ip_checksum(ipv4)
  702. ipv4_unknown_proto = start + csum + _ip_src + _ip_dst
  703. tot_len = 20
  704. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  705. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  706. csum = ip_checksum(ipv4)
  707. ipv4_missing_udp_hdr = start + csum + _ip_src + _ip_dst
  708. src_port = 68
  709. dst_port = 67
  710. udp = struct.pack('>HHHH', src_port, dst_port, 8 + 1, 0)
  711. tot_len = 20 + len(udp)
  712. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  713. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  714. csum = ip_checksum(ipv4)
  715. udp_overflow = start + csum + _ip_src + _ip_dst + udp
  716. udp = struct.pack('>HHHH', src_port, dst_port, 7, 0)
  717. tot_len = 20 + len(udp)
  718. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  719. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  720. csum = ip_checksum(ipv4)
  721. udp_underflow = start + csum + _ip_src + _ip_dst + udp
  722. src_port = 123
  723. dst_port = 456
  724. udp = struct.pack('>HHHH', src_port, dst_port, 8, 0)
  725. tot_len = 20 + len(udp)
  726. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  727. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  728. csum = ip_checksum(ipv4)
  729. udp_unknown_port = start + csum + _ip_src + _ip_dst + udp
  730. src_port = 68
  731. dst_port = 67
  732. udp = struct.pack('>HHHH', src_port, dst_port, 8, 0)
  733. tot_len = 20 + len(udp)
  734. start = struct.pack('>BBHHBBBB', 0x45, 0, tot_len, 0, 0, 0, 128, 17)
  735. ipv4 = start + '\x00\x00' + _ip_src + _ip_dst
  736. csum = ip_checksum(ipv4)
  737. dhcp_missing_data = start + csum + _ip_src + _ip_dst + udp
  738. dhcp_not_req = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  739. chaddr=dev[0].own_addr(), override_op=BOOTREPLY)
  740. dhcp_no_magic = build_dhcp(req=True, dhcp_msg=None,
  741. chaddr=dev[0].own_addr(), magic_override='',
  742. rapid_commit=False, opt_end=False)
  743. dhcp_unknown_magic = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  744. chaddr=dev[0].own_addr(),
  745. magic_override='\x00\x00\x00\x00')
  746. dhcp_opts = build_dhcp(req=True, dhcp_msg=DHCPNAK,
  747. chaddr=dev[0].own_addr(),
  748. extra_op='\x00\x11', opt_end=False)
  749. dhcp_opts2 = build_dhcp(req=True, dhcp_msg=DHCPNAK,
  750. chaddr=dev[0].own_addr(),
  751. extra_op='\x11\x01', opt_end=False)
  752. dhcp_valid = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  753. chaddr=dev[0].own_addr())
  754. tests = [ "ff",
  755. "0800",
  756. "0800" + 20*"00",
  757. "0800" + binascii.hexlify(ipv4_overflow),
  758. "0800" + binascii.hexlify(ipv4_unknown_proto),
  759. "0800" + binascii.hexlify(ipv4_missing_udp_hdr),
  760. "0800" + binascii.hexlify(udp_overflow),
  761. "0800" + binascii.hexlify(udp_underflow),
  762. "0800" + binascii.hexlify(udp_unknown_port),
  763. "0800" + binascii.hexlify(dhcp_missing_data),
  764. binascii.hexlify(dhcp_not_req),
  765. binascii.hexlify(dhcp_no_magic),
  766. binascii.hexlify(dhcp_unknown_magic) ]
  767. for t in tests:
  768. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + t):
  769. raise Exception("FILS_HLP_REQ_ADD failed: " + t)
  770. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  771. eap="PSK", identity="psk.user@example.com",
  772. password_hex="0123456789abcdef0123456789abcdef",
  773. erp="1", scan_freq="2412")
  774. dev[0].request("DISCONNECT")
  775. dev[0].wait_disconnected()
  776. dev[0].dump_monitor()
  777. dev[0].select_network(id, freq=2412)
  778. dev[0].wait_connected()
  779. dev[0].request("DISCONNECT")
  780. dev[0].wait_disconnected()
  781. dev[0].request("FILS_HLP_REQ_FLUSH")
  782. tests = [ binascii.hexlify(dhcp_opts),
  783. binascii.hexlify(dhcp_opts2) ]
  784. for t in tests:
  785. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + t):
  786. raise Exception("FILS_HLP_REQ_ADD failed: " + t)
  787. dev[0].dump_monitor()
  788. dev[0].select_network(id, freq=2412)
  789. dev[0].wait_connected()
  790. dev[0].request("DISCONNECT")
  791. dev[0].wait_disconnected()
  792. dev[0].request("FILS_HLP_REQ_FLUSH")
  793. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcp_valid)):
  794. raise Exception("FILS_HLP_REQ_ADD failed")
  795. hapd.set("own_ip_addr", "0.0.0.0")
  796. dev[0].select_network(id, freq=2412)
  797. dev[0].wait_connected()
  798. dev[0].request("DISCONNECT")
  799. dev[0].wait_disconnected()
  800. hapd.set("dhcp_server", "0.0.0.0")
  801. dev[0].select_network(id, freq=2412)
  802. dev[0].wait_connected()
  803. dev[0].request("DISCONNECT")
  804. dev[0].wait_disconnected()
  805. # FILS: Failed to bind DHCP socket: Address already in use
  806. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  807. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  808. sock.settimeout(5)
  809. sock.bind(("127.0.0.2", 67))
  810. hapd.set("own_ip_addr", "127.0.0.2")
  811. hapd.set("dhcp_server", "127.0.0.2")
  812. dev[0].select_network(id, freq=2412)
  813. dev[0].wait_connected()
  814. dev[0].request("DISCONNECT")
  815. dev[0].wait_disconnected()
  816. # FILS: DHCP sendto failed: Invalid argument
  817. hapd.set("own_ip_addr", "127.0.0.3")
  818. hapd.set("dhcp_server", "127.0.0.2")
  819. hapd.set("dhcp_relay_port", "0")
  820. hapd.set("dhcp_server_port", "0")
  821. dev[0].select_network(id, freq=2412)
  822. dev[0].wait_connected()
  823. dev[0].request("DISCONNECT")
  824. dev[0].wait_disconnected()
  825. dev[0].request("FILS_HLP_REQ_FLUSH")
  826. def test_fils_sk_hlp_dhcp_parsing(dev, apdev):
  827. """FILS SK HLP and DHCP response parsing"""
  828. check_fils_capa(dev[0])
  829. check_erp_capa(dev[0])
  830. start_erp_as(apdev[1])
  831. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  832. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  833. sock.settimeout(5)
  834. sock.bind(("127.0.0.2", 67))
  835. bssid = apdev[0]['bssid']
  836. params = fils_hlp_config(fils_hlp_wait_time=30)
  837. params['dhcp_rapid_commit_proxy'] = '1'
  838. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  839. dev[0].scan_for_bss(bssid, freq=2412)
  840. dev[0].request("ERP_FLUSH")
  841. if "OK" not in dev[0].request("FILS_HLP_REQ_FLUSH"):
  842. raise Exception("Failed to flush pending FILS HLP requests")
  843. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  844. chaddr=dev[0].own_addr())
  845. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  846. raise Exception("FILS_HLP_REQ_ADD failed")
  847. id = dev[0].connect("fils", key_mgmt="FILS-SHA256",
  848. eap="PSK", identity="psk.user@example.com",
  849. password_hex="0123456789abcdef0123456789abcdef",
  850. erp="1", scan_freq="2412")
  851. dev[0].request("DISCONNECT")
  852. dev[0].wait_disconnected()
  853. dev[0].dump_monitor()
  854. with alloc_fail(hapd, 1, "fils_process_hlp"):
  855. dev[0].select_network(id, freq=2412)
  856. dev[0].wait_connected()
  857. dev[0].request("DISCONNECT")
  858. dev[0].wait_disconnected()
  859. dev[0].dump_monitor()
  860. dev[0].select_network(id, freq=2412)
  861. (msg,addr) = sock.recvfrom(1000)
  862. logger.debug("Received DHCP message from %s" % str(addr))
  863. dhcpdisc = build_dhcp(req=False, dhcp_msg=DHCPACK,
  864. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  865. #sock.sendto(dhcpdisc[2+20+8:], addr)
  866. chaddr = binascii.unhexlify(dev[0].own_addr().replace(':','')) + 10*'\x00'
  867. tests = [ "\x00",
  868. "\x02" + 500 * "\x00",
  869. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 500 * "\x00",
  870. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 16*"\x00" + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63",
  871. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 16*"\x00" + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x00\x11",
  872. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + 16*"\x00" + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x11\x01",
  873. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + chaddr + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x35\x00\xff",
  874. "\x02\x00\x00\x00" + 20*"\x00" + "\x7f\x00\x00\x03" + chaddr + 64*"\x00" + 128*"\x00" + "\x63\x82\x53\x63" + "\x35\x01\x00\xff",
  875. 1501 * "\x00" ]
  876. for t in tests:
  877. sock.sendto(t, addr)
  878. dev[0].wait_connected()
  879. dev[0].request("DISCONNECT")
  880. dev[0].wait_disconnected()
  881. # FILS: DHCP sendto failed: Invalid argument for second DHCP TX in proxy
  882. dev[0].dump_monitor()
  883. dev[0].select_network(id, freq=2412)
  884. (msg,addr) = sock.recvfrom(1000)
  885. logger.debug("Received DHCP message from %s" % str(addr))
  886. hapd.set("dhcp_server_port", "0")
  887. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  888. chaddr=dev[0].own_addr(), giaddr="127.0.0.3")
  889. sock.sendto(dhcpoffer[2+20+8:], addr)
  890. dev[0].wait_connected()
  891. dev[0].request("DISCONNECT")
  892. dev[0].wait_disconnected()
  893. hapd.set("dhcp_server_port", "67")
  894. # Options in DHCPOFFER
  895. dev[0].dump_monitor()
  896. dev[0].select_network(id, freq=2412)
  897. (msg,addr) = sock.recvfrom(1000)
  898. logger.debug("Received DHCP message from %s" % str(addr))
  899. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  900. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  901. extra_op="\x00\x11", opt_end=False)
  902. sock.sendto(dhcpoffer[2+20+8:], addr)
  903. (msg,addr) = sock.recvfrom(1000)
  904. logger.debug("Received DHCP message from %s" % str(addr))
  905. dev[0].wait_connected()
  906. dev[0].request("DISCONNECT")
  907. dev[0].wait_disconnected()
  908. # Options in DHCPOFFER (2)
  909. dev[0].dump_monitor()
  910. dev[0].select_network(id, freq=2412)
  911. (msg,addr) = sock.recvfrom(1000)
  912. logger.debug("Received DHCP message from %s" % str(addr))
  913. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  914. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  915. extra_op="\x11\x01", opt_end=False)
  916. sock.sendto(dhcpoffer[2+20+8:], addr)
  917. (msg,addr) = sock.recvfrom(1000)
  918. logger.debug("Received DHCP message from %s" % str(addr))
  919. dev[0].wait_connected()
  920. dev[0].request("DISCONNECT")
  921. dev[0].wait_disconnected()
  922. # Server ID in DHCPOFFER
  923. dev[0].dump_monitor()
  924. dev[0].select_network(id, freq=2412)
  925. (msg,addr) = sock.recvfrom(1000)
  926. logger.debug("Received DHCP message from %s" % str(addr))
  927. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  928. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  929. extra_op="\x36\x01\x30")
  930. sock.sendto(dhcpoffer[2+20+8:], addr)
  931. (msg,addr) = sock.recvfrom(1000)
  932. logger.debug("Received DHCP message from %s" % str(addr))
  933. dev[0].wait_connected()
  934. dev[0].request("DISCONNECT")
  935. dev[0].wait_disconnected()
  936. # FILS: Could not update DHCPDISCOVER
  937. dev[0].request("FILS_HLP_REQ_FLUSH")
  938. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  939. chaddr=dev[0].own_addr(),
  940. extra_op="\x00\x11", opt_end=False)
  941. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  942. raise Exception("FILS_HLP_REQ_ADD failed")
  943. dev[0].dump_monitor()
  944. dev[0].select_network(id, freq=2412)
  945. (msg,addr) = sock.recvfrom(1000)
  946. logger.debug("Received DHCP message from %s" % str(addr))
  947. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  948. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  949. extra_op="\x36\x01\x30")
  950. sock.sendto(dhcpoffer[2+20+8:], addr)
  951. dev[0].wait_connected()
  952. dev[0].request("DISCONNECT")
  953. dev[0].wait_disconnected()
  954. # FILS: Could not update DHCPDISCOVER (2)
  955. dev[0].request("FILS_HLP_REQ_FLUSH")
  956. dhcpdisc = build_dhcp(req=True, dhcp_msg=DHCPDISCOVER,
  957. chaddr=dev[0].own_addr(),
  958. extra_op="\x11\x01", opt_end=False)
  959. if "OK" not in dev[0].request("FILS_HLP_REQ_ADD " + "ff:ff:ff:ff:ff:ff " + binascii.hexlify(dhcpdisc)):
  960. raise Exception("FILS_HLP_REQ_ADD failed")
  961. dev[0].dump_monitor()
  962. dev[0].select_network(id, freq=2412)
  963. (msg,addr) = sock.recvfrom(1000)
  964. logger.debug("Received DHCP message from %s" % str(addr))
  965. dhcpoffer = build_dhcp(req=False, dhcp_msg=DHCPOFFER, rapid_commit=False,
  966. chaddr=dev[0].own_addr(), giaddr="127.0.0.3",
  967. extra_op="\x36\x01\x30")
  968. sock.sendto(dhcpoffer[2+20+8:], addr)
  969. dev[0].wait_connected()
  970. dev[0].request("DISCONNECT")
  971. dev[0].wait_disconnected()
  972. dev[0].request("FILS_HLP_REQ_FLUSH")