tests: WPS PBC triggered based on hostapd event
[mech_eap.git] / tests / hwsim / test_ap_wps.py
1 # WPS 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 os
8 import time
9 import subprocess
10 import logging
11 logger = logging.getLogger()
12 import re
13 import socket
14 import httplib
15 import urlparse
16 import urllib
17 import xml.etree.ElementTree as ET
18 import StringIO
19
20 import hwsim_utils
21 import hostapd
22
23 def test_ap_wps_init(dev, apdev):
24     """Initial AP configuration with first WPS Enrollee"""
25     ssid = "test-wps"
26     hostapd.add_ap(apdev[0]['ifname'],
27                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
28     hapd = hostapd.Hostapd(apdev[0]['ifname'])
29     logger.info("WPS provisioning step")
30     hapd.request("WPS_PBC")
31     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
32         raise Exception("PBC status not shown correctly")
33
34     id = dev[0].add_network()
35     dev[0].set_network_quoted(id, "ssid", "home")
36     dev[0].set_network_quoted(id, "psk", "12345678")
37     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
38
39     id = dev[0].add_network()
40     dev[0].set_network_quoted(id, "ssid", "home2")
41     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
42     dev[0].set_network(id, "key_mgmt", "NONE")
43     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
44
45     dev[0].request("WPS_PBC")
46     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
47     if ev is None:
48         raise Exception("Association with the AP timed out")
49     status = dev[0].get_status()
50     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
51         raise Exception("Not fully connected")
52     if status['ssid'] != ssid:
53         raise Exception("Unexpected SSID")
54     if status['pairwise_cipher'] != 'CCMP':
55         raise Exception("Unexpected encryption configuration")
56     if status['key_mgmt'] != 'WPA2-PSK':
57         raise Exception("Unexpected key_mgmt")
58
59     status = hapd.request("WPS_GET_STATUS")
60     if "PBC Status: Disabled" not in status:
61         raise Exception("PBC status not shown correctly")
62     if "Last WPS result: Success" not in status:
63         raise Exception("Last WPS result not shown correctly")
64     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
65         raise Exception("Peer address not shown correctly")
66     conf = hapd.request("GET_CONFIG")
67     if "wps_state=configured" not in conf:
68         raise Exception("AP not in WPS configured state")
69     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
70         raise Exception("Unexpected rsn_pairwise_cipher")
71     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
72         raise Exception("Unexpected wpa_pairwise_cipher")
73     if "group_cipher=TKIP" not in conf:
74         raise Exception("Unexpected group_cipher")
75
76     if len(dev[0].list_networks()) != 3:
77         raise Exception("Unexpected number of network blocks")
78
79 def test_ap_wps_init_2ap_pbc(dev, apdev):
80     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
81     ssid = "test-wps"
82     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
83     hostapd.add_ap(apdev[0]['ifname'], params)
84     hostapd.add_ap(apdev[1]['ifname'], params)
85     hapd = hostapd.Hostapd(apdev[0]['ifname'])
86     logger.info("WPS provisioning step")
87     hapd.request("WPS_PBC")
88     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
89     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
90     bss = dev[0].get_bss(apdev[0]['bssid'])
91     if "[WPS-PBC]" not in bss['flags']:
92         raise Exception("WPS-PBC flag missing from AP1")
93     bss = dev[0].get_bss(apdev[1]['bssid'])
94     if "[WPS-PBC]" not in bss['flags']:
95         raise Exception("WPS-PBC flag missing from AP2")
96     dev[0].dump_monitor()
97     dev[0].request("SET wps_cred_processing 2")
98     dev[0].request("WPS_PBC")
99     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
100     dev[0].request("SET wps_cred_processing 0")
101     if ev is None:
102         raise Exception("WPS cred event not seen")
103     if "100e" not in ev:
104         raise Exception("WPS attributes not included in the cred event")
105     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
106     if ev is None:
107         raise Exception("Association with the AP timed out")
108
109     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
110     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
111     bss = dev[1].get_bss(apdev[0]['bssid'])
112     if "[WPS-PBC]" in bss['flags']:
113         raise Exception("WPS-PBC flag not cleared from AP1")
114     bss = dev[1].get_bss(apdev[1]['bssid'])
115     if "[WPS-PBC]" in bss['flags']:
116         raise Exception("WPS-PBC flag not cleared from AP2")
117
118 def test_ap_wps_init_2ap_pin(dev, apdev):
119     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
120     ssid = "test-wps"
121     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
122     hostapd.add_ap(apdev[0]['ifname'], params)
123     hostapd.add_ap(apdev[1]['ifname'], params)
124     hapd = hostapd.Hostapd(apdev[0]['ifname'])
125     logger.info("WPS provisioning step")
126     pin = dev[0].wps_read_pin()
127     hapd.request("WPS_PIN any " + pin)
128     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
129     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
130     bss = dev[0].get_bss(apdev[0]['bssid'])
131     if "[WPS-AUTH]" not in bss['flags']:
132         raise Exception("WPS-AUTH flag missing from AP1")
133     bss = dev[0].get_bss(apdev[1]['bssid'])
134     if "[WPS-AUTH]" not in bss['flags']:
135         raise Exception("WPS-AUTH flag missing from AP2")
136     dev[0].dump_monitor()
137     dev[0].request("WPS_PIN any " + pin)
138     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
139     if ev is None:
140         raise Exception("Association with the AP timed out")
141
142     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
143     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
144     bss = dev[1].get_bss(apdev[0]['bssid'])
145     if "[WPS-AUTH]" in bss['flags']:
146         raise Exception("WPS-AUTH flag not cleared from AP1")
147     bss = dev[1].get_bss(apdev[1]['bssid'])
148     if "[WPS-AUTH]" in bss['flags']:
149         raise Exception("WPS-AUTH flag not cleared from AP2")
150
151 def test_ap_wps_init_through_wps_config(dev, apdev):
152     """Initial AP configuration using wps_config command"""
153     ssid = "test-wps-init-config"
154     hostapd.add_ap(apdev[0]['ifname'],
155                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
156     hapd = hostapd.Hostapd(apdev[0]['ifname'])
157     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
158         raise Exception("WPS_CONFIG command failed")
159     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
160     if ev is None:
161         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
162     # It takes some time for the AP to update Beacon and Probe Response frames,
163     # so wait here before requesting the scan to be started to avoid adding
164     # extra five second wait to the test due to fetching obsolete scan results.
165     hapd.ping()
166     time.sleep(0.2)
167     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
168                    pairwise="CCMP", group="CCMP")
169
170 def test_ap_wps_conf(dev, apdev):
171     """WPS PBC provisioning with configured AP"""
172     ssid = "test-wps-conf"
173     hostapd.add_ap(apdev[0]['ifname'],
174                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
175                      "wpa_passphrase": "12345678", "wpa": "2",
176                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
177     hapd = hostapd.Hostapd(apdev[0]['ifname'])
178     logger.info("WPS provisioning step")
179     hapd.request("WPS_PBC")
180     dev[0].dump_monitor()
181     dev[0].request("WPS_PBC")
182     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
183     if ev is None:
184         raise Exception("Association with the AP timed out")
185     status = dev[0].get_status()
186     if status['wpa_state'] != 'COMPLETED':
187         raise Exception("Not fully connected")
188     if status['bssid'] != apdev[0]['bssid']:
189         raise Exception("Unexpected BSSID")
190     if status['ssid'] != ssid:
191         raise Exception("Unexpected SSID")
192     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
193         raise Exception("Unexpected encryption configuration")
194     if status['key_mgmt'] != 'WPA2-PSK':
195         raise Exception("Unexpected key_mgmt")
196
197     sta = hapd.get_sta(dev[0].p2p_interface_addr())
198     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
199         raise Exception("Device name not available in STA command")
200
201 def test_ap_wps_conf_5ghz(dev, apdev):
202     """WPS PBC provisioning with configured AP on 5 GHz band"""
203     try:
204         ssid = "test-wps-conf"
205         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
206                    "wpa_passphrase": "12345678", "wpa": "2",
207                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
208                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
209         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
210         logger.info("WPS provisioning step")
211         hapd.request("WPS_PBC")
212         dev[0].request("WPS_PBC")
213         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
214         if ev is None:
215             raise Exception("Association with the AP timed out")
216
217         sta = hapd.get_sta(dev[0].p2p_interface_addr())
218         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
219             raise Exception("Device name not available in STA command")
220     finally:
221         subprocess.call(['sudo', 'iw', 'reg', 'set', '00'])
222
223 def test_ap_wps_conf_chan14(dev, apdev):
224     """WPS PBC provisioning with configured AP on channel 14"""
225     try:
226         ssid = "test-wps-conf"
227         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
228                    "wpa_passphrase": "12345678", "wpa": "2",
229                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
230                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
231         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
232         logger.info("WPS provisioning step")
233         hapd.request("WPS_PBC")
234         dev[0].request("WPS_PBC")
235         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
236         if ev is None:
237             raise Exception("Association with the AP timed out")
238
239         sta = hapd.get_sta(dev[0].p2p_interface_addr())
240         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
241             raise Exception("Device name not available in STA command")
242     finally:
243         subprocess.call(['sudo', 'iw', 'reg', 'set', '00'])
244
245 def test_ap_wps_twice(dev, apdev):
246     """WPS provisioning with twice to change passphrase"""
247     ssid = "test-wps-twice"
248     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
249                "wpa_passphrase": "12345678", "wpa": "2",
250                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
251     hostapd.add_ap(apdev[0]['ifname'], params)
252     hapd = hostapd.Hostapd(apdev[0]['ifname'])
253     logger.info("WPS provisioning step")
254     hapd.request("WPS_PBC")
255     dev[0].dump_monitor()
256     dev[0].request("WPS_PBC")
257     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
258     if ev is None:
259         raise Exception("Association with the AP timed out")
260     dev[0].request("DISCONNECT")
261
262     logger.info("Restart AP with different passphrase and re-run WPS")
263     hapd_global = hostapd.HostapdGlobal()
264     hapd_global.remove(apdev[0]['ifname'])
265     params['wpa_passphrase'] = 'another passphrase'
266     hostapd.add_ap(apdev[0]['ifname'], params)
267     hapd = hostapd.Hostapd(apdev[0]['ifname'])
268     logger.info("WPS provisioning step")
269     hapd.request("WPS_PBC")
270     dev[0].dump_monitor()
271     dev[0].request("WPS_PBC any")
272     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
273     if ev is None:
274         raise Exception("Association with the AP timed out")
275     networks = dev[0].list_networks()
276     if len(networks) > 1:
277         raise Exception("Unexpected duplicated network block present")
278
279 def test_ap_wps_incorrect_pin(dev, apdev):
280     """WPS PIN provisioning with incorrect PIN"""
281     ssid = "test-wps-incorrect-pin"
282     hostapd.add_ap(apdev[0]['ifname'],
283                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
284                      "wpa_passphrase": "12345678", "wpa": "2",
285                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
286     hapd = hostapd.Hostapd(apdev[0]['ifname'])
287
288     logger.info("WPS provisioning attempt 1")
289     hapd.request("WPS_PIN any 12345670")
290     dev[0].dump_monitor()
291     dev[0].request("WPS_PIN any 55554444")
292     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
293     if ev is None:
294         raise Exception("WPS operation timed out")
295     if "config_error=18" not in ev:
296         raise Exception("Incorrect config_error reported")
297     if "msg=8" not in ev:
298         raise Exception("PIN error detected on incorrect message")
299     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
300     if ev is None:
301         raise Exception("Timeout on disconnection event")
302     dev[0].request("WPS_CANCEL")
303     # if a scan was in progress, wait for it to complete before trying WPS again
304     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
305
306     status = hapd.request("WPS_GET_STATUS")
307     if "Last WPS result: Failed" not in status:
308         raise Exception("WPS failure result not shown correctly")
309
310     logger.info("WPS provisioning attempt 2")
311     hapd.request("WPS_PIN any 12345670")
312     dev[0].dump_monitor()
313     dev[0].request("WPS_PIN any 12344444")
314     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
315     if ev is None:
316         raise Exception("WPS operation timed out")
317     if "config_error=18" not in ev:
318         raise Exception("Incorrect config_error reported")
319     if "msg=10" not in ev:
320         raise Exception("PIN error detected on incorrect message")
321     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
322     if ev is None:
323         raise Exception("Timeout on disconnection event")
324
325 def test_ap_wps_conf_pin(dev, apdev):
326     """WPS PIN provisioning with configured AP"""
327     ssid = "test-wps-conf-pin"
328     hostapd.add_ap(apdev[0]['ifname'],
329                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
330                      "wpa_passphrase": "12345678", "wpa": "2",
331                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
332     hapd = hostapd.Hostapd(apdev[0]['ifname'])
333     logger.info("WPS provisioning step")
334     pin = dev[0].wps_read_pin()
335     hapd.request("WPS_PIN any " + pin)
336     dev[0].dump_monitor()
337     dev[0].request("WPS_PIN any " + pin)
338     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
339     if ev is None:
340         raise Exception("Association with the AP timed out")
341     status = dev[0].get_status()
342     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
343         raise Exception("Not fully connected")
344     if status['ssid'] != ssid:
345         raise Exception("Unexpected SSID")
346     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
347         raise Exception("Unexpected encryption configuration")
348     if status['key_mgmt'] != 'WPA2-PSK':
349         raise Exception("Unexpected key_mgmt")
350
351     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
352     bss = dev[1].get_bss(apdev[0]['bssid'])
353     if "[WPS-AUTH]" in bss['flags']:
354         raise Exception("WPS-AUTH flag not cleared")
355     logger.info("Try to connect from another station using the same PIN")
356     pin = dev[1].request("WPS_PIN any")
357     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
358     if ev is None:
359         raise Exception("Operation timed out")
360     if "WPS-M2D" not in ev:
361         raise Exception("Unexpected WPS operation started")
362     hapd.request("WPS_PIN any " + pin)
363     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
364     if ev is None:
365         raise Exception("Association with the AP timed out")
366
367 def test_ap_wps_conf_pin_v1(dev, apdev):
368     """WPS PIN provisioning with configured WPS v1.0 AP"""
369     ssid = "test-wps-conf-pin-v1"
370     hostapd.add_ap(apdev[0]['ifname'],
371                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
372                      "wpa_passphrase": "12345678", "wpa": "2",
373                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
374     hapd = hostapd.Hostapd(apdev[0]['ifname'])
375     logger.info("WPS provisioning step")
376     pin = dev[0].wps_read_pin()
377     hapd.request("SET wps_version_number 0x10")
378     hapd.request("WPS_PIN any " + pin)
379     found = False
380     for i in range(0, 10):
381         dev[0].scan(freq="2412")
382         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
383             found = True
384             break
385     if not found:
386         hapd.request("SET wps_version_number 0x20")
387         raise Exception("WPS-PIN flag not seen in scan results")
388     dev[0].dump_monitor()
389     dev[0].request("WPS_PIN any " + pin)
390     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
391     hapd.request("SET wps_version_number 0x20")
392     if ev is None:
393         raise Exception("Association with the AP timed out")
394
395 def test_ap_wps_conf_pin_2sta(dev, apdev):
396     """Two stations trying to use WPS PIN at the same time"""
397     ssid = "test-wps-conf-pin2"
398     hostapd.add_ap(apdev[0]['ifname'],
399                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
400                      "wpa_passphrase": "12345678", "wpa": "2",
401                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
402     hapd = hostapd.Hostapd(apdev[0]['ifname'])
403     logger.info("WPS provisioning step")
404     pin = "12345670"
405     pin2 = "55554444"
406     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
407     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
408     dev[0].dump_monitor()
409     dev[1].dump_monitor()
410     dev[0].request("WPS_PIN any " + pin)
411     dev[1].request("WPS_PIN any " + pin)
412     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
413     if ev is None:
414         raise Exception("Association with the AP timed out")
415     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
416     if ev is None:
417         raise Exception("Association with the AP timed out")
418
419 def test_ap_wps_conf_pin_timeout(dev, apdev):
420     """WPS PIN provisioning with configured AP timing out PIN"""
421     ssid = "test-wps-conf-pin"
422     hostapd.add_ap(apdev[0]['ifname'],
423                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
424                      "wpa_passphrase": "12345678", "wpa": "2",
425                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
426     hapd = hostapd.Hostapd(apdev[0]['ifname'])
427     addr = dev[0].p2p_interface_addr()
428     pin = dev[0].wps_read_pin()
429     if "FAIL" not in hapd.request("WPS_PIN "):
430         raise Exception("Unexpected success on invalid WPS_PIN")
431     hapd.request("WPS_PIN any " + pin + " 1")
432     time.sleep(1.1)
433     dev[0].request("WPS_PIN any " + pin)
434     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
435     if ev is None:
436         raise Exception("WPS-PIN-NEEDED event timed out")
437     ev = dev[0].wait_event(["WPS-M2D"])
438     if ev is None:
439         raise Exception("M2D not reported")
440     dev[0].request("WPS_CANCEL")
441
442     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
443     dev[0].request("WPS_PIN any " + pin)
444     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
445     if ev is None:
446         raise Exception("Association with the AP timed out")
447
448 def test_ap_wps_reg_connect(dev, apdev):
449     """WPS registrar using AP PIN to connect"""
450     ssid = "test-wps-reg-ap-pin"
451     appin = "12345670"
452     hostapd.add_ap(apdev[0]['ifname'],
453                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
454                      "wpa_passphrase": "12345678", "wpa": "2",
455                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
456                      "ap_pin": appin})
457     logger.info("WPS provisioning step")
458     dev[0].dump_monitor()
459     dev[0].wps_reg(apdev[0]['bssid'], appin)
460     status = dev[0].get_status()
461     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
462         raise Exception("Not fully connected")
463     if status['ssid'] != ssid:
464         raise Exception("Unexpected SSID")
465     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
466         raise Exception("Unexpected encryption configuration")
467     if status['key_mgmt'] != 'WPA2-PSK':
468         raise Exception("Unexpected key_mgmt")
469
470 def check_wps_reg_failure(dev, ap, appin):
471     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
472     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
473     if ev is None:
474         raise Exception("WPS operation timed out")
475     if "WPS-SUCCESS" in ev:
476         raise Exception("WPS operation succeeded unexpectedly")
477     if "config_error=15" not in ev:
478         raise Exception("WPS setup locked state was not reported correctly")
479
480 def test_ap_wps_random_ap_pin(dev, apdev):
481     """WPS registrar using random AP PIN"""
482     ssid = "test-wps-reg-random-ap-pin"
483     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
484     hostapd.add_ap(apdev[0]['ifname'],
485                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
486                      "wpa_passphrase": "12345678", "wpa": "2",
487                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
488                      "device_name": "Wireless AP", "manufacturer": "Company",
489                      "model_name": "WAP", "model_number": "123",
490                      "serial_number": "12345", "device_type": "6-0050F204-1",
491                      "os_version": "01020300",
492                      "config_methods": "label push_button",
493                      "uuid": ap_uuid, "upnp_iface": "lo" })
494     hapd = hostapd.Hostapd(apdev[0]['ifname'])
495     appin = hapd.request("WPS_AP_PIN random")
496     if "FAIL" in appin:
497         raise Exception("Could not generate random AP PIN")
498     if appin not in hapd.request("WPS_AP_PIN get"):
499         raise Exception("Could not fetch current AP PIN")
500     logger.info("WPS provisioning step")
501     dev[0].wps_reg(apdev[0]['bssid'], appin)
502
503     hapd.request("WPS_AP_PIN disable")
504     logger.info("WPS provisioning step with AP PIN disabled")
505     check_wps_reg_failure(dev[1], apdev[0], appin)
506
507     logger.info("WPS provisioning step with AP PIN reset")
508     appin = "12345670"
509     hapd.request("WPS_AP_PIN set " + appin)
510     dev[1].wps_reg(apdev[0]['bssid'], appin)
511     dev[0].request("REMOVE_NETWORK all")
512     dev[1].request("REMOVE_NETWORK all")
513     dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
514     dev[1].wait_event(["CTRL-EVENT-DISCONNECTED"])
515
516     logger.info("WPS provisioning step after AP PIN timeout")
517     hapd.request("WPS_AP_PIN disable")
518     appin = hapd.request("WPS_AP_PIN random 1")
519     time.sleep(1.1)
520     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
521         raise Exception("AP PIN unexpectedly still enabled")
522     check_wps_reg_failure(dev[0], apdev[0], appin)
523
524     logger.info("WPS provisioning step after AP PIN timeout(2)")
525     hapd.request("WPS_AP_PIN disable")
526     appin = "12345670"
527     hapd.request("WPS_AP_PIN set " + appin + " 1")
528     time.sleep(1.1)
529     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
530         raise Exception("AP PIN unexpectedly still enabled")
531     check_wps_reg_failure(dev[1], apdev[0], appin)
532
533 def test_ap_wps_reg_config(dev, apdev):
534     """WPS registrar configuring an AP using AP PIN"""
535     ssid = "test-wps-init-ap-pin"
536     appin = "12345670"
537     hostapd.add_ap(apdev[0]['ifname'],
538                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
539                      "ap_pin": appin})
540     logger.info("WPS configuration step")
541     dev[0].dump_monitor()
542     new_ssid = "wps-new-ssid"
543     new_passphrase = "1234567890"
544     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
545                    new_passphrase)
546     status = dev[0].get_status()
547     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
548         raise Exception("Not fully connected")
549     if status['ssid'] != new_ssid:
550         raise Exception("Unexpected SSID")
551     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
552         raise Exception("Unexpected encryption configuration")
553     if status['key_mgmt'] != 'WPA2-PSK':
554         raise Exception("Unexpected key_mgmt")
555
556     logger.info("Re-configure back to open")
557     dev[0].request("REMOVE_NETWORK all")
558     dev[0].request("BSS_FLUSH 0")
559     dev[0].request("SCAN freq=2412 only_new=1")
560     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
561     if ev is None:
562         raise Exception("Scan timed out")
563     dev[0].dump_monitor()
564     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
565     status = dev[0].get_status()
566     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
567         raise Exception("Not fully connected")
568     if status['ssid'] != "wps-open":
569         raise Exception("Unexpected SSID")
570     if status['key_mgmt'] != 'NONE':
571         raise Exception("Unexpected key_mgmt")
572
573 def test_ap_wps_reg_config_ext_processing(dev, apdev):
574     """WPS registrar configuring an AP with external config processing"""
575     ssid = "test-wps-init-ap-pin"
576     appin = "12345670"
577     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
578                "wps_cred_processing": "1", "ap_pin": appin}
579     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
580     new_ssid = "wps-new-ssid"
581     new_passphrase = "1234567890"
582     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
583                    new_passphrase, no_wait=True)
584     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
585     if ev is None:
586         raise Exception("WPS registrar operation timed out")
587     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
588     if ev is None:
589         raise Exception("WPS configuration timed out")
590     if "1026" not in ev:
591         raise Exception("AP Settings missing from event")
592     hapd.request("SET wps_cred_processing 0")
593     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
594         raise Exception("WPS_CONFIG command failed")
595     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
596     if ev is None:
597         raise Exception("Association with the AP timed out")
598
599 def test_ap_wps_reg_config_tkip(dev, apdev):
600     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
601     ssid = "test-wps-init-ap"
602     appin = "12345670"
603     hostapd.add_ap(apdev[0]['ifname'],
604                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
605                      "ap_pin": appin})
606     logger.info("WPS configuration step")
607     dev[0].request("SET wps_version_number 0x10")
608     dev[0].dump_monitor()
609     new_ssid = "wps-new-ssid-with-tkip"
610     new_passphrase = "1234567890"
611     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
612                    new_passphrase)
613     logger.info("Re-connect to verify WPA2 mixed mode")
614     dev[0].request("DISCONNECT")
615     id = 0
616     dev[0].set_network(id, "pairwise", "CCMP")
617     dev[0].set_network(id, "proto", "RSN")
618     dev[0].connect_network(id)
619     status = dev[0].get_status()
620     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
621         raise Exception("Not fully connected")
622     if status['ssid'] != new_ssid:
623         raise Exception("Unexpected SSID")
624     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
625         raise Exception("Unexpected encryption configuration")
626     if status['key_mgmt'] != 'WPA2-PSK':
627         raise Exception("Unexpected key_mgmt")
628
629 def test_ap_wps_setup_locked(dev, apdev):
630     """WPS registrar locking up AP setup on AP PIN failures"""
631     ssid = "test-wps-incorrect-ap-pin"
632     appin = "12345670"
633     hostapd.add_ap(apdev[0]['ifname'],
634                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
635                      "wpa_passphrase": "12345678", "wpa": "2",
636                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
637                      "ap_pin": appin})
638     new_ssid = "wps-new-ssid-test"
639     new_passphrase = "1234567890"
640
641     ap_setup_locked=False
642     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
643         dev[0].dump_monitor()
644         logger.info("Try incorrect AP PIN - attempt " + pin)
645         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
646                        "CCMP", new_passphrase, no_wait=True)
647         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
648         if ev is None:
649             raise Exception("Timeout on receiving WPS operation failure event")
650         if "CTRL-EVENT-CONNECTED" in ev:
651             raise Exception("Unexpected connection")
652         if "config_error=15" in ev:
653             logger.info("AP Setup Locked")
654             ap_setup_locked=True
655         elif "config_error=18" not in ev:
656             raise Exception("config_error=18 not reported")
657         ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
658         if ev is None:
659             raise Exception("Timeout on disconnection event")
660         time.sleep(0.1)
661     if not ap_setup_locked:
662         raise Exception("AP setup was not locked")
663
664     hapd = hostapd.Hostapd(apdev[0]['ifname'])
665     status = hapd.request("WPS_GET_STATUS")
666     if "Last WPS result: Failed" not in status:
667         raise Exception("WPS failure result not shown correctly")
668     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
669         raise Exception("Peer address not shown correctly")
670
671     time.sleep(0.5)
672     dev[0].dump_monitor()
673     logger.info("WPS provisioning step")
674     pin = dev[0].wps_read_pin()
675     hapd = hostapd.Hostapd(apdev[0]['ifname'])
676     hapd.request("WPS_PIN any " + pin)
677     dev[0].request("WPS_PIN any " + pin)
678     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
679     if ev is None:
680         raise Exception("WPS success was not reported")
681     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
682     if ev is None:
683         raise Exception("Association with the AP timed out")
684
685     appin = hapd.request("WPS_AP_PIN random")
686     if "FAIL" in appin:
687         raise Exception("Could not generate random AP PIN")
688     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
689     if ev is None:
690         raise Exception("Failed to unlock AP PIN")
691
692 def test_ap_wps_setup_locked_timeout(dev, apdev):
693     """WPS re-enabling AP PIN after timeout"""
694     ssid = "test-wps-incorrect-ap-pin"
695     appin = "12345670"
696     hostapd.add_ap(apdev[0]['ifname'],
697                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
698                      "wpa_passphrase": "12345678", "wpa": "2",
699                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
700                      "ap_pin": appin})
701     new_ssid = "wps-new-ssid-test"
702     new_passphrase = "1234567890"
703
704     ap_setup_locked=False
705     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
706         dev[0].dump_monitor()
707         logger.info("Try incorrect AP PIN - attempt " + pin)
708         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
709                        "CCMP", new_passphrase, no_wait=True)
710         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
711         if ev is None:
712             raise Exception("Timeout on receiving WPS operation failure event")
713         if "CTRL-EVENT-CONNECTED" in ev:
714             raise Exception("Unexpected connection")
715         if "config_error=15" in ev:
716             logger.info("AP Setup Locked")
717             ap_setup_locked=True
718             break
719         elif "config_error=18" not in ev:
720             raise Exception("config_error=18 not reported")
721         ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
722         if ev is None:
723             raise Exception("Timeout on disconnection event")
724         time.sleep(0.1)
725     if not ap_setup_locked:
726         raise Exception("AP setup was not locked")
727     hapd = hostapd.Hostapd(apdev[0]['ifname'])
728     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
729     if ev is None:
730         raise Exception("AP PIN did not get unlocked on 60 second timeout")
731
732 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
733     """WPS PBC session overlap with two active APs"""
734     hostapd.add_ap(apdev[0]['ifname'],
735                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
736                      "wpa_passphrase": "12345678", "wpa": "2",
737                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
738                      "wps_independent": "1"})
739     hostapd.add_ap(apdev[1]['ifname'],
740                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
741                      "wpa_passphrase": "123456789", "wpa": "2",
742                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
743                      "wps_independent": "1"})
744     hapd = hostapd.Hostapd(apdev[0]['ifname'])
745     hapd.request("WPS_PBC")
746     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
747     hapd2.request("WPS_PBC")
748     logger.info("WPS provisioning step")
749     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
750     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
751     dev[0].request("WPS_PBC")
752     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
753     if ev is None:
754         raise Exception("PBC session overlap not detected")
755
756 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
757     """WPS PBC session overlap with two active STAs"""
758     ssid = "test-wps-pbc-overlap"
759     hostapd.add_ap(apdev[0]['ifname'],
760                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
761                      "wpa_passphrase": "12345678", "wpa": "2",
762                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
763     hapd = hostapd.Hostapd(apdev[0]['ifname'])
764     logger.info("WPS provisioning step")
765     hapd.request("WPS_PBC")
766     dev[0].dump_monitor()
767     dev[1].dump_monitor()
768     dev[0].request("WPS_PBC")
769     dev[1].request("WPS_PBC")
770     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
771     if ev is None:
772         raise Exception("PBC session overlap not detected (dev0)")
773     if "config_error=12" not in ev:
774         raise Exception("PBC session overlap not correctly reported (dev0)")
775     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
776     if ev is None:
777         raise Exception("PBC session overlap not detected (dev1)")
778     if "config_error=12" not in ev:
779         raise Exception("PBC session overlap not correctly reported (dev1)")
780     hapd.request("WPS_CANCEL")
781     ret = hapd.request("WPS_PBC")
782     if "FAIL" not in ret:
783         raise Exception("PBC mode allowed to be started while PBC overlap still active")
784
785 def test_ap_wps_cancel(dev, apdev):
786     """WPS AP cancelling enabled config method"""
787     ssid = "test-wps-ap-cancel"
788     hostapd.add_ap(apdev[0]['ifname'],
789                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
790                      "wpa_passphrase": "12345678", "wpa": "2",
791                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
792     bssid = apdev[0]['bssid']
793     hapd = hostapd.Hostapd(apdev[0]['ifname'])
794
795     logger.info("Verify PBC enable/cancel")
796     hapd.request("WPS_PBC")
797     dev[0].scan(freq="2412")
798     dev[0].scan(freq="2412")
799     bss = dev[0].get_bss(apdev[0]['bssid'])
800     if "[WPS-PBC]" not in bss['flags']:
801         raise Exception("WPS-PBC flag missing")
802     if "FAIL" in hapd.request("WPS_CANCEL"):
803         raise Exception("WPS_CANCEL failed")
804     dev[0].scan(freq="2412")
805     dev[0].scan(freq="2412")
806     bss = dev[0].get_bss(apdev[0]['bssid'])
807     if "[WPS-PBC]" in bss['flags']:
808         raise Exception("WPS-PBC flag not cleared")
809
810     logger.info("Verify PIN enable/cancel")
811     hapd.request("WPS_PIN any 12345670")
812     dev[0].scan(freq="2412")
813     dev[0].scan(freq="2412")
814     bss = dev[0].get_bss(apdev[0]['bssid'])
815     if "[WPS-AUTH]" not in bss['flags']:
816         raise Exception("WPS-AUTH flag missing")
817     if "FAIL" in hapd.request("WPS_CANCEL"):
818         raise Exception("WPS_CANCEL failed")
819     dev[0].scan(freq="2412")
820     dev[0].scan(freq="2412")
821     bss = dev[0].get_bss(apdev[0]['bssid'])
822     if "[WPS-AUTH]" in bss['flags']:
823         raise Exception("WPS-AUTH flag not cleared")
824
825 def test_ap_wps_er_add_enrollee(dev, apdev):
826     """WPS ER configuring AP and adding a new enrollee using PIN"""
827     ssid = "wps-er-add-enrollee"
828     ap_pin = "12345670"
829     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
830     hostapd.add_ap(apdev[0]['ifname'],
831                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
832                      "device_name": "Wireless AP", "manufacturer": "Company",
833                      "model_name": "WAP", "model_number": "123",
834                      "serial_number": "12345", "device_type": "6-0050F204-1",
835                      "os_version": "01020300",
836                      "config_methods": "label push_button",
837                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
838     logger.info("WPS configuration step")
839     new_passphrase = "1234567890"
840     dev[0].dump_monitor()
841     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
842                    new_passphrase)
843     status = dev[0].get_status()
844     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
845         raise Exception("Not fully connected")
846     if status['ssid'] != ssid:
847         raise Exception("Unexpected SSID")
848     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
849         raise Exception("Unexpected encryption configuration")
850     if status['key_mgmt'] != 'WPA2-PSK':
851         raise Exception("Unexpected key_mgmt")
852
853     logger.info("Start ER")
854     dev[0].request("WPS_ER_START ifname=lo")
855     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
856     if ev is None:
857         raise Exception("AP discovery timed out")
858     if ap_uuid not in ev:
859         raise Exception("Expected AP UUID not found")
860
861     logger.info("Learn AP configuration through UPnP")
862     dev[0].dump_monitor()
863     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
864     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
865     if ev is None:
866         raise Exception("AP learn timed out")
867     if ap_uuid not in ev:
868         raise Exception("Expected AP UUID not in settings")
869     if "ssid=" + ssid not in ev:
870         raise Exception("Expected SSID not in settings")
871     if "key=" + new_passphrase not in ev:
872         raise Exception("Expected passphrase not in settings")
873
874     logger.info("Add Enrollee using ER")
875     pin = dev[1].wps_read_pin()
876     dev[0].dump_monitor()
877     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
878     dev[1].dump_monitor()
879     dev[1].request("WPS_PIN any " + pin)
880     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
881     if ev is None:
882         raise Exception("Enrollee did not report success")
883     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
884     if ev is None:
885         raise Exception("Association with the AP timed out")
886     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
887     if ev is None:
888         raise Exception("WPS ER did not report success")
889     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
890
891     logger.info("Add a specific Enrollee using ER")
892     pin = dev[2].wps_read_pin()
893     addr2 = dev[2].p2p_interface_addr()
894     dev[0].dump_monitor()
895     dev[2].dump_monitor()
896     dev[2].request("WPS_PIN any " + pin)
897     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
898     if ev is None:
899         raise Exception("Enrollee not seen")
900     if addr2 not in ev:
901         raise Exception("Unexpected Enrollee MAC address")
902     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
903     ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
904     if ev is None:
905         raise Exception("Association with the AP timed out")
906     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
907     if ev is None:
908         raise Exception("WPS ER did not report success")
909
910     logger.info("Verify registrar selection behavior")
911     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
912     dev[1].request("DISCONNECT")
913     dev[1].wait_event(["CTRL-EVENT-DISCONNECTED"])
914     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
915     dev[1].scan(freq="2412")
916     bss = dev[1].get_bss(apdev[0]['bssid'])
917     if "[WPS-AUTH]" not in bss['flags']:
918         # It is possible for scan to miss an update especially when running
919         # tests under load with multiple VMs, so allow another attempt.
920         dev[1].scan(freq="2412")
921         bss = dev[1].get_bss(apdev[0]['bssid'])
922         if "[WPS-AUTH]" not in bss['flags']:
923             raise Exception("WPS-AUTH flag missing")
924
925     logger.info("Stop ER")
926     dev[0].dump_monitor()
927     dev[0].request("WPS_ER_STOP")
928     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
929     if ev is None:
930         raise Exception("WPS ER unsubscription timed out")
931     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
932     # a bit before verifying that the scan results have changed.
933     time.sleep(0.2)
934
935     for i in range(0, 10):
936         dev[1].request("BSS_FLUSH 0")
937         dev[1].scan(freq="2412", only_new=True)
938         bss = dev[1].get_bss(apdev[0]['bssid'])
939         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
940             break
941         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
942         time.sleep(0.1)
943     if "[WPS-AUTH]" in bss['flags']:
944         raise Exception("WPS-AUTH flag not removed")
945
946 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
947     """WPS ER connected to AP and adding a new enrollee using PBC"""
948     ssid = "wps-er-add-enrollee-pbc"
949     ap_pin = "12345670"
950     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
951     hostapd.add_ap(apdev[0]['ifname'],
952                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
953                      "wpa_passphrase": "12345678", "wpa": "2",
954                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
955                      "device_name": "Wireless AP", "manufacturer": "Company",
956                      "model_name": "WAP", "model_number": "123",
957                      "serial_number": "12345", "device_type": "6-0050F204-1",
958                      "os_version": "01020300",
959                      "config_methods": "label push_button",
960                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
961     logger.info("Learn AP configuration")
962     dev[0].dump_monitor()
963     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
964     status = dev[0].get_status()
965     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
966         raise Exception("Not fully connected")
967
968     logger.info("Start ER")
969     dev[0].request("WPS_ER_START ifname=lo")
970     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
971     if ev is None:
972         raise Exception("AP discovery timed out")
973     if ap_uuid not in ev:
974         raise Exception("Expected AP UUID not found")
975
976     logger.info("Use learned network configuration on ER")
977     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
978
979     logger.info("Add Enrollee using ER and PBC")
980     dev[0].dump_monitor()
981     enrollee = dev[1].p2p_interface_addr()
982     dev[1].dump_monitor()
983     dev[1].request("WPS_PBC")
984
985     for i in range(0, 2):
986         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
987         if ev is None:
988             raise Exception("Enrollee discovery timed out")
989         if enrollee in ev:
990             break
991         if i == 1:
992             raise Exception("Expected Enrollee not found")
993     dev[0].request("WPS_ER_PBC " + enrollee)
994
995     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
996     if ev is None:
997         raise Exception("Enrollee did not report success")
998     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
999     if ev is None:
1000         raise Exception("Association with the AP timed out")
1001     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1002     if ev is None:
1003         raise Exception("WPS ER did not report success")
1004     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1005
1006     # verify BSSID selection of the AP instead of UUID
1007     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1008         raise Exception("Could not select AP based on BSSID")
1009
1010 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1011     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1012     ssid = "wps-er-add-enrollee-pbc"
1013     ap_pin = "12345670"
1014     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1015     hostapd.add_ap(apdev[0]['ifname'],
1016                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1017                      "wpa_passphrase": "12345678", "wpa": "2",
1018                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1019                      "device_name": "Wireless AP", "manufacturer": "Company",
1020                      "model_name": "WAP", "model_number": "123",
1021                      "serial_number": "12345", "device_type": "6-0050F204-1",
1022                      "os_version": "01020300",
1023                      "config_methods": "label push_button",
1024                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1025     logger.info("Learn AP configuration")
1026     dev[0].request("SET wps_version_number 0x10")
1027     dev[0].dump_monitor()
1028     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1029     status = dev[0].get_status()
1030     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1031         raise Exception("Not fully connected")
1032
1033     logger.info("Start ER")
1034     dev[0].request("WPS_ER_START ifname=lo")
1035     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1036     if ev is None:
1037         raise Exception("AP discovery timed out")
1038     if ap_uuid not in ev:
1039         raise Exception("Expected AP UUID not found")
1040
1041     logger.info("Use learned network configuration on ER")
1042     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1043
1044     logger.info("Add Enrollee using ER and PIN")
1045     enrollee = dev[1].p2p_interface_addr()
1046     pin = dev[1].wps_read_pin()
1047     dev[0].dump_monitor()
1048     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1049     dev[1].dump_monitor()
1050     dev[1].request("WPS_PIN any " + pin)
1051     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=15)
1052     if ev is None:
1053         raise Exception("Association with the AP timed out")
1054     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1055     if ev is None:
1056         raise Exception("WPS ER did not report success")
1057
1058 def test_ap_wps_er_config_ap(dev, apdev):
1059     """WPS ER configuring AP over UPnP"""
1060     ssid = "wps-er-ap-config"
1061     ap_pin = "12345670"
1062     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1063     hostapd.add_ap(apdev[0]['ifname'],
1064                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1065                      "wpa_passphrase": "12345678", "wpa": "2",
1066                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1067                      "device_name": "Wireless AP", "manufacturer": "Company",
1068                      "model_name": "WAP", "model_number": "123",
1069                      "serial_number": "12345", "device_type": "6-0050F204-1",
1070                      "os_version": "01020300",
1071                      "config_methods": "label push_button",
1072                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1073
1074     logger.info("Connect ER to the AP")
1075     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1076
1077     logger.info("WPS configuration step")
1078     dev[0].request("WPS_ER_START ifname=lo")
1079     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1080     if ev is None:
1081         raise Exception("AP discovery timed out")
1082     if ap_uuid not in ev:
1083         raise Exception("Expected AP UUID not found")
1084     new_passphrase = "1234567890"
1085     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1086                    ssid.encode("hex") + " WPA2PSK CCMP " +
1087                    new_passphrase.encode("hex"))
1088     ev = dev[0].wait_event(["WPS-SUCCESS"])
1089     if ev is None:
1090         raise Exception("WPS ER configuration operation timed out")
1091     dev[1].wait_event(["CTRL-EVENT-DISCONNECTED"])
1092     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1093
1094 def test_ap_wps_fragmentation(dev, apdev):
1095     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1096     ssid = "test-wps-fragmentation"
1097     appin = "12345670"
1098     hostapd.add_ap(apdev[0]['ifname'],
1099                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1100                      "wpa_passphrase": "12345678", "wpa": "3",
1101                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1102                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1103                      "fragment_size": "50" })
1104     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1105     logger.info("WPS provisioning step (PBC)")
1106     hapd.request("WPS_PBC")
1107     dev[0].dump_monitor()
1108     dev[0].request("SET wps_fragment_size 50")
1109     dev[0].request("WPS_PBC")
1110     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
1111     if ev is None:
1112         raise Exception("Association with the AP timed out")
1113     status = dev[0].get_status()
1114     if status['wpa_state'] != 'COMPLETED':
1115         raise Exception("Not fully connected")
1116     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1117         raise Exception("Unexpected encryption configuration")
1118     if status['key_mgmt'] != 'WPA2-PSK':
1119         raise Exception("Unexpected key_mgmt")
1120
1121     logger.info("WPS provisioning step (PIN)")
1122     pin = dev[1].wps_read_pin()
1123     hapd.request("WPS_PIN any " + pin)
1124     dev[1].request("SET wps_fragment_size 50")
1125     dev[1].request("WPS_PIN any " + pin)
1126     ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
1127     if ev is None:
1128         raise Exception("Association with the AP timed out")
1129     status = dev[1].get_status()
1130     if status['wpa_state'] != 'COMPLETED':
1131         raise Exception("Not fully connected")
1132     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1133         raise Exception("Unexpected encryption configuration")
1134     if status['key_mgmt'] != 'WPA2-PSK':
1135         raise Exception("Unexpected key_mgmt")
1136
1137     logger.info("WPS connection as registrar")
1138     dev[2].request("SET wps_fragment_size 50")
1139     dev[2].wps_reg(apdev[0]['bssid'], appin)
1140     status = dev[2].get_status()
1141     if status['wpa_state'] != 'COMPLETED':
1142         raise Exception("Not fully connected")
1143     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1144         raise Exception("Unexpected encryption configuration")
1145     if status['key_mgmt'] != 'WPA2-PSK':
1146         raise Exception("Unexpected key_mgmt")
1147
1148 def test_ap_wps_new_version_sta(dev, apdev):
1149     """WPS compatibility with new version number on the station"""
1150     ssid = "test-wps-ver"
1151     hostapd.add_ap(apdev[0]['ifname'],
1152                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1153                      "wpa_passphrase": "12345678", "wpa": "2",
1154                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1155     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1156     logger.info("WPS provisioning step")
1157     hapd.request("WPS_PBC")
1158     dev[0].dump_monitor()
1159     dev[0].request("SET wps_version_number 0x43")
1160     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1161     dev[0].request("WPS_PBC")
1162     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
1163     if ev is None:
1164         raise Exception("Association with the AP timed out")
1165
1166 def test_ap_wps_new_version_ap(dev, apdev):
1167     """WPS compatibility with new version number on the AP"""
1168     ssid = "test-wps-ver"
1169     hostapd.add_ap(apdev[0]['ifname'],
1170                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1171                      "wpa_passphrase": "12345678", "wpa": "2",
1172                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1173     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1174     logger.info("WPS provisioning step")
1175     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1176         raise Exception("Failed to enable test functionality")
1177     hapd.request("WPS_PBC")
1178     dev[0].dump_monitor()
1179     dev[0].request("WPS_PBC")
1180     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
1181     hapd.request("SET wps_version_number 0x20")
1182     if ev is None:
1183         raise Exception("Association with the AP timed out")
1184
1185 def test_ap_wps_check_pin(dev, apdev):
1186     """Verify PIN checking through control interface"""
1187     hostapd.add_ap(apdev[0]['ifname'],
1188                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1189                      "wpa_passphrase": "12345678", "wpa": "2",
1190                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1191     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1192     for t in [ ("12345670", "12345670"),
1193                ("12345678", "FAIL-CHECKSUM"),
1194                ("12345", "FAIL"),
1195                ("123456789", "FAIL"),
1196                ("1234-5670", "12345670"),
1197                ("1234 5670", "12345670"),
1198                ("1-2.3:4 5670", "12345670") ]:
1199         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1200         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1201         if res != res2:
1202             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1203         if res != t[1]:
1204             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1205
1206     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1207         raise Exception("Unexpected WPS_CHECK_PIN success")
1208     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1209         raise Exception("Unexpected WPS_CHECK_PIN success")
1210
1211     for i in range(0, 10):
1212         pin = dev[0].request("WPS_PIN get")
1213         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1214         if pin != rpin:
1215             raise Exception("Random PIN validation failed for " + pin)
1216
1217 def test_ap_wps_wep_config(dev, apdev):
1218     """WPS 2.0 AP rejecting WEP configuration"""
1219     ssid = "test-wps-config"
1220     appin = "12345670"
1221     hostapd.add_ap(apdev[0]['ifname'],
1222                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1223                      "ap_pin": appin})
1224     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1225     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1226                    "hello", no_wait=True)
1227     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1228     if ev is None:
1229         raise Exception("WPS-FAIL timed out")
1230     if "reason=2" not in ev:
1231         raise Exception("Unexpected reason code in WPS-FAIL")
1232     status = hapd.request("WPS_GET_STATUS")
1233     if "Last WPS result: Failed" not in status:
1234         raise Exception("WPS failure result not shown correctly")
1235     if "Failure Reason: WEP Prohibited" not in status:
1236         raise Exception("Failure reason not reported correctly")
1237     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1238         raise Exception("Peer address not shown correctly")
1239
1240 def test_ap_wps_wep_enroll(dev, apdev):
1241     """WPS 2.0 STA rejecting WEP configuration"""
1242     ssid = "test-wps-wep"
1243     hostapd.add_ap(apdev[0]['ifname'],
1244                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1245                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1246     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1247     hapd.request("WPS_PBC")
1248     dev[0].request("WPS_PBC")
1249     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1250     if ev is None:
1251         raise Exception("WPS-FAIL event timed out")
1252     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1253         raise Exception("Unexpected WPS-FAIL event: " + ev)
1254
1255 def test_ap_wps_ie_fragmentation(dev, apdev):
1256     """WPS AP using fragmented WPS IE"""
1257     ssid = "test-wps-ie-fragmentation"
1258     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1259                "wpa_passphrase": "12345678", "wpa": "2",
1260                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1261                "device_name": "1234567890abcdef1234567890abcdef",
1262                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1263                "model_name": "1234567890abcdef1234567890abcdef",
1264                "model_number": "1234567890abcdef1234567890abcdef",
1265                "serial_number": "1234567890abcdef1234567890abcdef" }
1266     hostapd.add_ap(apdev[0]['ifname'], params)
1267     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1268     hapd.request("WPS_PBC")
1269     dev[0].request("WPS_PBC")
1270     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
1271     if ev is None:
1272         raise Exception("Association with the AP timed out")
1273     bss = dev[0].get_bss(apdev[0]['bssid'])
1274     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1275         logger.info("Device Name not received correctly")
1276         logger.info(bss)
1277         # This can fail if Probe Response frame is missed and Beacon frame was
1278         # used to fill in the BSS entry. This can happen, e.g., during heavy
1279         # load every now and then and is not really an error, so try to
1280         # workaround by runnign another scan.
1281         dev[0].scan(freq="2412", only_new=True)
1282         bss = dev[0].get_bss(apdev[0]['bssid'])
1283         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1284             logger.info(bss)
1285             raise Exception("Device Name not received correctly")
1286     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1287         raise Exception("Unexpected number of WPS IEs")
1288
1289 def get_psk(pskfile):
1290     psks = {}
1291     with open(pskfile, "r") as f:
1292         lines = f.read().splitlines()
1293         for l in lines:
1294             if l == "# WPA PSKs":
1295                 continue
1296             (addr,psk) = l.split(' ')
1297             psks[addr] = psk
1298     return psks
1299
1300 def test_ap_wps_per_station_psk(dev, apdev):
1301     """WPS PBC provisioning with per-station PSK"""
1302     addr0 = dev[0].p2p_dev_addr()
1303     addr1 = dev[1].p2p_dev_addr()
1304     addr2 = dev[2].p2p_dev_addr()
1305     ssid = "wps"
1306     appin = "12345670"
1307     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1308     try:
1309         os.remove(pskfile)
1310     except:
1311         pass
1312
1313     try:
1314         with open(pskfile, "w") as f:
1315             f.write("# WPA PSKs\n")
1316
1317         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1318                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1319                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1320                    "wpa_psk_file": pskfile }
1321         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1322
1323         logger.info("First enrollee")
1324         hapd.request("WPS_PBC")
1325         dev[0].request("WPS_PBC")
1326         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"])
1327         if ev is None:
1328             raise Exception("Association with the AP timed out (1)")
1329
1330         logger.info("Second enrollee")
1331         hapd.request("WPS_PBC")
1332         dev[1].request("WPS_PBC")
1333         ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"])
1334         if ev is None:
1335             raise Exception("Association with the AP timed out (2)")
1336
1337         logger.info("External registrar")
1338         dev[2].wps_reg(apdev[0]['bssid'], appin)
1339
1340         logger.info("Verifying PSK results")
1341         psks = get_psk(pskfile)
1342         if addr0 not in psks:
1343             raise Exception("No PSK recorded for sta0")
1344         if addr1 not in psks:
1345             raise Exception("No PSK recorded for sta1")
1346         if addr2 not in psks:
1347             raise Exception("No PSK recorded for sta2")
1348         if psks[addr0] == psks[addr1]:
1349             raise Exception("Same PSK recorded for sta0 and sta1")
1350         if psks[addr0] == psks[addr2]:
1351             raise Exception("Same PSK recorded for sta0 and sta2")
1352         if psks[addr1] == psks[addr2]:
1353             raise Exception("Same PSK recorded for sta1 and sta2")
1354
1355         dev[0].request("REMOVE_NETWORK all")
1356         logger.info("Second external registrar")
1357         dev[0].wps_reg(apdev[0]['bssid'], appin)
1358         psks2 = get_psk(pskfile)
1359         if addr0 not in psks2:
1360             raise Exception("No PSK recorded for sta0(reg)")
1361         if psks[addr0] == psks2[addr0]:
1362             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
1363     finally:
1364         os.remove(pskfile)
1365
1366 def test_ap_wps_per_station_psk_failure(dev, apdev):
1367     """WPS PBC provisioning with per-station PSK (file not writable)"""
1368     addr0 = dev[0].p2p_dev_addr()
1369     addr1 = dev[1].p2p_dev_addr()
1370     addr2 = dev[2].p2p_dev_addr()
1371     ssid = "wps"
1372     appin = "12345670"
1373     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1374     try:
1375         os.remove(pskfile)
1376     except:
1377         pass
1378
1379     try:
1380         with open(pskfile, "w") as f:
1381             f.write("# WPA PSKs\n")
1382
1383         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1384                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1385                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1386                    "wpa_psk_file": pskfile }
1387         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1388         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
1389             raise Exception("Failed to set wpa_psk_file")
1390
1391         logger.info("First enrollee")
1392         hapd.request("WPS_PBC")
1393         dev[0].request("WPS_PBC")
1394         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"])
1395         if ev is None:
1396             raise Exception("Association with the AP timed out (1)")
1397
1398         logger.info("Second enrollee")
1399         hapd.request("WPS_PBC")
1400         dev[1].request("WPS_PBC")
1401         ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"])
1402         if ev is None:
1403             raise Exception("Association with the AP timed out (2)")
1404
1405         logger.info("External registrar")
1406         dev[2].wps_reg(apdev[0]['bssid'], appin)
1407
1408         logger.info("Verifying PSK results")
1409         psks = get_psk(pskfile)
1410         if len(psks) > 0:
1411             raise Exception("PSK recorded unexpectedly")
1412     finally:
1413         os.remove(pskfile)
1414
1415 def test_ap_wps_pin_request_file(dev, apdev):
1416     """WPS PIN provisioning with configured AP"""
1417     ssid = "wps"
1418     pinfile = "/tmp/ap_wps_pin_request_file.log"
1419     if os.path.exists(pinfile):
1420         subprocess.call(['sudo', 'rm', pinfile])
1421     hostapd.add_ap(apdev[0]['ifname'],
1422                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1423                      "wps_pin_requests": pinfile,
1424                      "wpa_passphrase": "12345678", "wpa": "2",
1425                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
1426     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1427     uuid = dev[0].get_status_field("uuid")
1428     pin = dev[0].wps_read_pin()
1429     try:
1430         dev[0].request("WPS_PIN any " + pin)
1431         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
1432         if ev is None:
1433             raise Exception("PIN needed event not shown")
1434         if uuid not in ev:
1435             raise Exception("UUID mismatch")
1436         dev[0].request("WPS_CANCEL")
1437         success = False
1438         with open(pinfile, "r") as f:
1439             lines = f.readlines()
1440             for l in lines:
1441                 if uuid in l:
1442                     success = True
1443                     break
1444         if not success:
1445             raise Exception("PIN request entry not in the log file")
1446     finally:
1447         subprocess.call(['sudo', 'rm', pinfile])
1448
1449 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
1450     """WPS auto-setup with configuration file"""
1451     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
1452     ifname = apdev[0]['ifname']
1453     try:
1454         with open(conffile, "w") as f:
1455             f.write("driver=nl80211\n")
1456             f.write("hw_mode=g\n")
1457             f.write("channel=1\n")
1458             f.write("ieee80211n=1\n")
1459             f.write("interface=%s\n" % ifname)
1460             f.write("ctrl_interface=/var/run/hostapd\n")
1461             f.write("ssid=wps\n")
1462             f.write("eap_server=1\n")
1463             f.write("wps_state=1\n")
1464         hostapd.add_bss('phy3', ifname, conffile)
1465         hapd = hostapd.Hostapd(ifname)
1466         hapd.request("WPS_PBC")
1467         dev[0].request("WPS_PBC")
1468         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
1469         if ev is None:
1470             raise Exception("Association with the AP timed out")
1471         with open(conffile, "r") as f:
1472             lines = f.read().splitlines()
1473             vals = dict()
1474             for l in lines:
1475                 try:
1476                     [name,value] = l.split('=', 1)
1477                     vals[name] = value
1478                 except ValueError, e:
1479                     if "# WPS configuration" in l:
1480                         pass
1481                     else:
1482                         raise Exception("Unexpected configuration line: " + l)
1483         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
1484             raise Exception("Incorrect configuration: " + str(vals))
1485     finally:
1486         subprocess.call(['sudo', 'rm', conffile])
1487
1488 def test_ap_wps_pbc_timeout(dev, apdev, params):
1489     """wpa_supplicant PBC walk time [long]"""
1490     if not params['long']:
1491         logger.info("Skip test case with long duration due to --long not specified")
1492         return "skip"
1493     ssid = "test-wps"
1494     hostapd.add_ap(apdev[0]['ifname'],
1495                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
1496     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1497     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
1498     if "OK" not in dev[0].request("WPS_PBC"):
1499         raise Exception("WPS_PBC failed")
1500     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=150)
1501     if ev is None:
1502         raise Exception("WPS-TIMEOUT not reported")
1503
1504 def add_ssdp_ap(ifname, ap_uuid):
1505     ssid = "wps-ssdp"
1506     ap_pin = "12345670"
1507     hostapd.add_ap(ifname,
1508                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1509                      "wpa_passphrase": "12345678", "wpa": "2",
1510                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1511                      "device_name": "Wireless AP", "manufacturer": "Company",
1512                      "model_name": "WAP", "model_number": "123",
1513                      "serial_number": "12345", "device_type": "6-0050F204-1",
1514                      "os_version": "01020300",
1515                      "config_methods": "label push_button",
1516                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
1517                      "friendly_name": "WPS Access Point",
1518                      "manufacturer_url": "http://www.example.com/",
1519                      "model_description": "Wireless Access Point",
1520                      "model_url": "http://www.example.com/model/",
1521                      "upc": "123456789012" })
1522
1523 def ssdp_send(msg, no_recv=False):
1524     socket.setdefaulttimeout(1)
1525     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1526     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1527     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1528     sock.bind(("127.0.0.1", 0))
1529     sock.sendto(msg, ("239.255.255.250", 1900))
1530     if no_recv:
1531         return None
1532     return sock.recv(1000)
1533
1534 def ssdp_send_msearch(st):
1535     msg = '\r\n'.join([
1536             'M-SEARCH * HTTP/1.1',
1537             'HOST: 239.255.255.250:1900',
1538             'MX: 1',
1539             'MAN: "ssdp:discover"',
1540             'ST: ' + st,
1541             '', ''])
1542     return ssdp_send(msg)
1543
1544 def test_ap_wps_ssdp_msearch(dev, apdev):
1545     """WPS AP and SSDP M-SEARCH messages"""
1546     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1547     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1548
1549     msg = '\r\n'.join([
1550             'M-SEARCH * HTTP/1.1',
1551             'Host: 239.255.255.250:1900',
1552             'Mx: 1',
1553             'Man: "ssdp:discover"',
1554             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
1555             '', ''])
1556     ssdp_send(msg)
1557
1558     msg = '\r\n'.join([
1559             'M-SEARCH * HTTP/1.1',
1560             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
1561             'mx: \t1\t\t   ',
1562             'man: \t \t "ssdp:discover"   ',
1563             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
1564             '', ''])
1565     ssdp_send(msg)
1566
1567     ssdp_send_msearch("ssdp:all")
1568     ssdp_send_msearch("upnp:rootdevice")
1569     ssdp_send_msearch("uuid:" + ap_uuid)
1570     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
1571     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
1572
1573     msg = '\r\n'.join([
1574             'M-SEARCH * HTTP/1.1',
1575             'HOST:\t239.255.255.250:1900',
1576             'MAN: "ssdp:discover"',
1577             'MX: 130',
1578             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1579             '', ''])
1580     ssdp_send(msg, no_recv=True)
1581
1582 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
1583     """WPS AP and invalid SSDP M-SEARCH messages"""
1584     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1585     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1586
1587     socket.setdefaulttimeout(1)
1588     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1589     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1590     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1591     sock.bind(("127.0.0.1", 0))
1592
1593     logger.debug("Missing MX")
1594     msg = '\r\n'.join([
1595             'M-SEARCH * HTTP/1.1',
1596             'HOST: 239.255.255.250:1900',
1597             'MAN: "ssdp:discover"',
1598             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1599             '', ''])
1600     sock.sendto(msg, ("239.255.255.250", 1900))
1601
1602     logger.debug("Negative MX")
1603     msg = '\r\n'.join([
1604             'M-SEARCH * HTTP/1.1',
1605             'HOST: 239.255.255.250:1900',
1606             'MX: -1',
1607             'MAN: "ssdp:discover"',
1608             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1609             '', ''])
1610     sock.sendto(msg, ("239.255.255.250", 1900))
1611
1612     logger.debug("Invalid MX")
1613     msg = '\r\n'.join([
1614             'M-SEARCH * HTTP/1.1',
1615             'HOST: 239.255.255.250:1900',
1616             'MX; 1',
1617             'MAN: "ssdp:discover"',
1618             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1619             '', ''])
1620     sock.sendto(msg, ("239.255.255.250", 1900))
1621
1622     logger.debug("Missing MAN")
1623     msg = '\r\n'.join([
1624             'M-SEARCH * HTTP/1.1',
1625             'HOST: 239.255.255.250:1900',
1626             'MX: 1',
1627             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1628             '', ''])
1629     sock.sendto(msg, ("239.255.255.250", 1900))
1630
1631     logger.debug("Invalid MAN")
1632     msg = '\r\n'.join([
1633             'M-SEARCH * HTTP/1.1',
1634             'HOST: 239.255.255.250:1900',
1635             'MX: 1',
1636             'MAN: foo',
1637             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1638             '', ''])
1639     sock.sendto(msg, ("239.255.255.250", 1900))
1640     msg = '\r\n'.join([
1641             'M-SEARCH * HTTP/1.1',
1642             'HOST: 239.255.255.250:1900',
1643             'MX: 1',
1644             'MAN; "ssdp:discover"',
1645             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1646             '', ''])
1647     sock.sendto(msg, ("239.255.255.250", 1900))
1648
1649     logger.debug("Missing HOST")
1650     msg = '\r\n'.join([
1651             'M-SEARCH * HTTP/1.1',
1652             'MAN: "ssdp:discover"',
1653             'MX: 1',
1654             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1655             '', ''])
1656     sock.sendto(msg, ("239.255.255.250", 1900))
1657
1658     logger.debug("Missing ST")
1659     msg = '\r\n'.join([
1660             'M-SEARCH * HTTP/1.1',
1661             'HOST: 239.255.255.250:1900',
1662             'MAN: "ssdp:discover"',
1663             'MX: 1',
1664             '', ''])
1665     sock.sendto(msg, ("239.255.255.250", 1900))
1666
1667     logger.debug("Mismatching ST")
1668     msg = '\r\n'.join([
1669             'M-SEARCH * HTTP/1.1',
1670             'HOST: 239.255.255.250:1900',
1671             'MAN: "ssdp:discover"',
1672             'MX: 1',
1673             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
1674             '', ''])
1675     sock.sendto(msg, ("239.255.255.250", 1900))
1676     msg = '\r\n'.join([
1677             'M-SEARCH * HTTP/1.1',
1678             'HOST: 239.255.255.250:1900',
1679             'MAN: "ssdp:discover"',
1680             'MX: 1',
1681             'ST: foo:bar',
1682             '', ''])
1683     sock.sendto(msg, ("239.255.255.250", 1900))
1684     msg = '\r\n'.join([
1685             'M-SEARCH * HTTP/1.1',
1686             'HOST: 239.255.255.250:1900',
1687             'MAN: "ssdp:discover"',
1688             'MX: 1',
1689             'ST: foobar',
1690             '', ''])
1691     sock.sendto(msg, ("239.255.255.250", 1900))
1692
1693     logger.debug("Invalid ST")
1694     msg = '\r\n'.join([
1695             'M-SEARCH * HTTP/1.1',
1696             'HOST: 239.255.255.250:1900',
1697             'MAN: "ssdp:discover"',
1698             'MX: 1',
1699             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
1700             '', ''])
1701     sock.sendto(msg, ("239.255.255.250", 1900))
1702
1703     logger.debug("Invalid M-SEARCH")
1704     msg = '\r\n'.join([
1705             'M+SEARCH * HTTP/1.1',
1706             'HOST: 239.255.255.250:1900',
1707             'MAN: "ssdp:discover"',
1708             'MX: 1',
1709             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1710             '', ''])
1711     sock.sendto(msg, ("239.255.255.250", 1900))
1712     msg = '\r\n'.join([
1713             'M-SEARCH-* HTTP/1.1',
1714             'HOST: 239.255.255.250:1900',
1715             'MAN: "ssdp:discover"',
1716             'MX: 1',
1717             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1718             '', ''])
1719     sock.sendto(msg, ("239.255.255.250", 1900))
1720
1721     logger.debug("Invalid message format")
1722     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
1723     msg = '\r'.join([
1724             'M-SEARCH * HTTP/1.1',
1725             'HOST: 239.255.255.250:1900',
1726             'MAN: "ssdp:discover"',
1727             'MX: 1',
1728             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1729             '', ''])
1730     sock.sendto(msg, ("239.255.255.250", 1900))
1731
1732     try:
1733         r = sock.recv(1000)
1734         raise Exception("Unexpected M-SEARCH response: " + r)
1735     except socket.timeout:
1736         pass
1737
1738     logger.debug("Valid M-SEARCH")
1739     msg = '\r\n'.join([
1740             'M-SEARCH * HTTP/1.1',
1741             'HOST: 239.255.255.250:1900',
1742             'MAN: "ssdp:discover"',
1743             'MX: 1',
1744             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1745             '', ''])
1746     sock.sendto(msg, ("239.255.255.250", 1900))
1747
1748     try:
1749         r = sock.recv(1000)
1750         pass
1751     except socket.timeout:
1752         raise Exception("No SSDP response")
1753
1754 def test_ap_wps_ssdp_burst(dev, apdev):
1755     """WPS AP and SSDP burst"""
1756     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1757     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1758
1759     msg = '\r\n'.join([
1760             'M-SEARCH * HTTP/1.1',
1761             'HOST: 239.255.255.250:1900',
1762             'MAN: "ssdp:discover"',
1763             'MX: 1',
1764             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1765             '', ''])
1766     socket.setdefaulttimeout(1)
1767     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1768     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1769     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1770     sock.bind(("127.0.0.1", 0))
1771     for i in range(0, 25):
1772         sock.sendto(msg, ("239.255.255.250", 1900))
1773     resp = 0
1774     while True:
1775         try:
1776             r = sock.recv(1000)
1777             if not r.startswith("HTTP/1.1 200 OK\r\n"):
1778                 raise Exception("Unexpected message: " + r)
1779             resp += 1
1780         except socket.timeout:
1781             break
1782     if resp < 20:
1783         raise Exception("Too few SSDP responses")
1784
1785     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1786     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1787     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1788     sock.bind(("127.0.0.1", 0))
1789     for i in range(0, 25):
1790         sock.sendto(msg, ("239.255.255.250", 1900))
1791     while True:
1792         try:
1793             r = sock.recv(1000)
1794             if ap_uuid in r:
1795                 break
1796         except socket.timeout:
1797             raise Exception("No SSDP response")
1798
1799 def ssdp_get_location(uuid):
1800     res = ssdp_send_msearch("uuid:" + uuid)
1801     location = None
1802     for l in res.splitlines():
1803         if l.lower().startswith("location:"):
1804             location = l.split(':', 1)[1].strip()
1805             break
1806     if location is None:
1807         raise Exception("No UPnP location found")
1808     return location
1809
1810 def upnp_get_urls(location):
1811     conn = urllib.urlopen(location)
1812     tree = ET.parse(conn)
1813     root = tree.getroot()
1814     urn = '{urn:schemas-upnp-org:device-1-0}'
1815     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
1816     res = {}
1817     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
1818     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
1819     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
1820     return res
1821
1822 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
1823     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
1824     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
1825     ET.register_namespace('soapenv', soapns)
1826     ET.register_namespace('wfa', wpsns)
1827     attrib = {}
1828     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
1829     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
1830     body = ET.SubElement(root, "{%s}Body" % soapns)
1831     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
1832     tree = ET.ElementTree(root)
1833     soap = StringIO.StringIO()
1834     tree.write(soap, xml_declaration=True, encoding='utf-8')
1835
1836     headers = { "Content-type": 'text/xml; charset="utf-8"' }
1837     if include_soap_action:
1838         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
1839     elif soap_action_override:
1840         headers["SOAPAction"] = soap_action_override
1841     conn.request("POST", path, soap.getvalue(), headers)
1842     return conn.getresponse()
1843
1844 def test_ap_wps_upnp(dev, apdev):
1845     """WPS AP and UPnP operations"""
1846     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1847     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1848
1849     location = ssdp_get_location(ap_uuid)
1850     urls = upnp_get_urls(location)
1851
1852     conn = urllib.urlopen(urls['scpd_url'])
1853     scpd = conn.read()
1854
1855     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
1856     if conn.getcode() != 404:
1857         raise Exception("Unexpected HTTP response to GET unknown URL")
1858
1859     url = urlparse.urlparse(location)
1860     conn = httplib.HTTPConnection(url.netloc)
1861     #conn.set_debuglevel(1)
1862     headers = { "Content-type": 'text/xml; charset="utf-8"',
1863                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
1864     conn.request("POST", "hello", "\r\n\r\n", headers)
1865     resp = conn.getresponse()
1866     if resp.status != 404:
1867         raise Exception("Unexpected HTTP response: %s" % resp.status)
1868
1869     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
1870     resp = conn.getresponse()
1871     if resp.status != 501:
1872         raise Exception("Unexpected HTTP response: %s" % resp.status)
1873
1874     headers = { "Content-type": 'text/xml; charset="utf-8"',
1875                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
1876     ctrlurl = urlparse.urlparse(urls['control_url'])
1877     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
1878     resp = conn.getresponse()
1879     if resp.status != 401:
1880         raise Exception("Unexpected HTTP response: %s" % resp.status)
1881
1882     logger.debug("GetDeviceInfo without SOAPAction header")
1883     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
1884                             include_soap_action=False)
1885     if resp.status != 401:
1886         raise Exception("Unexpected HTTP response: %s" % resp.status)
1887
1888     logger.debug("GetDeviceInfo with invalid SOAPAction header")
1889     for act in [ "foo",
1890                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
1891                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
1892                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
1893         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
1894                                 include_soap_action=False,
1895                                 soap_action_override=act)
1896         if resp.status != 401:
1897             raise Exception("Unexpected HTTP response: %s" % resp.status)
1898
1899     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
1900     if resp.status != 200:
1901         raise Exception("Unexpected HTTP response: %s" % resp.status)
1902     dev = resp.read()
1903     if "NewDeviceInfo" not in dev:
1904         raise Exception("Unexpected GetDeviceInfo response")
1905
1906     logger.debug("PutMessage without required parameters")
1907     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
1908     if resp.status != 600:
1909         raise Exception("Unexpected HTTP response: %s" % resp.status)
1910
1911     logger.debug("PutWLANResponse without required parameters")
1912     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
1913     if resp.status != 600:
1914         raise Exception("Unexpected HTTP response: %s" % resp.status)
1915
1916     logger.debug("SetSelectedRegistrar from unregistered ER")
1917     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
1918     if resp.status != 501:
1919         raise Exception("Unexpected HTTP response: %s" % resp.status)
1920
1921     logger.debug("Unknown action")
1922     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
1923     if resp.status != 401:
1924         raise Exception("Unexpected HTTP response: %s" % resp.status)
1925
1926 def test_ap_wps_upnp_subscribe(dev, apdev):
1927     """WPS AP and UPnP event subscription"""
1928     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1929     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1930
1931     location = ssdp_get_location(ap_uuid)
1932     urls = upnp_get_urls(location)
1933     eventurl = urlparse.urlparse(urls['event_sub_url'])
1934
1935     url = urlparse.urlparse(location)
1936     conn = httplib.HTTPConnection(url.netloc)
1937     #conn.set_debuglevel(1)
1938     headers = { "callback": '<http://127.0.0.1:12345/event>',
1939                 "timeout": "Second-1234" }
1940     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
1941     resp = conn.getresponse()
1942     if resp.status != 412:
1943         raise Exception("Unexpected HTTP response: %s" % resp.status)
1944
1945     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1946     resp = conn.getresponse()
1947     if resp.status != 412:
1948         raise Exception("Unexpected HTTP response: %s" % resp.status)
1949
1950     headers = { "NT": "upnp:event",
1951                 "timeout": "Second-1234" }
1952     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1953     resp = conn.getresponse()
1954     if resp.status != 412:
1955         raise Exception("Unexpected HTTP response: %s" % resp.status)
1956
1957     headers = { "callback": '<http://127.0.0.1:12345/event>',
1958                 "NT": "upnp:foobar",
1959                 "timeout": "Second-1234" }
1960     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1961     resp = conn.getresponse()
1962     if resp.status != 400:
1963         raise Exception("Unexpected HTTP response: %s" % resp.status)
1964
1965     logger.debug("Valid subscription")
1966     headers = { "callback": '<http://127.0.0.1:12345/event>',
1967                 "NT": "upnp:event",
1968                 "timeout": "Second-1234" }
1969     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1970     resp = conn.getresponse()
1971     if resp.status != 200:
1972         raise Exception("Unexpected HTTP response: %s" % resp.status)
1973     sid = resp.getheader("sid")
1974     logger.debug("Subscription SID " + sid)
1975
1976     logger.debug("Invalid re-subscription")
1977     headers = { "NT": "upnp:event",
1978                 "sid": "123456734567854",
1979                 "timeout": "Second-1234" }
1980     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1981     resp = conn.getresponse()
1982     if resp.status != 400:
1983         raise Exception("Unexpected HTTP response: %s" % resp.status)
1984
1985     logger.debug("Invalid re-subscription")
1986     headers = { "NT": "upnp:event",
1987                 "sid": "uuid:123456734567854",
1988                 "timeout": "Second-1234" }
1989     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1990     resp = conn.getresponse()
1991     if resp.status != 400:
1992         raise Exception("Unexpected HTTP response: %s" % resp.status)
1993
1994     logger.debug("Invalid re-subscription")
1995     headers = { "callback": '<http://127.0.0.1:12345/event>',
1996                 "NT": "upnp:event",
1997                 "sid": sid,
1998                 "timeout": "Second-1234" }
1999     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2000     resp = conn.getresponse()
2001     if resp.status != 400:
2002         raise Exception("Unexpected HTTP response: %s" % resp.status)
2003
2004     logger.debug("SID mismatch in re-subscription")
2005     headers = { "NT": "upnp:event",
2006                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2007                 "timeout": "Second-1234" }
2008     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2009     resp = conn.getresponse()
2010     if resp.status != 412:
2011         raise Exception("Unexpected HTTP response: %s" % resp.status)
2012
2013     logger.debug("Valid re-subscription")
2014     headers = { "NT": "upnp:event",
2015                 "sid": sid,
2016                 "timeout": "Second-1234" }
2017     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2018     resp = conn.getresponse()
2019     if resp.status != 200:
2020         raise Exception("Unexpected HTTP response: %s" % resp.status)
2021     sid2 = resp.getheader("sid")
2022     logger.debug("Subscription SID " + sid2)
2023
2024     if sid != sid2:
2025         raise Exception("Unexpected SID change")
2026
2027     logger.debug("Valid re-subscription")
2028     headers = { "NT": "upnp:event",
2029                 "sid": "uuid: \t \t" + sid.split(':')[1],
2030                 "timeout": "Second-1234" }
2031     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2032     resp = conn.getresponse()
2033     if resp.status != 200:
2034         raise Exception("Unexpected HTTP response: %s" % resp.status)
2035
2036     logger.debug("Invalid unsubscription")
2037     headers = { "sid": sid }
2038     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2039     resp = conn.getresponse()
2040     if resp.status != 412:
2041         raise Exception("Unexpected HTTP response: %s" % resp.status)
2042     headers = { "foo": "bar" }
2043     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2044     resp = conn.getresponse()
2045     if resp.status != 412:
2046         raise Exception("Unexpected HTTP response: %s" % resp.status)
2047
2048     logger.debug("Valid unsubscription")
2049     headers = { "sid": sid }
2050     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2051     resp = conn.getresponse()
2052     if resp.status != 200:
2053         raise Exception("Unexpected HTTP response: %s" % resp.status)
2054
2055     logger.debug("Unsubscription for not existing SID")
2056     headers = { "sid": sid }
2057     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2058     resp = conn.getresponse()
2059     if resp.status != 412:
2060         raise Exception("Unexpected HTTP response: %s" % resp.status)
2061
2062     logger.debug("Invalid unsubscription")
2063     headers = { "sid": " \t \tfoo" }
2064     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2065     resp = conn.getresponse()
2066     if resp.status != 400:
2067         raise Exception("Unexpected HTTP response: %s" % resp.status)
2068
2069     logger.debug("Invalid unsubscription")
2070     headers = { "sid": "uuid:\t \tfoo" }
2071     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2072     resp = conn.getresponse()
2073     if resp.status != 400:
2074         raise Exception("Unexpected HTTP response: %s" % resp.status)
2075
2076     logger.debug("Invalid unsubscription")
2077     headers = { "NT": "upnp:event",
2078                 "sid": sid }
2079     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2080     resp = conn.getresponse()
2081     if resp.status != 400:
2082         raise Exception("Unexpected HTTP response: %s" % resp.status)
2083     headers = { "callback": '<http://127.0.0.1:12345/event>',
2084                 "sid": sid }
2085     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2086     resp = conn.getresponse()
2087     if resp.status != 400:
2088         raise Exception("Unexpected HTTP response: %s" % resp.status)
2089
2090     logger.debug("Valid subscription with multiple callbacks")
2091     headers = { "callback": '<http://127.0.0.1:12345/event> <http://127.0.0.1:12345/event>\t<http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event>',
2092                 "NT": "upnp:event",
2093                 "timeout": "Second-1234" }
2094     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2095     resp = conn.getresponse()
2096     if resp.status != 200:
2097         raise Exception("Unexpected HTTP response: %s" % resp.status)
2098     sid = resp.getheader("sid")
2099     logger.debug("Subscription SID " + sid)
2100
2101 def test_ap_wps_disabled(dev, apdev):
2102     """WPS operations while WPS is disabled"""
2103     ssid = "test-wps-disabled"
2104     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
2105     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2106     if "FAIL" not in hapd.request("WPS_PBC"):
2107         raise Exception("WPS_PBC succeeded unexpectedly")
2108     if "FAIL" not in hapd.request("WPS_CANCEL"):
2109         raise Exception("WPS_CANCEL succeeded unexpectedly")
2110
2111 def test_ap_wps_mixed_cred(dev, apdev):
2112     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
2113     ssid = "test-wps-wep"
2114     hostapd.add_ap(apdev[0]['ifname'],
2115                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2116                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
2117     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2118     hapd.request("WPS_PBC")
2119     dev[0].request("WPS_PBC")
2120     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
2121     if ev is None:
2122         raise Exception("WPS-SUCCESS event timed out")
2123     nets = dev[0].list_networks()
2124     if len(nets) != 1:
2125         raise Exception("Unexpected number of network blocks")
2126     id = nets[0]['id']
2127     proto = dev[0].get_network(id, "proto")
2128     if proto != "WPA RSN":
2129         raise Exception("Unexpected merged proto field value: " + proto)
2130     pairwise = dev[0].get_network(id, "pairwise")
2131     if pairwise != "CCMP TKIP":
2132         raise Exception("Unexpected merged pairwise field value: " + pairwise)
2133
2134 def test_ap_wps_while_connected(dev, apdev):
2135     """WPS PBC provisioning while connected to another AP"""
2136     ssid = "test-wps-conf"
2137     hostapd.add_ap(apdev[0]['ifname'],
2138                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2139                      "wpa_passphrase": "12345678", "wpa": "2",
2140                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2141     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2142
2143     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2144     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2145
2146     logger.info("WPS provisioning step")
2147     hapd.request("WPS_PBC")
2148     dev[0].dump_monitor()
2149     dev[0].request("WPS_PBC")
2150     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
2151     if ev is None:
2152         raise Exception("Association with the AP timed out")
2153     status = dev[0].get_status()
2154     if status['bssid'] != apdev[0]['bssid']:
2155         raise Exception("Unexpected BSSID")
2156
2157 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
2158     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
2159     ssid = "test-wps-conf"
2160     hostapd.add_ap(apdev[0]['ifname'],
2161                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2162                      "wpa_passphrase": "12345678", "wpa": "2",
2163                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2164     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2165
2166     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2167
2168     try:
2169         dev[0].request("STA_AUTOCONNECT 0")
2170         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2171
2172         logger.info("WPS provisioning step")
2173         hapd.request("WPS_PBC")
2174         dev[0].dump_monitor()
2175         dev[0].request("WPS_PBC")
2176         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
2177         if ev is None:
2178             raise Exception("Association with the AP timed out")
2179         status = dev[0].get_status()
2180         if status['bssid'] != apdev[0]['bssid']:
2181             raise Exception("Unexpected BSSID")
2182     finally:
2183         dev[0].request("STA_AUTOCONNECT 1")
2184
2185 def test_ap_wps_from_event(dev, apdev):
2186     """WPS PBC event on AP to enable PBC"""
2187     ssid = "test-wps-conf"
2188     hapd = hostapd.add_ap(apdev[0]['ifname'],
2189                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2190                             "wpa_passphrase": "12345678", "wpa": "2",
2191                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2192     dev[0].dump_monitor()
2193     dev[0].request("WPS_PBC")
2194
2195     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
2196     if ev is None:
2197         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
2198     vals = ev.split(' ')
2199     if vals[1] != dev[0].p2p_interface_addr():
2200         raise Exception("Unexpected enrollee address: " + vals[1])
2201     if vals[5] != '4':
2202         raise Exception("Unexpected Device Password Id: " + vals[5])
2203     hapd.request("WPS_PBC")
2204     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=30)
2205     if ev is None:
2206         raise Exception("Association with the AP timed out")