tests: Make ap_hs20_fetch_osu more robust under heavy load
[mech_eap.git] / tests / hwsim / test_ap_hs20.py
1 # Hotspot 2.0 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
7 import time
8 import subprocess
9 import logging
10 logger = logging.getLogger()
11 import os
12 import os.path
13 import subprocess
14
15 import hostapd
16 from wlantest import Wlantest
17 from wpasupplicant import WpaSupplicant
18
19 def hs20_ap_params(ssid="test-hs20"):
20     params = hostapd.wpa2_params(ssid=ssid)
21     params['wpa_key_mgmt'] = "WPA-EAP"
22     params['ieee80211w'] = "1"
23     params['ieee8021x'] = "1"
24     params['auth_server_addr'] = "127.0.0.1"
25     params['auth_server_port'] = "1812"
26     params['auth_server_shared_secret'] = "radius"
27     params['interworking'] = "1"
28     params['access_network_type'] = "14"
29     params['internet'] = "1"
30     params['asra'] = "0"
31     params['esr'] = "0"
32     params['uesa'] = "0"
33     params['venue_group'] = "7"
34     params['venue_type'] = "1"
35     params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
36     params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
37                                      "fedcba" ]
38     params['domain_name'] = "example.com,another.example.com"
39     params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
40                             "0,another.example.com" ]
41     params['hs20'] = "1"
42     params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
43     params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
44     params['hs20_operating_class'] = "5173"
45     params['anqp_3gpp_cell_net'] = "244,91"
46     return params
47
48 def check_auto_select(dev, bssid):
49     dev.scan_for_bss(bssid, freq="2412")
50     dev.request("INTERWORKING_SELECT auto freq=2412")
51     ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
52     if ev is None:
53         raise Exception("Connection timed out")
54     if bssid not in ev:
55         raise Exception("Connected to incorrect network")
56     dev.request("REMOVE_NETWORK all")
57
58 def interworking_select(dev, bssid, type=None, no_match=False, freq=None):
59     dev.dump_monitor()
60     if bssid and freq and not no_match:
61         dev.scan_for_bss(bssid, freq=freq)
62     freq_extra = " freq=" + freq if freq else ""
63     dev.request("INTERWORKING_SELECT" + freq_extra)
64     ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
65                         timeout=15)
66     if ev is None:
67         raise Exception("Network selection timed out");
68     if no_match:
69         if "INTERWORKING-NO-MATCH" not in ev:
70             raise Exception("Unexpected network match")
71         return
72     if "INTERWORKING-NO-MATCH" in ev:
73         logger.info("Matching network not found - try again")
74         dev.dump_monitor()
75         dev.request("INTERWORKING_SELECT" + freq_extra)
76         ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
77                             timeout=15)
78         if ev is None:
79             raise Exception("Network selection timed out");
80         if "INTERWORKING-NO-MATCH" in ev:
81             raise Exception("Matching network not found")
82     if bssid and bssid not in ev:
83         raise Exception("Unexpected BSSID in match")
84     if type and "type=" + type not in ev:
85         raise Exception("Network type not recognized correctly")
86
87 def check_sp_type(dev, sp_type):
88     type = dev.get_status_field("sp_type")
89     if type is None:
90         raise Exception("sp_type not available")
91     if type != sp_type:
92         raise Exception("sp_type did not indicate home network")
93
94 def hlr_auc_gw_available():
95     if not os.path.exists("/tmp/hlr_auc_gw.sock"):
96         logger.info("No hlr_auc_gw available");
97         return False
98     if not os.path.exists("../../hostapd/hlr_auc_gw"):
99         logger.info("No hlr_auc_gw available");
100         return False
101     return True
102
103 def interworking_ext_sim_connect(dev, bssid, method):
104     dev.request("INTERWORKING_CONNECT " + bssid)
105     interworking_ext_sim_auth(dev, method)
106
107 def interworking_ext_sim_auth(dev, method):
108     ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
109     if ev is None:
110         raise Exception("Network connected timed out")
111     if "(" + method + ")" not in ev:
112         raise Exception("Unexpected EAP method selection")
113
114     ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
115     if ev is None:
116         raise Exception("Wait for external SIM processing request timed out")
117     p = ev.split(':', 2)
118     if p[1] != "GSM-AUTH":
119         raise Exception("Unexpected CTRL-REQ-SIM type")
120     id = p[0].split('-')[3]
121     rand = p[2].split(' ')[0]
122
123     res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
124                                    "-m",
125                                    "auth_serv/hlr_auc_gw.milenage_db",
126                                    "GSM-AUTH-REQ 232010000000000 " + rand])
127     if "GSM-AUTH-RESP" not in res:
128         raise Exception("Unexpected hlr_auc_gw response")
129     resp = res.split(' ')[2].rstrip()
130
131     dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
132     ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
133     if ev is None:
134         raise Exception("Connection timed out")
135
136 def interworking_connect(dev, bssid, method):
137     dev.request("INTERWORKING_CONNECT " + bssid)
138     interworking_auth(dev, method)
139
140 def interworking_auth(dev, method):
141     ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
142     if ev is None:
143         raise Exception("Network connected timed out")
144     if "(" + method + ")" not in ev:
145         raise Exception("Unexpected EAP method selection")
146
147     ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
148     if ev is None:
149         raise Exception("Connection timed out")
150
151 def check_probe_resp(wt, bssid_unexpected, bssid_expected):
152     if bssid_unexpected:
153         count = wt.get_bss_counter("probe_response", bssid_unexpected)
154         if count > 0:
155             raise Exception("Unexpected Probe Response frame from AP")
156
157     if bssid_expected:
158         count = wt.get_bss_counter("probe_response", bssid_expected)
159         if count == 0:
160             raise Exception("No Probe Response frame from AP")
161
162 def test_ap_anqp_sharing(dev, apdev):
163     """ANQP sharing within ESS and explicit unshare"""
164     bssid = apdev[0]['bssid']
165     params = hs20_ap_params()
166     params['hessid'] = bssid
167     hostapd.add_ap(apdev[0]['ifname'], params)
168
169     bssid2 = apdev[1]['bssid']
170     params = hs20_ap_params()
171     params['hessid'] = bssid
172     params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
173     hostapd.add_ap(apdev[1]['ifname'], params)
174
175     dev[0].hs20_enable()
176     id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
177                                   'password': "secret",
178                                   'domain': "example.com" })
179     logger.info("Normal network selection with shared ANQP results")
180     dev[0].scan_for_bss(bssid, freq="2412")
181     dev[0].scan_for_bss(bssid2, freq="2412")
182     interworking_select(dev[0], None, "home", freq="2412")
183     dev[0].dump_monitor()
184
185     res1 = dev[0].get_bss(bssid)
186     res2 = dev[0].get_bss(bssid2)
187     if res1['anqp_nai_realm'] != res2['anqp_nai_realm']:
188         raise Exception("ANQP results were not shared between BSSes")
189
190     logger.info("Explicit ANQP request to unshare ANQP results")
191     dev[0].request("ANQP_GET " + bssid + " 263")
192     ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
193     if ev is None:
194         raise Exception("ANQP operation timed out")
195
196     dev[0].request("ANQP_GET " + bssid2 + " 263")
197     ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
198     if ev is None:
199         raise Exception("ANQP operation timed out")
200
201     res1 = dev[0].get_bss(bssid)
202     res2 = dev[0].get_bss(bssid2)
203     if res1['anqp_nai_realm'] == res2['anqp_nai_realm']:
204         raise Exception("ANQP results were not unshared")
205
206 def test_ap_nai_home_realm_query(dev, apdev):
207     """NAI Home Realm Query"""
208     bssid = apdev[0]['bssid']
209     params = hs20_ap_params()
210     params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
211                             "0,another.example.org" ]
212     hostapd.add_ap(apdev[0]['ifname'], params)
213
214     dev[0].scan(freq="2412")
215     dev[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid + " realm=example.com")
216     ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
217     if ev is None:
218         raise Exception("ANQP operation timed out")
219     nai1 = dev[0].get_bss(bssid)['anqp_nai_realm']
220     dev[0].dump_monitor()
221
222     dev[0].request("ANQP_GET " + bssid + " 263")
223     ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
224     if ev is None:
225         raise Exception("ANQP operation timed out")
226     nai2 = dev[0].get_bss(bssid)['anqp_nai_realm']
227
228     if len(nai1) >= len(nai2):
229         raise Exception("Unexpected NAI Realm list response lengths")
230     if "example.com".encode('hex') not in nai1:
231         raise Exception("Home realm not reported")
232     if "example.org".encode('hex') in nai1:
233         raise Exception("Non-home realm reported")
234     if "example.com".encode('hex') not in nai2:
235         raise Exception("Home realm not reported in wildcard query")
236     if "example.org".encode('hex') not in nai2:
237         raise Exception("Non-home realm not reported in wildcard query ")
238
239 def test_ap_interworking_scan_filtering(dev, apdev):
240     """Interworking scan filtering with HESSID and access network type"""
241     bssid = apdev[0]['bssid']
242     params = hs20_ap_params()
243     ssid = "test-hs20-ap1"
244     params['ssid'] = ssid
245     params['hessid'] = bssid
246     hostapd.add_ap(apdev[0]['ifname'], params)
247
248     bssid2 = apdev[1]['bssid']
249     params = hs20_ap_params()
250     ssid2 = "test-hs20-ap2"
251     params['ssid'] = ssid2
252     params['hessid'] = bssid2
253     params['access_network_type'] = "1"
254     del params['venue_group']
255     del params['venue_type']
256     hostapd.add_ap(apdev[1]['ifname'], params)
257
258     dev[0].hs20_enable()
259
260     wt = Wlantest()
261     wt.flush()
262
263     logger.info("Check probe request filtering based on HESSID")
264
265     dev[0].request("SET hessid " + bssid2)
266     dev[0].scan(freq="2412")
267     time.sleep(0.03)
268     check_probe_resp(wt, bssid, bssid2)
269
270     logger.info("Check probe request filtering based on access network type")
271
272     wt.clear_bss_counters(bssid)
273     wt.clear_bss_counters(bssid2)
274     dev[0].request("SET hessid 00:00:00:00:00:00")
275     dev[0].request("SET access_network_type 14")
276     dev[0].scan(freq="2412")
277     time.sleep(0.03)
278     check_probe_resp(wt, bssid2, bssid)
279
280     wt.clear_bss_counters(bssid)
281     wt.clear_bss_counters(bssid2)
282     dev[0].request("SET hessid 00:00:00:00:00:00")
283     dev[0].request("SET access_network_type 1")
284     dev[0].scan(freq="2412")
285     time.sleep(0.03)
286     check_probe_resp(wt, bssid, bssid2)
287
288     logger.info("Check probe request filtering based on HESSID and ANT")
289
290     wt.clear_bss_counters(bssid)
291     wt.clear_bss_counters(bssid2)
292     dev[0].request("SET hessid " + bssid)
293     dev[0].request("SET access_network_type 14")
294     dev[0].scan(freq="2412")
295     time.sleep(0.03)
296     check_probe_resp(wt, bssid2, bssid)
297
298     wt.clear_bss_counters(bssid)
299     wt.clear_bss_counters(bssid2)
300     dev[0].request("SET hessid " + bssid2)
301     dev[0].request("SET access_network_type 14")
302     dev[0].scan(freq="2412")
303     time.sleep(0.03)
304     check_probe_resp(wt, bssid, None)
305     check_probe_resp(wt, bssid2, None)
306
307     wt.clear_bss_counters(bssid)
308     wt.clear_bss_counters(bssid2)
309     dev[0].request("SET hessid " + bssid)
310     dev[0].request("SET access_network_type 1")
311     dev[0].scan(freq="2412")
312     time.sleep(0.03)
313     check_probe_resp(wt, bssid, None)
314     check_probe_resp(wt, bssid2, None)
315
316 def test_ap_hs20_select(dev, apdev):
317     """Hotspot 2.0 network selection"""
318     bssid = apdev[0]['bssid']
319     params = hs20_ap_params()
320     params['hessid'] = bssid
321     hostapd.add_ap(apdev[0]['ifname'], params)
322
323     dev[0].hs20_enable()
324     id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
325                                   'password': "secret",
326                                   'domain': "example.com" })
327     interworking_select(dev[0], bssid, "home")
328
329     dev[0].remove_cred(id)
330     id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
331                                   'password': "secret",
332                                   'domain': "no.match.example.com" })
333     interworking_select(dev[0], bssid, "roaming", freq="2412")
334
335     dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
336     interworking_select(dev[0], bssid, no_match=True, freq="2412")
337
338     bssid2 = apdev[1]['bssid']
339     params = hs20_ap_params()
340     params['nai_realm'] = [ "0,example.org,21" ]
341     params['hessid'] = bssid2
342     params['domain_name'] = "example.org"
343     hostapd.add_ap(apdev[1]['ifname'], params)
344     dev[0].remove_cred(id)
345     id = dev[0].add_cred_values({ 'realm': "example.org", 'username': "test",
346                                   'password': "secret",
347                                   'domain': "example.org" })
348     interworking_select(dev[0], bssid2, "home", freq="2412")
349
350 def hs20_simulated_sim(dev, ap, method):
351     bssid = ap['bssid']
352     params = hs20_ap_params()
353     params['hessid'] = bssid
354     params['anqp_3gpp_cell_net'] = "555,444"
355     params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
356     hostapd.add_ap(ap['ifname'], params)
357
358     dev.hs20_enable()
359     dev.add_cred_values({ 'imsi': "555444-333222111", 'eap': method,
360                           'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
361     interworking_select(dev, "home", freq="2412")
362     interworking_connect(dev, bssid, method)
363     check_sp_type(dev, "home")
364
365 def test_ap_hs20_sim(dev, apdev):
366     """Hotspot 2.0 with simulated SIM and EAP-SIM"""
367     if not hlr_auc_gw_available():
368         return "skip"
369     hs20_simulated_sim(dev[0], apdev[0], "SIM")
370     dev[0].request("INTERWORKING_SELECT auto freq=2412")
371     ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
372     if ev is None:
373         raise Exception("Timeout on already-connected event")
374
375 def test_ap_hs20_aka(dev, apdev):
376     """Hotspot 2.0 with simulated USIM and EAP-AKA"""
377     if not hlr_auc_gw_available():
378         return "skip"
379     hs20_simulated_sim(dev[0], apdev[0], "AKA")
380
381 def test_ap_hs20_aka_prime(dev, apdev):
382     """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
383     if not hlr_auc_gw_available():
384         return "skip"
385     hs20_simulated_sim(dev[0], apdev[0], "AKA'")
386
387 def test_ap_hs20_ext_sim(dev, apdev):
388     """Hotspot 2.0 with external SIM processing"""
389     if not hlr_auc_gw_available():
390         return "skip"
391     bssid = apdev[0]['bssid']
392     params = hs20_ap_params()
393     params['hessid'] = bssid
394     params['anqp_3gpp_cell_net'] = "232,01"
395     params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
396     hostapd.add_ap(apdev[0]['ifname'], params)
397
398     dev[0].hs20_enable()
399     dev[0].request("SET external_sim 1")
400     dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
401     interworking_select(dev[0], "home", freq="2412")
402     interworking_ext_sim_connect(dev[0], bssid, "SIM")
403     check_sp_type(dev[0], "home")
404
405 def test_ap_hs20_ext_sim_roaming(dev, apdev):
406     """Hotspot 2.0 with external SIM processing in roaming network"""
407     if not hlr_auc_gw_available():
408         return "skip"
409     bssid = apdev[0]['bssid']
410     params = hs20_ap_params()
411     params['hessid'] = bssid
412     params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
413     params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
414     hostapd.add_ap(apdev[0]['ifname'], params)
415
416     dev[0].hs20_enable()
417     dev[0].request("SET external_sim 1")
418     dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
419     interworking_select(dev[0], "roaming", freq="2412")
420     interworking_ext_sim_connect(dev[0], bssid, "SIM")
421     check_sp_type(dev[0], "roaming")
422
423 def test_ap_hs20_username(dev, apdev):
424     """Hotspot 2.0 connection in username/password credential"""
425     bssid = apdev[0]['bssid']
426     params = hs20_ap_params()
427     params['hessid'] = bssid
428     params['disable_dgaf'] = '1'
429     hostapd.add_ap(apdev[0]['ifname'], params)
430
431     dev[0].hs20_enable()
432     id = dev[0].add_cred_values({ 'realm': "example.com",
433                                   'username': "hs20-test",
434                                   'password': "password",
435                                   'ca_cert': "auth_serv/ca.pem",
436                                   'domain': "example.com",
437                                   'update_identifier': "1234" })
438     interworking_select(dev[0], bssid, "home", freq="2412")
439     interworking_connect(dev[0], bssid, "TTLS")
440     check_sp_type(dev[0], "home")
441     status = dev[0].get_status()
442     if status['pairwise_cipher'] != "CCMP":
443         raise Exception("Unexpected pairwise cipher")
444     if status['hs20'] != "2":
445         raise Exception("Unexpected HS 2.0 support indication")
446
447     dev[1].connect("test-hs20", key_mgmt="WPA-EAP", eap="TTLS",
448                    identity="hs20-test", password="password",
449                    ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
450                    scan_freq="2412")
451
452 def test_ap_hs20_connect_api(dev, apdev):
453     """Hotspot 2.0 connection with connect API"""
454     bssid = apdev[0]['bssid']
455     params = hs20_ap_params()
456     params['hessid'] = bssid
457     params['disable_dgaf'] = '1'
458     hostapd.add_ap(apdev[0]['ifname'], params)
459
460     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
461     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
462     wpas.hs20_enable()
463     id = wpas.add_cred_values({ 'realm': "example.com",
464                                   'username': "hs20-test",
465                                   'password': "password",
466                                   'ca_cert': "auth_serv/ca.pem",
467                                   'domain': "example.com",
468                                   'update_identifier': "1234" })
469     interworking_select(wpas, bssid, "home", freq="2412")
470     interworking_connect(wpas, bssid, "TTLS")
471     check_sp_type(wpas, "home")
472     status = wpas.get_status()
473     if status['pairwise_cipher'] != "CCMP":
474         raise Exception("Unexpected pairwise cipher")
475     if status['hs20'] != "2":
476         raise Exception("Unexpected HS 2.0 support indication")
477
478 def test_ap_hs20_auto_interworking(dev, apdev):
479     """Hotspot 2.0 connection with auto_interworking=1"""
480     bssid = apdev[0]['bssid']
481     params = hs20_ap_params()
482     params['hessid'] = bssid
483     params['disable_dgaf'] = '1'
484     hostapd.add_ap(apdev[0]['ifname'], params)
485
486     dev[0].hs20_enable(auto_interworking=True)
487     id = dev[0].add_cred_values({ 'realm': "example.com",
488                                   'username': "hs20-test",
489                                   'password': "password",
490                                   'ca_cert': "auth_serv/ca.pem",
491                                   'domain': "example.com",
492                                   'update_identifier': "1234" })
493     dev[0].request("REASSOCIATE")
494     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
495     if ev is None:
496         raise Exception("Connection timed out")
497     check_sp_type(dev[0], "home")
498     status = dev[0].get_status()
499     if status['pairwise_cipher'] != "CCMP":
500         raise Exception("Unexpected pairwise cipher")
501     if status['hs20'] != "2":
502         raise Exception("Unexpected HS 2.0 support indication")
503
504 def test_ap_hs20_auto_interworking_no_cred_match(dev, apdev):
505     """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
506     bssid = apdev[0]['bssid']
507     params = { "ssid": "test" }
508     hostapd.add_ap(apdev[0]['ifname'], params)
509
510     dev[0].hs20_enable(auto_interworking=True)
511     dev[0].add_cred_values({ 'realm': "example.com",
512                              'username': "hs20-test",
513                              'password': "password",
514                              'ca_cert': "auth_serv/ca.pem",
515                              'domain': "example.com" })
516
517     id = dev[0].connect("test", psk="12345678", only_add_network=True)
518     dev[0].request("ENABLE_NETWORK %s" % id)
519     logger.info("Verify that scanning continues when there is partial network block match")
520     for i in range(0, 2):
521         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
522         if ev is None:
523             raise Exception("Scan timed out")
524         logger.info("Scan completed")
525
526 def eap_test(dev, ap, eap_params, method, user):
527     bssid = ap['bssid']
528     params = hs20_ap_params()
529     params['nai_realm'] = [ "0,example.com," + eap_params ]
530     hostapd.add_ap(ap['ifname'], params)
531
532     dev.hs20_enable()
533     dev.add_cred_values({ 'realm': "example.com",
534                           'username': user,
535                           'password': "password" })
536     interworking_select(dev, bssid, freq="2412")
537     interworking_connect(dev, bssid, method)
538
539 def test_ap_hs20_eap_unknown(dev, apdev):
540     """Hotspot 2.0 connection with unknown EAP method"""
541     bssid = apdev[0]['bssid']
542     params = hs20_ap_params()
543     params['nai_realm'] = "0,example.com,99"
544     hostapd.add_ap(apdev[0]['ifname'], params)
545
546     dev[0].hs20_enable()
547     dev[0].add_cred_values(default_cred())
548     interworking_select(dev[0], None, no_match=True, freq="2412")
549
550 def test_ap_hs20_eap_peap_mschapv2(dev, apdev):
551     """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
552     eap_test(dev[0], apdev[0], "25[3:26]", "PEAP", "user")
553
554 def test_ap_hs20_eap_peap_default(dev, apdev):
555     """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
556     eap_test(dev[0], apdev[0], "25", "PEAP", "user")
557
558 def test_ap_hs20_eap_peap_gtc(dev, apdev):
559     """Hotspot 2.0 connection with PEAP/GTC"""
560     eap_test(dev[0], apdev[0], "25[3:6]", "PEAP", "user")
561
562 def test_ap_hs20_eap_peap_unknown(dev, apdev):
563     """Hotspot 2.0 connection with PEAP/unknown"""
564     bssid = apdev[0]['bssid']
565     params = hs20_ap_params()
566     params['nai_realm'] = "0,example.com,25[3:99]"
567     hostapd.add_ap(apdev[0]['ifname'], params)
568
569     dev[0].hs20_enable()
570     dev[0].add_cred_values(default_cred())
571     interworking_select(dev[0], None, no_match=True, freq="2412")
572
573 def test_ap_hs20_eap_ttls_chap(dev, apdev):
574     """Hotspot 2.0 connection with TTLS/CHAP"""
575     eap_test(dev[0], apdev[0], "21[2:2]", "TTLS", "chap user")
576
577 def test_ap_hs20_eap_ttls_mschap(dev, apdev):
578     """Hotspot 2.0 connection with TTLS/MSCHAP"""
579     eap_test(dev[0], apdev[0], "21[2:3]", "TTLS", "mschap user")
580
581 def test_ap_hs20_eap_ttls_eap_mschapv2(dev, apdev):
582     """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
583     eap_test(dev[0], apdev[0], "21[3:26][6:7][99:99]", "TTLS", "user")
584
585 def test_ap_hs20_eap_ttls_eap_unknown(dev, apdev):
586     """Hotspot 2.0 connection with TTLS/EAP-unknown"""
587     bssid = apdev[0]['bssid']
588     params = hs20_ap_params()
589     params['nai_realm'] = "0,example.com,21[3:99]"
590     hostapd.add_ap(apdev[0]['ifname'], params)
591
592     dev[0].hs20_enable()
593     dev[0].add_cred_values(default_cred())
594     interworking_select(dev[0], None, no_match=True, freq="2412")
595
596 def test_ap_hs20_eap_ttls_eap_unsupported(dev, apdev):
597     """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
598     bssid = apdev[0]['bssid']
599     params = hs20_ap_params()
600     params['nai_realm'] = "0,example.com,21[3:5]"
601     hostapd.add_ap(apdev[0]['ifname'], params)
602
603     dev[0].hs20_enable()
604     dev[0].add_cred_values(default_cred())
605     interworking_select(dev[0], None, no_match=True, freq="2412")
606
607 def test_ap_hs20_eap_ttls_unknown(dev, apdev):
608     """Hotspot 2.0 connection with TTLS/unknown"""
609     bssid = apdev[0]['bssid']
610     params = hs20_ap_params()
611     params['nai_realm'] = "0,example.com,21[2:5]"
612     hostapd.add_ap(apdev[0]['ifname'], params)
613
614     dev[0].hs20_enable()
615     dev[0].add_cred_values(default_cred())
616     interworking_select(dev[0], None, no_match=True, freq="2412")
617
618 def test_ap_hs20_eap_fast_mschapv2(dev, apdev):
619     """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
620     eap_test(dev[0], apdev[0], "43[3:26]", "FAST", "user")
621
622 def test_ap_hs20_eap_fast_gtc(dev, apdev):
623     """Hotspot 2.0 connection with FAST/EAP-GTC"""
624     eap_test(dev[0], apdev[0], "43[3:6]", "FAST", "user")
625
626 def test_ap_hs20_eap_tls(dev, apdev):
627     """Hotspot 2.0 connection with EAP-TLS"""
628     bssid = apdev[0]['bssid']
629     params = hs20_ap_params()
630     params['nai_realm'] = [ "0,example.com,13[5:6]" ]
631     hostapd.add_ap(apdev[0]['ifname'], params)
632
633     dev[0].hs20_enable()
634     dev[0].add_cred_values({ 'realm': "example.com",
635                              'username': "certificate-user",
636                              'ca_cert': "auth_serv/ca.pem",
637                              'client_cert': "auth_serv/user.pem",
638                              'private_key': "auth_serv/user.key"})
639     interworking_select(dev[0], bssid, freq="2412")
640     interworking_connect(dev[0], bssid, "TLS")
641
642 def test_ap_hs20_eap_cert_unknown(dev, apdev):
643     """Hotspot 2.0 connection with certificate, but unknown EAP method"""
644     bssid = apdev[0]['bssid']
645     params = hs20_ap_params()
646     params['nai_realm'] = [ "0,example.com,99[5:6]" ]
647     hostapd.add_ap(apdev[0]['ifname'], params)
648
649     dev[0].hs20_enable()
650     dev[0].add_cred_values({ 'realm': "example.com",
651                              'username': "certificate-user",
652                              'ca_cert': "auth_serv/ca.pem",
653                              'client_cert': "auth_serv/user.pem",
654                              'private_key': "auth_serv/user.key"})
655     interworking_select(dev[0], None, no_match=True, freq="2412")
656
657 def test_ap_hs20_eap_cert_unsupported(dev, apdev):
658     """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
659     bssid = apdev[0]['bssid']
660     params = hs20_ap_params()
661     params['nai_realm'] = [ "0,example.com,21[5:6]" ]
662     hostapd.add_ap(apdev[0]['ifname'], params)
663
664     dev[0].hs20_enable()
665     dev[0].add_cred_values({ 'realm': "example.com",
666                              'username': "certificate-user",
667                              'ca_cert': "auth_serv/ca.pem",
668                              'client_cert': "auth_serv/user.pem",
669                              'private_key': "auth_serv/user.key"})
670     interworking_select(dev[0], None, no_match=True, freq="2412")
671
672 def test_ap_hs20_eap_invalid_cred(dev, apdev):
673     """Hotspot 2.0 connection with invalid cred configuration"""
674     bssid = apdev[0]['bssid']
675     params = hs20_ap_params()
676     hostapd.add_ap(apdev[0]['ifname'], params)
677
678     dev[0].hs20_enable()
679     dev[0].add_cred_values({ 'realm': "example.com",
680                              'username': "certificate-user",
681                              'client_cert': "auth_serv/user.pem" })
682     interworking_select(dev[0], None, no_match=True, freq="2412")
683
684 def test_ap_hs20_nai_realms(dev, apdev):
685     """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
686     bssid = apdev[0]['bssid']
687     params = hs20_ap_params()
688     params['hessid'] = bssid
689     params['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
690     hostapd.add_ap(apdev[0]['ifname'], params)
691
692     dev[0].hs20_enable()
693     id = dev[0].add_cred_values({ 'realm': "example.com",
694                                   'username': "pap user",
695                                   'password': "password",
696                                   'domain': "example.com" })
697     interworking_select(dev[0], bssid, "home", freq="2412")
698     interworking_connect(dev[0], bssid, "TTLS")
699     check_sp_type(dev[0], "home")
700
701 def test_ap_hs20_roaming_consortium(dev, apdev):
702     """Hotspot 2.0 connection based on roaming consortium match"""
703     bssid = apdev[0]['bssid']
704     params = hs20_ap_params()
705     params['hessid'] = bssid
706     hostapd.add_ap(apdev[0]['ifname'], params)
707
708     dev[0].hs20_enable()
709     for consortium in [ "112233", "1020304050", "010203040506", "fedcba" ]:
710         id = dev[0].add_cred_values({ 'username': "user",
711                                       'password': "password",
712                                       'domain': "example.com",
713                                       'roaming_consortium': consortium,
714                                       'eap': "PEAP" })
715         interworking_select(dev[0], bssid, "home", freq="2412")
716         interworking_connect(dev[0], bssid, "PEAP")
717         check_sp_type(dev[0], "home")
718         dev[0].request("INTERWORKING_SELECT auto freq=2412")
719         ev = dev[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout=15)
720         if ev is None:
721             raise Exception("Timeout on already-connected event")
722         dev[0].remove_cred(id)
723
724 def test_ap_hs20_username_roaming(dev, apdev):
725     """Hotspot 2.0 connection in username/password credential (roaming)"""
726     bssid = apdev[0]['bssid']
727     params = hs20_ap_params()
728     params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
729                             "0,roaming.example.com,21[2:4][5:7]",
730                             "0,another.example.com" ]
731     params['domain_name'] = "another.example.com"
732     params['hessid'] = bssid
733     hostapd.add_ap(apdev[0]['ifname'], params)
734
735     dev[0].hs20_enable()
736     id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
737                                   'username': "hs20-test",
738                                   'password': "password",
739                                   'domain': "example.com" })
740     interworking_select(dev[0], bssid, "roaming", freq="2412")
741     interworking_connect(dev[0], bssid, "TTLS")
742     check_sp_type(dev[0], "roaming")
743
744 def test_ap_hs20_username_unknown(dev, apdev):
745     """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
746     bssid = apdev[0]['bssid']
747     params = hs20_ap_params()
748     params['hessid'] = bssid
749     hostapd.add_ap(apdev[0]['ifname'], params)
750
751     dev[0].hs20_enable()
752     id = dev[0].add_cred_values({ 'realm': "example.com",
753                                   'username': "hs20-test",
754                                   'password': "password" })
755     interworking_select(dev[0], bssid, "unknown", freq="2412")
756     interworking_connect(dev[0], bssid, "TTLS")
757     check_sp_type(dev[0], "unknown")
758
759 def test_ap_hs20_username_unknown2(dev, apdev):
760     """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
761     bssid = apdev[0]['bssid']
762     params = hs20_ap_params()
763     params['hessid'] = bssid
764     del params['domain_name']
765     hostapd.add_ap(apdev[0]['ifname'], params)
766
767     dev[0].hs20_enable()
768     id = dev[0].add_cred_values({ 'realm': "example.com",
769                                   'username': "hs20-test",
770                                   'password': "password",
771                                   'domain': "example.com" })
772     interworking_select(dev[0], bssid, "unknown", freq="2412")
773     interworking_connect(dev[0], bssid, "TTLS")
774     check_sp_type(dev[0], "unknown")
775
776 def test_ap_hs20_gas_while_associated(dev, apdev):
777     """Hotspot 2.0 connection with GAS query while associated"""
778     bssid = apdev[0]['bssid']
779     params = hs20_ap_params()
780     params['hessid'] = bssid
781     hostapd.add_ap(apdev[0]['ifname'], params)
782
783     dev[0].hs20_enable()
784     id = dev[0].add_cred_values({ 'realm': "example.com",
785                                   'username': "hs20-test",
786                                   'password': "password",
787                                   'domain': "example.com" })
788     interworking_select(dev[0], bssid, "home", freq="2412")
789     interworking_connect(dev[0], bssid, "TTLS")
790
791     logger.info("Verifying GAS query while associated")
792     dev[0].request("FETCH_ANQP")
793     for i in range(0, 6):
794         ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
795         if ev is None:
796             raise Exception("Operation timed out")
797
798 def test_ap_hs20_gas_while_associated_with_pmf(dev, apdev):
799     """Hotspot 2.0 connection with GAS query while associated and using PMF"""
800     bssid = apdev[0]['bssid']
801     params = hs20_ap_params()
802     params['hessid'] = bssid
803     hostapd.add_ap(apdev[0]['ifname'], params)
804
805     bssid2 = apdev[1]['bssid']
806     params = hs20_ap_params()
807     params['hessid'] = bssid2
808     params['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
809     hostapd.add_ap(apdev[1]['ifname'], params)
810
811     dev[0].hs20_enable()
812     dev[0].request("SET pmf 2")
813     id = dev[0].add_cred_values({ 'realm': "example.com",
814                                   'username': "hs20-test",
815                                   'password': "password",
816                                   'domain': "example.com" })
817     interworking_select(dev[0], bssid, "home", freq="2412")
818     interworking_connect(dev[0], bssid, "TTLS")
819
820     logger.info("Verifying GAS query while associated")
821     dev[0].request("FETCH_ANQP")
822     for i in range(0, 2 * 6):
823         ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
824         if ev is None:
825             raise Exception("Operation timed out")
826
827 def test_ap_hs20_gas_frag_while_associated(dev, apdev):
828     """Hotspot 2.0 connection with fragmented GAS query while associated"""
829     bssid = apdev[0]['bssid']
830     params = hs20_ap_params()
831     params['hessid'] = bssid
832     hostapd.add_ap(apdev[0]['ifname'], params)
833     hapd = hostapd.Hostapd(apdev[0]['ifname'])
834     hapd.set("gas_frag_limit", "50")
835
836     dev[0].hs20_enable()
837     id = dev[0].add_cred_values({ 'realm': "example.com",
838                                   'username': "hs20-test",
839                                   'password': "password",
840                                   'domain': "example.com" })
841     interworking_select(dev[0], bssid, "home", freq="2412")
842     interworking_connect(dev[0], bssid, "TTLS")
843
844     logger.info("Verifying GAS query while associated")
845     dev[0].request("FETCH_ANQP")
846     for i in range(0, 6):
847         ev = dev[0].wait_event(["RX-ANQP"], timeout=5)
848         if ev is None:
849             raise Exception("Operation timed out")
850
851 def test_ap_hs20_multiple_connects(dev, apdev):
852     """Hotspot 2.0 connection through multiple network selections"""
853     bssid = apdev[0]['bssid']
854     params = hs20_ap_params()
855     params['hessid'] = bssid
856     hostapd.add_ap(apdev[0]['ifname'], params)
857
858     dev[0].hs20_enable()
859     values = { 'realm': "example.com",
860                'username': "hs20-test",
861                'password': "password",
862                'domain': "example.com" }
863     id = dev[0].add_cred_values(values)
864
865     dev[0].scan_for_bss(bssid, freq="2412")
866
867     for i in range(0, 3):
868         logger.info("Starting Interworking network selection")
869         dev[0].request("INTERWORKING_SELECT auto freq=2412")
870         while True:
871             ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
872                                     "INTERWORKING-ALREADY-CONNECTED",
873                                     "CTRL-EVENT-CONNECTED"], timeout=15)
874             if ev is None:
875                 raise Exception("Connection timed out")
876             if "INTERWORKING-NO-MATCH" in ev:
877                 raise Exception("Matching AP not found")
878             if "CTRL-EVENT-CONNECTED" in ev:
879                 break
880             if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
881                 break
882         if i == 0:
883             dev[0].request("DISCONNECT")
884         dev[0].dump_monitor()
885
886     networks = dev[0].list_networks()
887     if len(networks) > 1:
888         raise Exception("Duplicated network block detected")
889
890 def test_ap_hs20_disallow_aps(dev, apdev):
891     """Hotspot 2.0 connection and disallow_aps"""
892     bssid = apdev[0]['bssid']
893     params = hs20_ap_params()
894     params['hessid'] = bssid
895     hostapd.add_ap(apdev[0]['ifname'], params)
896
897     dev[0].hs20_enable()
898     values = { 'realm': "example.com",
899                'username': "hs20-test",
900                'password': "password",
901                'domain': "example.com" }
902     id = dev[0].add_cred_values(values)
903
904     dev[0].scan_for_bss(bssid, freq="2412")
905
906     logger.info("Verify disallow_aps bssid")
907     dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
908     dev[0].request("INTERWORKING_SELECT auto")
909     ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
910     if ev is None:
911         raise Exception("Network selection timed out")
912     dev[0].dump_monitor()
913
914     logger.info("Verify disallow_aps ssid")
915     dev[0].request("SET disallow_aps ssid 746573742d68733230")
916     dev[0].request("INTERWORKING_SELECT auto freq=2412")
917     ev = dev[0].wait_event(["INTERWORKING-NO-MATCH"], timeout=15)
918     if ev is None:
919         raise Exception("Network selection timed out")
920     dev[0].dump_monitor()
921
922     logger.info("Verify disallow_aps clear")
923     dev[0].request("SET disallow_aps ")
924     interworking_select(dev[0], bssid, "home", freq="2412")
925
926     dev[0].request("SET disallow_aps bssid " + bssid.translate(None, ':'))
927     ret = dev[0].request("INTERWORKING_CONNECT " + bssid)
928     if "FAIL" not in ret:
929         raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
930
931 def policy_test(dev, ap, values, only_one=True):
932     dev.dump_monitor()
933     if ap:
934         logger.info("Verify network selection to AP " + ap['ifname'])
935         bssid = ap['bssid']
936         dev.scan_for_bss(bssid, freq="2412")
937     else:
938         logger.info("Verify network selection")
939         bssid = None
940     dev.hs20_enable()
941     id = dev.add_cred_values(values)
942     dev.request("INTERWORKING_SELECT auto freq=2412")
943     events = []
944     while True:
945         ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
946                              "INTERWORKING-BLACKLISTED",
947                              "INTERWORKING-SELECTED"], timeout=15)
948         if ev is None:
949             raise Exception("Network selection timed out")
950         events.append(ev)
951         if "INTERWORKING-NO-MATCH" in ev:
952             raise Exception("Matching AP not found")
953         if bssid and only_one and "INTERWORKING-AP" in ev and bssid not in ev:
954             raise Exception("Unexpected AP claimed acceptable")
955         if "INTERWORKING-SELECTED" in ev:
956             if bssid and bssid not in ev:
957                 raise Exception("Selected incorrect BSS")
958             break
959
960     ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
961     if ev is None:
962         raise Exception("Connection timed out")
963     if bssid and bssid not in ev:
964         raise Exception("Connected to incorrect BSS")
965
966     conn_bssid = dev.get_status_field("bssid")
967     if bssid and conn_bssid != bssid:
968         raise Exception("bssid information points to incorrect BSS")
969
970     dev.remove_cred(id)
971     dev.dump_monitor()
972     return events
973
974 def default_cred(domain=None):
975     cred = { 'realm': "example.com",
976              'username': "hs20-test",
977              'password': "password" }
978     if domain:
979         cred['domain'] = domain
980     return cred
981
982 def test_ap_hs20_prefer_home(dev, apdev):
983     """Hotspot 2.0 required roaming consortium"""
984     params = hs20_ap_params()
985     params['domain_name'] = "example.org"
986     hostapd.add_ap(apdev[0]['ifname'], params)
987
988     params = hs20_ap_params()
989     params['ssid'] = "test-hs20-other"
990     params['domain_name'] = "example.com"
991     hostapd.add_ap(apdev[1]['ifname'], params)
992
993     values = default_cred()
994     values['domain'] = "example.com"
995     policy_test(dev[0], apdev[1], values, only_one=False)
996     values['domain'] = "example.org"
997     policy_test(dev[0], apdev[0], values, only_one=False)
998
999 def test_ap_hs20_req_roaming_consortium(dev, apdev):
1000     """Hotspot 2.0 required roaming consortium"""
1001     params = hs20_ap_params()
1002     hostapd.add_ap(apdev[0]['ifname'], params)
1003
1004     params = hs20_ap_params()
1005     params['ssid'] = "test-hs20-other"
1006     params['roaming_consortium'] = [ "223344" ]
1007     hostapd.add_ap(apdev[1]['ifname'], params)
1008
1009     values = default_cred()
1010     values['required_roaming_consortium'] = "223344"
1011     policy_test(dev[0], apdev[1], values)
1012     values['required_roaming_consortium'] = "112233"
1013     policy_test(dev[0], apdev[0], values)
1014
1015     id = dev[0].add_cred()
1016     dev[0].set_cred(id, "required_roaming_consortium", "112233")
1017     dev[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1018
1019     for val in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1020         if "FAIL" not in dev[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val)):
1021             raise Exception("Invalid roaming consortium value accepted: " + val)
1022
1023 def test_ap_hs20_excluded_ssid(dev, apdev):
1024     """Hotspot 2.0 exclusion based on SSID"""
1025     params = hs20_ap_params()
1026     params['roaming_consortium'] = [ "223344" ]
1027     params['anqp_3gpp_cell_net'] = "555,444"
1028     hostapd.add_ap(apdev[0]['ifname'], params)
1029
1030     params = hs20_ap_params()
1031     params['ssid'] = "test-hs20-other"
1032     params['roaming_consortium'] = [ "223344" ]
1033     params['anqp_3gpp_cell_net'] = "555,444"
1034     hostapd.add_ap(apdev[1]['ifname'], params)
1035
1036     values = default_cred()
1037     values['excluded_ssid'] = "test-hs20"
1038     events = policy_test(dev[0], apdev[1], values)
1039     ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1040     if len(ev) != 1:
1041         raise Exception("Excluded network not reported")
1042     values['excluded_ssid'] = "test-hs20-other"
1043     events = policy_test(dev[0], apdev[0], values)
1044     ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[1]['bssid'] in e]
1045     if len(ev) != 1:
1046         raise Exception("Excluded network not reported")
1047
1048     values = default_cred()
1049     values['roaming_consortium'] = "223344"
1050     values['eap'] = "TTLS"
1051     values['phase2'] = "auth=MSCHAPV2"
1052     values['excluded_ssid'] = "test-hs20"
1053     events = policy_test(dev[0], apdev[1], values)
1054     ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1055     if len(ev) != 1:
1056         raise Exception("Excluded network not reported")
1057
1058     values = { 'imsi': "555444-333222111", 'eap': "SIM",
1059                'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1060                'excluded_ssid': "test-hs20" }
1061     events = policy_test(dev[0], apdev[1], values)
1062     ev = [e for e in events if "INTERWORKING-BLACKLISTED " + apdev[0]['bssid'] in e]
1063     if len(ev) != 1:
1064         raise Exception("Excluded network not reported")
1065
1066 def test_ap_hs20_roam_to_higher_prio(dev, apdev):
1067     """Hotspot 2.0 and roaming from current to higher priority network"""
1068     bssid = apdev[0]['bssid']
1069     params = hs20_ap_params(ssid="test-hs20-visited")
1070     params['domain_name'] = "visited.example.org"
1071     hostapd.add_ap(apdev[0]['ifname'], params)
1072
1073     dev[0].hs20_enable()
1074     id = dev[0].add_cred_values({ 'realm': "example.com",
1075                                   'username': "hs20-test",
1076                                   'password': "password",
1077                                   'domain': "example.com" })
1078     logger.info("Connect to the only network option")
1079     interworking_select(dev[0], bssid, "roaming", freq="2412")
1080     dev[0].dump_monitor()
1081     interworking_connect(dev[0], bssid, "TTLS")
1082
1083     logger.info("Start another AP (home operator) and reconnect")
1084     bssid2 = apdev[1]['bssid']
1085     params = hs20_ap_params(ssid="test-hs20-home")
1086     params['domain_name'] = "example.com"
1087     hostapd.add_ap(apdev[1]['ifname'], params)
1088
1089     dev[0].scan_for_bss(bssid2, freq="2412", force_scan=True)
1090     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1091     ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
1092                             "INTERWORKING-ALREADY-CONNECTED",
1093                             "CTRL-EVENT-CONNECTED"], timeout=15)
1094     if ev is None:
1095         raise Exception("Connection timed out")
1096     if "INTERWORKING-NO-MATCH" in ev:
1097         raise Exception("Matching AP not found")
1098     if "INTERWORKING-ALREADY-CONNECTED" in ev:
1099         raise Exception("Unexpected AP selected")
1100     if bssid2 not in ev:
1101         raise Exception("Unexpected BSSID after reconnection")
1102
1103 def test_ap_hs20_domain_suffix_match(dev, apdev):
1104     """Hotspot 2.0 and domain_suffix_match"""
1105     bssid = apdev[0]['bssid']
1106     params = hs20_ap_params()
1107     hostapd.add_ap(apdev[0]['ifname'], params)
1108
1109     dev[0].hs20_enable()
1110     id = dev[0].add_cred_values({ 'realm': "example.com",
1111                                   'username': "hs20-test",
1112                                   'password': "password",
1113                                   'domain': "example.com",
1114                                   'domain_suffix_match': "w1.fi" })
1115     interworking_select(dev[0], bssid, "home", freq="2412")
1116     dev[0].dump_monitor()
1117     interworking_connect(dev[0], bssid, "TTLS")
1118     dev[0].request("REMOVE_NETWORK all")
1119     dev[0].dump_monitor()
1120
1121     dev[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1122     interworking_select(dev[0], bssid, "home", freq="2412")
1123     dev[0].dump_monitor()
1124     dev[0].request("INTERWORKING_CONNECT " + bssid)
1125     ev = dev[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1126     if ev is None:
1127         raise Exception("TLS certificate error not reported")
1128     if "Domain suffix mismatch" not in ev:
1129         raise Exception("Domain suffix mismatch not reported")
1130
1131 def test_ap_hs20_roaming_partner_preference(dev, apdev):
1132     """Hotspot 2.0 and roaming partner preference"""
1133     params = hs20_ap_params()
1134     params['domain_name'] = "roaming.example.org"
1135     hostapd.add_ap(apdev[0]['ifname'], params)
1136
1137     params = hs20_ap_params()
1138     params['ssid'] = "test-hs20-other"
1139     params['domain_name'] = "roaming.example.net"
1140     hostapd.add_ap(apdev[1]['ifname'], params)
1141
1142     logger.info("Verify default vs. specified preference")
1143     values = default_cred()
1144     values['roaming_partner'] = "roaming.example.net,1,127,*"
1145     policy_test(dev[0], apdev[1], values, only_one=False)
1146     values['roaming_partner'] = "roaming.example.net,1,129,*"
1147     policy_test(dev[0], apdev[0], values, only_one=False)
1148
1149     logger.info("Verify partial FQDN match")
1150     values['roaming_partner'] = "example.net,0,0,*"
1151     policy_test(dev[0], apdev[1], values, only_one=False)
1152     values['roaming_partner'] = "example.net,0,255,*"
1153     policy_test(dev[0], apdev[0], values, only_one=False)
1154
1155 def test_ap_hs20_max_bss_load(dev, apdev):
1156     """Hotspot 2.0 and maximum BSS load"""
1157     params = hs20_ap_params()
1158     params['bss_load_test'] = "12:200:20000"
1159     hostapd.add_ap(apdev[0]['ifname'], params)
1160
1161     params = hs20_ap_params()
1162     params['ssid'] = "test-hs20-other"
1163     params['bss_load_test'] = "5:20:10000"
1164     hostapd.add_ap(apdev[1]['ifname'], params)
1165
1166     logger.info("Verify maximum BSS load constraint")
1167     values = default_cred()
1168     values['domain'] = "example.com"
1169     values['max_bss_load'] = "100"
1170     events = policy_test(dev[0], apdev[1], values, only_one=False)
1171
1172     ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1173     if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1174         raise Exception("Maximum BSS Load case not noticed")
1175     ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1176     if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1177         raise Exception("Maximum BSS Load case reported incorrectly")
1178
1179     logger.info("Verify maximum BSS load does not prevent connection")
1180     values['max_bss_load'] = "1"
1181     events = policy_test(dev[0], None, values)
1182
1183     ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1184     if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1185         raise Exception("Maximum BSS Load case not noticed")
1186     ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1187     if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1188         raise Exception("Maximum BSS Load case not noticed")
1189
1190 def test_ap_hs20_max_bss_load2(dev, apdev):
1191     """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1192     params = hs20_ap_params()
1193     params['bss_load_test'] = "12:200:20000"
1194     hostapd.add_ap(apdev[0]['ifname'], params)
1195
1196     params = hs20_ap_params()
1197     params['ssid'] = "test-hs20-other"
1198     hostapd.add_ap(apdev[1]['ifname'], params)
1199
1200     logger.info("Verify maximum BSS load constraint with AP advertisement")
1201     values = default_cred()
1202     values['domain'] = "example.com"
1203     values['max_bss_load'] = "100"
1204     events = policy_test(dev[0], apdev[1], values, only_one=False)
1205
1206     ev = [e for e in events if "INTERWORKING-AP " + apdev[0]['bssid'] in e]
1207     if len(ev) != 1 or "over_max_bss_load=1" not in ev[0]:
1208         raise Exception("Maximum BSS Load case not noticed")
1209     ev = [e for e in events if "INTERWORKING-AP " + apdev[1]['bssid'] in e]
1210     if len(ev) != 1 or "over_max_bss_load=1" in ev[0]:
1211         raise Exception("Maximum BSS Load case reported incorrectly")
1212
1213 def test_ap_hs20_multi_cred_sp_prio(dev, apdev):
1214     """Hotspot 2.0 multi-cred sp_priority"""
1215     if not hlr_auc_gw_available():
1216         return "skip"
1217     bssid = apdev[0]['bssid']
1218     params = hs20_ap_params()
1219     params['hessid'] = bssid
1220     del params['domain_name']
1221     params['anqp_3gpp_cell_net'] = "232,01"
1222     hostapd.add_ap(apdev[0]['ifname'], params)
1223
1224     dev[0].hs20_enable()
1225     dev[0].scan_for_bss(bssid, freq="2412")
1226     dev[0].request("SET external_sim 1")
1227     id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1228                                    'provisioning_sp': "example.com",
1229                                    'sp_priority' :"1" })
1230     id2 = dev[0].add_cred_values({ 'realm': "example.com",
1231                                    'username': "hs20-test",
1232                                    'password': "password",
1233                                    'domain': "example.com",
1234                                    'provisioning_sp': "example.com",
1235                                    'sp_priority': "2" })
1236     dev[0].dump_monitor()
1237     dev[0].scan_for_bss(bssid, freq="2412")
1238     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1239     interworking_ext_sim_auth(dev[0], "SIM")
1240     check_sp_type(dev[0], "unknown")
1241     dev[0].request("REMOVE_NETWORK all")
1242
1243     dev[0].set_cred(id1, "sp_priority", "2")
1244     dev[0].set_cred(id2, "sp_priority", "1")
1245     dev[0].dump_monitor()
1246     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1247     interworking_auth(dev[0], "TTLS")
1248     check_sp_type(dev[0], "unknown")
1249
1250 def test_ap_hs20_multi_cred_sp_prio2(dev, apdev):
1251     """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1252     if not hlr_auc_gw_available():
1253         return "skip"
1254     bssid = apdev[0]['bssid']
1255     params = hs20_ap_params()
1256     params['hessid'] = bssid
1257     del params['nai_realm']
1258     del params['domain_name']
1259     params['anqp_3gpp_cell_net'] = "232,01"
1260     hostapd.add_ap(apdev[0]['ifname'], params)
1261
1262     bssid2 = apdev[1]['bssid']
1263     params = hs20_ap_params()
1264     params['ssid'] = "test-hs20-other"
1265     params['hessid'] = bssid2
1266     del params['domain_name']
1267     del params['anqp_3gpp_cell_net']
1268     hostapd.add_ap(apdev[1]['ifname'], params)
1269
1270     dev[0].hs20_enable()
1271     dev[0].request("SET external_sim 1")
1272     id1 = dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1273                                    'provisioning_sp': "example.com",
1274                                    'sp_priority': "1" })
1275     id2 = dev[0].add_cred_values({ 'realm': "example.com",
1276                                    'username': "hs20-test",
1277                                    'password': "password",
1278                                    'domain': "example.com",
1279                                    'provisioning_sp': "example.com",
1280                                    'sp_priority': "2" })
1281     dev[0].dump_monitor()
1282     dev[0].scan_for_bss(bssid, freq="2412")
1283     dev[0].scan_for_bss(bssid2, freq="2412")
1284     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1285     interworking_ext_sim_auth(dev[0], "SIM")
1286     check_sp_type(dev[0], "unknown")
1287     conn_bssid = dev[0].get_status_field("bssid")
1288     if conn_bssid != bssid:
1289         raise Exception("Connected to incorrect BSS")
1290     dev[0].request("REMOVE_NETWORK all")
1291
1292     dev[0].set_cred(id1, "sp_priority", "2")
1293     dev[0].set_cred(id2, "sp_priority", "1")
1294     dev[0].dump_monitor()
1295     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1296     interworking_auth(dev[0], "TTLS")
1297     check_sp_type(dev[0], "unknown")
1298     conn_bssid = dev[0].get_status_field("bssid")
1299     if conn_bssid != bssid2:
1300         raise Exception("Connected to incorrect BSS")
1301
1302 def check_conn_capab_selection(dev, type, missing):
1303     dev.request("INTERWORKING_SELECT freq=2412")
1304     ev = dev.wait_event(["INTERWORKING-AP"])
1305     if ev is None:
1306         raise Exception("Network selection timed out");
1307     if "type=" + type not in ev:
1308         raise Exception("Unexpected network type")
1309     if missing and "conn_capab_missing=1" not in ev:
1310         raise Exception("conn_capab_missing not reported")
1311     if not missing and "conn_capab_missing=1" in ev:
1312         raise Exception("conn_capab_missing reported unexpectedly")
1313
1314 def conn_capab_cred(domain=None, req_conn_capab=None):
1315     cred = default_cred(domain=domain)
1316     if req_conn_capab:
1317         cred['req_conn_capab'] = req_conn_capab
1318     return cred
1319
1320 def test_ap_hs20_req_conn_capab(dev, apdev):
1321     """Hotspot 2.0 network selection with req_conn_capab"""
1322     bssid = apdev[0]['bssid']
1323     params = hs20_ap_params()
1324     hostapd.add_ap(apdev[0]['ifname'], params)
1325
1326     dev[0].hs20_enable()
1327     dev[0].scan_for_bss(bssid, freq="2412")
1328     logger.info("Not used in home network")
1329     values = conn_capab_cred(domain="example.com", req_conn_capab="6:1234")
1330     id = dev[0].add_cred_values(values)
1331     check_conn_capab_selection(dev[0], "home", False)
1332
1333     logger.info("Used in roaming network")
1334     dev[0].remove_cred(id)
1335     values = conn_capab_cred(domain="example.org", req_conn_capab="6:1234")
1336     id = dev[0].add_cred_values(values)
1337     check_conn_capab_selection(dev[0], "roaming", True)
1338
1339     logger.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1340     check_auto_select(dev[0], bssid)
1341
1342     logger.info("Additional req_conn_capab checks")
1343
1344     dev[0].remove_cred(id)
1345     values = conn_capab_cred(domain="example.org", req_conn_capab="1:0")
1346     id = dev[0].add_cred_values(values)
1347     check_conn_capab_selection(dev[0], "roaming", True)
1348
1349     dev[0].remove_cred(id)
1350     values = conn_capab_cred(domain="example.org", req_conn_capab="17:5060")
1351     id = dev[0].add_cred_values(values)
1352     check_conn_capab_selection(dev[0], "roaming", True)
1353
1354     bssid2 = apdev[1]['bssid']
1355     params = hs20_ap_params(ssid="test-hs20b")
1356     params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1357     hostapd.add_ap(apdev[1]['ifname'], params)
1358
1359     dev[0].remove_cred(id)
1360     values = conn_capab_cred(domain="example.org", req_conn_capab="50")
1361     id = dev[0].add_cred_values(values)
1362     dev[0].set_cred(id, "req_conn_capab", "6:22")
1363     dev[0].scan_for_bss(bssid2, freq="2412")
1364     dev[0].request("INTERWORKING_SELECT freq=2412")
1365     for i in range(0, 2):
1366         ev = dev[0].wait_event(["INTERWORKING-AP"])
1367         if ev is None:
1368             raise Exception("Network selection timed out");
1369         if bssid in ev and "conn_capab_missing=1" not in ev:
1370             raise Exception("Missing protocol connection capability not reported")
1371         if bssid2 in ev and "conn_capab_missing=1" in ev:
1372             raise Exception("Protocol connection capability not reported correctly")
1373
1374 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev, apdev):
1375     """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1376     bssid = apdev[0]['bssid']
1377     params = hs20_ap_params()
1378     params['domain_name'] = "roaming.example.org"
1379     params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1380     hostapd.add_ap(apdev[0]['ifname'], params)
1381
1382     bssid2 = apdev[1]['bssid']
1383     params = hs20_ap_params(ssid="test-hs20-b")
1384     params['domain_name'] = "roaming.example.net"
1385     hostapd.add_ap(apdev[1]['ifname'], params)
1386
1387     values = default_cred()
1388     values['roaming_partner'] = "roaming.example.net,1,127,*"
1389     id = dev[0].add_cred_values(values)
1390     check_auto_select(dev[0], bssid2)
1391
1392     dev[0].set_cred(id, "req_conn_capab", "50")
1393     check_auto_select(dev[0], bssid)
1394
1395     dev[0].remove_cred(id)
1396     id = dev[0].add_cred_values(values)
1397     dev[0].set_cred(id, "req_conn_capab", "51")
1398     check_auto_select(dev[0], bssid2)
1399
1400 def check_bandwidth_selection(dev, type, below):
1401     dev.request("INTERWORKING_SELECT freq=2412")
1402     ev = dev.wait_event(["INTERWORKING-AP"])
1403     if ev is None:
1404         raise Exception("Network selection timed out");
1405     if "type=" + type not in ev:
1406         raise Exception("Unexpected network type")
1407     if below and "below_min_backhaul=1" not in ev:
1408         raise Exception("below_min_backhaul not reported")
1409     if not below and "below_min_backhaul=1" in ev:
1410         raise Exception("below_min_backhaul reported unexpectedly")
1411
1412 def bw_cred(domain=None, dl_home=None, ul_home=None, dl_roaming=None, ul_roaming=None):
1413     cred = default_cred(domain=domain)
1414     if dl_home:
1415         cred['min_dl_bandwidth_home'] = str(dl_home)
1416     if ul_home:
1417         cred['min_ul_bandwidth_home'] = str(ul_home)
1418     if dl_roaming:
1419         cred['min_dl_bandwidth_roaming'] = str(dl_roaming)
1420     if ul_roaming:
1421         cred['min_ul_bandwidth_roaming'] = str(ul_roaming)
1422     return cred
1423
1424 def test_ap_hs20_min_bandwidth_home(dev, apdev):
1425     """Hotspot 2.0 network selection with min bandwidth (home)"""
1426     bssid = apdev[0]['bssid']
1427     params = hs20_ap_params()
1428     hostapd.add_ap(apdev[0]['ifname'], params)
1429
1430     dev[0].hs20_enable()
1431     dev[0].scan_for_bss(bssid, freq="2412")
1432     values = bw_cred(domain="example.com", dl_home=5490, ul_home=58)
1433     id = dev[0].add_cred_values(values)
1434     check_bandwidth_selection(dev[0], "home", False)
1435     dev[0].remove_cred(id)
1436
1437     values = bw_cred(domain="example.com", dl_home=5491, ul_home=58)
1438     id = dev[0].add_cred_values(values)
1439     check_bandwidth_selection(dev[0], "home", True)
1440     dev[0].remove_cred(id)
1441
1442     values = bw_cred(domain="example.com", dl_home=5490, ul_home=59)
1443     id = dev[0].add_cred_values(values)
1444     check_bandwidth_selection(dev[0], "home", True)
1445     dev[0].remove_cred(id)
1446
1447     values = bw_cred(domain="example.com", dl_home=5491, ul_home=59)
1448     id = dev[0].add_cred_values(values)
1449     check_bandwidth_selection(dev[0], "home", True)
1450     check_auto_select(dev[0], bssid)
1451
1452     bssid2 = apdev[1]['bssid']
1453     params = hs20_ap_params(ssid="test-hs20-b")
1454     params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1455     hostapd.add_ap(apdev[1]['ifname'], params)
1456
1457     check_auto_select(dev[0], bssid2)
1458
1459 def test_ap_hs20_min_bandwidth_roaming(dev, apdev):
1460     """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1461     bssid = apdev[0]['bssid']
1462     params = hs20_ap_params()
1463     hostapd.add_ap(apdev[0]['ifname'], params)
1464
1465     dev[0].hs20_enable()
1466     dev[0].scan_for_bss(bssid, freq="2412")
1467     values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=58)
1468     id = dev[0].add_cred_values(values)
1469     check_bandwidth_selection(dev[0], "roaming", False)
1470     dev[0].remove_cred(id)
1471
1472     values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=58)
1473     id = dev[0].add_cred_values(values)
1474     check_bandwidth_selection(dev[0], "roaming", True)
1475     dev[0].remove_cred(id)
1476
1477     values = bw_cred(domain="example.org", dl_roaming=5490, ul_roaming=59)
1478     id = dev[0].add_cred_values(values)
1479     check_bandwidth_selection(dev[0], "roaming", True)
1480     dev[0].remove_cred(id)
1481
1482     values = bw_cred(domain="example.org", dl_roaming=5491, ul_roaming=59)
1483     id = dev[0].add_cred_values(values)
1484     check_bandwidth_selection(dev[0], "roaming", True)
1485     check_auto_select(dev[0], bssid)
1486
1487     bssid2 = apdev[1]['bssid']
1488     params = hs20_ap_params(ssid="test-hs20-b")
1489     params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1490     hostapd.add_ap(apdev[1]['ifname'], params)
1491
1492     check_auto_select(dev[0], bssid2)
1493
1494 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev, apdev):
1495     """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1496     bssid = apdev[0]['bssid']
1497     params = hs20_ap_params()
1498     params['domain_name'] = "roaming.example.org"
1499     params['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1500     hostapd.add_ap(apdev[0]['ifname'], params)
1501
1502     bssid2 = apdev[1]['bssid']
1503     params = hs20_ap_params(ssid="test-hs20-b")
1504     params['domain_name'] = "roaming.example.net"
1505     hostapd.add_ap(apdev[1]['ifname'], params)
1506
1507     values = default_cred()
1508     values['roaming_partner'] = "roaming.example.net,1,127,*"
1509     id = dev[0].add_cred_values(values)
1510     check_auto_select(dev[0], bssid2)
1511
1512     dev[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1513     check_auto_select(dev[0], bssid)
1514
1515     dev[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1516     check_auto_select(dev[0], bssid2)
1517
1518 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev, apdev):
1519     """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1520     bssid = apdev[0]['bssid']
1521     params = hs20_ap_params()
1522     del params['hs20_wan_metrics']
1523     hostapd.add_ap(apdev[0]['ifname'], params)
1524
1525     dev[0].hs20_enable()
1526     dev[0].scan_for_bss(bssid, freq="2412")
1527     values = bw_cred(domain="example.com", dl_home=10000, ul_home=10000,
1528                      dl_roaming=10000, ul_roaming=10000)
1529     dev[0].add_cred_values(values)
1530     check_bandwidth_selection(dev[0], "home", False)
1531
1532 def test_ap_hs20_deauth_req_ess(dev, apdev):
1533     """Hotspot 2.0 connection and deauthentication request for ESS"""
1534     dev[0].request("SET pmf 2")
1535     eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1536     dev[0].dump_monitor()
1537     addr = dev[0].p2p_interface_addr()
1538     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1539     hapd.request("HS20_DEAUTH_REQ " + addr + " 1 120 http://example.com/")
1540     ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1541     if ev is None:
1542         raise Exception("Timeout on deauth imminent notice")
1543     if "1 120 http://example.com/" not in ev:
1544         raise Exception("Unexpected deauth imminent notice: " + ev)
1545     hapd.request("DEAUTHENTICATE " + addr)
1546     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1547     if ev is None:
1548         raise Exception("Timeout on disconnection")
1549     if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1550         raise Exception("Network not marked temporarily disabled")
1551     ev = dev[0].wait_event(["SME: Trying to authenticate",
1552                             "Trying to associate",
1553                             "CTRL-EVENT-CONNECTED"], timeout=5)
1554     if ev is not None:
1555         raise Exception("Unexpected connection attempt")
1556
1557 def test_ap_hs20_deauth_req_bss(dev, apdev):
1558     """Hotspot 2.0 connection and deauthentication request for BSS"""
1559     dev[0].request("SET pmf 2")
1560     eap_test(dev[0], apdev[0], "21[3:26]", "TTLS", "user")
1561     dev[0].dump_monitor()
1562     addr = dev[0].p2p_interface_addr()
1563     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1564     hapd.request("HS20_DEAUTH_REQ " + addr + " 0 120 http://example.com/")
1565     ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1566     if ev is None:
1567         raise Exception("Timeout on deauth imminent notice")
1568     if "0 120 http://example.com/" not in ev:
1569         raise Exception("Unexpected deauth imminent notice: " + ev)
1570     hapd.request("DEAUTHENTICATE " + addr + " reason=4")
1571     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
1572     if ev is None:
1573         raise Exception("Timeout on disconnection")
1574     if "reason=4" not in ev:
1575         raise Exception("Unexpected disconnection reason")
1576     if "[TEMP-DISABLED]" not in dev[0].list_networks()[0]['flags']:
1577         raise Exception("Network not marked temporarily disabled")
1578     ev = dev[0].wait_event(["SME: Trying to authenticate",
1579                             "Trying to associate",
1580                             "CTRL-EVENT-CONNECTED"], timeout=5)
1581     if ev is not None:
1582         raise Exception("Unexpected connection attempt")
1583
1584 def test_ap_hs20_deauth_req_from_radius(dev, apdev):
1585     """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1586     bssid = apdev[0]['bssid']
1587     params = hs20_ap_params()
1588     params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1589     params['hs20_deauth_req_timeout'] = "2"
1590     hostapd.add_ap(apdev[0]['ifname'], params)
1591
1592     dev[0].request("SET pmf 2")
1593     dev[0].hs20_enable()
1594     dev[0].add_cred_values({ 'realm': "example.com",
1595                              'username': "hs20-deauth-test",
1596                              'password': "password" })
1597     interworking_select(dev[0], bssid, freq="2412")
1598     interworking_connect(dev[0], bssid, "TTLS")
1599     ev = dev[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout=5)
1600     if ev is None:
1601         raise Exception("Timeout on deauth imminent notice")
1602     if " 1 100" not in ev:
1603         raise Exception("Unexpected deauth imminent contents")
1604     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=3)
1605     if ev is None:
1606         raise Exception("Timeout on disconnection")
1607
1608 def test_ap_hs20_remediation_required(dev, apdev):
1609     """Hotspot 2.0 connection and remediation required from RADIUS"""
1610     bssid = apdev[0]['bssid']
1611     params = hs20_ap_params()
1612     params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1613     hostapd.add_ap(apdev[0]['ifname'], params)
1614
1615     dev[0].request("SET pmf 1")
1616     dev[0].hs20_enable()
1617     dev[0].add_cred_values({ 'realm': "example.com",
1618                              'username': "hs20-subrem-test",
1619                              'password': "password" })
1620     interworking_select(dev[0], bssid, freq="2412")
1621     interworking_connect(dev[0], bssid, "TTLS")
1622     ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1623     if ev is None:
1624         raise Exception("Timeout on subscription remediation notice")
1625     if " 1 https://example.com/" not in ev:
1626         raise Exception("Unexpected subscription remediation event contents")
1627
1628 def test_ap_hs20_remediation_required_ctrl(dev, apdev):
1629     """Hotspot 2.0 connection and subrem from ctrl_iface"""
1630     bssid = apdev[0]['bssid']
1631     addr = dev[0].p2p_dev_addr()
1632     params = hs20_ap_params()
1633     params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1634     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1635
1636     dev[0].request("SET pmf 1")
1637     dev[0].hs20_enable()
1638     dev[0].add_cred_values(default_cred())
1639     interworking_select(dev[0], bssid, freq="2412")
1640     interworking_connect(dev[0], bssid, "TTLS")
1641
1642     hapd.request("HS20_WNM_NOTIF " + addr + " https://example.com/")
1643     ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1644     if ev is None:
1645         raise Exception("Timeout on subscription remediation notice")
1646     if " 1 https://example.com/" not in ev:
1647         raise Exception("Unexpected subscription remediation event contents")
1648
1649     hapd.request("HS20_WNM_NOTIF " + addr)
1650     ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
1651     if ev is None:
1652         raise Exception("Timeout on subscription remediation notice")
1653     if not ev.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1654         raise Exception("Unexpected subscription remediation event contents: " + ev)
1655
1656     if "FAIL" not in hapd.request("HS20_WNM_NOTIF "):
1657         raise Exception("Unexpected HS20_WNM_NOTIF success")
1658     if "FAIL" not in hapd.request("HS20_WNM_NOTIF foo"):
1659         raise Exception("Unexpected HS20_WNM_NOTIF success")
1660     if "FAIL" not in hapd.request("HS20_WNM_NOTIF " + addr + " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1661         raise Exception("Unexpected HS20_WNM_NOTIF success")
1662
1663 def test_ap_hs20_session_info(dev, apdev):
1664     """Hotspot 2.0 connection and session information from RADIUS"""
1665     bssid = apdev[0]['bssid']
1666     params = hs20_ap_params()
1667     params['nai_realm'] = [ "0,example.com,21[2:4]" ]
1668     hostapd.add_ap(apdev[0]['ifname'], params)
1669
1670     dev[0].request("SET pmf 1")
1671     dev[0].hs20_enable()
1672     dev[0].add_cred_values({ 'realm': "example.com",
1673                              'username': "hs20-session-info-test",
1674                              'password': "password" })
1675     interworking_select(dev[0], bssid, freq="2412")
1676     interworking_connect(dev[0], bssid, "TTLS")
1677     ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout=10)
1678     if ev is None:
1679         raise Exception("Timeout on ESS disassociation imminent notice")
1680     if " 1 59904 https://example.com/" not in ev:
1681         raise Exception("Unexpected ESS disassociation imminent event contents")
1682     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1683     if ev is None:
1684         raise Exception("Scan not started")
1685     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=30)
1686     if ev is None:
1687         raise Exception("Scan not completed")
1688
1689 def test_ap_hs20_osen(dev, apdev):
1690     """Hotspot 2.0 OSEN connection"""
1691     params = { 'ssid': "osen",
1692                'osen': "1",
1693                'auth_server_addr': "127.0.0.1",
1694                'auth_server_port': "1812",
1695                'auth_server_shared_secret': "radius" }
1696     hostapd.add_ap(apdev[0]['ifname'], params)
1697
1698     dev[1].connect("osen", key_mgmt="NONE", scan_freq="2412",
1699                    wait_connect=False)
1700     dev[2].connect("osen", key_mgmt="NONE", wep_key0='"hello"',
1701                    scan_freq="2412", wait_connect=False)
1702     dev[0].connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1703                    group="GTK_NOT_USED",
1704                    eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1705                    ca_cert="auth_serv/ca.pem",
1706                    scan_freq="2412")
1707
1708     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1709     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1710     wpas.connect("osen", proto="OSEN", key_mgmt="OSEN", pairwise="CCMP",
1711                  group="GTK_NOT_USED",
1712                  eap="WFA-UNAUTH-TLS", identity="osen@example.com",
1713                  ca_cert="auth_serv/ca.pem",
1714                  scan_freq="2412")
1715     wpas.request("DISCONNECT")
1716
1717 def test_ap_hs20_network_preference(dev, apdev):
1718     """Hotspot 2.0 network selection with preferred home network"""
1719     bssid = apdev[0]['bssid']
1720     params = hs20_ap_params()
1721     hostapd.add_ap(apdev[0]['ifname'], params)
1722
1723     dev[0].hs20_enable()
1724     values = { 'realm': "example.com",
1725                'username': "hs20-test",
1726                'password': "password",
1727                'domain': "example.com" }
1728     dev[0].add_cred_values(values)
1729
1730     id = dev[0].add_network()
1731     dev[0].set_network_quoted(id, "ssid", "home")
1732     dev[0].set_network_quoted(id, "psk", "12345678")
1733     dev[0].set_network(id, "priority", "1")
1734     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1735
1736     dev[0].scan_for_bss(bssid, freq="2412")
1737     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1738     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1739     if ev is None:
1740         raise Exception("Connection timed out")
1741     if bssid not in ev:
1742         raise Exception("Unexpected network selected")
1743
1744     bssid2 = apdev[1]['bssid']
1745     params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1746     hostapd.add_ap(apdev[1]['ifname'], params)
1747
1748     dev[0].scan_for_bss(bssid2, freq="2412")
1749     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1750     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1751                             "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1752     if ev is None:
1753         raise Exception("Connection timed out")
1754     if "INTERWORKING-ALREADY-CONNECTED" in ev:
1755         raise Exception("No roam to higher priority network")
1756     if bssid2 not in ev:
1757         raise Exception("Unexpected network selected")
1758
1759 def test_ap_hs20_network_preference2(dev, apdev):
1760     """Hotspot 2.0 network selection with preferred credential"""
1761     bssid2 = apdev[1]['bssid']
1762     params = hostapd.wpa2_params(ssid="home", passphrase="12345678")
1763     hostapd.add_ap(apdev[1]['ifname'], params)
1764
1765     dev[0].hs20_enable()
1766     values = { 'realm': "example.com",
1767                'username': "hs20-test",
1768                'password': "password",
1769                'domain': "example.com",
1770                'priority': "1" }
1771     dev[0].add_cred_values(values)
1772
1773     id = dev[0].add_network()
1774     dev[0].set_network_quoted(id, "ssid", "home")
1775     dev[0].set_network_quoted(id, "psk", "12345678")
1776     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
1777
1778     dev[0].scan_for_bss(bssid2, freq="2412")
1779     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1780     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1781     if ev is None:
1782         raise Exception("Connection timed out")
1783     if bssid2 not in ev:
1784         raise Exception("Unexpected network selected")
1785
1786     bssid = apdev[0]['bssid']
1787     params = hs20_ap_params()
1788     hostapd.add_ap(apdev[0]['ifname'], params)
1789
1790     dev[0].scan_for_bss(bssid, freq="2412")
1791     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1792     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1793                             "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1794     if ev is None:
1795         raise Exception("Connection timed out")
1796     if "INTERWORKING-ALREADY-CONNECTED" in ev:
1797         raise Exception("No roam to higher priority network")
1798     if bssid not in ev:
1799         raise Exception("Unexpected network selected")
1800
1801 def test_ap_hs20_network_preference3(dev, apdev):
1802     """Hotspot 2.0 network selection with two credential (one preferred)"""
1803     bssid = apdev[0]['bssid']
1804     params = hs20_ap_params()
1805     hostapd.add_ap(apdev[0]['ifname'], params)
1806
1807     bssid2 = apdev[1]['bssid']
1808     params = hs20_ap_params(ssid="test-hs20b")
1809     params['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1810     hostapd.add_ap(apdev[1]['ifname'], params)
1811
1812     dev[0].hs20_enable()
1813     values = { 'realm': "example.com",
1814                'username': "hs20-test",
1815                'password': "password",
1816                'priority': "1" }
1817     dev[0].add_cred_values(values)
1818     values = { 'realm': "example.org",
1819                'username': "hs20-test",
1820                'password': "password" }
1821     id = dev[0].add_cred_values(values)
1822
1823     dev[0].scan_for_bss(bssid, freq="2412")
1824     dev[0].scan_for_bss(bssid2, freq="2412")
1825     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1826     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1827     if ev is None:
1828         raise Exception("Connection timed out")
1829     if bssid not in ev:
1830         raise Exception("Unexpected network selected")
1831
1832     dev[0].set_cred(id, "priority", "2")
1833     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1834     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1835                             "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1836     if ev is None:
1837         raise Exception("Connection timed out")
1838     if "INTERWORKING-ALREADY-CONNECTED" in ev:
1839         raise Exception("No roam to higher priority network")
1840     if bssid2 not in ev:
1841         raise Exception("Unexpected network selected")
1842
1843 def test_ap_hs20_network_preference4(dev, apdev):
1844     """Hotspot 2.0 network selection with username vs. SIM credential"""
1845     bssid = apdev[0]['bssid']
1846     params = hs20_ap_params()
1847     hostapd.add_ap(apdev[0]['ifname'], params)
1848
1849     bssid2 = apdev[1]['bssid']
1850     params = hs20_ap_params(ssid="test-hs20b")
1851     params['hessid'] = bssid2
1852     params['anqp_3gpp_cell_net'] = "555,444"
1853     params['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1854     hostapd.add_ap(apdev[1]['ifname'], params)
1855
1856     dev[0].hs20_enable()
1857     values = { 'realm': "example.com",
1858                'username': "hs20-test",
1859                'password': "password",
1860                'priority': "1" }
1861     dev[0].add_cred_values(values)
1862     values = { 'imsi': "555444-333222111",
1863                'eap': "SIM",
1864                'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1865     id = dev[0].add_cred_values(values)
1866
1867     dev[0].scan_for_bss(bssid, freq="2412")
1868     dev[0].scan_for_bss(bssid2, freq="2412")
1869     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1870     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1871     if ev is None:
1872         raise Exception("Connection timed out")
1873     if bssid not in ev:
1874         raise Exception("Unexpected network selected")
1875
1876     dev[0].set_cred(id, "priority", "2")
1877     dev[0].request("INTERWORKING_SELECT auto freq=2412")
1878     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED",
1879                             "INTERWORKING-ALREADY-CONNECTED" ], timeout=15)
1880     if ev is None:
1881         raise Exception("Connection timed out")
1882     if "INTERWORKING-ALREADY-CONNECTED" in ev:
1883         raise Exception("No roam to higher priority network")
1884     if bssid2 not in ev:
1885         raise Exception("Unexpected network selected")
1886
1887 def test_ap_hs20_fetch_osu(dev, apdev):
1888     """Hotspot 2.0 OSU provider and icon fetch"""
1889     bssid = apdev[0]['bssid']
1890     params = hs20_ap_params()
1891     params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1892     params['osu_ssid'] = '"HS 2.0 OSU open"'
1893     params['osu_method_list'] = "1"
1894     params['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
1895     params['osu_icon'] = "w1fi_logo"
1896     params['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
1897     params['osu_server_uri'] = "https://example.com/osu/"
1898     hostapd.add_ap(apdev[0]['ifname'], params)
1899
1900     bssid2 = apdev[1]['bssid']
1901     params = hs20_ap_params(ssid="test-hs20b")
1902     params['hessid'] = bssid2
1903     params['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
1904     params['osu_ssid'] = '"HS 2.0 OSU OSEN"'
1905     params['osu_method_list'] = "0"
1906     params['osu_nai'] = "osen@example.com"
1907     params['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
1908     params['osu_icon'] = "w1fi_logo"
1909     params['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
1910     params['osu_server_uri'] = "https://example.org/osu/"
1911     hostapd.add_ap(apdev[1]['ifname'], params)
1912
1913     with open("w1fi_logo.png", "r") as f:
1914         orig_logo = f.read()
1915     dev[0].hs20_enable()
1916     dir = "/tmp/osu-fetch"
1917     if os.path.isdir(dir):
1918        files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
1919        for f in files:
1920            os.remove(dir + "/" + f)
1921     else:
1922         try:
1923             os.makedirs(dir)
1924         except:
1925             pass
1926     try:
1927         dev[1].scan_for_bss(bssid, freq="2412")
1928         dev[0].request("SET osu_dir " + dir)
1929         dev[0].request("FETCH_OSU")
1930         if "OK" not in dev[1].request("HS20_ICON_REQUEST " + bssid + " w1fi_logo"):
1931             raise Exception("HS20_ICON_REQUEST failed")
1932         icons = 0
1933         while True:
1934             ev = dev[0].wait_event(["OSU provider fetch completed",
1935                                     "RX-HS20-ANQP-ICON"], timeout=15)
1936             if ev is None:
1937                 raise Exception("Timeout on OSU fetch")
1938             if "OSU provider fetch completed" in ev:
1939                 break
1940             if "RX-HS20-ANQP-ICON" in ev:
1941                 with open(ev.split(' ')[1], "r") as f:
1942                     logo = f.read()
1943                     if logo == orig_logo:
1944                         icons += 1
1945
1946         with open(dir + "/osu-providers.txt", "r") as f:
1947             prov = f.read()
1948         if "OSU-PROVIDER " + bssid not in prov:
1949             raise Exception("Missing OSU_PROVIDER")
1950         if "OSU-PROVIDER " + bssid2 not in prov:
1951             raise Exception("Missing OSU_PROVIDER")
1952     finally:
1953         files = [ f for f in os.listdir(dir) if f.startswith("osu-") ]
1954         for f in files:
1955             os.remove(dir + "/" + f)
1956         os.rmdir(dir)
1957
1958     if icons != 2:
1959         raise Exception("Unexpected number of icons fetched")
1960
1961     ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=5)
1962     if ev is None:
1963         raise Exception("Timeout on GAS-QUERY-DONE")
1964     ev = dev[1].wait_event(["GAS-QUERY-DONE"], timeout=5)
1965     if ev is None:
1966         raise Exception("Timeout on GAS-QUERY-DONE")
1967     if "freq=2412 status_code=0 result=SUCCESS" not in ev:
1968         raise Exception("Unexpected GAS-QUERY-DONE: " + ev)
1969     ev = dev[1].wait_event(["RX-HS20-ANQP"], timeout=15)
1970     if ev is None:
1971         raise Exception("Timeout on icon fetch")
1972     if "Icon Binary File" not in ev:
1973         raise Exception("Unexpected ANQP element")
1974
1975 def test_ap_hs20_ft(dev, apdev):
1976     """Hotspot 2.0 connection with FT"""
1977     bssid = apdev[0]['bssid']
1978     params = hs20_ap_params()
1979     params['wpa_key_mgmt'] = "FT-EAP"
1980     params['nas_identifier'] = "nas1.w1.fi"
1981     params['r1_key_holder'] = "000102030405"
1982     params["mobility_domain"] = "a1b2"
1983     params["reassociation_deadline"] = "1000"
1984     hostapd.add_ap(apdev[0]['ifname'], params)
1985
1986     dev[0].hs20_enable()
1987     id = dev[0].add_cred_values({ 'realm': "example.com",
1988                                   'username': "hs20-test",
1989                                   'password': "password",
1990                                   'ca_cert': "auth_serv/ca.pem",
1991                                   'domain': "example.com",
1992                                   'update_identifier': "1234" })
1993     interworking_select(dev[0], bssid, "home", freq="2412")
1994     interworking_connect(dev[0], bssid, "TTLS")
1995
1996 def test_ap_hs20_remediation_sql(dev, apdev, params):
1997     """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
1998     try:
1999         import sqlite3
2000     except ImportError:
2001         return "skip"
2002     dbfile = os.path.join(params['logdir'], "eap-user.db")
2003     try:
2004         os.remove(dbfile)
2005     except:
2006         pass
2007     con = sqlite3.connect(dbfile)
2008     with con:
2009         cur = con.cursor()
2010         cur.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2011         cur.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2012         cur.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2013         cur.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2014         cur.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2015
2016     try:
2017         params = { "ssid": "as", "beacon_int": "2000",
2018                    "radius_server_clients": "auth_serv/radius_clients.conf",
2019                    "radius_server_auth_port": '18128',
2020                    "eap_server": "1",
2021                    "eap_user_file": "sqlite:" + dbfile,
2022                    "ca_cert": "auth_serv/ca.pem",
2023                    "server_cert": "auth_serv/server.pem",
2024                    "private_key": "auth_serv/server.key",
2025                    "subscr_remediation_url": "https://example.org/",
2026                    "subscr_remediation_method": "1" }
2027         hostapd.add_ap(apdev[1]['ifname'], params)
2028
2029         bssid = apdev[0]['bssid']
2030         params = hs20_ap_params()
2031         params['auth_server_port'] = "18128"
2032         hostapd.add_ap(apdev[0]['ifname'], params)
2033
2034         dev[0].request("SET pmf 1")
2035         dev[0].hs20_enable()
2036         id = dev[0].add_cred_values({ 'realm': "example.com",
2037                                       'username': "user-mschapv2",
2038                                       'password': "password",
2039                                       'ca_cert': "auth_serv/ca.pem" })
2040         interworking_select(dev[0], bssid, freq="2412")
2041         interworking_connect(dev[0], bssid, "TTLS")
2042         ev = dev[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout=5)
2043         if ev is None:
2044             raise Exception("Timeout on subscription remediation notice")
2045         if " 1 https://example.org/" not in ev:
2046             raise Exception("Unexpected subscription remediation event contents")
2047
2048         with con:
2049             cur = con.cursor()
2050             cur.execute("SELECT * from authlog")
2051             rows = cur.fetchall()
2052             if len(rows) < 1:
2053                 raise Exception("No authlog entries")
2054
2055     finally:
2056         os.remove(dbfile)
2057
2058 def test_ap_hs20_external_selection(dev, apdev):
2059     """Hotspot 2.0 connection using external network selection and creation"""
2060     bssid = apdev[0]['bssid']
2061     params = hs20_ap_params()
2062     params['hessid'] = bssid
2063     params['disable_dgaf'] = '1'
2064     hostapd.add_ap(apdev[0]['ifname'], params)
2065
2066     dev[0].hs20_enable()
2067     dev[0].connect("test-hs20", proto="RSN", key_mgmt="WPA-EAP", eap="TTLS",
2068                    identity="hs20-test", password="password",
2069                    ca_cert="auth_serv/ca.pem", phase2="auth=MSCHAPV2",
2070                    scan_freq="2412", update_identifier="54321")
2071     if dev[0].get_status_field("hs20") != "2":
2072         raise Exception("Unexpected hs20 indication")
2073
2074 def test_ap_hs20_random_mac_addr(dev, apdev):
2075     """Hotspot 2.0 connection with random MAC address"""
2076     bssid = apdev[0]['bssid']
2077     params = hs20_ap_params()
2078     params['hessid'] = bssid
2079     params['disable_dgaf'] = '1'
2080     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2081
2082     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2083     wpas.interface_add("wlan5")
2084     addr = wpas.p2p_interface_addr()
2085     wpas.request("SET mac_addr 1")
2086     wpas.request("SET preassoc_mac_addr 1")
2087     wpas.request("SET rand_addr_lifetime 60")
2088     wpas.hs20_enable()
2089     wpas.scan(freq="2412", only_new=True)
2090     id = wpas.add_cred_values({ 'realm': "example.com",
2091                                   'username': "hs20-test",
2092                                   'password': "password",
2093                                   'ca_cert': "auth_serv/ca.pem",
2094                                   'domain': "example.com",
2095                                   'update_identifier': "1234" })
2096     interworking_select(wpas, bssid, "home", freq="2412")
2097     interworking_connect(wpas, bssid, "TTLS")
2098     addr1 = wpas.get_driver_status_field("addr")
2099     if addr == addr1:
2100         raise Exception("Did not use random MAC address")
2101
2102     sta = hapd.get_sta(addr)
2103     if sta['addr'] != "FAIL":
2104         raise Exception("Unexpected STA association with permanent address")
2105     sta = hapd.get_sta(addr1)
2106     if sta['addr'] != addr1:
2107         raise Exception("STA association with random address not found")