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