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