]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_ap_hs20.py
Interworking: Reject BSS based on disallow_aps
[thirdparty/hostap.git] / tests / hwsim / test_ap_hs20.py
CommitLineData
93a06242
JM
1#!/usr/bin/python
2#
3# Hotspot 2.0 tests
4# Copyright (c) 2013, Jouni Malinen <j@w1.fi>
5#
6# This software may be distributed under the terms of the BSD license.
7# See README for more details.
8
9import time
10import subprocess
11import logging
c9aa4308 12logger = logging.getLogger()
efd43d85
JM
13import os.path
14import subprocess
93a06242
JM
15
16import hostapd
17
18def hs20_ap_params():
19 params = hostapd.wpa2_params(ssid="test-hs20")
20 params['wpa_key_mgmt'] = "WPA-EAP"
21 params['ieee80211w'] = "1"
22 params['ieee8021x'] = "1"
23 params['auth_server_addr'] = "127.0.0.1"
24 params['auth_server_port'] = "1812"
25 params['auth_server_shared_secret'] = "radius"
26 params['interworking'] = "1"
27 params['access_network_type'] = "14"
28 params['internet'] = "1"
29 params['asra'] = "0"
30 params['esr'] = "0"
31 params['uesa'] = "0"
32 params['venue_group'] = "7"
33 params['venue_type'] = "1"
34 params['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
35 params['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
36 "fedcba" ]
37 params['domain_name'] = "example.com,another.example.com"
38 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
39 "0,another.example.com" ]
40 params['hs20'] = "1"
41 params['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
42 params['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
43 params['hs20_operating_class'] = "5173"
44 params['anqp_3gpp_cell_net'] = "244,91"
45 return params
46
bbe86767
JM
47def interworking_select(dev, bssid, type=None, no_match=False):
48 dev.dump_monitor()
49 dev.request("INTERWORKING_SELECT")
50 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
51 timeout=15)
93a06242
JM
52 if ev is None:
53 raise Exception("Network selection timed out");
bbe86767
JM
54 if no_match:
55 if "INTERWORKING-NO-MATCH" not in ev:
56 raise Exception("Unexpected network match")
57 return
93a06242
JM
58 if "INTERWORKING-NO-MATCH" in ev:
59 raise Exception("Matching network not found")
60 if bssid not in ev:
61 raise Exception("Unexpected BSSID in match")
bbe86767
JM
62 if type and "type=" + type not in ev:
63 raise Exception("Network type not recognized correctly")
93a06242 64
bbe86767
JM
65def check_sp_type(dev, sp_type):
66 type = dev.get_status_field("sp_type")
67 if type is None:
68 raise Exception("sp_type not available")
69 if type != sp_type:
70 raise Exception("sp_type did not indicate home network")
efd43d85 71
bbe86767 72def hlr_auc_gw_available():
efd43d85
JM
73 if not os.path.exists("/tmp/hlr_auc_gw.sock"):
74 logger.info("No hlr_auc_gw available");
bbe86767 75 return False
efd43d85
JM
76 if not os.path.exists("../../hostapd/hlr_auc_gw"):
77 logger.info("No hlr_auc_gw available");
bbe86767
JM
78 return False
79 return True
efd43d85 80
bbe86767
JM
81def interworking_ext_sim_connect(dev, bssid, method):
82 dev.request("INTERWORKING_CONNECT " + bssid)
efd43d85 83
bbe86767 84 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
efd43d85
JM
85 if ev is None:
86 raise Exception("Network connected timed out")
bbe86767 87 if "(" + method + ")" not in ev:
efd43d85
JM
88 raise Exception("Unexpected EAP method selection")
89
bbe86767 90 ev = dev.wait_event(["CTRL-REQ-SIM"], timeout=15)
efd43d85
JM
91 if ev is None:
92 raise Exception("Wait for external SIM processing request timed out")
93 p = ev.split(':', 2)
94 if p[1] != "GSM-AUTH":
95 raise Exception("Unexpected CTRL-REQ-SIM type")
96 id = p[0].split('-')[3]
97 rand = p[2].split(' ')[0]
98
99 res = subprocess.check_output(["../../hostapd/hlr_auc_gw",
100 "-m",
101 "auth_serv/hlr_auc_gw.milenage_db",
102 "GSM-AUTH-REQ 232010000000000 " + rand])
103 if "GSM-AUTH-RESP" not in res:
104 raise Exception("Unexpected hlr_auc_gw response")
105 resp = res.split(' ')[2].rstrip()
106
bbe86767
JM
107 dev.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp)
108 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
efd43d85
JM
109 if ev is None:
110 raise Exception("Connection timed out")
f4defd91 111
8fba2e5d
JM
112def interworking_connect(dev, bssid, method):
113 dev.request("INTERWORKING_CONNECT " + bssid)
114
115 ev = dev.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout=15)
116 if ev is None:
117 raise Exception("Network connected timed out")
118 if "(" + method + ")" not in ev:
119 raise Exception("Unexpected EAP method selection")
120
121 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
122 if ev is None:
123 raise Exception("Connection timed out")
124
bbe86767
JM
125def test_ap_hs20_select(dev, apdev):
126 """Hotspot 2.0 network selection"""
127 bssid = apdev[0]['bssid']
128 params = hs20_ap_params()
129 params['hessid'] = bssid
130 hostapd.add_ap(apdev[0]['ifname'], params)
131
132 dev[0].hs20_enable()
2232edf8
JM
133 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
134 'password': "secret",
135 'domain': "example.com" })
bbe86767
JM
136 interworking_select(dev[0], bssid, "home")
137
138 dev[0].remove_cred(id)
2232edf8
JM
139 id = dev[0].add_cred_values({ 'realm': "example.com", 'username': "test",
140 'password': "secret",
141 'domain': "no.match.example.com" })
bbe86767
JM
142 interworking_select(dev[0], bssid, "roaming")
143
144 dev[0].set_cred_quoted(id, "realm", "no.match.example.com");
145 interworking_select(dev[0], bssid, no_match=True)
146
147def test_ap_hs20_ext_sim(dev, apdev):
148 """Hotspot 2.0 with external SIM processing"""
149 if not hlr_auc_gw_available():
150 return "skip"
151 bssid = apdev[0]['bssid']
152 params = hs20_ap_params()
153 params['hessid'] = bssid
154 params['anqp_3gpp_cell_net'] = "232,01"
155 params['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
156 hostapd.add_ap(apdev[0]['ifname'], params)
157
158 dev[0].hs20_enable()
159 dev[0].request("SET external_sim 1")
2232edf8 160 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
bbe86767
JM
161 interworking_select(dev[0], "home")
162 interworking_ext_sim_connect(dev[0], bssid, "SIM")
163 check_sp_type(dev[0], "home")
59f8a3c6
JM
164
165def test_ap_hs20_ext_sim_roaming(dev, apdev):
166 """Hotspot 2.0 with external SIM processing in roaming network"""
167 if not hlr_auc_gw_available():
168 return "skip"
169 bssid = apdev[0]['bssid']
170 params = hs20_ap_params()
171 params['hessid'] = bssid
172 params['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
173 params['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
174 hostapd.add_ap(apdev[0]['ifname'], params)
175
176 dev[0].hs20_enable()
177 dev[0].request("SET external_sim 1")
2232edf8 178 dev[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
59f8a3c6
JM
179 interworking_select(dev[0], "roaming")
180 interworking_ext_sim_connect(dev[0], bssid, "SIM")
181 check_sp_type(dev[0], "roaming")
8fba2e5d
JM
182
183def test_ap_hs20_username(dev, apdev):
184 """Hotspot 2.0 connection in username/password credential"""
8fba2e5d
JM
185 bssid = apdev[0]['bssid']
186 params = hs20_ap_params()
187 params['hessid'] = bssid
188 hostapd.add_ap(apdev[0]['ifname'], params)
189
190 dev[0].hs20_enable()
2232edf8
JM
191 id = dev[0].add_cred_values({ 'realm': "example.com",
192 'username': "hs20-test",
193 'password': "password",
194 'domain': "example.com" })
8fba2e5d
JM
195 interworking_select(dev[0], bssid, "home")
196 interworking_connect(dev[0], bssid, "TTLS")
197 check_sp_type(dev[0], "home")
198
199def test_ap_hs20_username_roaming(dev, apdev):
200 """Hotspot 2.0 connection in username/password credential (roaming)"""
8fba2e5d
JM
201 bssid = apdev[0]['bssid']
202 params = hs20_ap_params()
203 params['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
204 "0,roaming.example.com,21[2:4][5:7]",
205 "0,another.example.com" ]
206 params['domain_name'] = "another.example.com"
207 params['hessid'] = bssid
208 hostapd.add_ap(apdev[0]['ifname'], params)
209
210 dev[0].hs20_enable()
2232edf8
JM
211 id = dev[0].add_cred_values({ 'realm': "roaming.example.com",
212 'username': "hs20-test",
213 'password': "password",
214 'domain': "example.com" })
8fba2e5d
JM
215 interworking_select(dev[0], bssid, "roaming")
216 interworking_connect(dev[0], bssid, "TTLS")
217 check_sp_type(dev[0], "roaming")
218
219def test_ap_hs20_username_unknown(dev, apdev):
220 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
8fba2e5d
JM
221 bssid = apdev[0]['bssid']
222 params = hs20_ap_params()
223 params['hessid'] = bssid
224 hostapd.add_ap(apdev[0]['ifname'], params)
225
226 dev[0].hs20_enable()
2232edf8
JM
227 id = dev[0].add_cred_values({ 'realm': "example.com",
228 'username': "hs20-test",
229 'password': "password" })
8fba2e5d
JM
230 interworking_select(dev[0], bssid, "unknown")
231 interworking_connect(dev[0], bssid, "TTLS")
232 check_sp_type(dev[0], "unknown")
233
234def test_ap_hs20_username_unknown2(dev, apdev):
235 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
8fba2e5d
JM
236 bssid = apdev[0]['bssid']
237 params = hs20_ap_params()
238 params['hessid'] = bssid
239 del params['domain_name']
240 hostapd.add_ap(apdev[0]['ifname'], params)
241
242 dev[0].hs20_enable()
2232edf8
JM
243 id = dev[0].add_cred_values({ 'realm': "example.com",
244 'username': "hs20-test",
245 'password': "password",
246 'domain': "example.com" })
8fba2e5d
JM
247 interworking_select(dev[0], bssid, "unknown")
248 interworking_connect(dev[0], bssid, "TTLS")
249 check_sp_type(dev[0], "unknown")
d1ba402f 250
6a0b4002
JM
251def test_ap_hs20_multiple_connects(dev, apdev):
252 """Hotspot 2.0 connection through multiple network selections"""
253 bssid = apdev[0]['bssid']
254 params = hs20_ap_params()
255 params['hessid'] = bssid
256 hostapd.add_ap(apdev[0]['ifname'], params)
257
258 dev[0].hs20_enable()
259 values = { 'realm': "example.com",
260 'username': "hs20-test",
261 'password': "password",
262 'domain': "example.com" }
263 id = dev[0].add_cred_values(values)
264
265 for i in range(0, 3):
266 logger.info("Starting Interworking network selection")
267 dev[0].request("INTERWORKING_SELECT auto")
268 while True:
269 ev = dev[0].wait_event(["INTERWORKING-NO-MATCH",
270 "INTERWORKING-ALREADY-CONNECTED",
271 "CTRL-EVENT-CONNECTED"], timeout=15)
272 if ev is None:
273 raise Exception("Connection timed out")
274 if "INTERWORKING-NO-MATCH" in ev:
275 raise Exception("Matching AP not found")
276 if "CTRL-EVENT-CONNECTED" in ev:
277 break
278 if i == 2 and "INTERWORKING-ALREADY-CONNECTED" in ev:
279 break
280 if i == 0:
281 dev[0].request("DISCONNECT")
282 dev[0].dump_monitor()
283
284 networks = dev[0].list_networks()
285 if len(networks) > 1:
286 raise Exception("Duplicated network block detected")
287
d1ba402f
JM
288def policy_test(dev, ap, values, only_one=True):
289 dev.dump_monitor()
290 logger.info("Verify network selection to AP " + ap['ifname'])
291 bssid = ap['bssid']
292 dev.hs20_enable()
293 id = dev.add_cred_values(values)
294 dev.request("INTERWORKING_SELECT auto")
295 while True:
296 ev = dev.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
297 "CTRL-EVENT-CONNECTED"], timeout=15)
298 if ev is None:
299 raise Exception("Connection timed out")
300 if "INTERWORKING-NO-MATCH" in ev:
301 raise Exception("Matching AP not found")
302 if only_one and "INTERWORKING-AP" in ev and bssid not in ev:
303 raise Exception("Unexpected AP claimed acceptable")
304 if "CTRL-EVENT-CONNECTED" in ev:
305 if bssid not in ev:
306 raise Exception("Connected to incorrect BSS")
307 break
308
309 conn_bssid = dev.get_status_field("bssid")
310 if conn_bssid != bssid:
311 raise Exception("bssid information points to incorrect BSS")
312
313 dev.remove_cred(id)
314 dev.dump_monitor()
315
d355372c
JM
316def default_cred():
317 return { 'realm': "example.com",
318 'username': "hs20-test",
319 'password': "password" }
320
d1ba402f
JM
321def test_ap_hs20_req_roaming_consortium(dev, apdev):
322 """Hotspot 2.0 required roaming consortium"""
323 params = hs20_ap_params()
324 hostapd.add_ap(apdev[0]['ifname'], params)
325
326 params = hs20_ap_params()
327 params['ssid'] = "test-hs20-other"
328 params['roaming_consortium'] = [ "223344" ]
329 hostapd.add_ap(apdev[1]['ifname'], params)
330
d355372c
JM
331 values = default_cred()
332 values['required_roaming_consortium'] = "223344"
d1ba402f
JM
333 policy_test(dev[0], apdev[1], values)
334 values['required_roaming_consortium'] = "112233"
335 policy_test(dev[0], apdev[0], values)
d355372c
JM
336
337def test_ap_hs20_excluded_ssid(dev, apdev):
338 """Hotspot 2.0 exclusion based on SSID"""
339 params = hs20_ap_params()
340 hostapd.add_ap(apdev[0]['ifname'], params)
341
342 params = hs20_ap_params()
343 params['ssid'] = "test-hs20-other"
344 params['roaming_consortium'] = [ "223344" ]
345 hostapd.add_ap(apdev[1]['ifname'], params)
346
347 values = default_cred()
348 values['excluded_ssid'] = "test-hs20"
349 policy_test(dev[0], apdev[1], values)
350 values['excluded_ssid'] = "test-hs20-other"
351 policy_test(dev[0], apdev[0], values)