tests: WPS UPnP SetSelectedRegistrar protocol testing
[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 binascii
9 import os
10 import time
11 import stat
12 import subprocess
13 import logging
14 logger = logging.getLogger()
15 import re
16 import socket
17 import httplib
18 import urlparse
19 import urllib
20 import xml.etree.ElementTree as ET
21 import StringIO
22 import SocketServer
23
24 import hwsim_utils
25 import hostapd
26 from wpasupplicant import WpaSupplicant
27 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
28
29 def wps_start_ap(apdev, ssid="test-wps-conf"):
30     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
31                "wpa_passphrase": "12345678", "wpa": "2",
32                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
33     return hostapd.add_ap(apdev['ifname'], params)
34
35 def test_ap_wps_init(dev, apdev):
36     """Initial AP configuration with first WPS Enrollee"""
37     ssid = "test-wps"
38     hostapd.add_ap(apdev[0]['ifname'],
39                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
40     hapd = hostapd.Hostapd(apdev[0]['ifname'])
41     logger.info("WPS provisioning step")
42     hapd.request("WPS_PBC")
43     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
44         raise Exception("PBC status not shown correctly")
45
46     id = dev[0].add_network()
47     dev[0].set_network_quoted(id, "ssid", "home")
48     dev[0].set_network_quoted(id, "psk", "12345678")
49     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
50
51     id = dev[0].add_network()
52     dev[0].set_network_quoted(id, "ssid", "home2")
53     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
54     dev[0].set_network(id, "key_mgmt", "NONE")
55     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
56
57     dev[0].request("WPS_PBC")
58     dev[0].wait_connected(timeout=30)
59     status = dev[0].get_status()
60     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
61         raise Exception("Not fully connected")
62     if status['ssid'] != ssid:
63         raise Exception("Unexpected SSID")
64     if status['pairwise_cipher'] != 'CCMP':
65         raise Exception("Unexpected encryption configuration")
66     if status['key_mgmt'] != 'WPA2-PSK':
67         raise Exception("Unexpected key_mgmt")
68
69     status = hapd.request("WPS_GET_STATUS")
70     if "PBC Status: Disabled" not in status:
71         raise Exception("PBC status not shown correctly")
72     if "Last WPS result: Success" not in status:
73         raise Exception("Last WPS result not shown correctly")
74     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
75         raise Exception("Peer address not shown correctly")
76     conf = hapd.request("GET_CONFIG")
77     if "wps_state=configured" not in conf:
78         raise Exception("AP not in WPS configured state")
79     if "wpa=3" not in conf:
80         raise Exception("AP not in WPA+WPA2 configuration")
81     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
82         raise Exception("Unexpected rsn_pairwise_cipher")
83     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
84         raise Exception("Unexpected wpa_pairwise_cipher")
85     if "group_cipher=TKIP" not in conf:
86         raise Exception("Unexpected group_cipher")
87
88     if len(dev[0].list_networks()) != 3:
89         raise Exception("Unexpected number of network blocks")
90
91 def test_ap_wps_init_2ap_pbc(dev, apdev):
92     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
93     ssid = "test-wps"
94     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
95     hostapd.add_ap(apdev[0]['ifname'], params)
96     hostapd.add_ap(apdev[1]['ifname'], params)
97     hapd = hostapd.Hostapd(apdev[0]['ifname'])
98     logger.info("WPS provisioning step")
99     hapd.request("WPS_PBC")
100     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
101     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
102     bss = dev[0].get_bss(apdev[0]['bssid'])
103     if "[WPS-PBC]" not in bss['flags']:
104         raise Exception("WPS-PBC flag missing from AP1")
105     bss = dev[0].get_bss(apdev[1]['bssid'])
106     if "[WPS-PBC]" not in bss['flags']:
107         raise Exception("WPS-PBC flag missing from AP2")
108     dev[0].dump_monitor()
109     dev[0].request("SET wps_cred_processing 2")
110     dev[0].request("WPS_PBC")
111     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
112     dev[0].request("SET wps_cred_processing 0")
113     if ev is None:
114         raise Exception("WPS cred event not seen")
115     if "100e" not in ev:
116         raise Exception("WPS attributes not included in the cred event")
117     dev[0].wait_connected(timeout=30)
118
119     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
120     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
121     bss = dev[1].get_bss(apdev[0]['bssid'])
122     if "[WPS-PBC]" in bss['flags']:
123         raise Exception("WPS-PBC flag not cleared from AP1")
124     bss = dev[1].get_bss(apdev[1]['bssid'])
125     if "[WPS-PBC]" in bss['flags']:
126         raise Exception("WPS-PBC flag not cleared from AP2")
127
128 def test_ap_wps_init_2ap_pin(dev, apdev):
129     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
130     ssid = "test-wps"
131     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
132     hostapd.add_ap(apdev[0]['ifname'], params)
133     hostapd.add_ap(apdev[1]['ifname'], params)
134     hapd = hostapd.Hostapd(apdev[0]['ifname'])
135     logger.info("WPS provisioning step")
136     pin = dev[0].wps_read_pin()
137     hapd.request("WPS_PIN any " + pin)
138     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
139     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
140     bss = dev[0].get_bss(apdev[0]['bssid'])
141     if "[WPS-AUTH]" not in bss['flags']:
142         raise Exception("WPS-AUTH flag missing from AP1")
143     bss = dev[0].get_bss(apdev[1]['bssid'])
144     if "[WPS-AUTH]" not in bss['flags']:
145         raise Exception("WPS-AUTH flag missing from AP2")
146     dev[0].dump_monitor()
147     dev[0].request("WPS_PIN any " + pin)
148     dev[0].wait_connected(timeout=30)
149
150     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
151     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
152     bss = dev[1].get_bss(apdev[0]['bssid'])
153     if "[WPS-AUTH]" in bss['flags']:
154         raise Exception("WPS-AUTH flag not cleared from AP1")
155     bss = dev[1].get_bss(apdev[1]['bssid'])
156     if "[WPS-AUTH]" in bss['flags']:
157         raise Exception("WPS-AUTH flag not cleared from AP2")
158
159 def test_ap_wps_init_through_wps_config(dev, apdev):
160     """Initial AP configuration using wps_config command"""
161     ssid = "test-wps-init-config"
162     hostapd.add_ap(apdev[0]['ifname'],
163                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
164     hapd = hostapd.Hostapd(apdev[0]['ifname'])
165     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
166         raise Exception("WPS_CONFIG command failed")
167     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
168     if ev is None:
169         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
170     # It takes some time for the AP to update Beacon and Probe Response frames,
171     # so wait here before requesting the scan to be started to avoid adding
172     # extra five second wait to the test due to fetching obsolete scan results.
173     hapd.ping()
174     time.sleep(0.2)
175     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
176                    pairwise="CCMP", group="CCMP")
177
178 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
179     """AP configuration using wps_config command with invalid passphrase"""
180     ssid = "test-wps-init-config"
181     hostapd.add_ap(apdev[0]['ifname'],
182                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
183     hapd = hostapd.Hostapd(apdev[0]['ifname'])
184     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
185         raise Exception("Invalid WPS_CONFIG command accepted")
186
187 def test_ap_wps_conf(dev, apdev):
188     """WPS PBC provisioning with configured AP"""
189     ssid = "test-wps-conf"
190     hostapd.add_ap(apdev[0]['ifname'],
191                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
192                      "wpa_passphrase": "12345678", "wpa": "2",
193                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
194     hapd = hostapd.Hostapd(apdev[0]['ifname'])
195     logger.info("WPS provisioning step")
196     hapd.request("WPS_PBC")
197     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
198     dev[0].dump_monitor()
199     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
200     dev[0].wait_connected(timeout=30)
201     status = dev[0].get_status()
202     if status['wpa_state'] != 'COMPLETED':
203         raise Exception("Not fully connected")
204     if status['bssid'] != apdev[0]['bssid']:
205         raise Exception("Unexpected BSSID")
206     if status['ssid'] != ssid:
207         raise Exception("Unexpected SSID")
208     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
209         raise Exception("Unexpected encryption configuration")
210     if status['key_mgmt'] != 'WPA2-PSK':
211         raise Exception("Unexpected key_mgmt")
212
213     sta = hapd.get_sta(dev[0].p2p_interface_addr())
214     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
215         raise Exception("Device name not available in STA command")
216
217 def test_ap_wps_conf_5ghz(dev, apdev):
218     """WPS PBC provisioning with configured AP on 5 GHz band"""
219     try:
220         hapd = None
221         ssid = "test-wps-conf"
222         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
223                    "wpa_passphrase": "12345678", "wpa": "2",
224                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
225                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
226         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
227         logger.info("WPS provisioning step")
228         hapd.request("WPS_PBC")
229         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
230         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
231         dev[0].wait_connected(timeout=30)
232
233         sta = hapd.get_sta(dev[0].p2p_interface_addr())
234         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
235             raise Exception("Device name not available in STA command")
236     finally:
237         dev[0].request("DISCONNECT")
238         if hapd:
239             hapd.request("DISABLE")
240         subprocess.call(['iw', 'reg', 'set', '00'])
241         dev[0].flush_scan_cache()
242
243 def test_ap_wps_conf_chan14(dev, apdev):
244     """WPS PBC provisioning with configured AP on channel 14"""
245     try:
246         hapd = None
247         ssid = "test-wps-conf"
248         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
249                    "wpa_passphrase": "12345678", "wpa": "2",
250                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
251                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
252         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
253         logger.info("WPS provisioning step")
254         hapd.request("WPS_PBC")
255         dev[0].request("WPS_PBC")
256         dev[0].wait_connected(timeout=30)
257
258         sta = hapd.get_sta(dev[0].p2p_interface_addr())
259         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
260             raise Exception("Device name not available in STA command")
261     finally:
262         dev[0].request("DISCONNECT")
263         if hapd:
264             hapd.request("DISABLE")
265         subprocess.call(['iw', 'reg', 'set', '00'])
266         dev[0].flush_scan_cache()
267
268 def test_ap_wps_twice(dev, apdev):
269     """WPS provisioning with twice to change passphrase"""
270     ssid = "test-wps-twice"
271     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
272                "wpa_passphrase": "12345678", "wpa": "2",
273                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
274     hostapd.add_ap(apdev[0]['ifname'], params)
275     hapd = hostapd.Hostapd(apdev[0]['ifname'])
276     logger.info("WPS provisioning step")
277     hapd.request("WPS_PBC")
278     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
279     dev[0].dump_monitor()
280     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
281     dev[0].wait_connected(timeout=30)
282     dev[0].request("DISCONNECT")
283
284     logger.info("Restart AP with different passphrase and re-run WPS")
285     hapd_global = hostapd.HostapdGlobal()
286     hapd_global.remove(apdev[0]['ifname'])
287     params['wpa_passphrase'] = 'another passphrase'
288     hostapd.add_ap(apdev[0]['ifname'], params)
289     hapd = hostapd.Hostapd(apdev[0]['ifname'])
290     logger.info("WPS provisioning step")
291     hapd.request("WPS_PBC")
292     dev[0].dump_monitor()
293     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
294     dev[0].wait_connected(timeout=30)
295     networks = dev[0].list_networks()
296     if len(networks) > 1:
297         raise Exception("Unexpected duplicated network block present")
298
299 def test_ap_wps_incorrect_pin(dev, apdev):
300     """WPS PIN provisioning with incorrect PIN"""
301     ssid = "test-wps-incorrect-pin"
302     hostapd.add_ap(apdev[0]['ifname'],
303                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
304                      "wpa_passphrase": "12345678", "wpa": "2",
305                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
306     hapd = hostapd.Hostapd(apdev[0]['ifname'])
307
308     logger.info("WPS provisioning attempt 1")
309     hapd.request("WPS_PIN any 12345670")
310     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
311     dev[0].dump_monitor()
312     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
313     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
314     if ev is None:
315         raise Exception("WPS operation timed out")
316     if "config_error=18" not in ev:
317         raise Exception("Incorrect config_error reported")
318     if "msg=8" not in ev:
319         raise Exception("PIN error detected on incorrect message")
320     dev[0].wait_disconnected(timeout=10)
321     dev[0].request("WPS_CANCEL")
322     # if a scan was in progress, wait for it to complete before trying WPS again
323     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
324
325     status = hapd.request("WPS_GET_STATUS")
326     if "Last WPS result: Failed" not in status:
327         raise Exception("WPS failure result not shown correctly")
328
329     logger.info("WPS provisioning attempt 2")
330     hapd.request("WPS_PIN any 12345670")
331     dev[0].dump_monitor()
332     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
333     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
334     if ev is None:
335         raise Exception("WPS operation timed out")
336     if "config_error=18" not in ev:
337         raise Exception("Incorrect config_error reported")
338     if "msg=10" not in ev:
339         raise Exception("PIN error detected on incorrect message")
340     dev[0].wait_disconnected(timeout=10)
341
342 def test_ap_wps_conf_pin(dev, apdev):
343     """WPS PIN provisioning with configured AP"""
344     ssid = "test-wps-conf-pin"
345     hostapd.add_ap(apdev[0]['ifname'],
346                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
347                      "wpa_passphrase": "12345678", "wpa": "2",
348                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
349     hapd = hostapd.Hostapd(apdev[0]['ifname'])
350     logger.info("WPS provisioning step")
351     pin = dev[0].wps_read_pin()
352     hapd.request("WPS_PIN any " + pin)
353     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
354     dev[0].dump_monitor()
355     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
356     dev[0].wait_connected(timeout=30)
357     status = dev[0].get_status()
358     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
359         raise Exception("Not fully connected")
360     if status['ssid'] != ssid:
361         raise Exception("Unexpected SSID")
362     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
363         raise Exception("Unexpected encryption configuration")
364     if status['key_mgmt'] != 'WPA2-PSK':
365         raise Exception("Unexpected key_mgmt")
366
367     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
368     bss = dev[1].get_bss(apdev[0]['bssid'])
369     if "[WPS-AUTH]" in bss['flags']:
370         raise Exception("WPS-AUTH flag not cleared")
371     logger.info("Try to connect from another station using the same PIN")
372     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
373     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
374     if ev is None:
375         raise Exception("Operation timed out")
376     if "WPS-M2D" not in ev:
377         raise Exception("Unexpected WPS operation started")
378     hapd.request("WPS_PIN any " + pin)
379     dev[1].wait_connected(timeout=30)
380
381 def test_ap_wps_conf_pin_v1(dev, apdev):
382     """WPS PIN provisioning with configured WPS v1.0 AP"""
383     ssid = "test-wps-conf-pin-v1"
384     hostapd.add_ap(apdev[0]['ifname'],
385                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
386                      "wpa_passphrase": "12345678", "wpa": "2",
387                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
388     hapd = hostapd.Hostapd(apdev[0]['ifname'])
389     logger.info("WPS provisioning step")
390     pin = dev[0].wps_read_pin()
391     hapd.request("SET wps_version_number 0x10")
392     hapd.request("WPS_PIN any " + pin)
393     found = False
394     for i in range(0, 10):
395         dev[0].scan(freq="2412")
396         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
397             found = True
398             break
399     if not found:
400         hapd.request("SET wps_version_number 0x20")
401         raise Exception("WPS-PIN flag not seen in scan results")
402     dev[0].dump_monitor()
403     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
404     dev[0].wait_connected(timeout=30)
405     hapd.request("SET wps_version_number 0x20")
406
407 def test_ap_wps_conf_pin_2sta(dev, apdev):
408     """Two stations trying to use WPS PIN at the same time"""
409     ssid = "test-wps-conf-pin2"
410     hostapd.add_ap(apdev[0]['ifname'],
411                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
412                      "wpa_passphrase": "12345678", "wpa": "2",
413                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
414     hapd = hostapd.Hostapd(apdev[0]['ifname'])
415     logger.info("WPS provisioning step")
416     pin = "12345670"
417     pin2 = "55554444"
418     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
419     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
420     dev[0].dump_monitor()
421     dev[1].dump_monitor()
422     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
423     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
424     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
425     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
426     dev[0].wait_connected(timeout=30)
427     dev[1].wait_connected(timeout=30)
428
429 def test_ap_wps_conf_pin_timeout(dev, apdev):
430     """WPS PIN provisioning with configured AP timing out PIN"""
431     ssid = "test-wps-conf-pin"
432     hostapd.add_ap(apdev[0]['ifname'],
433                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
434                      "wpa_passphrase": "12345678", "wpa": "2",
435                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
436     hapd = hostapd.Hostapd(apdev[0]['ifname'])
437     addr = dev[0].p2p_interface_addr()
438     pin = dev[0].wps_read_pin()
439     if "FAIL" not in hapd.request("WPS_PIN "):
440         raise Exception("Unexpected success on invalid WPS_PIN")
441     hapd.request("WPS_PIN any " + pin + " 1")
442     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
443     time.sleep(1.1)
444     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
445     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
446     if ev is None:
447         raise Exception("WPS-PIN-NEEDED event timed out")
448     ev = dev[0].wait_event(["WPS-M2D"])
449     if ev is None:
450         raise Exception("M2D not reported")
451     dev[0].request("WPS_CANCEL")
452
453     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
454     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
455     dev[0].wait_connected(timeout=30)
456
457 def test_ap_wps_reg_connect(dev, apdev):
458     """WPS registrar using AP PIN to connect"""
459     ssid = "test-wps-reg-ap-pin"
460     appin = "12345670"
461     hostapd.add_ap(apdev[0]['ifname'],
462                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
463                      "wpa_passphrase": "12345678", "wpa": "2",
464                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
465                      "ap_pin": appin})
466     logger.info("WPS provisioning step")
467     dev[0].dump_monitor()
468     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
469     dev[0].wps_reg(apdev[0]['bssid'], appin)
470     status = dev[0].get_status()
471     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
472         raise Exception("Not fully connected")
473     if status['ssid'] != ssid:
474         raise Exception("Unexpected SSID")
475     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
476         raise Exception("Unexpected encryption configuration")
477     if status['key_mgmt'] != 'WPA2-PSK':
478         raise Exception("Unexpected key_mgmt")
479
480 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
481     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
482     ssid = "test-wps-reg-ap-pin"
483     appin = "12345670"
484     hostapd.add_ap(apdev[0]['ifname'],
485                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
486                      "wpa_passphrase": "12345678", "wpa": "3",
487                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
488                      "wpa_pairwise": "TKIP", "ap_pin": appin})
489     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
490     dev[0].wps_reg(apdev[0]['bssid'], appin)
491     status = dev[0].get_status()
492     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
493         raise Exception("Not fully connected")
494     if status['ssid'] != ssid:
495         raise Exception("Unexpected SSID")
496     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
497         raise Exception("Unexpected encryption configuration")
498     if status['key_mgmt'] != 'WPA2-PSK':
499         raise Exception("Unexpected key_mgmt")
500
501 def check_wps_reg_failure(dev, ap, appin):
502     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
503     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
504     if ev is None:
505         raise Exception("WPS operation timed out")
506     if "WPS-SUCCESS" in ev:
507         raise Exception("WPS operation succeeded unexpectedly")
508     if "config_error=15" not in ev:
509         raise Exception("WPS setup locked state was not reported correctly")
510
511 def test_ap_wps_random_ap_pin(dev, apdev):
512     """WPS registrar using random AP PIN"""
513     ssid = "test-wps-reg-random-ap-pin"
514     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
515     hostapd.add_ap(apdev[0]['ifname'],
516                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
517                      "wpa_passphrase": "12345678", "wpa": "2",
518                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
519                      "device_name": "Wireless AP", "manufacturer": "Company",
520                      "model_name": "WAP", "model_number": "123",
521                      "serial_number": "12345", "device_type": "6-0050F204-1",
522                      "os_version": "01020300",
523                      "config_methods": "label push_button",
524                      "uuid": ap_uuid, "upnp_iface": "lo" })
525     hapd = hostapd.Hostapd(apdev[0]['ifname'])
526     appin = hapd.request("WPS_AP_PIN random")
527     if "FAIL" in appin:
528         raise Exception("Could not generate random AP PIN")
529     if appin not in hapd.request("WPS_AP_PIN get"):
530         raise Exception("Could not fetch current AP PIN")
531     logger.info("WPS provisioning step")
532     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
533     dev[0].wps_reg(apdev[0]['bssid'], appin)
534
535     hapd.request("WPS_AP_PIN disable")
536     logger.info("WPS provisioning step with AP PIN disabled")
537     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
538     check_wps_reg_failure(dev[1], apdev[0], appin)
539
540     logger.info("WPS provisioning step with AP PIN reset")
541     appin = "12345670"
542     hapd.request("WPS_AP_PIN set " + appin)
543     dev[1].wps_reg(apdev[0]['bssid'], appin)
544     dev[0].request("REMOVE_NETWORK all")
545     dev[1].request("REMOVE_NETWORK all")
546     dev[0].wait_disconnected(timeout=10)
547     dev[1].wait_disconnected(timeout=10)
548
549     logger.info("WPS provisioning step after AP PIN timeout")
550     hapd.request("WPS_AP_PIN disable")
551     appin = hapd.request("WPS_AP_PIN random 1")
552     time.sleep(1.1)
553     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
554         raise Exception("AP PIN unexpectedly still enabled")
555     check_wps_reg_failure(dev[0], apdev[0], appin)
556
557     logger.info("WPS provisioning step after AP PIN timeout(2)")
558     hapd.request("WPS_AP_PIN disable")
559     appin = "12345670"
560     hapd.request("WPS_AP_PIN set " + appin + " 1")
561     time.sleep(1.1)
562     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
563         raise Exception("AP PIN unexpectedly still enabled")
564     check_wps_reg_failure(dev[1], apdev[0], appin)
565
566     with fail_test(hapd, 1, "os_get_random;wps_generate_pin"):
567         if "FAIL" in hapd.request("WPS_AP_PIN random 1"):
568             raise Exception("Failed to generate PIN during OOM")
569         hapd.request("WPS_AP_PIN disable")
570
571     with alloc_fail(hapd, 1, "upnp_wps_set_ap_pin"):
572         hapd.request("WPS_AP_PIN set 12345670")
573         hapd.request("WPS_AP_PIN disable")
574
575 def test_ap_wps_reg_config(dev, apdev):
576     """WPS registrar configuring an AP using AP PIN"""
577     ssid = "test-wps-init-ap-pin"
578     appin = "12345670"
579     hostapd.add_ap(apdev[0]['ifname'],
580                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
581                      "ap_pin": appin})
582     logger.info("WPS configuration step")
583     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
584     dev[0].dump_monitor()
585     new_ssid = "wps-new-ssid"
586     new_passphrase = "1234567890"
587     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
588                    new_passphrase)
589     status = dev[0].get_status()
590     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
591         raise Exception("Not fully connected")
592     if status['ssid'] != new_ssid:
593         raise Exception("Unexpected SSID")
594     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
595         raise Exception("Unexpected encryption configuration")
596     if status['key_mgmt'] != 'WPA2-PSK':
597         raise Exception("Unexpected key_mgmt")
598
599     logger.info("Re-configure back to open")
600     dev[0].request("REMOVE_NETWORK all")
601     dev[0].flush_scan_cache()
602     dev[0].dump_monitor()
603     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
604     status = dev[0].get_status()
605     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
606         raise Exception("Not fully connected")
607     if status['ssid'] != "wps-open":
608         raise Exception("Unexpected SSID")
609     if status['key_mgmt'] != 'NONE':
610         raise Exception("Unexpected key_mgmt")
611
612 def test_ap_wps_reg_config_ext_processing(dev, apdev):
613     """WPS registrar configuring an AP with external config processing"""
614     ssid = "test-wps-init-ap-pin"
615     appin = "12345670"
616     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
617                "wps_cred_processing": "1", "ap_pin": appin}
618     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
619     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
620     new_ssid = "wps-new-ssid"
621     new_passphrase = "1234567890"
622     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
623                    new_passphrase, no_wait=True)
624     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
625     if ev is None:
626         raise Exception("WPS registrar operation timed out")
627     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
628     if ev is None:
629         raise Exception("WPS configuration timed out")
630     if "1026" not in ev:
631         raise Exception("AP Settings missing from event")
632     hapd.request("SET wps_cred_processing 0")
633     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
634         raise Exception("WPS_CONFIG command failed")
635     dev[0].wait_connected(timeout=15)
636
637 def test_ap_wps_reg_config_tkip(dev, apdev):
638     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
639     skip_with_fips(dev[0])
640     ssid = "test-wps-init-ap"
641     appin = "12345670"
642     hostapd.add_ap(apdev[0]['ifname'],
643                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
644                      "ap_pin": appin})
645     logger.info("WPS configuration step")
646     dev[0].request("SET wps_version_number 0x10")
647     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
648     dev[0].dump_monitor()
649     new_ssid = "wps-new-ssid-with-tkip"
650     new_passphrase = "1234567890"
651     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
652                    new_passphrase)
653     logger.info("Re-connect to verify WPA2 mixed mode")
654     dev[0].request("DISCONNECT")
655     id = 0
656     dev[0].set_network(id, "pairwise", "CCMP")
657     dev[0].set_network(id, "proto", "RSN")
658     dev[0].connect_network(id)
659     status = dev[0].get_status()
660     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
661         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
662     if status['ssid'] != new_ssid:
663         raise Exception("Unexpected SSID")
664     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
665         raise Exception("Unexpected encryption configuration")
666     if status['key_mgmt'] != 'WPA2-PSK':
667         raise Exception("Unexpected key_mgmt")
668
669 def test_ap_wps_setup_locked(dev, apdev):
670     """WPS registrar locking up AP setup on AP PIN failures"""
671     ssid = "test-wps-incorrect-ap-pin"
672     appin = "12345670"
673     hostapd.add_ap(apdev[0]['ifname'],
674                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
675                      "wpa_passphrase": "12345678", "wpa": "2",
676                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
677                      "ap_pin": appin})
678     new_ssid = "wps-new-ssid-test"
679     new_passphrase = "1234567890"
680
681     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
682     ap_setup_locked=False
683     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
684         dev[0].dump_monitor()
685         logger.info("Try incorrect AP PIN - attempt " + pin)
686         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
687                        "CCMP", new_passphrase, no_wait=True)
688         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
689         if ev is None:
690             raise Exception("Timeout on receiving WPS operation failure event")
691         if "CTRL-EVENT-CONNECTED" in ev:
692             raise Exception("Unexpected connection")
693         if "config_error=15" in ev:
694             logger.info("AP Setup Locked")
695             ap_setup_locked=True
696         elif "config_error=18" not in ev:
697             raise Exception("config_error=18 not reported")
698         dev[0].wait_disconnected(timeout=10)
699         time.sleep(0.1)
700     if not ap_setup_locked:
701         raise Exception("AP setup was not locked")
702     dev[0].request("WPS_CANCEL")
703     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True,
704                         only_new=True)
705     bss = dev[0].get_bss(apdev[0]['bssid'])
706     if 'wps_ap_setup_locked' not in bss or bss['wps_ap_setup_locked'] != '1':
707         logger.info("BSS: " + str(bss))
708         raise Exception("AP Setup Locked not indicated in scan results")
709
710     hapd = hostapd.Hostapd(apdev[0]['ifname'])
711     status = hapd.request("WPS_GET_STATUS")
712     if "Last WPS result: Failed" not in status:
713         raise Exception("WPS failure result not shown correctly")
714     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
715         raise Exception("Peer address not shown correctly")
716
717     time.sleep(0.5)
718     dev[0].dump_monitor()
719     logger.info("WPS provisioning step")
720     pin = dev[0].wps_read_pin()
721     hapd = hostapd.Hostapd(apdev[0]['ifname'])
722     hapd.request("WPS_PIN any " + pin)
723     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
724     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
725     if ev is None:
726         raise Exception("WPS success was not reported")
727     dev[0].wait_connected(timeout=30)
728
729     appin = hapd.request("WPS_AP_PIN random")
730     if "FAIL" in appin:
731         raise Exception("Could not generate random AP PIN")
732     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
733     if ev is None:
734         raise Exception("Failed to unlock AP PIN")
735
736 def test_ap_wps_setup_locked_timeout(dev, apdev):
737     """WPS re-enabling AP PIN after timeout"""
738     ssid = "test-wps-incorrect-ap-pin"
739     appin = "12345670"
740     hostapd.add_ap(apdev[0]['ifname'],
741                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
742                      "wpa_passphrase": "12345678", "wpa": "2",
743                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
744                      "ap_pin": appin})
745     new_ssid = "wps-new-ssid-test"
746     new_passphrase = "1234567890"
747
748     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
749     ap_setup_locked=False
750     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
751         dev[0].dump_monitor()
752         logger.info("Try incorrect AP PIN - attempt " + pin)
753         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
754                        "CCMP", new_passphrase, no_wait=True)
755         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
756         if ev is None:
757             raise Exception("Timeout on receiving WPS operation failure event")
758         if "CTRL-EVENT-CONNECTED" in ev:
759             raise Exception("Unexpected connection")
760         if "config_error=15" in ev:
761             logger.info("AP Setup Locked")
762             ap_setup_locked=True
763             break
764         elif "config_error=18" not in ev:
765             raise Exception("config_error=18 not reported")
766         dev[0].wait_disconnected(timeout=10)
767         time.sleep(0.1)
768     if not ap_setup_locked:
769         raise Exception("AP setup was not locked")
770     hapd = hostapd.Hostapd(apdev[0]['ifname'])
771     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
772     if ev is None:
773         raise Exception("AP PIN did not get unlocked on 60 second timeout")
774
775 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
776     """WPS PBC session overlap with two active APs"""
777     hostapd.add_ap(apdev[0]['ifname'],
778                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
779                      "wpa_passphrase": "12345678", "wpa": "2",
780                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
781                      "wps_independent": "1"})
782     hostapd.add_ap(apdev[1]['ifname'],
783                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
784                      "wpa_passphrase": "123456789", "wpa": "2",
785                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
786                      "wps_independent": "1"})
787     hapd = hostapd.Hostapd(apdev[0]['ifname'])
788     hapd.request("WPS_PBC")
789     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
790     hapd2.request("WPS_PBC")
791     logger.info("WPS provisioning step")
792     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
793     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
794     dev[0].request("WPS_PBC")
795     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
796     if ev is None:
797         raise Exception("PBC session overlap not detected")
798     hapd.request("DISABLE")
799     hapd2.request("DISABLE")
800     dev[0].flush_scan_cache()
801
802 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
803     """WPS PBC session overlap with two active STAs"""
804     ssid = "test-wps-pbc-overlap"
805     hostapd.add_ap(apdev[0]['ifname'],
806                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
807                      "wpa_passphrase": "12345678", "wpa": "2",
808                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
809     hapd = hostapd.Hostapd(apdev[0]['ifname'])
810     logger.info("WPS provisioning step")
811     hapd.request("WPS_PBC")
812     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
813     dev[0].dump_monitor()
814     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
815     dev[1].dump_monitor()
816     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
817     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
818     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
819     if ev is None:
820         raise Exception("PBC session overlap not detected (dev0)")
821     if "config_error=12" not in ev:
822         raise Exception("PBC session overlap not correctly reported (dev0)")
823     dev[0].request("WPS_CANCEL")
824     dev[0].request("DISCONNECT")
825     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
826     if ev is None:
827         raise Exception("PBC session overlap not detected (dev1)")
828     if "config_error=12" not in ev:
829         raise Exception("PBC session overlap not correctly reported (dev1)")
830     dev[1].request("WPS_CANCEL")
831     dev[1].request("DISCONNECT")
832     hapd.request("WPS_CANCEL")
833     ret = hapd.request("WPS_PBC")
834     if "FAIL" not in ret:
835         raise Exception("PBC mode allowed to be started while PBC overlap still active")
836     hapd.request("DISABLE")
837     dev[0].flush_scan_cache()
838     dev[1].flush_scan_cache()
839
840 def test_ap_wps_cancel(dev, apdev):
841     """WPS AP cancelling enabled config method"""
842     ssid = "test-wps-ap-cancel"
843     hostapd.add_ap(apdev[0]['ifname'],
844                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
845                      "wpa_passphrase": "12345678", "wpa": "2",
846                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
847     bssid = apdev[0]['bssid']
848     hapd = hostapd.Hostapd(apdev[0]['ifname'])
849
850     logger.info("Verify PBC enable/cancel")
851     hapd.request("WPS_PBC")
852     dev[0].scan(freq="2412")
853     dev[0].scan(freq="2412")
854     bss = dev[0].get_bss(apdev[0]['bssid'])
855     if "[WPS-PBC]" not in bss['flags']:
856         raise Exception("WPS-PBC flag missing")
857     if "FAIL" in hapd.request("WPS_CANCEL"):
858         raise Exception("WPS_CANCEL failed")
859     dev[0].scan(freq="2412")
860     dev[0].scan(freq="2412")
861     bss = dev[0].get_bss(apdev[0]['bssid'])
862     if "[WPS-PBC]" in bss['flags']:
863         raise Exception("WPS-PBC flag not cleared")
864
865     logger.info("Verify PIN enable/cancel")
866     hapd.request("WPS_PIN any 12345670")
867     dev[0].scan(freq="2412")
868     dev[0].scan(freq="2412")
869     bss = dev[0].get_bss(apdev[0]['bssid'])
870     if "[WPS-AUTH]" not in bss['flags']:
871         raise Exception("WPS-AUTH flag missing")
872     if "FAIL" in hapd.request("WPS_CANCEL"):
873         raise Exception("WPS_CANCEL failed")
874     dev[0].scan(freq="2412")
875     dev[0].scan(freq="2412")
876     bss = dev[0].get_bss(apdev[0]['bssid'])
877     if "[WPS-AUTH]" in bss['flags']:
878         raise Exception("WPS-AUTH flag not cleared")
879
880 def test_ap_wps_er_add_enrollee(dev, apdev):
881     """WPS ER configuring AP and adding a new enrollee using PIN"""
882     try:
883         _test_ap_wps_er_add_enrollee(dev, apdev)
884     finally:
885         dev[0].request("WPS_ER_STOP")
886
887 def _test_ap_wps_er_add_enrollee(dev, apdev):
888     ssid = "wps-er-add-enrollee"
889     ap_pin = "12345670"
890     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
891     hostapd.add_ap(apdev[0]['ifname'],
892                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
893                      "device_name": "Wireless AP", "manufacturer": "Company",
894                      "model_name": "WAP", "model_number": "123",
895                      "serial_number": "12345", "device_type": "6-0050F204-1",
896                      "os_version": "01020300",
897                      'friendly_name': "WPS AP - <>&'\" - TEST",
898                      "config_methods": "label push_button",
899                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
900     logger.info("WPS configuration step")
901     new_passphrase = "1234567890"
902     dev[0].dump_monitor()
903     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
904     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
905                    new_passphrase)
906     status = dev[0].get_status()
907     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
908         raise Exception("Not fully connected")
909     if status['ssid'] != ssid:
910         raise Exception("Unexpected SSID")
911     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
912         raise Exception("Unexpected encryption configuration")
913     if status['key_mgmt'] != 'WPA2-PSK':
914         raise Exception("Unexpected key_mgmt")
915
916     logger.info("Start ER")
917     dev[0].request("WPS_ER_START ifname=lo")
918     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
919     if ev is None:
920         raise Exception("AP discovery timed out")
921     if ap_uuid not in ev:
922         raise Exception("Expected AP UUID not found")
923     if "|WPS AP - &lt;&gt;&amp;&apos;&quot; - TEST|Company|" not in ev:
924         raise Exception("Expected friendly name not found")
925
926     logger.info("Learn AP configuration through UPnP")
927     dev[0].dump_monitor()
928     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
929     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
930     if ev is None:
931         raise Exception("AP learn timed out")
932     if ap_uuid not in ev:
933         raise Exception("Expected AP UUID not in settings")
934     if "ssid=" + ssid not in ev:
935         raise Exception("Expected SSID not in settings")
936     if "key=" + new_passphrase not in ev:
937         raise Exception("Expected passphrase not in settings")
938     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
939     if ev is None:
940         raise Exception("WPS-FAIL after AP learn timed out")
941     time.sleep(0.1)
942
943     logger.info("Add Enrollee using ER")
944     pin = dev[1].wps_read_pin()
945     dev[0].dump_monitor()
946     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
947     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
948     dev[1].dump_monitor()
949     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
950     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
951     if ev is None:
952         raise Exception("Enrollee did not report success")
953     dev[1].wait_connected(timeout=15)
954     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
955     if ev is None:
956         raise Exception("WPS ER did not report success")
957     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
958
959     logger.info("Add a specific Enrollee using ER")
960     pin = dev[2].wps_read_pin()
961     addr2 = dev[2].p2p_interface_addr()
962     dev[0].dump_monitor()
963     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
964     dev[2].dump_monitor()
965     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
966     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
967     if ev is None:
968         raise Exception("Enrollee not seen")
969     if addr2 not in ev:
970         raise Exception("Unexpected Enrollee MAC address")
971     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
972     dev[2].wait_connected(timeout=30)
973     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
974     if ev is None:
975         raise Exception("WPS ER did not report success")
976
977     logger.info("Verify registrar selection behavior")
978     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
979     dev[1].request("DISCONNECT")
980     dev[1].wait_disconnected(timeout=10)
981     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
982     dev[1].scan(freq="2412")
983     bss = dev[1].get_bss(apdev[0]['bssid'])
984     if "[WPS-AUTH]" not in bss['flags']:
985         # It is possible for scan to miss an update especially when running
986         # tests under load with multiple VMs, so allow another attempt.
987         dev[1].scan(freq="2412")
988         bss = dev[1].get_bss(apdev[0]['bssid'])
989         if "[WPS-AUTH]" not in bss['flags']:
990             raise Exception("WPS-AUTH flag missing")
991
992     logger.info("Stop ER")
993     dev[0].dump_monitor()
994     dev[0].request("WPS_ER_STOP")
995     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
996     if ev is None:
997         raise Exception("WPS ER unsubscription timed out")
998     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
999     # a bit before verifying that the scan results have changed.
1000     time.sleep(0.2)
1001
1002     for i in range(0, 10):
1003         dev[1].request("BSS_FLUSH 0")
1004         dev[1].scan(freq="2412", only_new=True)
1005         bss = dev[1].get_bss(apdev[0]['bssid'])
1006         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
1007             break
1008         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
1009         time.sleep(0.1)
1010     if "[WPS-AUTH]" in bss['flags']:
1011         raise Exception("WPS-AUTH flag not removed")
1012
1013 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1014     """WPS ER adding a new enrollee identified by UUID"""
1015     try:
1016         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
1017     finally:
1018         dev[0].request("WPS_ER_STOP")
1019
1020 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1021     ssid = "wps-er-add-enrollee"
1022     ap_pin = "12345670"
1023     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1024     hostapd.add_ap(apdev[0]['ifname'],
1025                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1026                      "wpa_passphrase": "12345678", "wpa": "2",
1027                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1028                      "device_name": "Wireless AP", "manufacturer": "Company",
1029                      "model_name": "WAP", "model_number": "123",
1030                      "serial_number": "12345", "device_type": "6-0050F204-1",
1031                      "os_version": "01020300",
1032                      "config_methods": "label push_button",
1033                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1034     logger.info("WPS configuration step")
1035     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1036     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1037
1038     logger.info("Start ER")
1039     dev[0].request("WPS_ER_START ifname=lo")
1040     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1041     if ev is None:
1042         raise Exception("AP discovery timed out")
1043     if ap_uuid not in ev:
1044         raise Exception("Expected AP UUID not found")
1045
1046     logger.info("Learn AP configuration through UPnP")
1047     dev[0].dump_monitor()
1048     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1049     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1050     if ev is None:
1051         raise Exception("AP learn timed out")
1052     if ap_uuid not in ev:
1053         raise Exception("Expected AP UUID not in settings")
1054     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1055     if ev is None:
1056         raise Exception("WPS-FAIL after AP learn timed out")
1057     time.sleep(0.1)
1058
1059     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1060     addr1 = dev[1].p2p_interface_addr()
1061     dev[0].dump_monitor()
1062     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1063     dev[1].dump_monitor()
1064     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1065     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1066     if ev is None:
1067         raise Exception("Enrollee not seen")
1068     if addr1 not in ev:
1069         raise Exception("Unexpected Enrollee MAC address")
1070     uuid = ev.split(' ')[1]
1071     dev[0].request("WPS_ER_PBC " + uuid)
1072     dev[1].wait_connected(timeout=30)
1073     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1074     if ev is None:
1075         raise Exception("WPS ER did not report success")
1076
1077     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1078     pin = dev[2].wps_read_pin()
1079     addr2 = dev[2].p2p_interface_addr()
1080     dev[0].dump_monitor()
1081     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1082     dev[2].dump_monitor()
1083     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1084     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1085     if ev is None:
1086         raise Exception("Enrollee not seen")
1087     if addr2 not in ev:
1088         raise Exception("Unexpected Enrollee MAC address")
1089     uuid = ev.split(' ')[1]
1090     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1091     dev[2].wait_connected(timeout=30)
1092     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1093     if ev is None:
1094         raise Exception("WPS ER did not report success")
1095
1096     logger.info("Stop ER")
1097     dev[0].dump_monitor()
1098     dev[0].request("WPS_ER_STOP")
1099
1100 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1101     """WPS ER connected to AP and adding a new enrollee using PBC"""
1102     try:
1103         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1104     finally:
1105         dev[0].request("WPS_ER_STOP")
1106
1107 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1108     ssid = "wps-er-add-enrollee-pbc"
1109     ap_pin = "12345670"
1110     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1111     hostapd.add_ap(apdev[0]['ifname'],
1112                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1113                      "wpa_passphrase": "12345678", "wpa": "2",
1114                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1115                      "device_name": "Wireless AP", "manufacturer": "Company",
1116                      "model_name": "WAP", "model_number": "123",
1117                      "serial_number": "12345", "device_type": "6-0050F204-1",
1118                      "os_version": "01020300",
1119                      "config_methods": "label push_button",
1120                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1121     logger.info("Learn AP configuration")
1122     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1123     dev[0].dump_monitor()
1124     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1125     status = dev[0].get_status()
1126     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1127         raise Exception("Not fully connected")
1128
1129     logger.info("Start ER")
1130     dev[0].request("WPS_ER_START ifname=lo")
1131     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1132     if ev is None:
1133         raise Exception("AP discovery timed out")
1134     if ap_uuid not in ev:
1135         raise Exception("Expected AP UUID not found")
1136
1137     enrollee = dev[1].p2p_interface_addr()
1138
1139     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1140         raise Exception("Unknown UUID not reported")
1141
1142     logger.info("Add Enrollee using ER and PBC")
1143     dev[0].dump_monitor()
1144     dev[1].dump_monitor()
1145     dev[1].request("WPS_PBC")
1146
1147     for i in range(0, 2):
1148         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1149         if ev is None:
1150             raise Exception("Enrollee discovery timed out")
1151         if enrollee in ev:
1152             break
1153         if i == 1:
1154             raise Exception("Expected Enrollee not found")
1155     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1156         raise Exception("Unknown UUID not reported")
1157     logger.info("Use learned network configuration on ER")
1158     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1159     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1160         raise Exception("WPS_ER_PBC failed")
1161
1162     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1163     if ev is None:
1164         raise Exception("Enrollee did not report success")
1165     dev[1].wait_connected(timeout=15)
1166     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1167     if ev is None:
1168         raise Exception("WPS ER did not report success")
1169     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1170
1171 def test_ap_wps_er_pbc_overlap(dev, apdev):
1172     """WPS ER connected to AP and PBC session overlap"""
1173     try:
1174         _test_ap_wps_er_pbc_overlap(dev, apdev)
1175     finally:
1176         dev[0].request("WPS_ER_STOP")
1177
1178 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1179     ssid = "wps-er-add-enrollee-pbc"
1180     ap_pin = "12345670"
1181     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1182     hostapd.add_ap(apdev[0]['ifname'],
1183                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1184                      "wpa_passphrase": "12345678", "wpa": "2",
1185                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1186                      "device_name": "Wireless AP", "manufacturer": "Company",
1187                      "model_name": "WAP", "model_number": "123",
1188                      "serial_number": "12345", "device_type": "6-0050F204-1",
1189                      "os_version": "01020300",
1190                      "config_methods": "label push_button",
1191                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1192     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1193     dev[0].dump_monitor()
1194     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1195
1196     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1197     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1198     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1199     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1200
1201     dev[0].dump_monitor()
1202     dev[0].request("WPS_ER_START ifname=lo")
1203
1204     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1205     if ev is None:
1206         raise Exception("AP discovery timed out")
1207     if ap_uuid not in ev:
1208         raise Exception("Expected AP UUID not found")
1209
1210     # verify BSSID selection of the AP instead of UUID
1211     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1212         raise Exception("Could not select AP based on BSSID")
1213
1214     dev[0].dump_monitor()
1215     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1216     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1217     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1218     if ev is None:
1219         raise Exception("PBC scan failed")
1220     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1221     if ev is None:
1222         raise Exception("PBC scan failed")
1223     found1 = False
1224     found2 = False
1225     addr1 = dev[1].own_addr()
1226     addr2 = dev[2].own_addr()
1227     for i in range(3):
1228         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1229         if ev is None:
1230             raise Exception("Enrollee discovery timed out")
1231         if addr1 in ev:
1232             found1 = True
1233             if found2:
1234                 break
1235         if addr2 in ev:
1236             found2 = True
1237             if found1:
1238                 break
1239     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1240         raise Exception("PBC overlap not reported")
1241     dev[1].request("WPS_CANCEL")
1242     dev[2].request("WPS_CANCEL")
1243     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1244         raise Exception("Invalid WPS_ER_PBC accepted")
1245
1246 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1247     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1248     try:
1249         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1250     finally:
1251         dev[0].request("WPS_ER_STOP")
1252
1253 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1254     ssid = "wps-er-add-enrollee-pbc"
1255     ap_pin = "12345670"
1256     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1257     hostapd.add_ap(apdev[0]['ifname'],
1258                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1259                      "wpa_passphrase": "12345678", "wpa": "2",
1260                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1261                      "device_name": "Wireless AP", "manufacturer": "Company",
1262                      "model_name": "WAP", "model_number": "123",
1263                      "serial_number": "12345", "device_type": "6-0050F204-1",
1264                      "os_version": "01020300",
1265                      "config_methods": "label push_button",
1266                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1267     logger.info("Learn AP configuration")
1268     dev[0].request("SET wps_version_number 0x10")
1269     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1270     dev[0].dump_monitor()
1271     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1272     status = dev[0].get_status()
1273     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1274         raise Exception("Not fully connected")
1275
1276     logger.info("Start ER")
1277     dev[0].request("WPS_ER_START ifname=lo")
1278     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1279     if ev is None:
1280         raise Exception("AP discovery timed out")
1281     if ap_uuid not in ev:
1282         raise Exception("Expected AP UUID not found")
1283
1284     logger.info("Use learned network configuration on ER")
1285     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1286
1287     logger.info("Add Enrollee using ER and PIN")
1288     enrollee = dev[1].p2p_interface_addr()
1289     pin = dev[1].wps_read_pin()
1290     dev[0].dump_monitor()
1291     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1292     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1293     dev[1].dump_monitor()
1294     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1295     dev[1].wait_connected(timeout=30)
1296     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1297     if ev is None:
1298         raise Exception("WPS ER did not report success")
1299
1300 def test_ap_wps_er_config_ap(dev, apdev):
1301     """WPS ER configuring AP over UPnP"""
1302     try:
1303         _test_ap_wps_er_config_ap(dev, apdev)
1304     finally:
1305         dev[0].request("WPS_ER_STOP")
1306
1307 def _test_ap_wps_er_config_ap(dev, apdev):
1308     ssid = "wps-er-ap-config"
1309     ap_pin = "12345670"
1310     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1311     hostapd.add_ap(apdev[0]['ifname'],
1312                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1313                      "wpa_passphrase": "12345678", "wpa": "2",
1314                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1315                      "device_name": "Wireless AP", "manufacturer": "Company",
1316                      "model_name": "WAP", "model_number": "123",
1317                      "serial_number": "12345", "device_type": "6-0050F204-1",
1318                      "os_version": "01020300",
1319                      "config_methods": "label push_button",
1320                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1321
1322     logger.info("Connect ER to the AP")
1323     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1324
1325     logger.info("WPS configuration step")
1326     dev[0].request("WPS_ER_START ifname=lo")
1327     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1328     if ev is None:
1329         raise Exception("AP discovery timed out")
1330     if ap_uuid not in ev:
1331         raise Exception("Expected AP UUID not found")
1332     new_passphrase = "1234567890"
1333     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1334                    ssid.encode("hex") + " WPA2PSK CCMP " +
1335                    new_passphrase.encode("hex"))
1336     ev = dev[0].wait_event(["WPS-SUCCESS"])
1337     if ev is None:
1338         raise Exception("WPS ER configuration operation timed out")
1339     dev[0].wait_disconnected(timeout=10)
1340     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1341
1342     logger.info("WPS ER restart")
1343     dev[0].request("WPS_ER_START")
1344     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1345     if ev is None:
1346         raise Exception("AP discovery timed out on ER restart")
1347     if ap_uuid not in ev:
1348         raise Exception("Expected AP UUID not found on ER restart")
1349     if "OK" not in dev[0].request("WPS_ER_STOP"):
1350         raise Exception("WPS_ER_STOP failed")
1351     if "OK" not in dev[0].request("WPS_ER_STOP"):
1352         raise Exception("WPS_ER_STOP failed")
1353
1354 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1355     """WPS ER caching AP settings"""
1356     try:
1357         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1358     finally:
1359         dev[0].request("WPS_ER_STOP")
1360
1361 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1362     ssid = "wps-er-add-enrollee"
1363     ap_pin = "12345670"
1364     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1365     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1366                "wpa_passphrase": "12345678", "wpa": "2",
1367                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1368                "device_name": "Wireless AP", "manufacturer": "Company",
1369                "model_name": "WAP", "model_number": "123",
1370                "serial_number": "12345", "device_type": "6-0050F204-1",
1371                "os_version": "01020300",
1372                "config_methods": "label push_button",
1373                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1374     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1375     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1376     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1377     id = int(dev[0].list_networks()[0]['id'])
1378     dev[0].set_network(id, "scan_freq", "2412")
1379
1380     dev[0].request("WPS_ER_START ifname=lo")
1381     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1382     if ev is None:
1383         raise Exception("AP discovery timed out")
1384     if ap_uuid not in ev:
1385         raise Exception("Expected AP UUID not found")
1386
1387     dev[0].dump_monitor()
1388     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1389     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1390     if ev is None:
1391         raise Exception("AP learn timed out")
1392     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1393     if ev is None:
1394         raise Exception("WPS-FAIL after AP learn timed out")
1395     time.sleep(0.1)
1396
1397     hapd.disable()
1398
1399     for i in range(2):
1400         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1401                                  "CTRL-EVENT-DISCONNECTED" ],
1402                                timeout=15)
1403         if ev is None:
1404             raise Exception("AP removal or disconnection timed out")
1405
1406     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1407     for i in range(2):
1408         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1409                                timeout=15)
1410         if ev is None:
1411             raise Exception("AP discovery or connection timed out")
1412
1413     pin = dev[1].wps_read_pin()
1414     dev[0].dump_monitor()
1415     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1416
1417     time.sleep(0.2)
1418
1419     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1420     dev[1].dump_monitor()
1421     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1422     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1423     if ev is None:
1424         raise Exception("Enrollee did not report success")
1425     dev[1].wait_connected(timeout=15)
1426     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1427     if ev is None:
1428         raise Exception("WPS ER did not report success")
1429
1430     dev[0].dump_monitor()
1431     dev[0].request("WPS_ER_STOP")
1432
1433 def test_ap_wps_fragmentation(dev, apdev):
1434     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1435     ssid = "test-wps-fragmentation"
1436     appin = "12345670"
1437     hostapd.add_ap(apdev[0]['ifname'],
1438                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1439                      "wpa_passphrase": "12345678", "wpa": "3",
1440                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1441                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1442                      "fragment_size": "50" })
1443     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1444     logger.info("WPS provisioning step (PBC)")
1445     hapd.request("WPS_PBC")
1446     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1447     dev[0].dump_monitor()
1448     dev[0].request("SET wps_fragment_size 50")
1449     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1450     dev[0].wait_connected(timeout=30)
1451     status = dev[0].get_status()
1452     if status['wpa_state'] != 'COMPLETED':
1453         raise Exception("Not fully connected")
1454     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1455         raise Exception("Unexpected encryption configuration")
1456     if status['key_mgmt'] != 'WPA2-PSK':
1457         raise Exception("Unexpected key_mgmt")
1458
1459     logger.info("WPS provisioning step (PIN)")
1460     pin = dev[1].wps_read_pin()
1461     hapd.request("WPS_PIN any " + pin)
1462     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1463     dev[1].request("SET wps_fragment_size 50")
1464     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1465     dev[1].wait_connected(timeout=30)
1466     status = dev[1].get_status()
1467     if status['wpa_state'] != 'COMPLETED':
1468         raise Exception("Not fully connected")
1469     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1470         raise Exception("Unexpected encryption configuration")
1471     if status['key_mgmt'] != 'WPA2-PSK':
1472         raise Exception("Unexpected key_mgmt")
1473
1474     logger.info("WPS connection as registrar")
1475     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1476     dev[2].request("SET wps_fragment_size 50")
1477     dev[2].wps_reg(apdev[0]['bssid'], appin)
1478     status = dev[2].get_status()
1479     if status['wpa_state'] != 'COMPLETED':
1480         raise Exception("Not fully connected")
1481     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1482         raise Exception("Unexpected encryption configuration")
1483     if status['key_mgmt'] != 'WPA2-PSK':
1484         raise Exception("Unexpected key_mgmt")
1485
1486 def test_ap_wps_new_version_sta(dev, apdev):
1487     """WPS compatibility with new version number on the station"""
1488     ssid = "test-wps-ver"
1489     hostapd.add_ap(apdev[0]['ifname'],
1490                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1491                      "wpa_passphrase": "12345678", "wpa": "2",
1492                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1493     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1494     logger.info("WPS provisioning step")
1495     hapd.request("WPS_PBC")
1496     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1497     dev[0].dump_monitor()
1498     dev[0].request("SET wps_version_number 0x43")
1499     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1500     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1501     dev[0].wait_connected(timeout=30)
1502
1503 def test_ap_wps_new_version_ap(dev, apdev):
1504     """WPS compatibility with new version number on the AP"""
1505     ssid = "test-wps-ver"
1506     hostapd.add_ap(apdev[0]['ifname'],
1507                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1508                      "wpa_passphrase": "12345678", "wpa": "2",
1509                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1510     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1511     logger.info("WPS provisioning step")
1512     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1513         raise Exception("Failed to enable test functionality")
1514     hapd.request("WPS_PBC")
1515     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1516     dev[0].dump_monitor()
1517     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1518     dev[0].wait_connected(timeout=30)
1519     hapd.request("SET wps_version_number 0x20")
1520
1521 def test_ap_wps_check_pin(dev, apdev):
1522     """Verify PIN checking through control interface"""
1523     hostapd.add_ap(apdev[0]['ifname'],
1524                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1525                      "wpa_passphrase": "12345678", "wpa": "2",
1526                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1527     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1528     for t in [ ("12345670", "12345670"),
1529                ("12345678", "FAIL-CHECKSUM"),
1530                ("12345", "FAIL"),
1531                ("123456789", "FAIL"),
1532                ("1234-5670", "12345670"),
1533                ("1234 5670", "12345670"),
1534                ("1-2.3:4 5670", "12345670") ]:
1535         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1536         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1537         if res != res2:
1538             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1539         if res != t[1]:
1540             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1541
1542     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1543         raise Exception("Unexpected WPS_CHECK_PIN success")
1544     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1545         raise Exception("Unexpected WPS_CHECK_PIN success")
1546
1547     for i in range(0, 10):
1548         pin = dev[0].request("WPS_PIN get")
1549         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1550         if pin != rpin:
1551             raise Exception("Random PIN validation failed for " + pin)
1552
1553 def test_ap_wps_wep_config(dev, apdev):
1554     """WPS 2.0 AP rejecting WEP configuration"""
1555     ssid = "test-wps-config"
1556     appin = "12345670"
1557     hostapd.add_ap(apdev[0]['ifname'],
1558                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1559                      "ap_pin": appin})
1560     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1561     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1562     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1563                    "hello", no_wait=True)
1564     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1565     if ev is None:
1566         raise Exception("WPS-FAIL timed out")
1567     if "reason=2" not in ev:
1568         raise Exception("Unexpected reason code in WPS-FAIL")
1569     status = hapd.request("WPS_GET_STATUS")
1570     if "Last WPS result: Failed" not in status:
1571         raise Exception("WPS failure result not shown correctly")
1572     if "Failure Reason: WEP Prohibited" not in status:
1573         raise Exception("Failure reason not reported correctly")
1574     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1575         raise Exception("Peer address not shown correctly")
1576
1577 def test_ap_wps_wep_enroll(dev, apdev):
1578     """WPS 2.0 STA rejecting WEP configuration"""
1579     ssid = "test-wps-wep"
1580     hostapd.add_ap(apdev[0]['ifname'],
1581                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1582                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1583     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1584     hapd.request("WPS_PBC")
1585     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1586     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1587     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1588     if ev is None:
1589         raise Exception("WPS-FAIL event timed out")
1590     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1591         raise Exception("Unexpected WPS-FAIL event: " + ev)
1592
1593 def test_ap_wps_ie_fragmentation(dev, apdev):
1594     """WPS AP using fragmented WPS IE"""
1595     ssid = "test-wps-ie-fragmentation"
1596     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1597                "wpa_passphrase": "12345678", "wpa": "2",
1598                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1599                "device_name": "1234567890abcdef1234567890abcdef",
1600                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1601                "model_name": "1234567890abcdef1234567890abcdef",
1602                "model_number": "1234567890abcdef1234567890abcdef",
1603                "serial_number": "1234567890abcdef1234567890abcdef" }
1604     hostapd.add_ap(apdev[0]['ifname'], params)
1605     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1606     hapd.request("WPS_PBC")
1607     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1608     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1609     dev[0].wait_connected(timeout=30)
1610     bss = dev[0].get_bss(apdev[0]['bssid'])
1611     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1612         logger.info("Device Name not received correctly")
1613         logger.info(bss)
1614         # This can fail if Probe Response frame is missed and Beacon frame was
1615         # used to fill in the BSS entry. This can happen, e.g., during heavy
1616         # load every now and then and is not really an error, so try to
1617         # workaround by runnign another scan.
1618         dev[0].scan(freq="2412", only_new=True)
1619         bss = dev[0].get_bss(apdev[0]['bssid'])
1620         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1621             logger.info(bss)
1622             raise Exception("Device Name not received correctly")
1623     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1624         raise Exception("Unexpected number of WPS IEs")
1625
1626 def get_psk(pskfile):
1627     psks = {}
1628     with open(pskfile, "r") as f:
1629         lines = f.read().splitlines()
1630         for l in lines:
1631             if l == "# WPA PSKs":
1632                 continue
1633             (addr,psk) = l.split(' ')
1634             psks[addr] = psk
1635     return psks
1636
1637 def test_ap_wps_per_station_psk(dev, apdev):
1638     """WPS PBC provisioning with per-station PSK"""
1639     addr0 = dev[0].own_addr()
1640     addr1 = dev[1].own_addr()
1641     addr2 = dev[2].own_addr()
1642     ssid = "wps"
1643     appin = "12345670"
1644     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1645     try:
1646         os.remove(pskfile)
1647     except:
1648         pass
1649
1650     try:
1651         with open(pskfile, "w") as f:
1652             f.write("# WPA PSKs\n")
1653
1654         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1655                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1656                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1657                    "wpa_psk_file": pskfile }
1658         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1659
1660         logger.info("First enrollee")
1661         hapd.request("WPS_PBC")
1662         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1663         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1664         dev[0].wait_connected(timeout=30)
1665
1666         logger.info("Second enrollee")
1667         hapd.request("WPS_PBC")
1668         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1669         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1670         dev[1].wait_connected(timeout=30)
1671
1672         logger.info("External registrar")
1673         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1674         dev[2].wps_reg(apdev[0]['bssid'], appin)
1675
1676         logger.info("Verifying PSK results")
1677         psks = get_psk(pskfile)
1678         if addr0 not in psks:
1679             raise Exception("No PSK recorded for sta0")
1680         if addr1 not in psks:
1681             raise Exception("No PSK recorded for sta1")
1682         if addr2 not in psks:
1683             raise Exception("No PSK recorded for sta2")
1684         if psks[addr0] == psks[addr1]:
1685             raise Exception("Same PSK recorded for sta0 and sta1")
1686         if psks[addr0] == psks[addr2]:
1687             raise Exception("Same PSK recorded for sta0 and sta2")
1688         if psks[addr1] == psks[addr2]:
1689             raise Exception("Same PSK recorded for sta1 and sta2")
1690
1691         dev[0].request("REMOVE_NETWORK all")
1692         logger.info("Second external registrar")
1693         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1694         dev[0].wps_reg(apdev[0]['bssid'], appin)
1695         psks2 = get_psk(pskfile)
1696         if addr0 not in psks2:
1697             raise Exception("No PSK recorded for sta0(reg)")
1698         if psks[addr0] == psks2[addr0]:
1699             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
1700     finally:
1701         os.remove(pskfile)
1702
1703 def test_ap_wps_per_station_psk_failure(dev, apdev):
1704     """WPS PBC provisioning with per-station PSK (file not writable)"""
1705     addr0 = dev[0].p2p_dev_addr()
1706     addr1 = dev[1].p2p_dev_addr()
1707     addr2 = dev[2].p2p_dev_addr()
1708     ssid = "wps"
1709     appin = "12345670"
1710     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1711     try:
1712         os.remove(pskfile)
1713     except:
1714         pass
1715
1716     try:
1717         with open(pskfile, "w") as f:
1718             f.write("# WPA PSKs\n")
1719
1720         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1721                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1722                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1723                    "wpa_psk_file": pskfile }
1724         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1725         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
1726             raise Exception("Failed to set wpa_psk_file")
1727
1728         logger.info("First enrollee")
1729         hapd.request("WPS_PBC")
1730         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1731         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1732         dev[0].wait_connected(timeout=30)
1733
1734         logger.info("Second enrollee")
1735         hapd.request("WPS_PBC")
1736         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1737         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1738         dev[1].wait_connected(timeout=30)
1739
1740         logger.info("External registrar")
1741         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1742         dev[2].wps_reg(apdev[0]['bssid'], appin)
1743
1744         logger.info("Verifying PSK results")
1745         psks = get_psk(pskfile)
1746         if len(psks) > 0:
1747             raise Exception("PSK recorded unexpectedly")
1748     finally:
1749         os.remove(pskfile)
1750
1751 def test_ap_wps_pin_request_file(dev, apdev):
1752     """WPS PIN provisioning with configured AP"""
1753     ssid = "wps"
1754     pinfile = "/tmp/ap_wps_pin_request_file.log"
1755     if os.path.exists(pinfile):
1756         os.remove(pinfile)
1757     hostapd.add_ap(apdev[0]['ifname'],
1758                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1759                      "wps_pin_requests": pinfile,
1760                      "wpa_passphrase": "12345678", "wpa": "2",
1761                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
1762     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1763     uuid = dev[0].get_status_field("uuid")
1764     pin = dev[0].wps_read_pin()
1765     try:
1766         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1767         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1768         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
1769         if ev is None:
1770             raise Exception("PIN needed event not shown")
1771         if uuid not in ev:
1772             raise Exception("UUID mismatch")
1773         dev[0].request("WPS_CANCEL")
1774         success = False
1775         with open(pinfile, "r") as f:
1776             lines = f.readlines()
1777             for l in lines:
1778                 if uuid in l:
1779                     success = True
1780                     break
1781         if not success:
1782             raise Exception("PIN request entry not in the log file")
1783     finally:
1784         try:
1785             os.remove(pinfile)
1786         except:
1787             pass
1788
1789 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
1790     """WPS auto-setup with configuration file"""
1791     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
1792     ifname = apdev[0]['ifname']
1793     try:
1794         with open(conffile, "w") as f:
1795             f.write("driver=nl80211\n")
1796             f.write("hw_mode=g\n")
1797             f.write("channel=1\n")
1798             f.write("ieee80211n=1\n")
1799             f.write("interface=%s\n" % ifname)
1800             f.write("ctrl_interface=/var/run/hostapd\n")
1801             f.write("ssid=wps\n")
1802             f.write("eap_server=1\n")
1803             f.write("wps_state=1\n")
1804         hostapd.add_bss('phy3', ifname, conffile)
1805         hapd = hostapd.Hostapd(ifname)
1806         hapd.request("WPS_PBC")
1807         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1808         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1809         dev[0].wait_connected(timeout=30)
1810         with open(conffile, "r") as f:
1811             lines = f.read().splitlines()
1812             vals = dict()
1813             for l in lines:
1814                 try:
1815                     [name,value] = l.split('=', 1)
1816                     vals[name] = value
1817                 except ValueError, e:
1818                     if "# WPS configuration" in l:
1819                         pass
1820                     else:
1821                         raise Exception("Unexpected configuration line: " + l)
1822         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
1823             raise Exception("Incorrect configuration: " + str(vals))
1824     finally:
1825         try:
1826             os.remove(conffile)
1827         except:
1828             pass
1829
1830 def test_ap_wps_pbc_timeout(dev, apdev, params):
1831     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
1832     if not params['long']:
1833         raise HwsimSkip("Skip test case with long duration due to --long not specified")
1834     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1835     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1836
1837     location = ssdp_get_location(ap_uuid)
1838     urls = upnp_get_urls(location)
1839     eventurl = urlparse.urlparse(urls['event_sub_url'])
1840     ctrlurl = urlparse.urlparse(urls['control_url'])
1841
1842     url = urlparse.urlparse(location)
1843     conn = httplib.HTTPConnection(url.netloc)
1844
1845     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
1846         def handle(self):
1847             data = self.rfile.readline().strip()
1848             logger.debug(data)
1849             self.wfile.write(gen_wps_event())
1850
1851     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
1852     server.timeout = 1
1853
1854     headers = { "callback": '<http://127.0.0.1:12345/event>',
1855                 "NT": "upnp:event",
1856                 "timeout": "Second-1234" }
1857     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
1858     resp = conn.getresponse()
1859     if resp.status != 200:
1860         raise Exception("Unexpected HTTP response: %d" % resp.status)
1861     sid = resp.getheader("sid")
1862     logger.debug("Subscription SID " + sid)
1863
1864     msg = '''<?xml version="1.0"?>
1865 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1866 <s:Body>
1867 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
1868 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
1869 VFi5hrLk
1870 </NewMessage>
1871 </u:SetSelectedRegistrar>
1872 </s:Body>
1873 </s:Envelope>'''
1874     headers = { "Content-type": 'text/xml; charset="utf-8"' }
1875     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
1876     conn.request("POST", ctrlurl.path, msg, headers)
1877     resp = conn.getresponse()
1878     if resp.status != 200:
1879         raise Exception("Unexpected HTTP response: %d" % resp.status)
1880
1881     server.handle_request()
1882
1883     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
1884     if "OK" not in dev[0].request("WPS_PBC"):
1885         raise Exception("WPS_PBC failed")
1886
1887     start = os.times()[4]
1888
1889     server.handle_request()
1890     dev[1].request("BSS_FLUSH 0")
1891     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
1892                         only_new=True)
1893     bss = dev[1].get_bss(apdev[0]['bssid'])
1894     logger.debug("BSS: " + str(bss))
1895     if '[WPS-AUTH]' not in bss['flags']:
1896         raise Exception("WPS not indicated authorized")
1897
1898     server.handle_request()
1899
1900     wps_timeout_seen = False
1901
1902     while True:
1903         hapd.dump_monitor()
1904         dev[1].dump_monitor()
1905         if not wps_timeout_seen:
1906             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
1907             if ev is not None:
1908                 logger.info("PBC timeout seen")
1909                 wps_timeout_seen = True
1910         else:
1911             dev[0].dump_monitor()
1912         now = os.times()[4]
1913         if now - start > 130:
1914             raise Exception("Selected registration information not removed")
1915         dev[1].request("BSS_FLUSH 0")
1916         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
1917                             only_new=True)
1918         bss = dev[1].get_bss(apdev[0]['bssid'])
1919         logger.debug("BSS: " + str(bss))
1920         if '[WPS-AUTH]' not in bss['flags']:
1921             break
1922         server.handle_request()
1923
1924     server.server_close()
1925
1926     if wps_timeout_seen:
1927         return
1928
1929     now = os.times()[4]
1930     if now < start + 150:
1931         dur = start + 150 - now
1932     else:
1933         dur = 1
1934     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
1935     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
1936     if ev is None:
1937         raise Exception("WPS-TIMEOUT not reported")
1938
1939 def add_ssdp_ap(ifname, ap_uuid):
1940     ssid = "wps-ssdp"
1941     ap_pin = "12345670"
1942     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1943                "wpa_passphrase": "12345678", "wpa": "2",
1944                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1945                "device_name": "Wireless AP", "manufacturer": "Company",
1946                "model_name": "WAP", "model_number": "123",
1947                "serial_number": "12345", "device_type": "6-0050F204-1",
1948                "os_version": "01020300",
1949                "config_methods": "label push_button",
1950                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
1951                "friendly_name": "WPS Access Point",
1952                "manufacturer_url": "http://www.example.com/",
1953                "model_description": "Wireless Access Point",
1954                "model_url": "http://www.example.com/model/",
1955                "upc": "123456789012" }
1956     return hostapd.add_ap(ifname, params)
1957
1958 def ssdp_send(msg, no_recv=False):
1959     socket.setdefaulttimeout(1)
1960     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1961     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1962     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1963     sock.bind(("127.0.0.1", 0))
1964     sock.sendto(msg, ("239.255.255.250", 1900))
1965     if no_recv:
1966         return None
1967     return sock.recv(1000)
1968
1969 def ssdp_send_msearch(st):
1970     msg = '\r\n'.join([
1971             'M-SEARCH * HTTP/1.1',
1972             'HOST: 239.255.255.250:1900',
1973             'MX: 1',
1974             'MAN: "ssdp:discover"',
1975             'ST: ' + st,
1976             '', ''])
1977     return ssdp_send(msg)
1978
1979 def test_ap_wps_ssdp_msearch(dev, apdev):
1980     """WPS AP and SSDP M-SEARCH messages"""
1981     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1982     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1983
1984     msg = '\r\n'.join([
1985             'M-SEARCH * HTTP/1.1',
1986             'Host: 239.255.255.250:1900',
1987             'Mx: 1',
1988             'Man: "ssdp:discover"',
1989             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
1990             '', ''])
1991     ssdp_send(msg)
1992
1993     msg = '\r\n'.join([
1994             'M-SEARCH * HTTP/1.1',
1995             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
1996             'mx: \t1\t\t   ',
1997             'man: \t \t "ssdp:discover"   ',
1998             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
1999             '', ''])
2000     ssdp_send(msg)
2001
2002     ssdp_send_msearch("ssdp:all")
2003     ssdp_send_msearch("upnp:rootdevice")
2004     ssdp_send_msearch("uuid:" + ap_uuid)
2005     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2006     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2007
2008     msg = '\r\n'.join([
2009             'M-SEARCH * HTTP/1.1',
2010             'HOST:\t239.255.255.250:1900',
2011             'MAN: "ssdp:discover"',
2012             'MX: 130',
2013             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2014             '', ''])
2015     ssdp_send(msg, no_recv=True)
2016
2017 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2018     """WPS AP and invalid SSDP M-SEARCH messages"""
2019     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2020     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2021
2022     socket.setdefaulttimeout(1)
2023     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2024     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2025     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2026     sock.bind(("127.0.0.1", 0))
2027
2028     logger.debug("Missing MX")
2029     msg = '\r\n'.join([
2030             'M-SEARCH * HTTP/1.1',
2031             'HOST: 239.255.255.250:1900',
2032             'MAN: "ssdp:discover"',
2033             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2034             '', ''])
2035     sock.sendto(msg, ("239.255.255.250", 1900))
2036
2037     logger.debug("Negative MX")
2038     msg = '\r\n'.join([
2039             'M-SEARCH * HTTP/1.1',
2040             'HOST: 239.255.255.250:1900',
2041             'MX: -1',
2042             'MAN: "ssdp:discover"',
2043             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2044             '', ''])
2045     sock.sendto(msg, ("239.255.255.250", 1900))
2046
2047     logger.debug("Invalid MX")
2048     msg = '\r\n'.join([
2049             'M-SEARCH * HTTP/1.1',
2050             'HOST: 239.255.255.250:1900',
2051             'MX; 1',
2052             'MAN: "ssdp:discover"',
2053             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2054             '', ''])
2055     sock.sendto(msg, ("239.255.255.250", 1900))
2056
2057     logger.debug("Missing MAN")
2058     msg = '\r\n'.join([
2059             'M-SEARCH * HTTP/1.1',
2060             'HOST: 239.255.255.250:1900',
2061             'MX: 1',
2062             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2063             '', ''])
2064     sock.sendto(msg, ("239.255.255.250", 1900))
2065
2066     logger.debug("Invalid MAN")
2067     msg = '\r\n'.join([
2068             'M-SEARCH * HTTP/1.1',
2069             'HOST: 239.255.255.250:1900',
2070             'MX: 1',
2071             'MAN: foo',
2072             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2073             '', ''])
2074     sock.sendto(msg, ("239.255.255.250", 1900))
2075     msg = '\r\n'.join([
2076             'M-SEARCH * HTTP/1.1',
2077             'HOST: 239.255.255.250:1900',
2078             'MX: 1',
2079             'MAN; "ssdp:discover"',
2080             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2081             '', ''])
2082     sock.sendto(msg, ("239.255.255.250", 1900))
2083
2084     logger.debug("Missing HOST")
2085     msg = '\r\n'.join([
2086             'M-SEARCH * HTTP/1.1',
2087             'MAN: "ssdp:discover"',
2088             'MX: 1',
2089             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2090             '', ''])
2091     sock.sendto(msg, ("239.255.255.250", 1900))
2092
2093     logger.debug("Missing ST")
2094     msg = '\r\n'.join([
2095             'M-SEARCH * HTTP/1.1',
2096             'HOST: 239.255.255.250:1900',
2097             'MAN: "ssdp:discover"',
2098             'MX: 1',
2099             '', ''])
2100     sock.sendto(msg, ("239.255.255.250", 1900))
2101
2102     logger.debug("Mismatching ST")
2103     msg = '\r\n'.join([
2104             'M-SEARCH * HTTP/1.1',
2105             'HOST: 239.255.255.250:1900',
2106             'MAN: "ssdp:discover"',
2107             'MX: 1',
2108             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2109             '', ''])
2110     sock.sendto(msg, ("239.255.255.250", 1900))
2111     msg = '\r\n'.join([
2112             'M-SEARCH * HTTP/1.1',
2113             'HOST: 239.255.255.250:1900',
2114             'MAN: "ssdp:discover"',
2115             'MX: 1',
2116             'ST: foo:bar',
2117             '', ''])
2118     sock.sendto(msg, ("239.255.255.250", 1900))
2119     msg = '\r\n'.join([
2120             'M-SEARCH * HTTP/1.1',
2121             'HOST: 239.255.255.250:1900',
2122             'MAN: "ssdp:discover"',
2123             'MX: 1',
2124             'ST: foobar',
2125             '', ''])
2126     sock.sendto(msg, ("239.255.255.250", 1900))
2127
2128     logger.debug("Invalid ST")
2129     msg = '\r\n'.join([
2130             'M-SEARCH * HTTP/1.1',
2131             'HOST: 239.255.255.250:1900',
2132             'MAN: "ssdp:discover"',
2133             'MX: 1',
2134             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2135             '', ''])
2136     sock.sendto(msg, ("239.255.255.250", 1900))
2137
2138     logger.debug("Invalid M-SEARCH")
2139     msg = '\r\n'.join([
2140             'M+SEARCH * HTTP/1.1',
2141             'HOST: 239.255.255.250:1900',
2142             'MAN: "ssdp:discover"',
2143             'MX: 1',
2144             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2145             '', ''])
2146     sock.sendto(msg, ("239.255.255.250", 1900))
2147     msg = '\r\n'.join([
2148             'M-SEARCH-* HTTP/1.1',
2149             'HOST: 239.255.255.250:1900',
2150             'MAN: "ssdp:discover"',
2151             'MX: 1',
2152             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2153             '', ''])
2154     sock.sendto(msg, ("239.255.255.250", 1900))
2155
2156     logger.debug("Invalid message format")
2157     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2158     msg = '\r'.join([
2159             'M-SEARCH * HTTP/1.1',
2160             'HOST: 239.255.255.250:1900',
2161             'MAN: "ssdp:discover"',
2162             'MX: 1',
2163             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2164             '', ''])
2165     sock.sendto(msg, ("239.255.255.250", 1900))
2166
2167     try:
2168         r = sock.recv(1000)
2169         raise Exception("Unexpected M-SEARCH response: " + r)
2170     except socket.timeout:
2171         pass
2172
2173     logger.debug("Valid M-SEARCH")
2174     msg = '\r\n'.join([
2175             'M-SEARCH * HTTP/1.1',
2176             'HOST: 239.255.255.250:1900',
2177             'MAN: "ssdp:discover"',
2178             'MX: 1',
2179             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2180             '', ''])
2181     sock.sendto(msg, ("239.255.255.250", 1900))
2182
2183     try:
2184         r = sock.recv(1000)
2185         pass
2186     except socket.timeout:
2187         raise Exception("No SSDP response")
2188
2189 def test_ap_wps_ssdp_burst(dev, apdev):
2190     """WPS AP and SSDP burst"""
2191     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2192     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2193
2194     msg = '\r\n'.join([
2195             'M-SEARCH * HTTP/1.1',
2196             'HOST: 239.255.255.250:1900',
2197             'MAN: "ssdp:discover"',
2198             'MX: 1',
2199             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2200             '', ''])
2201     socket.setdefaulttimeout(1)
2202     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2203     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2204     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2205     sock.bind(("127.0.0.1", 0))
2206     for i in range(0, 25):
2207         sock.sendto(msg, ("239.255.255.250", 1900))
2208     resp = 0
2209     while True:
2210         try:
2211             r = sock.recv(1000)
2212             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2213                 raise Exception("Unexpected message: " + r)
2214             resp += 1
2215         except socket.timeout:
2216             break
2217     if resp < 20:
2218         raise Exception("Too few SSDP responses")
2219
2220     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2221     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2222     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2223     sock.bind(("127.0.0.1", 0))
2224     for i in range(0, 25):
2225         sock.sendto(msg, ("239.255.255.250", 1900))
2226     while True:
2227         try:
2228             r = sock.recv(1000)
2229             if ap_uuid in r:
2230                 break
2231         except socket.timeout:
2232             raise Exception("No SSDP response")
2233
2234 def ssdp_get_location(uuid):
2235     res = ssdp_send_msearch("uuid:" + uuid)
2236     location = None
2237     for l in res.splitlines():
2238         if l.lower().startswith("location:"):
2239             location = l.split(':', 1)[1].strip()
2240             break
2241     if location is None:
2242         raise Exception("No UPnP location found")
2243     return location
2244
2245 def upnp_get_urls(location):
2246     conn = urllib.urlopen(location)
2247     tree = ET.parse(conn)
2248     root = tree.getroot()
2249     urn = '{urn:schemas-upnp-org:device-1-0}'
2250     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2251     res = {}
2252     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2253     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2254     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2255     return res
2256
2257 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2258     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2259     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2260     ET.register_namespace('soapenv', soapns)
2261     ET.register_namespace('wfa', wpsns)
2262     attrib = {}
2263     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2264     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2265     body = ET.SubElement(root, "{%s}Body" % soapns)
2266     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2267     tree = ET.ElementTree(root)
2268     soap = StringIO.StringIO()
2269     tree.write(soap, xml_declaration=True, encoding='utf-8')
2270
2271     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2272     if include_soap_action:
2273         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2274     elif soap_action_override:
2275         headers["SOAPAction"] = soap_action_override
2276     conn.request("POST", path, soap.getvalue(), headers)
2277     return conn.getresponse()
2278
2279 def test_ap_wps_upnp(dev, apdev):
2280     """WPS AP and UPnP operations"""
2281     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2282     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2283
2284     location = ssdp_get_location(ap_uuid)
2285     urls = upnp_get_urls(location)
2286
2287     conn = urllib.urlopen(urls['scpd_url'])
2288     scpd = conn.read()
2289
2290     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2291     if conn.getcode() != 404:
2292         raise Exception("Unexpected HTTP response to GET unknown URL")
2293
2294     url = urlparse.urlparse(location)
2295     conn = httplib.HTTPConnection(url.netloc)
2296     #conn.set_debuglevel(1)
2297     headers = { "Content-type": 'text/xml; charset="utf-8"',
2298                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2299     conn.request("POST", "hello", "\r\n\r\n", headers)
2300     resp = conn.getresponse()
2301     if resp.status != 404:
2302         raise Exception("Unexpected HTTP response: %d" % resp.status)
2303
2304     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2305     resp = conn.getresponse()
2306     if resp.status != 501:
2307         raise Exception("Unexpected HTTP response: %d" % resp.status)
2308
2309     headers = { "Content-type": 'text/xml; charset="utf-8"',
2310                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2311     ctrlurl = urlparse.urlparse(urls['control_url'])
2312     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2313     resp = conn.getresponse()
2314     if resp.status != 401:
2315         raise Exception("Unexpected HTTP response: %d" % resp.status)
2316
2317     logger.debug("GetDeviceInfo without SOAPAction header")
2318     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2319                             include_soap_action=False)
2320     if resp.status != 401:
2321         raise Exception("Unexpected HTTP response: %d" % resp.status)
2322
2323     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2324     for act in [ "foo",
2325                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2326                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2327                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2328         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2329                                 include_soap_action=False,
2330                                 soap_action_override=act)
2331         if resp.status != 401:
2332             raise Exception("Unexpected HTTP response: %d" % resp.status)
2333
2334     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2335     if resp.status != 200:
2336         raise Exception("Unexpected HTTP response: %d" % resp.status)
2337     dev = resp.read()
2338     if "NewDeviceInfo" not in dev:
2339         raise Exception("Unexpected GetDeviceInfo response")
2340
2341     logger.debug("PutMessage without required parameters")
2342     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2343     if resp.status != 600:
2344         raise Exception("Unexpected HTTP response: %d" % resp.status)
2345
2346     logger.debug("PutWLANResponse without required parameters")
2347     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2348     if resp.status != 600:
2349         raise Exception("Unexpected HTTP response: %d" % resp.status)
2350
2351     logger.debug("SetSelectedRegistrar from unregistered ER")
2352     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2353     if resp.status != 501:
2354         raise Exception("Unexpected HTTP response: %d" % resp.status)
2355
2356     logger.debug("Unknown action")
2357     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2358     if resp.status != 401:
2359         raise Exception("Unexpected HTTP response: %d" % resp.status)
2360
2361 def test_ap_wps_upnp_subscribe(dev, apdev):
2362     """WPS AP and UPnP event subscription"""
2363     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2364     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2365
2366     location = ssdp_get_location(ap_uuid)
2367     urls = upnp_get_urls(location)
2368     eventurl = urlparse.urlparse(urls['event_sub_url'])
2369
2370     url = urlparse.urlparse(location)
2371     conn = httplib.HTTPConnection(url.netloc)
2372     #conn.set_debuglevel(1)
2373     headers = { "callback": '<http://127.0.0.1:12345/event>',
2374                 "timeout": "Second-1234" }
2375     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2376     resp = conn.getresponse()
2377     if resp.status != 412:
2378         raise Exception("Unexpected HTTP response: %d" % resp.status)
2379
2380     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2381     resp = conn.getresponse()
2382     if resp.status != 412:
2383         raise Exception("Unexpected HTTP response: %d" % resp.status)
2384
2385     headers = { "NT": "upnp:event",
2386                 "timeout": "Second-1234" }
2387     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2388     resp = conn.getresponse()
2389     if resp.status != 412:
2390         raise Exception("Unexpected HTTP response: %d" % resp.status)
2391
2392     headers = { "callback": '<http://127.0.0.1:12345/event>',
2393                 "NT": "upnp:foobar",
2394                 "timeout": "Second-1234" }
2395     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2396     resp = conn.getresponse()
2397     if resp.status != 400:
2398         raise Exception("Unexpected HTTP response: %d" % resp.status)
2399
2400     logger.debug("Valid subscription")
2401     headers = { "callback": '<http://127.0.0.1:12345/event>',
2402                 "NT": "upnp:event",
2403                 "timeout": "Second-1234" }
2404     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2405     resp = conn.getresponse()
2406     if resp.status != 200:
2407         raise Exception("Unexpected HTTP response: %d" % resp.status)
2408     sid = resp.getheader("sid")
2409     logger.debug("Subscription SID " + sid)
2410
2411     logger.debug("Invalid re-subscription")
2412     headers = { "NT": "upnp:event",
2413                 "sid": "123456734567854",
2414                 "timeout": "Second-1234" }
2415     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2416     resp = conn.getresponse()
2417     if resp.status != 400:
2418         raise Exception("Unexpected HTTP response: %d" % resp.status)
2419
2420     logger.debug("Invalid re-subscription")
2421     headers = { "NT": "upnp:event",
2422                 "sid": "uuid:123456734567854",
2423                 "timeout": "Second-1234" }
2424     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2425     resp = conn.getresponse()
2426     if resp.status != 400:
2427         raise Exception("Unexpected HTTP response: %d" % resp.status)
2428
2429     logger.debug("Invalid re-subscription")
2430     headers = { "callback": '<http://127.0.0.1:12345/event>',
2431                 "NT": "upnp:event",
2432                 "sid": sid,
2433                 "timeout": "Second-1234" }
2434     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2435     resp = conn.getresponse()
2436     if resp.status != 400:
2437         raise Exception("Unexpected HTTP response: %d" % resp.status)
2438
2439     logger.debug("SID mismatch in re-subscription")
2440     headers = { "NT": "upnp:event",
2441                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2442                 "timeout": "Second-1234" }
2443     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2444     resp = conn.getresponse()
2445     if resp.status != 412:
2446         raise Exception("Unexpected HTTP response: %d" % resp.status)
2447
2448     logger.debug("Valid re-subscription")
2449     headers = { "NT": "upnp:event",
2450                 "sid": sid,
2451                 "timeout": "Second-1234" }
2452     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2453     resp = conn.getresponse()
2454     if resp.status != 200:
2455         raise Exception("Unexpected HTTP response: %d" % resp.status)
2456     sid2 = resp.getheader("sid")
2457     logger.debug("Subscription SID " + sid2)
2458
2459     if sid != sid2:
2460         raise Exception("Unexpected SID change")
2461
2462     logger.debug("Valid re-subscription")
2463     headers = { "NT": "upnp:event",
2464                 "sid": "uuid: \t \t" + sid.split(':')[1],
2465                 "timeout": "Second-1234" }
2466     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2467     resp = conn.getresponse()
2468     if resp.status != 200:
2469         raise Exception("Unexpected HTTP response: %d" % resp.status)
2470
2471     logger.debug("Invalid unsubscription")
2472     headers = { "sid": sid }
2473     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2474     resp = conn.getresponse()
2475     if resp.status != 412:
2476         raise Exception("Unexpected HTTP response: %d" % resp.status)
2477     headers = { "foo": "bar" }
2478     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2479     resp = conn.getresponse()
2480     if resp.status != 412:
2481         raise Exception("Unexpected HTTP response: %d" % resp.status)
2482
2483     logger.debug("Valid unsubscription")
2484     headers = { "sid": sid }
2485     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2486     resp = conn.getresponse()
2487     if resp.status != 200:
2488         raise Exception("Unexpected HTTP response: %d" % resp.status)
2489
2490     logger.debug("Unsubscription for not existing SID")
2491     headers = { "sid": sid }
2492     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2493     resp = conn.getresponse()
2494     if resp.status != 412:
2495         raise Exception("Unexpected HTTP response: %d" % resp.status)
2496
2497     logger.debug("Invalid unsubscription")
2498     headers = { "sid": " \t \tfoo" }
2499     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2500     resp = conn.getresponse()
2501     if resp.status != 400:
2502         raise Exception("Unexpected HTTP response: %d" % resp.status)
2503
2504     logger.debug("Invalid unsubscription")
2505     headers = { "sid": "uuid:\t \tfoo" }
2506     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2507     resp = conn.getresponse()
2508     if resp.status != 400:
2509         raise Exception("Unexpected HTTP response: %d" % resp.status)
2510
2511     logger.debug("Invalid unsubscription")
2512     headers = { "NT": "upnp:event",
2513                 "sid": sid }
2514     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2515     resp = conn.getresponse()
2516     if resp.status != 400:
2517         raise Exception("Unexpected HTTP response: %d" % resp.status)
2518     headers = { "callback": '<http://127.0.0.1:12345/event>',
2519                 "sid": sid }
2520     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2521     resp = conn.getresponse()
2522     if resp.status != 400:
2523         raise Exception("Unexpected HTTP response: %d" % resp.status)
2524
2525     logger.debug("Valid subscription with multiple callbacks")
2526     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>',
2527                 "NT": "upnp:event",
2528                 "timeout": "Second-1234" }
2529     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2530     resp = conn.getresponse()
2531     if resp.status != 200:
2532         raise Exception("Unexpected HTTP response: %d" % resp.status)
2533     sid = resp.getheader("sid")
2534     logger.debug("Subscription SID " + sid)
2535
2536     # Force subscription to be deleted due to errors
2537     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2538     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2539     with alloc_fail(hapd, 1, "event_build_message"):
2540         for i in range(10):
2541             dev[1].dump_monitor()
2542             dev[2].dump_monitor()
2543             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2544             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2545             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2546             dev[1].request("WPS_CANCEL")
2547             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2548             dev[2].request("WPS_CANCEL")
2549             if i % 4 == 1:
2550                 time.sleep(1)
2551             else:
2552                 time.sleep(0.1)
2553     time.sleep(0.2)
2554
2555     headers = { "sid": sid }
2556     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2557     resp = conn.getresponse()
2558     if resp.status != 200 and resp.status != 412:
2559         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2560
2561     headers = { "callback": '<http://127.0.0.1:12345/event>',
2562                 "NT": "upnp:event",
2563                 "timeout": "Second-1234" }
2564     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2565         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2566         resp = conn.getresponse()
2567         if resp.status != 200:
2568             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2569         sid = resp.getheader("sid")
2570         logger.debug("Subscription SID " + sid)
2571
2572     headers = { "sid": sid }
2573     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2574     resp = conn.getresponse()
2575     if resp.status != 200:
2576         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2577
2578     headers = { "callback": '<http://127.0.0.1:12345/event>',
2579                 "NT": "upnp:event",
2580                 "timeout": "Second-1234" }
2581     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2582     resp = conn.getresponse()
2583     if resp.status != 200:
2584         raise Exception("Unexpected HTTP response: %d" % resp.status)
2585     sid = resp.getheader("sid")
2586     logger.debug("Subscription SID " + sid)
2587
2588     with alloc_fail(hapd, 1, "=event_add"):
2589         for i in range(2):
2590             dev[1].dump_monitor()
2591             dev[2].dump_monitor()
2592             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2593             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2594             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2595             dev[1].request("WPS_CANCEL")
2596             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2597             dev[2].request("WPS_CANCEL")
2598             if i == 0:
2599                 time.sleep(1)
2600             else:
2601                 time.sleep(0.1)
2602
2603     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2604     resp = conn.getresponse()
2605     if resp.status != 200:
2606         raise Exception("Unexpected HTTP response: %d" % resp.status)
2607
2608     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
2609         dev[1].dump_monitor()
2610         dev[2].dump_monitor()
2611         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2612         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2613         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2614         dev[1].request("WPS_CANCEL")
2615         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2616         dev[2].request("WPS_CANCEL")
2617         time.sleep(0.1)
2618
2619     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
2620         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2621         resp = conn.getresponse()
2622         if resp.status != 500:
2623             raise Exception("Unexpected HTTP response: %d" % resp.status)
2624
2625     with alloc_fail(hapd, 1, "=subscription_start"):
2626         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2627         resp = conn.getresponse()
2628         if resp.status != 500:
2629             raise Exception("Unexpected HTTP response: %d" % resp.status)
2630
2631     headers = { "callback": '',
2632                 "NT": "upnp:event",
2633                 "timeout": "Second-1234" }
2634     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2635     resp = conn.getresponse()
2636     if resp.status != 500:
2637         raise Exception("Unexpected HTTP response: %d" % resp.status)
2638
2639     headers = { "callback": ' <',
2640                 "NT": "upnp:event",
2641                 "timeout": "Second-1234" }
2642     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2643     resp = conn.getresponse()
2644     if resp.status != 500:
2645         raise Exception("Unexpected HTTP response: %d" % resp.status)
2646
2647     headers = { "callback": '<http://127.0.0.1:12345/event>',
2648                 "NT": "upnp:event",
2649                 "timeout": "Second-1234" }
2650     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
2651         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2652         resp = conn.getresponse()
2653         if resp.status != 500:
2654             raise Exception("Unexpected HTTP response: %d" % resp.status)
2655
2656     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
2657         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2658         resp = conn.getresponse()
2659         if resp.status != 500:
2660             raise Exception("Unexpected HTTP response: %d" % resp.status)
2661
2662     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
2663         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2664         resp = conn.getresponse()
2665         if resp.status != 500:
2666             raise Exception("Unexpected HTTP response: %d" % resp.status)
2667
2668     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
2669         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2670         resp = conn.getresponse()
2671         if resp.status != 500:
2672             raise Exception("Unexpected HTTP response: %d" % resp.status)
2673
2674     for i in range(6):
2675         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
2676                     "NT": "upnp:event",
2677                     "timeout": "Second-1234" }
2678         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2679         resp = conn.getresponse()
2680         if resp.status != 200:
2681             raise Exception("Unexpected HTTP response: %d" % resp.status)
2682
2683     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
2684         dev[1].dump_monitor()
2685         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2686         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2687         dev[1].request("WPS_CANCEL")
2688         time.sleep(0.1)
2689
2690     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
2691         dev[1].dump_monitor()
2692         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2693         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2694         dev[1].request("WPS_CANCEL")
2695         time.sleep(0.1)
2696
2697     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
2698         dev[1].dump_monitor()
2699         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2700         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2701         dev[1].request("WPS_CANCEL")
2702         time.sleep(0.1)
2703
2704     hapd.disable()
2705     with alloc_fail(hapd, 1, "get_netif_info"):
2706         if "FAIL" not in hapd.request("ENABLE"):
2707             raise Exception("ENABLE succeeded during OOM")
2708
2709 def test_ap_wps_upnp_http_proto(dev, apdev):
2710     """WPS AP and UPnP/HTTP protocol testing"""
2711     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2712     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2713
2714     location = ssdp_get_location(ap_uuid)
2715
2716     url = urlparse.urlparse(location)
2717     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
2718     #conn.set_debuglevel(1)
2719
2720     conn.request("HEAD", "hello")
2721     resp = conn.getresponse()
2722     if resp.status != 501:
2723         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2724     conn.close()
2725
2726     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
2727         try:
2728             conn.request(cmd, "hello")
2729             resp = conn.getresponse()
2730         except Exception, e:
2731             pass
2732         conn.close()
2733
2734     headers = { "Content-Length": 'abc' }
2735     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2736     try:
2737         resp = conn.getresponse()
2738     except Exception, e:
2739         pass
2740     conn.close()
2741
2742     headers = { "Content-Length": '-10' }
2743     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2744     try:
2745         resp = conn.getresponse()
2746     except Exception, e:
2747         pass
2748     conn.close()
2749
2750     headers = { "Content-Length": '10000000000000' }
2751     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
2752     try:
2753         resp = conn.getresponse()
2754     except Exception, e:
2755         pass
2756     conn.close()
2757
2758     headers = { "Transfer-Encoding": 'abc' }
2759     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2760     resp = conn.getresponse()
2761     if resp.status != 501:
2762         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2763     conn.close()
2764
2765     headers = { "Transfer-Encoding": 'chunked' }
2766     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2767     resp = conn.getresponse()
2768     if resp.status != 501:
2769         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2770     conn.close()
2771
2772     # Too long a header
2773     conn.request("HEAD", 5000 * 'A')
2774     try:
2775         resp = conn.getresponse()
2776     except Exception, e:
2777         pass
2778     conn.close()
2779
2780     # Long URL but within header length limits
2781     conn.request("HEAD", 3000 * 'A')
2782     resp = conn.getresponse()
2783     if resp.status != 501:
2784         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2785     conn.close()
2786
2787     headers = { "Content-Length": '20' }
2788     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
2789     try:
2790         resp = conn.getresponse()
2791     except Exception, e:
2792         pass
2793     conn.close()
2794
2795     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
2796     resp = conn.getresponse()
2797     if resp.status != 404:
2798         raise Exception("Unexpected HTTP response: %d" % resp.status)
2799     conn.close()
2800
2801     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
2802     try:
2803         resp = conn.getresponse()
2804     except Exception, e:
2805         pass
2806     conn.close()
2807
2808 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
2809     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
2810     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2811     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2812
2813     location = ssdp_get_location(ap_uuid)
2814
2815     url = urlparse.urlparse(location)
2816     conn = httplib.HTTPConnection(url.netloc)
2817     #conn.set_debuglevel(1)
2818
2819     headers = { "Transfer-Encoding": 'chunked' }
2820     conn.request("POST", "hello",
2821                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
2822                  headers)
2823     resp = conn.getresponse()
2824     if resp.status != 404:
2825         raise Exception("Unexpected HTTP response: %d" % resp.status)
2826     conn.close()
2827
2828     conn.putrequest("POST", "hello")
2829     conn.putheader('Transfer-Encoding', 'chunked')
2830     conn.endheaders()
2831     conn.send("a\r\nabcdefghij\r\n")
2832     time.sleep(0.1)
2833     conn.send("2\r\nkl\r\n")
2834     conn.send("0\r\n\r\n")
2835     resp = conn.getresponse()
2836     if resp.status != 404:
2837         raise Exception("Unexpected HTTP response: %d" % resp.status)
2838     conn.close()
2839
2840     conn.putrequest("POST", "hello")
2841     conn.putheader('Transfer-Encoding', 'chunked')
2842     conn.endheaders()
2843     completed = False
2844     try:
2845         for i in range(20000):
2846             conn.send("1\r\nZ\r\n")
2847         conn.send("0\r\n\r\n")
2848         resp = conn.getresponse()
2849         completed = True
2850     except Exception, e:
2851         pass
2852     conn.close()
2853     if completed:
2854         raise Exception("Too long chunked request did not result in connection reset")
2855
2856     headers = { "Transfer-Encoding": 'chunked' }
2857     conn.request("POST", "hello", "80000000\r\na", headers)
2858     try:
2859         resp = conn.getresponse()
2860     except Exception, e:
2861         pass
2862     conn.close()
2863
2864     conn.request("POST", "hello", "10000000\r\na", headers)
2865     try:
2866         resp = conn.getresponse()
2867     except Exception, e:
2868         pass
2869     conn.close()
2870
2871 def test_ap_wps_disabled(dev, apdev):
2872     """WPS operations while WPS is disabled"""
2873     ssid = "test-wps-disabled"
2874     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
2875     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2876     if "FAIL" not in hapd.request("WPS_PBC"):
2877         raise Exception("WPS_PBC succeeded unexpectedly")
2878     if "FAIL" not in hapd.request("WPS_CANCEL"):
2879         raise Exception("WPS_CANCEL succeeded unexpectedly")
2880
2881 def test_ap_wps_mixed_cred(dev, apdev):
2882     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
2883     ssid = "test-wps-wep"
2884     hostapd.add_ap(apdev[0]['ifname'],
2885                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2886                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
2887     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2888     hapd.request("WPS_PBC")
2889     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2890     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2891     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
2892     if ev is None:
2893         raise Exception("WPS-SUCCESS event timed out")
2894     nets = dev[0].list_networks()
2895     if len(nets) != 1:
2896         raise Exception("Unexpected number of network blocks")
2897     id = nets[0]['id']
2898     proto = dev[0].get_network(id, "proto")
2899     if proto != "WPA RSN":
2900         raise Exception("Unexpected merged proto field value: " + proto)
2901     pairwise = dev[0].get_network(id, "pairwise")
2902     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
2903         raise Exception("Unexpected merged pairwise field value: " + pairwise)
2904
2905 def test_ap_wps_while_connected(dev, apdev):
2906     """WPS PBC provisioning while connected to another AP"""
2907     ssid = "test-wps-conf"
2908     hostapd.add_ap(apdev[0]['ifname'],
2909                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2910                      "wpa_passphrase": "12345678", "wpa": "2",
2911                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2912     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2913
2914     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2915     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2916
2917     logger.info("WPS provisioning step")
2918     hapd.request("WPS_PBC")
2919     dev[0].dump_monitor()
2920     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2921     dev[0].wait_connected(timeout=30)
2922     status = dev[0].get_status()
2923     if status['bssid'] != apdev[0]['bssid']:
2924         raise Exception("Unexpected BSSID")
2925
2926 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
2927     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
2928     ssid = "test-wps-conf"
2929     hostapd.add_ap(apdev[0]['ifname'],
2930                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2931                      "wpa_passphrase": "12345678", "wpa": "2",
2932                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2933     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2934
2935     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2936
2937     try:
2938         dev[0].request("STA_AUTOCONNECT 0")
2939         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2940
2941         logger.info("WPS provisioning step")
2942         hapd.request("WPS_PBC")
2943         dev[0].dump_monitor()
2944         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2945         dev[0].wait_connected(timeout=30)
2946         status = dev[0].get_status()
2947         if status['bssid'] != apdev[0]['bssid']:
2948             raise Exception("Unexpected BSSID")
2949     finally:
2950         dev[0].request("STA_AUTOCONNECT 1")
2951
2952 def test_ap_wps_from_event(dev, apdev):
2953     """WPS PBC event on AP to enable PBC"""
2954     ssid = "test-wps-conf"
2955     hapd = hostapd.add_ap(apdev[0]['ifname'],
2956                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2957                             "wpa_passphrase": "12345678", "wpa": "2",
2958                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2959     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2960     dev[0].dump_monitor()
2961     hapd.dump_monitor()
2962     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2963
2964     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
2965     if ev is None:
2966         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
2967     vals = ev.split(' ')
2968     if vals[1] != dev[0].p2p_interface_addr():
2969         raise Exception("Unexpected enrollee address: " + vals[1])
2970     if vals[5] != '4':
2971         raise Exception("Unexpected Device Password Id: " + vals[5])
2972     hapd.request("WPS_PBC")
2973     dev[0].wait_connected(timeout=30)
2974
2975 def test_ap_wps_ap_scan_2(dev, apdev):
2976     """AP_SCAN 2 for WPS"""
2977     ssid = "test-wps-conf"
2978     hapd = hostapd.add_ap(apdev[0]['ifname'],
2979                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2980                             "wpa_passphrase": "12345678", "wpa": "2",
2981                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2982     hapd.request("WPS_PBC")
2983
2984     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2985     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
2986
2987     if "OK" not in wpas.request("AP_SCAN 2"):
2988         raise Exception("Failed to set AP_SCAN 2")
2989
2990     wpas.flush_scan_cache()
2991     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
2992     wpas.request("WPS_PBC " + apdev[0]['bssid'])
2993     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
2994     if ev is None:
2995         raise Exception("WPS-SUCCESS event timed out")
2996     wpas.wait_connected(timeout=30)
2997     wpas.request("DISCONNECT")
2998     wpas.request("BSS_FLUSH 0")
2999     wpas.dump_monitor()
3000     wpas.request("REASSOCIATE")
3001     wpas.wait_connected(timeout=30)
3002
3003 def test_ap_wps_eapol_workaround(dev, apdev):
3004     """EAPOL workaround code path for 802.1X header length mismatch"""
3005     ssid = "test-wps"
3006     hostapd.add_ap(apdev[0]['ifname'],
3007                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3008     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3009     bssid = apdev[0]['bssid']
3010     hapd.request("SET ext_eapol_frame_io 1")
3011     dev[0].request("SET ext_eapol_frame_io 1")
3012     hapd.request("WPS_PBC")
3013     dev[0].request("WPS_PBC")
3014
3015     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3016     if ev is None:
3017         raise Exception("Timeout on EAPOL-TX from hostapd")
3018
3019     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3020     if "OK" not in res:
3021         raise Exception("EAPOL_RX to wpa_supplicant failed")
3022
3023 def test_ap_wps_iteration(dev, apdev):
3024     """WPS PIN and iterate through APs without selected registrar"""
3025     ssid = "test-wps-conf"
3026     hapd = hostapd.add_ap(apdev[0]['ifname'],
3027                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3028                             "wpa_passphrase": "12345678", "wpa": "2",
3029                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3030
3031     ssid2 = "test-wps-conf2"
3032     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3033                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3034                              "wpa_passphrase": "12345678", "wpa": "2",
3035                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3036
3037     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3038     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3039     dev[0].dump_monitor()
3040     pin = dev[0].request("WPS_PIN any")
3041
3042     # Wait for iteration through all WPS APs to happen before enabling any
3043     # Registrar.
3044     for i in range(2):
3045         ev = dev[0].wait_event(["Associated with"], timeout=30)
3046         if ev is None:
3047             raise Exception("No association seen")
3048         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3049         if ev is None:
3050             raise Exception("No M2D from AP")
3051         dev[0].wait_disconnected()
3052
3053     # Verify that each AP requested PIN
3054     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3055     if ev is None:
3056         raise Exception("No WPS-PIN-NEEDED event from AP")
3057     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3058     if ev is None:
3059         raise Exception("No WPS-PIN-NEEDED event from AP2")
3060
3061     # Provide PIN to one of the APs and verify that connection gets formed
3062     hapd.request("WPS_PIN any " + pin)
3063     dev[0].wait_connected(timeout=30)
3064
3065 def test_ap_wps_iteration_error(dev, apdev):
3066     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3067     ssid = "test-wps-conf-pin"
3068     hapd = hostapd.add_ap(apdev[0]['ifname'],
3069                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3070                             "wpa_passphrase": "12345678", "wpa": "2",
3071                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3072                             "wps_independent": "1" })
3073     hapd.request("SET ext_eapol_frame_io 1")
3074     bssid = apdev[0]['bssid']
3075     pin = dev[0].wps_read_pin()
3076     dev[0].request("WPS_PIN any " + pin)
3077
3078     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3079     if ev is None:
3080         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3081     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3082
3083     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3084     if ev is None:
3085         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3086     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3087     if ev is None:
3088         raise Exception("No CTRL-EVENT-EAP-STARTED")
3089
3090     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3091     # a case with an incorrectly behaving WPS AP.
3092
3093     # Start the real target AP and activate registrar on it.
3094     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3095                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3096                             "wpa_passphrase": "12345678", "wpa": "2",
3097                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3098                             "wps_independent": "1" })
3099     hapd2.request("WPS_PIN any " + pin)
3100
3101     dev[0].wait_disconnected(timeout=15)
3102     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3103     if ev is None:
3104         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3105     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3106     if ev is None:
3107         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3108     dev[0].wait_connected(timeout=15)
3109
3110 def test_ap_wps_priority(dev, apdev):
3111     """WPS PIN provisioning with configured AP and wps_priority"""
3112     ssid = "test-wps-conf-pin"
3113     hostapd.add_ap(apdev[0]['ifname'],
3114                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3115                      "wpa_passphrase": "12345678", "wpa": "2",
3116                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3117     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3118     logger.info("WPS provisioning step")
3119     pin = dev[0].wps_read_pin()
3120     hapd.request("WPS_PIN any " + pin)
3121     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3122     dev[0].dump_monitor()
3123     try:
3124         dev[0].request("SET wps_priority 6")
3125         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3126         dev[0].wait_connected(timeout=30)
3127         netw = dev[0].list_networks()
3128         prio = dev[0].get_network(netw[0]['id'], 'priority')
3129         if prio != '6':
3130             raise Exception("Unexpected network priority: " + prio)
3131     finally:
3132         dev[0].request("SET wps_priority 0")
3133
3134 def test_ap_wps_and_non_wps(dev, apdev):
3135     """WPS and non-WPS AP in single hostapd process"""
3136     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3137     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3138
3139     params = { "ssid": "no wps" }
3140     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3141
3142     appin = hapd.request("WPS_AP_PIN random")
3143     if "FAIL" in appin:
3144         raise Exception("Could not generate random AP PIN")
3145     if appin not in hapd.request("WPS_AP_PIN get"):
3146         raise Exception("Could not fetch current AP PIN")
3147
3148     if "FAIL" in hapd.request("WPS_PBC"):
3149         raise Exception("WPS_PBC failed")
3150     if "FAIL" in hapd.request("WPS_CANCEL"):
3151         raise Exception("WPS_CANCEL failed")
3152
3153 def test_ap_wps_init_oom(dev, apdev):
3154     """Initial AP configuration and OOM during PSK generation"""
3155     ssid = "test-wps"
3156     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3157     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3158
3159     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3160         pin = dev[0].wps_read_pin()
3161         hapd.request("WPS_PIN any " + pin)
3162         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3163         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3164         dev[0].wait_disconnected()
3165
3166     hapd.request("WPS_PIN any " + pin)
3167     dev[0].wait_connected(timeout=30)
3168
3169 def test_ap_wps_er_oom(dev, apdev):
3170     """WPS ER OOM in XML processing"""
3171     try:
3172         _test_ap_wps_er_oom(dev, apdev)
3173     finally:
3174         dev[0].request("WPS_ER_STOP")
3175         dev[1].request("WPS_CANCEL")
3176         dev[0].request("DISCONNECT")
3177
3178 def _test_ap_wps_er_oom(dev, apdev):
3179     ssid = "wps-er-ap-config"
3180     ap_pin = "12345670"
3181     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3182     hostapd.add_ap(apdev[0]['ifname'],
3183                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3184                      "wpa_passphrase": "12345678", "wpa": "2",
3185                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3186                      "device_name": "Wireless AP", "manufacturer": "Company",
3187                      "model_name": "WAP", "model_number": "123",
3188                      "serial_number": "12345", "device_type": "6-0050F204-1",
3189                      "os_version": "01020300",
3190                      "config_methods": "label push_button",
3191                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3192
3193     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3194
3195     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3196         dev[0].request("WPS_ER_START ifname=lo")
3197         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3198         if ev is not None:
3199             raise Exception("Unexpected AP discovery")
3200
3201     dev[0].request("WPS_ER_STOP")
3202     dev[0].request("WPS_ER_START ifname=lo")
3203     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3204     if ev is None:
3205         raise Exception("AP discovery timed out")
3206
3207     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3208     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3209         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3210         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3211         if ev is None:
3212             raise Exception("PBC scan failed")
3213         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3214         if ev is None:
3215             raise Exception("Enrollee discovery timed out")
3216
3217 def test_ap_wps_er_init_oom(dev, apdev):
3218     """WPS ER and OOM during init"""
3219     try:
3220         _test_ap_wps_er_init_oom(dev, apdev)
3221     finally:
3222         dev[0].request("WPS_ER_STOP")
3223
3224 def _test_ap_wps_er_init_oom(dev, apdev):
3225     with alloc_fail(dev[0], 1, "wps_er_init"):
3226         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3227             raise Exception("WPS_ER_START succeeded during OOM")
3228     with alloc_fail(dev[0], 1, "http_server_init"):
3229         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3230             raise Exception("WPS_ER_START succeeded during OOM")
3231     with alloc_fail(dev[0], 2, "http_server_init"):
3232         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3233             raise Exception("WPS_ER_START succeeded during OOM")
3234     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3235         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3236             raise Exception("WPS_ER_START succeeded during OOM")
3237     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3238         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3239             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3240
3241 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3242     """WPS events and wpa_cli action script"""
3243     logdir = os.path.abspath(test_params['logdir'])
3244     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3245     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3246     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3247
3248     with open(actionfile, 'w') as f:
3249         f.write('#!/bin/sh\n')
3250         f.write('echo $* >> %s\n' % logfile)
3251         # Kill the process and wait some time before returning to allow all the
3252         # pending events to be processed with some of this happening after the
3253         # eloop SIGALRM signal has been scheduled.
3254         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3255
3256     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3257              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3258
3259     ssid = "test-wps-conf"
3260     hostapd.add_ap(apdev[0]['ifname'],
3261                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3262                      "wpa_passphrase": "12345678", "wpa": "2",
3263                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3264     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3265
3266     prg = os.path.join(test_params['logdir'],
3267                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3268     if not os.path.exists(prg):
3269         prg = '../../wpa_supplicant/wpa_cli'
3270     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3271     subprocess.call(arg)
3272
3273     arg = [ 'ps', 'ax' ]
3274     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3275     out = cmd.communicate()[0]
3276     cmd.wait()
3277     logger.debug("Processes:\n" + out)
3278     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3279         raise Exception("Did not see wpa_cli running")
3280
3281     hapd.request("WPS_PIN any 12345670")
3282     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3283     dev[0].dump_monitor()
3284     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3285     dev[0].wait_connected(timeout=30)
3286
3287     for i in range(30):
3288         if not os.path.exists(pidfile):
3289             break
3290         time.sleep(0.1)
3291
3292     if not os.path.exists(logfile):
3293         raise Exception("wpa_cli action results file not found")
3294     with open(logfile, 'r') as f:
3295         res = f.read()
3296     if "WPS-SUCCESS" not in res:
3297         raise Exception("WPS-SUCCESS event not seen in action file")
3298
3299     arg = [ 'ps', 'ax' ]
3300     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3301     out = cmd.communicate()[0]
3302     cmd.wait()
3303     logger.debug("Remaining processes:\n" + out)
3304     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3305         raise Exception("wpa_cli still running")
3306
3307     if os.path.exists(pidfile):
3308         raise Exception("PID file not removed")
3309
3310 def test_ap_wps_er_ssdp_proto(dev, apdev):
3311     """WPS ER SSDP protocol testing"""
3312     try:
3313         _test_ap_wps_er_ssdp_proto(dev, apdev)
3314     finally:
3315         dev[0].request("WPS_ER_STOP")
3316
3317 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3318     socket.setdefaulttimeout(1)
3319     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3320     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3321     sock.bind(("239.255.255.250", 1900))
3322     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3323         raise Exception("Invalid filter accepted")
3324     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3325         raise Exception("WPS_ER_START with filter failed")
3326     (msg,addr) = sock.recvfrom(1000)
3327     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3328     if "M-SEARCH" not in msg:
3329         raise Exception("Not an M-SEARCH")
3330     sock.sendto("FOO", addr)
3331     time.sleep(0.1)
3332     dev[0].request("WPS_ER_STOP")
3333
3334     dev[0].request("WPS_ER_START ifname=lo")
3335     (msg,addr) = sock.recvfrom(1000)
3336     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3337     if "M-SEARCH" not in msg:
3338         raise Exception("Not an M-SEARCH")
3339     sock.sendto("FOO", addr)
3340     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3341     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3342     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3343     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3344     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3345     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3346     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3347     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3348     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3349     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3350     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3351     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)
3352     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3353     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3354         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)
3355         time.sleep(0.1)
3356     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3357         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)
3358         time.sleep(0.1)
3359
3360     # Add an AP with bogus URL
3361     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)
3362     # Update timeout on AP without updating URL
3363     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)
3364     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3365     if ev is None:
3366         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3367
3368     # Add an AP with a valid URL (but no server listing to it)
3369     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)
3370     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3371     if ev is None:
3372         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3373
3374     sock.close()
3375
3376 wps_event_url = None
3377
3378 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3379                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3380     payload = '''<?xml version="1.0"?>
3381 <root xmlns="urn:schemas-upnp-org:device-1-0">
3382 <specVersion>
3383 <major>1</major>
3384 <minor>0</minor>
3385 </specVersion>
3386 <device>
3387 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3388 <friendlyName>WPS Access Point</friendlyName>
3389 <manufacturer>Company</manufacturer>
3390 <modelName>WAP</modelName>
3391 <modelNumber>123</modelNumber>
3392 <serialNumber>12345</serialNumber>
3393 '''
3394     if udn:
3395         payload += '<UDN>' + udn + '</UDN>'
3396     payload += '''<serviceList>
3397 <service>
3398 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3399 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3400 <SCPDURL>wps_scpd.xml</SCPDURL>
3401 '''
3402     if controlURL:
3403         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3404     if eventSubURL:
3405         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3406     payload += '''</service>
3407 </serviceList>
3408 </device>
3409 </root>
3410 '''
3411     hdr = 'HTTP/1.1 200 OK\r\n' + \
3412           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3413           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3414           'Connection: close\r\n' + \
3415           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3416           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3417     return hdr + payload
3418
3419 def gen_wps_control(payload_override=None):
3420     payload = '''<?xml version="1.0"?>
3421 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3422 <s:Body>
3423 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3424 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3425 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3426 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3427 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3428 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3429 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3430 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3431 AAYANyoAASA=
3432 </NewDeviceInfo>
3433 </u:GetDeviceInfoResponse>
3434 </s:Body>
3435 </s:Envelope>
3436 '''
3437     if payload_override:
3438         payload = payload_override
3439     hdr = 'HTTP/1.1 200 OK\r\n' + \
3440           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3441           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3442           'Connection: close\r\n' + \
3443           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3444           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3445     return hdr + payload
3446
3447 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3448     payload = ""
3449     hdr = 'HTTP/1.1 200 OK\r\n' + \
3450           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3451           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3452           'Connection: close\r\n' + \
3453           'Content-Length: ' + str(len(payload)) + '\r\n'
3454     if sid:
3455         hdr += 'SID: ' + sid + '\r\n'
3456     hdr += 'Timeout: Second-1801\r\n' + \
3457           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3458     return hdr + payload
3459
3460 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3461     def handle(self):
3462         data = self.rfile.readline().strip()
3463         logger.info("HTTP server received: " + data)
3464         while True:
3465             hdr = self.rfile.readline().strip()
3466             if len(hdr) == 0:
3467                 break
3468             logger.info("HTTP header: " + hdr)
3469             if "CALLBACK:" in hdr:
3470                 global wps_event_url
3471                 wps_event_url = hdr.split(' ')[1].strip('<>')
3472
3473         if "GET /foo.xml" in data:
3474             self.handle_upnp_info()
3475         elif "POST /wps_control" in data:
3476             self.handle_wps_control()
3477         elif "SUBSCRIBE /wps_event" in data:
3478             self.handle_wps_event()
3479         else:
3480             self.handle_others(data)
3481
3482     def handle_upnp_info(self):
3483         self.wfile.write(gen_upnp_info())
3484
3485     def handle_wps_control(self):
3486         self.wfile.write(gen_wps_control())
3487
3488     def handle_wps_event(self):
3489         self.wfile.write(gen_wps_event())
3490
3491     def handle_others(self, data):
3492         logger.info("Ignore HTTP request: " + data)
3493
3494 class MyTCPServer(SocketServer.TCPServer):
3495     def __init__(self, addr, handler):
3496         self.allow_reuse_address = True
3497         SocketServer.TCPServer.__init__(self, addr, handler)
3498
3499 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3500                  location_url=None):
3501     socket.setdefaulttimeout(1)
3502     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3503     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3504     sock.bind(("239.255.255.250", 1900))
3505     dev.request("WPS_ER_START ifname=lo")
3506     for i in range(100):
3507         (msg,addr) = sock.recvfrom(1000)
3508         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3509         if "M-SEARCH" in msg:
3510             break
3511         if not wait_m_search:
3512             raise Exception("Not an M-SEARCH")
3513         if i == 99:
3514             raise Exception("No M-SEARCH seen")
3515
3516     # Add an AP with a valid URL and server listing to it
3517     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3518     if not location_url:
3519         location_url = 'http://127.0.0.1:12345/foo.xml'
3520     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:%s\r\ncache-control:max-age=%d\r\n\r\n" % (location_url, max_age), addr)
3521     server.timeout = 1
3522     return server,sock
3523
3524 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3525     sock.close()
3526     server.server_close()
3527
3528     if on_alloc_fail:
3529         done = False
3530         for i in range(50):
3531             res = dev.request("GET_ALLOC_FAIL")
3532             if res.startswith("0:"):
3533                 done = True
3534                 break
3535             time.sleep(0.1)
3536         if not done:
3537             raise Exception("No allocation failure reported")
3538     else:
3539         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3540         if ev is None:
3541             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3542     dev.request("WPS_ER_STOP")
3543
3544 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
3545     try:
3546         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3547         server,sock = wps_er_start(dev, handler, location_url=location_url)
3548         global wps_event_url
3549         wps_event_url = None
3550         server.handle_request()
3551         server.handle_request()
3552         server.handle_request()
3553         server.server_close()
3554         if no_event_url:
3555             if wps_event_url:
3556                 raise Exception("Received event URL unexpectedly")
3557             return
3558         if wps_event_url is None:
3559             raise Exception("Did not get event URL")
3560         logger.info("Event URL: " + wps_event_url)
3561     finally:
3562             dev.request("WPS_ER_STOP")
3563
3564 def send_wlanevent(url, uuid, data):
3565     conn = httplib.HTTPConnection(url.netloc)
3566     payload = '''<?xml version="1.0" encoding="utf-8"?>
3567 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3568 <e:property><STAStatus>1</STAStatus></e:property>
3569 <e:property><APStatus>1</APStatus></e:property>
3570 <e:property><WLANEvent>'''
3571     payload += base64.b64encode(data)
3572     payload += '</WLANEvent></e:property></e:propertyset>'
3573     headers = { "Content-type": 'text/xml; charset="utf-8"',
3574                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3575                 "HOST": url.netloc,
3576                 "NT": "upnp:event",
3577                 "SID": "uuid:" + uuid,
3578                 "SEQ": "0",
3579                 "Content-Length": str(len(payload)) }
3580     conn.request("NOTIFY", url.path, payload, headers)
3581     resp = conn.getresponse()
3582     if resp.status != 200:
3583         raise Exception("Unexpected HTTP response: %d" % resp.status)
3584
3585 def test_ap_wps_er_http_proto(dev, apdev):
3586     """WPS ER HTTP protocol testing"""
3587     try:
3588         _test_ap_wps_er_http_proto(dev, apdev)
3589     finally:
3590         dev[0].request("WPS_ER_STOP")
3591
3592 def _test_ap_wps_er_http_proto(dev, apdev):
3593     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3594     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
3595     global wps_event_url
3596     wps_event_url = None
3597     server.handle_request()
3598     server.handle_request()
3599     server.handle_request()
3600     server.server_close()
3601     if wps_event_url is None:
3602         raise Exception("Did not get event URL")
3603     logger.info("Event URL: " + wps_event_url)
3604
3605     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3606     if ev is None:
3607         raise Exception("No WPS-ER-AP-ADD event")
3608     if uuid not in ev:
3609         raise Exception("UUID mismatch")
3610
3611     sock.close()
3612
3613     logger.info("Valid Probe Request notification")
3614     url = urlparse.urlparse(wps_event_url)
3615     conn = httplib.HTTPConnection(url.netloc)
3616     payload = '''<?xml version="1.0" encoding="utf-8"?>
3617 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3618 <e:property><STAStatus>1</STAStatus></e:property>
3619 <e:property><APStatus>1</APStatus></e:property>
3620 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
3621 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
3622 RGV2aWNlIEEQSQAGADcqAAEg
3623 </WLANEvent></e:property>
3624 </e:propertyset>
3625 '''
3626     headers = { "Content-type": 'text/xml; charset="utf-8"',
3627                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3628                 "HOST": url.netloc,
3629                 "NT": "upnp:event",
3630                 "SID": "uuid:" + uuid,
3631                 "SEQ": "0",
3632                 "Content-Length": str(len(payload)) }
3633     conn.request("NOTIFY", url.path, payload, headers)
3634     resp = conn.getresponse()
3635     if resp.status != 200:
3636         raise Exception("Unexpected HTTP response: %d" % resp.status)
3637
3638     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
3639     if ev is None:
3640         raise Exception("No WPS-ER-ENROLLEE-ADD event")
3641     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
3642         raise Exception("No Enrollee UUID match")
3643
3644     logger.info("Incorrect event URL AP id")
3645     conn = httplib.HTTPConnection(url.netloc)
3646     conn.request("NOTIFY", url.path + '123', payload, headers)
3647     resp = conn.getresponse()
3648     if resp.status != 404:
3649         raise Exception("Unexpected HTTP response: %d" % resp.status)
3650
3651     logger.info("Missing AP id")
3652     conn = httplib.HTTPConnection(url.netloc)
3653     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
3654                  payload, headers)
3655     time.sleep(0.1)
3656
3657     logger.info("Incorrect event URL event id")
3658     conn = httplib.HTTPConnection(url.netloc)
3659     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
3660     time.sleep(0.1)
3661
3662     logger.info("Incorrect event URL prefix")
3663     conn = httplib.HTTPConnection(url.netloc)
3664     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
3665     resp = conn.getresponse()
3666     if resp.status != 404:
3667         raise Exception("Unexpected HTTP response: %d" % resp.status)
3668
3669     logger.info("Unsupported request")
3670     conn = httplib.HTTPConnection(url.netloc)
3671     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
3672     resp = conn.getresponse()
3673     if resp.status != 501:
3674         raise Exception("Unexpected HTTP response: %d" % resp.status)
3675
3676     logger.info("Unsupported request and OOM")
3677     with alloc_fail(dev[0], 1, "wps_er_http_req"):
3678         conn = httplib.HTTPConnection(url.netloc)
3679         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
3680         time.sleep(0.5)
3681
3682     logger.info("Too short WLANEvent")
3683     data = '\x00'
3684     send_wlanevent(url, uuid, data)
3685
3686     logger.info("Invalid WLANEventMAC")
3687     data = '\x00qwertyuiopasdfghjklzxcvbnm'
3688     send_wlanevent(url, uuid, data)
3689
3690     logger.info("Unknown WLANEventType")
3691     data = '\xff02:00:00:00:00:00'
3692     send_wlanevent(url, uuid, data)
3693
3694     logger.info("Probe Request notification without any attributes")
3695     data = '\x0102:00:00:00:00:00'
3696     send_wlanevent(url, uuid, data)
3697
3698     logger.info("Probe Request notification with invalid attribute")
3699     data = '\x0102:00:00:00:00:00\xff'
3700     send_wlanevent(url, uuid, data)
3701
3702     logger.info("EAP message without any attributes")
3703     data = '\x0202:00:00:00:00:00'
3704     send_wlanevent(url, uuid, data)
3705
3706     logger.info("EAP message with invalid attribute")
3707     data = '\x0202:00:00:00:00:00\xff'
3708     send_wlanevent(url, uuid, data)
3709
3710     logger.info("EAP message from new STA and not M1")
3711     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
3712     send_wlanevent(url, uuid, data)
3713
3714     logger.info("EAP message: M1")
3715     data = '\x0202:00:00:00:00:00'
3716     data += '\x10\x22\x00\x01\x04'
3717     data += '\x10\x47\x00\x10' + 16*'\x00'
3718     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
3719     data += '\x10\x1a\x00\x10' + 16*'\x00'
3720     data += '\x10\x32\x00\xc0' + 192*'\x00'
3721     data += '\x10\x04\x00\x02\x00\x00'
3722     data += '\x10\x10\x00\x02\x00\x00'
3723     data += '\x10\x0d\x00\x01\x00'
3724     data += '\x10\x08\x00\x02\x00\x00'
3725     data += '\x10\x44\x00\x01\x00'
3726     data += '\x10\x21\x00\x00'
3727     data += '\x10\x23\x00\x00'
3728     data += '\x10\x24\x00\x00'
3729     data += '\x10\x42\x00\x00'
3730     data += '\x10\x54\x00\x08' + 8*'\x00'
3731     data += '\x10\x11\x00\x00'
3732     data += '\x10\x3c\x00\x01\x00'
3733     data += '\x10\x02\x00\x02\x00\x00'
3734     data += '\x10\x12\x00\x02\x00\x00'
3735     data += '\x10\x09\x00\x02\x00\x00'
3736     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
3737     m1 = data
3738     send_wlanevent(url, uuid, data)
3739
3740     logger.info("EAP message: WSC_ACK")
3741     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
3742     send_wlanevent(url, uuid, data)
3743
3744     logger.info("EAP message: M1")
3745     send_wlanevent(url, uuid, m1)
3746
3747     logger.info("EAP message: WSC_NACK")
3748     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
3749     send_wlanevent(url, uuid, data)
3750
3751     logger.info("EAP message: M1 - Too long attribute values")
3752     data = '\x0202:00:00:00:00:00'
3753     data += '\x10\x11\x00\x21' + 33*'\x00'
3754     data += '\x10\x45\x00\x21' + 33*'\x00'
3755     data += '\x10\x42\x00\x21' + 33*'\x00'
3756     data += '\x10\x24\x00\x21' + 33*'\x00'
3757     data += '\x10\x23\x00\x21' + 33*'\x00'
3758     data += '\x10\x21\x00\x41' + 65*'\x00'
3759     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
3760     send_wlanevent(url, uuid, data)
3761
3762     logger.info("EAP message: M1 missing UUID-E")
3763     data = '\x0202:00:00:00:00:00'
3764     data += '\x10\x22\x00\x01\x04'
3765     send_wlanevent(url, uuid, data)
3766
3767     logger.info("EAP message: M1 missing MAC Address")
3768     data += '\x10\x47\x00\x10' + 16*'\x00'
3769     send_wlanevent(url, uuid, data)
3770
3771     logger.info("EAP message: M1 missing Enrollee Nonce")
3772     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
3773     send_wlanevent(url, uuid, data)
3774
3775     logger.info("EAP message: M1 missing Public Key")
3776     data += '\x10\x1a\x00\x10' + 16*'\x00'
3777     send_wlanevent(url, uuid, data)
3778
3779     logger.info("EAP message: M1 missing Authentication Type flags")
3780     data += '\x10\x32\x00\xc0' + 192*'\x00'
3781     send_wlanevent(url, uuid, data)
3782
3783     logger.info("EAP message: M1 missing Encryption Type Flags")
3784     data += '\x10\x04\x00\x02\x00\x00'
3785     send_wlanevent(url, uuid, data)
3786
3787     logger.info("EAP message: M1 missing Connection Type flags")
3788     data += '\x10\x10\x00\x02\x00\x00'
3789     send_wlanevent(url, uuid, data)
3790
3791     logger.info("EAP message: M1 missing Config Methods")
3792     data += '\x10\x0d\x00\x01\x00'
3793     send_wlanevent(url, uuid, data)
3794
3795     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
3796     data += '\x10\x08\x00\x02\x00\x00'
3797     send_wlanevent(url, uuid, data)
3798
3799     logger.info("EAP message: M1 missing Manufacturer")
3800     data += '\x10\x44\x00\x01\x00'
3801     send_wlanevent(url, uuid, data)
3802
3803     logger.info("EAP message: M1 missing Model Name")
3804     data += '\x10\x21\x00\x00'
3805     send_wlanevent(url, uuid, data)
3806
3807     logger.info("EAP message: M1 missing Model Number")
3808     data += '\x10\x23\x00\x00'
3809     send_wlanevent(url, uuid, data)
3810
3811     logger.info("EAP message: M1 missing Serial Number")
3812     data += '\x10\x24\x00\x00'
3813     send_wlanevent(url, uuid, data)
3814
3815     logger.info("EAP message: M1 missing Primary Device Type")
3816     data += '\x10\x42\x00\x00'
3817     send_wlanevent(url, uuid, data)
3818
3819     logger.info("EAP message: M1 missing Device Name")
3820     data += '\x10\x54\x00\x08' + 8*'\x00'
3821     send_wlanevent(url, uuid, data)
3822
3823     logger.info("EAP message: M1 missing RF Bands")
3824     data += '\x10\x11\x00\x00'
3825     send_wlanevent(url, uuid, data)
3826
3827     logger.info("EAP message: M1 missing Association State")
3828     data += '\x10\x3c\x00\x01\x00'
3829     send_wlanevent(url, uuid, data)
3830
3831     logger.info("EAP message: M1 missing Device Password ID")
3832     data += '\x10\x02\x00\x02\x00\x00'
3833     send_wlanevent(url, uuid, data)
3834
3835     logger.info("EAP message: M1 missing Configuration Error")
3836     data += '\x10\x12\x00\x02\x00\x00'
3837     send_wlanevent(url, uuid, data)
3838
3839     logger.info("EAP message: M1 missing OS Version")
3840     data += '\x10\x09\x00\x02\x00\x00'
3841     send_wlanevent(url, uuid, data)
3842
3843     logger.info("Check max concurrent requests")
3844     addr = (url.hostname, url.port)
3845     socks = {}
3846     for i in range(20):
3847         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3848                                  socket.IPPROTO_TCP)
3849         socks[i].connect(addr)
3850     for i in range(20):
3851         socks[i].send("GET / HTTP/1.1\r\n\r\n")
3852     count = 0
3853     for i in range(20):
3854         try:
3855             res = socks[i].recv(100)
3856             if "HTTP/1" in res:
3857                 count += 1
3858         except:
3859             pass
3860         socks[i].close()
3861     logger.info("%d concurrent HTTP GET operations returned response" % count)
3862     if count < 10:
3863         raise Exception("Too few concurrent HTTP connections accepted")
3864
3865     logger.info("OOM in HTTP server")
3866     for func in [ "http_request_init", "httpread_create",
3867                   "eloop_register_timeout;httpread_create",
3868                   "eloop_register_sock;httpread_create",
3869                   "httpread_hdr_analyze" ]:
3870         with alloc_fail(dev[0], 1, func):
3871             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3872                                  socket.IPPROTO_TCP)
3873             sock.connect(addr)
3874             sock.send("GET / HTTP/1.1\r\n\r\n")
3875             try:
3876                 sock.recv(100)
3877             except:
3878                 pass
3879             sock.close()
3880
3881     logger.info("Invalid HTTP header")
3882     for req in [ " GET / HTTP/1.1\r\n\r\n",
3883                  "HTTP/1.1 200 OK\r\n\r\n",
3884                  "HTTP/\r\n\r\n",
3885                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
3886                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
3887                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
3888                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
3889                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
3890                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
3891                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
3892                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
3893         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3894                              socket.IPPROTO_TCP)
3895         sock.settimeout(0.1)
3896         sock.connect(addr)
3897         sock.send(req)
3898         try:
3899             sock.recv(100)
3900         except:
3901             pass
3902         sock.close()
3903
3904     with alloc_fail(dev[0], 2, "httpread_read_handler"):
3905         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3906                              socket.IPPROTO_TCP)
3907         sock.connect(addr)
3908         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
3909         try:
3910             sock.recv(100)
3911         except:
3912             pass
3913         sock.close()
3914
3915     conn = httplib.HTTPConnection(url.netloc)
3916     payload = '<foo'
3917     headers = { "Content-type": 'text/xml; charset="utf-8"',
3918                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3919                 "HOST": url.netloc,
3920                 "NT": "upnp:event",
3921                 "SID": "uuid:" + uuid,
3922                 "SEQ": "0",
3923                 "Content-Length": str(len(payload)) }
3924     conn.request("NOTIFY", url.path, payload, headers)
3925     resp = conn.getresponse()
3926     if resp.status != 200:
3927         raise Exception("Unexpected HTTP response: %d" % resp.status)
3928
3929     conn = httplib.HTTPConnection(url.netloc)
3930     payload = '<WLANEvent foo></WLANEvent>'
3931     headers = { "Content-type": 'text/xml; charset="utf-8"',
3932                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3933                 "HOST": url.netloc,
3934                 "NT": "upnp:event",
3935                 "SID": "uuid:" + uuid,
3936                 "SEQ": "0",
3937                 "Content-Length": str(len(payload)) }
3938     conn.request("NOTIFY", url.path, payload, headers)
3939     resp = conn.getresponse()
3940     if resp.status != 200:
3941         raise Exception("Unexpected HTTP response: %d" % resp.status)
3942
3943     with alloc_fail(dev[0], 1, "xml_get_first_item"):
3944         send_wlanevent(url, uuid, '')
3945
3946     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
3947         send_wlanevent(url, uuid, 'foo')
3948
3949     for func in [ "wps_init",
3950                   "wps_process_manufacturer",
3951                   "wps_process_model_name",
3952                   "wps_process_model_number",
3953                   "wps_process_serial_number",
3954                   "wps_process_dev_name" ]:
3955         with alloc_fail(dev[0], 1, func):
3956             send_wlanevent(url, uuid, m1)
3957
3958 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
3959     """WPS ER HTTP protocol testing - no eventSubURL"""
3960     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
3961         def handle_upnp_info(self):
3962             self.wfile.write(gen_upnp_info(eventSubURL=None))
3963     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
3964                           no_event_url=True)
3965
3966 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
3967     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
3968     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
3969         def handle_upnp_info(self):
3970             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
3971     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
3972                           no_event_url=True)
3973
3974 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
3975     """WPS ER HTTP protocol testing - subscribe OOM"""
3976     try:
3977         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
3978     finally:
3979         dev[0].request("WPS_ER_STOP")
3980
3981 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
3982     tests = [ (1, "http_client_url_parse"),
3983               (1, "wpabuf_alloc;wps_er_subscribe"),
3984               (1, "http_client_addr"),
3985               (1, "eloop_register_sock;http_client_addr"),
3986               (1, "eloop_register_timeout;http_client_addr") ]
3987     for count,func in tests:
3988         with alloc_fail(dev[0], count, func):
3989             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
3990             server.handle_request()
3991             server.handle_request()
3992             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
3993
3994 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
3995     """WPS ER HTTP protocol testing - no SID"""
3996     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
3997         def handle_wps_event(self):
3998             self.wfile.write(gen_wps_event(sid=None))
3999     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4000
4001 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4002     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4003     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4004         def handle_wps_event(self):
4005             self.wfile.write(gen_wps_event(sid='FOO'))
4006     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4007
4008 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4009     """WPS ER HTTP protocol testing - invalid SID UUID"""
4010     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4011         def handle_wps_event(self):
4012             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4013     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4014
4015 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4016     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4017     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4018         def handle_wps_event(self):
4019             payload = ""
4020             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4021                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4022                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4023                   'Connection: close\r\n' + \
4024                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4025                   'Timeout: Second-1801\r\n' + \
4026                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4027             self.wfile.write(hdr + payload)
4028     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4029
4030 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4031     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4032     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4033         def handle_wps_event(self):
4034             payload = ""
4035             hdr = 'HTTP/1.1 FOO\r\n' + \
4036                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4037                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4038                   'Connection: close\r\n' + \
4039                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4040                   'Timeout: Second-1801\r\n' + \
4041                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4042             self.wfile.write(hdr + payload)
4043     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4044
4045 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4046     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4047     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4048         def handle_wps_control(self):
4049             payload = '''<?xml version="1.0"?>
4050 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4051 <s:Body>
4052 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4053 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4054 </u:GetDeviceInfoResponse>
4055 </s:Body>
4056 </s:Envelope>
4057 '''
4058             self.wfile.write(gen_wps_control(payload_override=payload))
4059     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4060
4061 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4062     """WPS ER HTTP protocol testing - No device in UPnP info"""
4063     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4064         def handle_upnp_info(self):
4065             payload = '''<?xml version="1.0"?>
4066 <root xmlns="urn:schemas-upnp-org:device-1-0">
4067 <specVersion>
4068 <major>1</major>
4069 <minor>0</minor>
4070 </specVersion>
4071 </root>
4072 '''
4073             hdr = 'HTTP/1.1 200 OK\r\n' + \
4074                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4075                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4076                   'Connection: close\r\n' + \
4077                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4078                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4079             self.wfile.write(hdr + payload)
4080     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4081
4082 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4083     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4084     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4085         def handle_upnp_info(self):
4086             payload = '''<?xml version="1.0"?>
4087 <root xmlns="urn:schemas-upnp-org:device-1-0">
4088 <specVersion>
4089 <major>1</major>
4090 <minor>0</minor>
4091 </specVersion>
4092 <device>
4093 </device>
4094 </root>
4095 '''
4096             hdr = 'HTTP/1.1 200 OK\r\n' + \
4097                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4098                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4099                   'Connection: close\r\n' + \
4100                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4101                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4102             self.wfile.write(hdr + payload)
4103     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4104
4105 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4106     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4107     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4108         def handle_upnp_info(self):
4109             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4110     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4111
4112 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4113     """WPS ER HTTP protocol testing - no controlURL"""
4114     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4115         def handle_upnp_info(self):
4116             self.wfile.write(gen_upnp_info(controlURL=None))
4117     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4118                           no_event_url=True)
4119
4120 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4121     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4122     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4123         def handle_upnp_info(self):
4124             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4125     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4126                           no_event_url=True)
4127
4128 def test_ap_wps_http_timeout(dev, apdev):
4129     """WPS AP/ER and HTTP timeout"""
4130     try:
4131         _test_ap_wps_http_timeout(dev, apdev)
4132     finally:
4133         dev[0].request("WPS_ER_STOP")
4134
4135 def _test_ap_wps_http_timeout(dev, apdev):
4136     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4137     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4138
4139     location = ssdp_get_location(ap_uuid)
4140     url = urlparse.urlparse(location)
4141     addr = (url.hostname, url.port)
4142     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4143     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4144                          socket.IPPROTO_TCP)
4145     sock.connect(addr)
4146     sock.send("G")
4147
4148     class DummyServer(SocketServer.StreamRequestHandler):
4149         def handle(self):
4150             logger.debug("DummyServer - start 31 sec wait")
4151             time.sleep(31)
4152             logger.debug("DummyServer - wait done")
4153
4154     logger.debug("Start WPS ER")
4155     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4156                                 wait_m_search=True)
4157
4158     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4159     # This will wait for 31 seconds..
4160     server.handle_request()
4161
4162     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4163     try:
4164         sock.send("ET / HTTP/1.1\r\n\r\n")
4165         res = sock.recv(100)
4166         sock.close()
4167     except:
4168         pass
4169
4170 def test_ap_wps_er_url_parse(dev, apdev):
4171     """WPS ER and URL parsing special cases"""
4172     try:
4173         _test_ap_wps_er_url_parse(dev, apdev)
4174     finally:
4175         dev[0].request("WPS_ER_STOP")
4176
4177 def _test_ap_wps_er_url_parse(dev, apdev):
4178     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4179     sock.settimeout(1)
4180     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4181     sock.bind(("239.255.255.250", 1900))
4182     dev[0].request("WPS_ER_START ifname=lo")
4183     (msg,addr) = sock.recvfrom(1000)
4184     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4185     if "M-SEARCH" not in msg:
4186         raise Exception("Not an M-SEARCH")
4187     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1\r\ncache-control:max-age=1\r\n\r\n", addr)
4188     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4189     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1/:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
4190     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4191     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://255.255.255.255:0/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
4192     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4193
4194     sock.close()
4195
4196 def test_ap_wps_er_link_update(dev, apdev):
4197     """WPS ER and link update special cases"""
4198     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4199         def handle_upnp_info(self):
4200             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4201     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4202
4203     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4204         def handle_others(self, data):
4205             if "GET / " in data:
4206                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4207     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4208                           location_url='http://127.0.0.1:12345')
4209
4210 def test_ap_wps_er_http_client(dev, apdev):
4211     """WPS ER and HTTP client special cases"""
4212     with alloc_fail(dev[0], 1, "http_link_update"):
4213         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4214
4215     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4216         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4217
4218     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4219         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4220
4221     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4222         def handle_upnp_info(self):
4223             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4224     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4225                           no_event_url=True)
4226
4227 def test_ap_wps_init_oom(dev, apdev):
4228     """wps_init OOM cases"""
4229     ssid = "test-wps"
4230     appin = "12345670"
4231     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4232                "ap_pin": appin }
4233     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4234     pin = dev[0].wps_read_pin()
4235
4236     with alloc_fail(hapd, 1, "wps_init"):
4237         hapd.request("WPS_PIN any " + pin)
4238         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4239         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4240         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4241         if ev is None:
4242             raise Exception("No EAP failure reported")
4243         dev[0].request("WPS_CANCEL")
4244
4245     with alloc_fail(dev[0], 2, "wps_init"):
4246         hapd.request("WPS_PIN any " + pin)
4247         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4248         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4249         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4250         if ev is None:
4251             raise Exception("No EAP failure reported")
4252         dev[0].request("WPS_CANCEL")
4253
4254     with alloc_fail(dev[0], 2, "wps_init"):
4255         hapd.request("WPS_PBC")
4256         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4257         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4258         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4259         if ev is None:
4260             raise Exception("No EAP failure reported")
4261         dev[0].request("WPS_CANCEL")
4262
4263     dev[0].dump_monitor()
4264     new_ssid = "wps-new-ssid"
4265     new_passphrase = "1234567890"
4266     with alloc_fail(dev[0], 3, "wps_init"):
4267         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4268                        new_passphrase, no_wait=True)
4269         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4270         if ev is None:
4271             raise Exception("No EAP failure reported")
4272
4273     dev[0].flush_scan_cache()
4274
4275 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4276     """WPS and invalid IE in Association Request frame"""
4277     ssid = "test-wps"
4278     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4279     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4280     pin = "12345670"
4281     hapd.request("WPS_PIN any " + pin)
4282     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4283     try:
4284         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4285         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4286         for i in range(5):
4287             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4288             if ev and "vendor=14122" in ev:
4289                 break
4290         if ev is None or "vendor=14122" not in ev:
4291             raise Exception("EAP-WSC not started")
4292         dev[0].request("WPS_CANCEL")
4293     finally:
4294         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4295
4296 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4297     """WPS PBC/PIN mismatch"""
4298     ssid = "test-wps"
4299     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4300     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4301     hapd.request("SET wps_version_number 0x10")
4302     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4303     hapd.request("WPS_PBC")
4304     pin = dev[0].wps_read_pin()
4305     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4306     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4307     if ev is None:
4308         raise Exception("Scan did not complete")
4309     dev[0].request("WPS_CANCEL")
4310
4311     hapd.request("WPS_CANCEL")
4312     dev[0].flush_scan_cache()
4313
4314 def test_ap_wps_ie_invalid(dev, apdev):
4315     """WPS PIN attempt with AP that has invalid WSC IE"""
4316     ssid = "test-wps"
4317     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4318                "vendor_elements": "dd050050f20410" }
4319     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4320     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4321     hostapd.add_ap(apdev[1]['ifname'], params)
4322     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4323     pin = dev[0].wps_read_pin()
4324     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4325     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4326     if ev is None:
4327         raise Exception("Scan did not complete")
4328     dev[0].request("WPS_CANCEL")
4329
4330 def test_ap_wps_scan_prio_order(dev, apdev):
4331     """WPS scan priority ordering"""
4332     ssid = "test-wps"
4333     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4334     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4335     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4336     hostapd.add_ap(apdev[1]['ifname'], params)
4337     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4338     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4339     pin = dev[0].wps_read_pin()
4340     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4341     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4342     if ev is None:
4343         raise Exception("Scan did not complete")
4344     dev[0].request("WPS_CANCEL")
4345
4346 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4347     """WPS ProbeReq IE OOM"""
4348     ssid = "test-wps"
4349     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4350     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4351     pin = dev[0].wps_read_pin()
4352     hapd.request("WPS_PIN any " + pin)
4353     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4354     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4355         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4356         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4357         if ev is None:
4358             raise Exception("Association not seen")
4359     dev[0].request("WPS_CANCEL")
4360
4361     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4362         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4363         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4364         if ev is None:
4365             raise Exception("Association not seen")
4366     dev[0].request("WPS_CANCEL")
4367
4368 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4369     """WPS AssocReq IE OOM"""
4370     ssid = "test-wps"
4371     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4372     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4373     pin = dev[0].wps_read_pin()
4374     hapd.request("WPS_PIN any " + pin)
4375     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4376     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4377         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4378         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4379         if ev is None:
4380             raise Exception("Association not seen")
4381     dev[0].request("WPS_CANCEL")
4382
4383 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4384     """WPS AssocResp IE OOM"""
4385     ssid = "test-wps"
4386     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4387     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4388     pin = dev[0].wps_read_pin()
4389     hapd.request("WPS_PIN any " + pin)
4390     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4391     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4392         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4393         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4394         if ev is None:
4395             raise Exception("Association not seen")
4396     dev[0].request("WPS_CANCEL")
4397
4398 def test_ap_wps_bss_info_errors(dev, apdev):
4399     """WPS BSS info errors"""
4400     params = { "ssid": "1",
4401                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4402     hostapd.add_ap(apdev[0]['ifname'], params)
4403     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4404     hostapd.add_ap(apdev[1]['ifname'], params)
4405     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4406     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4407     bss = dev[0].get_bss(apdev[0]['bssid'])
4408     logger.info("BSS: " + str(bss))
4409     if "wps_state" in bss:
4410         raise Exception("Unexpected wps_state in BSS info")
4411     if 'wps_device_name' not in bss:
4412         raise Exception("No wps_device_name in BSS info")
4413     if bss['wps_device_name'] != '_':
4414         raise Exception("Unexpected wps_device_name value")
4415     bss = dev[0].get_bss(apdev[1]['bssid'])
4416     logger.info("BSS: " + str(bss))
4417
4418     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4419         bss = dev[0].get_bss(apdev[0]['bssid'])
4420         logger.info("BSS(OOM): " + str(bss))
4421
4422 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4423     hapd.request("WPS_PBC")
4424     dev.scan_for_bss(apdev['bssid'], freq="2412")
4425     dev.request("WPS_PBC " + apdev['bssid'])
4426     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4427     if ev is None:
4428         raise Exception("No EAP failure reported")
4429     dev.request("WPS_CANCEL")
4430     dev.wait_disconnected()
4431     for i in range(5):
4432         try:
4433             dev.flush_scan_cache()
4434             break
4435         except Exception, e:
4436             if str(e).startswith("Failed to trigger scan"):
4437                 # Try again
4438                 time.sleep(1)
4439             else:
4440                 raise
4441
4442 def wps_run_pbc_fail(apdev, dev):
4443     hapd = wps_start_ap(apdev)
4444     wps_run_pbc_fail_ap(apdev, dev, hapd)
4445
4446 def test_ap_wps_pk_oom(dev, apdev):
4447     """WPS and public key OOM"""
4448     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4449         wps_run_pbc_fail(apdev[0], dev[0])
4450
4451 def test_ap_wps_pk_oom_ap(dev, apdev):
4452     """WPS and public key OOM on AP"""
4453     hapd = wps_start_ap(apdev[0])
4454     with alloc_fail(hapd, 1, "wps_build_public_key"):
4455         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4456
4457 def test_ap_wps_encr_oom_ap(dev, apdev):
4458     """WPS and encrypted settings decryption OOM on AP"""
4459     hapd = wps_start_ap(apdev[0])
4460     pin = dev[0].wps_read_pin()
4461     hapd.request("WPS_PIN any " + pin)
4462     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4463     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4464         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4465         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4466         if ev is None:
4467             raise Exception("No WPS-FAIL reported")
4468         dev[0].request("WPS_CANCEL")
4469     dev[0].wait_disconnected()
4470
4471 def test_ap_wps_encr_no_random_ap(dev, apdev):
4472     """WPS and no random data available for encryption on AP"""
4473     hapd = wps_start_ap(apdev[0])
4474     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4475         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4476
4477 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4478     """WPS and no random data available for e-hash on STA"""
4479     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4480         wps_run_pbc_fail(apdev[0], dev[0])
4481
4482 def test_ap_wps_m1_no_random(dev, apdev):
4483     """WPS and no random for M1 on STA"""
4484     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4485         wps_run_pbc_fail(apdev[0], dev[0])
4486
4487 def test_ap_wps_m1_oom(dev, apdev):
4488     """WPS and OOM for M1 on STA"""
4489     with alloc_fail(dev[0], 1, "wps_build_m1"):
4490         wps_run_pbc_fail(apdev[0], dev[0])
4491
4492 def test_ap_wps_m3_oom(dev, apdev):
4493     """WPS and OOM for M3 on STA"""
4494     with alloc_fail(dev[0], 1, "wps_build_m3"):
4495         wps_run_pbc_fail(apdev[0], dev[0])
4496
4497 def test_ap_wps_m5_oom(dev, apdev):
4498     """WPS and OOM for M5 on STA"""
4499     hapd = wps_start_ap(apdev[0])
4500     hapd.request("WPS_PBC")
4501     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4502     for i in range(1, 3):
4503         with alloc_fail(dev[0], i, "wps_build_m5"):
4504             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4505             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4506             if ev is None:
4507                 raise Exception("No EAP failure reported")
4508             dev[0].request("WPS_CANCEL")
4509             dev[0].wait_disconnected()
4510     dev[0].flush_scan_cache()
4511
4512 def test_ap_wps_m5_no_random(dev, apdev):
4513     """WPS and no random for M5 on STA"""
4514     with fail_test(dev[0], 1,
4515                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
4516         wps_run_pbc_fail(apdev[0], dev[0])
4517
4518 def test_ap_wps_m7_oom(dev, apdev):
4519     """WPS and OOM for M7 on STA"""
4520     hapd = wps_start_ap(apdev[0])
4521     hapd.request("WPS_PBC")
4522     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4523     for i in range(1, 3):
4524         with alloc_fail(dev[0], i, "wps_build_m7"):
4525             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4526             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4527             if ev is None:
4528                 raise Exception("No EAP failure reported")
4529             dev[0].request("WPS_CANCEL")
4530             dev[0].wait_disconnected()
4531     dev[0].flush_scan_cache()
4532
4533 def test_ap_wps_m7_no_random(dev, apdev):
4534     """WPS and no random for M7 on STA"""
4535     with fail_test(dev[0], 1,
4536                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
4537         wps_run_pbc_fail(apdev[0], dev[0])
4538
4539 def test_ap_wps_wsc_done_oom(dev, apdev):
4540     """WPS and OOM for WSC_Done on STA"""
4541     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
4542         wps_run_pbc_fail(apdev[0], dev[0])
4543
4544 def test_ap_wps_random_psk_fail(dev, apdev):
4545     """WPS and no random for PSK on AP"""
4546     ssid = "test-wps"
4547     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
4548     appin = "12345670"
4549     try:
4550         os.remove(pskfile)
4551     except:
4552         pass
4553
4554     try:
4555         with open(pskfile, "w") as f:
4556             f.write("# WPA PSKs\n")
4557
4558         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4559                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
4560                    "rsn_pairwise": "CCMP", "ap_pin": appin,
4561                    "wpa_psk_file": pskfile }
4562         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4563
4564         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4565         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
4566             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
4567             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4568             if ev is None:
4569                 raise Exception("No EAP failure reported")
4570             dev[0].request("WPS_CANCEL")
4571         dev[0].wait_disconnected()
4572
4573         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
4574             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4575
4576         with alloc_fail(hapd, 1, "wps_build_cred"):
4577             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4578
4579         with alloc_fail(hapd, 2, "wps_build_cred"):
4580             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4581     finally:
4582         os.remove(pskfile)
4583
4584 def wps_ext_eap_identity_req(dev, hapd, bssid):
4585     logger.debug("EAP-Identity/Request")
4586     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4587     if ev is None:
4588         raise Exception("Timeout on EAPOL-TX from hostapd")
4589     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
4590     if "OK" not in res:
4591         raise Exception("EAPOL_RX to wpa_supplicant failed")
4592
4593 def wps_ext_eap_identity_resp(hapd, dev, addr):
4594     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
4595     if ev is None:
4596         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
4597     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
4598     if "OK" not in res:
4599         raise Exception("EAPOL_RX to hostapd failed")
4600
4601 def wps_ext_eap_wsc(dst, src, src_addr, msg):
4602     logger.debug(msg)
4603     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4604     if ev is None:
4605         raise Exception("Timeout on EAPOL-TX")
4606     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
4607     if "OK" not in res:
4608         raise Exception("EAPOL_RX failed")
4609
4610 def wps_start_ext(apdev, dev):
4611     addr = dev.own_addr()
4612     bssid = apdev['bssid']
4613     ssid = "test-wps-conf"
4614     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4615                "wpa_passphrase": "12345678", "wpa": "2",
4616                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
4617     hapd = hostapd.add_ap(apdev['ifname'], params)
4618
4619     pin = dev.wps_read_pin()
4620     hapd.request("WPS_PIN any " + pin)
4621     dev.scan_for_bss(bssid, freq="2412")
4622     hapd.request("SET ext_eapol_frame_io 1")
4623     dev.request("SET ext_eapol_frame_io 1")
4624
4625     dev.request("WPS_PIN " + bssid + " " + pin)
4626     return addr,bssid,hapd
4627
4628 def wps_auth_corrupt(dst, src, addr):
4629     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4630     if ev is None:
4631         raise Exception("Timeout on EAPOL-TX")
4632     src.request("SET ext_eapol_frame_io 0")
4633     dst.request("SET ext_eapol_frame_io 0")
4634     msg = ev.split(' ')[2]
4635     if msg[-24:-16] != '10050008':
4636         raise Exception("Could not find Authenticator attribute")
4637     # Corrupt Authenticator value
4638     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
4639     res = dst.request("EAPOL_RX " + addr + " " + msg)
4640     if "OK" not in res:
4641         raise Exception("EAPOL_RX failed")
4642
4643 def wps_fail_finish(hapd, dev, fail_str):
4644     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
4645     if ev is None:
4646         raise Exception("WPS-FAIL not indicated")
4647     if fail_str not in ev:
4648         raise Exception("Unexpected WPS-FAIL value: " + ev)
4649     dev.request("WPS_CANCEL")
4650     dev.wait_disconnected()
4651
4652 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
4653     wps_auth_corrupt(dev, hapd, bssid)
4654     wps_fail_finish(hapd, dev, fail_str)
4655
4656 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
4657     wps_auth_corrupt(hapd, dev, addr)
4658     wps_fail_finish(hapd, dev, fail_str)
4659
4660 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
4661     """WPS and Authenticator attribute mismatch in M2"""
4662     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4663     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4664     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4665     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4666     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4667     logger.debug("M2")
4668     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
4669
4670 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
4671     """WPS and Authenticator attribute mismatch in M3"""
4672     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4673     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4674     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4675     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4676     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4677     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4678     logger.debug("M3")
4679     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
4680
4681 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
4682     """WPS and Authenticator attribute mismatch in M4"""
4683     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4684     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4685     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4686     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4687     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4688     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4689     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4690     logger.debug("M4")
4691     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
4692
4693 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
4694     """WPS and Authenticator attribute mismatch in M5"""
4695     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4696     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4697     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4698     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4699     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4700     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4701     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4702     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4703     logger.debug("M5")
4704     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
4705
4706 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
4707     """WPS and Authenticator attribute mismatch in M6"""
4708     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4709     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4710     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4711     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4712     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4713     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4714     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4715     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4716     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
4717     logger.debug("M6")
4718     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
4719
4720 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
4721     """WPS and Authenticator attribute mismatch in M7"""
4722     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4723     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4724     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4725     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4726     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4727     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4728     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4729     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4730     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
4731     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
4732     logger.debug("M7")
4733     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
4734
4735 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
4736     """WPS and Authenticator attribute mismatch in M8"""
4737     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4738     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4739     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4740     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4741     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4742     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4743     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4744     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4745     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
4746     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
4747     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
4748     logger.debug("M8")
4749     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
4750
4751 def test_ap_wps_authenticator_missing_m2(dev, apdev):
4752     """WPS and Authenticator attribute missing from M2"""
4753     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4754     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4755     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4756     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4757     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4758     logger.debug("M2")
4759     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4760     if ev is None:
4761         raise Exception("Timeout on EAPOL-TX")
4762     hapd.request("SET ext_eapol_frame_io 0")
4763     dev[0].request("SET ext_eapol_frame_io 0")
4764     msg = ev.split(' ')[2]
4765     if msg[-24:-16] != '10050008':
4766         raise Exception("Could not find Authenticator attribute")
4767     # Remove Authenticator value
4768     msg = msg[:-24]
4769     mlen = "%04x" % (int(msg[4:8], 16) - 12)
4770     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
4771     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
4772     if "OK" not in res:
4773         raise Exception("EAPOL_RX failed")
4774     wps_fail_finish(hapd, dev[0], "msg=5")
4775
4776 def test_ap_wps_config_methods(dev, apdev):
4777     """WPS configuration method parsing"""
4778     ssid = "test-wps-conf"
4779     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4780                "wpa_passphrase": "12345678", "wpa": "2",
4781                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
4782                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
4783     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4784     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4785                "wpa_passphrase": "12345678", "wpa": "2",
4786                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
4787                "config_methods": "display push_button" }
4788     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
4789
4790 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
4791     """WPS UPnP SetSelectedRegistrar protocol testing"""
4792     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4793     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4794
4795     location = ssdp_get_location(ap_uuid)
4796     urls = upnp_get_urls(location)
4797     eventurl = urlparse.urlparse(urls['event_sub_url'])
4798     ctrlurl = urlparse.urlparse(urls['control_url'])
4799     url = urlparse.urlparse(location)
4800     conn = httplib.HTTPConnection(url.netloc)
4801
4802     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
4803         def handle(self):
4804             data = self.rfile.readline().strip()
4805             logger.debug(data)
4806             self.wfile.write(gen_wps_event())
4807
4808     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
4809     server.timeout = 1
4810
4811     headers = { "callback": '<http://127.0.0.1:12345/event>',
4812                 "NT": "upnp:event",
4813                 "timeout": "Second-1234" }
4814     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
4815     resp = conn.getresponse()
4816     if resp.status != 200:
4817         raise Exception("Unexpected HTTP response: %d" % resp.status)
4818     sid = resp.getheader("sid")
4819     logger.debug("Subscription SID " + sid)
4820     server.handle_request()
4821
4822     tests = [ (500, "10"),
4823               (200, "104a000110" + "1041000101" + "101200020000" +
4824                "105300023148" +
4825                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
4826                "10480010362db47ba53a519188fb5458b986b2e4"),
4827               (200, "104a000110" + "1041000100" + "101200020000" +
4828                "105300020000"),
4829               (200, "104a000110" + "1041000100"),
4830               (200, "104a000110") ]
4831     for status,test in tests:
4832         tlvs = binascii.unhexlify(test)
4833         newmsg = base64.b64encode(tlvs)
4834         msg = '<?xml version="1.0"?>\n'
4835         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
4836         msg += '<s:Body>'
4837         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
4838         msg += '<NewMessage>'
4839         msg += newmsg
4840         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
4841         headers = { "Content-type": 'text/xml; charset="utf-8"' }
4842         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
4843         conn.request("POST", ctrlurl.path, msg, headers)
4844         resp = conn.getresponse()
4845         if resp.status != status:
4846             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))