a817ddbf929c1b3087469246d4fa91c4c45fab8e
[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 [long]"""
1831     if not params['long']:
1832         raise HwsimSkip("Skip test case with long duration due to --long not specified")
1833     ssid = "test-wps"
1834     hostapd.add_ap(apdev[0]['ifname'],
1835                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
1836     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1837     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
1838     if "OK" not in dev[0].request("WPS_PBC"):
1839         raise Exception("WPS_PBC failed")
1840     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=150)
1841     if ev is None:
1842         raise Exception("WPS-TIMEOUT not reported")
1843
1844 def add_ssdp_ap(ifname, ap_uuid):
1845     ssid = "wps-ssdp"
1846     ap_pin = "12345670"
1847     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1848                "wpa_passphrase": "12345678", "wpa": "2",
1849                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1850                "device_name": "Wireless AP", "manufacturer": "Company",
1851                "model_name": "WAP", "model_number": "123",
1852                "serial_number": "12345", "device_type": "6-0050F204-1",
1853                "os_version": "01020300",
1854                "config_methods": "label push_button",
1855                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
1856                "friendly_name": "WPS Access Point",
1857                "manufacturer_url": "http://www.example.com/",
1858                "model_description": "Wireless Access Point",
1859                "model_url": "http://www.example.com/model/",
1860                "upc": "123456789012" }
1861     return hostapd.add_ap(ifname, params)
1862
1863 def ssdp_send(msg, no_recv=False):
1864     socket.setdefaulttimeout(1)
1865     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1866     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1867     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1868     sock.bind(("127.0.0.1", 0))
1869     sock.sendto(msg, ("239.255.255.250", 1900))
1870     if no_recv:
1871         return None
1872     return sock.recv(1000)
1873
1874 def ssdp_send_msearch(st):
1875     msg = '\r\n'.join([
1876             'M-SEARCH * HTTP/1.1',
1877             'HOST: 239.255.255.250:1900',
1878             'MX: 1',
1879             'MAN: "ssdp:discover"',
1880             'ST: ' + st,
1881             '', ''])
1882     return ssdp_send(msg)
1883
1884 def test_ap_wps_ssdp_msearch(dev, apdev):
1885     """WPS AP and SSDP M-SEARCH messages"""
1886     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1887     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1888
1889     msg = '\r\n'.join([
1890             'M-SEARCH * HTTP/1.1',
1891             'Host: 239.255.255.250:1900',
1892             'Mx: 1',
1893             'Man: "ssdp:discover"',
1894             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
1895             '', ''])
1896     ssdp_send(msg)
1897
1898     msg = '\r\n'.join([
1899             'M-SEARCH * HTTP/1.1',
1900             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
1901             'mx: \t1\t\t   ',
1902             'man: \t \t "ssdp:discover"   ',
1903             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
1904             '', ''])
1905     ssdp_send(msg)
1906
1907     ssdp_send_msearch("ssdp:all")
1908     ssdp_send_msearch("upnp:rootdevice")
1909     ssdp_send_msearch("uuid:" + ap_uuid)
1910     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
1911     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
1912
1913     msg = '\r\n'.join([
1914             'M-SEARCH * HTTP/1.1',
1915             'HOST:\t239.255.255.250:1900',
1916             'MAN: "ssdp:discover"',
1917             'MX: 130',
1918             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1919             '', ''])
1920     ssdp_send(msg, no_recv=True)
1921
1922 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
1923     """WPS AP and invalid SSDP M-SEARCH messages"""
1924     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1925     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1926
1927     socket.setdefaulttimeout(1)
1928     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1929     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1930     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1931     sock.bind(("127.0.0.1", 0))
1932
1933     logger.debug("Missing MX")
1934     msg = '\r\n'.join([
1935             'M-SEARCH * HTTP/1.1',
1936             'HOST: 239.255.255.250:1900',
1937             'MAN: "ssdp:discover"',
1938             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1939             '', ''])
1940     sock.sendto(msg, ("239.255.255.250", 1900))
1941
1942     logger.debug("Negative MX")
1943     msg = '\r\n'.join([
1944             'M-SEARCH * HTTP/1.1',
1945             'HOST: 239.255.255.250:1900',
1946             'MX: -1',
1947             'MAN: "ssdp:discover"',
1948             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1949             '', ''])
1950     sock.sendto(msg, ("239.255.255.250", 1900))
1951
1952     logger.debug("Invalid MX")
1953     msg = '\r\n'.join([
1954             'M-SEARCH * HTTP/1.1',
1955             'HOST: 239.255.255.250:1900',
1956             'MX; 1',
1957             'MAN: "ssdp:discover"',
1958             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1959             '', ''])
1960     sock.sendto(msg, ("239.255.255.250", 1900))
1961
1962     logger.debug("Missing MAN")
1963     msg = '\r\n'.join([
1964             'M-SEARCH * HTTP/1.1',
1965             'HOST: 239.255.255.250:1900',
1966             'MX: 1',
1967             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1968             '', ''])
1969     sock.sendto(msg, ("239.255.255.250", 1900))
1970
1971     logger.debug("Invalid MAN")
1972     msg = '\r\n'.join([
1973             'M-SEARCH * HTTP/1.1',
1974             'HOST: 239.255.255.250:1900',
1975             'MX: 1',
1976             'MAN: foo',
1977             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1978             '', ''])
1979     sock.sendto(msg, ("239.255.255.250", 1900))
1980     msg = '\r\n'.join([
1981             'M-SEARCH * HTTP/1.1',
1982             'HOST: 239.255.255.250:1900',
1983             'MX: 1',
1984             'MAN; "ssdp:discover"',
1985             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1986             '', ''])
1987     sock.sendto(msg, ("239.255.255.250", 1900))
1988
1989     logger.debug("Missing HOST")
1990     msg = '\r\n'.join([
1991             'M-SEARCH * HTTP/1.1',
1992             'MAN: "ssdp:discover"',
1993             'MX: 1',
1994             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1995             '', ''])
1996     sock.sendto(msg, ("239.255.255.250", 1900))
1997
1998     logger.debug("Missing ST")
1999     msg = '\r\n'.join([
2000             'M-SEARCH * HTTP/1.1',
2001             'HOST: 239.255.255.250:1900',
2002             'MAN: "ssdp:discover"',
2003             'MX: 1',
2004             '', ''])
2005     sock.sendto(msg, ("239.255.255.250", 1900))
2006
2007     logger.debug("Mismatching ST")
2008     msg = '\r\n'.join([
2009             'M-SEARCH * HTTP/1.1',
2010             'HOST: 239.255.255.250:1900',
2011             'MAN: "ssdp:discover"',
2012             'MX: 1',
2013             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2014             '', ''])
2015     sock.sendto(msg, ("239.255.255.250", 1900))
2016     msg = '\r\n'.join([
2017             'M-SEARCH * HTTP/1.1',
2018             'HOST: 239.255.255.250:1900',
2019             'MAN: "ssdp:discover"',
2020             'MX: 1',
2021             'ST: foo:bar',
2022             '', ''])
2023     sock.sendto(msg, ("239.255.255.250", 1900))
2024     msg = '\r\n'.join([
2025             'M-SEARCH * HTTP/1.1',
2026             'HOST: 239.255.255.250:1900',
2027             'MAN: "ssdp:discover"',
2028             'MX: 1',
2029             'ST: foobar',
2030             '', ''])
2031     sock.sendto(msg, ("239.255.255.250", 1900))
2032
2033     logger.debug("Invalid ST")
2034     msg = '\r\n'.join([
2035             'M-SEARCH * HTTP/1.1',
2036             'HOST: 239.255.255.250:1900',
2037             'MAN: "ssdp:discover"',
2038             'MX: 1',
2039             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2040             '', ''])
2041     sock.sendto(msg, ("239.255.255.250", 1900))
2042
2043     logger.debug("Invalid M-SEARCH")
2044     msg = '\r\n'.join([
2045             'M+SEARCH * HTTP/1.1',
2046             'HOST: 239.255.255.250:1900',
2047             'MAN: "ssdp:discover"',
2048             'MX: 1',
2049             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2050             '', ''])
2051     sock.sendto(msg, ("239.255.255.250", 1900))
2052     msg = '\r\n'.join([
2053             'M-SEARCH-* HTTP/1.1',
2054             'HOST: 239.255.255.250:1900',
2055             'MAN: "ssdp:discover"',
2056             'MX: 1',
2057             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2058             '', ''])
2059     sock.sendto(msg, ("239.255.255.250", 1900))
2060
2061     logger.debug("Invalid message format")
2062     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2063     msg = '\r'.join([
2064             'M-SEARCH * HTTP/1.1',
2065             'HOST: 239.255.255.250:1900',
2066             'MAN: "ssdp:discover"',
2067             'MX: 1',
2068             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2069             '', ''])
2070     sock.sendto(msg, ("239.255.255.250", 1900))
2071
2072     try:
2073         r = sock.recv(1000)
2074         raise Exception("Unexpected M-SEARCH response: " + r)
2075     except socket.timeout:
2076         pass
2077
2078     logger.debug("Valid M-SEARCH")
2079     msg = '\r\n'.join([
2080             'M-SEARCH * HTTP/1.1',
2081             'HOST: 239.255.255.250:1900',
2082             'MAN: "ssdp:discover"',
2083             'MX: 1',
2084             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2085             '', ''])
2086     sock.sendto(msg, ("239.255.255.250", 1900))
2087
2088     try:
2089         r = sock.recv(1000)
2090         pass
2091     except socket.timeout:
2092         raise Exception("No SSDP response")
2093
2094 def test_ap_wps_ssdp_burst(dev, apdev):
2095     """WPS AP and SSDP burst"""
2096     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2097     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2098
2099     msg = '\r\n'.join([
2100             'M-SEARCH * HTTP/1.1',
2101             'HOST: 239.255.255.250:1900',
2102             'MAN: "ssdp:discover"',
2103             'MX: 1',
2104             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2105             '', ''])
2106     socket.setdefaulttimeout(1)
2107     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2108     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2109     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2110     sock.bind(("127.0.0.1", 0))
2111     for i in range(0, 25):
2112         sock.sendto(msg, ("239.255.255.250", 1900))
2113     resp = 0
2114     while True:
2115         try:
2116             r = sock.recv(1000)
2117             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2118                 raise Exception("Unexpected message: " + r)
2119             resp += 1
2120         except socket.timeout:
2121             break
2122     if resp < 20:
2123         raise Exception("Too few SSDP responses")
2124
2125     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2126     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2127     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2128     sock.bind(("127.0.0.1", 0))
2129     for i in range(0, 25):
2130         sock.sendto(msg, ("239.255.255.250", 1900))
2131     while True:
2132         try:
2133             r = sock.recv(1000)
2134             if ap_uuid in r:
2135                 break
2136         except socket.timeout:
2137             raise Exception("No SSDP response")
2138
2139 def ssdp_get_location(uuid):
2140     res = ssdp_send_msearch("uuid:" + uuid)
2141     location = None
2142     for l in res.splitlines():
2143         if l.lower().startswith("location:"):
2144             location = l.split(':', 1)[1].strip()
2145             break
2146     if location is None:
2147         raise Exception("No UPnP location found")
2148     return location
2149
2150 def upnp_get_urls(location):
2151     conn = urllib.urlopen(location)
2152     tree = ET.parse(conn)
2153     root = tree.getroot()
2154     urn = '{urn:schemas-upnp-org:device-1-0}'
2155     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2156     res = {}
2157     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2158     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2159     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2160     return res
2161
2162 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2163     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2164     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2165     ET.register_namespace('soapenv', soapns)
2166     ET.register_namespace('wfa', wpsns)
2167     attrib = {}
2168     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2169     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2170     body = ET.SubElement(root, "{%s}Body" % soapns)
2171     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2172     tree = ET.ElementTree(root)
2173     soap = StringIO.StringIO()
2174     tree.write(soap, xml_declaration=True, encoding='utf-8')
2175
2176     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2177     if include_soap_action:
2178         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2179     elif soap_action_override:
2180         headers["SOAPAction"] = soap_action_override
2181     conn.request("POST", path, soap.getvalue(), headers)
2182     return conn.getresponse()
2183
2184 def test_ap_wps_upnp(dev, apdev):
2185     """WPS AP and UPnP operations"""
2186     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2187     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2188
2189     location = ssdp_get_location(ap_uuid)
2190     urls = upnp_get_urls(location)
2191
2192     conn = urllib.urlopen(urls['scpd_url'])
2193     scpd = conn.read()
2194
2195     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2196     if conn.getcode() != 404:
2197         raise Exception("Unexpected HTTP response to GET unknown URL")
2198
2199     url = urlparse.urlparse(location)
2200     conn = httplib.HTTPConnection(url.netloc)
2201     #conn.set_debuglevel(1)
2202     headers = { "Content-type": 'text/xml; charset="utf-8"',
2203                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2204     conn.request("POST", "hello", "\r\n\r\n", headers)
2205     resp = conn.getresponse()
2206     if resp.status != 404:
2207         raise Exception("Unexpected HTTP response: %d" % resp.status)
2208
2209     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2210     resp = conn.getresponse()
2211     if resp.status != 501:
2212         raise Exception("Unexpected HTTP response: %d" % resp.status)
2213
2214     headers = { "Content-type": 'text/xml; charset="utf-8"',
2215                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2216     ctrlurl = urlparse.urlparse(urls['control_url'])
2217     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2218     resp = conn.getresponse()
2219     if resp.status != 401:
2220         raise Exception("Unexpected HTTP response: %d" % resp.status)
2221
2222     logger.debug("GetDeviceInfo without SOAPAction header")
2223     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2224                             include_soap_action=False)
2225     if resp.status != 401:
2226         raise Exception("Unexpected HTTP response: %d" % resp.status)
2227
2228     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2229     for act in [ "foo",
2230                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2231                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2232                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2233         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2234                                 include_soap_action=False,
2235                                 soap_action_override=act)
2236         if resp.status != 401:
2237             raise Exception("Unexpected HTTP response: %d" % resp.status)
2238
2239     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2240     if resp.status != 200:
2241         raise Exception("Unexpected HTTP response: %d" % resp.status)
2242     dev = resp.read()
2243     if "NewDeviceInfo" not in dev:
2244         raise Exception("Unexpected GetDeviceInfo response")
2245
2246     logger.debug("PutMessage without required parameters")
2247     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2248     if resp.status != 600:
2249         raise Exception("Unexpected HTTP response: %d" % resp.status)
2250
2251     logger.debug("PutWLANResponse without required parameters")
2252     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2253     if resp.status != 600:
2254         raise Exception("Unexpected HTTP response: %d" % resp.status)
2255
2256     logger.debug("SetSelectedRegistrar from unregistered ER")
2257     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2258     if resp.status != 501:
2259         raise Exception("Unexpected HTTP response: %d" % resp.status)
2260
2261     logger.debug("Unknown action")
2262     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2263     if resp.status != 401:
2264         raise Exception("Unexpected HTTP response: %d" % resp.status)
2265
2266 def test_ap_wps_upnp_subscribe(dev, apdev):
2267     """WPS AP and UPnP event subscription"""
2268     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2269     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2270
2271     location = ssdp_get_location(ap_uuid)
2272     urls = upnp_get_urls(location)
2273     eventurl = urlparse.urlparse(urls['event_sub_url'])
2274
2275     url = urlparse.urlparse(location)
2276     conn = httplib.HTTPConnection(url.netloc)
2277     #conn.set_debuglevel(1)
2278     headers = { "callback": '<http://127.0.0.1:12345/event>',
2279                 "timeout": "Second-1234" }
2280     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2281     resp = conn.getresponse()
2282     if resp.status != 412:
2283         raise Exception("Unexpected HTTP response: %d" % resp.status)
2284
2285     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2286     resp = conn.getresponse()
2287     if resp.status != 412:
2288         raise Exception("Unexpected HTTP response: %d" % resp.status)
2289
2290     headers = { "NT": "upnp:event",
2291                 "timeout": "Second-1234" }
2292     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2293     resp = conn.getresponse()
2294     if resp.status != 412:
2295         raise Exception("Unexpected HTTP response: %d" % resp.status)
2296
2297     headers = { "callback": '<http://127.0.0.1:12345/event>',
2298                 "NT": "upnp:foobar",
2299                 "timeout": "Second-1234" }
2300     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2301     resp = conn.getresponse()
2302     if resp.status != 400:
2303         raise Exception("Unexpected HTTP response: %d" % resp.status)
2304
2305     logger.debug("Valid subscription")
2306     headers = { "callback": '<http://127.0.0.1:12345/event>',
2307                 "NT": "upnp:event",
2308                 "timeout": "Second-1234" }
2309     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2310     resp = conn.getresponse()
2311     if resp.status != 200:
2312         raise Exception("Unexpected HTTP response: %d" % resp.status)
2313     sid = resp.getheader("sid")
2314     logger.debug("Subscription SID " + sid)
2315
2316     logger.debug("Invalid re-subscription")
2317     headers = { "NT": "upnp:event",
2318                 "sid": "123456734567854",
2319                 "timeout": "Second-1234" }
2320     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2321     resp = conn.getresponse()
2322     if resp.status != 400:
2323         raise Exception("Unexpected HTTP response: %d" % resp.status)
2324
2325     logger.debug("Invalid re-subscription")
2326     headers = { "NT": "upnp:event",
2327                 "sid": "uuid:123456734567854",
2328                 "timeout": "Second-1234" }
2329     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2330     resp = conn.getresponse()
2331     if resp.status != 400:
2332         raise Exception("Unexpected HTTP response: %d" % resp.status)
2333
2334     logger.debug("Invalid re-subscription")
2335     headers = { "callback": '<http://127.0.0.1:12345/event>',
2336                 "NT": "upnp:event",
2337                 "sid": sid,
2338                 "timeout": "Second-1234" }
2339     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2340     resp = conn.getresponse()
2341     if resp.status != 400:
2342         raise Exception("Unexpected HTTP response: %d" % resp.status)
2343
2344     logger.debug("SID mismatch in re-subscription")
2345     headers = { "NT": "upnp:event",
2346                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2347                 "timeout": "Second-1234" }
2348     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2349     resp = conn.getresponse()
2350     if resp.status != 412:
2351         raise Exception("Unexpected HTTP response: %d" % resp.status)
2352
2353     logger.debug("Valid re-subscription")
2354     headers = { "NT": "upnp:event",
2355                 "sid": sid,
2356                 "timeout": "Second-1234" }
2357     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2358     resp = conn.getresponse()
2359     if resp.status != 200:
2360         raise Exception("Unexpected HTTP response: %d" % resp.status)
2361     sid2 = resp.getheader("sid")
2362     logger.debug("Subscription SID " + sid2)
2363
2364     if sid != sid2:
2365         raise Exception("Unexpected SID change")
2366
2367     logger.debug("Valid re-subscription")
2368     headers = { "NT": "upnp:event",
2369                 "sid": "uuid: \t \t" + sid.split(':')[1],
2370                 "timeout": "Second-1234" }
2371     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2372     resp = conn.getresponse()
2373     if resp.status != 200:
2374         raise Exception("Unexpected HTTP response: %d" % resp.status)
2375
2376     logger.debug("Invalid unsubscription")
2377     headers = { "sid": sid }
2378     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2379     resp = conn.getresponse()
2380     if resp.status != 412:
2381         raise Exception("Unexpected HTTP response: %d" % resp.status)
2382     headers = { "foo": "bar" }
2383     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2384     resp = conn.getresponse()
2385     if resp.status != 412:
2386         raise Exception("Unexpected HTTP response: %d" % resp.status)
2387
2388     logger.debug("Valid unsubscription")
2389     headers = { "sid": sid }
2390     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2391     resp = conn.getresponse()
2392     if resp.status != 200:
2393         raise Exception("Unexpected HTTP response: %d" % resp.status)
2394
2395     logger.debug("Unsubscription for not existing SID")
2396     headers = { "sid": sid }
2397     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2398     resp = conn.getresponse()
2399     if resp.status != 412:
2400         raise Exception("Unexpected HTTP response: %d" % resp.status)
2401
2402     logger.debug("Invalid unsubscription")
2403     headers = { "sid": " \t \tfoo" }
2404     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2405     resp = conn.getresponse()
2406     if resp.status != 400:
2407         raise Exception("Unexpected HTTP response: %d" % resp.status)
2408
2409     logger.debug("Invalid unsubscription")
2410     headers = { "sid": "uuid:\t \tfoo" }
2411     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2412     resp = conn.getresponse()
2413     if resp.status != 400:
2414         raise Exception("Unexpected HTTP response: %d" % resp.status)
2415
2416     logger.debug("Invalid unsubscription")
2417     headers = { "NT": "upnp:event",
2418                 "sid": sid }
2419     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2420     resp = conn.getresponse()
2421     if resp.status != 400:
2422         raise Exception("Unexpected HTTP response: %d" % resp.status)
2423     headers = { "callback": '<http://127.0.0.1:12345/event>',
2424                 "sid": sid }
2425     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2426     resp = conn.getresponse()
2427     if resp.status != 400:
2428         raise Exception("Unexpected HTTP response: %d" % resp.status)
2429
2430     logger.debug("Valid subscription with multiple callbacks")
2431     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>',
2432                 "NT": "upnp:event",
2433                 "timeout": "Second-1234" }
2434     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2435     resp = conn.getresponse()
2436     if resp.status != 200:
2437         raise Exception("Unexpected HTTP response: %d" % resp.status)
2438     sid = resp.getheader("sid")
2439     logger.debug("Subscription SID " + sid)
2440
2441     # Force subscription to be deleted due to errors
2442     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2443     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2444     with alloc_fail(hapd, 1, "event_build_message"):
2445         for i in range(10):
2446             dev[1].dump_monitor()
2447             dev[2].dump_monitor()
2448             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2449             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2450             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2451             dev[1].request("WPS_CANCEL")
2452             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2453             dev[2].request("WPS_CANCEL")
2454             if i % 4 == 1:
2455                 time.sleep(1)
2456             else:
2457                 time.sleep(0.1)
2458     time.sleep(0.2)
2459
2460     headers = { "sid": sid }
2461     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2462     resp = conn.getresponse()
2463     if resp.status != 200 and resp.status != 412:
2464         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2465
2466     headers = { "callback": '<http://127.0.0.1:12345/event>',
2467                 "NT": "upnp:event",
2468                 "timeout": "Second-1234" }
2469     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2470         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2471         resp = conn.getresponse()
2472         if resp.status != 200:
2473             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2474         sid = resp.getheader("sid")
2475         logger.debug("Subscription SID " + sid)
2476
2477     headers = { "sid": sid }
2478     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2479     resp = conn.getresponse()
2480     if resp.status != 200:
2481         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2482
2483     headers = { "callback": '<http://127.0.0.1:12345/event>',
2484                 "NT": "upnp:event",
2485                 "timeout": "Second-1234" }
2486     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2487     resp = conn.getresponse()
2488     if resp.status != 200:
2489         raise Exception("Unexpected HTTP response: %d" % resp.status)
2490     sid = resp.getheader("sid")
2491     logger.debug("Subscription SID " + sid)
2492
2493     with alloc_fail(hapd, 1, "=event_add"):
2494         for i in range(2):
2495             dev[1].dump_monitor()
2496             dev[2].dump_monitor()
2497             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2498             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2499             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2500             dev[1].request("WPS_CANCEL")
2501             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2502             dev[2].request("WPS_CANCEL")
2503             if i == 0:
2504                 time.sleep(1)
2505             else:
2506                 time.sleep(0.1)
2507
2508     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2509     resp = conn.getresponse()
2510     if resp.status != 200:
2511         raise Exception("Unexpected HTTP response: %d" % resp.status)
2512
2513     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
2514         dev[1].dump_monitor()
2515         dev[2].dump_monitor()
2516         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2517         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2518         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2519         dev[1].request("WPS_CANCEL")
2520         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2521         dev[2].request("WPS_CANCEL")
2522         time.sleep(0.1)
2523
2524     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
2525         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2526         resp = conn.getresponse()
2527         if resp.status != 500:
2528             raise Exception("Unexpected HTTP response: %d" % resp.status)
2529
2530     with alloc_fail(hapd, 1, "=subscription_start"):
2531         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2532         resp = conn.getresponse()
2533         if resp.status != 500:
2534             raise Exception("Unexpected HTTP response: %d" % resp.status)
2535
2536     headers = { "callback": '',
2537                 "NT": "upnp:event",
2538                 "timeout": "Second-1234" }
2539     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2540     resp = conn.getresponse()
2541     if resp.status != 500:
2542         raise Exception("Unexpected HTTP response: %d" % resp.status)
2543
2544     headers = { "callback": ' <',
2545                 "NT": "upnp:event",
2546                 "timeout": "Second-1234" }
2547     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2548     resp = conn.getresponse()
2549     if resp.status != 500:
2550         raise Exception("Unexpected HTTP response: %d" % resp.status)
2551
2552     headers = { "callback": '<http://127.0.0.1:12345/event>',
2553                 "NT": "upnp:event",
2554                 "timeout": "Second-1234" }
2555     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
2556         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2557         resp = conn.getresponse()
2558         if resp.status != 500:
2559             raise Exception("Unexpected HTTP response: %d" % resp.status)
2560
2561     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
2562         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2563         resp = conn.getresponse()
2564         if resp.status != 500:
2565             raise Exception("Unexpected HTTP response: %d" % resp.status)
2566
2567     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
2568         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2569         resp = conn.getresponse()
2570         if resp.status != 500:
2571             raise Exception("Unexpected HTTP response: %d" % resp.status)
2572
2573     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
2574         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2575         resp = conn.getresponse()
2576         if resp.status != 500:
2577             raise Exception("Unexpected HTTP response: %d" % resp.status)
2578
2579     for i in range(6):
2580         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
2581                     "NT": "upnp:event",
2582                     "timeout": "Second-1234" }
2583         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2584         resp = conn.getresponse()
2585         if resp.status != 200:
2586             raise Exception("Unexpected HTTP response: %d" % resp.status)
2587
2588     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
2589         dev[1].dump_monitor()
2590         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2591         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2592         dev[1].request("WPS_CANCEL")
2593         time.sleep(0.1)
2594
2595     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
2596         dev[1].dump_monitor()
2597         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2598         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2599         dev[1].request("WPS_CANCEL")
2600         time.sleep(0.1)
2601
2602     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
2603         dev[1].dump_monitor()
2604         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2605         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2606         dev[1].request("WPS_CANCEL")
2607         time.sleep(0.1)
2608
2609     hapd.disable()
2610     with alloc_fail(hapd, 1, "get_netif_info"):
2611         if "FAIL" not in hapd.request("ENABLE"):
2612             raise Exception("ENABLE succeeded during OOM")
2613
2614 def test_ap_wps_upnp_http_proto(dev, apdev):
2615     """WPS AP and UPnP/HTTP protocol testing"""
2616     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2617     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2618
2619     location = ssdp_get_location(ap_uuid)
2620
2621     url = urlparse.urlparse(location)
2622     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
2623     #conn.set_debuglevel(1)
2624
2625     conn.request("HEAD", "hello")
2626     resp = conn.getresponse()
2627     if resp.status != 501:
2628         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2629     conn.close()
2630
2631     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
2632         try:
2633             conn.request(cmd, "hello")
2634             resp = conn.getresponse()
2635         except Exception, e:
2636             pass
2637         conn.close()
2638
2639     headers = { "Content-Length": 'abc' }
2640     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2641     try:
2642         resp = conn.getresponse()
2643     except Exception, e:
2644         pass
2645     conn.close()
2646
2647     headers = { "Content-Length": '-10' }
2648     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2649     try:
2650         resp = conn.getresponse()
2651     except Exception, e:
2652         pass
2653     conn.close()
2654
2655     headers = { "Content-Length": '10000000000000' }
2656     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
2657     try:
2658         resp = conn.getresponse()
2659     except Exception, e:
2660         pass
2661     conn.close()
2662
2663     headers = { "Transfer-Encoding": 'abc' }
2664     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2665     resp = conn.getresponse()
2666     if resp.status != 501:
2667         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2668     conn.close()
2669
2670     headers = { "Transfer-Encoding": 'chunked' }
2671     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2672     resp = conn.getresponse()
2673     if resp.status != 501:
2674         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2675     conn.close()
2676
2677     # Too long a header
2678     conn.request("HEAD", 5000 * 'A')
2679     try:
2680         resp = conn.getresponse()
2681     except Exception, e:
2682         pass
2683     conn.close()
2684
2685     # Long URL but within header length limits
2686     conn.request("HEAD", 3000 * 'A')
2687     resp = conn.getresponse()
2688     if resp.status != 501:
2689         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2690     conn.close()
2691
2692     headers = { "Content-Length": '20' }
2693     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
2694     try:
2695         resp = conn.getresponse()
2696     except Exception, e:
2697         pass
2698     conn.close()
2699
2700     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
2701     resp = conn.getresponse()
2702     if resp.status != 404:
2703         raise Exception("Unexpected HTTP response: %d" % resp.status)
2704     conn.close()
2705
2706     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
2707     try:
2708         resp = conn.getresponse()
2709     except Exception, e:
2710         pass
2711     conn.close()
2712
2713 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
2714     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
2715     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2716     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2717
2718     location = ssdp_get_location(ap_uuid)
2719
2720     url = urlparse.urlparse(location)
2721     conn = httplib.HTTPConnection(url.netloc)
2722     #conn.set_debuglevel(1)
2723
2724     headers = { "Transfer-Encoding": 'chunked' }
2725     conn.request("POST", "hello",
2726                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
2727                  headers)
2728     resp = conn.getresponse()
2729     if resp.status != 404:
2730         raise Exception("Unexpected HTTP response: %d" % resp.status)
2731     conn.close()
2732
2733     conn.putrequest("POST", "hello")
2734     conn.putheader('Transfer-Encoding', 'chunked')
2735     conn.endheaders()
2736     conn.send("a\r\nabcdefghij\r\n")
2737     time.sleep(0.1)
2738     conn.send("2\r\nkl\r\n")
2739     conn.send("0\r\n\r\n")
2740     resp = conn.getresponse()
2741     if resp.status != 404:
2742         raise Exception("Unexpected HTTP response: %d" % resp.status)
2743     conn.close()
2744
2745     conn.putrequest("POST", "hello")
2746     conn.putheader('Transfer-Encoding', 'chunked')
2747     conn.endheaders()
2748     completed = False
2749     try:
2750         for i in range(20000):
2751             conn.send("1\r\nZ\r\n")
2752         conn.send("0\r\n\r\n")
2753         resp = conn.getresponse()
2754         completed = True
2755     except Exception, e:
2756         pass
2757     conn.close()
2758     if completed:
2759         raise Exception("Too long chunked request did not result in connection reset")
2760
2761     headers = { "Transfer-Encoding": 'chunked' }
2762     conn.request("POST", "hello", "80000000\r\na", headers)
2763     try:
2764         resp = conn.getresponse()
2765     except Exception, e:
2766         pass
2767     conn.close()
2768
2769     conn.request("POST", "hello", "10000000\r\na", headers)
2770     try:
2771         resp = conn.getresponse()
2772     except Exception, e:
2773         pass
2774     conn.close()
2775
2776 def test_ap_wps_disabled(dev, apdev):
2777     """WPS operations while WPS is disabled"""
2778     ssid = "test-wps-disabled"
2779     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
2780     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2781     if "FAIL" not in hapd.request("WPS_PBC"):
2782         raise Exception("WPS_PBC succeeded unexpectedly")
2783     if "FAIL" not in hapd.request("WPS_CANCEL"):
2784         raise Exception("WPS_CANCEL succeeded unexpectedly")
2785
2786 def test_ap_wps_mixed_cred(dev, apdev):
2787     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
2788     ssid = "test-wps-wep"
2789     hostapd.add_ap(apdev[0]['ifname'],
2790                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2791                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
2792     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2793     hapd.request("WPS_PBC")
2794     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2795     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2796     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
2797     if ev is None:
2798         raise Exception("WPS-SUCCESS event timed out")
2799     nets = dev[0].list_networks()
2800     if len(nets) != 1:
2801         raise Exception("Unexpected number of network blocks")
2802     id = nets[0]['id']
2803     proto = dev[0].get_network(id, "proto")
2804     if proto != "WPA RSN":
2805         raise Exception("Unexpected merged proto field value: " + proto)
2806     pairwise = dev[0].get_network(id, "pairwise")
2807     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
2808         raise Exception("Unexpected merged pairwise field value: " + pairwise)
2809
2810 def test_ap_wps_while_connected(dev, apdev):
2811     """WPS PBC provisioning while connected to another AP"""
2812     ssid = "test-wps-conf"
2813     hostapd.add_ap(apdev[0]['ifname'],
2814                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2815                      "wpa_passphrase": "12345678", "wpa": "2",
2816                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2817     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2818
2819     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2820     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2821
2822     logger.info("WPS provisioning step")
2823     hapd.request("WPS_PBC")
2824     dev[0].dump_monitor()
2825     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2826     dev[0].wait_connected(timeout=30)
2827     status = dev[0].get_status()
2828     if status['bssid'] != apdev[0]['bssid']:
2829         raise Exception("Unexpected BSSID")
2830
2831 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
2832     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
2833     ssid = "test-wps-conf"
2834     hostapd.add_ap(apdev[0]['ifname'],
2835                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2836                      "wpa_passphrase": "12345678", "wpa": "2",
2837                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2838     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2839
2840     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2841
2842     try:
2843         dev[0].request("STA_AUTOCONNECT 0")
2844         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2845
2846         logger.info("WPS provisioning step")
2847         hapd.request("WPS_PBC")
2848         dev[0].dump_monitor()
2849         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2850         dev[0].wait_connected(timeout=30)
2851         status = dev[0].get_status()
2852         if status['bssid'] != apdev[0]['bssid']:
2853             raise Exception("Unexpected BSSID")
2854     finally:
2855         dev[0].request("STA_AUTOCONNECT 1")
2856
2857 def test_ap_wps_from_event(dev, apdev):
2858     """WPS PBC event on AP to enable PBC"""
2859     ssid = "test-wps-conf"
2860     hapd = hostapd.add_ap(apdev[0]['ifname'],
2861                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2862                             "wpa_passphrase": "12345678", "wpa": "2",
2863                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2864     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2865     dev[0].dump_monitor()
2866     hapd.dump_monitor()
2867     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2868
2869     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
2870     if ev is None:
2871         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
2872     vals = ev.split(' ')
2873     if vals[1] != dev[0].p2p_interface_addr():
2874         raise Exception("Unexpected enrollee address: " + vals[1])
2875     if vals[5] != '4':
2876         raise Exception("Unexpected Device Password Id: " + vals[5])
2877     hapd.request("WPS_PBC")
2878     dev[0].wait_connected(timeout=30)
2879
2880 def test_ap_wps_ap_scan_2(dev, apdev):
2881     """AP_SCAN 2 for WPS"""
2882     ssid = "test-wps-conf"
2883     hapd = hostapd.add_ap(apdev[0]['ifname'],
2884                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2885                             "wpa_passphrase": "12345678", "wpa": "2",
2886                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2887     hapd.request("WPS_PBC")
2888
2889     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2890     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
2891
2892     if "OK" not in wpas.request("AP_SCAN 2"):
2893         raise Exception("Failed to set AP_SCAN 2")
2894
2895     wpas.flush_scan_cache()
2896     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
2897     wpas.request("WPS_PBC " + apdev[0]['bssid'])
2898     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
2899     if ev is None:
2900         raise Exception("WPS-SUCCESS event timed out")
2901     wpas.wait_connected(timeout=30)
2902     wpas.request("DISCONNECT")
2903     wpas.request("BSS_FLUSH 0")
2904     wpas.dump_monitor()
2905     wpas.request("REASSOCIATE")
2906     wpas.wait_connected(timeout=30)
2907
2908 def test_ap_wps_eapol_workaround(dev, apdev):
2909     """EAPOL workaround code path for 802.1X header length mismatch"""
2910     ssid = "test-wps"
2911     hostapd.add_ap(apdev[0]['ifname'],
2912                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
2913     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2914     bssid = apdev[0]['bssid']
2915     hapd.request("SET ext_eapol_frame_io 1")
2916     dev[0].request("SET ext_eapol_frame_io 1")
2917     hapd.request("WPS_PBC")
2918     dev[0].request("WPS_PBC")
2919
2920     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2921     if ev is None:
2922         raise Exception("Timeout on EAPOL-TX from hostapd")
2923
2924     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
2925     if "OK" not in res:
2926         raise Exception("EAPOL_RX to wpa_supplicant failed")
2927
2928 def test_ap_wps_iteration(dev, apdev):
2929     """WPS PIN and iterate through APs without selected registrar"""
2930     ssid = "test-wps-conf"
2931     hapd = hostapd.add_ap(apdev[0]['ifname'],
2932                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2933                             "wpa_passphrase": "12345678", "wpa": "2",
2934                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2935
2936     ssid2 = "test-wps-conf2"
2937     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
2938                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
2939                              "wpa_passphrase": "12345678", "wpa": "2",
2940                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2941
2942     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2943     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
2944     dev[0].dump_monitor()
2945     pin = dev[0].request("WPS_PIN any")
2946
2947     # Wait for iteration through all WPS APs to happen before enabling any
2948     # Registrar.
2949     for i in range(2):
2950         ev = dev[0].wait_event(["Associated with"], timeout=30)
2951         if ev is None:
2952             raise Exception("No association seen")
2953         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
2954         if ev is None:
2955             raise Exception("No M2D from AP")
2956         dev[0].wait_disconnected()
2957
2958     # Verify that each AP requested PIN
2959     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
2960     if ev is None:
2961         raise Exception("No WPS-PIN-NEEDED event from AP")
2962     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
2963     if ev is None:
2964         raise Exception("No WPS-PIN-NEEDED event from AP2")
2965
2966     # Provide PIN to one of the APs and verify that connection gets formed
2967     hapd.request("WPS_PIN any " + pin)
2968     dev[0].wait_connected(timeout=30)
2969
2970 def test_ap_wps_iteration_error(dev, apdev):
2971     """WPS AP iteration on no Selected Registrar and error case with an AP"""
2972     ssid = "test-wps-conf-pin"
2973     hapd = hostapd.add_ap(apdev[0]['ifname'],
2974                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2975                             "wpa_passphrase": "12345678", "wpa": "2",
2976                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2977                             "wps_independent": "1" })
2978     hapd.request("SET ext_eapol_frame_io 1")
2979     bssid = apdev[0]['bssid']
2980     pin = dev[0].wps_read_pin()
2981     dev[0].request("WPS_PIN any " + pin)
2982
2983     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2984     if ev is None:
2985         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
2986     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
2987
2988     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2989     if ev is None:
2990         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
2991     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
2992     if ev is None:
2993         raise Exception("No CTRL-EVENT-EAP-STARTED")
2994
2995     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
2996     # a case with an incorrectly behaving WPS AP.
2997
2998     # Start the real target AP and activate registrar on it.
2999     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3000                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3001                             "wpa_passphrase": "12345678", "wpa": "2",
3002                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3003                             "wps_independent": "1" })
3004     hapd2.request("WPS_PIN any " + pin)
3005
3006     dev[0].wait_disconnected(timeout=15)
3007     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3008     if ev is None:
3009         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3010     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3011     if ev is None:
3012         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3013     dev[0].wait_connected(timeout=15)
3014
3015 def test_ap_wps_priority(dev, apdev):
3016     """WPS PIN provisioning with configured AP and wps_priority"""
3017     ssid = "test-wps-conf-pin"
3018     hostapd.add_ap(apdev[0]['ifname'],
3019                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3020                      "wpa_passphrase": "12345678", "wpa": "2",
3021                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3022     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3023     logger.info("WPS provisioning step")
3024     pin = dev[0].wps_read_pin()
3025     hapd.request("WPS_PIN any " + pin)
3026     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3027     dev[0].dump_monitor()
3028     try:
3029         dev[0].request("SET wps_priority 6")
3030         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3031         dev[0].wait_connected(timeout=30)
3032         netw = dev[0].list_networks()
3033         prio = dev[0].get_network(netw[0]['id'], 'priority')
3034         if prio != '6':
3035             raise Exception("Unexpected network priority: " + prio)
3036     finally:
3037         dev[0].request("SET wps_priority 0")
3038
3039 def test_ap_wps_and_non_wps(dev, apdev):
3040     """WPS and non-WPS AP in single hostapd process"""
3041     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3042     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3043
3044     params = { "ssid": "no wps" }
3045     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3046
3047     appin = hapd.request("WPS_AP_PIN random")
3048     if "FAIL" in appin:
3049         raise Exception("Could not generate random AP PIN")
3050     if appin not in hapd.request("WPS_AP_PIN get"):
3051         raise Exception("Could not fetch current AP PIN")
3052
3053     if "FAIL" in hapd.request("WPS_PBC"):
3054         raise Exception("WPS_PBC failed")
3055     if "FAIL" in hapd.request("WPS_CANCEL"):
3056         raise Exception("WPS_CANCEL failed")
3057
3058 def test_ap_wps_init_oom(dev, apdev):
3059     """Initial AP configuration and OOM during PSK generation"""
3060     ssid = "test-wps"
3061     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3062     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3063
3064     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3065         pin = dev[0].wps_read_pin()
3066         hapd.request("WPS_PIN any " + pin)
3067         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3068         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3069         dev[0].wait_disconnected()
3070
3071     hapd.request("WPS_PIN any " + pin)
3072     dev[0].wait_connected(timeout=30)
3073
3074 def test_ap_wps_er_oom(dev, apdev):
3075     """WPS ER OOM in XML processing"""
3076     try:
3077         _test_ap_wps_er_oom(dev, apdev)
3078     finally:
3079         dev[0].request("WPS_ER_STOP")
3080         dev[1].request("WPS_CANCEL")
3081         dev[0].request("DISCONNECT")
3082
3083 def _test_ap_wps_er_oom(dev, apdev):
3084     ssid = "wps-er-ap-config"
3085     ap_pin = "12345670"
3086     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3087     hostapd.add_ap(apdev[0]['ifname'],
3088                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3089                      "wpa_passphrase": "12345678", "wpa": "2",
3090                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3091                      "device_name": "Wireless AP", "manufacturer": "Company",
3092                      "model_name": "WAP", "model_number": "123",
3093                      "serial_number": "12345", "device_type": "6-0050F204-1",
3094                      "os_version": "01020300",
3095                      "config_methods": "label push_button",
3096                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3097
3098     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3099
3100     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3101         dev[0].request("WPS_ER_START ifname=lo")
3102         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3103         if ev is not None:
3104             raise Exception("Unexpected AP discovery")
3105
3106     dev[0].request("WPS_ER_STOP")
3107     dev[0].request("WPS_ER_START ifname=lo")
3108     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3109     if ev is None:
3110         raise Exception("AP discovery timed out")
3111
3112     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3113     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3114         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3115         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3116         if ev is None:
3117             raise Exception("PBC scan failed")
3118         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3119         if ev is None:
3120             raise Exception("Enrollee discovery timed out")
3121
3122 def test_ap_wps_er_init_oom(dev, apdev):
3123     """WPS ER and OOM during init"""
3124     try:
3125         _test_ap_wps_er_init_oom(dev, apdev)
3126     finally:
3127         dev[0].request("WPS_ER_STOP")
3128
3129 def _test_ap_wps_er_init_oom(dev, apdev):
3130     with alloc_fail(dev[0], 1, "wps_er_init"):
3131         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3132             raise Exception("WPS_ER_START succeeded during OOM")
3133     with alloc_fail(dev[0], 1, "http_server_init"):
3134         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3135             raise Exception("WPS_ER_START succeeded during OOM")
3136     with alloc_fail(dev[0], 2, "http_server_init"):
3137         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3138             raise Exception("WPS_ER_START succeeded during OOM")
3139     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3140         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3141             raise Exception("WPS_ER_START succeeded during OOM")
3142     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3143         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3144             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3145
3146 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3147     """WPS events and wpa_cli action script"""
3148     logdir = os.path.abspath(test_params['logdir'])
3149     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3150     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3151     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3152
3153     with open(actionfile, 'w') as f:
3154         f.write('#!/bin/sh\n')
3155         f.write('echo $* >> %s\n' % logfile)
3156         # Kill the process and wait some time before returning to allow all the
3157         # pending events to be processed with some of this happening after the
3158         # eloop SIGALRM signal has been scheduled.
3159         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3160
3161     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3162              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3163
3164     ssid = "test-wps-conf"
3165     hostapd.add_ap(apdev[0]['ifname'],
3166                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3167                      "wpa_passphrase": "12345678", "wpa": "2",
3168                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3169     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3170
3171     prg = os.path.join(test_params['logdir'],
3172                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3173     if not os.path.exists(prg):
3174         prg = '../../wpa_supplicant/wpa_cli'
3175     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3176     subprocess.call(arg)
3177
3178     arg = [ 'ps', 'ax' ]
3179     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3180     out = cmd.communicate()[0]
3181     cmd.wait()
3182     logger.debug("Processes:\n" + out)
3183     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3184         raise Exception("Did not see wpa_cli running")
3185
3186     hapd.request("WPS_PIN any 12345670")
3187     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3188     dev[0].dump_monitor()
3189     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3190     dev[0].wait_connected(timeout=30)
3191
3192     for i in range(30):
3193         if not os.path.exists(pidfile):
3194             break
3195         time.sleep(0.1)
3196
3197     if not os.path.exists(logfile):
3198         raise Exception("wpa_cli action results file not found")
3199     with open(logfile, 'r') as f:
3200         res = f.read()
3201     if "WPS-SUCCESS" not in res:
3202         raise Exception("WPS-SUCCESS event not seen in action file")
3203
3204     arg = [ 'ps', 'ax' ]
3205     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3206     out = cmd.communicate()[0]
3207     cmd.wait()
3208     logger.debug("Remaining processes:\n" + out)
3209     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3210         raise Exception("wpa_cli still running")
3211
3212     if os.path.exists(pidfile):
3213         raise Exception("PID file not removed")
3214
3215 def test_ap_wps_er_ssdp_proto(dev, apdev):
3216     """WPS ER SSDP protocol testing"""
3217     try:
3218         _test_ap_wps_er_ssdp_proto(dev, apdev)
3219     finally:
3220         dev[0].request("WPS_ER_STOP")
3221
3222 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3223     socket.setdefaulttimeout(1)
3224     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3225     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3226     sock.bind(("239.255.255.250", 1900))
3227     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3228         raise Exception("Invalid filter accepted")
3229     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3230         raise Exception("WPS_ER_START with filter failed")
3231     (msg,addr) = sock.recvfrom(1000)
3232     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3233     if "M-SEARCH" not in msg:
3234         raise Exception("Not an M-SEARCH")
3235     sock.sendto("FOO", addr)
3236     time.sleep(0.1)
3237     dev[0].request("WPS_ER_STOP")
3238
3239     dev[0].request("WPS_ER_START ifname=lo")
3240     (msg,addr) = sock.recvfrom(1000)
3241     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3242     if "M-SEARCH" not in msg:
3243         raise Exception("Not an M-SEARCH")
3244     sock.sendto("FOO", addr)
3245     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3246     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3247     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3248     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3249     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3250     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3251     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3252     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3253     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3254     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3255     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3256     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)
3257     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3258     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3259         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)
3260         time.sleep(0.1)
3261     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3262         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)
3263         time.sleep(0.1)
3264
3265     # Add an AP with bogus URL
3266     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)
3267     # Update timeout on AP without updating URL
3268     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)
3269     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3270     if ev is None:
3271         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3272
3273     # Add an AP with a valid URL (but no server listing to it)
3274     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)
3275     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3276     if ev is None:
3277         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3278
3279     sock.close()
3280
3281 wps_event_url = None
3282
3283 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3284                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3285     payload = '''<?xml version="1.0"?>
3286 <root xmlns="urn:schemas-upnp-org:device-1-0">
3287 <specVersion>
3288 <major>1</major>
3289 <minor>0</minor>
3290 </specVersion>
3291 <device>
3292 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3293 <friendlyName>WPS Access Point</friendlyName>
3294 <manufacturer>Company</manufacturer>
3295 <modelName>WAP</modelName>
3296 <modelNumber>123</modelNumber>
3297 <serialNumber>12345</serialNumber>
3298 '''
3299     if udn:
3300         payload += '<UDN>' + udn + '</UDN>'
3301     payload += '''<serviceList>
3302 <service>
3303 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3304 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3305 <SCPDURL>wps_scpd.xml</SCPDURL>
3306 '''
3307     if controlURL:
3308         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3309     if eventSubURL:
3310         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3311     payload += '''</service>
3312 </serviceList>
3313 </device>
3314 </root>
3315 '''
3316     hdr = 'HTTP/1.1 200 OK\r\n' + \
3317           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3318           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3319           'Connection: close\r\n' + \
3320           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3321           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3322     return hdr + payload
3323
3324 def gen_wps_control(payload_override=None):
3325     payload = '''<?xml version="1.0"?>
3326 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3327 <s:Body>
3328 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3329 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3330 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3331 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3332 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3333 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3334 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3335 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3336 AAYANyoAASA=
3337 </NewDeviceInfo>
3338 </u:GetDeviceInfoResponse>
3339 </s:Body>
3340 </s:Envelope>
3341 '''
3342     if payload_override:
3343         payload = payload_override
3344     hdr = 'HTTP/1.1 200 OK\r\n' + \
3345           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3346           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3347           'Connection: close\r\n' + \
3348           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3349           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3350     return hdr + payload
3351
3352 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3353     payload = ""
3354     hdr = 'HTTP/1.1 200 OK\r\n' + \
3355           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3356           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3357           'Connection: close\r\n' + \
3358           'Content-Length: ' + str(len(payload)) + '\r\n'
3359     if sid:
3360         hdr += 'SID: ' + sid + '\r\n'
3361     hdr += 'Timeout: Second-1801\r\n' + \
3362           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3363     return hdr + payload
3364
3365 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3366     def handle(self):
3367         data = self.rfile.readline().strip()
3368         logger.info("HTTP server received: " + data)
3369         while True:
3370             hdr = self.rfile.readline().strip()
3371             if len(hdr) == 0:
3372                 break
3373             logger.info("HTTP header: " + hdr)
3374             if "CALLBACK:" in hdr:
3375                 global wps_event_url
3376                 wps_event_url = hdr.split(' ')[1].strip('<>')
3377
3378         if "GET /foo.xml" in data:
3379             self.handle_upnp_info()
3380         elif "POST /wps_control" in data:
3381             self.handle_wps_control()
3382         elif "SUBSCRIBE /wps_event" in data:
3383             self.handle_wps_event()
3384         else:
3385             self.handle_others(data)
3386
3387     def handle_upnp_info(self):
3388         self.wfile.write(gen_upnp_info())
3389
3390     def handle_wps_control(self):
3391         self.wfile.write(gen_wps_control())
3392
3393     def handle_wps_event(self):
3394         self.wfile.write(gen_wps_event())
3395
3396     def handle_others(self, data):
3397         logger.info("Ignore HTTP request: " + data)
3398
3399 class MyTCPServer(SocketServer.TCPServer):
3400     def __init__(self, addr, handler):
3401         self.allow_reuse_address = True
3402         SocketServer.TCPServer.__init__(self, addr, handler)
3403
3404 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3405                  location_url=None):
3406     socket.setdefaulttimeout(1)
3407     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3408     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3409     sock.bind(("239.255.255.250", 1900))
3410     dev.request("WPS_ER_START ifname=lo")
3411     for i in range(100):
3412         (msg,addr) = sock.recvfrom(1000)
3413         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3414         if "M-SEARCH" in msg:
3415             break
3416         if not wait_m_search:
3417             raise Exception("Not an M-SEARCH")
3418         if i == 99:
3419             raise Exception("No M-SEARCH seen")
3420
3421     # Add an AP with a valid URL and server listing to it
3422     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3423     if not location_url:
3424         location_url = 'http://127.0.0.1:12345/foo.xml'
3425     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)
3426     server.timeout = 1
3427     return server,sock
3428
3429 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3430     sock.close()
3431     server.server_close()
3432
3433     if on_alloc_fail:
3434         done = False
3435         for i in range(50):
3436             res = dev.request("GET_ALLOC_FAIL")
3437             if res.startswith("0:"):
3438                 done = True
3439                 break
3440             time.sleep(0.1)
3441         if not done:
3442             raise Exception("No allocation failure reported")
3443     else:
3444         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3445         if ev is None:
3446             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3447     dev.request("WPS_ER_STOP")
3448
3449 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
3450     try:
3451         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3452         server,sock = wps_er_start(dev, handler, location_url=location_url)
3453         global wps_event_url
3454         wps_event_url = None
3455         server.handle_request()
3456         server.handle_request()
3457         server.handle_request()
3458         server.server_close()
3459         if no_event_url:
3460             if wps_event_url:
3461                 raise Exception("Received event URL unexpectedly")
3462             return
3463         if wps_event_url is None:
3464             raise Exception("Did not get event URL")
3465         logger.info("Event URL: " + wps_event_url)
3466     finally:
3467             dev.request("WPS_ER_STOP")
3468
3469 def send_wlanevent(url, uuid, data):
3470     conn = httplib.HTTPConnection(url.netloc)
3471     payload = '''<?xml version="1.0" encoding="utf-8"?>
3472 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3473 <e:property><STAStatus>1</STAStatus></e:property>
3474 <e:property><APStatus>1</APStatus></e:property>
3475 <e:property><WLANEvent>'''
3476     payload += base64.b64encode(data)
3477     payload += '</WLANEvent></e:property></e:propertyset>'
3478     headers = { "Content-type": 'text/xml; charset="utf-8"',
3479                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3480                 "HOST": url.netloc,
3481                 "NT": "upnp:event",
3482                 "SID": "uuid:" + uuid,
3483                 "SEQ": "0",
3484                 "Content-Length": str(len(payload)) }
3485     conn.request("NOTIFY", url.path, payload, headers)
3486     resp = conn.getresponse()
3487     if resp.status != 200:
3488         raise Exception("Unexpected HTTP response: %d" % resp.status)
3489
3490 def test_ap_wps_er_http_proto(dev, apdev):
3491     """WPS ER HTTP protocol testing"""
3492     try:
3493         _test_ap_wps_er_http_proto(dev, apdev)
3494     finally:
3495         dev[0].request("WPS_ER_STOP")
3496
3497 def _test_ap_wps_er_http_proto(dev, apdev):
3498     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3499     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
3500     global wps_event_url
3501     wps_event_url = None
3502     server.handle_request()
3503     server.handle_request()
3504     server.handle_request()
3505     server.server_close()
3506     if wps_event_url is None:
3507         raise Exception("Did not get event URL")
3508     logger.info("Event URL: " + wps_event_url)
3509
3510     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3511     if ev is None:
3512         raise Exception("No WPS-ER-AP-ADD event")
3513     if uuid not in ev:
3514         raise Exception("UUID mismatch")
3515
3516     sock.close()
3517
3518     logger.info("Valid Probe Request notification")
3519     url = urlparse.urlparse(wps_event_url)
3520     conn = httplib.HTTPConnection(url.netloc)
3521     payload = '''<?xml version="1.0" encoding="utf-8"?>
3522 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3523 <e:property><STAStatus>1</STAStatus></e:property>
3524 <e:property><APStatus>1</APStatus></e:property>
3525 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
3526 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
3527 RGV2aWNlIEEQSQAGADcqAAEg
3528 </WLANEvent></e:property>
3529 </e:propertyset>
3530 '''
3531     headers = { "Content-type": 'text/xml; charset="utf-8"',
3532                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3533                 "HOST": url.netloc,
3534                 "NT": "upnp:event",
3535                 "SID": "uuid:" + uuid,
3536                 "SEQ": "0",
3537                 "Content-Length": str(len(payload)) }
3538     conn.request("NOTIFY", url.path, payload, headers)
3539     resp = conn.getresponse()
3540     if resp.status != 200:
3541         raise Exception("Unexpected HTTP response: %d" % resp.status)
3542
3543     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
3544     if ev is None:
3545         raise Exception("No WPS-ER-ENROLLEE-ADD event")
3546     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
3547         raise Exception("No Enrollee UUID match")
3548
3549     logger.info("Incorrect event URL AP id")
3550     conn = httplib.HTTPConnection(url.netloc)
3551     conn.request("NOTIFY", url.path + '123', payload, headers)
3552     resp = conn.getresponse()
3553     if resp.status != 404:
3554         raise Exception("Unexpected HTTP response: %d" % resp.status)
3555
3556     logger.info("Missing AP id")
3557     conn = httplib.HTTPConnection(url.netloc)
3558     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
3559                  payload, headers)
3560     time.sleep(0.1)
3561
3562     logger.info("Incorrect event URL event id")
3563     conn = httplib.HTTPConnection(url.netloc)
3564     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
3565     time.sleep(0.1)
3566
3567     logger.info("Incorrect event URL prefix")
3568     conn = httplib.HTTPConnection(url.netloc)
3569     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
3570     resp = conn.getresponse()
3571     if resp.status != 404:
3572         raise Exception("Unexpected HTTP response: %d" % resp.status)
3573
3574     logger.info("Unsupported request")
3575     conn = httplib.HTTPConnection(url.netloc)
3576     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
3577     resp = conn.getresponse()
3578     if resp.status != 501:
3579         raise Exception("Unexpected HTTP response: %d" % resp.status)
3580
3581     logger.info("Unsupported request and OOM")
3582     with alloc_fail(dev[0], 1, "wps_er_http_req"):
3583         conn = httplib.HTTPConnection(url.netloc)
3584         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
3585         time.sleep(0.5)
3586
3587     logger.info("Too short WLANEvent")
3588     data = '\x00'
3589     send_wlanevent(url, uuid, data)
3590
3591     logger.info("Invalid WLANEventMAC")
3592     data = '\x00qwertyuiopasdfghjklzxcvbnm'
3593     send_wlanevent(url, uuid, data)
3594
3595     logger.info("Unknown WLANEventType")
3596     data = '\xff02:00:00:00:00:00'
3597     send_wlanevent(url, uuid, data)
3598
3599     logger.info("Probe Request notification without any attributes")
3600     data = '\x0102:00:00:00:00:00'
3601     send_wlanevent(url, uuid, data)
3602
3603     logger.info("Probe Request notification with invalid attribute")
3604     data = '\x0102:00:00:00:00:00\xff'
3605     send_wlanevent(url, uuid, data)
3606
3607     logger.info("EAP message without any attributes")
3608     data = '\x0202:00:00:00:00:00'
3609     send_wlanevent(url, uuid, data)
3610
3611     logger.info("EAP message with invalid attribute")
3612     data = '\x0202:00:00:00:00:00\xff'
3613     send_wlanevent(url, uuid, data)
3614
3615     logger.info("EAP message from new STA and not M1")
3616     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
3617     send_wlanevent(url, uuid, data)
3618
3619     logger.info("EAP message: M1")
3620     data = '\x0202:00:00:00:00:00'
3621     data += '\x10\x22\x00\x01\x04'
3622     data += '\x10\x47\x00\x10' + 16*'\x00'
3623     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
3624     data += '\x10\x1a\x00\x10' + 16*'\x00'
3625     data += '\x10\x32\x00\xc0' + 192*'\x00'
3626     data += '\x10\x04\x00\x02\x00\x00'
3627     data += '\x10\x10\x00\x02\x00\x00'
3628     data += '\x10\x0d\x00\x01\x00'
3629     data += '\x10\x08\x00\x02\x00\x00'
3630     data += '\x10\x44\x00\x01\x00'
3631     data += '\x10\x21\x00\x00'
3632     data += '\x10\x23\x00\x00'
3633     data += '\x10\x24\x00\x00'
3634     data += '\x10\x42\x00\x00'
3635     data += '\x10\x54\x00\x08' + 8*'\x00'
3636     data += '\x10\x11\x00\x00'
3637     data += '\x10\x3c\x00\x01\x00'
3638     data += '\x10\x02\x00\x02\x00\x00'
3639     data += '\x10\x12\x00\x02\x00\x00'
3640     data += '\x10\x09\x00\x02\x00\x00'
3641     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
3642     m1 = data
3643     send_wlanevent(url, uuid, data)
3644
3645     logger.info("EAP message: WSC_ACK")
3646     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
3647     send_wlanevent(url, uuid, data)
3648
3649     logger.info("EAP message: M1")
3650     send_wlanevent(url, uuid, m1)
3651
3652     logger.info("EAP message: WSC_NACK")
3653     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
3654     send_wlanevent(url, uuid, data)
3655
3656     logger.info("EAP message: M1 - Too long attribute values")
3657     data = '\x0202:00:00:00:00:00'
3658     data += '\x10\x11\x00\x21' + 33*'\x00'
3659     data += '\x10\x45\x00\x21' + 33*'\x00'
3660     data += '\x10\x42\x00\x21' + 33*'\x00'
3661     data += '\x10\x24\x00\x21' + 33*'\x00'
3662     data += '\x10\x23\x00\x21' + 33*'\x00'
3663     data += '\x10\x21\x00\x41' + 65*'\x00'
3664     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
3665     send_wlanevent(url, uuid, data)
3666
3667     logger.info("EAP message: M1 missing UUID-E")
3668     data = '\x0202:00:00:00:00:00'
3669     data += '\x10\x22\x00\x01\x04'
3670     send_wlanevent(url, uuid, data)
3671
3672     logger.info("EAP message: M1 missing MAC Address")
3673     data += '\x10\x47\x00\x10' + 16*'\x00'
3674     send_wlanevent(url, uuid, data)
3675
3676     logger.info("EAP message: M1 missing Enrollee Nonce")
3677     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
3678     send_wlanevent(url, uuid, data)
3679
3680     logger.info("EAP message: M1 missing Public Key")
3681     data += '\x10\x1a\x00\x10' + 16*'\x00'
3682     send_wlanevent(url, uuid, data)
3683
3684     logger.info("EAP message: M1 missing Authentication Type flags")
3685     data += '\x10\x32\x00\xc0' + 192*'\x00'
3686     send_wlanevent(url, uuid, data)
3687
3688     logger.info("EAP message: M1 missing Encryption Type Flags")
3689     data += '\x10\x04\x00\x02\x00\x00'
3690     send_wlanevent(url, uuid, data)
3691
3692     logger.info("EAP message: M1 missing Connection Type flags")
3693     data += '\x10\x10\x00\x02\x00\x00'
3694     send_wlanevent(url, uuid, data)
3695
3696     logger.info("EAP message: M1 missing Config Methods")
3697     data += '\x10\x0d\x00\x01\x00'
3698     send_wlanevent(url, uuid, data)
3699
3700     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
3701     data += '\x10\x08\x00\x02\x00\x00'
3702     send_wlanevent(url, uuid, data)
3703
3704     logger.info("EAP message: M1 missing Manufacturer")
3705     data += '\x10\x44\x00\x01\x00'
3706     send_wlanevent(url, uuid, data)
3707
3708     logger.info("EAP message: M1 missing Model Name")
3709     data += '\x10\x21\x00\x00'
3710     send_wlanevent(url, uuid, data)
3711
3712     logger.info("EAP message: M1 missing Model Number")
3713     data += '\x10\x23\x00\x00'
3714     send_wlanevent(url, uuid, data)
3715
3716     logger.info("EAP message: M1 missing Serial Number")
3717     data += '\x10\x24\x00\x00'
3718     send_wlanevent(url, uuid, data)
3719
3720     logger.info("EAP message: M1 missing Primary Device Type")
3721     data += '\x10\x42\x00\x00'
3722     send_wlanevent(url, uuid, data)
3723
3724     logger.info("EAP message: M1 missing Device Name")
3725     data += '\x10\x54\x00\x08' + 8*'\x00'
3726     send_wlanevent(url, uuid, data)
3727
3728     logger.info("EAP message: M1 missing RF Bands")
3729     data += '\x10\x11\x00\x00'
3730     send_wlanevent(url, uuid, data)
3731
3732     logger.info("EAP message: M1 missing Association State")
3733     data += '\x10\x3c\x00\x01\x00'
3734     send_wlanevent(url, uuid, data)
3735
3736     logger.info("EAP message: M1 missing Device Password ID")
3737     data += '\x10\x02\x00\x02\x00\x00'
3738     send_wlanevent(url, uuid, data)
3739
3740     logger.info("EAP message: M1 missing Configuration Error")
3741     data += '\x10\x12\x00\x02\x00\x00'
3742     send_wlanevent(url, uuid, data)
3743
3744     logger.info("EAP message: M1 missing OS Version")
3745     data += '\x10\x09\x00\x02\x00\x00'
3746     send_wlanevent(url, uuid, data)
3747
3748     logger.info("Check max concurrent requests")
3749     addr = (url.hostname, url.port)
3750     socks = {}
3751     for i in range(20):
3752         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3753                                  socket.IPPROTO_TCP)
3754         socks[i].connect(addr)
3755     for i in range(20):
3756         socks[i].send("GET / HTTP/1.1\r\n\r\n")
3757     count = 0
3758     for i in range(20):
3759         try:
3760             res = socks[i].recv(100)
3761             if "HTTP/1" in res:
3762                 count += 1
3763         except:
3764             pass
3765         socks[i].close()
3766     logger.info("%d concurrent HTTP GET operations returned response" % count)
3767     if count < 10:
3768         raise Exception("Too few concurrent HTTP connections accepted")
3769
3770     logger.info("OOM in HTTP server")
3771     for func in [ "http_request_init", "httpread_create",
3772                   "eloop_register_timeout;httpread_create",
3773                   "eloop_register_sock;httpread_create",
3774                   "httpread_hdr_analyze" ]:
3775         with alloc_fail(dev[0], 1, func):
3776             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3777                                  socket.IPPROTO_TCP)
3778             sock.connect(addr)
3779             sock.send("GET / HTTP/1.1\r\n\r\n")
3780             try:
3781                 sock.recv(100)
3782             except:
3783                 pass
3784             sock.close()
3785
3786     logger.info("Invalid HTTP header")
3787     for req in [ " GET / HTTP/1.1\r\n\r\n",
3788                  "HTTP/1.1 200 OK\r\n\r\n",
3789                  "HTTP/\r\n\r\n",
3790                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
3791                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
3792                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
3793                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
3794                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
3795                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
3796                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
3797                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
3798         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3799                              socket.IPPROTO_TCP)
3800         sock.settimeout(0.1)
3801         sock.connect(addr)
3802         sock.send(req)
3803         try:
3804             sock.recv(100)
3805         except:
3806             pass
3807         sock.close()
3808
3809     with alloc_fail(dev[0], 2, "httpread_read_handler"):
3810         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
3811                              socket.IPPROTO_TCP)
3812         sock.connect(addr)
3813         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
3814         try:
3815             sock.recv(100)
3816         except:
3817             pass
3818         sock.close()
3819
3820     conn = httplib.HTTPConnection(url.netloc)
3821     payload = '<foo'
3822     headers = { "Content-type": 'text/xml; charset="utf-8"',
3823                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3824                 "HOST": url.netloc,
3825                 "NT": "upnp:event",
3826                 "SID": "uuid:" + uuid,
3827                 "SEQ": "0",
3828                 "Content-Length": str(len(payload)) }
3829     conn.request("NOTIFY", url.path, payload, headers)
3830     resp = conn.getresponse()
3831     if resp.status != 200:
3832         raise Exception("Unexpected HTTP response: %d" % resp.status)
3833
3834     conn = httplib.HTTPConnection(url.netloc)
3835     payload = '<WLANEvent foo></WLANEvent>'
3836     headers = { "Content-type": 'text/xml; charset="utf-8"',
3837                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3838                 "HOST": url.netloc,
3839                 "NT": "upnp:event",
3840                 "SID": "uuid:" + uuid,
3841                 "SEQ": "0",
3842                 "Content-Length": str(len(payload)) }
3843     conn.request("NOTIFY", url.path, payload, headers)
3844     resp = conn.getresponse()
3845     if resp.status != 200:
3846         raise Exception("Unexpected HTTP response: %d" % resp.status)
3847
3848     with alloc_fail(dev[0], 1, "xml_get_first_item"):
3849         send_wlanevent(url, uuid, '')
3850
3851     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
3852         send_wlanevent(url, uuid, 'foo')
3853
3854     for func in [ "wps_init",
3855                   "wps_process_manufacturer",
3856                   "wps_process_model_name",
3857                   "wps_process_model_number",
3858                   "wps_process_serial_number",
3859                   "wps_process_dev_name" ]:
3860         with alloc_fail(dev[0], 1, func):
3861             send_wlanevent(url, uuid, m1)
3862
3863 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
3864     """WPS ER HTTP protocol testing - no eventSubURL"""
3865     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
3866         def handle_upnp_info(self):
3867             self.wfile.write(gen_upnp_info(eventSubURL=None))
3868     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
3869                           no_event_url=True)
3870
3871 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
3872     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
3873     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
3874         def handle_upnp_info(self):
3875             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
3876     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
3877                           no_event_url=True)
3878
3879 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
3880     """WPS ER HTTP protocol testing - subscribe OOM"""
3881     try:
3882         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
3883     finally:
3884         dev[0].request("WPS_ER_STOP")
3885
3886 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
3887     tests = [ (1, "http_client_url_parse"),
3888               (1, "wpabuf_alloc;wps_er_subscribe"),
3889               (1, "http_client_addr"),
3890               (1, "eloop_register_sock;http_client_addr"),
3891               (1, "eloop_register_timeout;http_client_addr") ]
3892     for count,func in tests:
3893         with alloc_fail(dev[0], count, func):
3894             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
3895             server.handle_request()
3896             server.handle_request()
3897             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
3898
3899 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
3900     """WPS ER HTTP protocol testing - no SID"""
3901     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
3902         def handle_wps_event(self):
3903             self.wfile.write(gen_wps_event(sid=None))
3904     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
3905
3906 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
3907     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
3908     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
3909         def handle_wps_event(self):
3910             self.wfile.write(gen_wps_event(sid='FOO'))
3911     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
3912
3913 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
3914     """WPS ER HTTP protocol testing - invalid SID UUID"""
3915     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
3916         def handle_wps_event(self):
3917             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
3918     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
3919
3920 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
3921     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
3922     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
3923         def handle_wps_event(self):
3924             payload = ""
3925             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
3926                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3927                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3928                   'Connection: close\r\n' + \
3929                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3930                   'Timeout: Second-1801\r\n' + \
3931                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3932             self.wfile.write(hdr + payload)
3933     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
3934
3935 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
3936     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
3937     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
3938         def handle_wps_event(self):
3939             payload = ""
3940             hdr = 'HTTP/1.1 FOO\r\n' + \
3941                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3942                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3943                   'Connection: close\r\n' + \
3944                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3945                   'Timeout: Second-1801\r\n' + \
3946                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3947             self.wfile.write(hdr + payload)
3948     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
3949
3950 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
3951     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
3952     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
3953         def handle_wps_control(self):
3954             payload = '''<?xml version="1.0"?>
3955 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3956 <s:Body>
3957 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3958 <NewDeviceInfo>Rk9P</NewDeviceInfo>
3959 </u:GetDeviceInfoResponse>
3960 </s:Body>
3961 </s:Envelope>
3962 '''
3963             self.wfile.write(gen_wps_control(payload_override=payload))
3964     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
3965
3966 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
3967     """WPS ER HTTP protocol testing - No device in UPnP info"""
3968     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
3969         def handle_upnp_info(self):
3970             payload = '''<?xml version="1.0"?>
3971 <root xmlns="urn:schemas-upnp-org:device-1-0">
3972 <specVersion>
3973 <major>1</major>
3974 <minor>0</minor>
3975 </specVersion>
3976 </root>
3977 '''
3978             hdr = 'HTTP/1.1 200 OK\r\n' + \
3979                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
3980                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3981                   'Connection: close\r\n' + \
3982                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
3983                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3984             self.wfile.write(hdr + payload)
3985     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
3986
3987 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
3988     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
3989     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
3990         def handle_upnp_info(self):
3991             payload = '''<?xml version="1.0"?>
3992 <root xmlns="urn:schemas-upnp-org:device-1-0">
3993 <specVersion>
3994 <major>1</major>
3995 <minor>0</minor>
3996 </specVersion>
3997 <device>
3998 </device>
3999 </root>
4000 '''
4001             hdr = 'HTTP/1.1 200 OK\r\n' + \
4002                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4003                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4004                   'Connection: close\r\n' + \
4005                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4006                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4007             self.wfile.write(hdr + payload)
4008     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4009
4010 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4011     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4012     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4013         def handle_upnp_info(self):
4014             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4015     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4016
4017 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4018     """WPS ER HTTP protocol testing - no controlURL"""
4019     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4020         def handle_upnp_info(self):
4021             self.wfile.write(gen_upnp_info(controlURL=None))
4022     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4023                           no_event_url=True)
4024
4025 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4026     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4027     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4028         def handle_upnp_info(self):
4029             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4030     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4031                           no_event_url=True)
4032
4033 def test_ap_wps_http_timeout(dev, apdev):
4034     """WPS AP/ER and HTTP timeout"""
4035     try:
4036         _test_ap_wps_http_timeout(dev, apdev)
4037     finally:
4038         dev[0].request("WPS_ER_STOP")
4039
4040 def _test_ap_wps_http_timeout(dev, apdev):
4041     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4042     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4043
4044     location = ssdp_get_location(ap_uuid)
4045     url = urlparse.urlparse(location)
4046     addr = (url.hostname, url.port)
4047     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4048     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4049                          socket.IPPROTO_TCP)
4050     sock.connect(addr)
4051     sock.send("G")
4052
4053     class DummyServer(SocketServer.StreamRequestHandler):
4054         def handle(self):
4055             logger.debug("DummyServer - start 31 sec wait")
4056             time.sleep(31)
4057             logger.debug("DummyServer - wait done")
4058
4059     logger.debug("Start WPS ER")
4060     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4061                                 wait_m_search=True)
4062
4063     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4064     # This will wait for 31 seconds..
4065     server.handle_request()
4066
4067     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4068     try:
4069         sock.send("ET / HTTP/1.1\r\n\r\n")
4070         res = sock.recv(100)
4071         sock.close()
4072     except:
4073         pass
4074
4075 def test_ap_wps_er_url_parse(dev, apdev):
4076     """WPS ER and URL parsing special cases"""
4077     try:
4078         _test_ap_wps_er_url_parse(dev, apdev)
4079     finally:
4080         dev[0].request("WPS_ER_STOP")
4081
4082 def _test_ap_wps_er_url_parse(dev, apdev):
4083     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4084     sock.settimeout(1)
4085     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4086     sock.bind(("239.255.255.250", 1900))
4087     dev[0].request("WPS_ER_START ifname=lo")
4088     (msg,addr) = sock.recvfrom(1000)
4089     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4090     if "M-SEARCH" not in msg:
4091         raise Exception("Not an M-SEARCH")
4092     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)
4093     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4094     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)
4095     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4096     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)
4097     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4098
4099     sock.close()
4100
4101 def test_ap_wps_er_link_update(dev, apdev):
4102     """WPS ER and link update special cases"""
4103     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4104         def handle_upnp_info(self):
4105             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4106     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4107
4108     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4109         def handle_others(self, data):
4110             if "GET / " in data:
4111                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4112     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4113                           location_url='http://127.0.0.1:12345')
4114
4115 def test_ap_wps_er_http_client(dev, apdev):
4116     """WPS ER and HTTP client special cases"""
4117     with alloc_fail(dev[0], 1, "http_link_update"):
4118         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4119
4120     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4121         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4122
4123     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4124         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4125
4126     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4127         def handle_upnp_info(self):
4128             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4129     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4130                           no_event_url=True)
4131
4132 def test_ap_wps_init_oom(dev, apdev):
4133     """wps_init OOM cases"""
4134     ssid = "test-wps"
4135     appin = "12345670"
4136     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4137                "ap_pin": appin }
4138     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4139     pin = dev[0].wps_read_pin()
4140
4141     with alloc_fail(hapd, 1, "wps_init"):
4142         hapd.request("WPS_PIN any " + pin)
4143         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4144         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4145         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4146         if ev is None:
4147             raise Exception("No EAP failure reported")
4148         dev[0].request("WPS_CANCEL")
4149
4150     with alloc_fail(dev[0], 2, "wps_init"):
4151         hapd.request("WPS_PIN any " + pin)
4152         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4153         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4154         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4155         if ev is None:
4156             raise Exception("No EAP failure reported")
4157         dev[0].request("WPS_CANCEL")
4158
4159     with alloc_fail(dev[0], 2, "wps_init"):
4160         hapd.request("WPS_PBC")
4161         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4162         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4163         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4164         if ev is None:
4165             raise Exception("No EAP failure reported")
4166         dev[0].request("WPS_CANCEL")
4167
4168     dev[0].dump_monitor()
4169     new_ssid = "wps-new-ssid"
4170     new_passphrase = "1234567890"
4171     with alloc_fail(dev[0], 3, "wps_init"):
4172         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4173                        new_passphrase, no_wait=True)
4174         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4175         if ev is None:
4176             raise Exception("No EAP failure reported")
4177
4178     dev[0].flush_scan_cache()
4179
4180 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4181     """WPS and invalid IE in Association Request frame"""
4182     ssid = "test-wps"
4183     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4184     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4185     pin = "12345670"
4186     hapd.request("WPS_PIN any " + pin)
4187     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4188     try:
4189         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4190         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4191         for i in range(5):
4192             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4193             if ev and "vendor=14122" in ev:
4194                 break
4195         if ev is None or "vendor=14122" not in ev:
4196             raise Exception("EAP-WSC not started")
4197         dev[0].request("WPS_CANCEL")
4198     finally:
4199         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4200
4201 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4202     """WPS PBC/PIN mismatch"""
4203     ssid = "test-wps"
4204     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4205     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4206     hapd.request("SET wps_version_number 0x10")
4207     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4208     hapd.request("WPS_PBC")
4209     pin = dev[0].wps_read_pin()
4210     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4211     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4212     if ev is None:
4213         raise Exception("Scan did not complete")
4214     dev[0].request("WPS_CANCEL")
4215
4216     hapd.request("WPS_CANCEL")
4217     dev[0].flush_scan_cache()
4218
4219 def test_ap_wps_ie_invalid(dev, apdev):
4220     """WPS PIN attempt with AP that has invalid WSC IE"""
4221     ssid = "test-wps"
4222     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4223                "vendor_elements": "dd050050f20410" }
4224     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4225     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4226     hostapd.add_ap(apdev[1]['ifname'], params)
4227     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4228     pin = dev[0].wps_read_pin()
4229     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4230     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4231     if ev is None:
4232         raise Exception("Scan did not complete")
4233     dev[0].request("WPS_CANCEL")
4234
4235 def test_ap_wps_scan_prio_order(dev, apdev):
4236     """WPS scan priority ordering"""
4237     ssid = "test-wps"
4238     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4239     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4240     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4241     hostapd.add_ap(apdev[1]['ifname'], params)
4242     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4243     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4244     pin = dev[0].wps_read_pin()
4245     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4246     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4247     if ev is None:
4248         raise Exception("Scan did not complete")
4249     dev[0].request("WPS_CANCEL")
4250
4251 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4252     """WPS ProbeReq IE OOM"""
4253     ssid = "test-wps"
4254     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4255     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4256     pin = dev[0].wps_read_pin()
4257     hapd.request("WPS_PIN any " + pin)
4258     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4259     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4260         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4261         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4262         if ev is None:
4263             raise Exception("Association not seen")
4264     dev[0].request("WPS_CANCEL")
4265
4266     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4267         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4268         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4269         if ev is None:
4270             raise Exception("Association not seen")
4271     dev[0].request("WPS_CANCEL")
4272
4273 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4274     """WPS AssocReq IE OOM"""
4275     ssid = "test-wps"
4276     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4277     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4278     pin = dev[0].wps_read_pin()
4279     hapd.request("WPS_PIN any " + pin)
4280     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4281     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4282         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4283         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4284         if ev is None:
4285             raise Exception("Association not seen")
4286     dev[0].request("WPS_CANCEL")
4287
4288 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4289     """WPS AssocResp IE OOM"""
4290     ssid = "test-wps"
4291     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4292     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4293     pin = dev[0].wps_read_pin()
4294     hapd.request("WPS_PIN any " + pin)
4295     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4296     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4297         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4298         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4299         if ev is None:
4300             raise Exception("Association not seen")
4301     dev[0].request("WPS_CANCEL")
4302
4303 def test_ap_wps_bss_info_errors(dev, apdev):
4304     """WPS BSS info errors"""
4305     params = { "ssid": "1",
4306                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4307     hostapd.add_ap(apdev[0]['ifname'], params)
4308     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4309     hostapd.add_ap(apdev[1]['ifname'], params)
4310     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4311     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4312     bss = dev[0].get_bss(apdev[0]['bssid'])
4313     logger.info("BSS: " + str(bss))
4314     if "wps_state" in bss:
4315         raise Exception("Unexpected wps_state in BSS info")
4316     if 'wps_device_name' not in bss:
4317         raise Exception("No wps_device_name in BSS info")
4318     if bss['wps_device_name'] != '_':
4319         raise Exception("Unexpected wps_device_name value")
4320     bss = dev[0].get_bss(apdev[1]['bssid'])
4321     logger.info("BSS: " + str(bss))
4322
4323     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4324         bss = dev[0].get_bss(apdev[0]['bssid'])
4325         logger.info("BSS(OOM): " + str(bss))
4326
4327 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4328     hapd.request("WPS_PBC")
4329     dev.scan_for_bss(apdev['bssid'], freq="2412")
4330     dev.request("WPS_PBC " + apdev['bssid'])
4331     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4332     if ev is None:
4333         raise Exception("No EAP failure reported")
4334     dev.request("WPS_CANCEL")
4335     dev.wait_disconnected()
4336     for i in range(5):
4337         try:
4338             dev.flush_scan_cache()
4339             break
4340         except Exception, e:
4341             if str(e).startswith("Failed to trigger scan"):
4342                 # Try again
4343                 time.sleep(1)
4344             else:
4345                 raise
4346
4347 def wps_run_pbc_fail(apdev, dev):
4348     hapd = wps_start_ap(apdev)
4349     wps_run_pbc_fail_ap(apdev, dev, hapd)
4350
4351 def test_ap_wps_pk_oom(dev, apdev):
4352     """WPS and public key OOM"""
4353     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4354         wps_run_pbc_fail(apdev[0], dev[0])
4355
4356 def test_ap_wps_pk_oom_ap(dev, apdev):
4357     """WPS and public key OOM on AP"""
4358     hapd = wps_start_ap(apdev[0])
4359     with alloc_fail(hapd, 1, "wps_build_public_key"):
4360         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4361
4362 def test_ap_wps_encr_oom_ap(dev, apdev):
4363     """WPS and encrypted settings decryption OOM on AP"""
4364     hapd = wps_start_ap(apdev[0])
4365     pin = dev[0].wps_read_pin()
4366     hapd.request("WPS_PIN any " + pin)
4367     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4368     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4369         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4370         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4371         if ev is None:
4372             raise Exception("No WPS-FAIL reported")
4373         dev[0].request("WPS_CANCEL")
4374     dev[0].wait_disconnected()
4375
4376 def test_ap_wps_encr_no_random_ap(dev, apdev):
4377     """WPS and no random data available for encryption on AP"""
4378     hapd = wps_start_ap(apdev[0])
4379     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4380         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4381
4382 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4383     """WPS and no random data available for e-hash on STA"""
4384     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4385         wps_run_pbc_fail(apdev[0], dev[0])
4386
4387 def test_ap_wps_m1_no_random(dev, apdev):
4388     """WPS and no random for M1 on STA"""
4389     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4390         wps_run_pbc_fail(apdev[0], dev[0])
4391
4392 def test_ap_wps_m1_oom(dev, apdev):
4393     """WPS and OOM for M1 on STA"""
4394     with alloc_fail(dev[0], 1, "wps_build_m1"):
4395         wps_run_pbc_fail(apdev[0], dev[0])
4396
4397 def test_ap_wps_m3_oom(dev, apdev):
4398     """WPS and OOM for M3 on STA"""
4399     with alloc_fail(dev[0], 1, "wps_build_m3"):
4400         wps_run_pbc_fail(apdev[0], dev[0])
4401
4402 def test_ap_wps_m5_oom(dev, apdev):
4403     """WPS and OOM for M5 on STA"""
4404     hapd = wps_start_ap(apdev[0])
4405     hapd.request("WPS_PBC")
4406     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4407     for i in range(1, 3):
4408         with alloc_fail(dev[0], i, "wps_build_m5"):
4409             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4410             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4411             if ev is None:
4412                 raise Exception("No EAP failure reported")
4413             dev[0].request("WPS_CANCEL")
4414             dev[0].wait_disconnected()
4415     dev[0].flush_scan_cache()
4416
4417 def test_ap_wps_m5_no_random(dev, apdev):
4418     """WPS and no random for M5 on STA"""
4419     with fail_test(dev[0], 1,
4420                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
4421         wps_run_pbc_fail(apdev[0], dev[0])
4422
4423 def test_ap_wps_m7_oom(dev, apdev):
4424     """WPS and OOM for M7 on STA"""
4425     hapd = wps_start_ap(apdev[0])
4426     hapd.request("WPS_PBC")
4427     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4428     for i in range(1, 3):
4429         with alloc_fail(dev[0], i, "wps_build_m7"):
4430             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4431             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4432             if ev is None:
4433                 raise Exception("No EAP failure reported")
4434             dev[0].request("WPS_CANCEL")
4435             dev[0].wait_disconnected()
4436     dev[0].flush_scan_cache()
4437
4438 def test_ap_wps_m7_no_random(dev, apdev):
4439     """WPS and no random for M7 on STA"""
4440     with fail_test(dev[0], 1,
4441                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
4442         wps_run_pbc_fail(apdev[0], dev[0])
4443
4444 def test_ap_wps_wsc_done_oom(dev, apdev):
4445     """WPS and OOM for WSC_Done on STA"""
4446     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
4447         wps_run_pbc_fail(apdev[0], dev[0])
4448
4449 def test_ap_wps_random_psk_fail(dev, apdev):
4450     """WPS and no random for PSK on AP"""
4451     ssid = "test-wps"
4452     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
4453     appin = "12345670"
4454     try:
4455         os.remove(pskfile)
4456     except:
4457         pass
4458
4459     try:
4460         with open(pskfile, "w") as f:
4461             f.write("# WPA PSKs\n")
4462
4463         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4464                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
4465                    "rsn_pairwise": "CCMP", "ap_pin": appin,
4466                    "wpa_psk_file": pskfile }
4467         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4468
4469         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4470         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
4471             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
4472             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4473             if ev is None:
4474                 raise Exception("No EAP failure reported")
4475             dev[0].request("WPS_CANCEL")
4476         dev[0].wait_disconnected()
4477
4478         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
4479             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4480
4481         with alloc_fail(hapd, 1, "wps_build_cred"):
4482             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4483
4484         with alloc_fail(hapd, 2, "wps_build_cred"):
4485             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4486     finally:
4487         os.remove(pskfile)
4488
4489 def wps_ext_eap_identity_req(dev, hapd, bssid):
4490     logger.debug("EAP-Identity/Request")
4491     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4492     if ev is None:
4493         raise Exception("Timeout on EAPOL-TX from hostapd")
4494     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
4495     if "OK" not in res:
4496         raise Exception("EAPOL_RX to wpa_supplicant failed")
4497
4498 def wps_ext_eap_identity_resp(hapd, dev, addr):
4499     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
4500     if ev is None:
4501         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
4502     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
4503     if "OK" not in res:
4504         raise Exception("EAPOL_RX to hostapd failed")
4505
4506 def wps_ext_eap_wsc(dst, src, src_addr, msg):
4507     logger.debug(msg)
4508     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4509     if ev is None:
4510         raise Exception("Timeout on EAPOL-TX")
4511     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
4512     if "OK" not in res:
4513         raise Exception("EAPOL_RX failed")
4514
4515 def wps_start_ext(apdev, dev):
4516     addr = dev.own_addr()
4517     bssid = apdev['bssid']
4518     ssid = "test-wps-conf"
4519     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4520                "wpa_passphrase": "12345678", "wpa": "2",
4521                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
4522     hapd = hostapd.add_ap(apdev['ifname'], params)
4523
4524     pin = dev.wps_read_pin()
4525     hapd.request("WPS_PIN any " + pin)
4526     dev.scan_for_bss(bssid, freq="2412")
4527     hapd.request("SET ext_eapol_frame_io 1")
4528     dev.request("SET ext_eapol_frame_io 1")
4529
4530     dev.request("WPS_PIN " + bssid + " " + pin)
4531     return addr,bssid,hapd
4532
4533 def wps_auth_corrupt(dst, src, addr):
4534     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4535     if ev is None:
4536         raise Exception("Timeout on EAPOL-TX")
4537     src.request("SET ext_eapol_frame_io 0")
4538     dst.request("SET ext_eapol_frame_io 0")
4539     msg = ev.split(' ')[2]
4540     if msg[-24:-16] != '10050008':
4541         raise Exception("Could not find Authenticator attribute")
4542     # Corrupt Authenticator value
4543     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
4544     res = dst.request("EAPOL_RX " + addr + " " + msg)
4545     if "OK" not in res:
4546         raise Exception("EAPOL_RX failed")
4547
4548 def wps_fail_finish(hapd, dev, fail_str):
4549     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
4550     if ev is None:
4551         raise Exception("WPS-FAIL not indicated")
4552     if fail_str not in ev:
4553         raise Exception("Unexpected WPS-FAIL value: " + ev)
4554     dev.request("WPS_CANCEL")
4555     dev.wait_disconnected()
4556
4557 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
4558     wps_auth_corrupt(dev, hapd, bssid)
4559     wps_fail_finish(hapd, dev, fail_str)
4560
4561 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
4562     wps_auth_corrupt(hapd, dev, addr)
4563     wps_fail_finish(hapd, dev, fail_str)
4564
4565 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
4566     """WPS and Authenticator attribute mismatch in M2"""
4567     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4568     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4569     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4570     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4571     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4572     logger.debug("M2")
4573     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
4574
4575 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
4576     """WPS and Authenticator attribute mismatch in M3"""
4577     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4578     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4579     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4580     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4581     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4582     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4583     logger.debug("M3")
4584     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
4585
4586 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
4587     """WPS and Authenticator attribute mismatch in M4"""
4588     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4589     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4590     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4591     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4592     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4593     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4594     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4595     logger.debug("M4")
4596     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
4597
4598 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
4599     """WPS and Authenticator attribute mismatch in M5"""
4600     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4601     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4602     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4603     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4604     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4605     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4606     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4607     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4608     logger.debug("M5")
4609     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
4610
4611 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
4612     """WPS and Authenticator attribute mismatch in M6"""
4613     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4614     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4615     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4616     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4617     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4618     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4619     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4620     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4621     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
4622     logger.debug("M6")
4623     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
4624
4625 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
4626     """WPS and Authenticator attribute mismatch in M7"""
4627     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4628     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4629     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4630     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4631     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4632     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4633     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4634     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4635     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
4636     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
4637     logger.debug("M7")
4638     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
4639
4640 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
4641     """WPS and Authenticator attribute mismatch in M8"""
4642     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4643     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4644     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4645     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4646     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4647     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
4648     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
4649     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
4650     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
4651     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
4652     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
4653     logger.debug("M8")
4654     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
4655
4656 def test_ap_wps_authenticator_missing_m2(dev, apdev):
4657     """WPS and Authenticator attribute missing from M2"""
4658     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
4659     wps_ext_eap_identity_req(dev[0], hapd, bssid)
4660     wps_ext_eap_identity_resp(hapd, dev[0], addr)
4661     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
4662     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
4663     logger.debug("M2")
4664     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4665     if ev is None:
4666         raise Exception("Timeout on EAPOL-TX")
4667     hapd.request("SET ext_eapol_frame_io 0")
4668     dev[0].request("SET ext_eapol_frame_io 0")
4669     msg = ev.split(' ')[2]
4670     if msg[-24:-16] != '10050008':
4671         raise Exception("Could not find Authenticator attribute")
4672     # Remove Authenticator value
4673     msg = msg[:-24]
4674     mlen = "%04x" % (int(msg[4:8], 16) - 12)
4675     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
4676     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
4677     if "OK" not in res:
4678         raise Exception("EAPOL_RX failed")
4679     wps_fail_finish(hapd, dev[0], "msg=5")
4680
4681 def test_ap_wps_config_methods(dev, apdev):
4682     """WPS configuration method parsing"""
4683     ssid = "test-wps-conf"
4684     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4685                "wpa_passphrase": "12345678", "wpa": "2",
4686                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
4687                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
4688     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4689     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4690                "wpa_passphrase": "12345678", "wpa": "2",
4691                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
4692                "config_methods": "display push_button" }
4693     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)