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