EAP-WSC peer: Reject connection on unexpected failure
[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 base64
8 import os
9 import time
10 import stat
11 import subprocess
12 import logging
13 logger = logging.getLogger()
14 import re
15 import socket
16 import httplib
17 import urlparse
18 import urllib
19 import xml.etree.ElementTree as ET
20 import StringIO
21 import SocketServer
22
23 import hwsim_utils
24 import hostapd
25 from wpasupplicant import WpaSupplicant
26 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
27
28 def test_ap_wps_init(dev, apdev):
29     """Initial AP configuration with first WPS Enrollee"""
30     ssid = "test-wps"
31     hostapd.add_ap(apdev[0]['ifname'],
32                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
33     hapd = hostapd.Hostapd(apdev[0]['ifname'])
34     logger.info("WPS provisioning step")
35     hapd.request("WPS_PBC")
36     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
37         raise Exception("PBC status not shown correctly")
38
39     id = dev[0].add_network()
40     dev[0].set_network_quoted(id, "ssid", "home")
41     dev[0].set_network_quoted(id, "psk", "12345678")
42     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
43
44     id = dev[0].add_network()
45     dev[0].set_network_quoted(id, "ssid", "home2")
46     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
47     dev[0].set_network(id, "key_mgmt", "NONE")
48     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
49
50     dev[0].request("WPS_PBC")
51     dev[0].wait_connected(timeout=30)
52     status = dev[0].get_status()
53     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
54         raise Exception("Not fully connected")
55     if status['ssid'] != ssid:
56         raise Exception("Unexpected SSID")
57     if status['pairwise_cipher'] != 'CCMP':
58         raise Exception("Unexpected encryption configuration")
59     if status['key_mgmt'] != 'WPA2-PSK':
60         raise Exception("Unexpected key_mgmt")
61
62     status = hapd.request("WPS_GET_STATUS")
63     if "PBC Status: Disabled" not in status:
64         raise Exception("PBC status not shown correctly")
65     if "Last WPS result: Success" not in status:
66         raise Exception("Last WPS result not shown correctly")
67     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
68         raise Exception("Peer address not shown correctly")
69     conf = hapd.request("GET_CONFIG")
70     if "wps_state=configured" not in conf:
71         raise Exception("AP not in WPS configured state")
72     if "wpa=3" not in conf:
73         raise Exception("AP not in WPA+WPA2 configuration")
74     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
75         raise Exception("Unexpected rsn_pairwise_cipher")
76     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
77         raise Exception("Unexpected wpa_pairwise_cipher")
78     if "group_cipher=TKIP" not in conf:
79         raise Exception("Unexpected group_cipher")
80
81     if len(dev[0].list_networks()) != 3:
82         raise Exception("Unexpected number of network blocks")
83
84 def test_ap_wps_init_2ap_pbc(dev, apdev):
85     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
86     ssid = "test-wps"
87     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
88     hostapd.add_ap(apdev[0]['ifname'], params)
89     hostapd.add_ap(apdev[1]['ifname'], params)
90     hapd = hostapd.Hostapd(apdev[0]['ifname'])
91     logger.info("WPS provisioning step")
92     hapd.request("WPS_PBC")
93     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
94     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
95     bss = dev[0].get_bss(apdev[0]['bssid'])
96     if "[WPS-PBC]" not in bss['flags']:
97         raise Exception("WPS-PBC flag missing from AP1")
98     bss = dev[0].get_bss(apdev[1]['bssid'])
99     if "[WPS-PBC]" not in bss['flags']:
100         raise Exception("WPS-PBC flag missing from AP2")
101     dev[0].dump_monitor()
102     dev[0].request("SET wps_cred_processing 2")
103     dev[0].request("WPS_PBC")
104     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
105     dev[0].request("SET wps_cred_processing 0")
106     if ev is None:
107         raise Exception("WPS cred event not seen")
108     if "100e" not in ev:
109         raise Exception("WPS attributes not included in the cred event")
110     dev[0].wait_connected(timeout=30)
111
112     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
113     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
114     bss = dev[1].get_bss(apdev[0]['bssid'])
115     if "[WPS-PBC]" in bss['flags']:
116         raise Exception("WPS-PBC flag not cleared from AP1")
117     bss = dev[1].get_bss(apdev[1]['bssid'])
118     if "[WPS-PBC]" in bss['flags']:
119         raise Exception("WPS-PBC flag not cleared from AP2")
120
121 def test_ap_wps_init_2ap_pin(dev, apdev):
122     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
123     ssid = "test-wps"
124     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
125     hostapd.add_ap(apdev[0]['ifname'], params)
126     hostapd.add_ap(apdev[1]['ifname'], params)
127     hapd = hostapd.Hostapd(apdev[0]['ifname'])
128     logger.info("WPS provisioning step")
129     pin = dev[0].wps_read_pin()
130     hapd.request("WPS_PIN any " + pin)
131     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
132     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
133     bss = dev[0].get_bss(apdev[0]['bssid'])
134     if "[WPS-AUTH]" not in bss['flags']:
135         raise Exception("WPS-AUTH flag missing from AP1")
136     bss = dev[0].get_bss(apdev[1]['bssid'])
137     if "[WPS-AUTH]" not in bss['flags']:
138         raise Exception("WPS-AUTH flag missing from AP2")
139     dev[0].dump_monitor()
140     dev[0].request("WPS_PIN any " + pin)
141     dev[0].wait_connected(timeout=30)
142
143     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
144     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
145     bss = dev[1].get_bss(apdev[0]['bssid'])
146     if "[WPS-AUTH]" in bss['flags']:
147         raise Exception("WPS-AUTH flag not cleared from AP1")
148     bss = dev[1].get_bss(apdev[1]['bssid'])
149     if "[WPS-AUTH]" in bss['flags']:
150         raise Exception("WPS-AUTH flag not cleared from AP2")
151
152 def test_ap_wps_init_through_wps_config(dev, apdev):
153     """Initial AP configuration using wps_config command"""
154     ssid = "test-wps-init-config"
155     hostapd.add_ap(apdev[0]['ifname'],
156                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
157     hapd = hostapd.Hostapd(apdev[0]['ifname'])
158     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
159         raise Exception("WPS_CONFIG command failed")
160     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
161     if ev is None:
162         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
163     # It takes some time for the AP to update Beacon and Probe Response frames,
164     # so wait here before requesting the scan to be started to avoid adding
165     # extra five second wait to the test due to fetching obsolete scan results.
166     hapd.ping()
167     time.sleep(0.2)
168     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
169                    pairwise="CCMP", group="CCMP")
170
171 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
172     """AP configuration using wps_config command with invalid passphrase"""
173     ssid = "test-wps-init-config"
174     hostapd.add_ap(apdev[0]['ifname'],
175                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
176     hapd = hostapd.Hostapd(apdev[0]['ifname'])
177     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
178         raise Exception("Invalid WPS_CONFIG command accepted")
179
180 def test_ap_wps_conf(dev, apdev):
181     """WPS PBC provisioning with configured AP"""
182     ssid = "test-wps-conf"
183     hostapd.add_ap(apdev[0]['ifname'],
184                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
185                      "wpa_passphrase": "12345678", "wpa": "2",
186                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
187     hapd = hostapd.Hostapd(apdev[0]['ifname'])
188     logger.info("WPS provisioning step")
189     hapd.request("WPS_PBC")
190     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
191     dev[0].dump_monitor()
192     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
193     dev[0].wait_connected(timeout=30)
194     status = dev[0].get_status()
195     if status['wpa_state'] != 'COMPLETED':
196         raise Exception("Not fully connected")
197     if status['bssid'] != apdev[0]['bssid']:
198         raise Exception("Unexpected BSSID")
199     if status['ssid'] != ssid:
200         raise Exception("Unexpected SSID")
201     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
202         raise Exception("Unexpected encryption configuration")
203     if status['key_mgmt'] != 'WPA2-PSK':
204         raise Exception("Unexpected key_mgmt")
205
206     sta = hapd.get_sta(dev[0].p2p_interface_addr())
207     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
208         raise Exception("Device name not available in STA command")
209
210 def test_ap_wps_conf_5ghz(dev, apdev):
211     """WPS PBC provisioning with configured AP on 5 GHz band"""
212     try:
213         hapd = None
214         ssid = "test-wps-conf"
215         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
216                    "wpa_passphrase": "12345678", "wpa": "2",
217                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
218                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
219         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
220         logger.info("WPS provisioning step")
221         hapd.request("WPS_PBC")
222         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
223         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
224         dev[0].wait_connected(timeout=30)
225
226         sta = hapd.get_sta(dev[0].p2p_interface_addr())
227         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
228             raise Exception("Device name not available in STA command")
229     finally:
230         dev[0].request("DISCONNECT")
231         if hapd:
232             hapd.request("DISABLE")
233         subprocess.call(['iw', 'reg', 'set', '00'])
234         dev[0].flush_scan_cache()
235
236 def test_ap_wps_conf_chan14(dev, apdev):
237     """WPS PBC provisioning with configured AP on channel 14"""
238     try:
239         hapd = None
240         ssid = "test-wps-conf"
241         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
242                    "wpa_passphrase": "12345678", "wpa": "2",
243                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
244                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
245         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
246         logger.info("WPS provisioning step")
247         hapd.request("WPS_PBC")
248         dev[0].request("WPS_PBC")
249         dev[0].wait_connected(timeout=30)
250
251         sta = hapd.get_sta(dev[0].p2p_interface_addr())
252         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
253             raise Exception("Device name not available in STA command")
254     finally:
255         dev[0].request("DISCONNECT")
256         if hapd:
257             hapd.request("DISABLE")
258         subprocess.call(['iw', 'reg', 'set', '00'])
259         dev[0].flush_scan_cache()
260
261 def test_ap_wps_twice(dev, apdev):
262     """WPS provisioning with twice to change passphrase"""
263     ssid = "test-wps-twice"
264     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
265                "wpa_passphrase": "12345678", "wpa": "2",
266                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
267     hostapd.add_ap(apdev[0]['ifname'], params)
268     hapd = hostapd.Hostapd(apdev[0]['ifname'])
269     logger.info("WPS provisioning step")
270     hapd.request("WPS_PBC")
271     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
272     dev[0].dump_monitor()
273     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
274     dev[0].wait_connected(timeout=30)
275     dev[0].request("DISCONNECT")
276
277     logger.info("Restart AP with different passphrase and re-run WPS")
278     hapd_global = hostapd.HostapdGlobal()
279     hapd_global.remove(apdev[0]['ifname'])
280     params['wpa_passphrase'] = 'another passphrase'
281     hostapd.add_ap(apdev[0]['ifname'], params)
282     hapd = hostapd.Hostapd(apdev[0]['ifname'])
283     logger.info("WPS provisioning step")
284     hapd.request("WPS_PBC")
285     dev[0].dump_monitor()
286     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
287     dev[0].wait_connected(timeout=30)
288     networks = dev[0].list_networks()
289     if len(networks) > 1:
290         raise Exception("Unexpected duplicated network block present")
291
292 def test_ap_wps_incorrect_pin(dev, apdev):
293     """WPS PIN provisioning with incorrect PIN"""
294     ssid = "test-wps-incorrect-pin"
295     hostapd.add_ap(apdev[0]['ifname'],
296                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
297                      "wpa_passphrase": "12345678", "wpa": "2",
298                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
299     hapd = hostapd.Hostapd(apdev[0]['ifname'])
300
301     logger.info("WPS provisioning attempt 1")
302     hapd.request("WPS_PIN any 12345670")
303     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
304     dev[0].dump_monitor()
305     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
306     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
307     if ev is None:
308         raise Exception("WPS operation timed out")
309     if "config_error=18" not in ev:
310         raise Exception("Incorrect config_error reported")
311     if "msg=8" not in ev:
312         raise Exception("PIN error detected on incorrect message")
313     dev[0].wait_disconnected(timeout=10)
314     dev[0].request("WPS_CANCEL")
315     # if a scan was in progress, wait for it to complete before trying WPS again
316     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
317
318     status = hapd.request("WPS_GET_STATUS")
319     if "Last WPS result: Failed" not in status:
320         raise Exception("WPS failure result not shown correctly")
321
322     logger.info("WPS provisioning attempt 2")
323     hapd.request("WPS_PIN any 12345670")
324     dev[0].dump_monitor()
325     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
326     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
327     if ev is None:
328         raise Exception("WPS operation timed out")
329     if "config_error=18" not in ev:
330         raise Exception("Incorrect config_error reported")
331     if "msg=10" not in ev:
332         raise Exception("PIN error detected on incorrect message")
333     dev[0].wait_disconnected(timeout=10)
334
335 def test_ap_wps_conf_pin(dev, apdev):
336     """WPS PIN provisioning with configured AP"""
337     ssid = "test-wps-conf-pin"
338     hostapd.add_ap(apdev[0]['ifname'],
339                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
340                      "wpa_passphrase": "12345678", "wpa": "2",
341                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
342     hapd = hostapd.Hostapd(apdev[0]['ifname'])
343     logger.info("WPS provisioning step")
344     pin = dev[0].wps_read_pin()
345     hapd.request("WPS_PIN any " + pin)
346     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
347     dev[0].dump_monitor()
348     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
349     dev[0].wait_connected(timeout=30)
350     status = dev[0].get_status()
351     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
352         raise Exception("Not fully connected")
353     if status['ssid'] != ssid:
354         raise Exception("Unexpected SSID")
355     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
356         raise Exception("Unexpected encryption configuration")
357     if status['key_mgmt'] != 'WPA2-PSK':
358         raise Exception("Unexpected key_mgmt")
359
360     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
361     bss = dev[1].get_bss(apdev[0]['bssid'])
362     if "[WPS-AUTH]" in bss['flags']:
363         raise Exception("WPS-AUTH flag not cleared")
364     logger.info("Try to connect from another station using the same PIN")
365     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
366     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
367     if ev is None:
368         raise Exception("Operation timed out")
369     if "WPS-M2D" not in ev:
370         raise Exception("Unexpected WPS operation started")
371     hapd.request("WPS_PIN any " + pin)
372     dev[1].wait_connected(timeout=30)
373
374 def test_ap_wps_conf_pin_v1(dev, apdev):
375     """WPS PIN provisioning with configured WPS v1.0 AP"""
376     ssid = "test-wps-conf-pin-v1"
377     hostapd.add_ap(apdev[0]['ifname'],
378                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
379                      "wpa_passphrase": "12345678", "wpa": "2",
380                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
381     hapd = hostapd.Hostapd(apdev[0]['ifname'])
382     logger.info("WPS provisioning step")
383     pin = dev[0].wps_read_pin()
384     hapd.request("SET wps_version_number 0x10")
385     hapd.request("WPS_PIN any " + pin)
386     found = False
387     for i in range(0, 10):
388         dev[0].scan(freq="2412")
389         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
390             found = True
391             break
392     if not found:
393         hapd.request("SET wps_version_number 0x20")
394         raise Exception("WPS-PIN flag not seen in scan results")
395     dev[0].dump_monitor()
396     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
397     dev[0].wait_connected(timeout=30)
398     hapd.request("SET wps_version_number 0x20")
399
400 def test_ap_wps_conf_pin_2sta(dev, apdev):
401     """Two stations trying to use WPS PIN at the same time"""
402     ssid = "test-wps-conf-pin2"
403     hostapd.add_ap(apdev[0]['ifname'],
404                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
405                      "wpa_passphrase": "12345678", "wpa": "2",
406                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
407     hapd = hostapd.Hostapd(apdev[0]['ifname'])
408     logger.info("WPS provisioning step")
409     pin = "12345670"
410     pin2 = "55554444"
411     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
412     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
413     dev[0].dump_monitor()
414     dev[1].dump_monitor()
415     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
416     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
417     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
418     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
419     dev[0].wait_connected(timeout=30)
420     dev[1].wait_connected(timeout=30)
421
422 def test_ap_wps_conf_pin_timeout(dev, apdev):
423     """WPS PIN provisioning with configured AP timing out PIN"""
424     ssid = "test-wps-conf-pin"
425     hostapd.add_ap(apdev[0]['ifname'],
426                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
427                      "wpa_passphrase": "12345678", "wpa": "2",
428                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
429     hapd = hostapd.Hostapd(apdev[0]['ifname'])
430     addr = dev[0].p2p_interface_addr()
431     pin = dev[0].wps_read_pin()
432     if "FAIL" not in hapd.request("WPS_PIN "):
433         raise Exception("Unexpected success on invalid WPS_PIN")
434     hapd.request("WPS_PIN any " + pin + " 1")
435     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
436     time.sleep(1.1)
437     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
438     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
439     if ev is None:
440         raise Exception("WPS-PIN-NEEDED event timed out")
441     ev = dev[0].wait_event(["WPS-M2D"])
442     if ev is None:
443         raise Exception("M2D not reported")
444     dev[0].request("WPS_CANCEL")
445
446     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
447     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
448     dev[0].wait_connected(timeout=30)
449
450 def test_ap_wps_reg_connect(dev, apdev):
451     """WPS registrar using AP PIN to connect"""
452     ssid = "test-wps-reg-ap-pin"
453     appin = "12345670"
454     hostapd.add_ap(apdev[0]['ifname'],
455                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
456                      "wpa_passphrase": "12345678", "wpa": "2",
457                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
458                      "ap_pin": appin})
459     logger.info("WPS provisioning step")
460     dev[0].dump_monitor()
461     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
462     dev[0].wps_reg(apdev[0]['bssid'], appin)
463     status = dev[0].get_status()
464     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
465         raise Exception("Not fully connected")
466     if status['ssid'] != ssid:
467         raise Exception("Unexpected SSID")
468     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
469         raise Exception("Unexpected encryption configuration")
470     if status['key_mgmt'] != 'WPA2-PSK':
471         raise Exception("Unexpected key_mgmt")
472
473 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
474     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
475     ssid = "test-wps-reg-ap-pin"
476     appin = "12345670"
477     hostapd.add_ap(apdev[0]['ifname'],
478                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
479                      "wpa_passphrase": "12345678", "wpa": "3",
480                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
481                      "wpa_pairwise": "TKIP", "ap_pin": appin})
482     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
483     dev[0].wps_reg(apdev[0]['bssid'], appin)
484     status = dev[0].get_status()
485     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
486         raise Exception("Not fully connected")
487     if status['ssid'] != ssid:
488         raise Exception("Unexpected SSID")
489     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
490         raise Exception("Unexpected encryption configuration")
491     if status['key_mgmt'] != 'WPA2-PSK':
492         raise Exception("Unexpected key_mgmt")
493
494 def check_wps_reg_failure(dev, ap, appin):
495     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
496     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
497     if ev is None:
498         raise Exception("WPS operation timed out")
499     if "WPS-SUCCESS" in ev:
500         raise Exception("WPS operation succeeded unexpectedly")
501     if "config_error=15" not in ev:
502         raise Exception("WPS setup locked state was not reported correctly")
503
504 def test_ap_wps_random_ap_pin(dev, apdev):
505     """WPS registrar using random AP PIN"""
506     ssid = "test-wps-reg-random-ap-pin"
507     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
508     hostapd.add_ap(apdev[0]['ifname'],
509                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
510                      "wpa_passphrase": "12345678", "wpa": "2",
511                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
512                      "device_name": "Wireless AP", "manufacturer": "Company",
513                      "model_name": "WAP", "model_number": "123",
514                      "serial_number": "12345", "device_type": "6-0050F204-1",
515                      "os_version": "01020300",
516                      "config_methods": "label push_button",
517                      "uuid": ap_uuid, "upnp_iface": "lo" })
518     hapd = hostapd.Hostapd(apdev[0]['ifname'])
519     appin = hapd.request("WPS_AP_PIN random")
520     if "FAIL" in appin:
521         raise Exception("Could not generate random AP PIN")
522     if appin not in hapd.request("WPS_AP_PIN get"):
523         raise Exception("Could not fetch current AP PIN")
524     logger.info("WPS provisioning step")
525     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
526     dev[0].wps_reg(apdev[0]['bssid'], appin)
527
528     hapd.request("WPS_AP_PIN disable")
529     logger.info("WPS provisioning step with AP PIN disabled")
530     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
531     check_wps_reg_failure(dev[1], apdev[0], appin)
532
533     logger.info("WPS provisioning step with AP PIN reset")
534     appin = "12345670"
535     hapd.request("WPS_AP_PIN set " + appin)
536     dev[1].wps_reg(apdev[0]['bssid'], appin)
537     dev[0].request("REMOVE_NETWORK all")
538     dev[1].request("REMOVE_NETWORK all")
539     dev[0].wait_disconnected(timeout=10)
540     dev[1].wait_disconnected(timeout=10)
541
542     logger.info("WPS provisioning step after AP PIN timeout")
543     hapd.request("WPS_AP_PIN disable")
544     appin = hapd.request("WPS_AP_PIN random 1")
545     time.sleep(1.1)
546     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
547         raise Exception("AP PIN unexpectedly still enabled")
548     check_wps_reg_failure(dev[0], apdev[0], appin)
549
550     logger.info("WPS provisioning step after AP PIN timeout(2)")
551     hapd.request("WPS_AP_PIN disable")
552     appin = "12345670"
553     hapd.request("WPS_AP_PIN set " + appin + " 1")
554     time.sleep(1.1)
555     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
556         raise Exception("AP PIN unexpectedly still enabled")
557     check_wps_reg_failure(dev[1], apdev[0], appin)
558
559 def test_ap_wps_reg_config(dev, apdev):
560     """WPS registrar configuring an AP using AP PIN"""
561     ssid = "test-wps-init-ap-pin"
562     appin = "12345670"
563     hostapd.add_ap(apdev[0]['ifname'],
564                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
565                      "ap_pin": appin})
566     logger.info("WPS configuration step")
567     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
568     dev[0].dump_monitor()
569     new_ssid = "wps-new-ssid"
570     new_passphrase = "1234567890"
571     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
572                    new_passphrase)
573     status = dev[0].get_status()
574     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
575         raise Exception("Not fully connected")
576     if status['ssid'] != new_ssid:
577         raise Exception("Unexpected SSID")
578     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
579         raise Exception("Unexpected encryption configuration")
580     if status['key_mgmt'] != 'WPA2-PSK':
581         raise Exception("Unexpected key_mgmt")
582
583     logger.info("Re-configure back to open")
584     dev[0].request("REMOVE_NETWORK all")
585     dev[0].flush_scan_cache()
586     dev[0].dump_monitor()
587     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
588     status = dev[0].get_status()
589     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
590         raise Exception("Not fully connected")
591     if status['ssid'] != "wps-open":
592         raise Exception("Unexpected SSID")
593     if status['key_mgmt'] != 'NONE':
594         raise Exception("Unexpected key_mgmt")
595
596 def test_ap_wps_reg_config_ext_processing(dev, apdev):
597     """WPS registrar configuring an AP with external config processing"""
598     ssid = "test-wps-init-ap-pin"
599     appin = "12345670"
600     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
601                "wps_cred_processing": "1", "ap_pin": appin}
602     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
603     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
604     new_ssid = "wps-new-ssid"
605     new_passphrase = "1234567890"
606     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
607                    new_passphrase, no_wait=True)
608     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
609     if ev is None:
610         raise Exception("WPS registrar operation timed out")
611     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
612     if ev is None:
613         raise Exception("WPS configuration timed out")
614     if "1026" not in ev:
615         raise Exception("AP Settings missing from event")
616     hapd.request("SET wps_cred_processing 0")
617     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
618         raise Exception("WPS_CONFIG command failed")
619     dev[0].wait_connected(timeout=15)
620
621 def test_ap_wps_reg_config_tkip(dev, apdev):
622     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
623     skip_with_fips(dev[0])
624     ssid = "test-wps-init-ap"
625     appin = "12345670"
626     hostapd.add_ap(apdev[0]['ifname'],
627                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
628                      "ap_pin": appin})
629     logger.info("WPS configuration step")
630     dev[0].request("SET wps_version_number 0x10")
631     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
632     dev[0].dump_monitor()
633     new_ssid = "wps-new-ssid-with-tkip"
634     new_passphrase = "1234567890"
635     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
636                    new_passphrase)
637     logger.info("Re-connect to verify WPA2 mixed mode")
638     dev[0].request("DISCONNECT")
639     id = 0
640     dev[0].set_network(id, "pairwise", "CCMP")
641     dev[0].set_network(id, "proto", "RSN")
642     dev[0].connect_network(id)
643     status = dev[0].get_status()
644     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
645         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
646     if status['ssid'] != new_ssid:
647         raise Exception("Unexpected SSID")
648     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
649         raise Exception("Unexpected encryption configuration")
650     if status['key_mgmt'] != 'WPA2-PSK':
651         raise Exception("Unexpected key_mgmt")
652
653 def test_ap_wps_setup_locked(dev, apdev):
654     """WPS registrar locking up AP setup on AP PIN failures"""
655     ssid = "test-wps-incorrect-ap-pin"
656     appin = "12345670"
657     hostapd.add_ap(apdev[0]['ifname'],
658                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
659                      "wpa_passphrase": "12345678", "wpa": "2",
660                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
661                      "ap_pin": appin})
662     new_ssid = "wps-new-ssid-test"
663     new_passphrase = "1234567890"
664
665     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
666     ap_setup_locked=False
667     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
668         dev[0].dump_monitor()
669         logger.info("Try incorrect AP PIN - attempt " + pin)
670         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
671                        "CCMP", new_passphrase, no_wait=True)
672         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
673         if ev is None:
674             raise Exception("Timeout on receiving WPS operation failure event")
675         if "CTRL-EVENT-CONNECTED" in ev:
676             raise Exception("Unexpected connection")
677         if "config_error=15" in ev:
678             logger.info("AP Setup Locked")
679             ap_setup_locked=True
680         elif "config_error=18" not in ev:
681             raise Exception("config_error=18 not reported")
682         dev[0].wait_disconnected(timeout=10)
683         time.sleep(0.1)
684     if not ap_setup_locked:
685         raise Exception("AP setup was not locked")
686
687     hapd = hostapd.Hostapd(apdev[0]['ifname'])
688     status = hapd.request("WPS_GET_STATUS")
689     if "Last WPS result: Failed" not in status:
690         raise Exception("WPS failure result not shown correctly")
691     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
692         raise Exception("Peer address not shown correctly")
693
694     time.sleep(0.5)
695     dev[0].dump_monitor()
696     logger.info("WPS provisioning step")
697     pin = dev[0].wps_read_pin()
698     hapd = hostapd.Hostapd(apdev[0]['ifname'])
699     hapd.request("WPS_PIN any " + pin)
700     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
701     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
702     if ev is None:
703         raise Exception("WPS success was not reported")
704     dev[0].wait_connected(timeout=30)
705
706     appin = hapd.request("WPS_AP_PIN random")
707     if "FAIL" in appin:
708         raise Exception("Could not generate random AP PIN")
709     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
710     if ev is None:
711         raise Exception("Failed to unlock AP PIN")
712
713 def test_ap_wps_setup_locked_timeout(dev, apdev):
714     """WPS re-enabling AP PIN after timeout"""
715     ssid = "test-wps-incorrect-ap-pin"
716     appin = "12345670"
717     hostapd.add_ap(apdev[0]['ifname'],
718                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
719                      "wpa_passphrase": "12345678", "wpa": "2",
720                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
721                      "ap_pin": appin})
722     new_ssid = "wps-new-ssid-test"
723     new_passphrase = "1234567890"
724
725     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
726     ap_setup_locked=False
727     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
728         dev[0].dump_monitor()
729         logger.info("Try incorrect AP PIN - attempt " + pin)
730         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
731                        "CCMP", new_passphrase, no_wait=True)
732         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
733         if ev is None:
734             raise Exception("Timeout on receiving WPS operation failure event")
735         if "CTRL-EVENT-CONNECTED" in ev:
736             raise Exception("Unexpected connection")
737         if "config_error=15" in ev:
738             logger.info("AP Setup Locked")
739             ap_setup_locked=True
740             break
741         elif "config_error=18" not in ev:
742             raise Exception("config_error=18 not reported")
743         dev[0].wait_disconnected(timeout=10)
744         time.sleep(0.1)
745     if not ap_setup_locked:
746         raise Exception("AP setup was not locked")
747     hapd = hostapd.Hostapd(apdev[0]['ifname'])
748     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
749     if ev is None:
750         raise Exception("AP PIN did not get unlocked on 60 second timeout")
751
752 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
753     """WPS PBC session overlap with two active APs"""
754     hostapd.add_ap(apdev[0]['ifname'],
755                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
756                      "wpa_passphrase": "12345678", "wpa": "2",
757                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
758                      "wps_independent": "1"})
759     hostapd.add_ap(apdev[1]['ifname'],
760                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
761                      "wpa_passphrase": "123456789", "wpa": "2",
762                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
763                      "wps_independent": "1"})
764     hapd = hostapd.Hostapd(apdev[0]['ifname'])
765     hapd.request("WPS_PBC")
766     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
767     hapd2.request("WPS_PBC")
768     logger.info("WPS provisioning step")
769     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
770     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
771     dev[0].request("WPS_PBC")
772     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
773     if ev is None:
774         raise Exception("PBC session overlap not detected")
775     hapd.request("DISABLE")
776     hapd2.request("DISABLE")
777     dev[0].flush_scan_cache()
778
779 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
780     """WPS PBC session overlap with two active STAs"""
781     ssid = "test-wps-pbc-overlap"
782     hostapd.add_ap(apdev[0]['ifname'],
783                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
784                      "wpa_passphrase": "12345678", "wpa": "2",
785                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
786     hapd = hostapd.Hostapd(apdev[0]['ifname'])
787     logger.info("WPS provisioning step")
788     hapd.request("WPS_PBC")
789     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
790     dev[0].dump_monitor()
791     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
792     dev[1].dump_monitor()
793     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
794     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
795     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
796     if ev is None:
797         raise Exception("PBC session overlap not detected (dev0)")
798     if "config_error=12" not in ev:
799         raise Exception("PBC session overlap not correctly reported (dev0)")
800     dev[0].request("WPS_CANCEL")
801     dev[0].request("DISCONNECT")
802     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
803     if ev is None:
804         raise Exception("PBC session overlap not detected (dev1)")
805     if "config_error=12" not in ev:
806         raise Exception("PBC session overlap not correctly reported (dev1)")
807     dev[1].request("WPS_CANCEL")
808     dev[1].request("DISCONNECT")
809     hapd.request("WPS_CANCEL")
810     ret = hapd.request("WPS_PBC")
811     if "FAIL" not in ret:
812         raise Exception("PBC mode allowed to be started while PBC overlap still active")
813     hapd.request("DISABLE")
814     dev[0].flush_scan_cache()
815     dev[1].flush_scan_cache()
816
817 def test_ap_wps_cancel(dev, apdev):
818     """WPS AP cancelling enabled config method"""
819     ssid = "test-wps-ap-cancel"
820     hostapd.add_ap(apdev[0]['ifname'],
821                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
822                      "wpa_passphrase": "12345678", "wpa": "2",
823                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
824     bssid = apdev[0]['bssid']
825     hapd = hostapd.Hostapd(apdev[0]['ifname'])
826
827     logger.info("Verify PBC enable/cancel")
828     hapd.request("WPS_PBC")
829     dev[0].scan(freq="2412")
830     dev[0].scan(freq="2412")
831     bss = dev[0].get_bss(apdev[0]['bssid'])
832     if "[WPS-PBC]" not in bss['flags']:
833         raise Exception("WPS-PBC flag missing")
834     if "FAIL" in hapd.request("WPS_CANCEL"):
835         raise Exception("WPS_CANCEL failed")
836     dev[0].scan(freq="2412")
837     dev[0].scan(freq="2412")
838     bss = dev[0].get_bss(apdev[0]['bssid'])
839     if "[WPS-PBC]" in bss['flags']:
840         raise Exception("WPS-PBC flag not cleared")
841
842     logger.info("Verify PIN enable/cancel")
843     hapd.request("WPS_PIN any 12345670")
844     dev[0].scan(freq="2412")
845     dev[0].scan(freq="2412")
846     bss = dev[0].get_bss(apdev[0]['bssid'])
847     if "[WPS-AUTH]" not in bss['flags']:
848         raise Exception("WPS-AUTH flag missing")
849     if "FAIL" in hapd.request("WPS_CANCEL"):
850         raise Exception("WPS_CANCEL failed")
851     dev[0].scan(freq="2412")
852     dev[0].scan(freq="2412")
853     bss = dev[0].get_bss(apdev[0]['bssid'])
854     if "[WPS-AUTH]" in bss['flags']:
855         raise Exception("WPS-AUTH flag not cleared")
856
857 def test_ap_wps_er_add_enrollee(dev, apdev):
858     """WPS ER configuring AP and adding a new enrollee using PIN"""
859     try:
860         _test_ap_wps_er_add_enrollee(dev, apdev)
861     finally:
862         dev[0].request("WPS_ER_STOP")
863
864 def _test_ap_wps_er_add_enrollee(dev, apdev):
865     ssid = "wps-er-add-enrollee"
866     ap_pin = "12345670"
867     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
868     hostapd.add_ap(apdev[0]['ifname'],
869                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
870                      "device_name": "Wireless AP", "manufacturer": "Company",
871                      "model_name": "WAP", "model_number": "123",
872                      "serial_number": "12345", "device_type": "6-0050F204-1",
873                      "os_version": "01020300",
874                      "config_methods": "label push_button",
875                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
876     logger.info("WPS configuration step")
877     new_passphrase = "1234567890"
878     dev[0].dump_monitor()
879     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
880     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
881                    new_passphrase)
882     status = dev[0].get_status()
883     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
884         raise Exception("Not fully connected")
885     if status['ssid'] != ssid:
886         raise Exception("Unexpected SSID")
887     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
888         raise Exception("Unexpected encryption configuration")
889     if status['key_mgmt'] != 'WPA2-PSK':
890         raise Exception("Unexpected key_mgmt")
891
892     logger.info("Start ER")
893     dev[0].request("WPS_ER_START ifname=lo")
894     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
895     if ev is None:
896         raise Exception("AP discovery timed out")
897     if ap_uuid not in ev:
898         raise Exception("Expected AP UUID not found")
899
900     logger.info("Learn AP configuration through UPnP")
901     dev[0].dump_monitor()
902     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
903     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
904     if ev is None:
905         raise Exception("AP learn timed out")
906     if ap_uuid not in ev:
907         raise Exception("Expected AP UUID not in settings")
908     if "ssid=" + ssid not in ev:
909         raise Exception("Expected SSID not in settings")
910     if "key=" + new_passphrase not in ev:
911         raise Exception("Expected passphrase not in settings")
912     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
913     if ev is None:
914         raise Exception("WPS-FAIL after AP learn timed out")
915     time.sleep(0.1)
916
917     logger.info("Add Enrollee using ER")
918     pin = dev[1].wps_read_pin()
919     dev[0].dump_monitor()
920     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
921     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
922     dev[1].dump_monitor()
923     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
924     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
925     if ev is None:
926         raise Exception("Enrollee did not report success")
927     dev[1].wait_connected(timeout=15)
928     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
929     if ev is None:
930         raise Exception("WPS ER did not report success")
931     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
932
933     logger.info("Add a specific Enrollee using ER")
934     pin = dev[2].wps_read_pin()
935     addr2 = dev[2].p2p_interface_addr()
936     dev[0].dump_monitor()
937     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
938     dev[2].dump_monitor()
939     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
940     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
941     if ev is None:
942         raise Exception("Enrollee not seen")
943     if addr2 not in ev:
944         raise Exception("Unexpected Enrollee MAC address")
945     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
946     dev[2].wait_connected(timeout=30)
947     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
948     if ev is None:
949         raise Exception("WPS ER did not report success")
950
951     logger.info("Verify registrar selection behavior")
952     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
953     dev[1].request("DISCONNECT")
954     dev[1].wait_disconnected(timeout=10)
955     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
956     dev[1].scan(freq="2412")
957     bss = dev[1].get_bss(apdev[0]['bssid'])
958     if "[WPS-AUTH]" not in bss['flags']:
959         # It is possible for scan to miss an update especially when running
960         # tests under load with multiple VMs, so allow another attempt.
961         dev[1].scan(freq="2412")
962         bss = dev[1].get_bss(apdev[0]['bssid'])
963         if "[WPS-AUTH]" not in bss['flags']:
964             raise Exception("WPS-AUTH flag missing")
965
966     logger.info("Stop ER")
967     dev[0].dump_monitor()
968     dev[0].request("WPS_ER_STOP")
969     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
970     if ev is None:
971         raise Exception("WPS ER unsubscription timed out")
972     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
973     # a bit before verifying that the scan results have changed.
974     time.sleep(0.2)
975
976     for i in range(0, 10):
977         dev[1].request("BSS_FLUSH 0")
978         dev[1].scan(freq="2412", only_new=True)
979         bss = dev[1].get_bss(apdev[0]['bssid'])
980         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
981             break
982         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
983         time.sleep(0.1)
984     if "[WPS-AUTH]" in bss['flags']:
985         raise Exception("WPS-AUTH flag not removed")
986
987 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
988     """WPS ER adding a new enrollee identified by UUID"""
989     try:
990         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
991     finally:
992         dev[0].request("WPS_ER_STOP")
993
994 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
995     ssid = "wps-er-add-enrollee"
996     ap_pin = "12345670"
997     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
998     hostapd.add_ap(apdev[0]['ifname'],
999                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1000                      "wpa_passphrase": "12345678", "wpa": "2",
1001                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1002                      "device_name": "Wireless AP", "manufacturer": "Company",
1003                      "model_name": "WAP", "model_number": "123",
1004                      "serial_number": "12345", "device_type": "6-0050F204-1",
1005                      "os_version": "01020300",
1006                      "config_methods": "label push_button",
1007                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1008     logger.info("WPS configuration step")
1009     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1010     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1011
1012     logger.info("Start ER")
1013     dev[0].request("WPS_ER_START ifname=lo")
1014     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1015     if ev is None:
1016         raise Exception("AP discovery timed out")
1017     if ap_uuid not in ev:
1018         raise Exception("Expected AP UUID not found")
1019
1020     logger.info("Learn AP configuration through UPnP")
1021     dev[0].dump_monitor()
1022     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1023     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1024     if ev is None:
1025         raise Exception("AP learn timed out")
1026     if ap_uuid not in ev:
1027         raise Exception("Expected AP UUID not in settings")
1028     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1029     if ev is None:
1030         raise Exception("WPS-FAIL after AP learn timed out")
1031     time.sleep(0.1)
1032
1033     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1034     addr1 = dev[1].p2p_interface_addr()
1035     dev[0].dump_monitor()
1036     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1037     dev[1].dump_monitor()
1038     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1039     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1040     if ev is None:
1041         raise Exception("Enrollee not seen")
1042     if addr1 not in ev:
1043         raise Exception("Unexpected Enrollee MAC address")
1044     uuid = ev.split(' ')[1]
1045     dev[0].request("WPS_ER_PBC " + uuid)
1046     dev[1].wait_connected(timeout=30)
1047     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1048     if ev is None:
1049         raise Exception("WPS ER did not report success")
1050
1051     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1052     pin = dev[2].wps_read_pin()
1053     addr2 = dev[2].p2p_interface_addr()
1054     dev[0].dump_monitor()
1055     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1056     dev[2].dump_monitor()
1057     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1058     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1059     if ev is None:
1060         raise Exception("Enrollee not seen")
1061     if addr2 not in ev:
1062         raise Exception("Unexpected Enrollee MAC address")
1063     uuid = ev.split(' ')[1]
1064     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1065     dev[2].wait_connected(timeout=30)
1066     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1067     if ev is None:
1068         raise Exception("WPS ER did not report success")
1069
1070     logger.info("Stop ER")
1071     dev[0].dump_monitor()
1072     dev[0].request("WPS_ER_STOP")
1073
1074 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1075     """WPS ER connected to AP and adding a new enrollee using PBC"""
1076     try:
1077         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1078     finally:
1079         dev[0].request("WPS_ER_STOP")
1080
1081 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1082     ssid = "wps-er-add-enrollee-pbc"
1083     ap_pin = "12345670"
1084     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1085     hostapd.add_ap(apdev[0]['ifname'],
1086                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1087                      "wpa_passphrase": "12345678", "wpa": "2",
1088                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1089                      "device_name": "Wireless AP", "manufacturer": "Company",
1090                      "model_name": "WAP", "model_number": "123",
1091                      "serial_number": "12345", "device_type": "6-0050F204-1",
1092                      "os_version": "01020300",
1093                      "config_methods": "label push_button",
1094                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1095     logger.info("Learn AP configuration")
1096     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1097     dev[0].dump_monitor()
1098     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1099     status = dev[0].get_status()
1100     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1101         raise Exception("Not fully connected")
1102
1103     logger.info("Start ER")
1104     dev[0].request("WPS_ER_START ifname=lo")
1105     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1106     if ev is None:
1107         raise Exception("AP discovery timed out")
1108     if ap_uuid not in ev:
1109         raise Exception("Expected AP UUID not found")
1110
1111     enrollee = dev[1].p2p_interface_addr()
1112
1113     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1114         raise Exception("Unknown UUID not reported")
1115
1116     logger.info("Add Enrollee using ER and PBC")
1117     dev[0].dump_monitor()
1118     dev[1].dump_monitor()
1119     dev[1].request("WPS_PBC")
1120
1121     for i in range(0, 2):
1122         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1123         if ev is None:
1124             raise Exception("Enrollee discovery timed out")
1125         if enrollee in ev:
1126             break
1127         if i == 1:
1128             raise Exception("Expected Enrollee not found")
1129     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1130         raise Exception("Unknown UUID not reported")
1131     logger.info("Use learned network configuration on ER")
1132     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1133     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1134         raise Exception("WPS_ER_PBC failed")
1135
1136     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1137     if ev is None:
1138         raise Exception("Enrollee did not report success")
1139     dev[1].wait_connected(timeout=15)
1140     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1141     if ev is None:
1142         raise Exception("WPS ER did not report success")
1143     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1144
1145 def test_ap_wps_er_pbc_overlap(dev, apdev):
1146     """WPS ER connected to AP and PBC session overlap"""
1147     try:
1148         _test_ap_wps_er_pbc_overlap(dev, apdev)
1149     finally:
1150         dev[0].request("WPS_ER_STOP")
1151
1152 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1153     ssid = "wps-er-add-enrollee-pbc"
1154     ap_pin = "12345670"
1155     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1156     hostapd.add_ap(apdev[0]['ifname'],
1157                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1158                      "wpa_passphrase": "12345678", "wpa": "2",
1159                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1160                      "device_name": "Wireless AP", "manufacturer": "Company",
1161                      "model_name": "WAP", "model_number": "123",
1162                      "serial_number": "12345", "device_type": "6-0050F204-1",
1163                      "os_version": "01020300",
1164                      "config_methods": "label push_button",
1165                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1166     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1167     dev[0].dump_monitor()
1168     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1169
1170     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1171     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1172     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1173     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1174
1175     dev[0].dump_monitor()
1176     dev[0].request("WPS_ER_START ifname=lo")
1177
1178     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1179     if ev is None:
1180         raise Exception("AP discovery timed out")
1181     if ap_uuid not in ev:
1182         raise Exception("Expected AP UUID not found")
1183
1184     # verify BSSID selection of the AP instead of UUID
1185     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1186         raise Exception("Could not select AP based on BSSID")
1187
1188     dev[0].dump_monitor()
1189     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1190     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1191     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1192     if ev is None:
1193         raise Exception("PBC scan failed")
1194     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1195     if ev is None:
1196         raise Exception("PBC scan failed")
1197     found1 = False
1198     found2 = False
1199     addr1 = dev[1].own_addr()
1200     addr2 = dev[2].own_addr()
1201     for i in range(3):
1202         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1203         if ev is None:
1204             raise Exception("Enrollee discovery timed out")
1205         if addr1 in ev:
1206             found1 = True
1207             if found2:
1208                 break
1209         if addr2 in ev:
1210             found2 = True
1211             if found1:
1212                 break
1213     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1214         raise Exception("PBC overlap not reported")
1215     dev[1].request("WPS_CANCEL")
1216     dev[2].request("WPS_CANCEL")
1217     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1218         raise Exception("Invalid WPS_ER_PBC accepted")
1219
1220 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1221     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1222     try:
1223         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1224     finally:
1225         dev[0].request("WPS_ER_STOP")
1226
1227 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1228     ssid = "wps-er-add-enrollee-pbc"
1229     ap_pin = "12345670"
1230     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1231     hostapd.add_ap(apdev[0]['ifname'],
1232                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1233                      "wpa_passphrase": "12345678", "wpa": "2",
1234                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1235                      "device_name": "Wireless AP", "manufacturer": "Company",
1236                      "model_name": "WAP", "model_number": "123",
1237                      "serial_number": "12345", "device_type": "6-0050F204-1",
1238                      "os_version": "01020300",
1239                      "config_methods": "label push_button",
1240                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1241     logger.info("Learn AP configuration")
1242     dev[0].request("SET wps_version_number 0x10")
1243     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1244     dev[0].dump_monitor()
1245     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1246     status = dev[0].get_status()
1247     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1248         raise Exception("Not fully connected")
1249
1250     logger.info("Start ER")
1251     dev[0].request("WPS_ER_START ifname=lo")
1252     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1253     if ev is None:
1254         raise Exception("AP discovery timed out")
1255     if ap_uuid not in ev:
1256         raise Exception("Expected AP UUID not found")
1257
1258     logger.info("Use learned network configuration on ER")
1259     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1260
1261     logger.info("Add Enrollee using ER and PIN")
1262     enrollee = dev[1].p2p_interface_addr()
1263     pin = dev[1].wps_read_pin()
1264     dev[0].dump_monitor()
1265     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1266     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1267     dev[1].dump_monitor()
1268     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1269     dev[1].wait_connected(timeout=30)
1270     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1271     if ev is None:
1272         raise Exception("WPS ER did not report success")
1273
1274 def test_ap_wps_er_config_ap(dev, apdev):
1275     """WPS ER configuring AP over UPnP"""
1276     try:
1277         _test_ap_wps_er_config_ap(dev, apdev)
1278     finally:
1279         dev[0].request("WPS_ER_STOP")
1280
1281 def _test_ap_wps_er_config_ap(dev, apdev):
1282     ssid = "wps-er-ap-config"
1283     ap_pin = "12345670"
1284     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1285     hostapd.add_ap(apdev[0]['ifname'],
1286                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1287                      "wpa_passphrase": "12345678", "wpa": "2",
1288                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1289                      "device_name": "Wireless AP", "manufacturer": "Company",
1290                      "model_name": "WAP", "model_number": "123",
1291                      "serial_number": "12345", "device_type": "6-0050F204-1",
1292                      "os_version": "01020300",
1293                      "config_methods": "label push_button",
1294                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1295
1296     logger.info("Connect ER to the AP")
1297     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1298
1299     logger.info("WPS configuration step")
1300     dev[0].request("WPS_ER_START ifname=lo")
1301     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1302     if ev is None:
1303         raise Exception("AP discovery timed out")
1304     if ap_uuid not in ev:
1305         raise Exception("Expected AP UUID not found")
1306     new_passphrase = "1234567890"
1307     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1308                    ssid.encode("hex") + " WPA2PSK CCMP " +
1309                    new_passphrase.encode("hex"))
1310     ev = dev[0].wait_event(["WPS-SUCCESS"])
1311     if ev is None:
1312         raise Exception("WPS ER configuration operation timed out")
1313     dev[0].wait_disconnected(timeout=10)
1314     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1315
1316     logger.info("WPS ER restart")
1317     dev[0].request("WPS_ER_START")
1318     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1319     if ev is None:
1320         raise Exception("AP discovery timed out on ER restart")
1321     if ap_uuid not in ev:
1322         raise Exception("Expected AP UUID not found on ER restart")
1323     if "OK" not in dev[0].request("WPS_ER_STOP"):
1324         raise Exception("WPS_ER_STOP failed")
1325     if "OK" not in dev[0].request("WPS_ER_STOP"):
1326         raise Exception("WPS_ER_STOP failed")
1327
1328 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1329     """WPS ER caching AP settings"""
1330     try:
1331         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1332     finally:
1333         dev[0].request("WPS_ER_STOP")
1334
1335 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1336     ssid = "wps-er-add-enrollee"
1337     ap_pin = "12345670"
1338     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1339     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1340                "wpa_passphrase": "12345678", "wpa": "2",
1341                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1342                "device_name": "Wireless AP", "manufacturer": "Company",
1343                "model_name": "WAP", "model_number": "123",
1344                "serial_number": "12345", "device_type": "6-0050F204-1",
1345                "os_version": "01020300",
1346                "config_methods": "label push_button",
1347                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1348     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1349     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1350     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1351     id = int(dev[0].list_networks()[0]['id'])
1352     dev[0].set_network(id, "scan_freq", "2412")
1353
1354     dev[0].request("WPS_ER_START ifname=lo")
1355     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1356     if ev is None:
1357         raise Exception("AP discovery timed out")
1358     if ap_uuid not in ev:
1359         raise Exception("Expected AP UUID not found")
1360
1361     dev[0].dump_monitor()
1362     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1363     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1364     if ev is None:
1365         raise Exception("AP learn timed out")
1366     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1367     if ev is None:
1368         raise Exception("WPS-FAIL after AP learn timed out")
1369     time.sleep(0.1)
1370
1371     hapd.disable()
1372
1373     for i in range(2):
1374         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1375                                  "CTRL-EVENT-DISCONNECTED" ],
1376                                timeout=15)
1377         if ev is None:
1378             raise Exception("AP removal or disconnection timed out")
1379
1380     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1381     for i in range(2):
1382         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1383                                timeout=15)
1384         if ev is None:
1385             raise Exception("AP discovery or connection timed out")
1386
1387     pin = dev[1].wps_read_pin()
1388     dev[0].dump_monitor()
1389     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1390
1391     time.sleep(0.2)
1392
1393     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1394     dev[1].dump_monitor()
1395     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1396     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1397     if ev is None:
1398         raise Exception("Enrollee did not report success")
1399     dev[1].wait_connected(timeout=15)
1400     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1401     if ev is None:
1402         raise Exception("WPS ER did not report success")
1403
1404     dev[0].dump_monitor()
1405     dev[0].request("WPS_ER_STOP")
1406
1407 def test_ap_wps_fragmentation(dev, apdev):
1408     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1409     ssid = "test-wps-fragmentation"
1410     appin = "12345670"
1411     hostapd.add_ap(apdev[0]['ifname'],
1412                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1413                      "wpa_passphrase": "12345678", "wpa": "3",
1414                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1415                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1416                      "fragment_size": "50" })
1417     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1418     logger.info("WPS provisioning step (PBC)")
1419     hapd.request("WPS_PBC")
1420     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1421     dev[0].dump_monitor()
1422     dev[0].request("SET wps_fragment_size 50")
1423     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1424     dev[0].wait_connected(timeout=30)
1425     status = dev[0].get_status()
1426     if status['wpa_state'] != 'COMPLETED':
1427         raise Exception("Not fully connected")
1428     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1429         raise Exception("Unexpected encryption configuration")
1430     if status['key_mgmt'] != 'WPA2-PSK':
1431         raise Exception("Unexpected key_mgmt")
1432
1433     logger.info("WPS provisioning step (PIN)")
1434     pin = dev[1].wps_read_pin()
1435     hapd.request("WPS_PIN any " + pin)
1436     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1437     dev[1].request("SET wps_fragment_size 50")
1438     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1439     dev[1].wait_connected(timeout=30)
1440     status = dev[1].get_status()
1441     if status['wpa_state'] != 'COMPLETED':
1442         raise Exception("Not fully connected")
1443     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1444         raise Exception("Unexpected encryption configuration")
1445     if status['key_mgmt'] != 'WPA2-PSK':
1446         raise Exception("Unexpected key_mgmt")
1447
1448     logger.info("WPS connection as registrar")
1449     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1450     dev[2].request("SET wps_fragment_size 50")
1451     dev[2].wps_reg(apdev[0]['bssid'], appin)
1452     status = dev[2].get_status()
1453     if status['wpa_state'] != 'COMPLETED':
1454         raise Exception("Not fully connected")
1455     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1456         raise Exception("Unexpected encryption configuration")
1457     if status['key_mgmt'] != 'WPA2-PSK':
1458         raise Exception("Unexpected key_mgmt")
1459
1460 def test_ap_wps_new_version_sta(dev, apdev):
1461     """WPS compatibility with new version number on the station"""
1462     ssid = "test-wps-ver"
1463     hostapd.add_ap(apdev[0]['ifname'],
1464                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1465                      "wpa_passphrase": "12345678", "wpa": "2",
1466                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1467     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1468     logger.info("WPS provisioning step")
1469     hapd.request("WPS_PBC")
1470     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1471     dev[0].dump_monitor()
1472     dev[0].request("SET wps_version_number 0x43")
1473     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1474     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1475     dev[0].wait_connected(timeout=30)
1476
1477 def test_ap_wps_new_version_ap(dev, apdev):
1478     """WPS compatibility with new version number on the AP"""
1479     ssid = "test-wps-ver"
1480     hostapd.add_ap(apdev[0]['ifname'],
1481                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1482                      "wpa_passphrase": "12345678", "wpa": "2",
1483                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1484     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1485     logger.info("WPS provisioning step")
1486     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1487         raise Exception("Failed to enable test functionality")
1488     hapd.request("WPS_PBC")
1489     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1490     dev[0].dump_monitor()
1491     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1492     dev[0].wait_connected(timeout=30)
1493     hapd.request("SET wps_version_number 0x20")
1494
1495 def test_ap_wps_check_pin(dev, apdev):
1496     """Verify PIN checking through control interface"""
1497     hostapd.add_ap(apdev[0]['ifname'],
1498                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1499                      "wpa_passphrase": "12345678", "wpa": "2",
1500                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1501     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1502     for t in [ ("12345670", "12345670"),
1503                ("12345678", "FAIL-CHECKSUM"),
1504                ("12345", "FAIL"),
1505                ("123456789", "FAIL"),
1506                ("1234-5670", "12345670"),
1507                ("1234 5670", "12345670"),
1508                ("1-2.3:4 5670", "12345670") ]:
1509         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1510         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1511         if res != res2:
1512             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1513         if res != t[1]:
1514             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1515
1516     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1517         raise Exception("Unexpected WPS_CHECK_PIN success")
1518     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1519         raise Exception("Unexpected WPS_CHECK_PIN success")
1520
1521     for i in range(0, 10):
1522         pin = dev[0].request("WPS_PIN get")
1523         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1524         if pin != rpin:
1525             raise Exception("Random PIN validation failed for " + pin)
1526
1527 def test_ap_wps_wep_config(dev, apdev):
1528     """WPS 2.0 AP rejecting WEP configuration"""
1529     ssid = "test-wps-config"
1530     appin = "12345670"
1531     hostapd.add_ap(apdev[0]['ifname'],
1532                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1533                      "ap_pin": appin})
1534     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1535     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1536     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1537                    "hello", no_wait=True)
1538     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1539     if ev is None:
1540         raise Exception("WPS-FAIL timed out")
1541     if "reason=2" not in ev:
1542         raise Exception("Unexpected reason code in WPS-FAIL")
1543     status = hapd.request("WPS_GET_STATUS")
1544     if "Last WPS result: Failed" not in status:
1545         raise Exception("WPS failure result not shown correctly")
1546     if "Failure Reason: WEP Prohibited" not in status:
1547         raise Exception("Failure reason not reported correctly")
1548     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1549         raise Exception("Peer address not shown correctly")
1550
1551 def test_ap_wps_wep_enroll(dev, apdev):
1552     """WPS 2.0 STA rejecting WEP configuration"""
1553     ssid = "test-wps-wep"
1554     hostapd.add_ap(apdev[0]['ifname'],
1555                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1556                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1557     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1558     hapd.request("WPS_PBC")
1559     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1560     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1561     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1562     if ev is None:
1563         raise Exception("WPS-FAIL event timed out")
1564     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1565         raise Exception("Unexpected WPS-FAIL event: " + ev)
1566
1567 def test_ap_wps_ie_fragmentation(dev, apdev):
1568     """WPS AP using fragmented WPS IE"""
1569     ssid = "test-wps-ie-fragmentation"
1570     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1571                "wpa_passphrase": "12345678", "wpa": "2",
1572                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1573                "device_name": "1234567890abcdef1234567890abcdef",
1574                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1575                "model_name": "1234567890abcdef1234567890abcdef",
1576                "model_number": "1234567890abcdef1234567890abcdef",
1577                "serial_number": "1234567890abcdef1234567890abcdef" }
1578     hostapd.add_ap(apdev[0]['ifname'], params)
1579     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1580     hapd.request("WPS_PBC")
1581     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1582     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1583     dev[0].wait_connected(timeout=30)
1584     bss = dev[0].get_bss(apdev[0]['bssid'])
1585     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1586         logger.info("Device Name not received correctly")
1587         logger.info(bss)
1588         # This can fail if Probe Response frame is missed and Beacon frame was
1589         # used to fill in the BSS entry. This can happen, e.g., during heavy
1590         # load every now and then and is not really an error, so try to
1591         # workaround by runnign another scan.
1592         dev[0].scan(freq="2412", only_new=True)
1593         bss = dev[0].get_bss(apdev[0]['bssid'])
1594         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1595             logger.info(bss)
1596             raise Exception("Device Name not received correctly")
1597     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1598         raise Exception("Unexpected number of WPS IEs")
1599
1600 def get_psk(pskfile):
1601     psks = {}
1602     with open(pskfile, "r") as f:
1603         lines = f.read().splitlines()
1604         for l in lines:
1605             if l == "# WPA PSKs":
1606                 continue
1607             (addr,psk) = l.split(' ')
1608             psks[addr] = psk
1609     return psks
1610
1611 def test_ap_wps_per_station_psk(dev, apdev):
1612     """WPS PBC provisioning with per-station PSK"""
1613     addr0 = dev[0].own_addr()
1614     addr1 = dev[1].own_addr()
1615     addr2 = dev[2].own_addr()
1616     ssid = "wps"
1617     appin = "12345670"
1618     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1619     try:
1620         os.remove(pskfile)
1621     except:
1622         pass
1623
1624     try:
1625         with open(pskfile, "w") as f:
1626             f.write("# WPA PSKs\n")
1627
1628         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1629                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1630                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1631                    "wpa_psk_file": pskfile }
1632         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1633
1634         logger.info("First enrollee")
1635         hapd.request("WPS_PBC")
1636         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1637         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1638         dev[0].wait_connected(timeout=30)
1639
1640         logger.info("Second enrollee")
1641         hapd.request("WPS_PBC")
1642         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1643         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1644         dev[1].wait_connected(timeout=30)
1645
1646         logger.info("External registrar")
1647         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1648         dev[2].wps_reg(apdev[0]['bssid'], appin)
1649
1650         logger.info("Verifying PSK results")
1651         psks = get_psk(pskfile)
1652         if addr0 not in psks:
1653             raise Exception("No PSK recorded for sta0")
1654         if addr1 not in psks:
1655             raise Exception("No PSK recorded for sta1")
1656         if addr2 not in psks:
1657             raise Exception("No PSK recorded for sta2")
1658         if psks[addr0] == psks[addr1]:
1659             raise Exception("Same PSK recorded for sta0 and sta1")
1660         if psks[addr0] == psks[addr2]:
1661             raise Exception("Same PSK recorded for sta0 and sta2")
1662         if psks[addr1] == psks[addr2]:
1663             raise Exception("Same PSK recorded for sta1 and sta2")
1664
1665         dev[0].request("REMOVE_NETWORK all")
1666         logger.info("Second external registrar")
1667         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1668         dev[0].wps_reg(apdev[0]['bssid'], appin)
1669         psks2 = get_psk(pskfile)
1670         if addr0 not in psks2:
1671             raise Exception("No PSK recorded for sta0(reg)")
1672         if psks[addr0] == psks2[addr0]:
1673             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
1674     finally:
1675         os.remove(pskfile)
1676
1677 def test_ap_wps_per_station_psk_failure(dev, apdev):
1678     """WPS PBC provisioning with per-station PSK (file not writable)"""
1679     addr0 = dev[0].p2p_dev_addr()
1680     addr1 = dev[1].p2p_dev_addr()
1681     addr2 = dev[2].p2p_dev_addr()
1682     ssid = "wps"
1683     appin = "12345670"
1684     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1685     try:
1686         os.remove(pskfile)
1687     except:
1688         pass
1689
1690     try:
1691         with open(pskfile, "w") as f:
1692             f.write("# WPA PSKs\n")
1693
1694         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1695                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1696                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1697                    "wpa_psk_file": pskfile }
1698         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1699         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
1700             raise Exception("Failed to set wpa_psk_file")
1701
1702         logger.info("First enrollee")
1703         hapd.request("WPS_PBC")
1704         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1705         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1706         dev[0].wait_connected(timeout=30)
1707
1708         logger.info("Second enrollee")
1709         hapd.request("WPS_PBC")
1710         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1711         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1712         dev[1].wait_connected(timeout=30)
1713
1714         logger.info("External registrar")
1715         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1716         dev[2].wps_reg(apdev[0]['bssid'], appin)
1717
1718         logger.info("Verifying PSK results")
1719         psks = get_psk(pskfile)
1720         if len(psks) > 0:
1721             raise Exception("PSK recorded unexpectedly")
1722     finally:
1723         os.remove(pskfile)
1724
1725 def test_ap_wps_pin_request_file(dev, apdev):
1726     """WPS PIN provisioning with configured AP"""
1727     ssid = "wps"
1728     pinfile = "/tmp/ap_wps_pin_request_file.log"
1729     if os.path.exists(pinfile):
1730         os.remove(pinfile)
1731     hostapd.add_ap(apdev[0]['ifname'],
1732                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1733                      "wps_pin_requests": pinfile,
1734                      "wpa_passphrase": "12345678", "wpa": "2",
1735                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
1736     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1737     uuid = dev[0].get_status_field("uuid")
1738     pin = dev[0].wps_read_pin()
1739     try:
1740         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1741         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1742         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
1743         if ev is None:
1744             raise Exception("PIN needed event not shown")
1745         if uuid not in ev:
1746             raise Exception("UUID mismatch")
1747         dev[0].request("WPS_CANCEL")
1748         success = False
1749         with open(pinfile, "r") as f:
1750             lines = f.readlines()
1751             for l in lines:
1752                 if uuid in l:
1753                     success = True
1754                     break
1755         if not success:
1756             raise Exception("PIN request entry not in the log file")
1757     finally:
1758         try:
1759             os.remove(pinfile)
1760         except:
1761             pass
1762
1763 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
1764     """WPS auto-setup with configuration file"""
1765     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
1766     ifname = apdev[0]['ifname']
1767     try:
1768         with open(conffile, "w") as f:
1769             f.write("driver=nl80211\n")
1770             f.write("hw_mode=g\n")
1771             f.write("channel=1\n")
1772             f.write("ieee80211n=1\n")
1773             f.write("interface=%s\n" % ifname)
1774             f.write("ctrl_interface=/var/run/hostapd\n")
1775             f.write("ssid=wps\n")
1776             f.write("eap_server=1\n")
1777             f.write("wps_state=1\n")
1778         hostapd.add_bss('phy3', ifname, conffile)
1779         hapd = hostapd.Hostapd(ifname)
1780         hapd.request("WPS_PBC")
1781         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1782         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1783         dev[0].wait_connected(timeout=30)
1784         with open(conffile, "r") as f:
1785             lines = f.read().splitlines()
1786             vals = dict()
1787             for l in lines:
1788                 try:
1789                     [name,value] = l.split('=', 1)
1790                     vals[name] = value
1791                 except ValueError, e:
1792                     if "# WPS configuration" in l:
1793                         pass
1794                     else:
1795                         raise Exception("Unexpected configuration line: " + l)
1796         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
1797             raise Exception("Incorrect configuration: " + str(vals))
1798     finally:
1799         try:
1800             os.remove(conffile)
1801         except:
1802             pass
1803
1804 def test_ap_wps_pbc_timeout(dev, apdev, params):
1805     """wpa_supplicant PBC walk time [long]"""
1806     if not params['long']:
1807         raise HwsimSkip("Skip test case with long duration due to --long not specified")
1808     ssid = "test-wps"
1809     hostapd.add_ap(apdev[0]['ifname'],
1810                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
1811     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1812     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
1813     if "OK" not in dev[0].request("WPS_PBC"):
1814         raise Exception("WPS_PBC failed")
1815     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=150)
1816     if ev is None:
1817         raise Exception("WPS-TIMEOUT not reported")
1818
1819 def add_ssdp_ap(ifname, ap_uuid):
1820     ssid = "wps-ssdp"
1821     ap_pin = "12345670"
1822     hostapd.add_ap(ifname,
1823                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1824                      "wpa_passphrase": "12345678", "wpa": "2",
1825                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1826                      "device_name": "Wireless AP", "manufacturer": "Company",
1827                      "model_name": "WAP", "model_number": "123",
1828                      "serial_number": "12345", "device_type": "6-0050F204-1",
1829                      "os_version": "01020300",
1830                      "config_methods": "label push_button",
1831                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
1832                      "friendly_name": "WPS Access Point",
1833                      "manufacturer_url": "http://www.example.com/",
1834                      "model_description": "Wireless Access Point",
1835                      "model_url": "http://www.example.com/model/",
1836                      "upc": "123456789012" })
1837
1838 def ssdp_send(msg, no_recv=False):
1839     socket.setdefaulttimeout(1)
1840     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1841     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1842     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1843     sock.bind(("127.0.0.1", 0))
1844     sock.sendto(msg, ("239.255.255.250", 1900))
1845     if no_recv:
1846         return None
1847     return sock.recv(1000)
1848
1849 def ssdp_send_msearch(st):
1850     msg = '\r\n'.join([
1851             'M-SEARCH * HTTP/1.1',
1852             'HOST: 239.255.255.250:1900',
1853             'MX: 1',
1854             'MAN: "ssdp:discover"',
1855             'ST: ' + st,
1856             '', ''])
1857     return ssdp_send(msg)
1858
1859 def test_ap_wps_ssdp_msearch(dev, apdev):
1860     """WPS AP and SSDP M-SEARCH messages"""
1861     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1862     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1863
1864     msg = '\r\n'.join([
1865             'M-SEARCH * HTTP/1.1',
1866             'Host: 239.255.255.250:1900',
1867             'Mx: 1',
1868             'Man: "ssdp:discover"',
1869             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
1870             '', ''])
1871     ssdp_send(msg)
1872
1873     msg = '\r\n'.join([
1874             'M-SEARCH * HTTP/1.1',
1875             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
1876             'mx: \t1\t\t   ',
1877             'man: \t \t "ssdp:discover"   ',
1878             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
1879             '', ''])
1880     ssdp_send(msg)
1881
1882     ssdp_send_msearch("ssdp:all")
1883     ssdp_send_msearch("upnp:rootdevice")
1884     ssdp_send_msearch("uuid:" + ap_uuid)
1885     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
1886     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
1887
1888     msg = '\r\n'.join([
1889             'M-SEARCH * HTTP/1.1',
1890             'HOST:\t239.255.255.250:1900',
1891             'MAN: "ssdp:discover"',
1892             'MX: 130',
1893             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1894             '', ''])
1895     ssdp_send(msg, no_recv=True)
1896
1897 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
1898     """WPS AP and invalid SSDP M-SEARCH messages"""
1899     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1900     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1901
1902     socket.setdefaulttimeout(1)
1903     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1904     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1905     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1906     sock.bind(("127.0.0.1", 0))
1907
1908     logger.debug("Missing MX")
1909     msg = '\r\n'.join([
1910             'M-SEARCH * HTTP/1.1',
1911             'HOST: 239.255.255.250:1900',
1912             'MAN: "ssdp:discover"',
1913             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1914             '', ''])
1915     sock.sendto(msg, ("239.255.255.250", 1900))
1916
1917     logger.debug("Negative MX")
1918     msg = '\r\n'.join([
1919             'M-SEARCH * HTTP/1.1',
1920             'HOST: 239.255.255.250:1900',
1921             'MX: -1',
1922             'MAN: "ssdp:discover"',
1923             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1924             '', ''])
1925     sock.sendto(msg, ("239.255.255.250", 1900))
1926
1927     logger.debug("Invalid MX")
1928     msg = '\r\n'.join([
1929             'M-SEARCH * HTTP/1.1',
1930             'HOST: 239.255.255.250:1900',
1931             'MX; 1',
1932             'MAN: "ssdp:discover"',
1933             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1934             '', ''])
1935     sock.sendto(msg, ("239.255.255.250", 1900))
1936
1937     logger.debug("Missing MAN")
1938     msg = '\r\n'.join([
1939             'M-SEARCH * HTTP/1.1',
1940             'HOST: 239.255.255.250:1900',
1941             'MX: 1',
1942             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1943             '', ''])
1944     sock.sendto(msg, ("239.255.255.250", 1900))
1945
1946     logger.debug("Invalid MAN")
1947     msg = '\r\n'.join([
1948             'M-SEARCH * HTTP/1.1',
1949             'HOST: 239.255.255.250:1900',
1950             'MX: 1',
1951             'MAN: foo',
1952             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1953             '', ''])
1954     sock.sendto(msg, ("239.255.255.250", 1900))
1955     msg = '\r\n'.join([
1956             'M-SEARCH * HTTP/1.1',
1957             'HOST: 239.255.255.250:1900',
1958             'MX: 1',
1959             'MAN; "ssdp:discover"',
1960             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1961             '', ''])
1962     sock.sendto(msg, ("239.255.255.250", 1900))
1963
1964     logger.debug("Missing HOST")
1965     msg = '\r\n'.join([
1966             'M-SEARCH * HTTP/1.1',
1967             'MAN: "ssdp:discover"',
1968             'MX: 1',
1969             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1970             '', ''])
1971     sock.sendto(msg, ("239.255.255.250", 1900))
1972
1973     logger.debug("Missing ST")
1974     msg = '\r\n'.join([
1975             'M-SEARCH * HTTP/1.1',
1976             'HOST: 239.255.255.250:1900',
1977             'MAN: "ssdp:discover"',
1978             'MX: 1',
1979             '', ''])
1980     sock.sendto(msg, ("239.255.255.250", 1900))
1981
1982     logger.debug("Mismatching ST")
1983     msg = '\r\n'.join([
1984             'M-SEARCH * HTTP/1.1',
1985             'HOST: 239.255.255.250:1900',
1986             'MAN: "ssdp:discover"',
1987             'MX: 1',
1988             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
1989             '', ''])
1990     sock.sendto(msg, ("239.255.255.250", 1900))
1991     msg = '\r\n'.join([
1992             'M-SEARCH * HTTP/1.1',
1993             'HOST: 239.255.255.250:1900',
1994             'MAN: "ssdp:discover"',
1995             'MX: 1',
1996             'ST: foo:bar',
1997             '', ''])
1998     sock.sendto(msg, ("239.255.255.250", 1900))
1999     msg = '\r\n'.join([
2000             'M-SEARCH * HTTP/1.1',
2001             'HOST: 239.255.255.250:1900',
2002             'MAN: "ssdp:discover"',
2003             'MX: 1',
2004             'ST: foobar',
2005             '', ''])
2006     sock.sendto(msg, ("239.255.255.250", 1900))
2007
2008     logger.debug("Invalid ST")
2009     msg = '\r\n'.join([
2010             'M-SEARCH * HTTP/1.1',
2011             'HOST: 239.255.255.250:1900',
2012             'MAN: "ssdp:discover"',
2013             'MX: 1',
2014             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2015             '', ''])
2016     sock.sendto(msg, ("239.255.255.250", 1900))
2017
2018     logger.debug("Invalid M-SEARCH")
2019     msg = '\r\n'.join([
2020             'M+SEARCH * HTTP/1.1',
2021             'HOST: 239.255.255.250:1900',
2022             'MAN: "ssdp:discover"',
2023             'MX: 1',
2024             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2025             '', ''])
2026     sock.sendto(msg, ("239.255.255.250", 1900))
2027     msg = '\r\n'.join([
2028             'M-SEARCH-* HTTP/1.1',
2029             'HOST: 239.255.255.250:1900',
2030             'MAN: "ssdp:discover"',
2031             'MX: 1',
2032             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2033             '', ''])
2034     sock.sendto(msg, ("239.255.255.250", 1900))
2035
2036     logger.debug("Invalid message format")
2037     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2038     msg = '\r'.join([
2039             'M-SEARCH * HTTP/1.1',
2040             'HOST: 239.255.255.250:1900',
2041             'MAN: "ssdp:discover"',
2042             'MX: 1',
2043             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2044             '', ''])
2045     sock.sendto(msg, ("239.255.255.250", 1900))
2046
2047     try:
2048         r = sock.recv(1000)
2049         raise Exception("Unexpected M-SEARCH response: " + r)
2050     except socket.timeout:
2051         pass
2052
2053     logger.debug("Valid M-SEARCH")
2054     msg = '\r\n'.join([
2055             'M-SEARCH * HTTP/1.1',
2056             'HOST: 239.255.255.250:1900',
2057             'MAN: "ssdp:discover"',
2058             'MX: 1',
2059             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2060             '', ''])
2061     sock.sendto(msg, ("239.255.255.250", 1900))
2062
2063     try:
2064         r = sock.recv(1000)
2065         pass
2066     except socket.timeout:
2067         raise Exception("No SSDP response")
2068
2069 def test_ap_wps_ssdp_burst(dev, apdev):
2070     """WPS AP and SSDP burst"""
2071     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2072     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2073
2074     msg = '\r\n'.join([
2075             'M-SEARCH * HTTP/1.1',
2076             'HOST: 239.255.255.250:1900',
2077             'MAN: "ssdp:discover"',
2078             'MX: 1',
2079             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2080             '', ''])
2081     socket.setdefaulttimeout(1)
2082     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2083     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2084     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2085     sock.bind(("127.0.0.1", 0))
2086     for i in range(0, 25):
2087         sock.sendto(msg, ("239.255.255.250", 1900))
2088     resp = 0
2089     while True:
2090         try:
2091             r = sock.recv(1000)
2092             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2093                 raise Exception("Unexpected message: " + r)
2094             resp += 1
2095         except socket.timeout:
2096             break
2097     if resp < 20:
2098         raise Exception("Too few SSDP responses")
2099
2100     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2101     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2102     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2103     sock.bind(("127.0.0.1", 0))
2104     for i in range(0, 25):
2105         sock.sendto(msg, ("239.255.255.250", 1900))
2106     while True:
2107         try:
2108             r = sock.recv(1000)
2109             if ap_uuid in r:
2110                 break
2111         except socket.timeout:
2112             raise Exception("No SSDP response")
2113
2114 def ssdp_get_location(uuid):
2115     res = ssdp_send_msearch("uuid:" + uuid)
2116     location = None
2117     for l in res.splitlines():
2118         if l.lower().startswith("location:"):
2119             location = l.split(':', 1)[1].strip()
2120             break
2121     if location is None:
2122         raise Exception("No UPnP location found")
2123     return location
2124
2125 def upnp_get_urls(location):
2126     conn = urllib.urlopen(location)
2127     tree = ET.parse(conn)
2128     root = tree.getroot()
2129     urn = '{urn:schemas-upnp-org:device-1-0}'
2130     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2131     res = {}
2132     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2133     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2134     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2135     return res
2136
2137 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2138     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2139     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2140     ET.register_namespace('soapenv', soapns)
2141     ET.register_namespace('wfa', wpsns)
2142     attrib = {}
2143     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2144     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2145     body = ET.SubElement(root, "{%s}Body" % soapns)
2146     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2147     tree = ET.ElementTree(root)
2148     soap = StringIO.StringIO()
2149     tree.write(soap, xml_declaration=True, encoding='utf-8')
2150
2151     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2152     if include_soap_action:
2153         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2154     elif soap_action_override:
2155         headers["SOAPAction"] = soap_action_override
2156     conn.request("POST", path, soap.getvalue(), headers)
2157     return conn.getresponse()
2158
2159 def test_ap_wps_upnp(dev, apdev):
2160     """WPS AP and UPnP operations"""
2161     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2162     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2163
2164     location = ssdp_get_location(ap_uuid)
2165     urls = upnp_get_urls(location)
2166
2167     conn = urllib.urlopen(urls['scpd_url'])
2168     scpd = conn.read()
2169
2170     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2171     if conn.getcode() != 404:
2172         raise Exception("Unexpected HTTP response to GET unknown URL")
2173
2174     url = urlparse.urlparse(location)
2175     conn = httplib.HTTPConnection(url.netloc)
2176     #conn.set_debuglevel(1)
2177     headers = { "Content-type": 'text/xml; charset="utf-8"',
2178                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2179     conn.request("POST", "hello", "\r\n\r\n", headers)
2180     resp = conn.getresponse()
2181     if resp.status != 404:
2182         raise Exception("Unexpected HTTP response: %d" % resp.status)
2183
2184     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2185     resp = conn.getresponse()
2186     if resp.status != 501:
2187         raise Exception("Unexpected HTTP response: %d" % resp.status)
2188
2189     headers = { "Content-type": 'text/xml; charset="utf-8"',
2190                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2191     ctrlurl = urlparse.urlparse(urls['control_url'])
2192     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2193     resp = conn.getresponse()
2194     if resp.status != 401:
2195         raise Exception("Unexpected HTTP response: %d" % resp.status)
2196
2197     logger.debug("GetDeviceInfo without SOAPAction header")
2198     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2199                             include_soap_action=False)
2200     if resp.status != 401:
2201         raise Exception("Unexpected HTTP response: %d" % resp.status)
2202
2203     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2204     for act in [ "foo",
2205                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2206                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2207                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2208         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2209                                 include_soap_action=False,
2210                                 soap_action_override=act)
2211         if resp.status != 401:
2212             raise Exception("Unexpected HTTP response: %d" % resp.status)
2213
2214     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2215     if resp.status != 200:
2216         raise Exception("Unexpected HTTP response: %d" % resp.status)
2217     dev = resp.read()
2218     if "NewDeviceInfo" not in dev:
2219         raise Exception("Unexpected GetDeviceInfo response")
2220
2221     logger.debug("PutMessage without required parameters")
2222     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2223     if resp.status != 600:
2224         raise Exception("Unexpected HTTP response: %d" % resp.status)
2225
2226     logger.debug("PutWLANResponse without required parameters")
2227     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2228     if resp.status != 600:
2229         raise Exception("Unexpected HTTP response: %d" % resp.status)
2230
2231     logger.debug("SetSelectedRegistrar from unregistered ER")
2232     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2233     if resp.status != 501:
2234         raise Exception("Unexpected HTTP response: %d" % resp.status)
2235
2236     logger.debug("Unknown action")
2237     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2238     if resp.status != 401:
2239         raise Exception("Unexpected HTTP response: %d" % resp.status)
2240
2241 def test_ap_wps_upnp_subscribe(dev, apdev):
2242     """WPS AP and UPnP event subscription"""
2243     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2244     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2245
2246     location = ssdp_get_location(ap_uuid)
2247     urls = upnp_get_urls(location)
2248     eventurl = urlparse.urlparse(urls['event_sub_url'])
2249
2250     url = urlparse.urlparse(location)
2251     conn = httplib.HTTPConnection(url.netloc)
2252     #conn.set_debuglevel(1)
2253     headers = { "callback": '<http://127.0.0.1:12345/event>',
2254                 "timeout": "Second-1234" }
2255     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2256     resp = conn.getresponse()
2257     if resp.status != 412:
2258         raise Exception("Unexpected HTTP response: %d" % resp.status)
2259
2260     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2261     resp = conn.getresponse()
2262     if resp.status != 412:
2263         raise Exception("Unexpected HTTP response: %d" % resp.status)
2264
2265     headers = { "NT": "upnp:event",
2266                 "timeout": "Second-1234" }
2267     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2268     resp = conn.getresponse()
2269     if resp.status != 412:
2270         raise Exception("Unexpected HTTP response: %d" % resp.status)
2271
2272     headers = { "callback": '<http://127.0.0.1:12345/event>',
2273                 "NT": "upnp:foobar",
2274                 "timeout": "Second-1234" }
2275     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2276     resp = conn.getresponse()
2277     if resp.status != 400:
2278         raise Exception("Unexpected HTTP response: %d" % resp.status)
2279
2280     logger.debug("Valid subscription")
2281     headers = { "callback": '<http://127.0.0.1:12345/event>',
2282                 "NT": "upnp:event",
2283                 "timeout": "Second-1234" }
2284     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2285     resp = conn.getresponse()
2286     if resp.status != 200:
2287         raise Exception("Unexpected HTTP response: %d" % resp.status)
2288     sid = resp.getheader("sid")
2289     logger.debug("Subscription SID " + sid)
2290
2291     logger.debug("Invalid re-subscription")
2292     headers = { "NT": "upnp:event",
2293                 "sid": "123456734567854",
2294                 "timeout": "Second-1234" }
2295     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2296     resp = conn.getresponse()
2297     if resp.status != 400:
2298         raise Exception("Unexpected HTTP response: %d" % resp.status)
2299
2300     logger.debug("Invalid re-subscription")
2301     headers = { "NT": "upnp:event",
2302                 "sid": "uuid:123456734567854",
2303                 "timeout": "Second-1234" }
2304     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2305     resp = conn.getresponse()
2306     if resp.status != 400:
2307         raise Exception("Unexpected HTTP response: %d" % resp.status)
2308
2309     logger.debug("Invalid re-subscription")
2310     headers = { "callback": '<http://127.0.0.1:12345/event>',
2311                 "NT": "upnp:event",
2312                 "sid": sid,
2313                 "timeout": "Second-1234" }
2314     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2315     resp = conn.getresponse()
2316     if resp.status != 400:
2317         raise Exception("Unexpected HTTP response: %d" % resp.status)
2318
2319     logger.debug("SID mismatch in re-subscription")
2320     headers = { "NT": "upnp:event",
2321                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2322                 "timeout": "Second-1234" }
2323     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2324     resp = conn.getresponse()
2325     if resp.status != 412:
2326         raise Exception("Unexpected HTTP response: %d" % resp.status)
2327
2328     logger.debug("Valid re-subscription")
2329     headers = { "NT": "upnp:event",
2330                 "sid": sid,
2331                 "timeout": "Second-1234" }
2332     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2333     resp = conn.getresponse()
2334     if resp.status != 200:
2335         raise Exception("Unexpected HTTP response: %d" % resp.status)
2336     sid2 = resp.getheader("sid")
2337     logger.debug("Subscription SID " + sid2)
2338
2339     if sid != sid2:
2340         raise Exception("Unexpected SID change")
2341
2342     logger.debug("Valid re-subscription")
2343     headers = { "NT": "upnp:event",
2344                 "sid": "uuid: \t \t" + sid.split(':')[1],
2345                 "timeout": "Second-1234" }
2346     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2347     resp = conn.getresponse()
2348     if resp.status != 200:
2349         raise Exception("Unexpected HTTP response: %d" % resp.status)
2350
2351     logger.debug("Invalid unsubscription")
2352     headers = { "sid": sid }
2353     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2354     resp = conn.getresponse()
2355     if resp.status != 412:
2356         raise Exception("Unexpected HTTP response: %d" % resp.status)
2357     headers = { "foo": "bar" }
2358     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2359     resp = conn.getresponse()
2360     if resp.status != 412:
2361         raise Exception("Unexpected HTTP response: %d" % resp.status)
2362
2363     logger.debug("Valid unsubscription")
2364     headers = { "sid": sid }
2365     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2366     resp = conn.getresponse()
2367     if resp.status != 200:
2368         raise Exception("Unexpected HTTP response: %d" % resp.status)
2369
2370     logger.debug("Unsubscription for not existing SID")
2371     headers = { "sid": sid }
2372     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2373     resp = conn.getresponse()
2374     if resp.status != 412:
2375         raise Exception("Unexpected HTTP response: %d" % resp.status)
2376
2377     logger.debug("Invalid unsubscription")
2378     headers = { "sid": " \t \tfoo" }
2379     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2380     resp = conn.getresponse()
2381     if resp.status != 400:
2382         raise Exception("Unexpected HTTP response: %d" % resp.status)
2383
2384     logger.debug("Invalid unsubscription")
2385     headers = { "sid": "uuid:\t \tfoo" }
2386     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2387     resp = conn.getresponse()
2388     if resp.status != 400:
2389         raise Exception("Unexpected HTTP response: %d" % resp.status)
2390
2391     logger.debug("Invalid unsubscription")
2392     headers = { "NT": "upnp:event",
2393                 "sid": sid }
2394     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2395     resp = conn.getresponse()
2396     if resp.status != 400:
2397         raise Exception("Unexpected HTTP response: %d" % resp.status)
2398     headers = { "callback": '<http://127.0.0.1:12345/event>',
2399                 "sid": sid }
2400     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2401     resp = conn.getresponse()
2402     if resp.status != 400:
2403         raise Exception("Unexpected HTTP response: %d" % resp.status)
2404
2405     logger.debug("Valid subscription with multiple callbacks")
2406     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>',
2407                 "NT": "upnp:event",
2408                 "timeout": "Second-1234" }
2409     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2410     resp = conn.getresponse()
2411     if resp.status != 200:
2412         raise Exception("Unexpected HTTP response: %d" % resp.status)
2413     sid = resp.getheader("sid")
2414     logger.debug("Subscription SID " + sid)
2415
2416 def test_ap_wps_upnp_http_proto(dev, apdev):
2417     """WPS AP and UPnP/HTTP protocol testing"""
2418     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2419     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2420
2421     location = ssdp_get_location(ap_uuid)
2422
2423     url = urlparse.urlparse(location)
2424     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
2425     #conn.set_debuglevel(1)
2426
2427     conn.request("HEAD", "hello")
2428     resp = conn.getresponse()
2429     if resp.status != 501:
2430         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2431     conn.close()
2432
2433     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
2434         try:
2435             conn.request(cmd, "hello")
2436             resp = conn.getresponse()
2437         except Exception, e:
2438             pass
2439         conn.close()
2440
2441     headers = { "Content-Length": 'abc' }
2442     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2443     try:
2444         resp = conn.getresponse()
2445     except Exception, e:
2446         pass
2447     conn.close()
2448
2449     headers = { "Content-Length": '-10' }
2450     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2451     try:
2452         resp = conn.getresponse()
2453     except Exception, e:
2454         pass
2455     conn.close()
2456
2457     headers = { "Content-Length": '10000000000000' }
2458     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
2459     try:
2460         resp = conn.getresponse()
2461     except Exception, e:
2462         pass
2463     conn.close()
2464
2465     headers = { "Transfer-Encoding": 'abc' }
2466     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2467     resp = conn.getresponse()
2468     if resp.status != 501:
2469         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2470     conn.close()
2471
2472     headers = { "Transfer-Encoding": 'chunked' }
2473     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2474     resp = conn.getresponse()
2475     if resp.status != 501:
2476         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2477     conn.close()
2478
2479     # Too long a header
2480     conn.request("HEAD", 5000 * 'A')
2481     try:
2482         resp = conn.getresponse()
2483     except Exception, e:
2484         pass
2485     conn.close()
2486
2487     # Long URL but within header length limits
2488     conn.request("HEAD", 3000 * 'A')
2489     resp = conn.getresponse()
2490     if resp.status != 501:
2491         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2492     conn.close()
2493
2494     headers = { "Content-Length": '20' }
2495     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
2496     try:
2497         resp = conn.getresponse()
2498     except Exception, e:
2499         pass
2500     conn.close()
2501
2502     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
2503     resp = conn.getresponse()
2504     if resp.status != 404:
2505         raise Exception("Unexpected HTTP response: %d" % resp.status)
2506     conn.close()
2507
2508     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
2509     try:
2510         resp = conn.getresponse()
2511     except Exception, e:
2512         pass
2513     conn.close()
2514
2515 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
2516     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
2517     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2518     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2519
2520     location = ssdp_get_location(ap_uuid)
2521
2522     url = urlparse.urlparse(location)
2523     conn = httplib.HTTPConnection(url.netloc)
2524     #conn.set_debuglevel(1)
2525
2526     headers = { "Transfer-Encoding": 'chunked' }
2527     conn.request("POST", "hello",
2528                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
2529                  headers)
2530     resp = conn.getresponse()
2531     if resp.status != 404:
2532         raise Exception("Unexpected HTTP response: %d" % resp.status)
2533     conn.close()
2534
2535     conn.putrequest("POST", "hello")
2536     conn.putheader('Transfer-Encoding', 'chunked')
2537     conn.endheaders()
2538     conn.send("a\r\nabcdefghij\r\n")
2539     time.sleep(0.1)
2540     conn.send("2\r\nkl\r\n")
2541     conn.send("0\r\n\r\n")
2542     resp = conn.getresponse()
2543     if resp.status != 404:
2544         raise Exception("Unexpected HTTP response: %d" % resp.status)
2545     conn.close()
2546
2547     conn.putrequest("POST", "hello")
2548     conn.putheader('Transfer-Encoding', 'chunked')
2549     conn.endheaders()
2550     completed = False
2551     try:
2552         for i in range(20000):
2553             conn.send("1\r\nZ\r\n")
2554         conn.send("0\r\n\r\n")
2555         resp = conn.getresponse()
2556         completed = True
2557     except Exception, e:
2558         pass
2559     conn.close()
2560     if completed:
2561         raise Exception("Too long chunked request did not result in connection reset")
2562
2563     headers = { "Transfer-Encoding": 'chunked' }
2564     conn.request("POST", "hello", "80000000\r\na", headers)
2565     try:
2566         resp = conn.getresponse()
2567     except Exception, e:
2568         pass
2569     conn.close()
2570
2571     conn.request("POST", "hello", "10000000\r\na", headers)
2572     try:
2573         resp = conn.getresponse()
2574     except Exception, e:
2575         pass
2576     conn.close()
2577
2578 def test_ap_wps_disabled(dev, apdev):
2579     """WPS operations while WPS is disabled"""
2580     ssid = "test-wps-disabled"
2581     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
2582     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2583     if "FAIL" not in hapd.request("WPS_PBC"):
2584         raise Exception("WPS_PBC succeeded unexpectedly")
2585     if "FAIL" not in hapd.request("WPS_CANCEL"):
2586         raise Exception("WPS_CANCEL succeeded unexpectedly")
2587
2588 def test_ap_wps_mixed_cred(dev, apdev):
2589     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
2590     ssid = "test-wps-wep"
2591     hostapd.add_ap(apdev[0]['ifname'],
2592                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2593                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
2594     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2595     hapd.request("WPS_PBC")
2596     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2597     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2598     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
2599     if ev is None:
2600         raise Exception("WPS-SUCCESS event timed out")
2601     nets = dev[0].list_networks()
2602     if len(nets) != 1:
2603         raise Exception("Unexpected number of network blocks")
2604     id = nets[0]['id']
2605     proto = dev[0].get_network(id, "proto")
2606     if proto != "WPA RSN":
2607         raise Exception("Unexpected merged proto field value: " + proto)
2608     pairwise = dev[0].get_network(id, "pairwise")
2609     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
2610         raise Exception("Unexpected merged pairwise field value: " + pairwise)
2611
2612 def test_ap_wps_while_connected(dev, apdev):
2613     """WPS PBC provisioning while connected to another AP"""
2614     ssid = "test-wps-conf"
2615     hostapd.add_ap(apdev[0]['ifname'],
2616                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2617                      "wpa_passphrase": "12345678", "wpa": "2",
2618                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2619     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2620
2621     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2622     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2623
2624     logger.info("WPS provisioning step")
2625     hapd.request("WPS_PBC")
2626     dev[0].dump_monitor()
2627     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2628     dev[0].wait_connected(timeout=30)
2629     status = dev[0].get_status()
2630     if status['bssid'] != apdev[0]['bssid']:
2631         raise Exception("Unexpected BSSID")
2632
2633 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
2634     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
2635     ssid = "test-wps-conf"
2636     hostapd.add_ap(apdev[0]['ifname'],
2637                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2638                      "wpa_passphrase": "12345678", "wpa": "2",
2639                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2640     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2641
2642     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2643
2644     try:
2645         dev[0].request("STA_AUTOCONNECT 0")
2646         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2647
2648         logger.info("WPS provisioning step")
2649         hapd.request("WPS_PBC")
2650         dev[0].dump_monitor()
2651         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2652         dev[0].wait_connected(timeout=30)
2653         status = dev[0].get_status()
2654         if status['bssid'] != apdev[0]['bssid']:
2655             raise Exception("Unexpected BSSID")
2656     finally:
2657         dev[0].request("STA_AUTOCONNECT 1")
2658
2659 def test_ap_wps_from_event(dev, apdev):
2660     """WPS PBC event on AP to enable PBC"""
2661     ssid = "test-wps-conf"
2662     hapd = hostapd.add_ap(apdev[0]['ifname'],
2663                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2664                             "wpa_passphrase": "12345678", "wpa": "2",
2665                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2666     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2667     dev[0].dump_monitor()
2668     hapd.dump_monitor()
2669     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2670
2671     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
2672     if ev is None:
2673         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
2674     vals = ev.split(' ')
2675     if vals[1] != dev[0].p2p_interface_addr():
2676         raise Exception("Unexpected enrollee address: " + vals[1])
2677     if vals[5] != '4':
2678         raise Exception("Unexpected Device Password Id: " + vals[5])
2679     hapd.request("WPS_PBC")
2680     dev[0].wait_connected(timeout=30)
2681
2682 def test_ap_wps_ap_scan_2(dev, apdev):
2683     """AP_SCAN 2 for WPS"""
2684     ssid = "test-wps-conf"
2685     hapd = hostapd.add_ap(apdev[0]['ifname'],
2686                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2687                             "wpa_passphrase": "12345678", "wpa": "2",
2688                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2689     hapd.request("WPS_PBC")
2690
2691     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2692     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
2693
2694     if "OK" not in wpas.request("AP_SCAN 2"):
2695         raise Exception("Failed to set AP_SCAN 2")
2696
2697     wpas.flush_scan_cache()
2698     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
2699     wpas.request("WPS_PBC " + apdev[0]['bssid'])
2700     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
2701     if ev is None:
2702         raise Exception("WPS-SUCCESS event timed out")
2703     wpas.wait_connected(timeout=30)
2704     wpas.request("DISCONNECT")
2705     wpas.request("BSS_FLUSH 0")
2706     wpas.dump_monitor()
2707     wpas.request("REASSOCIATE")
2708     wpas.wait_connected(timeout=30)
2709
2710 def test_ap_wps_eapol_workaround(dev, apdev):
2711     """EAPOL workaround code path for 802.1X header length mismatch"""
2712     ssid = "test-wps"
2713     hostapd.add_ap(apdev[0]['ifname'],
2714                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
2715     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2716     bssid = apdev[0]['bssid']
2717     hapd.request("SET ext_eapol_frame_io 1")
2718     dev[0].request("SET ext_eapol_frame_io 1")
2719     hapd.request("WPS_PBC")
2720     dev[0].request("WPS_PBC")
2721
2722     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2723     if ev is None:
2724         raise Exception("Timeout on EAPOL-TX from hostapd")
2725
2726     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
2727     if "OK" not in res:
2728         raise Exception("EAPOL_RX to wpa_supplicant failed")
2729
2730 def test_ap_wps_iteration(dev, apdev):
2731     """WPS PIN and iterate through APs without selected registrar"""
2732     ssid = "test-wps-conf"
2733     hapd = hostapd.add_ap(apdev[0]['ifname'],
2734                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2735                             "wpa_passphrase": "12345678", "wpa": "2",
2736                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2737
2738     ssid2 = "test-wps-conf2"
2739     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
2740                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
2741                              "wpa_passphrase": "12345678", "wpa": "2",
2742                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2743
2744     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2745     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
2746     dev[0].dump_monitor()
2747     pin = dev[0].request("WPS_PIN any")
2748
2749     # Wait for iteration through all WPS APs to happen before enabling any
2750     # Registrar.
2751     for i in range(2):
2752         ev = dev[0].wait_event(["Associated with"], timeout=30)
2753         if ev is None:
2754             raise Exception("No association seen")
2755         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
2756         if ev is None:
2757             raise Exception("No M2D from AP")
2758         dev[0].wait_disconnected()
2759
2760     # Verify that each AP requested PIN
2761     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
2762     if ev is None:
2763         raise Exception("No WPS-PIN-NEEDED event from AP")
2764     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
2765     if ev is None:
2766         raise Exception("No WPS-PIN-NEEDED event from AP2")
2767
2768     # Provide PIN to one of the APs and verify that connection gets formed
2769     hapd.request("WPS_PIN any " + pin)
2770     dev[0].wait_connected(timeout=30)
2771
2772 def test_ap_wps_iteration_error(dev, apdev):
2773     """WPS AP iteration on no Selected Registrar and error case with an AP"""
2774     ssid = "test-wps-conf-pin"
2775     hapd = hostapd.add_ap(apdev[0]['ifname'],
2776                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2777                             "wpa_passphrase": "12345678", "wpa": "2",
2778                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2779                             "wps_independent": "1" })
2780     hapd.request("SET ext_eapol_frame_io 1")
2781     bssid = apdev[0]['bssid']
2782     pin = dev[0].wps_read_pin()
2783     dev[0].request("WPS_PIN any " + pin)
2784
2785     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2786     if ev is None:
2787         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
2788     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
2789
2790     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2791     if ev is None:
2792         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
2793     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
2794     if ev is None:
2795         raise Exception("No CTRL-EVENT-EAP-STARTED")
2796
2797     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
2798     # a case with an incorrectly behaving WPS AP.
2799
2800     # Start the real target AP and activate registrar on it.
2801     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
2802                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2803                             "wpa_passphrase": "12345678", "wpa": "2",
2804                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2805                             "wps_independent": "1" })
2806     hapd2.request("WPS_PIN any " + pin)
2807
2808     dev[0].wait_disconnected(timeout=15)
2809     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
2810     if ev is None:
2811         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
2812     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
2813     if ev is None:
2814         raise Exception("No WPS-CRED-RECEIVED for the second AP")
2815     dev[0].wait_connected(timeout=15)
2816
2817 def test_ap_wps_priority(dev, apdev):
2818     """WPS PIN provisioning with configured AP and wps_priority"""
2819     ssid = "test-wps-conf-pin"
2820     hostapd.add_ap(apdev[0]['ifname'],
2821                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2822                      "wpa_passphrase": "12345678", "wpa": "2",
2823                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2824     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2825     logger.info("WPS provisioning step")
2826     pin = dev[0].wps_read_pin()
2827     hapd.request("WPS_PIN any " + pin)
2828     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2829     dev[0].dump_monitor()
2830     try:
2831         dev[0].request("SET wps_priority 6")
2832         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2833         dev[0].wait_connected(timeout=30)
2834         netw = dev[0].list_networks()
2835         prio = dev[0].get_network(netw[0]['id'], 'priority')
2836         if prio != '6':
2837             raise Exception("Unexpected network priority: " + prio)
2838     finally:
2839         dev[0].request("SET wps_priority 0")
2840
2841 def test_ap_wps_and_non_wps(dev, apdev):
2842     """WPS and non-WPS AP in single hostapd process"""
2843     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
2844     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2845
2846     params = { "ssid": "no wps" }
2847     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
2848
2849     appin = hapd.request("WPS_AP_PIN random")
2850     if "FAIL" in appin:
2851         raise Exception("Could not generate random AP PIN")
2852     if appin not in hapd.request("WPS_AP_PIN get"):
2853         raise Exception("Could not fetch current AP PIN")
2854
2855     if "FAIL" in hapd.request("WPS_PBC"):
2856         raise Exception("WPS_PBC failed")
2857     if "FAIL" in hapd.request("WPS_CANCEL"):
2858         raise Exception("WPS_CANCEL failed")
2859
2860 def test_ap_wps_init_oom(dev, apdev):
2861     """Initial AP configuration and OOM during PSK generation"""
2862     ssid = "test-wps"
2863     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
2864     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2865
2866     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
2867         pin = dev[0].wps_read_pin()
2868         hapd.request("WPS_PIN any " + pin)
2869         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2870         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2871         dev[0].wait_disconnected()
2872
2873     hapd.request("WPS_PIN any " + pin)
2874     dev[0].wait_connected(timeout=30)
2875
2876 def test_ap_wps_er_oom(dev, apdev):
2877     """WPS ER OOM in XML processing"""
2878     try:
2879         _test_ap_wps_er_oom(dev, apdev)
2880     finally:
2881         dev[0].request("WPS_ER_STOP")
2882         dev[1].request("WPS_CANCEL")
2883         dev[0].request("DISCONNECT")
2884
2885 def _test_ap_wps_er_oom(dev, apdev):
2886     ssid = "wps-er-ap-config"
2887     ap_pin = "12345670"
2888     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2889     hostapd.add_ap(apdev[0]['ifname'],
2890                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2891                      "wpa_passphrase": "12345678", "wpa": "2",
2892                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2893                      "device_name": "Wireless AP", "manufacturer": "Company",
2894                      "model_name": "WAP", "model_number": "123",
2895                      "serial_number": "12345", "device_type": "6-0050F204-1",
2896                      "os_version": "01020300",
2897                      "config_methods": "label push_button",
2898                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
2899
2900     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
2901
2902     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
2903         dev[0].request("WPS_ER_START ifname=lo")
2904         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
2905         if ev is not None:
2906             raise Exception("Unexpected AP discovery")
2907
2908     dev[0].request("WPS_ER_STOP")
2909     dev[0].request("WPS_ER_START ifname=lo")
2910     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
2911     if ev is None:
2912         raise Exception("AP discovery timed out")
2913
2914     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2915     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
2916         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2917         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
2918         if ev is None:
2919             raise Exception("PBC scan failed")
2920         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
2921         if ev is None:
2922             raise Exception("Enrollee discovery timed out")
2923
2924 def test_ap_wps_er_init_oom(dev, apdev):
2925     """WPS ER and OOM during init"""
2926     try:
2927         _test_ap_wps_er_init_oom(dev, apdev)
2928     finally:
2929         dev[0].request("WPS_ER_STOP")
2930
2931 def _test_ap_wps_er_init_oom(dev, apdev):
2932     with alloc_fail(dev[0], 1, "wps_er_init"):
2933         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
2934             raise Exception("WPS_ER_START succeeded during OOM")
2935     with alloc_fail(dev[0], 1, "http_server_init"):
2936         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
2937             raise Exception("WPS_ER_START succeeded during OOM")
2938     with alloc_fail(dev[0], 2, "http_server_init"):
2939         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
2940             raise Exception("WPS_ER_START succeeded during OOM")
2941     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
2942         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
2943             raise Exception("WPS_ER_START succeeded during OOM")
2944     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
2945         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
2946             raise Exception("WPS_ER_START succeeded during os_get_random failure")
2947
2948 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
2949     """WPS events and wpa_cli action script"""
2950     logdir = os.path.abspath(test_params['logdir'])
2951     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
2952     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
2953     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
2954
2955     with open(actionfile, 'w') as f:
2956         f.write('#!/bin/sh\n')
2957         f.write('echo $* >> %s\n' % logfile)
2958         # Kill the process and wait some time before returning to allow all the
2959         # pending events to be processed with some of this happening after the
2960         # eloop SIGALRM signal has been scheduled.
2961         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
2962
2963     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
2964              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
2965
2966     ssid = "test-wps-conf"
2967     hostapd.add_ap(apdev[0]['ifname'],
2968                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2969                      "wpa_passphrase": "12345678", "wpa": "2",
2970                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2971     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2972
2973     prg = os.path.join(test_params['logdir'],
2974                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
2975     if not os.path.exists(prg):
2976         prg = '../../wpa_supplicant/wpa_cli'
2977     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
2978     subprocess.call(arg)
2979
2980     arg = [ 'ps', 'ax' ]
2981     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
2982     out = cmd.communicate()[0]
2983     cmd.wait()
2984     logger.debug("Processes:\n" + out)
2985     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
2986         raise Exception("Did not see wpa_cli running")
2987
2988     hapd.request("WPS_PIN any 12345670")
2989     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2990     dev[0].dump_monitor()
2991     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2992     dev[0].wait_connected(timeout=30)
2993
2994     for i in range(30):
2995         if not os.path.exists(pidfile):
2996             break
2997         time.sleep(0.1)
2998
2999     if not os.path.exists(logfile):
3000         raise Exception("wpa_cli action results file not found")
3001     with open(logfile, 'r') as f:
3002         res = f.read()
3003     if "WPS-SUCCESS" not in res:
3004         raise Exception("WPS-SUCCESS event not seen in action file")
3005
3006     arg = [ 'ps', 'ax' ]
3007     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3008     out = cmd.communicate()[0]
3009     cmd.wait()
3010     logger.debug("Remaining processes:\n" + out)
3011     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3012         raise Exception("wpa_cli still running")
3013
3014     if os.path.exists(pidfile):
3015         raise Exception("PID file not removed")
3016
3017 def test_ap_wps_er_ssdp_proto(dev, apdev):
3018     """WPS ER SSDP protocol testing"""
3019     try:
3020         _test_ap_wps_er_ssdp_proto(dev, apdev)
3021     finally:
3022         dev[0].request("WPS_ER_STOP")
3023
3024 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3025     socket.setdefaulttimeout(1)
3026     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3027     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3028     sock.bind(("239.255.255.250", 1900))
3029     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3030         raise Exception("Invalid filter accepted")
3031     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3032         raise Exception("WPS_ER_START with filter failed")
3033     (msg,addr) = sock.recvfrom(1000)
3034     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3035     if "M-SEARCH" not in msg:
3036         raise Exception("Not an M-SEARCH")
3037     sock.sendto("FOO", addr)
3038     time.sleep(0.1)
3039     dev[0].request("WPS_ER_STOP")
3040
3041     dev[0].request("WPS_ER_START ifname=lo")
3042     (msg,addr) = sock.recvfrom(1000)
3043     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3044     if "M-SEARCH" not in msg:
3045         raise Exception("Not an M-SEARCH")
3046     sock.sendto("FOO", addr)
3047     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3048     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3049     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3050     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3051     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3052     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3053     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3054     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3055     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3056     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3057     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3058     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3059     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3060     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3061         sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3062         time.sleep(0.1)
3063     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3064         sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3065         time.sleep(0.1)
3066
3067     # Add an AP with bogus URL
3068     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3069     # Update timeout on AP without updating URL
3070     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
3071     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3072     if ev is None:
3073         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3074
3075     # Add an AP with a valid URL (but no server listing to it)
3076     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
3077     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3078     if ev is None:
3079         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3080
3081     sock.close()
3082
3083 wps_event_url = None
3084
3085 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3086                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3087     payload = '''<?xml version="1.0"?>
3088 <root xmlns="urn:schemas-upnp-org:device-1-0">
3089 <specVersion>
3090 <major>1</major>
3091 <minor>0</minor>
3092 </specVersion>
3093 <device>
3094 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3095 <friendlyName>WPS Access Point</friendlyName>
3096 <manufacturer>Company</manufacturer>
3097 <modelName>WAP</modelName>
3098 <modelNumber>123</modelNumber>
3099 <serialNumber>12345</serialNumber>
3100 '''
3101     if udn:
3102         payload += '<UDN>' + udn + '</UDN>'
3103     payload += '''<serviceList>
3104 <service>
3105 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3106 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3107 <SCPDURL>wps_scpd.xml</SCPDURL>
3108 '''
3109     if controlURL:
3110         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3111     if eventSubURL:
3112         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3113     payload += '''</service>
3114 </serviceList>
3115 </device>
3116 </root>
3117 '''
3118     hdr = 'HTTP/1.1 200 OK\r\n' + \
3119           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3120           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3121           'Connection: close\r\n' + \
3122           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3123           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3124     return hdr + payload
3125
3126 def gen_wps_control(payload_override=None):
3127     payload = '''<?xml version="1.0"?>
3128 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3129 <s:Body>
3130 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3131 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3132 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3133 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3134 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3135 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3136 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3137 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3138 AAYANyoAASA=
3139 </NewDeviceInfo>
3140 </u:GetDeviceInfoResponse>
3141 </s:Body>
3142 </s:Envelope>
3143 '''
3144     if payload_override:
3145         payload = payload_override
3146     hdr = 'HTTP/1.1 200 OK\r\n' + \
3147           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3148           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3149           'Connection: close\r\n' + \
3150           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3151           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3152     return hdr + payload
3153
3154 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3155     payload = ""
3156     hdr = 'HTTP/1.1 200 OK\r\n' + \
3157           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3158           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3159           'Connection: close\r\n' + \
3160           'Content-Length: ' + str(len(payload)) + '\r\n'
3161     if sid:
3162         hdr += 'SID: ' + sid + '\r\n'
3163     hdr += 'Timeout: Second-1801\r\n' + \
3164           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3165     return hdr + payload
3166
3167 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3168     def handle(self):
3169         data = self.rfile.readline().strip()
3170         logger.info("HTTP server received: " + data)
3171         while True:
3172             hdr = self.rfile.readline().strip()
3173             if len(hdr) == 0:
3174                 break
3175             logger.info("HTTP header: " + hdr)
3176             if "CALLBACK:" in hdr:
3177                 global wps_event_url
3178                 wps_event_url = hdr.split(' ')[1].strip('<>')
3179
3180         if "GET /foo.xml" in data:
3181             self.handle_upnp_info()
3182         elif "POST /wps_control" in data:
3183             self.handle_wps_control()
3184         elif "SUBSCRIBE /wps_event" in data:
3185             self.handle_wps_event()
3186
3187     def handle_upnp_info(self):
3188         self.wfile.write(gen_upnp_info())
3189
3190     def handle_wps_control(self):
3191         self.wfile.write(gen_wps_control())
3192
3193     def handle_wps_event(self):
3194         self.wfile.write(gen_wps_event())
3195
3196 class MyTCPServer(SocketServer.TCPServer):
3197     def __init__(self, addr, handler):
3198         self.allow_reuse_address = True
3199         SocketServer.TCPServer.__init__(self, addr, handler)
3200
3201 def wps_er_start(dev, http_server, max_age=1):
3202     socket.setdefaulttimeout(1)
3203     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3204     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3205     sock.bind(("239.255.255.250", 1900))
3206     dev.request("WPS_ER_START ifname=lo")
3207     (msg,addr) = sock.recvfrom(1000)
3208     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3209     if "M-SEARCH" not in msg:
3210         raise Exception("Not an M-SEARCH")
3211
3212     # Add an AP with a valid URL and server listing to it
3213     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3214     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=%d\r\n\r\n" % max_age, addr)
3215     server.timeout = 1
3216     return server,sock
3217
3218 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3219     sock.close()
3220     server.server_close()
3221
3222     if on_alloc_fail:
3223         done = False
3224         for i in range(50):
3225             res = dev.request("GET_ALLOC_FAIL")
3226             if res.startswith("0:"):
3227                 done = True
3228                 break
3229             time.sleep(0.1)
3230         if not done:
3231             raise Exception("No allocation failure reported")
3232     else:
3233         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3234         if ev is None:
3235             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3236     dev.request("WPS_ER_STOP")
3237
3238 def run_wps_er_proto_test(dev, handler, no_event_url=False):
3239     try:
3240         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3241         server,sock = wps_er_start(dev, handler)
3242         global wps_event_url
3243         wps_event_url = None
3244         server.handle_request()
3245         server.handle_request()
3246         server.handle_request()
3247         server.server_close()
3248         if no_event_url:
3249             if wps_event_url:
3250                 raise Exception("Received event URL unexpectedly")
3251             return
3252         if wps_event_url is None:
3253             raise Exception("Did not get event URL")
3254         logger.info("Event URL: " + wps_event_url)
3255     finally:
3256         dev.request("WPS_ER_STOP")
3257
3258 def send_wlanevent(url, uuid, data):
3259     conn = httplib.HTTPConnection(url.netloc)
3260     payload = '''<?xml version="1.0" encoding="utf-8"?>
3261 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3262 <e:property><STAStatus>1</STAStatus></e:property>
3263 <e:property><APStatus>1</APStatus></e:property>
3264 <e:property><WLANEvent>'''
3265     payload += base64.b64encode(data)
3266     payload += '</WLANEvent></e:property></e:propertyset>'
3267     headers = { "Content-type": 'text/xml; charset="utf-8"',
3268                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3269                 "HOST": url.netloc,
3270                 "NT": "upnp:event",
3271                 "SID": "uuid:" + uuid,
3272                 "SEQ": "0",
3273                 "Content-Length": str(len(payload)) }
3274     conn.request("NOTIFY", url.path, payload, headers)
3275     resp = conn.getresponse()
3276     if resp.status != 200:
3277         raise Exception("Unexpected HTTP response: %d" % resp.status)
3278
3279 def test_ap_wps_er_http_proto(dev, apdev):
3280     """WPS ER HTTP protocol testing"""
3281     try:
3282         _test_ap_wps_er_http_proto(dev, apdev)
3283     finally:
3284         dev[0].request("WPS_ER_STOP")
3285
3286 def _test_ap_wps_er_http_proto(dev, apdev):
3287     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3288     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
3289     global wps_event_url
3290     wps_event_url = None
3291     server.handle_request()
3292     server.handle_request()
3293     server.handle_request()
3294     server.server_close()
3295     if wps_event_url is None:
3296         raise Exception("Did not get event URL")
3297     logger.info("Event URL: " + wps_event_url)
3298
3299     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3300     if ev is None:
3301         raise Exception("No WPS-ER-AP-ADD event")
3302     if uuid not in ev:
3303         raise Exception("UUID mismatch")
3304
3305     sock.close()
3306
3307     logger.info("Valid Probe Request notification")
3308     url = urlparse.urlparse(wps_event_url)
3309     conn = httplib.HTTPConnection(url.netloc)
3310     payload = '''<?xml version="1.0" encoding="utf-8"?>
3311 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3312 <e:property><STAStatus>1</STAStatus></e:property>
3313 <e:property><APStatus>1</APStatus></e:property>
3314 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
3315 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
3316 RGV2aWNlIEEQSQAGADcqAAEg
3317 </WLANEvent></e:property>
3318 </e:propertyset>
3319 '''
3320     headers = { "Content-type": 'text/xml; charset="utf-8"',
3321                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3322                 "HOST": url.netloc,
3323                 "NT": "upnp:event",
3324                 "SID": "uuid:" + uuid,
3325                 "SEQ": "0",
3326                 "Content-Length": str(len(payload)) }
3327     conn.request("NOTIFY", url.path, payload, headers)
3328     resp = conn.getresponse()
3329     if resp.status != 200:
3330         raise Exception("Unexpected HTTP response: %d" % resp.status)
3331
3332     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
3333     if ev is None:
3334         raise Exception("No WPS-ER-ENROLLEE-ADD event")
3335     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
3336         raise Exception("No Enrollee UUID match")
3337
3338     logger.info("Incorrect event URL AP id")
3339     conn = httplib.HTTPConnection(url.netloc)
3340     conn.request("NOTIFY", url.path + '123', payload, headers)
3341     resp = conn.getresponse()
3342     if resp.status != 404:
3343         raise Exception("Unexpected HTTP response: %d" % resp.status)
3344
3345     logger.info("Missing AP id")
3346     conn = httplib.HTTPConnection(url.netloc)
3347     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
3348                  payload, headers)
3349     time.sleep(0.1)
3350
3351     logger.info("Incorrect event URL event id")
3352     conn = httplib.HTTPConnection(url.netloc)
3353     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
3354     time.sleep(0.1)
3355
3356     logger.info("Incorrect event URL prefix")
3357     conn = httplib.HTTPConnection(url.netloc)
3358     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
3359     resp = conn.getresponse()
3360     if resp.status != 404:
3361         raise Exception("Unexpected HTTP response: %d" % resp.status)
3362
3363     logger.info("Unsupported request")
3364     conn = httplib.HTTPConnection(url.netloc)
3365     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
3366     resp = conn.getresponse()
3367     if resp.status != 501:
3368         raise Exception("Unexpected HTTP response: %d" % resp.status)
3369
3370     logger.info("Unsupported request and OOM")
3371     with alloc_fail(dev[0], 1, "wps_er_http_req"):
3372         conn = httplib.HTTPConnection(url.netloc)
3373         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
3374         time.sleep(0.5)
3375
3376     logger.info("Too short WLANEvent")
3377     data = '\x00'
3378     send_wlanevent(url, uuid, data)
3379
3380     logger.info("Invalid WLANEventMAC")
3381     data = '\x00qwertyuiopasdfghjklzxcvbnm'
3382     send_wlanevent(url, uuid, data)
3383
3384     logger.info("Unknown WLANEventType")
3385     data = '\xff02:00:00:00:00:00'
3386     send_wlanevent(url, uuid, data)
3387
3388     logger.info("Probe Request notification without any attributes")
3389     data = '\x0102:00:00:00:00:00'
3390     send_wlanevent(url, uuid, data)
3391
3392     logger.info("Probe Request notification with invalid attribute")
3393     data = '\x0102:00:00:00:00:00\xff'
3394     send_wlanevent(url, uuid, data)
3395
3396     logger.info("EAP message without any attributes")
3397     data = '\x0202:00:00:00:00:00'
3398     send_wlanevent(url, uuid, data)
3399
3400     logger.info("EAP message with invalid attribute")
3401     data = '\x0202:00:00:00:00:00\xff'
3402     send_wlanevent(url, uuid, data)
3403
3404     logger.info("EAP message from new STA and not M1")
3405     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
3406     send_wlanevent(url, uuid, data)
3407
3408     logger.info("EAP message: M1")
3409     data = '\x0202:00:00:00:00:00'
3410     data += '\x10\x22\x00\x01\x04'
3411     data += '\x10\x47\x00\x10' + 16*'\x00'
3412     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
3413     data += '\x10\x1a\x00\x10' + 16*'\x00'
3414     data += '\x10\x32\x00\xc0' + 192*'\x00'
3415     data += '\x10\x04\x00\x02\x00\x00'
3416     data += '\x10\x10\x00\x02\x00\x00'
3417     data += '\x10\x0d\x00\x01\x00'
3418     data += '\x10\x08\x00\x02\x00\x00'
3419     data += '\x10\x44\x00\x01\x00'
3420     data += '\x10\x21\x00\x00'
3421     data += '\x10\x23\x00\x00'
3422     data += '\x10\x24\x00\x00'
3423     data += '\x10\x42\x00\x00'
3424     data += '\x10\x54\x00\x08' + 8*'\x00'
3425     data += '\x10\x11\x00\x00'
3426     data += '\x10\x3c\x00\x01\x00'
3427     data += '\x10\x02\x00\x02\x00\x00'
3428     data += '\x10\x12\x00\x02\x00\x00'
3429     data += '\x10\x09\x00\x02\x00\x00'
3430     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
3431     m1 = data
3432     send_wlanevent(url, uuid, data)
3433
3434     logger.info("EAP message: WSC_ACK")
3435     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
3436     send_wlanevent(url, uuid, data)
3437
3438     logger.info("EAP message: M1")
3439     send_wlanevent(url, uuid, m1)
3440
3441     logger.info("EAP message: WSC_NACK")
3442     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
3443     send_wlanevent(url, uuid, data)
3444
3445     logger.info("EAP message: M1 - Too long attribute values")
3446     data = '\x0202:00:00:00:00:00'
3447     data += '\x10\x11\x00\x21' + 33*'\x00'
3448     data += '\x10\x45\x00\x21' + 33*'\x00'
3449     data += '\x10\x42\x00\x21' + 33*'\x00'
3450     data += '\x10\x24\x00\x21' + 33*'\x00'
3451     data += '\x10\x23\x00\x21' + 33*'\x00'
3452     data += '\x10\x21\x00\x41' + 65*'\x00'
3453     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
3454     send_wlanevent(url, uuid, data)
3455
3456     logger.info("EAP message: M1 missing UUID-E")
3457     data = '\x0202:00:00:00:00:00'
3458     data += '\x10\x22\x00\x01\x04'
3459     send_wlanevent(url, uuid, data)
3460
3461     logger.info("EAP message: M1 missing MAC Address")
3462     data += '\x10\x47\x00\x10' + 16*'\x00'
3463     send_wlanevent(url, uuid, data)
3464
3465     logger.info("EAP message: M1 missing Enrollee Nonce")
3466     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
3467     send_wlanevent(url, uuid, data)
3468
3469     logger.info("EAP message: M1 missing Public Key")
3470     data += '\x10\x1a\x00\x10' + 16*'\x00'
3471     send_wlanevent(url, uuid, data)
3472
3473     logger.info("EAP message: M1 missing Authentication Type flags")
3474     data += '\x10\x32\x00\xc0' + 192*'\x00'
3475     send_wlanevent(url, uuid, data)
3476
3477     logger.info("EAP message: M1 missing Encryption Type Flags")
3478     data += '\x10\x04\x00\x02\x00\x00'
3479     send_wlanevent(url, uuid, data)
3480
3481     logger.info("EAP message: M1 missing Connection Type flags")
3482     data += '\x10\x10\x00\x02\x00\x00'
3483     send_wlanevent(url, uuid, data)
3484
3485     logger.info("EAP message: M1 missing Config Methods")
3486     data += '\x10\x0d\x00\x01\x00'
3487     send_wlanevent(url, uuid, data)
3488
3489     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
3490     data += '\x10\x08\x00\x02\x00\x00'
3491     send_wlanevent(url, uuid, data)
3492
3493     logger.info("EAP message: M1 missing Manufacturer")
3494     data += '\x10\x44\x00\x01\x00'
3495     send_wlanevent(url, uuid, data)
3496
3497     logger.info("EAP message: M1 missing Model Name")
3498     data += '\x10\x21\x00\x00'
3499     send_wlanevent(url, uuid, data)
3500
3501     logger.info("EAP message: M1 missing Model Number")
3502     data += '\x10\x23\x00\x00'
3503     send_wlanevent(url, uuid, data)
3504
3505     logger.info("EAP message: M1 missing Serial Number")
3506     data += '\x10\x24\x00\x00'
3507     send_wlanevent(url, uuid, data)
3508
3509     logger.info("EAP message: M1 missing Primary Device Type")
3510     data += '\x10\x42\x00\x00'
3511     send_wlanevent(url, uuid, data)
3512
3513     logger.info("EAP message: M1 missing Device Name")
3514     data += '\x10\x54\x00\x08' + 8*'\x00'
3515     send_wlanevent(url, uuid, data)
3516
3517     logger.info("EAP message: M1 missing RF Bands")
3518     data += '\x10\x11\x00\x00'
3519     send_wlanevent(url, uuid, data)
3520
3521     logger.info("EAP message: M1 missing Association State")
3522     data += '\x10\x3c\x00\x01\x00'
3523     send_wlanevent(url, uuid, data)
3524
3525     logger.info("EAP message: M1 missing Device Password ID")
3526     data += '\x10\x02\x00\x02\x00\x00'
3527     send_wlanevent(url, uuid, data)
3528
3529     logger.info("EAP message: M1 missing Configuration Error")
3530     data += '\x10\x12\x00\x02\x00\x00'
3531     send_wlanevent(url, uuid, data)
3532
3533     logger.info("EAP message: M1 missing OS Version")
3534     data += '\x10\x09\x00\x02\x00\x00'
3535     send_wlanevent(url, uuid, data)
3536
3537 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
3538     """WPS ER HTTP protocol testing - no eventSubURL"""
3539     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
3540         def handle_upnp_info(self):
3541             self.wfile.write(gen_upnp_info(eventSubURL=None))
3542     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
3543                           no_event_url=True)
3544
3545 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
3546     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
3547     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
3548         def handle_upnp_info(self):
3549             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
3550     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
3551                           no_event_url=True)
3552
3553 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
3554     """WPS ER HTTP protocol testing - subscribe OOM"""
3555     try:
3556         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
3557     finally:
3558         dev[0].request("WPS_ER_STOP")
3559
3560 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
3561     tests = [ (1, "http_client_url_parse"),
3562               (1, "wpabuf_alloc;wps_er_subscribe"),
3563               (1, "http_client_addr"),
3564               (1, "eloop_register_sock;http_client_addr"),
3565               (1, "eloop_register_timeout;http_client_addr") ]
3566     for count,func in tests:
3567         with alloc_fail(dev[0], count, func):
3568             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
3569             server.handle_request()
3570             server.handle_request()
3571             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
3572
3573 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
3574     """WPS ER HTTP protocol testing - no SID"""
3575     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
3576         def handle_wps_event(self):
3577             self.wfile.write(gen_wps_event(sid=None))
3578     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
3579
3580 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
3581     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
3582     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
3583         def handle_wps_event(self):
3584             self.wfile.write(gen_wps_event(sid='FOO'))
3585     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
3586
3587 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
3588     """WPS ER HTTP protocol testing - invalid SID UUID"""
3589     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
3590         def handle_wps_event(self):
3591             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
3592     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
3593
3594 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
3595     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
3596     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
3597         def handle_wps_event(self):
3598             payload = ""
3599             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
3600                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3601                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3602                   'Connection: close\r\n' + \
3603                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3604                   'Timeout: Second-1801\r\n' + \
3605                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3606             self.wfile.write(hdr + payload)
3607     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
3608
3609 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
3610     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
3611     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
3612         def handle_wps_event(self):
3613             payload = ""
3614             hdr = 'HTTP/1.1 FOO\r\n' + \
3615                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3616                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3617                   'Connection: close\r\n' + \
3618                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3619                   'Timeout: Second-1801\r\n' + \
3620                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3621             self.wfile.write(hdr + payload)
3622     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
3623
3624 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
3625     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
3626     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
3627         def handle_wps_control(self):
3628             payload = '''<?xml version="1.0"?>
3629 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3630 <s:Body>
3631 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3632 <NewDeviceInfo>Rk9P</NewDeviceInfo>
3633 </u:GetDeviceInfoResponse>
3634 </s:Body>
3635 </s:Envelope>
3636 '''
3637             self.wfile.write(gen_wps_control(payload_override=payload))
3638     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
3639
3640 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
3641     """WPS ER HTTP protocol testing - No device in UPnP info"""
3642     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
3643         def handle_upnp_info(self):
3644             payload = '''<?xml version="1.0"?>
3645 <root xmlns="urn:schemas-upnp-org:device-1-0">
3646 <specVersion>
3647 <major>1</major>
3648 <minor>0</minor>
3649 </specVersion>
3650 </root>
3651 '''
3652             hdr = 'HTTP/1.1 200 OK\r\n' + \
3653                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3654                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3655                   'Connection: close\r\n' + \
3656                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3657                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3658             self.wfile.write(hdr + payload)
3659     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
3660
3661 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
3662     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
3663     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
3664         def handle_upnp_info(self):
3665             payload = '''<?xml version="1.0"?>
3666 <root xmlns="urn:schemas-upnp-org:device-1-0">
3667 <specVersion>
3668 <major>1</major>
3669 <minor>0</minor>
3670 </specVersion>
3671 <device>
3672 </device>
3673 </root>
3674 '''
3675             hdr = 'HTTP/1.1 200 OK\r\n' + \
3676                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3677                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3678                   'Connection: close\r\n' + \
3679                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3680                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3681             self.wfile.write(hdr + payload)
3682     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
3683
3684 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
3685     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
3686     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
3687         def handle_upnp_info(self):
3688             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
3689     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
3690
3691 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
3692     """WPS ER HTTP protocol testing - no controlURL"""
3693     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
3694         def handle_upnp_info(self):
3695             self.wfile.write(gen_upnp_info(controlURL=None))
3696     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
3697                           no_event_url=True)
3698
3699 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
3700     """WPS ER HTTP protocol testing - DNS name in controlURL"""
3701     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
3702         def handle_upnp_info(self):
3703             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
3704     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
3705                           no_event_url=True)