fe28b45288173cccd848c0e8356eb75f6f00aed0
[mech_eap.git] / tests / hwsim / test_ap_wps.py
1 # WPS tests
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import base64
8 import binascii
9 from Crypto.Cipher import AES
10 import hashlib
11 import hmac
12 import os
13 import time
14 import stat
15 import subprocess
16 import logging
17 logger = logging.getLogger()
18 import re
19 import socket
20 import struct
21 import httplib
22 import urlparse
23 import urllib
24 import xml.etree.ElementTree as ET
25 import StringIO
26 import SocketServer
27
28 import hwsim_utils
29 import hostapd
30 from wpasupplicant import WpaSupplicant
31 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
32 from utils import wait_fail_trigger
33 from test_ap_eap import int_eap_server_params
34
35 def wps_start_ap(apdev, ssid="test-wps-conf"):
36     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
37                "wpa_passphrase": "12345678", "wpa": "2",
38                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
39     return hostapd.add_ap(apdev['ifname'], params)
40
41 def test_ap_wps_init(dev, apdev):
42     """Initial AP configuration with first WPS Enrollee"""
43     ssid = "test-wps"
44     hostapd.add_ap(apdev[0],
45                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
46     hapd = hostapd.Hostapd(apdev[0]['ifname'])
47     logger.info("WPS provisioning step")
48     hapd.request("WPS_PBC")
49     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
50         raise Exception("PBC status not shown correctly")
51
52     id = dev[0].add_network()
53     dev[0].set_network_quoted(id, "ssid", "home")
54     dev[0].set_network_quoted(id, "psk", "12345678")
55     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
56
57     id = dev[0].add_network()
58     dev[0].set_network_quoted(id, "ssid", "home2")
59     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
60     dev[0].set_network(id, "key_mgmt", "NONE")
61     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
62
63     dev[0].request("WPS_PBC")
64     dev[0].wait_connected(timeout=30)
65     status = dev[0].get_status()
66     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
67         raise Exception("Not fully connected")
68     if status['ssid'] != ssid:
69         raise Exception("Unexpected SSID")
70     if status['pairwise_cipher'] != 'CCMP':
71         raise Exception("Unexpected encryption configuration")
72     if status['key_mgmt'] != 'WPA2-PSK':
73         raise Exception("Unexpected key_mgmt")
74
75     status = hapd.request("WPS_GET_STATUS")
76     if "PBC Status: Disabled" not in status:
77         raise Exception("PBC status not shown correctly")
78     if "Last WPS result: Success" not in status:
79         raise Exception("Last WPS result not shown correctly")
80     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
81         raise Exception("Peer address not shown correctly")
82     conf = hapd.request("GET_CONFIG")
83     if "wps_state=configured" not in conf:
84         raise Exception("AP not in WPS configured state")
85     if "wpa=3" not in conf:
86         raise Exception("AP not in WPA+WPA2 configuration")
87     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
88         raise Exception("Unexpected rsn_pairwise_cipher")
89     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
90         raise Exception("Unexpected wpa_pairwise_cipher")
91     if "group_cipher=TKIP" not in conf:
92         raise Exception("Unexpected group_cipher")
93
94     if len(dev[0].list_networks()) != 3:
95         raise Exception("Unexpected number of network blocks")
96
97 def test_ap_wps_init_2ap_pbc(dev, apdev):
98     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
99     ssid = "test-wps"
100     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
101     hostapd.add_ap(apdev[0], params)
102     hostapd.add_ap(apdev[1], params)
103     hapd = hostapd.Hostapd(apdev[0]['ifname'])
104     logger.info("WPS provisioning step")
105     hapd.request("WPS_PBC")
106     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
107     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
108     bss = dev[0].get_bss(apdev[0]['bssid'])
109     if "[WPS-PBC]" not in bss['flags']:
110         raise Exception("WPS-PBC flag missing from AP1")
111     bss = dev[0].get_bss(apdev[1]['bssid'])
112     if "[WPS-PBC]" not in bss['flags']:
113         raise Exception("WPS-PBC flag missing from AP2")
114     dev[0].dump_monitor()
115     dev[0].request("SET wps_cred_processing 2")
116     dev[0].request("WPS_PBC")
117     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
118     dev[0].request("SET wps_cred_processing 0")
119     if ev is None:
120         raise Exception("WPS cred event not seen")
121     if "100e" not in ev:
122         raise Exception("WPS attributes not included in the cred event")
123     dev[0].wait_connected(timeout=30)
124
125     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
126     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
127     bss = dev[1].get_bss(apdev[0]['bssid'])
128     if "[WPS-PBC]" in bss['flags']:
129         raise Exception("WPS-PBC flag not cleared from AP1")
130     bss = dev[1].get_bss(apdev[1]['bssid'])
131     if "[WPS-PBC]" in bss['flags']:
132         raise Exception("WPS-PBC flag not cleared from AP2")
133
134 def test_ap_wps_init_2ap_pin(dev, apdev):
135     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
136     ssid = "test-wps"
137     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
138     hostapd.add_ap(apdev[0], params)
139     hostapd.add_ap(apdev[1], params)
140     hapd = hostapd.Hostapd(apdev[0]['ifname'])
141     logger.info("WPS provisioning step")
142     pin = dev[0].wps_read_pin()
143     hapd.request("WPS_PIN any " + pin)
144     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
145     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
146     bss = dev[0].get_bss(apdev[0]['bssid'])
147     if "[WPS-AUTH]" not in bss['flags']:
148         raise Exception("WPS-AUTH flag missing from AP1")
149     bss = dev[0].get_bss(apdev[1]['bssid'])
150     if "[WPS-AUTH]" not in bss['flags']:
151         raise Exception("WPS-AUTH flag missing from AP2")
152     dev[0].dump_monitor()
153     dev[0].request("WPS_PIN any " + pin)
154     dev[0].wait_connected(timeout=30)
155
156     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
157     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
158     bss = dev[1].get_bss(apdev[0]['bssid'])
159     if "[WPS-AUTH]" in bss['flags']:
160         raise Exception("WPS-AUTH flag not cleared from AP1")
161     bss = dev[1].get_bss(apdev[1]['bssid'])
162     if "[WPS-AUTH]" in bss['flags']:
163         raise Exception("WPS-AUTH flag not cleared from AP2")
164
165 def test_ap_wps_init_through_wps_config(dev, apdev):
166     """Initial AP configuration using wps_config command"""
167     ssid = "test-wps-init-config"
168     hostapd.add_ap(apdev[0],
169                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
170     hapd = hostapd.Hostapd(apdev[0]['ifname'])
171     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
172         raise Exception("WPS_CONFIG command failed")
173     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
174     if ev is None:
175         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
176     # It takes some time for the AP to update Beacon and Probe Response frames,
177     # so wait here before requesting the scan to be started to avoid adding
178     # extra five second wait to the test due to fetching obsolete scan results.
179     hapd.ping()
180     time.sleep(0.2)
181     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
182                    pairwise="CCMP", group="CCMP")
183
184 def test_ap_wps_init_through_wps_config_2(dev, apdev):
185     """AP configuration using wps_config and wps_cred_processing=2"""
186     ssid = "test-wps-init-config"
187     hostapd.add_ap(apdev[0],
188                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
189                      "wps_cred_processing": "2" })
190     hapd = hostapd.Hostapd(apdev[0]['ifname'])
191     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
192         raise Exception("WPS_CONFIG command failed")
193     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
194     if ev is None:
195         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
196     if "100e" not in ev:
197         raise Exception("WPS-NEW-AP-SETTINGS did not include Credential")
198
199 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
200     """AP configuration using wps_config command with invalid passphrase"""
201     ssid = "test-wps-init-config"
202     hostapd.add_ap(apdev[0],
203                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
204     hapd = hostapd.Hostapd(apdev[0]['ifname'])
205     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
206         raise Exception("Invalid WPS_CONFIG command accepted")
207
208 def test_ap_wps_conf(dev, apdev):
209     """WPS PBC provisioning with configured AP"""
210     ssid = "test-wps-conf"
211     hostapd.add_ap(apdev[0],
212                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
213                      "wpa_passphrase": "12345678", "wpa": "2",
214                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
215     hapd = hostapd.Hostapd(apdev[0]['ifname'])
216     logger.info("WPS provisioning step")
217     hapd.request("WPS_PBC")
218     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
219     dev[0].dump_monitor()
220     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
221     dev[0].wait_connected(timeout=30)
222     status = dev[0].get_status()
223     if status['wpa_state'] != 'COMPLETED':
224         raise Exception("Not fully connected")
225     if status['bssid'] != apdev[0]['bssid']:
226         raise Exception("Unexpected BSSID")
227     if status['ssid'] != ssid:
228         raise Exception("Unexpected SSID")
229     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
230         raise Exception("Unexpected encryption configuration")
231     if status['key_mgmt'] != 'WPA2-PSK':
232         raise Exception("Unexpected key_mgmt")
233
234     sta = hapd.get_sta(dev[0].p2p_interface_addr())
235     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
236         raise Exception("Device name not available in STA command")
237
238 def test_ap_wps_conf_5ghz(dev, apdev):
239     """WPS PBC provisioning with configured AP on 5 GHz band"""
240     try:
241         hapd = None
242         ssid = "test-wps-conf"
243         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
244                    "wpa_passphrase": "12345678", "wpa": "2",
245                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
246                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
247         hapd = hostapd.add_ap(apdev[0], params)
248         logger.info("WPS provisioning step")
249         hapd.request("WPS_PBC")
250         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
251         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
252         dev[0].wait_connected(timeout=30)
253
254         sta = hapd.get_sta(dev[0].p2p_interface_addr())
255         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
256             raise Exception("Device name not available in STA command")
257     finally:
258         dev[0].request("DISCONNECT")
259         if hapd:
260             hapd.request("DISABLE")
261         subprocess.call(['iw', 'reg', 'set', '00'])
262         dev[0].flush_scan_cache()
263
264 def test_ap_wps_conf_chan14(dev, apdev):
265     """WPS PBC provisioning with configured AP on channel 14"""
266     try:
267         hapd = None
268         ssid = "test-wps-conf"
269         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
270                    "wpa_passphrase": "12345678", "wpa": "2",
271                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
272                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
273         hapd = hostapd.add_ap(apdev[0], params)
274         logger.info("WPS provisioning step")
275         hapd.request("WPS_PBC")
276         dev[0].request("WPS_PBC")
277         dev[0].wait_connected(timeout=30)
278
279         sta = hapd.get_sta(dev[0].p2p_interface_addr())
280         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
281             raise Exception("Device name not available in STA command")
282     finally:
283         dev[0].request("DISCONNECT")
284         if hapd:
285             hapd.request("DISABLE")
286         subprocess.call(['iw', 'reg', 'set', '00'])
287         dev[0].flush_scan_cache()
288
289 def test_ap_wps_twice(dev, apdev):
290     """WPS provisioning with twice to change passphrase"""
291     ssid = "test-wps-twice"
292     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
293                "wpa_passphrase": "12345678", "wpa": "2",
294                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
295     hostapd.add_ap(apdev[0], params)
296     hapd = hostapd.Hostapd(apdev[0]['ifname'])
297     logger.info("WPS provisioning step")
298     hapd.request("WPS_PBC")
299     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
300     dev[0].dump_monitor()
301     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
302     dev[0].wait_connected(timeout=30)
303     dev[0].request("DISCONNECT")
304
305     logger.info("Restart AP with different passphrase and re-run WPS")
306     hapd_global = hostapd.HostapdGlobal()
307     hapd_global.remove(apdev[0]['ifname'])
308     params['wpa_passphrase'] = 'another passphrase'
309     hostapd.add_ap(apdev[0], params)
310     hapd = hostapd.Hostapd(apdev[0]['ifname'])
311     logger.info("WPS provisioning step")
312     hapd.request("WPS_PBC")
313     dev[0].dump_monitor()
314     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
315     dev[0].wait_connected(timeout=30)
316     networks = dev[0].list_networks()
317     if len(networks) > 1:
318         raise Exception("Unexpected duplicated network block present")
319
320 def test_ap_wps_incorrect_pin(dev, apdev):
321     """WPS PIN provisioning with incorrect PIN"""
322     ssid = "test-wps-incorrect-pin"
323     hostapd.add_ap(apdev[0],
324                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
325                      "wpa_passphrase": "12345678", "wpa": "2",
326                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
327     hapd = hostapd.Hostapd(apdev[0]['ifname'])
328
329     logger.info("WPS provisioning attempt 1")
330     hapd.request("WPS_PIN any 12345670")
331     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
332     dev[0].dump_monitor()
333     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
334     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
335     if ev is None:
336         raise Exception("WPS operation timed out")
337     if "config_error=18" not in ev:
338         raise Exception("Incorrect config_error reported")
339     if "msg=8" not in ev:
340         raise Exception("PIN error detected on incorrect message")
341     dev[0].wait_disconnected(timeout=10)
342     dev[0].request("WPS_CANCEL")
343     # if a scan was in progress, wait for it to complete before trying WPS again
344     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
345
346     status = hapd.request("WPS_GET_STATUS")
347     if "Last WPS result: Failed" not in status:
348         raise Exception("WPS failure result not shown correctly")
349
350     logger.info("WPS provisioning attempt 2")
351     hapd.request("WPS_PIN any 12345670")
352     dev[0].dump_monitor()
353     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
354     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
355     if ev is None:
356         raise Exception("WPS operation timed out")
357     if "config_error=18" not in ev:
358         raise Exception("Incorrect config_error reported")
359     if "msg=10" not in ev:
360         raise Exception("PIN error detected on incorrect message")
361     dev[0].wait_disconnected(timeout=10)
362
363 def test_ap_wps_conf_pin(dev, apdev):
364     """WPS PIN provisioning with configured AP"""
365     ssid = "test-wps-conf-pin"
366     hostapd.add_ap(apdev[0],
367                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
368                      "wpa_passphrase": "12345678", "wpa": "2",
369                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
370     hapd = hostapd.Hostapd(apdev[0]['ifname'])
371     logger.info("WPS provisioning step")
372     pin = dev[0].wps_read_pin()
373     hapd.request("WPS_PIN any " + pin)
374     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
375     dev[0].dump_monitor()
376     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
377     dev[0].wait_connected(timeout=30)
378     status = dev[0].get_status()
379     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
380         raise Exception("Not fully connected")
381     if status['ssid'] != ssid:
382         raise Exception("Unexpected SSID")
383     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
384         raise Exception("Unexpected encryption configuration")
385     if status['key_mgmt'] != 'WPA2-PSK':
386         raise Exception("Unexpected key_mgmt")
387
388     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
389     bss = dev[1].get_bss(apdev[0]['bssid'])
390     if "[WPS-AUTH]" in bss['flags']:
391         raise Exception("WPS-AUTH flag not cleared")
392     logger.info("Try to connect from another station using the same PIN")
393     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
394     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
395     if ev is None:
396         raise Exception("Operation timed out")
397     if "WPS-M2D" not in ev:
398         raise Exception("Unexpected WPS operation started")
399     hapd.request("WPS_PIN any " + pin)
400     dev[1].wait_connected(timeout=30)
401
402 def test_ap_wps_conf_pin_mixed_mode(dev, apdev):
403     """WPS PIN provisioning with configured AP (WPA+WPA2)"""
404     ssid = "test-wps-conf-pin-mixed"
405     hostapd.add_ap(apdev[0],
406                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
407                      "wpa_passphrase": "12345678", "wpa": "3",
408                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
409                      "wpa_pairwise": "TKIP" })
410     hapd = hostapd.Hostapd(apdev[0]['ifname'])
411
412     logger.info("WPS provisioning step")
413     pin = dev[0].wps_read_pin()
414     hapd.request("WPS_PIN any " + pin)
415     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
416     dev[0].dump_monitor()
417     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
418     dev[0].wait_connected(timeout=30)
419     status = dev[0].get_status()
420     dev[0].request("REMOVE_NETWORK all")
421     dev[0].wait_disconnected()
422     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP' or status['key_mgmt'] != 'WPA2-PSK':
423         raise Exception("Unexpected encryption/key_mgmt configuration: pairwise=%s group=%s key_mgmt=%s" % (status['pairwise_cipher'], status['group_cipher'], status['key_mgmt']))
424
425     logger.info("WPS provisioning step (auth_types=0x1b)")
426     if "OK" not in dev[0].request("SET wps_force_auth_types 0x1b"):
427         raise Exception("Failed to set wps_force_auth_types 0x1b")
428     pin = dev[0].wps_read_pin()
429     hapd.request("WPS_PIN any " + pin)
430     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
431     dev[0].dump_monitor()
432     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
433     dev[0].wait_connected(timeout=30)
434     status = dev[0].get_status()
435     dev[0].request("REMOVE_NETWORK all")
436     dev[0].wait_disconnected()
437     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP' or status['key_mgmt'] != 'WPA2-PSK':
438         raise Exception("Unexpected encryption/key_mgmt configuration: pairwise=%s group=%s key_mgmt=%s" % (status['pairwise_cipher'], status['group_cipher'], status['key_mgmt']))
439
440     logger.info("WPS provisioning step (auth_types=0 encr_types=0)")
441     if "OK" not in dev[0].request("SET wps_force_auth_types 0"):
442         raise Exception("Failed to set wps_force_auth_types 0")
443     if "OK" not in dev[0].request("SET wps_force_encr_types 0"):
444         raise Exception("Failed to set wps_force_encr_types 0")
445     pin = dev[0].wps_read_pin()
446     hapd.request("WPS_PIN any " + pin)
447     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
448     dev[0].dump_monitor()
449     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
450     dev[0].wait_connected(timeout=30)
451     status = dev[0].get_status()
452     dev[0].request("REMOVE_NETWORK all")
453     dev[0].wait_disconnected()
454     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP' or status['key_mgmt'] != 'WPA2-PSK':
455         raise Exception("Unexpected encryption/key_mgmt configuration: pairwise=%s group=%s key_mgmt=%s" % (status['pairwise_cipher'], status['group_cipher'], status['key_mgmt']))
456
457     dev[0].request("SET wps_force_auth_types ")
458     dev[0].request("SET wps_force_encr_types ")
459
460 def test_ap_wps_conf_pin_v1(dev, apdev):
461     """WPS PIN provisioning with configured WPS v1.0 AP"""
462     ssid = "test-wps-conf-pin-v1"
463     hostapd.add_ap(apdev[0],
464                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
465                      "wpa_passphrase": "12345678", "wpa": "2",
466                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
467     hapd = hostapd.Hostapd(apdev[0]['ifname'])
468     logger.info("WPS provisioning step")
469     pin = dev[0].wps_read_pin()
470     hapd.request("SET wps_version_number 0x10")
471     hapd.request("WPS_PIN any " + pin)
472     found = False
473     for i in range(0, 10):
474         dev[0].scan(freq="2412")
475         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
476             found = True
477             break
478     if not found:
479         hapd.request("SET wps_version_number 0x20")
480         raise Exception("WPS-PIN flag not seen in scan results")
481     dev[0].dump_monitor()
482     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
483     dev[0].wait_connected(timeout=30)
484     hapd.request("SET wps_version_number 0x20")
485
486 def test_ap_wps_conf_pin_2sta(dev, apdev):
487     """Two stations trying to use WPS PIN at the same time"""
488     ssid = "test-wps-conf-pin2"
489     hostapd.add_ap(apdev[0],
490                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
491                      "wpa_passphrase": "12345678", "wpa": "2",
492                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
493     hapd = hostapd.Hostapd(apdev[0]['ifname'])
494     logger.info("WPS provisioning step")
495     pin = "12345670"
496     pin2 = "55554444"
497     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
498     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
499     dev[0].dump_monitor()
500     dev[1].dump_monitor()
501     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
502     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
503     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
504     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
505     dev[0].wait_connected(timeout=30)
506     dev[1].wait_connected(timeout=30)
507
508 def test_ap_wps_conf_pin_timeout(dev, apdev):
509     """WPS PIN provisioning with configured AP timing out PIN"""
510     ssid = "test-wps-conf-pin"
511     hostapd.add_ap(apdev[0],
512                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
513                      "wpa_passphrase": "12345678", "wpa": "2",
514                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
515     hapd = hostapd.Hostapd(apdev[0]['ifname'])
516     addr = dev[0].p2p_interface_addr()
517     pin = dev[0].wps_read_pin()
518     if "FAIL" not in hapd.request("WPS_PIN "):
519         raise Exception("Unexpected success on invalid WPS_PIN")
520     hapd.request("WPS_PIN any " + pin + " 1")
521     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
522     time.sleep(1.1)
523     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
524     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
525     if ev is None:
526         raise Exception("WPS-PIN-NEEDED event timed out")
527     ev = dev[0].wait_event(["WPS-M2D"])
528     if ev is None:
529         raise Exception("M2D not reported")
530     dev[0].request("WPS_CANCEL")
531
532     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
533     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
534     dev[0].wait_connected(timeout=30)
535
536 def test_ap_wps_reg_connect(dev, apdev):
537     """WPS registrar using AP PIN to connect"""
538     ssid = "test-wps-reg-ap-pin"
539     appin = "12345670"
540     hostapd.add_ap(apdev[0],
541                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
542                      "wpa_passphrase": "12345678", "wpa": "2",
543                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
544                      "ap_pin": appin})
545     logger.info("WPS provisioning step")
546     dev[0].dump_monitor()
547     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
548     dev[0].wps_reg(apdev[0]['bssid'], appin)
549     status = dev[0].get_status()
550     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
551         raise Exception("Not fully connected")
552     if status['ssid'] != ssid:
553         raise Exception("Unexpected SSID")
554     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
555         raise Exception("Unexpected encryption configuration")
556     if status['key_mgmt'] != 'WPA2-PSK':
557         raise Exception("Unexpected key_mgmt")
558
559 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
560     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
561     ssid = "test-wps-reg-ap-pin"
562     appin = "12345670"
563     hostapd.add_ap(apdev[0],
564                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
565                      "wpa_passphrase": "12345678", "wpa": "3",
566                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
567                      "wpa_pairwise": "TKIP", "ap_pin": appin})
568     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
569     dev[0].wps_reg(apdev[0]['bssid'], appin)
570     status = dev[0].get_status()
571     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
572         raise Exception("Not fully connected")
573     if status['ssid'] != ssid:
574         raise Exception("Unexpected SSID")
575     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
576         raise Exception("Unexpected encryption configuration")
577     if status['key_mgmt'] != 'WPA2-PSK':
578         raise Exception("Unexpected key_mgmt")
579
580 def test_ap_wps_reg_override_ap_settings(dev, apdev):
581     """WPS registrar and ap_settings override"""
582     ap_settings = "/tmp/ap_wps_reg_override_ap_settings"
583     try:
584         os.remove(ap_settings)
585     except:
586         pass
587     # Override AP Settings with values that point to another AP
588     data = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
589     data += build_wsc_attr(ATTR_SSID, "test")
590     data += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
591     data += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
592     data += build_wsc_attr(ATTR_NETWORK_KEY, '')
593     data += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[1]['bssid'].replace(':', '')))
594     with open(ap_settings, "w") as f:
595         f.write(data)
596     ssid = "test-wps-reg-ap-pin"
597     appin = "12345670"
598     hostapd.add_ap(apdev[0],
599                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
600                      "wpa_passphrase": "12345678", "wpa": "2",
601                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
602                      "ap_pin": appin, "ap_settings": ap_settings })
603     hapd2 = hostapd.add_ap(apdev[1], { "ssid": "test" })
604     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
605     dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
606     dev[0].wps_reg(apdev[0]['bssid'], appin)
607     ev = hapd2.wait_event(['AP-STA-CONNECTED'], timeout=10)
608     os.remove(ap_settings)
609     if ev is None:
610         raise Exception("No connection with the other AP")
611
612 def check_wps_reg_failure(dev, ap, appin):
613     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
614     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
615     if ev is None:
616         raise Exception("WPS operation timed out")
617     if "WPS-SUCCESS" in ev:
618         raise Exception("WPS operation succeeded unexpectedly")
619     if "config_error=15" not in ev:
620         raise Exception("WPS setup locked state was not reported correctly")
621
622 def test_ap_wps_random_ap_pin(dev, apdev):
623     """WPS registrar using random AP PIN"""
624     ssid = "test-wps-reg-random-ap-pin"
625     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
626     hostapd.add_ap(apdev[0],
627                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
628                      "wpa_passphrase": "12345678", "wpa": "2",
629                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
630                      "device_name": "Wireless AP", "manufacturer": "Company",
631                      "model_name": "WAP", "model_number": "123",
632                      "serial_number": "12345", "device_type": "6-0050F204-1",
633                      "os_version": "01020300",
634                      "config_methods": "label push_button",
635                      "uuid": ap_uuid, "upnp_iface": "lo" })
636     hapd = hostapd.Hostapd(apdev[0]['ifname'])
637     appin = hapd.request("WPS_AP_PIN random")
638     if "FAIL" in appin:
639         raise Exception("Could not generate random AP PIN")
640     if appin not in hapd.request("WPS_AP_PIN get"):
641         raise Exception("Could not fetch current AP PIN")
642     logger.info("WPS provisioning step")
643     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
644     dev[0].wps_reg(apdev[0]['bssid'], appin)
645
646     hapd.request("WPS_AP_PIN disable")
647     logger.info("WPS provisioning step with AP PIN disabled")
648     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
649     check_wps_reg_failure(dev[1], apdev[0], appin)
650
651     logger.info("WPS provisioning step with AP PIN reset")
652     appin = "12345670"
653     hapd.request("WPS_AP_PIN set " + appin)
654     dev[1].wps_reg(apdev[0]['bssid'], appin)
655     dev[0].request("REMOVE_NETWORK all")
656     dev[1].request("REMOVE_NETWORK all")
657     dev[0].wait_disconnected(timeout=10)
658     dev[1].wait_disconnected(timeout=10)
659
660     logger.info("WPS provisioning step after AP PIN timeout")
661     hapd.request("WPS_AP_PIN disable")
662     appin = hapd.request("WPS_AP_PIN random 1")
663     time.sleep(1.1)
664     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
665         raise Exception("AP PIN unexpectedly still enabled")
666     check_wps_reg_failure(dev[0], apdev[0], appin)
667
668     logger.info("WPS provisioning step after AP PIN timeout(2)")
669     hapd.request("WPS_AP_PIN disable")
670     appin = "12345670"
671     hapd.request("WPS_AP_PIN set " + appin + " 1")
672     time.sleep(1.1)
673     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
674         raise Exception("AP PIN unexpectedly still enabled")
675     check_wps_reg_failure(dev[1], apdev[0], appin)
676
677     with fail_test(hapd, 1, "os_get_random;wps_generate_pin"):
678         hapd.request("WPS_AP_PIN random 1")
679         hapd.request("WPS_AP_PIN disable")
680
681     with alloc_fail(hapd, 1, "upnp_wps_set_ap_pin"):
682         hapd.request("WPS_AP_PIN set 12345670")
683         hapd.request("WPS_AP_PIN disable")
684
685 def test_ap_wps_reg_config(dev, apdev):
686     """WPS registrar configuring an AP using AP PIN"""
687     ssid = "test-wps-init-ap-pin"
688     appin = "12345670"
689     hostapd.add_ap(apdev[0],
690                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
691                      "ap_pin": appin})
692     logger.info("WPS configuration step")
693     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
694     dev[0].dump_monitor()
695     new_ssid = "wps-new-ssid"
696     new_passphrase = "1234567890"
697     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
698                    new_passphrase)
699     status = dev[0].get_status()
700     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
701         raise Exception("Not fully connected")
702     if status['ssid'] != new_ssid:
703         raise Exception("Unexpected SSID")
704     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
705         raise Exception("Unexpected encryption configuration")
706     if status['key_mgmt'] != 'WPA2-PSK':
707         raise Exception("Unexpected key_mgmt")
708
709     logger.info("Re-configure back to open")
710     dev[0].request("REMOVE_NETWORK all")
711     dev[0].flush_scan_cache()
712     dev[0].dump_monitor()
713     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
714     status = dev[0].get_status()
715     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
716         raise Exception("Not fully connected")
717     if status['ssid'] != "wps-open":
718         raise Exception("Unexpected SSID")
719     if status['key_mgmt'] != 'NONE':
720         raise Exception("Unexpected key_mgmt")
721
722 def test_ap_wps_reg_config_ext_processing(dev, apdev):
723     """WPS registrar configuring an AP with external config processing"""
724     ssid = "test-wps-init-ap-pin"
725     appin = "12345670"
726     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
727                "wps_cred_processing": "1", "ap_pin": appin}
728     hapd = hostapd.add_ap(apdev[0], params)
729     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
730     new_ssid = "wps-new-ssid"
731     new_passphrase = "1234567890"
732     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
733                    new_passphrase, no_wait=True)
734     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
735     if ev is None:
736         raise Exception("WPS registrar operation timed out")
737     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
738     if ev is None:
739         raise Exception("WPS configuration timed out")
740     if "1026" not in ev:
741         raise Exception("AP Settings missing from event")
742     hapd.request("SET wps_cred_processing 0")
743     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
744         raise Exception("WPS_CONFIG command failed")
745     dev[0].wait_connected(timeout=15)
746
747 def test_ap_wps_reg_config_tkip(dev, apdev):
748     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
749     skip_with_fips(dev[0])
750     ssid = "test-wps-init-ap"
751     appin = "12345670"
752     hostapd.add_ap(apdev[0],
753                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
754                      "ap_pin": appin})
755     logger.info("WPS configuration step")
756     dev[0].request("SET wps_version_number 0x10")
757     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
758     dev[0].dump_monitor()
759     new_ssid = "wps-new-ssid-with-tkip"
760     new_passphrase = "1234567890"
761     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
762                    new_passphrase)
763     logger.info("Re-connect to verify WPA2 mixed mode")
764     dev[0].request("DISCONNECT")
765     id = 0
766     dev[0].set_network(id, "pairwise", "CCMP")
767     dev[0].set_network(id, "proto", "RSN")
768     dev[0].connect_network(id)
769     status = dev[0].get_status()
770     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
771         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
772     if status['ssid'] != new_ssid:
773         raise Exception("Unexpected SSID")
774     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
775         raise Exception("Unexpected encryption configuration")
776     if status['key_mgmt'] != 'WPA2-PSK':
777         raise Exception("Unexpected key_mgmt")
778
779 def test_ap_wps_setup_locked(dev, apdev):
780     """WPS registrar locking up AP setup on AP PIN failures"""
781     ssid = "test-wps-incorrect-ap-pin"
782     appin = "12345670"
783     hostapd.add_ap(apdev[0],
784                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
785                      "wpa_passphrase": "12345678", "wpa": "2",
786                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
787                      "ap_pin": appin})
788     new_ssid = "wps-new-ssid-test"
789     new_passphrase = "1234567890"
790
791     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
792     ap_setup_locked=False
793     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
794         dev[0].dump_monitor()
795         logger.info("Try incorrect AP PIN - attempt " + pin)
796         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
797                        "CCMP", new_passphrase, no_wait=True)
798         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
799         if ev is None:
800             raise Exception("Timeout on receiving WPS operation failure event")
801         if "CTRL-EVENT-CONNECTED" in ev:
802             raise Exception("Unexpected connection")
803         if "config_error=15" in ev:
804             logger.info("AP Setup Locked")
805             ap_setup_locked=True
806         elif "config_error=18" not in ev:
807             raise Exception("config_error=18 not reported")
808         dev[0].wait_disconnected(timeout=10)
809         time.sleep(0.1)
810     if not ap_setup_locked:
811         raise Exception("AP setup was not locked")
812     dev[0].request("WPS_CANCEL")
813     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True,
814                         only_new=True)
815     bss = dev[0].get_bss(apdev[0]['bssid'])
816     if 'wps_ap_setup_locked' not in bss or bss['wps_ap_setup_locked'] != '1':
817         logger.info("BSS: " + str(bss))
818         raise Exception("AP Setup Locked not indicated in scan results")
819
820     hapd = hostapd.Hostapd(apdev[0]['ifname'])
821     status = hapd.request("WPS_GET_STATUS")
822     if "Last WPS result: Failed" not in status:
823         raise Exception("WPS failure result not shown correctly")
824     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
825         raise Exception("Peer address not shown correctly")
826
827     time.sleep(0.5)
828     dev[0].dump_monitor()
829     logger.info("WPS provisioning step")
830     pin = dev[0].wps_read_pin()
831     hapd = hostapd.Hostapd(apdev[0]['ifname'])
832     hapd.request("WPS_PIN any " + pin)
833     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
834     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
835     if ev is None:
836         raise Exception("WPS success was not reported")
837     dev[0].wait_connected(timeout=30)
838
839     appin = hapd.request("WPS_AP_PIN random")
840     if "FAIL" in appin:
841         raise Exception("Could not generate random AP PIN")
842     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
843     if ev is None:
844         raise Exception("Failed to unlock AP PIN")
845
846 def test_ap_wps_setup_locked_timeout(dev, apdev):
847     """WPS re-enabling AP PIN after timeout"""
848     ssid = "test-wps-incorrect-ap-pin"
849     appin = "12345670"
850     hostapd.add_ap(apdev[0],
851                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
852                      "wpa_passphrase": "12345678", "wpa": "2",
853                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
854                      "ap_pin": appin})
855     new_ssid = "wps-new-ssid-test"
856     new_passphrase = "1234567890"
857
858     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
859     ap_setup_locked=False
860     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
861         dev[0].dump_monitor()
862         logger.info("Try incorrect AP PIN - attempt " + pin)
863         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
864                        "CCMP", new_passphrase, no_wait=True)
865         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
866         if ev is None:
867             raise Exception("Timeout on receiving WPS operation failure event")
868         if "CTRL-EVENT-CONNECTED" in ev:
869             raise Exception("Unexpected connection")
870         if "config_error=15" in ev:
871             logger.info("AP Setup Locked")
872             ap_setup_locked=True
873             break
874         elif "config_error=18" not in ev:
875             raise Exception("config_error=18 not reported")
876         dev[0].wait_disconnected(timeout=10)
877         time.sleep(0.1)
878     if not ap_setup_locked:
879         raise Exception("AP setup was not locked")
880     hapd = hostapd.Hostapd(apdev[0]['ifname'])
881     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
882     if ev is None:
883         raise Exception("AP PIN did not get unlocked on 60 second timeout")
884
885 def test_ap_wps_setup_locked_2(dev, apdev):
886     """WPS AP configured for special ap_setup_locked=2 mode"""
887     ssid = "test-wps-ap-pin"
888     appin = "12345670"
889     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
890                "wpa_passphrase": "12345678", "wpa": "2",
891                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
892                "ap_pin": appin, "ap_setup_locked": "2" }
893     hapd = hostapd.add_ap(apdev[0], params)
894     new_ssid = "wps-new-ssid-test"
895     new_passphrase = "1234567890"
896
897     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
898     dev[0].wps_reg(apdev[0]['bssid'], appin)
899     dev[0].request("REMOVE_NETWORK all")
900     dev[0].wait_disconnected()
901
902     hapd.dump_monitor()
903     dev[0].dump_monitor()
904     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK",
905                    "CCMP", new_passphrase, no_wait=True)
906
907     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
908     if ev is None:
909         raise Exception("hostapd did not report WPS failure")
910     if "msg=12 config_error=15" not in ev:
911         raise Exception("Unexpected failure reason (AP): " + ev)
912
913     ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
914     if ev is None:
915         raise Exception("Timeout on receiving WPS operation failure event")
916     if "CTRL-EVENT-CONNECTED" in ev:
917         raise Exception("Unexpected connection")
918     if "config_error=15" not in ev:
919         raise Exception("Unexpected failure reason (STA): " + ev)
920     dev[0].request("WPS_CANCEL")
921     dev[0].wait_disconnected()
922
923 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
924     """WPS PBC session overlap with two active APs"""
925     hostapd.add_ap(apdev[0],
926                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
927                      "wpa_passphrase": "12345678", "wpa": "2",
928                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
929                      "wps_independent": "1"})
930     hostapd.add_ap(apdev[1],
931                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
932                      "wpa_passphrase": "123456789", "wpa": "2",
933                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
934                      "wps_independent": "1"})
935     hapd = hostapd.Hostapd(apdev[0]['ifname'])
936     hapd.request("WPS_PBC")
937     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
938     hapd2.request("WPS_PBC")
939     logger.info("WPS provisioning step")
940     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
941     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
942     dev[0].request("WPS_PBC")
943     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
944     if ev is None:
945         raise Exception("PBC session overlap not detected")
946     hapd.request("DISABLE")
947     hapd2.request("DISABLE")
948     dev[0].flush_scan_cache()
949
950 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
951     """WPS PBC session overlap with two active STAs"""
952     ssid = "test-wps-pbc-overlap"
953     hostapd.add_ap(apdev[0],
954                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
955                      "wpa_passphrase": "12345678", "wpa": "2",
956                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
957     hapd = hostapd.Hostapd(apdev[0]['ifname'])
958     logger.info("WPS provisioning step")
959     hapd.request("WPS_PBC")
960     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
961     dev[0].dump_monitor()
962     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
963     dev[1].dump_monitor()
964     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
965     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
966     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
967     if ev is None:
968         raise Exception("PBC session overlap not detected (dev0)")
969     if "config_error=12" not in ev:
970         raise Exception("PBC session overlap not correctly reported (dev0)")
971     dev[0].request("WPS_CANCEL")
972     dev[0].request("DISCONNECT")
973     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
974     if ev is None:
975         raise Exception("PBC session overlap not detected (dev1)")
976     if "config_error=12" not in ev:
977         raise Exception("PBC session overlap not correctly reported (dev1)")
978     dev[1].request("WPS_CANCEL")
979     dev[1].request("DISCONNECT")
980     hapd.request("WPS_CANCEL")
981     ret = hapd.request("WPS_PBC")
982     if "FAIL" not in ret:
983         raise Exception("PBC mode allowed to be started while PBC overlap still active")
984     hapd.request("DISABLE")
985     dev[0].flush_scan_cache()
986     dev[1].flush_scan_cache()
987
988 def test_ap_wps_cancel(dev, apdev):
989     """WPS AP cancelling enabled config method"""
990     ssid = "test-wps-ap-cancel"
991     hostapd.add_ap(apdev[0],
992                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
993                      "wpa_passphrase": "12345678", "wpa": "2",
994                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
995     bssid = apdev[0]['bssid']
996     hapd = hostapd.Hostapd(apdev[0]['ifname'])
997
998     logger.info("Verify PBC enable/cancel")
999     hapd.request("WPS_PBC")
1000     dev[0].scan(freq="2412")
1001     dev[0].scan(freq="2412")
1002     bss = dev[0].get_bss(apdev[0]['bssid'])
1003     if "[WPS-PBC]" not in bss['flags']:
1004         raise Exception("WPS-PBC flag missing")
1005     if "FAIL" in hapd.request("WPS_CANCEL"):
1006         raise Exception("WPS_CANCEL failed")
1007     dev[0].scan(freq="2412")
1008     dev[0].scan(freq="2412")
1009     bss = dev[0].get_bss(apdev[0]['bssid'])
1010     if "[WPS-PBC]" in bss['flags']:
1011         raise Exception("WPS-PBC flag not cleared")
1012
1013     logger.info("Verify PIN enable/cancel")
1014     hapd.request("WPS_PIN any 12345670")
1015     dev[0].scan(freq="2412")
1016     dev[0].scan(freq="2412")
1017     bss = dev[0].get_bss(apdev[0]['bssid'])
1018     if "[WPS-AUTH]" not in bss['flags']:
1019         raise Exception("WPS-AUTH flag missing")
1020     if "FAIL" in hapd.request("WPS_CANCEL"):
1021         raise Exception("WPS_CANCEL failed")
1022     dev[0].scan(freq="2412")
1023     dev[0].scan(freq="2412")
1024     bss = dev[0].get_bss(apdev[0]['bssid'])
1025     if "[WPS-AUTH]" in bss['flags']:
1026         raise Exception("WPS-AUTH flag not cleared")
1027
1028 def test_ap_wps_er_add_enrollee(dev, apdev):
1029     """WPS ER configuring AP and adding a new enrollee using PIN"""
1030     try:
1031         _test_ap_wps_er_add_enrollee(dev, apdev)
1032     finally:
1033         dev[0].request("WPS_ER_STOP")
1034
1035 def _test_ap_wps_er_add_enrollee(dev, apdev):
1036     ssid = "wps-er-add-enrollee"
1037     ap_pin = "12345670"
1038     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1039     hostapd.add_ap(apdev[0],
1040                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
1041                      "device_name": "Wireless AP", "manufacturer": "Company",
1042                      "model_name": "WAP", "model_number": "123",
1043                      "serial_number": "12345", "device_type": "6-0050F204-1",
1044                      "os_version": "01020300",
1045                      'friendly_name': "WPS AP - <>&'\" - TEST",
1046                      "config_methods": "label push_button",
1047                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1048     logger.info("WPS configuration step")
1049     new_passphrase = "1234567890"
1050     dev[0].dump_monitor()
1051     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1052     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
1053                    new_passphrase)
1054     status = dev[0].get_status()
1055     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1056         raise Exception("Not fully connected")
1057     if status['ssid'] != ssid:
1058         raise Exception("Unexpected SSID")
1059     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
1060         raise Exception("Unexpected encryption configuration")
1061     if status['key_mgmt'] != 'WPA2-PSK':
1062         raise Exception("Unexpected key_mgmt")
1063
1064     logger.info("Start ER")
1065     dev[0].request("WPS_ER_START ifname=lo")
1066     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1067     if ev is None:
1068         raise Exception("AP discovery timed out")
1069     if ap_uuid not in ev:
1070         raise Exception("Expected AP UUID not found")
1071     if "|WPS AP - &lt;&gt;&amp;&apos;&quot; - TEST|Company|" not in ev:
1072         raise Exception("Expected friendly name not found")
1073
1074     logger.info("Learn AP configuration through UPnP")
1075     dev[0].dump_monitor()
1076     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1077     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1078     if ev is None:
1079         raise Exception("AP learn timed out")
1080     if ap_uuid not in ev:
1081         raise Exception("Expected AP UUID not in settings")
1082     if "ssid=" + ssid not in ev:
1083         raise Exception("Expected SSID not in settings")
1084     if "key=" + new_passphrase not in ev:
1085         raise Exception("Expected passphrase not in settings")
1086     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1087     if ev is None:
1088         raise Exception("WPS-FAIL after AP learn timed out")
1089     time.sleep(0.1)
1090
1091     logger.info("Add Enrollee using ER")
1092     pin = dev[1].wps_read_pin()
1093     dev[0].dump_monitor()
1094     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1095     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1096     dev[1].dump_monitor()
1097     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1098     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1099     if ev is None:
1100         raise Exception("Enrollee did not report success")
1101     dev[1].wait_connected(timeout=15)
1102     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1103     if ev is None:
1104         raise Exception("WPS ER did not report success")
1105     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1106
1107     logger.info("Add a specific Enrollee using ER")
1108     pin = dev[2].wps_read_pin()
1109     addr2 = dev[2].p2p_interface_addr()
1110     dev[0].dump_monitor()
1111     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1112     dev[2].dump_monitor()
1113     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1114     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1115     if ev is None:
1116         raise Exception("Enrollee not seen")
1117     if addr2 not in ev:
1118         raise Exception("Unexpected Enrollee MAC address")
1119     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
1120     dev[2].wait_connected(timeout=30)
1121     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1122     if ev is None:
1123         raise Exception("WPS ER did not report success")
1124
1125     logger.info("Verify registrar selection behavior")
1126     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1127     dev[1].request("DISCONNECT")
1128     dev[1].wait_disconnected(timeout=10)
1129     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1130     dev[1].scan(freq="2412")
1131     bss = dev[1].get_bss(apdev[0]['bssid'])
1132     if "[WPS-AUTH]" not in bss['flags']:
1133         # It is possible for scan to miss an update especially when running
1134         # tests under load with multiple VMs, so allow another attempt.
1135         dev[1].scan(freq="2412")
1136         bss = dev[1].get_bss(apdev[0]['bssid'])
1137         if "[WPS-AUTH]" not in bss['flags']:
1138             raise Exception("WPS-AUTH flag missing")
1139
1140     logger.info("Stop ER")
1141     dev[0].dump_monitor()
1142     dev[0].request("WPS_ER_STOP")
1143     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
1144     if ev is None:
1145         raise Exception("WPS ER unsubscription timed out")
1146     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
1147     # a bit before verifying that the scan results have changed.
1148     time.sleep(0.2)
1149
1150     for i in range(0, 10):
1151         dev[1].request("BSS_FLUSH 0")
1152         dev[1].scan(freq="2412", only_new=True)
1153         bss = dev[1].get_bss(apdev[0]['bssid'])
1154         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
1155             break
1156         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
1157         time.sleep(0.1)
1158     if "[WPS-AUTH]" in bss['flags']:
1159         raise Exception("WPS-AUTH flag not removed")
1160
1161 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1162     """WPS ER adding a new enrollee identified by UUID"""
1163     try:
1164         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
1165     finally:
1166         dev[0].request("WPS_ER_STOP")
1167
1168 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1169     ssid = "wps-er-add-enrollee"
1170     ap_pin = "12345670"
1171     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1172     hostapd.add_ap(apdev[0],
1173                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1174                      "wpa_passphrase": "12345678", "wpa": "2",
1175                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1176                      "device_name": "Wireless AP", "manufacturer": "Company",
1177                      "model_name": "WAP", "model_number": "123",
1178                      "serial_number": "12345", "device_type": "6-0050F204-1",
1179                      "os_version": "01020300",
1180                      "config_methods": "label push_button",
1181                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1182     logger.info("WPS configuration step")
1183     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1184     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1185
1186     logger.info("Start ER")
1187     dev[0].request("WPS_ER_START ifname=lo")
1188     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1189     if ev is None:
1190         raise Exception("AP discovery timed out")
1191     if ap_uuid not in ev:
1192         raise Exception("Expected AP UUID not found")
1193
1194     logger.info("Learn AP configuration through UPnP")
1195     dev[0].dump_monitor()
1196     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1197     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1198     if ev is None:
1199         raise Exception("AP learn timed out")
1200     if ap_uuid not in ev:
1201         raise Exception("Expected AP UUID not in settings")
1202     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1203     if ev is None:
1204         raise Exception("WPS-FAIL after AP learn timed out")
1205     time.sleep(0.1)
1206
1207     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1208     addr1 = dev[1].p2p_interface_addr()
1209     dev[0].dump_monitor()
1210     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1211     dev[1].dump_monitor()
1212     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1213     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1214     if ev is None:
1215         raise Exception("Enrollee not seen")
1216     if addr1 not in ev:
1217         raise Exception("Unexpected Enrollee MAC address")
1218     uuid = ev.split(' ')[1]
1219     dev[0].request("WPS_ER_PBC " + uuid)
1220     dev[1].wait_connected(timeout=30)
1221     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1222     if ev is None:
1223         raise Exception("WPS ER did not report success")
1224
1225     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1226     pin = dev[2].wps_read_pin()
1227     addr2 = dev[2].p2p_interface_addr()
1228     dev[0].dump_monitor()
1229     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1230     dev[2].dump_monitor()
1231     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1232     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1233     if ev is None:
1234         raise Exception("Enrollee not seen")
1235     if addr2 not in ev:
1236         raise Exception("Unexpected Enrollee MAC address")
1237     uuid = ev.split(' ')[1]
1238     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1239     dev[2].wait_connected(timeout=30)
1240     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1241     if ev is None:
1242         raise Exception("WPS ER did not report success")
1243
1244     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-REMOVE"], timeout=15)
1245     if ev is None:
1246         raise Exception("No Enrollee STA entry timeout seen")
1247
1248     logger.info("Stop ER")
1249     dev[0].dump_monitor()
1250     dev[0].request("WPS_ER_STOP")
1251
1252 def test_ap_wps_er_multi_add_enrollee(dev, apdev):
1253     """Multiple WPS ERs adding a new enrollee using PIN"""
1254     try:
1255         _test_ap_wps_er_multi_add_enrollee(dev, apdev)
1256     finally:
1257         for i in range(2):
1258             dev[i].request("WPS_ER_STOP")
1259
1260 def _test_ap_wps_er_multi_add_enrollee(dev, apdev):
1261     ssid = "wps-er-add-enrollee"
1262     ap_pin = "12345670"
1263     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1264     hostapd.add_ap(apdev[0],
1265                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1266                      "wpa_passphrase": "12345678", "wpa": "2",
1267                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1268                      "device_name": "Wireless AP", "manufacturer": "Company",
1269                      "model_name": "WAP", "model_number": "123",
1270                      "serial_number": "12345", "device_type": "6-0050F204-1",
1271                      "os_version": "01020300",
1272                      'friendly_name': "WPS AP",
1273                      "config_methods": "label push_button",
1274                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1275
1276     for i in range(2):
1277         dev[i].scan_for_bss(apdev[0]['bssid'], freq=2412)
1278         dev[i].wps_reg(apdev[0]['bssid'], ap_pin)
1279     for i in range(2):
1280         dev[i].request("WPS_ER_START ifname=lo")
1281     for i in range(2):
1282         ev = dev[i].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1283         if ev is None:
1284             raise Exception("AP discovery timed out")
1285         dev[i].dump_monitor()
1286     for i in range(2):
1287         dev[i].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1288     for i in range(2):
1289         ev = dev[i].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1290         if ev is None:
1291             raise Exception("AP learn timed out")
1292         ev = dev[i].wait_event(["WPS-FAIL"], timeout=15)
1293         if ev is None:
1294             raise Exception("WPS-FAIL after AP learn timed out")
1295
1296     time.sleep(0.1)
1297
1298     pin = dev[2].wps_read_pin()
1299     addr = dev[2].own_addr()
1300     dev[0].dump_monitor()
1301     dev[0].request("WPS_ER_PIN any " + pin + " " + addr)
1302     dev[1].dump_monitor()
1303     dev[1].request("WPS_ER_PIN any " + pin + " " + addr)
1304
1305     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1306     dev[2].dump_monitor()
1307     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1308     ev = dev[2].wait_event(["WPS-SUCCESS"], timeout=30)
1309     if ev is None:
1310         raise Exception("Enrollee did not report success")
1311     dev[2].wait_connected(timeout=15)
1312
1313 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1314     """WPS ER connected to AP and adding a new enrollee using PBC"""
1315     try:
1316         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1317     finally:
1318         dev[0].request("WPS_ER_STOP")
1319
1320 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1321     ssid = "wps-er-add-enrollee-pbc"
1322     ap_pin = "12345670"
1323     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1324     hostapd.add_ap(apdev[0],
1325                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1326                      "wpa_passphrase": "12345678", "wpa": "2",
1327                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1328                      "device_name": "Wireless AP", "manufacturer": "Company",
1329                      "model_name": "WAP", "model_number": "123",
1330                      "serial_number": "12345", "device_type": "6-0050F204-1",
1331                      "os_version": "01020300",
1332                      "config_methods": "label push_button",
1333                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1334     logger.info("Learn AP configuration")
1335     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1336     dev[0].dump_monitor()
1337     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1338     status = dev[0].get_status()
1339     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1340         raise Exception("Not fully connected")
1341
1342     logger.info("Start ER")
1343     dev[0].request("WPS_ER_START ifname=lo")
1344     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1345     if ev is None:
1346         raise Exception("AP discovery timed out")
1347     if ap_uuid not in ev:
1348         raise Exception("Expected AP UUID not found")
1349
1350     enrollee = dev[1].p2p_interface_addr()
1351
1352     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1353         raise Exception("Unknown UUID not reported")
1354
1355     logger.info("Add Enrollee using ER and PBC")
1356     dev[0].dump_monitor()
1357     dev[1].dump_monitor()
1358     dev[1].request("WPS_PBC")
1359
1360     for i in range(0, 2):
1361         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1362         if ev is None:
1363             raise Exception("Enrollee discovery timed out")
1364         if enrollee in ev:
1365             break
1366         if i == 1:
1367             raise Exception("Expected Enrollee not found")
1368     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1369         raise Exception("Unknown UUID not reported")
1370     logger.info("Use learned network configuration on ER")
1371     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1372     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1373         raise Exception("WPS_ER_PBC failed")
1374
1375     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1376     if ev is None:
1377         raise Exception("Enrollee did not report success")
1378     dev[1].wait_connected(timeout=15)
1379     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1380     if ev is None:
1381         raise Exception("WPS ER did not report success")
1382     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1383
1384 def test_ap_wps_er_pbc_overlap(dev, apdev):
1385     """WPS ER connected to AP and PBC session overlap"""
1386     try:
1387         _test_ap_wps_er_pbc_overlap(dev, apdev)
1388     finally:
1389         dev[0].request("WPS_ER_STOP")
1390
1391 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1392     ssid = "wps-er-add-enrollee-pbc"
1393     ap_pin = "12345670"
1394     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1395     hostapd.add_ap(apdev[0],
1396                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1397                      "wpa_passphrase": "12345678", "wpa": "2",
1398                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1399                      "device_name": "Wireless AP", "manufacturer": "Company",
1400                      "model_name": "WAP", "model_number": "123",
1401                      "serial_number": "12345", "device_type": "6-0050F204-1",
1402                      "os_version": "01020300",
1403                      "config_methods": "label push_button",
1404                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1405     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1406     dev[0].dump_monitor()
1407     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1408
1409     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1410     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1411     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1412     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1413
1414     dev[0].dump_monitor()
1415     dev[0].request("WPS_ER_START ifname=lo")
1416
1417     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1418     if ev is None:
1419         raise Exception("AP discovery timed out")
1420     if ap_uuid not in ev:
1421         raise Exception("Expected AP UUID not found")
1422
1423     # verify BSSID selection of the AP instead of UUID
1424     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1425         raise Exception("Could not select AP based on BSSID")
1426
1427     dev[0].dump_monitor()
1428     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1429     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1430     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1431     if ev is None:
1432         raise Exception("PBC scan failed")
1433     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1434     if ev is None:
1435         raise Exception("PBC scan failed")
1436     found1 = False
1437     found2 = False
1438     addr1 = dev[1].own_addr()
1439     addr2 = dev[2].own_addr()
1440     for i in range(3):
1441         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1442         if ev is None:
1443             raise Exception("Enrollee discovery timed out")
1444         if addr1 in ev:
1445             found1 = True
1446             if found2:
1447                 break
1448         if addr2 in ev:
1449             found2 = True
1450             if found1:
1451                 break
1452     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1453         raise Exception("PBC overlap not reported")
1454     dev[1].request("WPS_CANCEL")
1455     dev[2].request("WPS_CANCEL")
1456     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1457         raise Exception("Invalid WPS_ER_PBC accepted")
1458
1459 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1460     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1461     try:
1462         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1463     finally:
1464         dev[0].request("WPS_ER_STOP")
1465
1466 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1467     ssid = "wps-er-add-enrollee-pbc"
1468     ap_pin = "12345670"
1469     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1470     hostapd.add_ap(apdev[0],
1471                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1472                      "wpa_passphrase": "12345678", "wpa": "2",
1473                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1474                      "device_name": "Wireless AP", "manufacturer": "Company",
1475                      "model_name": "WAP", "model_number": "123",
1476                      "serial_number": "12345", "device_type": "6-0050F204-1",
1477                      "os_version": "01020300",
1478                      "config_methods": "label push_button",
1479                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1480     logger.info("Learn AP configuration")
1481     dev[0].request("SET wps_version_number 0x10")
1482     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1483     dev[0].dump_monitor()
1484     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1485     status = dev[0].get_status()
1486     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1487         raise Exception("Not fully connected")
1488
1489     logger.info("Start ER")
1490     dev[0].request("WPS_ER_START ifname=lo")
1491     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1492     if ev is None:
1493         raise Exception("AP discovery timed out")
1494     if ap_uuid not in ev:
1495         raise Exception("Expected AP UUID not found")
1496
1497     logger.info("Use learned network configuration on ER")
1498     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1499
1500     logger.info("Add Enrollee using ER and PIN")
1501     enrollee = dev[1].p2p_interface_addr()
1502     pin = dev[1].wps_read_pin()
1503     dev[0].dump_monitor()
1504     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1505     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1506     dev[1].dump_monitor()
1507     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1508     dev[1].wait_connected(timeout=30)
1509     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1510     if ev is None:
1511         raise Exception("WPS ER did not report success")
1512
1513 def test_ap_wps_er_config_ap(dev, apdev):
1514     """WPS ER configuring AP over UPnP"""
1515     try:
1516         _test_ap_wps_er_config_ap(dev, apdev)
1517     finally:
1518         dev[0].request("WPS_ER_STOP")
1519
1520 def _test_ap_wps_er_config_ap(dev, apdev):
1521     ssid = "wps-er-ap-config"
1522     ap_pin = "12345670"
1523     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1524     hostapd.add_ap(apdev[0],
1525                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1526                      "wpa_passphrase": "12345678", "wpa": "2",
1527                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1528                      "device_name": "Wireless AP", "manufacturer": "Company",
1529                      "model_name": "WAP", "model_number": "123",
1530                      "serial_number": "12345", "device_type": "6-0050F204-1",
1531                      "os_version": "01020300",
1532                      "config_methods": "label push_button",
1533                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1534
1535     logger.info("Connect ER to the AP")
1536     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1537
1538     logger.info("WPS configuration step")
1539     dev[0].request("WPS_ER_START ifname=lo")
1540     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1541     if ev is None:
1542         raise Exception("AP discovery timed out")
1543     if ap_uuid not in ev:
1544         raise Exception("Expected AP UUID not found")
1545     new_passphrase = "1234567890"
1546     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1547                    ssid.encode("hex") + " WPA2PSK CCMP " +
1548                    new_passphrase.encode("hex"))
1549     ev = dev[0].wait_event(["WPS-SUCCESS"])
1550     if ev is None:
1551         raise Exception("WPS ER configuration operation timed out")
1552     dev[0].wait_disconnected(timeout=10)
1553     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1554
1555     logger.info("WPS ER restart")
1556     dev[0].request("WPS_ER_START")
1557     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1558     if ev is None:
1559         raise Exception("AP discovery timed out on ER restart")
1560     if ap_uuid not in ev:
1561         raise Exception("Expected AP UUID not found on ER restart")
1562     if "OK" not in dev[0].request("WPS_ER_STOP"):
1563         raise Exception("WPS_ER_STOP failed")
1564     if "OK" not in dev[0].request("WPS_ER_STOP"):
1565         raise Exception("WPS_ER_STOP failed")
1566
1567 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1568     """WPS ER caching AP settings"""
1569     try:
1570         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1571     finally:
1572         dev[0].request("WPS_ER_STOP")
1573
1574 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1575     ssid = "wps-er-add-enrollee"
1576     ap_pin = "12345670"
1577     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1578     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1579                "wpa_passphrase": "12345678", "wpa": "2",
1580                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1581                "device_name": "Wireless AP", "manufacturer": "Company",
1582                "model_name": "WAP", "model_number": "123",
1583                "serial_number": "12345", "device_type": "6-0050F204-1",
1584                "os_version": "01020300",
1585                "config_methods": "label push_button",
1586                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1587     hapd = hostapd.add_ap(apdev[0], params)
1588     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1589     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1590     id = int(dev[0].list_networks()[0]['id'])
1591     dev[0].set_network(id, "scan_freq", "2412")
1592
1593     dev[0].request("WPS_ER_START ifname=lo")
1594     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1595     if ev is None:
1596         raise Exception("AP discovery timed out")
1597     if ap_uuid not in ev:
1598         raise Exception("Expected AP UUID not found")
1599
1600     dev[0].dump_monitor()
1601     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1602     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1603     if ev is None:
1604         raise Exception("AP learn timed out")
1605     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1606     if ev is None:
1607         raise Exception("WPS-FAIL after AP learn timed out")
1608     time.sleep(0.1)
1609
1610     hapd.disable()
1611
1612     for i in range(2):
1613         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1614                                  "CTRL-EVENT-DISCONNECTED" ],
1615                                timeout=15)
1616         if ev is None:
1617             raise Exception("AP removal or disconnection timed out")
1618
1619     hapd = hostapd.add_ap(apdev[0], params)
1620     for i in range(2):
1621         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1622                                timeout=15)
1623         if ev is None:
1624             raise Exception("AP discovery or connection timed out")
1625
1626     pin = dev[1].wps_read_pin()
1627     dev[0].dump_monitor()
1628     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1629
1630     time.sleep(0.2)
1631
1632     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1633     dev[1].dump_monitor()
1634     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1635     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1636     if ev is None:
1637         raise Exception("Enrollee did not report success")
1638     dev[1].wait_connected(timeout=15)
1639     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1640     if ev is None:
1641         raise Exception("WPS ER did not report success")
1642
1643     dev[0].dump_monitor()
1644     dev[0].request("WPS_ER_STOP")
1645
1646 def test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1647     """WPS ER caching AP settings (OOM)"""
1648     try:
1649         _test_ap_wps_er_cache_ap_settings_oom(dev, apdev)
1650     finally:
1651         dev[0].request("WPS_ER_STOP")
1652
1653 def _test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1654     ssid = "wps-er-add-enrollee"
1655     ap_pin = "12345670"
1656     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1657     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1658                "wpa_passphrase": "12345678", "wpa": "2",
1659                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1660                "device_name": "Wireless AP", "manufacturer": "Company",
1661                "model_name": "WAP", "model_number": "123",
1662                "serial_number": "12345", "device_type": "6-0050F204-1",
1663                "os_version": "01020300",
1664                "config_methods": "label push_button",
1665                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1666     hapd = hostapd.add_ap(apdev[0], params)
1667     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1668     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1669     id = int(dev[0].list_networks()[0]['id'])
1670     dev[0].set_network(id, "scan_freq", "2412")
1671
1672     dev[0].request("WPS_ER_START ifname=lo")
1673     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1674     if ev is None:
1675         raise Exception("AP discovery timed out")
1676     if ap_uuid not in ev:
1677         raise Exception("Expected AP UUID not found")
1678
1679     dev[0].dump_monitor()
1680     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1681     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1682     if ev is None:
1683         raise Exception("AP learn timed out")
1684     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1685     if ev is None:
1686         raise Exception("WPS-FAIL after AP learn timed out")
1687     time.sleep(0.1)
1688
1689     with alloc_fail(dev[0], 1, "=wps_er_ap_use_cached_settings"):
1690         hapd.disable()
1691
1692         for i in range(2):
1693             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1694                                      "CTRL-EVENT-DISCONNECTED" ],
1695                                    timeout=15)
1696             if ev is None:
1697                 raise Exception("AP removal or disconnection timed out")
1698
1699         hapd = hostapd.add_ap(apdev[0], params)
1700         for i in range(2):
1701             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1702                                    timeout=15)
1703             if ev is None:
1704                 raise Exception("AP discovery or connection timed out")
1705
1706     dev[0].request("WPS_ER_STOP")
1707
1708 def test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1709     """WPS ER caching AP settings (OOM 2)"""
1710     try:
1711         _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev)
1712     finally:
1713         dev[0].request("WPS_ER_STOP")
1714
1715 def _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1716     ssid = "wps-er-add-enrollee"
1717     ap_pin = "12345670"
1718     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1719     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1720                "wpa_passphrase": "12345678", "wpa": "2",
1721                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1722                "device_name": "Wireless AP", "manufacturer": "Company",
1723                "model_name": "WAP", "model_number": "123",
1724                "serial_number": "12345", "device_type": "6-0050F204-1",
1725                "os_version": "01020300",
1726                "config_methods": "label push_button",
1727                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1728     hapd = hostapd.add_ap(apdev[0], params)
1729     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1730     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1731     id = int(dev[0].list_networks()[0]['id'])
1732     dev[0].set_network(id, "scan_freq", "2412")
1733
1734     dev[0].request("WPS_ER_START ifname=lo")
1735     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1736     if ev is None:
1737         raise Exception("AP discovery timed out")
1738     if ap_uuid not in ev:
1739         raise Exception("Expected AP UUID not found")
1740
1741     dev[0].dump_monitor()
1742     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1743     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1744     if ev is None:
1745         raise Exception("AP learn timed out")
1746     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1747     if ev is None:
1748         raise Exception("WPS-FAIL after AP learn timed out")
1749     time.sleep(0.1)
1750
1751     with alloc_fail(dev[0], 1, "=wps_er_ap_cache_settings"):
1752         hapd.disable()
1753
1754         for i in range(2):
1755             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1756                                      "CTRL-EVENT-DISCONNECTED" ],
1757                                    timeout=15)
1758             if ev is None:
1759                 raise Exception("AP removal or disconnection timed out")
1760
1761         hapd = hostapd.add_ap(apdev[0], params)
1762         for i in range(2):
1763             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1764                                    timeout=15)
1765             if ev is None:
1766                 raise Exception("AP discovery or connection timed out")
1767
1768     dev[0].request("WPS_ER_STOP")
1769
1770 def test_ap_wps_er_subscribe_oom(dev, apdev):
1771     """WPS ER subscribe OOM"""
1772     try:
1773         _test_ap_wps_er_subscribe_oom(dev, apdev)
1774     finally:
1775         dev[0].request("WPS_ER_STOP")
1776
1777 def _test_ap_wps_er_subscribe_oom(dev, apdev):
1778     ssid = "wps-er-add-enrollee"
1779     ap_pin = "12345670"
1780     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1781     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1782                "wpa_passphrase": "12345678", "wpa": "2",
1783                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1784                "device_name": "Wireless AP", "manufacturer": "Company",
1785                "model_name": "WAP", "model_number": "123",
1786                "serial_number": "12345", "device_type": "6-0050F204-1",
1787                "os_version": "01020300",
1788                "config_methods": "label push_button",
1789                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1790     hapd = hostapd.add_ap(apdev[0], params)
1791     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1792     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1793     id = int(dev[0].list_networks()[0]['id'])
1794     dev[0].set_network(id, "scan_freq", "2412")
1795
1796     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_subscribe"):
1797         dev[0].request("WPS_ER_START ifname=lo")
1798         for i in range(50):
1799             res = dev[0].request("GET_ALLOC_FAIL")
1800             if res.startswith("0:"):
1801                 break
1802             time.sleep(0.1)
1803         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=0)
1804         if ev:
1805             raise Exception("Unexpected AP discovery during OOM")
1806
1807     dev[0].request("WPS_ER_STOP")
1808
1809 def test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1810     """WPS ER SetSelectedRegistrar OOM"""
1811     try:
1812         _test_ap_wps_er_set_sel_reg_oom(dev, apdev)
1813     finally:
1814         dev[0].request("WPS_ER_STOP")
1815
1816 def _test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1817     ssid = "wps-er-add-enrollee"
1818     ap_pin = "12345670"
1819     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1820     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1821                "wpa_passphrase": "12345678", "wpa": "2",
1822                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1823                "device_name": "Wireless AP", "manufacturer": "Company",
1824                "model_name": "WAP", "model_number": "123",
1825                "serial_number": "12345", "device_type": "6-0050F204-1",
1826                "os_version": "01020300",
1827                "config_methods": "label push_button",
1828                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1829     hapd = hostapd.add_ap(apdev[0], params)
1830     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1831     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1832
1833     dev[0].request("WPS_ER_START ifname=lo")
1834     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1835     if ev is None:
1836         raise Exception("AP not discovered")
1837
1838     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1839     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1840     if ev is None:
1841         raise Exception("AP learn timed out")
1842     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1843     if ev is None:
1844         raise Exception("WPS-FAIL timed out")
1845     time.sleep(0.1)
1846
1847     for func in [ "http_client_url_parse;wps_er_send_set_sel_reg",
1848                   "wps_er_soap_hdr;wps_er_send_set_sel_reg",
1849                   "http_client_addr;wps_er_send_set_sel_reg",
1850                   "wpabuf_alloc;wps_er_set_sel_reg" ]:
1851         with alloc_fail(dev[0], 1, func):
1852             if "OK" not in dev[0].request("WPS_ER_PBC " + ap_uuid):
1853                 raise Exception("WPS_ER_PBC failed")
1854             ev = dev[0].wait_event(["WPS-PBC-ACTIVE"], timeout=3)
1855             if ev is None:
1856                 raise Exception("WPS-PBC-ACTIVE not seen")
1857
1858     dev[0].request("WPS_ER_STOP")
1859
1860 def test_ap_wps_er_learn_oom(dev, apdev):
1861     """WPS ER learn OOM"""
1862     try:
1863         _test_ap_wps_er_learn_oom(dev, apdev)
1864     finally:
1865         dev[0].request("WPS_ER_STOP")
1866
1867 def _test_ap_wps_er_learn_oom(dev, apdev):
1868     ssid = "wps-er-add-enrollee"
1869     ap_pin = "12345670"
1870     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1871     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1872                "wpa_passphrase": "12345678", "wpa": "2",
1873                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1874                "device_name": "Wireless AP", "manufacturer": "Company",
1875                "model_name": "WAP", "model_number": "123",
1876                "serial_number": "12345", "device_type": "6-0050F204-1",
1877                "os_version": "01020300",
1878                "config_methods": "label push_button",
1879                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1880     hapd = hostapd.add_ap(apdev[0], params)
1881     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1882     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1883
1884     dev[0].request("WPS_ER_START ifname=lo")
1885     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1886     if ev is None:
1887         raise Exception("AP not discovered")
1888
1889     for func in [ "wps_er_http_put_message_cb",
1890                   "xml_get_base64_item;wps_er_http_put_message_cb",
1891                   "http_client_url_parse;wps_er_ap_put_message",
1892                   "wps_er_soap_hdr;wps_er_ap_put_message",
1893                   "http_client_addr;wps_er_ap_put_message" ]:
1894         with alloc_fail(dev[0], 1, func):
1895             dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1896             ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=1)
1897             if ev is not None:
1898                 raise Exception("AP learn succeeded during OOM")
1899
1900     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1901     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=10)
1902     if ev is None:
1903         raise Exception("AP learn did not succeed")
1904
1905     if "FAIL" not in dev[0].request("WPS_ER_LEARN 00000000-9e5c-4e73-bd82-f89cbcd10d7e " + ap_pin):
1906         raise Exception("WPS_ER_LEARN for unknown AP accepted")
1907
1908     dev[0].request("WPS_ER_STOP")
1909
1910 def test_ap_wps_fragmentation(dev, apdev):
1911     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1912     ssid = "test-wps-fragmentation"
1913     appin = "12345670"
1914     hostapd.add_ap(apdev[0],
1915                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1916                      "wpa_passphrase": "12345678", "wpa": "3",
1917                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1918                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1919                      "fragment_size": "50" })
1920     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1921     logger.info("WPS provisioning step (PBC)")
1922     hapd.request("WPS_PBC")
1923     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1924     dev[0].dump_monitor()
1925     dev[0].request("SET wps_fragment_size 50")
1926     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1927     dev[0].wait_connected(timeout=30)
1928     status = dev[0].get_status()
1929     if status['wpa_state'] != 'COMPLETED':
1930         raise Exception("Not fully connected")
1931     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1932         raise Exception("Unexpected encryption configuration")
1933     if status['key_mgmt'] != 'WPA2-PSK':
1934         raise Exception("Unexpected key_mgmt")
1935
1936     logger.info("WPS provisioning step (PIN)")
1937     pin = dev[1].wps_read_pin()
1938     hapd.request("WPS_PIN any " + pin)
1939     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1940     dev[1].request("SET wps_fragment_size 50")
1941     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1942     dev[1].wait_connected(timeout=30)
1943     status = dev[1].get_status()
1944     if status['wpa_state'] != 'COMPLETED':
1945         raise Exception("Not fully connected")
1946     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1947         raise Exception("Unexpected encryption configuration")
1948     if status['key_mgmt'] != 'WPA2-PSK':
1949         raise Exception("Unexpected key_mgmt")
1950
1951     logger.info("WPS connection as registrar")
1952     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1953     dev[2].request("SET wps_fragment_size 50")
1954     dev[2].wps_reg(apdev[0]['bssid'], appin)
1955     status = dev[2].get_status()
1956     if status['wpa_state'] != 'COMPLETED':
1957         raise Exception("Not fully connected")
1958     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1959         raise Exception("Unexpected encryption configuration")
1960     if status['key_mgmt'] != 'WPA2-PSK':
1961         raise Exception("Unexpected key_mgmt")
1962
1963 def test_ap_wps_new_version_sta(dev, apdev):
1964     """WPS compatibility with new version number on the station"""
1965     ssid = "test-wps-ver"
1966     hostapd.add_ap(apdev[0],
1967                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1968                      "wpa_passphrase": "12345678", "wpa": "2",
1969                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1970     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1971     logger.info("WPS provisioning step")
1972     hapd.request("WPS_PBC")
1973     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1974     dev[0].dump_monitor()
1975     dev[0].request("SET wps_version_number 0x43")
1976     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1977     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1978     dev[0].wait_connected(timeout=30)
1979
1980 def test_ap_wps_new_version_ap(dev, apdev):
1981     """WPS compatibility with new version number on the AP"""
1982     ssid = "test-wps-ver"
1983     hostapd.add_ap(apdev[0],
1984                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1985                      "wpa_passphrase": "12345678", "wpa": "2",
1986                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1987     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1988     logger.info("WPS provisioning step")
1989     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1990         raise Exception("Failed to enable test functionality")
1991     hapd.request("WPS_PBC")
1992     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1993     dev[0].dump_monitor()
1994     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1995     dev[0].wait_connected(timeout=30)
1996     hapd.request("SET wps_version_number 0x20")
1997
1998 def test_ap_wps_check_pin(dev, apdev):
1999     """Verify PIN checking through control interface"""
2000     hostapd.add_ap(apdev[0],
2001                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
2002                      "wpa_passphrase": "12345678", "wpa": "2",
2003                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
2004     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2005     for t in [ ("12345670", "12345670"),
2006                ("12345678", "FAIL-CHECKSUM"),
2007                ("12345", "FAIL"),
2008                ("123456789", "FAIL"),
2009                ("1234-5670", "12345670"),
2010                ("1234 5670", "12345670"),
2011                ("1-2.3:4 5670", "12345670") ]:
2012         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
2013         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
2014         if res != res2:
2015             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
2016         if res != t[1]:
2017             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
2018
2019     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
2020         raise Exception("Unexpected WPS_CHECK_PIN success")
2021     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
2022         raise Exception("Unexpected WPS_CHECK_PIN success")
2023
2024     for i in range(0, 10):
2025         pin = dev[0].request("WPS_PIN get")
2026         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
2027         if pin != rpin:
2028             raise Exception("Random PIN validation failed for " + pin)
2029
2030 def test_ap_wps_wep_config(dev, apdev):
2031     """WPS 2.0 AP rejecting WEP configuration"""
2032     ssid = "test-wps-config"
2033     appin = "12345670"
2034     hostapd.add_ap(apdev[0],
2035                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2036                      "ap_pin": appin})
2037     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2038     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2039     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
2040                    "hello", no_wait=True)
2041     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
2042     if ev is None:
2043         raise Exception("WPS-FAIL timed out")
2044     if "reason=2" not in ev:
2045         raise Exception("Unexpected reason code in WPS-FAIL")
2046     status = hapd.request("WPS_GET_STATUS")
2047     if "Last WPS result: Failed" not in status:
2048         raise Exception("WPS failure result not shown correctly")
2049     if "Failure Reason: WEP Prohibited" not in status:
2050         raise Exception("Failure reason not reported correctly")
2051     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
2052         raise Exception("Peer address not shown correctly")
2053
2054 def test_ap_wps_wep_enroll(dev, apdev):
2055     """WPS 2.0 STA rejecting WEP configuration"""
2056     ssid = "test-wps-wep"
2057     hostapd.add_ap(apdev[0],
2058                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2059                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
2060     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2061     hapd.request("WPS_PBC")
2062     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2063     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2064     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
2065     if ev is None:
2066         raise Exception("WPS-FAIL event timed out")
2067     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
2068         raise Exception("Unexpected WPS-FAIL event: " + ev)
2069
2070 def test_ap_wps_ie_fragmentation(dev, apdev):
2071     """WPS AP using fragmented WPS IE"""
2072     ssid = "test-wps-ie-fragmentation"
2073     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2074                "wpa_passphrase": "12345678", "wpa": "2",
2075                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2076                "device_name": "1234567890abcdef1234567890abcdef",
2077                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
2078                "model_name": "1234567890abcdef1234567890abcdef",
2079                "model_number": "1234567890abcdef1234567890abcdef",
2080                "serial_number": "1234567890abcdef1234567890abcdef" }
2081     hostapd.add_ap(apdev[0], params)
2082     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2083     hapd.request("WPS_PBC")
2084     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2085     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2086     dev[0].wait_connected(timeout=30)
2087     bss = dev[0].get_bss(apdev[0]['bssid'])
2088     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
2089         logger.info("Device Name not received correctly")
2090         logger.info(bss)
2091         # This can fail if Probe Response frame is missed and Beacon frame was
2092         # used to fill in the BSS entry. This can happen, e.g., during heavy
2093         # load every now and then and is not really an error, so try to
2094         # workaround by runnign another scan.
2095         dev[0].scan(freq="2412", only_new=True)
2096         bss = dev[0].get_bss(apdev[0]['bssid'])
2097         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
2098             logger.info(bss)
2099             raise Exception("Device Name not received correctly")
2100     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
2101         raise Exception("Unexpected number of WPS IEs")
2102
2103 def get_psk(pskfile):
2104     psks = {}
2105     with open(pskfile, "r") as f:
2106         lines = f.read().splitlines()
2107         for l in lines:
2108             if l == "# WPA PSKs":
2109                 continue
2110             (addr,psk) = l.split(' ')
2111             psks[addr] = psk
2112     return psks
2113
2114 def test_ap_wps_per_station_psk(dev, apdev):
2115     """WPS PBC provisioning with per-station PSK"""
2116     addr0 = dev[0].own_addr()
2117     addr1 = dev[1].own_addr()
2118     addr2 = dev[2].own_addr()
2119     ssid = "wps"
2120     appin = "12345670"
2121     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2122     try:
2123         os.remove(pskfile)
2124     except:
2125         pass
2126
2127     hapd = None
2128     try:
2129         with open(pskfile, "w") as f:
2130             f.write("# WPA PSKs\n")
2131
2132         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2133                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2134                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2135                    "wpa_psk_file": pskfile }
2136         hapd = hostapd.add_ap(apdev[0], params)
2137
2138         logger.info("First enrollee")
2139         hapd.request("WPS_PBC")
2140         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2141         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2142         dev[0].wait_connected(timeout=30)
2143
2144         logger.info("Second enrollee")
2145         hapd.request("WPS_PBC")
2146         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2147         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2148         dev[1].wait_connected(timeout=30)
2149
2150         logger.info("External registrar")
2151         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2152         dev[2].wps_reg(apdev[0]['bssid'], appin)
2153
2154         logger.info("Verifying PSK results")
2155         psks = get_psk(pskfile)
2156         if addr0 not in psks:
2157             raise Exception("No PSK recorded for sta0")
2158         if addr1 not in psks:
2159             raise Exception("No PSK recorded for sta1")
2160         if addr2 not in psks:
2161             raise Exception("No PSK recorded for sta2")
2162         if psks[addr0] == psks[addr1]:
2163             raise Exception("Same PSK recorded for sta0 and sta1")
2164         if psks[addr0] == psks[addr2]:
2165             raise Exception("Same PSK recorded for sta0 and sta2")
2166         if psks[addr1] == psks[addr2]:
2167             raise Exception("Same PSK recorded for sta1 and sta2")
2168
2169         dev[0].request("REMOVE_NETWORK all")
2170         logger.info("Second external registrar")
2171         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2172         dev[0].wps_reg(apdev[0]['bssid'], appin)
2173         psks2 = get_psk(pskfile)
2174         if addr0 not in psks2:
2175             raise Exception("No PSK recorded for sta0(reg)")
2176         if psks[addr0] == psks2[addr0]:
2177             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
2178     finally:
2179         os.remove(pskfile)
2180         if hapd:
2181             dev[0].request("DISCONNECT")
2182             dev[1].request("DISCONNECT")
2183             dev[2].request("DISCONNECT")
2184             hapd.disable()
2185             dev[0].flush_scan_cache()
2186             dev[1].flush_scan_cache()
2187             dev[2].flush_scan_cache()
2188
2189 def test_ap_wps_per_station_psk_failure(dev, apdev):
2190     """WPS PBC provisioning with per-station PSK (file not writable)"""
2191     addr0 = dev[0].p2p_dev_addr()
2192     addr1 = dev[1].p2p_dev_addr()
2193     addr2 = dev[2].p2p_dev_addr()
2194     ssid = "wps"
2195     appin = "12345670"
2196     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2197     try:
2198         os.remove(pskfile)
2199     except:
2200         pass
2201
2202     try:
2203         with open(pskfile, "w") as f:
2204             f.write("# WPA PSKs\n")
2205
2206         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2207                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2208                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2209                    "wpa_psk_file": pskfile }
2210         hapd = hostapd.add_ap(apdev[0], params)
2211         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2212             raise Exception("Failed to set wpa_psk_file")
2213
2214         logger.info("First enrollee")
2215         hapd.request("WPS_PBC")
2216         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2217         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2218         dev[0].wait_connected(timeout=30)
2219
2220         logger.info("Second enrollee")
2221         hapd.request("WPS_PBC")
2222         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2223         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2224         dev[1].wait_connected(timeout=30)
2225
2226         logger.info("External registrar")
2227         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2228         dev[2].wps_reg(apdev[0]['bssid'], appin)
2229
2230         logger.info("Verifying PSK results")
2231         psks = get_psk(pskfile)
2232         if len(psks) > 0:
2233             raise Exception("PSK recorded unexpectedly")
2234     finally:
2235         os.remove(pskfile)
2236
2237 def test_ap_wps_pin_request_file(dev, apdev):
2238     """WPS PIN provisioning with configured AP"""
2239     ssid = "wps"
2240     pinfile = "/tmp/ap_wps_pin_request_file.log"
2241     if os.path.exists(pinfile):
2242         os.remove(pinfile)
2243     hostapd.add_ap(apdev[0],
2244                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2245                      "wps_pin_requests": pinfile,
2246                      "wpa_passphrase": "12345678", "wpa": "2",
2247                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2248     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2249     uuid = dev[0].get_status_field("uuid")
2250     pin = dev[0].wps_read_pin()
2251     try:
2252         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2253         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2254         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2255         if ev is None:
2256             raise Exception("PIN needed event not shown")
2257         if uuid not in ev:
2258             raise Exception("UUID mismatch")
2259         dev[0].request("WPS_CANCEL")
2260         success = False
2261         with open(pinfile, "r") as f:
2262             lines = f.readlines()
2263             for l in lines:
2264                 if uuid in l:
2265                     success = True
2266                     break
2267         if not success:
2268             raise Exception("PIN request entry not in the log file")
2269     finally:
2270         try:
2271             os.remove(pinfile)
2272         except:
2273             pass
2274
2275 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2276     """WPS auto-setup with configuration file"""
2277     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2278     ifname = apdev[0]['ifname']
2279     try:
2280         with open(conffile, "w") as f:
2281             f.write("driver=nl80211\n")
2282             f.write("hw_mode=g\n")
2283             f.write("channel=1\n")
2284             f.write("ieee80211n=1\n")
2285             f.write("interface=%s\n" % ifname)
2286             f.write("ctrl_interface=/var/run/hostapd\n")
2287             f.write("ssid=wps\n")
2288             f.write("eap_server=1\n")
2289             f.write("wps_state=1\n")
2290         hostapd.add_bss('phy3', ifname, conffile)
2291         hapd = hostapd.Hostapd(ifname)
2292         hapd.request("WPS_PBC")
2293         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2294         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2295         dev[0].wait_connected(timeout=30)
2296         with open(conffile, "r") as f:
2297             lines = f.read().splitlines()
2298             vals = dict()
2299             for l in lines:
2300                 try:
2301                     [name,value] = l.split('=', 1)
2302                     vals[name] = value
2303                 except ValueError, e:
2304                     if "# WPS configuration" in l:
2305                         pass
2306                     else:
2307                         raise Exception("Unexpected configuration line: " + l)
2308         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2309             raise Exception("Incorrect configuration: " + str(vals))
2310     finally:
2311         try:
2312             os.remove(conffile)
2313         except:
2314             pass
2315
2316 def test_ap_wps_pbc_timeout(dev, apdev, params):
2317     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2318     if not params['long']:
2319         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2320     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2321     hapd = add_ssdp_ap(apdev[0], ap_uuid)
2322
2323     location = ssdp_get_location(ap_uuid)
2324     urls = upnp_get_urls(location)
2325     eventurl = urlparse.urlparse(urls['event_sub_url'])
2326     ctrlurl = urlparse.urlparse(urls['control_url'])
2327
2328     url = urlparse.urlparse(location)
2329     conn = httplib.HTTPConnection(url.netloc)
2330
2331     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2332         def handle(self):
2333             data = self.rfile.readline().strip()
2334             logger.debug(data)
2335             self.wfile.write(gen_wps_event())
2336
2337     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2338     server.timeout = 1
2339
2340     headers = { "callback": '<http://127.0.0.1:12345/event>',
2341                 "NT": "upnp:event",
2342                 "timeout": "Second-1234" }
2343     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2344     resp = conn.getresponse()
2345     if resp.status != 200:
2346         raise Exception("Unexpected HTTP response: %d" % resp.status)
2347     sid = resp.getheader("sid")
2348     logger.debug("Subscription SID " + sid)
2349
2350     msg = '''<?xml version="1.0"?>
2351 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2352 <s:Body>
2353 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2354 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2355 VFi5hrLk
2356 </NewMessage>
2357 </u:SetSelectedRegistrar>
2358 </s:Body>
2359 </s:Envelope>'''
2360     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2361     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2362     conn.request("POST", ctrlurl.path, msg, headers)
2363     resp = conn.getresponse()
2364     if resp.status != 200:
2365         raise Exception("Unexpected HTTP response: %d" % resp.status)
2366
2367     server.handle_request()
2368
2369     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2370     if "OK" not in dev[0].request("WPS_PBC"):
2371         raise Exception("WPS_PBC failed")
2372
2373     start = os.times()[4]
2374
2375     server.handle_request()
2376     dev[1].request("BSS_FLUSH 0")
2377     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2378                         only_new=True)
2379     bss = dev[1].get_bss(apdev[0]['bssid'])
2380     logger.debug("BSS: " + str(bss))
2381     if '[WPS-AUTH]' not in bss['flags']:
2382         raise Exception("WPS not indicated authorized")
2383
2384     server.handle_request()
2385
2386     wps_timeout_seen = False
2387
2388     while True:
2389         hapd.dump_monitor()
2390         dev[1].dump_monitor()
2391         if not wps_timeout_seen:
2392             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2393             if ev is not None:
2394                 logger.info("PBC timeout seen")
2395                 wps_timeout_seen = True
2396         else:
2397             dev[0].dump_monitor()
2398         now = os.times()[4]
2399         if now - start > 130:
2400             raise Exception("Selected registration information not removed")
2401         dev[1].request("BSS_FLUSH 0")
2402         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2403                             only_new=True)
2404         bss = dev[1].get_bss(apdev[0]['bssid'])
2405         logger.debug("BSS: " + str(bss))
2406         if '[WPS-AUTH]' not in bss['flags']:
2407             break
2408         server.handle_request()
2409
2410     server.server_close()
2411
2412     if wps_timeout_seen:
2413         return
2414
2415     now = os.times()[4]
2416     if now < start + 150:
2417         dur = start + 150 - now
2418     else:
2419         dur = 1
2420     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2421     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2422     if ev is None:
2423         raise Exception("WPS-TIMEOUT not reported")
2424
2425 def add_ssdp_ap(ap, ap_uuid):
2426     ssid = "wps-ssdp"
2427     ap_pin = "12345670"
2428     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2429                "wpa_passphrase": "12345678", "wpa": "2",
2430                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2431                "device_name": "Wireless AP", "manufacturer": "Company",
2432                "model_name": "WAP", "model_number": "123",
2433                "serial_number": "12345", "device_type": "6-0050F204-1",
2434                "os_version": "01020300",
2435                "config_methods": "label push_button",
2436                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2437                "friendly_name": "WPS Access Point",
2438                "manufacturer_url": "http://www.example.com/",
2439                "model_description": "Wireless Access Point",
2440                "model_url": "http://www.example.com/model/",
2441                "upc": "123456789012" }
2442     return hostapd.add_ap(ap, params)
2443
2444 def ssdp_send(msg, no_recv=False):
2445     socket.setdefaulttimeout(1)
2446     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2447     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2448     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2449     sock.bind(("127.0.0.1", 0))
2450     sock.sendto(msg, ("239.255.255.250", 1900))
2451     if no_recv:
2452         return None
2453     return sock.recv(1000)
2454
2455 def ssdp_send_msearch(st, no_recv=False):
2456     msg = '\r\n'.join([
2457             'M-SEARCH * HTTP/1.1',
2458             'HOST: 239.255.255.250:1900',
2459             'MX: 1',
2460             'MAN: "ssdp:discover"',
2461             'ST: ' + st,
2462             '', ''])
2463     return ssdp_send(msg, no_recv=no_recv)
2464
2465 def test_ap_wps_ssdp_msearch(dev, apdev):
2466     """WPS AP and SSDP M-SEARCH messages"""
2467     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2468     add_ssdp_ap(apdev[0], ap_uuid)
2469
2470     msg = '\r\n'.join([
2471             'M-SEARCH * HTTP/1.1',
2472             'Host: 239.255.255.250:1900',
2473             'Mx: 1',
2474             'Man: "ssdp:discover"',
2475             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2476             '', ''])
2477     ssdp_send(msg)
2478
2479     msg = '\r\n'.join([
2480             'M-SEARCH * HTTP/1.1',
2481             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2482             'mx: \t1\t\t   ',
2483             'man: \t \t "ssdp:discover"   ',
2484             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2485             '', ''])
2486     ssdp_send(msg)
2487
2488     ssdp_send_msearch("ssdp:all")
2489     ssdp_send_msearch("upnp:rootdevice")
2490     ssdp_send_msearch("uuid:" + ap_uuid)
2491     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2492     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2493
2494     msg = '\r\n'.join([
2495             'M-SEARCH * HTTP/1.1',
2496             'HOST:\t239.255.255.250:1900',
2497             'MAN: "ssdp:discover"',
2498             'MX: 130',
2499             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2500             '', ''])
2501     ssdp_send(msg, no_recv=True)
2502
2503 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2504     """WPS AP and invalid SSDP M-SEARCH messages"""
2505     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2506     add_ssdp_ap(apdev[0], ap_uuid)
2507
2508     socket.setdefaulttimeout(1)
2509     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2510     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2511     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2512     sock.bind(("127.0.0.1", 0))
2513
2514     logger.debug("Missing MX")
2515     msg = '\r\n'.join([
2516             'M-SEARCH * HTTP/1.1',
2517             'HOST: 239.255.255.250:1900',
2518             'MAN: "ssdp:discover"',
2519             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2520             '', ''])
2521     sock.sendto(msg, ("239.255.255.250", 1900))
2522
2523     logger.debug("Negative MX")
2524     msg = '\r\n'.join([
2525             'M-SEARCH * HTTP/1.1',
2526             'HOST: 239.255.255.250:1900',
2527             'MX: -1',
2528             'MAN: "ssdp:discover"',
2529             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2530             '', ''])
2531     sock.sendto(msg, ("239.255.255.250", 1900))
2532
2533     logger.debug("Invalid MX")
2534     msg = '\r\n'.join([
2535             'M-SEARCH * HTTP/1.1',
2536             'HOST: 239.255.255.250:1900',
2537             'MX; 1',
2538             'MAN: "ssdp:discover"',
2539             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2540             '', ''])
2541     sock.sendto(msg, ("239.255.255.250", 1900))
2542
2543     logger.debug("Missing MAN")
2544     msg = '\r\n'.join([
2545             'M-SEARCH * HTTP/1.1',
2546             'HOST: 239.255.255.250:1900',
2547             'MX: 1',
2548             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2549             '', ''])
2550     sock.sendto(msg, ("239.255.255.250", 1900))
2551
2552     logger.debug("Invalid MAN")
2553     msg = '\r\n'.join([
2554             'M-SEARCH * HTTP/1.1',
2555             'HOST: 239.255.255.250:1900',
2556             'MX: 1',
2557             'MAN: foo',
2558             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2559             '', ''])
2560     sock.sendto(msg, ("239.255.255.250", 1900))
2561     msg = '\r\n'.join([
2562             'M-SEARCH * HTTP/1.1',
2563             'HOST: 239.255.255.250:1900',
2564             'MX: 1',
2565             'MAN; "ssdp:discover"',
2566             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2567             '', ''])
2568     sock.sendto(msg, ("239.255.255.250", 1900))
2569
2570     logger.debug("Missing HOST")
2571     msg = '\r\n'.join([
2572             'M-SEARCH * HTTP/1.1',
2573             'MAN: "ssdp:discover"',
2574             'MX: 1',
2575             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2576             '', ''])
2577     sock.sendto(msg, ("239.255.255.250", 1900))
2578
2579     logger.debug("Missing ST")
2580     msg = '\r\n'.join([
2581             'M-SEARCH * HTTP/1.1',
2582             'HOST: 239.255.255.250:1900',
2583             'MAN: "ssdp:discover"',
2584             'MX: 1',
2585             '', ''])
2586     sock.sendto(msg, ("239.255.255.250", 1900))
2587
2588     logger.debug("Mismatching ST")
2589     msg = '\r\n'.join([
2590             'M-SEARCH * HTTP/1.1',
2591             'HOST: 239.255.255.250:1900',
2592             'MAN: "ssdp:discover"',
2593             'MX: 1',
2594             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2595             '', ''])
2596     sock.sendto(msg, ("239.255.255.250", 1900))
2597     msg = '\r\n'.join([
2598             'M-SEARCH * HTTP/1.1',
2599             'HOST: 239.255.255.250:1900',
2600             'MAN: "ssdp:discover"',
2601             'MX: 1',
2602             'ST: foo:bar',
2603             '', ''])
2604     sock.sendto(msg, ("239.255.255.250", 1900))
2605     msg = '\r\n'.join([
2606             'M-SEARCH * HTTP/1.1',
2607             'HOST: 239.255.255.250:1900',
2608             'MAN: "ssdp:discover"',
2609             'MX: 1',
2610             'ST: foobar',
2611             '', ''])
2612     sock.sendto(msg, ("239.255.255.250", 1900))
2613
2614     logger.debug("Invalid ST")
2615     msg = '\r\n'.join([
2616             'M-SEARCH * HTTP/1.1',
2617             'HOST: 239.255.255.250:1900',
2618             'MAN: "ssdp:discover"',
2619             'MX: 1',
2620             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2621             '', ''])
2622     sock.sendto(msg, ("239.255.255.250", 1900))
2623
2624     logger.debug("Invalid M-SEARCH")
2625     msg = '\r\n'.join([
2626             'M+SEARCH * HTTP/1.1',
2627             'HOST: 239.255.255.250:1900',
2628             'MAN: "ssdp:discover"',
2629             'MX: 1',
2630             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2631             '', ''])
2632     sock.sendto(msg, ("239.255.255.250", 1900))
2633     msg = '\r\n'.join([
2634             'M-SEARCH-* HTTP/1.1',
2635             'HOST: 239.255.255.250:1900',
2636             'MAN: "ssdp:discover"',
2637             'MX: 1',
2638             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2639             '', ''])
2640     sock.sendto(msg, ("239.255.255.250", 1900))
2641
2642     logger.debug("Invalid message format")
2643     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2644     msg = '\r'.join([
2645             'M-SEARCH * HTTP/1.1',
2646             'HOST: 239.255.255.250:1900',
2647             'MAN: "ssdp:discover"',
2648             'MX: 1',
2649             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2650             '', ''])
2651     sock.sendto(msg, ("239.255.255.250", 1900))
2652
2653     try:
2654         r = sock.recv(1000)
2655         raise Exception("Unexpected M-SEARCH response: " + r)
2656     except socket.timeout:
2657         pass
2658
2659     logger.debug("Valid M-SEARCH")
2660     msg = '\r\n'.join([
2661             'M-SEARCH * HTTP/1.1',
2662             'HOST: 239.255.255.250:1900',
2663             'MAN: "ssdp:discover"',
2664             'MX: 1',
2665             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2666             '', ''])
2667     sock.sendto(msg, ("239.255.255.250", 1900))
2668
2669     try:
2670         r = sock.recv(1000)
2671         pass
2672     except socket.timeout:
2673         raise Exception("No SSDP response")
2674
2675 def test_ap_wps_ssdp_burst(dev, apdev):
2676     """WPS AP and SSDP burst"""
2677     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2678     add_ssdp_ap(apdev[0], ap_uuid)
2679
2680     msg = '\r\n'.join([
2681             'M-SEARCH * HTTP/1.1',
2682             'HOST: 239.255.255.250:1900',
2683             'MAN: "ssdp:discover"',
2684             'MX: 1',
2685             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2686             '', ''])
2687     socket.setdefaulttimeout(1)
2688     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2689     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2690     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2691     sock.bind(("127.0.0.1", 0))
2692     for i in range(0, 25):
2693         sock.sendto(msg, ("239.255.255.250", 1900))
2694     resp = 0
2695     while True:
2696         try:
2697             r = sock.recv(1000)
2698             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2699                 raise Exception("Unexpected message: " + r)
2700             resp += 1
2701         except socket.timeout:
2702             break
2703     if resp < 20:
2704         raise Exception("Too few SSDP responses")
2705
2706     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2707     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2708     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2709     sock.bind(("127.0.0.1", 0))
2710     for i in range(0, 25):
2711         sock.sendto(msg, ("239.255.255.250", 1900))
2712     while True:
2713         try:
2714             r = sock.recv(1000)
2715             if ap_uuid in r:
2716                 break
2717         except socket.timeout:
2718             raise Exception("No SSDP response")
2719
2720 def ssdp_get_location(uuid):
2721     res = ssdp_send_msearch("uuid:" + uuid)
2722     location = None
2723     for l in res.splitlines():
2724         if l.lower().startswith("location:"):
2725             location = l.split(':', 1)[1].strip()
2726             break
2727     if location is None:
2728         raise Exception("No UPnP location found")
2729     return location
2730
2731 def upnp_get_urls(location):
2732     conn = urllib.urlopen(location)
2733     tree = ET.parse(conn)
2734     root = tree.getroot()
2735     urn = '{urn:schemas-upnp-org:device-1-0}'
2736     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2737     res = {}
2738     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2739     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2740     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2741     return res
2742
2743 def upnp_soap_action(conn, path, action, include_soap_action=True,
2744                      soap_action_override=None, newmsg=None, neweventtype=None,
2745                      neweventmac=None):
2746     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2747     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2748     ET.register_namespace('soapenv', soapns)
2749     ET.register_namespace('wfa', wpsns)
2750     attrib = {}
2751     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2752     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2753     body = ET.SubElement(root, "{%s}Body" % soapns)
2754     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2755     if newmsg:
2756         msg = ET.SubElement(act, "NewMessage")
2757         msg.text = base64.b64encode(newmsg)
2758     if neweventtype:
2759         msg = ET.SubElement(act, "NewWLANEventType")
2760         msg.text = neweventtype
2761     if neweventmac:
2762         msg = ET.SubElement(act, "NewWLANEventMAC")
2763         msg.text = neweventmac
2764     tree = ET.ElementTree(root)
2765     soap = StringIO.StringIO()
2766     tree.write(soap, xml_declaration=True, encoding='utf-8')
2767
2768     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2769     if include_soap_action:
2770         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2771     elif soap_action_override:
2772         headers["SOAPAction"] = soap_action_override
2773     conn.request("POST", path, soap.getvalue(), headers)
2774     return conn.getresponse()
2775
2776 def test_ap_wps_upnp(dev, apdev):
2777     """WPS AP and UPnP operations"""
2778     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2779     add_ssdp_ap(apdev[0], ap_uuid)
2780
2781     location = ssdp_get_location(ap_uuid)
2782     urls = upnp_get_urls(location)
2783
2784     conn = urllib.urlopen(urls['scpd_url'])
2785     scpd = conn.read()
2786
2787     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2788     if conn.getcode() != 404:
2789         raise Exception("Unexpected HTTP response to GET unknown URL")
2790
2791     url = urlparse.urlparse(location)
2792     conn = httplib.HTTPConnection(url.netloc)
2793     #conn.set_debuglevel(1)
2794     headers = { "Content-type": 'text/xml; charset="utf-8"',
2795                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2796     conn.request("POST", "hello", "\r\n\r\n", headers)
2797     resp = conn.getresponse()
2798     if resp.status != 404:
2799         raise Exception("Unexpected HTTP response: %d" % resp.status)
2800
2801     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2802     resp = conn.getresponse()
2803     if resp.status != 501:
2804         raise Exception("Unexpected HTTP response: %d" % resp.status)
2805
2806     headers = { "Content-type": 'text/xml; charset="utf-8"',
2807                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2808     ctrlurl = urlparse.urlparse(urls['control_url'])
2809     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2810     resp = conn.getresponse()
2811     if resp.status != 401:
2812         raise Exception("Unexpected HTTP response: %d" % resp.status)
2813
2814     logger.debug("GetDeviceInfo without SOAPAction header")
2815     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2816                             include_soap_action=False)
2817     if resp.status != 401:
2818         raise Exception("Unexpected HTTP response: %d" % resp.status)
2819
2820     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2821     for act in [ "foo",
2822                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2823                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2824                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2825         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2826                                 include_soap_action=False,
2827                                 soap_action_override=act)
2828         if resp.status != 401:
2829             raise Exception("Unexpected HTTP response: %d" % resp.status)
2830
2831     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2832     if resp.status != 200:
2833         raise Exception("Unexpected HTTP response: %d" % resp.status)
2834     dev = resp.read()
2835     if "NewDeviceInfo" not in dev:
2836         raise Exception("Unexpected GetDeviceInfo response")
2837
2838     logger.debug("PutMessage without required parameters")
2839     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2840     if resp.status != 600:
2841         raise Exception("Unexpected HTTP response: %d" % resp.status)
2842
2843     logger.debug("PutWLANResponse without required parameters")
2844     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2845     if resp.status != 600:
2846         raise Exception("Unexpected HTTP response: %d" % resp.status)
2847
2848     logger.debug("SetSelectedRegistrar from unregistered ER")
2849     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2850     if resp.status != 501:
2851         raise Exception("Unexpected HTTP response: %d" % resp.status)
2852
2853     logger.debug("Unknown action")
2854     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2855     if resp.status != 401:
2856         raise Exception("Unexpected HTTP response: %d" % resp.status)
2857
2858 def test_ap_wps_upnp_subscribe(dev, apdev):
2859     """WPS AP and UPnP event subscription"""
2860     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2861     hapd = add_ssdp_ap(apdev[0], ap_uuid)
2862
2863     location = ssdp_get_location(ap_uuid)
2864     urls = upnp_get_urls(location)
2865     eventurl = urlparse.urlparse(urls['event_sub_url'])
2866
2867     url = urlparse.urlparse(location)
2868     conn = httplib.HTTPConnection(url.netloc)
2869     #conn.set_debuglevel(1)
2870     headers = { "callback": '<http://127.0.0.1:12345/event>',
2871                 "timeout": "Second-1234" }
2872     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2873     resp = conn.getresponse()
2874     if resp.status != 412:
2875         raise Exception("Unexpected HTTP response: %d" % resp.status)
2876
2877     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2878     resp = conn.getresponse()
2879     if resp.status != 412:
2880         raise Exception("Unexpected HTTP response: %d" % resp.status)
2881
2882     headers = { "NT": "upnp:event",
2883                 "timeout": "Second-1234" }
2884     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2885     resp = conn.getresponse()
2886     if resp.status != 412:
2887         raise Exception("Unexpected HTTP response: %d" % resp.status)
2888
2889     headers = { "callback": '<http://127.0.0.1:12345/event>',
2890                 "NT": "upnp:foobar",
2891                 "timeout": "Second-1234" }
2892     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2893     resp = conn.getresponse()
2894     if resp.status != 400:
2895         raise Exception("Unexpected HTTP response: %d" % resp.status)
2896
2897     logger.debug("Valid subscription")
2898     headers = { "callback": '<http://127.0.0.1:12345/event>',
2899                 "NT": "upnp:event",
2900                 "timeout": "Second-1234" }
2901     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2902     resp = conn.getresponse()
2903     if resp.status != 200:
2904         raise Exception("Unexpected HTTP response: %d" % resp.status)
2905     sid = resp.getheader("sid")
2906     logger.debug("Subscription SID " + sid)
2907
2908     logger.debug("Invalid re-subscription")
2909     headers = { "NT": "upnp:event",
2910                 "sid": "123456734567854",
2911                 "timeout": "Second-1234" }
2912     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2913     resp = conn.getresponse()
2914     if resp.status != 400:
2915         raise Exception("Unexpected HTTP response: %d" % resp.status)
2916
2917     logger.debug("Invalid re-subscription")
2918     headers = { "NT": "upnp:event",
2919                 "sid": "uuid:123456734567854",
2920                 "timeout": "Second-1234" }
2921     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2922     resp = conn.getresponse()
2923     if resp.status != 400:
2924         raise Exception("Unexpected HTTP response: %d" % resp.status)
2925
2926     logger.debug("Invalid re-subscription")
2927     headers = { "callback": '<http://127.0.0.1:12345/event>',
2928                 "NT": "upnp:event",
2929                 "sid": sid,
2930                 "timeout": "Second-1234" }
2931     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2932     resp = conn.getresponse()
2933     if resp.status != 400:
2934         raise Exception("Unexpected HTTP response: %d" % resp.status)
2935
2936     logger.debug("SID mismatch in re-subscription")
2937     headers = { "NT": "upnp:event",
2938                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2939                 "timeout": "Second-1234" }
2940     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2941     resp = conn.getresponse()
2942     if resp.status != 412:
2943         raise Exception("Unexpected HTTP response: %d" % resp.status)
2944
2945     logger.debug("Valid re-subscription")
2946     headers = { "NT": "upnp:event",
2947                 "sid": sid,
2948                 "timeout": "Second-1234" }
2949     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2950     resp = conn.getresponse()
2951     if resp.status != 200:
2952         raise Exception("Unexpected HTTP response: %d" % resp.status)
2953     sid2 = resp.getheader("sid")
2954     logger.debug("Subscription SID " + sid2)
2955
2956     if sid != sid2:
2957         raise Exception("Unexpected SID change")
2958
2959     logger.debug("Valid re-subscription")
2960     headers = { "NT": "upnp:event",
2961                 "sid": "uuid: \t \t" + sid.split(':')[1],
2962                 "timeout": "Second-1234" }
2963     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2964     resp = conn.getresponse()
2965     if resp.status != 200:
2966         raise Exception("Unexpected HTTP response: %d" % resp.status)
2967
2968     logger.debug("Invalid unsubscription")
2969     headers = { "sid": sid }
2970     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2971     resp = conn.getresponse()
2972     if resp.status != 412:
2973         raise Exception("Unexpected HTTP response: %d" % resp.status)
2974     headers = { "foo": "bar" }
2975     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2976     resp = conn.getresponse()
2977     if resp.status != 412:
2978         raise Exception("Unexpected HTTP response: %d" % resp.status)
2979
2980     logger.debug("Valid unsubscription")
2981     headers = { "sid": sid }
2982     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2983     resp = conn.getresponse()
2984     if resp.status != 200:
2985         raise Exception("Unexpected HTTP response: %d" % resp.status)
2986
2987     logger.debug("Unsubscription for not existing SID")
2988     headers = { "sid": sid }
2989     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2990     resp = conn.getresponse()
2991     if resp.status != 412:
2992         raise Exception("Unexpected HTTP response: %d" % resp.status)
2993
2994     logger.debug("Invalid unsubscription")
2995     headers = { "sid": " \t \tfoo" }
2996     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2997     resp = conn.getresponse()
2998     if resp.status != 400:
2999         raise Exception("Unexpected HTTP response: %d" % resp.status)
3000
3001     logger.debug("Invalid unsubscription")
3002     headers = { "sid": "uuid:\t \tfoo" }
3003     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3004     resp = conn.getresponse()
3005     if resp.status != 400:
3006         raise Exception("Unexpected HTTP response: %d" % resp.status)
3007
3008     logger.debug("Invalid unsubscription")
3009     headers = { "NT": "upnp:event",
3010                 "sid": sid }
3011     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3012     resp = conn.getresponse()
3013     if resp.status != 400:
3014         raise Exception("Unexpected HTTP response: %d" % resp.status)
3015     headers = { "callback": '<http://127.0.0.1:12345/event>',
3016                 "sid": sid }
3017     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3018     resp = conn.getresponse()
3019     if resp.status != 400:
3020         raise Exception("Unexpected HTTP response: %d" % resp.status)
3021
3022     logger.debug("Valid subscription with multiple callbacks")
3023     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>',
3024                 "NT": "upnp:event",
3025                 "timeout": "Second-1234" }
3026     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3027     resp = conn.getresponse()
3028     if resp.status != 200:
3029         raise Exception("Unexpected HTTP response: %d" % resp.status)
3030     sid = resp.getheader("sid")
3031     logger.debug("Subscription SID " + sid)
3032
3033     # Force subscription to be deleted due to errors
3034     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3035     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3036     with alloc_fail(hapd, 1, "event_build_message"):
3037         for i in range(10):
3038             dev[1].dump_monitor()
3039             dev[2].dump_monitor()
3040             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3041             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3042             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3043             dev[1].request("WPS_CANCEL")
3044             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3045             dev[2].request("WPS_CANCEL")
3046             if i % 4 == 1:
3047                 time.sleep(1)
3048             else:
3049                 time.sleep(0.1)
3050     time.sleep(0.2)
3051
3052     headers = { "sid": sid }
3053     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
3054     resp = conn.getresponse()
3055     if resp.status != 200 and resp.status != 412:
3056         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
3057
3058     headers = { "callback": '<http://127.0.0.1:12345/event>',
3059                 "NT": "upnp:event",
3060                 "timeout": "Second-1234" }
3061     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
3062         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3063         resp = conn.getresponse()
3064         if resp.status != 200:
3065             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
3066         sid = resp.getheader("sid")
3067         logger.debug("Subscription SID " + sid)
3068
3069     headers = { "sid": sid }
3070     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3071     resp = conn.getresponse()
3072     if resp.status != 200:
3073         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
3074
3075     headers = { "callback": '<http://127.0.0.1:12345/event>',
3076                 "NT": "upnp:event",
3077                 "timeout": "Second-1234" }
3078     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3079     resp = conn.getresponse()
3080     if resp.status != 200:
3081         raise Exception("Unexpected HTTP response: %d" % resp.status)
3082     sid = resp.getheader("sid")
3083     logger.debug("Subscription SID " + sid)
3084
3085     with alloc_fail(hapd, 1, "=event_add"):
3086         for i in range(2):
3087             dev[1].dump_monitor()
3088             dev[2].dump_monitor()
3089             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3090             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3091             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3092             dev[1].request("WPS_CANCEL")
3093             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3094             dev[2].request("WPS_CANCEL")
3095             if i == 0:
3096                 time.sleep(1)
3097             else:
3098                 time.sleep(0.1)
3099
3100     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3101     resp = conn.getresponse()
3102     if resp.status != 200:
3103         raise Exception("Unexpected HTTP response: %d" % resp.status)
3104
3105     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
3106         dev[1].dump_monitor()
3107         dev[2].dump_monitor()
3108         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3109         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3110         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3111         dev[1].request("WPS_CANCEL")
3112         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3113         dev[2].request("WPS_CANCEL")
3114         time.sleep(0.1)
3115
3116     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
3117         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3118         resp = conn.getresponse()
3119         if resp.status != 500:
3120             raise Exception("Unexpected HTTP response: %d" % resp.status)
3121
3122     with alloc_fail(hapd, 1, "=subscription_start"):
3123         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3124         resp = conn.getresponse()
3125         if resp.status != 500:
3126             raise Exception("Unexpected HTTP response: %d" % resp.status)
3127
3128     headers = { "callback": '',
3129                 "NT": "upnp:event",
3130                 "timeout": "Second-1234" }
3131     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3132     resp = conn.getresponse()
3133     if resp.status != 500:
3134         raise Exception("Unexpected HTTP response: %d" % resp.status)
3135
3136     headers = { "callback": ' <',
3137                 "NT": "upnp:event",
3138                 "timeout": "Second-1234" }
3139     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3140     resp = conn.getresponse()
3141     if resp.status != 500:
3142         raise Exception("Unexpected HTTP response: %d" % resp.status)
3143
3144     headers = { "callback": '<http://127.0.0.1:12345/event>',
3145                 "NT": "upnp:event",
3146                 "timeout": "Second-1234" }
3147     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
3148         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3149         resp = conn.getresponse()
3150         if resp.status != 500:
3151             raise Exception("Unexpected HTTP response: %d" % resp.status)
3152
3153     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
3154         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3155         resp = conn.getresponse()
3156         if resp.status != 500:
3157             raise Exception("Unexpected HTTP response: %d" % resp.status)
3158
3159     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
3160         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3161         resp = conn.getresponse()
3162         if resp.status != 500:
3163             raise Exception("Unexpected HTTP response: %d" % resp.status)
3164
3165     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
3166         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3167         resp = conn.getresponse()
3168         if resp.status != 500:
3169             raise Exception("Unexpected HTTP response: %d" % resp.status)
3170
3171     for i in range(6):
3172         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
3173                     "NT": "upnp:event",
3174                     "timeout": "Second-1234" }
3175         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3176         resp = conn.getresponse()
3177         if resp.status != 200:
3178             raise Exception("Unexpected HTTP response: %d" % resp.status)
3179
3180     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
3181         dev[1].dump_monitor()
3182         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3183         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3184         dev[1].request("WPS_CANCEL")
3185         time.sleep(0.1)
3186
3187     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
3188         dev[1].dump_monitor()
3189         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3190         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3191         dev[1].request("WPS_CANCEL")
3192         time.sleep(0.1)
3193
3194     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
3195         dev[1].dump_monitor()
3196         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3197         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3198         dev[1].request("WPS_CANCEL")
3199         time.sleep(0.1)
3200
3201     hapd.disable()
3202     with alloc_fail(hapd, 1, "get_netif_info"):
3203         if "FAIL" not in hapd.request("ENABLE"):
3204             raise Exception("ENABLE succeeded during OOM")
3205
3206 def test_ap_wps_upnp_subscribe_events(dev, apdev):
3207     """WPS AP and UPnP event subscription and many events"""
3208     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3209     hapd = add_ssdp_ap(apdev[0], ap_uuid)
3210
3211     location = ssdp_get_location(ap_uuid)
3212     urls = upnp_get_urls(location)
3213     eventurl = urlparse.urlparse(urls['event_sub_url'])
3214
3215     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
3216         def handle(self):
3217             data = self.rfile.readline().strip()
3218             logger.debug(data)
3219             self.wfile.write(gen_wps_event())
3220
3221     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
3222     server.timeout = 1
3223
3224     url = urlparse.urlparse(location)
3225     conn = httplib.HTTPConnection(url.netloc)
3226
3227     headers = { "callback": '<http://127.0.0.1:12345/event>',
3228                 "NT": "upnp:event",
3229                 "timeout": "Second-1234" }
3230     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3231     resp = conn.getresponse()
3232     if resp.status != 200:
3233         raise Exception("Unexpected HTTP response: %d" % resp.status)
3234     sid = resp.getheader("sid")
3235     logger.debug("Subscription SID " + sid)
3236
3237     # Fetch the first event message
3238     server.handle_request()
3239
3240     # Force subscription event queue to reach the maximum length by generating
3241     # new proxied events without the ER fetching any of the pending events.
3242     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3243     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3244     for i in range(16):
3245         dev[1].dump_monitor()
3246         dev[2].dump_monitor()
3247         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3248         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3249         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3250         dev[1].request("WPS_CANCEL")
3251         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3252         dev[2].request("WPS_CANCEL")
3253         if i % 4 == 1:
3254             time.sleep(1)
3255         else:
3256             time.sleep(0.1)
3257
3258     hapd.request("WPS_PIN any 12345670")
3259     dev[1].dump_monitor()
3260     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3261     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3262     if ev is None:
3263         raise Exception("WPS success not reported")
3264
3265     # Close the WPS ER HTTP server without fetching all the pending events.
3266     # This tests hostapd code path that clears subscription and the remaining
3267     # event queue when the interface is deinitialized.
3268     server.handle_request()
3269     server.server_close()
3270
3271     dev[1].wait_connected()
3272
3273 def test_ap_wps_upnp_http_proto(dev, apdev):
3274     """WPS AP and UPnP/HTTP protocol testing"""
3275     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3276     add_ssdp_ap(apdev[0], ap_uuid)
3277
3278     location = ssdp_get_location(ap_uuid)
3279
3280     url = urlparse.urlparse(location)
3281     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3282     #conn.set_debuglevel(1)
3283
3284     conn.request("HEAD", "hello")
3285     resp = conn.getresponse()
3286     if resp.status != 501:
3287         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3288     conn.close()
3289
3290     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3291         try:
3292             conn.request(cmd, "hello")
3293             resp = conn.getresponse()
3294         except Exception, e:
3295             pass
3296         conn.close()
3297
3298     headers = { "Content-Length": 'abc' }
3299     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3300     try:
3301         resp = conn.getresponse()
3302     except Exception, e:
3303         pass
3304     conn.close()
3305
3306     headers = { "Content-Length": '-10' }
3307     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3308     try:
3309         resp = conn.getresponse()
3310     except Exception, e:
3311         pass
3312     conn.close()
3313
3314     headers = { "Content-Length": '10000000000000' }
3315     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3316     try:
3317         resp = conn.getresponse()
3318     except Exception, e:
3319         pass
3320     conn.close()
3321
3322     headers = { "Transfer-Encoding": 'abc' }
3323     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3324     resp = conn.getresponse()
3325     if resp.status != 501:
3326         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3327     conn.close()
3328
3329     headers = { "Transfer-Encoding": 'chunked' }
3330     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3331     resp = conn.getresponse()
3332     if resp.status != 501:
3333         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3334     conn.close()
3335
3336     # Too long a header
3337     conn.request("HEAD", 5000 * 'A')
3338     try:
3339         resp = conn.getresponse()
3340     except Exception, e:
3341         pass
3342     conn.close()
3343
3344     # Long URL but within header length limits
3345     conn.request("HEAD", 3000 * 'A')
3346     resp = conn.getresponse()
3347     if resp.status != 501:
3348         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3349     conn.close()
3350
3351     headers = { "Content-Length": '20' }
3352     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3353     try:
3354         resp = conn.getresponse()
3355     except Exception, e:
3356         pass
3357     conn.close()
3358
3359     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3360     resp = conn.getresponse()
3361     if resp.status != 404:
3362         raise Exception("Unexpected HTTP response: %d" % resp.status)
3363     conn.close()
3364
3365     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3366     try:
3367         resp = conn.getresponse()
3368     except Exception, e:
3369         pass
3370     conn.close()
3371
3372 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3373     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3374     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3375     add_ssdp_ap(apdev[0], ap_uuid)
3376
3377     location = ssdp_get_location(ap_uuid)
3378
3379     url = urlparse.urlparse(location)
3380     conn = httplib.HTTPConnection(url.netloc)
3381     #conn.set_debuglevel(1)
3382
3383     headers = { "Transfer-Encoding": 'chunked' }
3384     conn.request("POST", "hello",
3385                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3386                  headers)
3387     resp = conn.getresponse()
3388     if resp.status != 404:
3389         raise Exception("Unexpected HTTP response: %d" % resp.status)
3390     conn.close()
3391
3392     conn.putrequest("POST", "hello")
3393     conn.putheader('Transfer-Encoding', 'chunked')
3394     conn.endheaders()
3395     conn.send("a\r\nabcdefghij\r\n")
3396     time.sleep(0.1)
3397     conn.send("2\r\nkl\r\n")
3398     conn.send("0\r\n\r\n")
3399     resp = conn.getresponse()
3400     if resp.status != 404:
3401         raise Exception("Unexpected HTTP response: %d" % resp.status)
3402     conn.close()
3403
3404     conn.putrequest("POST", "hello")
3405     conn.putheader('Transfer-Encoding', 'chunked')
3406     conn.endheaders()
3407     completed = False
3408     try:
3409         for i in range(20000):
3410             conn.send("1\r\nZ\r\n")
3411         conn.send("0\r\n\r\n")
3412         resp = conn.getresponse()
3413         completed = True
3414     except Exception, e:
3415         pass
3416     conn.close()
3417     if completed:
3418         raise Exception("Too long chunked request did not result in connection reset")
3419
3420     headers = { "Transfer-Encoding": 'chunked' }
3421     conn.request("POST", "hello", "80000000\r\na", headers)
3422     try:
3423         resp = conn.getresponse()
3424     except Exception, e:
3425         pass
3426     conn.close()
3427
3428     conn.request("POST", "hello", "10000000\r\na", headers)
3429     try:
3430         resp = conn.getresponse()
3431     except Exception, e:
3432         pass
3433     conn.close()
3434
3435 def test_ap_wps_disabled(dev, apdev):
3436     """WPS operations while WPS is disabled"""
3437     ssid = "test-wps-disabled"
3438     hostapd.add_ap(apdev[0], { "ssid": ssid })
3439     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3440     if "FAIL" not in hapd.request("WPS_PBC"):
3441         raise Exception("WPS_PBC succeeded unexpectedly")
3442     if "FAIL" not in hapd.request("WPS_CANCEL"):
3443         raise Exception("WPS_CANCEL succeeded unexpectedly")
3444
3445 def test_ap_wps_mixed_cred(dev, apdev):
3446     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3447     ssid = "test-wps-wep"
3448     hostapd.add_ap(apdev[0],
3449                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3450                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
3451     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3452     hapd.request("WPS_PBC")
3453     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3454     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3455     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3456     if ev is None:
3457         raise Exception("WPS-SUCCESS event timed out")
3458     nets = dev[0].list_networks()
3459     if len(nets) != 1:
3460         raise Exception("Unexpected number of network blocks")
3461     id = nets[0]['id']
3462     proto = dev[0].get_network(id, "proto")
3463     if proto != "WPA RSN":
3464         raise Exception("Unexpected merged proto field value: " + proto)
3465     pairwise = dev[0].get_network(id, "pairwise")
3466     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3467         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3468
3469 def test_ap_wps_while_connected(dev, apdev):
3470     """WPS PBC provisioning while connected to another AP"""
3471     ssid = "test-wps-conf"
3472     hostapd.add_ap(apdev[0],
3473                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3474                      "wpa_passphrase": "12345678", "wpa": "2",
3475                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3476     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3477
3478     hostapd.add_ap(apdev[1], { "ssid": "open" })
3479     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3480
3481     logger.info("WPS provisioning step")
3482     hapd.request("WPS_PBC")
3483     dev[0].dump_monitor()
3484     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3485     dev[0].wait_connected(timeout=30)
3486     status = dev[0].get_status()
3487     if status['bssid'] != apdev[0]['bssid']:
3488         raise Exception("Unexpected BSSID")
3489
3490 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3491     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3492     ssid = "test-wps-conf"
3493     hostapd.add_ap(apdev[0],
3494                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3495                      "wpa_passphrase": "12345678", "wpa": "2",
3496                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3497     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3498
3499     hostapd.add_ap(apdev[1], { "ssid": "open" })
3500
3501     try:
3502         dev[0].request("STA_AUTOCONNECT 0")
3503         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3504
3505         logger.info("WPS provisioning step")
3506         hapd.request("WPS_PBC")
3507         dev[0].dump_monitor()
3508         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3509         dev[0].wait_connected(timeout=30)
3510         status = dev[0].get_status()
3511         if status['bssid'] != apdev[0]['bssid']:
3512             raise Exception("Unexpected BSSID")
3513     finally:
3514         dev[0].request("STA_AUTOCONNECT 1")
3515
3516 def test_ap_wps_from_event(dev, apdev):
3517     """WPS PBC event on AP to enable PBC"""
3518     ssid = "test-wps-conf"
3519     hapd = hostapd.add_ap(apdev[0],
3520                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3521                             "wpa_passphrase": "12345678", "wpa": "2",
3522                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3523     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3524     dev[0].dump_monitor()
3525     hapd.dump_monitor()
3526     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3527
3528     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3529     if ev is None:
3530         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3531     vals = ev.split(' ')
3532     if vals[1] != dev[0].p2p_interface_addr():
3533         raise Exception("Unexpected enrollee address: " + vals[1])
3534     if vals[5] != '4':
3535         raise Exception("Unexpected Device Password Id: " + vals[5])
3536     hapd.request("WPS_PBC")
3537     dev[0].wait_connected(timeout=30)
3538
3539 def test_ap_wps_ap_scan_2(dev, apdev):
3540     """AP_SCAN 2 for WPS"""
3541     ssid = "test-wps-conf"
3542     hapd = hostapd.add_ap(apdev[0],
3543                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3544                             "wpa_passphrase": "12345678", "wpa": "2",
3545                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3546     hapd.request("WPS_PBC")
3547
3548     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3549     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3550     wpas.dump_monitor()
3551
3552     if "OK" not in wpas.request("AP_SCAN 2"):
3553         raise Exception("Failed to set AP_SCAN 2")
3554
3555     wpas.flush_scan_cache()
3556     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3557     wpas.dump_monitor()
3558     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3559     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3560     if ev is None:
3561         raise Exception("WPS-SUCCESS event timed out")
3562     wpas.wait_connected(timeout=30)
3563     wpas.dump_monitor()
3564     wpas.request("DISCONNECT")
3565     wpas.request("BSS_FLUSH 0")
3566     wpas.dump_monitor()
3567     wpas.request("REASSOCIATE")
3568     wpas.wait_connected(timeout=30)
3569     wpas.dump_monitor()
3570
3571 def test_ap_wps_eapol_workaround(dev, apdev):
3572     """EAPOL workaround code path for 802.1X header length mismatch"""
3573     ssid = "test-wps"
3574     hostapd.add_ap(apdev[0],
3575                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3576     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3577     bssid = apdev[0]['bssid']
3578     hapd.request("SET ext_eapol_frame_io 1")
3579     dev[0].request("SET ext_eapol_frame_io 1")
3580     hapd.request("WPS_PBC")
3581     dev[0].request("WPS_PBC")
3582
3583     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3584     if ev is None:
3585         raise Exception("Timeout on EAPOL-TX from hostapd")
3586
3587     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3588     if "OK" not in res:
3589         raise Exception("EAPOL_RX to wpa_supplicant failed")
3590
3591 def test_ap_wps_iteration(dev, apdev):
3592     """WPS PIN and iterate through APs without selected registrar"""
3593     ssid = "test-wps-conf"
3594     hapd = hostapd.add_ap(apdev[0],
3595                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3596                             "wpa_passphrase": "12345678", "wpa": "2",
3597                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3598
3599     ssid2 = "test-wps-conf2"
3600     hapd2 = hostapd.add_ap(apdev[1],
3601                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3602                              "wpa_passphrase": "12345678", "wpa": "2",
3603                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3604
3605     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3606     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3607     dev[0].dump_monitor()
3608     pin = dev[0].request("WPS_PIN any")
3609
3610     # Wait for iteration through all WPS APs to happen before enabling any
3611     # Registrar.
3612     for i in range(2):
3613         ev = dev[0].wait_event(["Associated with"], timeout=30)
3614         if ev is None:
3615             raise Exception("No association seen")
3616         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3617         if ev is None:
3618             raise Exception("No M2D from AP")
3619         dev[0].wait_disconnected()
3620
3621     # Verify that each AP requested PIN
3622     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3623     if ev is None:
3624         raise Exception("No WPS-PIN-NEEDED event from AP")
3625     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3626     if ev is None:
3627         raise Exception("No WPS-PIN-NEEDED event from AP2")
3628
3629     # Provide PIN to one of the APs and verify that connection gets formed
3630     hapd.request("WPS_PIN any " + pin)
3631     dev[0].wait_connected(timeout=30)
3632
3633 def test_ap_wps_iteration_error(dev, apdev):
3634     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3635     ssid = "test-wps-conf-pin"
3636     hapd = hostapd.add_ap(apdev[0],
3637                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3638                             "wpa_passphrase": "12345678", "wpa": "2",
3639                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3640                             "wps_independent": "1" })
3641     hapd.request("SET ext_eapol_frame_io 1")
3642     bssid = apdev[0]['bssid']
3643     pin = dev[0].wps_read_pin()
3644     dev[0].request("WPS_PIN any " + pin)
3645
3646     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3647     if ev is None:
3648         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3649     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3650
3651     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3652     if ev is None:
3653         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3654     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3655     if ev is None:
3656         raise Exception("No CTRL-EVENT-EAP-STARTED")
3657
3658     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3659     # a case with an incorrectly behaving WPS AP.
3660
3661     # Start the real target AP and activate registrar on it.
3662     hapd2 = hostapd.add_ap(apdev[1],
3663                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3664                             "wpa_passphrase": "12345678", "wpa": "2",
3665                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3666                             "wps_independent": "1" })
3667     hapd2.request("WPS_PIN any " + pin)
3668
3669     dev[0].wait_disconnected(timeout=15)
3670     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3671     if ev is None:
3672         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3673     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3674     if ev is None:
3675         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3676     dev[0].wait_connected(timeout=15)
3677
3678 def test_ap_wps_priority(dev, apdev):
3679     """WPS PIN provisioning with configured AP and wps_priority"""
3680     ssid = "test-wps-conf-pin"
3681     hostapd.add_ap(apdev[0],
3682                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3683                      "wpa_passphrase": "12345678", "wpa": "2",
3684                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3685     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3686     logger.info("WPS provisioning step")
3687     pin = dev[0].wps_read_pin()
3688     hapd.request("WPS_PIN any " + pin)
3689     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3690     dev[0].dump_monitor()
3691     try:
3692         dev[0].request("SET wps_priority 6")
3693         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3694         dev[0].wait_connected(timeout=30)
3695         netw = dev[0].list_networks()
3696         prio = dev[0].get_network(netw[0]['id'], 'priority')
3697         if prio != '6':
3698             raise Exception("Unexpected network priority: " + prio)
3699     finally:
3700         dev[0].request("SET wps_priority 0")
3701
3702 def test_ap_wps_and_non_wps(dev, apdev):
3703     """WPS and non-WPS AP in single hostapd process"""
3704     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3705     hapd = hostapd.add_ap(apdev[0], params)
3706
3707     params = { "ssid": "no wps" }
3708     hapd2 = hostapd.add_ap(apdev[1], params)
3709
3710     appin = hapd.request("WPS_AP_PIN random")
3711     if "FAIL" in appin:
3712         raise Exception("Could not generate random AP PIN")
3713     if appin not in hapd.request("WPS_AP_PIN get"):
3714         raise Exception("Could not fetch current AP PIN")
3715
3716     if "FAIL" in hapd.request("WPS_PBC"):
3717         raise Exception("WPS_PBC failed")
3718     if "FAIL" in hapd.request("WPS_CANCEL"):
3719         raise Exception("WPS_CANCEL failed")
3720
3721 def test_ap_wps_init_oom(dev, apdev):
3722     """Initial AP configuration and OOM during PSK generation"""
3723     ssid = "test-wps"
3724     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3725     hapd = hostapd.add_ap(apdev[0], params)
3726
3727     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3728         pin = dev[0].wps_read_pin()
3729         hapd.request("WPS_PIN any " + pin)
3730         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3731         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3732         dev[0].wait_disconnected()
3733
3734     hapd.request("WPS_PIN any " + pin)
3735     dev[0].wait_connected(timeout=30)
3736
3737 def test_ap_wps_er_oom(dev, apdev):
3738     """WPS ER OOM in XML processing"""
3739     try:
3740         _test_ap_wps_er_oom(dev, apdev)
3741     finally:
3742         dev[0].request("WPS_ER_STOP")
3743         dev[1].request("WPS_CANCEL")
3744         dev[0].request("DISCONNECT")
3745
3746 def _test_ap_wps_er_oom(dev, apdev):
3747     ssid = "wps-er-ap-config"
3748     ap_pin = "12345670"
3749     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3750     hostapd.add_ap(apdev[0],
3751                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3752                      "wpa_passphrase": "12345678", "wpa": "2",
3753                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3754                      "device_name": "Wireless AP", "manufacturer": "Company",
3755                      "model_name": "WAP", "model_number": "123",
3756                      "serial_number": "12345", "device_type": "6-0050F204-1",
3757                      "os_version": "01020300",
3758                      "config_methods": "label push_button",
3759                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3760
3761     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3762
3763     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3764         dev[0].request("WPS_ER_START ifname=lo")
3765         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3766         if ev is not None:
3767             raise Exception("Unexpected AP discovery")
3768
3769     dev[0].request("WPS_ER_STOP")
3770     dev[0].request("WPS_ER_START ifname=lo")
3771     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3772     if ev is None:
3773         raise Exception("AP discovery timed out")
3774
3775     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3776     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3777         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3778         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3779         if ev is None:
3780             raise Exception("PBC scan failed")
3781         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3782         if ev is None:
3783             raise Exception("Enrollee discovery timed out")
3784
3785 def test_ap_wps_er_init_oom(dev, apdev):
3786     """WPS ER and OOM during init"""
3787     try:
3788         _test_ap_wps_er_init_oom(dev, apdev)
3789     finally:
3790         dev[0].request("WPS_ER_STOP")
3791
3792 def _test_ap_wps_er_init_oom(dev, apdev):
3793     with alloc_fail(dev[0], 1, "wps_er_init"):
3794         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3795             raise Exception("WPS_ER_START succeeded during OOM")
3796     with alloc_fail(dev[0], 1, "http_server_init"):
3797         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3798             raise Exception("WPS_ER_START succeeded during OOM")
3799     with alloc_fail(dev[0], 2, "http_server_init"):
3800         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3801             raise Exception("WPS_ER_START succeeded during OOM")
3802     with alloc_fail(dev[0], 1, "eloop_sock_table_add_sock;?eloop_register_sock;wps_er_ssdp_init"):
3803         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3804             raise Exception("WPS_ER_START succeeded during OOM")
3805     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3806         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3807             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3808
3809 def test_ap_wps_er_init_fail(dev, apdev):
3810     """WPS ER init failure"""
3811     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3812         dev[0].request("WPS_ER_STOP")
3813         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3814
3815 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3816     """WPS events and wpa_cli action script"""
3817     logdir = os.path.abspath(test_params['logdir'])
3818     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3819     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3820     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3821
3822     with open(actionfile, 'w') as f:
3823         f.write('#!/bin/sh\n')
3824         f.write('echo $* >> %s\n' % logfile)
3825         # Kill the process and wait some time before returning to allow all the
3826         # pending events to be processed with some of this happening after the
3827         # eloop SIGALRM signal has been scheduled.
3828         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3829
3830     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3831              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3832
3833     ssid = "test-wps-conf"
3834     hostapd.add_ap(apdev[0],
3835                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3836                      "wpa_passphrase": "12345678", "wpa": "2",
3837                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3838     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3839
3840     prg = os.path.join(test_params['logdir'],
3841                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3842     if not os.path.exists(prg):
3843         prg = '../../wpa_supplicant/wpa_cli'
3844     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3845     subprocess.call(arg)
3846
3847     arg = [ 'ps', 'ax' ]
3848     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3849     out = cmd.communicate()[0]
3850     cmd.wait()
3851     logger.debug("Processes:\n" + out)
3852     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3853         raise Exception("Did not see wpa_cli running")
3854
3855     hapd.request("WPS_PIN any 12345670")
3856     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3857     dev[0].dump_monitor()
3858     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3859     dev[0].wait_connected(timeout=30)
3860
3861     for i in range(30):
3862         if not os.path.exists(pidfile):
3863             break
3864         time.sleep(0.1)
3865
3866     if not os.path.exists(logfile):
3867         raise Exception("wpa_cli action results file not found")
3868     with open(logfile, 'r') as f:
3869         res = f.read()
3870     if "WPS-SUCCESS" not in res:
3871         raise Exception("WPS-SUCCESS event not seen in action file")
3872
3873     arg = [ 'ps', 'ax' ]
3874     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3875     out = cmd.communicate()[0]
3876     cmd.wait()
3877     logger.debug("Remaining processes:\n" + out)
3878     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3879         raise Exception("wpa_cli still running")
3880
3881     if os.path.exists(pidfile):
3882         raise Exception("PID file not removed")
3883
3884 def test_ap_wps_er_ssdp_proto(dev, apdev):
3885     """WPS ER SSDP protocol testing"""
3886     try:
3887         _test_ap_wps_er_ssdp_proto(dev, apdev)
3888     finally:
3889         dev[0].request("WPS_ER_STOP")
3890
3891 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3892     socket.setdefaulttimeout(1)
3893     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3894     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3895     sock.bind(("239.255.255.250", 1900))
3896     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3897         raise Exception("Invalid filter accepted")
3898     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3899         raise Exception("WPS_ER_START with filter failed")
3900     (msg,addr) = sock.recvfrom(1000)
3901     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3902     if "M-SEARCH" not in msg:
3903         raise Exception("Not an M-SEARCH")
3904     sock.sendto("FOO", addr)
3905     time.sleep(0.1)
3906     dev[0].request("WPS_ER_STOP")
3907
3908     dev[0].request("WPS_ER_START ifname=lo")
3909     (msg,addr) = sock.recvfrom(1000)
3910     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3911     if "M-SEARCH" not in msg:
3912         raise Exception("Not an M-SEARCH")
3913     sock.sendto("FOO", addr)
3914     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3915     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3916     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3917     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3918     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3919     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3920     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3921     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3922     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3923     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3924     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3925     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)
3926     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3927     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3928         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)
3929         time.sleep(0.1)
3930     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3931         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)
3932         time.sleep(0.1)
3933
3934     # Add an AP with bogus URL
3935     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)
3936     # Update timeout on AP without updating URL
3937     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)
3938     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3939     if ev is None:
3940         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3941
3942     # Add an AP with a valid URL (but no server listing to it)
3943     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)
3944     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3945     if ev is None:
3946         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3947
3948     sock.close()
3949
3950 wps_event_url = None
3951
3952 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3953                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3954     payload = '''<?xml version="1.0"?>
3955 <root xmlns="urn:schemas-upnp-org:device-1-0">
3956 <specVersion>
3957 <major>1</major>
3958 <minor>0</minor>
3959 </specVersion>
3960 <device>
3961 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3962 <friendlyName>WPS Access Point</friendlyName>
3963 <manufacturer>Company</manufacturer>
3964 <modelName>WAP</modelName>
3965 <modelNumber>123</modelNumber>
3966 <serialNumber>12345</serialNumber>
3967 '''
3968     if udn:
3969         payload += '<UDN>' + udn + '</UDN>'
3970     payload += '''<serviceList>
3971 <service>
3972 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3973 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3974 <SCPDURL>wps_scpd.xml</SCPDURL>
3975 '''
3976     if controlURL:
3977         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3978     if eventSubURL:
3979         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3980     payload += '''</service>
3981 </serviceList>
3982 </device>
3983 </root>
3984 '''
3985     hdr = 'HTTP/1.1 200 OK\r\n' + \
3986           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3987           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3988           'Connection: close\r\n' + \
3989           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3990           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3991     return hdr + payload
3992
3993 def gen_wps_control(payload_override=None):
3994     payload = '''<?xml version="1.0"?>
3995 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3996 <s:Body>
3997 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3998 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3999 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
4000 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
4001 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
4002 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
4003 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
4004 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
4005 AAYANyoAASA=
4006 </NewDeviceInfo>
4007 </u:GetDeviceInfoResponse>
4008 </s:Body>
4009 </s:Envelope>
4010 '''
4011     if payload_override:
4012         payload = payload_override
4013     hdr = 'HTTP/1.1 200 OK\r\n' + \
4014           'Content-Type: text/xml; charset="utf-8"\r\n' + \
4015           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4016           'Connection: close\r\n' + \
4017           'Content-Length: ' + str(len(payload)) + '\r\n' + \
4018           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4019     return hdr + payload
4020
4021 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
4022     payload = ""
4023     hdr = 'HTTP/1.1 200 OK\r\n' + \
4024           'Content-Type: text/xml; charset="utf-8"\r\n' + \
4025           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4026           'Connection: close\r\n' + \
4027           'Content-Length: ' + str(len(payload)) + '\r\n'
4028     if sid:
4029         hdr += 'SID: ' + sid + '\r\n'
4030     hdr += 'Timeout: Second-1801\r\n' + \
4031           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4032     return hdr + payload
4033
4034 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
4035     def handle(self):
4036         data = self.rfile.readline().strip()
4037         logger.info("HTTP server received: " + data)
4038         while True:
4039             hdr = self.rfile.readline().strip()
4040             if len(hdr) == 0:
4041                 break
4042             logger.info("HTTP header: " + hdr)
4043             if "CALLBACK:" in hdr:
4044                 global wps_event_url
4045                 wps_event_url = hdr.split(' ')[1].strip('<>')
4046
4047         if "GET /foo.xml" in data:
4048             self.handle_upnp_info()
4049         elif "POST /wps_control" in data:
4050             self.handle_wps_control()
4051         elif "SUBSCRIBE /wps_event" in data:
4052             self.handle_wps_event()
4053         else:
4054             self.handle_others(data)
4055
4056     def handle_upnp_info(self):
4057         self.wfile.write(gen_upnp_info())
4058
4059     def handle_wps_control(self):
4060         self.wfile.write(gen_wps_control())
4061
4062     def handle_wps_event(self):
4063         self.wfile.write(gen_wps_event())
4064
4065     def handle_others(self, data):
4066         logger.info("Ignore HTTP request: " + data)
4067
4068 class MyTCPServer(SocketServer.TCPServer):
4069     def __init__(self, addr, handler):
4070         self.allow_reuse_address = True
4071         SocketServer.TCPServer.__init__(self, addr, handler)
4072
4073 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
4074                  location_url=None):
4075     socket.setdefaulttimeout(1)
4076     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4077     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4078     sock.bind(("239.255.255.250", 1900))
4079     dev.request("WPS_ER_START ifname=lo")
4080     for i in range(100):
4081         (msg,addr) = sock.recvfrom(1000)
4082         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4083         if "M-SEARCH" in msg:
4084             break
4085         if not wait_m_search:
4086             raise Exception("Not an M-SEARCH")
4087         if i == 99:
4088             raise Exception("No M-SEARCH seen")
4089
4090     # Add an AP with a valid URL and server listing to it
4091     server = MyTCPServer(("127.0.0.1", 12345), http_server)
4092     if not location_url:
4093         location_url = 'http://127.0.0.1:12345/foo.xml'
4094     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)
4095     server.timeout = 1
4096     return server,sock
4097
4098 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
4099     sock.close()
4100     server.server_close()
4101
4102     if on_alloc_fail:
4103         done = False
4104         for i in range(50):
4105             res = dev.request("GET_ALLOC_FAIL")
4106             if res.startswith("0:"):
4107                 done = True
4108                 break
4109             time.sleep(0.1)
4110         if not done:
4111             raise Exception("No allocation failure reported")
4112     else:
4113         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
4114         if ev is None:
4115             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
4116     dev.request("WPS_ER_STOP")
4117
4118 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
4119     try:
4120         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4121         server,sock = wps_er_start(dev, handler, location_url=location_url)
4122         global wps_event_url
4123         wps_event_url = None
4124         server.handle_request()
4125         server.handle_request()
4126         server.handle_request()
4127         server.server_close()
4128         if no_event_url:
4129             if wps_event_url:
4130                 raise Exception("Received event URL unexpectedly")
4131             return
4132         if wps_event_url is None:
4133             raise Exception("Did not get event URL")
4134         logger.info("Event URL: " + wps_event_url)
4135     finally:
4136             dev.request("WPS_ER_STOP")
4137
4138 def send_wlanevent(url, uuid, data, no_response=False):
4139     conn = httplib.HTTPConnection(url.netloc)
4140     payload = '''<?xml version="1.0" encoding="utf-8"?>
4141 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4142 <e:property><STAStatus>1</STAStatus></e:property>
4143 <e:property><APStatus>1</APStatus></e:property>
4144 <e:property><WLANEvent>'''
4145     payload += base64.b64encode(data)
4146     payload += '</WLANEvent></e:property></e:propertyset>'
4147     headers = { "Content-type": 'text/xml; charset="utf-8"',
4148                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4149                 "HOST": url.netloc,
4150                 "NT": "upnp:event",
4151                 "SID": "uuid:" + uuid,
4152                 "SEQ": "0",
4153                 "Content-Length": str(len(payload)) }
4154     conn.request("NOTIFY", url.path, payload, headers)
4155     if no_response:
4156         try:
4157             conn.getresponse()
4158         except Exception, e:
4159             pass
4160         return
4161     resp = conn.getresponse()
4162     if resp.status != 200:
4163         raise Exception("Unexpected HTTP response: %d" % resp.status)
4164
4165 def test_ap_wps_er_http_proto(dev, apdev):
4166     """WPS ER HTTP protocol testing"""
4167     try:
4168         _test_ap_wps_er_http_proto(dev, apdev)
4169     finally:
4170         dev[0].request("WPS_ER_STOP")
4171
4172 def _test_ap_wps_er_http_proto(dev, apdev):
4173     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4174     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
4175     global wps_event_url
4176     wps_event_url = None
4177     server.handle_request()
4178     server.handle_request()
4179     server.handle_request()
4180     server.server_close()
4181     if wps_event_url is None:
4182         raise Exception("Did not get event URL")
4183     logger.info("Event URL: " + wps_event_url)
4184
4185     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
4186     if ev is None:
4187         raise Exception("No WPS-ER-AP-ADD event")
4188     if uuid not in ev:
4189         raise Exception("UUID mismatch")
4190
4191     sock.close()
4192
4193     logger.info("Valid Probe Request notification")
4194     url = urlparse.urlparse(wps_event_url)
4195     conn = httplib.HTTPConnection(url.netloc)
4196     payload = '''<?xml version="1.0" encoding="utf-8"?>
4197 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4198 <e:property><STAStatus>1</STAStatus></e:property>
4199 <e:property><APStatus>1</APStatus></e:property>
4200 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
4201 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
4202 RGV2aWNlIEEQSQAGADcqAAEg
4203 </WLANEvent></e:property>
4204 </e:propertyset>
4205 '''
4206     headers = { "Content-type": 'text/xml; charset="utf-8"',
4207                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4208                 "HOST": url.netloc,
4209                 "NT": "upnp:event",
4210                 "SID": "uuid:" + uuid,
4211                 "SEQ": "0",
4212                 "Content-Length": str(len(payload)) }
4213     conn.request("NOTIFY", url.path, payload, headers)
4214     resp = conn.getresponse()
4215     if resp.status != 200:
4216         raise Exception("Unexpected HTTP response: %d" % resp.status)
4217
4218     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
4219     if ev is None:
4220         raise Exception("No WPS-ER-ENROLLEE-ADD event")
4221     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
4222         raise Exception("No Enrollee UUID match")
4223
4224     logger.info("Incorrect event URL AP id")
4225     conn = httplib.HTTPConnection(url.netloc)
4226     conn.request("NOTIFY", url.path + '123', payload, headers)
4227     resp = conn.getresponse()
4228     if resp.status != 404:
4229         raise Exception("Unexpected HTTP response: %d" % resp.status)
4230
4231     logger.info("Missing AP id")
4232     conn = httplib.HTTPConnection(url.netloc)
4233     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4234                  payload, headers)
4235     time.sleep(0.1)
4236
4237     logger.info("Incorrect event URL event id")
4238     conn = httplib.HTTPConnection(url.netloc)
4239     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4240     time.sleep(0.1)
4241
4242     logger.info("Incorrect event URL prefix")
4243     conn = httplib.HTTPConnection(url.netloc)
4244     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4245     resp = conn.getresponse()
4246     if resp.status != 404:
4247         raise Exception("Unexpected HTTP response: %d" % resp.status)
4248
4249     logger.info("Unsupported request")
4250     conn = httplib.HTTPConnection(url.netloc)
4251     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4252     resp = conn.getresponse()
4253     if resp.status != 501:
4254         raise Exception("Unexpected HTTP response: %d" % resp.status)
4255
4256     logger.info("Unsupported request and OOM")
4257     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4258         conn = httplib.HTTPConnection(url.netloc)
4259         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4260         time.sleep(0.5)
4261
4262     logger.info("Too short WLANEvent")
4263     data = '\x00'
4264     send_wlanevent(url, uuid, data)
4265
4266     logger.info("Invalid WLANEventMAC")
4267     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4268     send_wlanevent(url, uuid, data)
4269
4270     logger.info("Unknown WLANEventType")
4271     data = '\xff02:00:00:00:00:00'
4272     send_wlanevent(url, uuid, data)
4273
4274     logger.info("Probe Request notification without any attributes")
4275     data = '\x0102:00:00:00:00:00'
4276     send_wlanevent(url, uuid, data)
4277
4278     logger.info("Probe Request notification with invalid attribute")
4279     data = '\x0102:00:00:00:00:00\xff'
4280     send_wlanevent(url, uuid, data)
4281
4282     logger.info("EAP message without any attributes")
4283     data = '\x0202:00:00:00:00:00'
4284     send_wlanevent(url, uuid, data)
4285
4286     logger.info("EAP message with invalid attribute")
4287     data = '\x0202:00:00:00:00:00\xff'
4288     send_wlanevent(url, uuid, data)
4289
4290     logger.info("EAP message from new STA and not M1")
4291     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4292     send_wlanevent(url, uuid, data)
4293
4294     logger.info("EAP message: M1")
4295     data = '\x0202:00:00:00:00:00'
4296     data += '\x10\x22\x00\x01\x04'
4297     data += '\x10\x47\x00\x10' + 16*'\x00'
4298     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4299     data += '\x10\x1a\x00\x10' + 16*'\x00'
4300     data += '\x10\x32\x00\xc0' + 192*'\x00'
4301     data += '\x10\x04\x00\x02\x00\x00'
4302     data += '\x10\x10\x00\x02\x00\x00'
4303     data += '\x10\x0d\x00\x01\x00'
4304     data += '\x10\x08\x00\x02\x00\x00'
4305     data += '\x10\x44\x00\x01\x00'
4306     data += '\x10\x21\x00\x00'
4307     data += '\x10\x23\x00\x00'
4308     data += '\x10\x24\x00\x00'
4309     data += '\x10\x42\x00\x00'
4310     data += '\x10\x54\x00\x08' + 8*'\x00'
4311     data += '\x10\x11\x00\x00'
4312     data += '\x10\x3c\x00\x01\x00'
4313     data += '\x10\x02\x00\x02\x00\x00'
4314     data += '\x10\x12\x00\x02\x00\x00'
4315     data += '\x10\x09\x00\x02\x00\x00'
4316     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4317     m1 = data
4318     send_wlanevent(url, uuid, data)
4319
4320     logger.info("EAP message: WSC_ACK")
4321     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4322     send_wlanevent(url, uuid, data)
4323
4324     logger.info("EAP message: M1")
4325     send_wlanevent(url, uuid, m1)
4326
4327     logger.info("EAP message: WSC_NACK")
4328     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4329     send_wlanevent(url, uuid, data)
4330
4331     logger.info("EAP message: M1 - Too long attribute values")
4332     data = '\x0202:00:00:00:00:00'
4333     data += '\x10\x11\x00\x21' + 33*'\x00'
4334     data += '\x10\x45\x00\x21' + 33*'\x00'
4335     data += '\x10\x42\x00\x21' + 33*'\x00'
4336     data += '\x10\x24\x00\x21' + 33*'\x00'
4337     data += '\x10\x23\x00\x21' + 33*'\x00'
4338     data += '\x10\x21\x00\x41' + 65*'\x00'
4339     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4340     send_wlanevent(url, uuid, data)
4341
4342     logger.info("EAP message: M1 missing UUID-E")
4343     data = '\x0202:00:00:00:00:00'
4344     data += '\x10\x22\x00\x01\x04'
4345     send_wlanevent(url, uuid, data)
4346
4347     logger.info("EAP message: M1 missing MAC Address")
4348     data += '\x10\x47\x00\x10' + 16*'\x00'
4349     send_wlanevent(url, uuid, data)
4350
4351     logger.info("EAP message: M1 missing Enrollee Nonce")
4352     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4353     send_wlanevent(url, uuid, data)
4354
4355     logger.info("EAP message: M1 missing Public Key")
4356     data += '\x10\x1a\x00\x10' + 16*'\x00'
4357     send_wlanevent(url, uuid, data)
4358
4359     logger.info("EAP message: M1 missing Authentication Type flags")
4360     data += '\x10\x32\x00\xc0' + 192*'\x00'
4361     send_wlanevent(url, uuid, data)
4362
4363     logger.info("EAP message: M1 missing Encryption Type Flags")
4364     data += '\x10\x04\x00\x02\x00\x00'
4365     send_wlanevent(url, uuid, data)
4366
4367     logger.info("EAP message: M1 missing Connection Type flags")
4368     data += '\x10\x10\x00\x02\x00\x00'
4369     send_wlanevent(url, uuid, data)
4370
4371     logger.info("EAP message: M1 missing Config Methods")
4372     data += '\x10\x0d\x00\x01\x00'
4373     send_wlanevent(url, uuid, data)
4374
4375     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4376     data += '\x10\x08\x00\x02\x00\x00'
4377     send_wlanevent(url, uuid, data)
4378
4379     logger.info("EAP message: M1 missing Manufacturer")
4380     data += '\x10\x44\x00\x01\x00'
4381     send_wlanevent(url, uuid, data)
4382
4383     logger.info("EAP message: M1 missing Model Name")
4384     data += '\x10\x21\x00\x00'
4385     send_wlanevent(url, uuid, data)
4386
4387     logger.info("EAP message: M1 missing Model Number")
4388     data += '\x10\x23\x00\x00'
4389     send_wlanevent(url, uuid, data)
4390
4391     logger.info("EAP message: M1 missing Serial Number")
4392     data += '\x10\x24\x00\x00'
4393     send_wlanevent(url, uuid, data)
4394
4395     logger.info("EAP message: M1 missing Primary Device Type")
4396     data += '\x10\x42\x00\x00'
4397     send_wlanevent(url, uuid, data)
4398
4399     logger.info("EAP message: M1 missing Device Name")
4400     data += '\x10\x54\x00\x08' + 8*'\x00'
4401     send_wlanevent(url, uuid, data)
4402
4403     logger.info("EAP message: M1 missing RF Bands")
4404     data += '\x10\x11\x00\x00'
4405     send_wlanevent(url, uuid, data)
4406
4407     logger.info("EAP message: M1 missing Association State")
4408     data += '\x10\x3c\x00\x01\x00'
4409     send_wlanevent(url, uuid, data)
4410
4411     logger.info("EAP message: M1 missing Device Password ID")
4412     data += '\x10\x02\x00\x02\x00\x00'
4413     send_wlanevent(url, uuid, data)
4414
4415     logger.info("EAP message: M1 missing Configuration Error")
4416     data += '\x10\x12\x00\x02\x00\x00'
4417     send_wlanevent(url, uuid, data)
4418
4419     logger.info("EAP message: M1 missing OS Version")
4420     data += '\x10\x09\x00\x02\x00\x00'
4421     send_wlanevent(url, uuid, data)
4422
4423     logger.info("Check max concurrent requests")
4424     addr = (url.hostname, url.port)
4425     socks = {}
4426     for i in range(20):
4427         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4428                                  socket.IPPROTO_TCP)
4429         socks[i].connect(addr)
4430     for i in range(20):
4431         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4432     count = 0
4433     for i in range(20):
4434         try:
4435             res = socks[i].recv(100)
4436             if "HTTP/1" in res:
4437                 count += 1
4438         except:
4439             pass
4440         socks[i].close()
4441     logger.info("%d concurrent HTTP GET operations returned response" % count)
4442     if count < 10:
4443         raise Exception("Too few concurrent HTTP connections accepted")
4444
4445     logger.info("OOM in HTTP server")
4446     for func in [ "http_request_init", "httpread_create",
4447                   "eloop_register_timeout;httpread_create",
4448                   "eloop_sock_table_add_sock;?eloop_register_sock;httpread_create",
4449                   "httpread_hdr_analyze" ]:
4450         with alloc_fail(dev[0], 1, func):
4451             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4452                                  socket.IPPROTO_TCP)
4453             sock.connect(addr)
4454             sock.send("GET / HTTP/1.1\r\n\r\n")
4455             try:
4456                 sock.recv(100)
4457             except:
4458                 pass
4459             sock.close()
4460
4461     logger.info("Invalid HTTP header")
4462     for req in [ " GET / HTTP/1.1\r\n\r\n",
4463                  "HTTP/1.1 200 OK\r\n\r\n",
4464                  "HTTP/\r\n\r\n",
4465                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4466                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4467                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4468                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4469                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4470                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4471                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4472                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4473         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4474                              socket.IPPROTO_TCP)
4475         sock.settimeout(0.1)
4476         sock.connect(addr)
4477         sock.send(req)
4478         try:
4479             sock.recv(100)
4480         except:
4481             pass
4482         sock.close()
4483
4484     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4485         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4486                              socket.IPPROTO_TCP)
4487         sock.connect(addr)
4488         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4489         try:
4490             sock.recv(100)
4491         except:
4492             pass
4493         sock.close()
4494
4495     conn = httplib.HTTPConnection(url.netloc)
4496     payload = '<foo'
4497     headers = { "Content-type": 'text/xml; charset="utf-8"',
4498                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4499                 "HOST": url.netloc,
4500                 "NT": "upnp:event",
4501                 "SID": "uuid:" + uuid,
4502                 "SEQ": "0",
4503                 "Content-Length": str(len(payload)) }
4504     conn.request("NOTIFY", url.path, payload, headers)
4505     resp = conn.getresponse()
4506     if resp.status != 200:
4507         raise Exception("Unexpected HTTP response: %d" % resp.status)
4508
4509     conn = httplib.HTTPConnection(url.netloc)
4510     payload = '<WLANEvent foo></WLANEvent>'
4511     headers = { "Content-type": 'text/xml; charset="utf-8"',
4512                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4513                 "HOST": url.netloc,
4514                 "NT": "upnp:event",
4515                 "SID": "uuid:" + uuid,
4516                 "SEQ": "0",
4517                 "Content-Length": str(len(payload)) }
4518     conn.request("NOTIFY", url.path, payload, headers)
4519     resp = conn.getresponse()
4520     if resp.status != 200:
4521         raise Exception("Unexpected HTTP response: %d" % resp.status)
4522
4523     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4524         send_wlanevent(url, uuid, '')
4525
4526     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4527         send_wlanevent(url, uuid, 'foo')
4528
4529     for func in [ "wps_init",
4530                   "wps_process_manufacturer",
4531                   "wps_process_model_name",
4532                   "wps_process_model_number",
4533                   "wps_process_serial_number",
4534                   "wps_process_dev_name" ]:
4535         with alloc_fail(dev[0], 1, func):
4536             send_wlanevent(url, uuid, m1)
4537
4538     with alloc_fail(dev[0], 1, "wps_er_http_resp_ok"):
4539         send_wlanevent(url, uuid, m1, no_response=True)
4540
4541     with alloc_fail(dev[0], 1, "wps_er_http_resp_not_found"):
4542         url2 = urlparse.urlparse(wps_event_url.replace('/event/', '/notfound/'))
4543         send_wlanevent(url2, uuid, m1, no_response=True)
4544
4545     logger.info("EAP message: M1")
4546     data = '\x0202:11:22:00:00:00'
4547     data += '\x10\x22\x00\x01\x04'
4548     data += '\x10\x47\x00\x10' + 16*'\x00'
4549     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4550     data += '\x10\x1a\x00\x10' + 16*'\x00'
4551     data += '\x10\x32\x00\xc0' + 192*'\x00'
4552     data += '\x10\x04\x00\x02\x00\x00'
4553     data += '\x10\x10\x00\x02\x00\x00'
4554     data += '\x10\x0d\x00\x01\x00'
4555     data += '\x10\x08\x00\x02\x00\x00'
4556     data += '\x10\x44\x00\x01\x00'
4557     data += '\x10\x21\x00\x00'
4558     data += '\x10\x23\x00\x00'
4559     data += '\x10\x24\x00\x00'
4560     data += '\x10\x42\x00\x00'
4561     data += '\x10\x54\x00\x08' + 8*'\x00'
4562     data += '\x10\x11\x00\x00'
4563     data += '\x10\x3c\x00\x01\x00'
4564     data += '\x10\x02\x00\x02\x00\x00'
4565     data += '\x10\x12\x00\x02\x00\x00'
4566     data += '\x10\x09\x00\x02\x00\x00'
4567     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4568     dev[0].dump_monitor()
4569     with alloc_fail(dev[0], 1, "wps_er_add_sta_data"):
4570         send_wlanevent(url, uuid, data)
4571         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=0.1)
4572         if ev is not None:
4573             raise Exception("Unexpected enrollee add event")
4574     send_wlanevent(url, uuid, data)
4575     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=2)
4576     if ev is None:
4577         raise Exception("Enrollee add event not seen")
4578
4579     with alloc_fail(dev[0], 1, "base64_encode;wps_er_soap_hdr"):
4580         send_wlanevent(url, uuid, data)
4581
4582     with alloc_fail(dev[0], 1, "wpabuf_alloc;wps_er_soap_hdr"):
4583         send_wlanevent(url, uuid, data)
4584
4585     with alloc_fail(dev[0], 1, "http_client_url_parse;wps_er_sta_send_msg"):
4586         send_wlanevent(url, uuid, data)
4587
4588     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_sta_send_msg"):
4589         send_wlanevent(url, uuid, data)
4590
4591 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4592     """WPS ER HTTP protocol testing - no eventSubURL"""
4593     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4594         def handle_upnp_info(self):
4595             self.wfile.write(gen_upnp_info(eventSubURL=None))
4596     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4597                           no_event_url=True)
4598
4599 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4600     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4601     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4602         def handle_upnp_info(self):
4603             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4604     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4605                           no_event_url=True)
4606
4607 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4608     """WPS ER HTTP protocol testing - subscribe OOM"""
4609     try:
4610         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4611     finally:
4612         dev[0].request("WPS_ER_STOP")
4613
4614 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4615     tests = [ (1, "http_client_url_parse"),
4616               (1, "wpabuf_alloc;wps_er_subscribe"),
4617               (1, "http_client_addr"),
4618               (1, "eloop_sock_table_add_sock;?eloop_register_sock;http_client_addr"),
4619               (1, "eloop_register_timeout;http_client_addr") ]
4620     for count,func in tests:
4621         with alloc_fail(dev[0], count, func):
4622             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4623             server.handle_request()
4624             server.handle_request()
4625             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4626
4627 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4628     """WPS ER HTTP protocol testing - no SID"""
4629     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4630         def handle_wps_event(self):
4631             self.wfile.write(gen_wps_event(sid=None))
4632     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4633
4634 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4635     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4636     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4637         def handle_wps_event(self):
4638             self.wfile.write(gen_wps_event(sid='FOO'))
4639     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4640
4641 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4642     """WPS ER HTTP protocol testing - invalid SID UUID"""
4643     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4644         def handle_wps_event(self):
4645             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4646     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4647
4648 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4649     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4650     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4651         def handle_wps_event(self):
4652             payload = ""
4653             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4654                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4655                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4656                   'Connection: close\r\n' + \
4657                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4658                   'Timeout: Second-1801\r\n' + \
4659                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4660             self.wfile.write(hdr + payload)
4661     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4662
4663 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4664     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4665     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4666         def handle_wps_event(self):
4667             payload = ""
4668             hdr = 'HTTP/1.1 FOO\r\n' + \
4669                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4670                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4671                   'Connection: close\r\n' + \
4672                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4673                   'Timeout: Second-1801\r\n' + \
4674                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4675             self.wfile.write(hdr + payload)
4676     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4677
4678 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4679     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4680     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4681         def handle_wps_control(self):
4682             payload = '''<?xml version="1.0"?>
4683 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4684 <s:Body>
4685 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4686 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4687 </u:GetDeviceInfoResponse>
4688 </s:Body>
4689 </s:Envelope>
4690 '''
4691             self.wfile.write(gen_wps_control(payload_override=payload))
4692     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4693
4694 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4695     """WPS ER HTTP protocol testing - No device in UPnP info"""
4696     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4697         def handle_upnp_info(self):
4698             payload = '''<?xml version="1.0"?>
4699 <root xmlns="urn:schemas-upnp-org:device-1-0">
4700 <specVersion>
4701 <major>1</major>
4702 <minor>0</minor>
4703 </specVersion>
4704 </root>
4705 '''
4706             hdr = 'HTTP/1.1 200 OK\r\n' + \
4707                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4708                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4709                   'Connection: close\r\n' + \
4710                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4711                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4712             self.wfile.write(hdr + payload)
4713     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4714
4715 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4716     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4717     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4718         def handle_upnp_info(self):
4719             payload = '''<?xml version="1.0"?>
4720 <root xmlns="urn:schemas-upnp-org:device-1-0">
4721 <specVersion>
4722 <major>1</major>
4723 <minor>0</minor>
4724 </specVersion>
4725 <device>
4726 </device>
4727 </root>
4728 '''
4729             hdr = 'HTTP/1.1 200 OK\r\n' + \
4730                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4731                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4732                   'Connection: close\r\n' + \
4733                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4734                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4735             self.wfile.write(hdr + payload)
4736     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4737
4738 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4739     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4740     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4741         def handle_upnp_info(self):
4742             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4743     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4744
4745 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4746     """WPS ER HTTP protocol testing - no controlURL"""
4747     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4748         def handle_upnp_info(self):
4749             self.wfile.write(gen_upnp_info(controlURL=None))
4750     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4751                           no_event_url=True)
4752
4753 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4754     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4755     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4756         def handle_upnp_info(self):
4757             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4758     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4759                           no_event_url=True)
4760
4761 def test_ap_wps_http_timeout(dev, apdev):
4762     """WPS AP/ER and HTTP timeout"""
4763     try:
4764         _test_ap_wps_http_timeout(dev, apdev)
4765     finally:
4766         dev[0].request("WPS_ER_STOP")
4767
4768 def _test_ap_wps_http_timeout(dev, apdev):
4769     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4770     add_ssdp_ap(apdev[0], ap_uuid)
4771
4772     location = ssdp_get_location(ap_uuid)
4773     url = urlparse.urlparse(location)
4774     addr = (url.hostname, url.port)
4775     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4776     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4777                          socket.IPPROTO_TCP)
4778     sock.connect(addr)
4779     sock.send("G")
4780
4781     class DummyServer(SocketServer.StreamRequestHandler):
4782         def handle(self):
4783             logger.debug("DummyServer - start 31 sec wait")
4784             time.sleep(31)
4785             logger.debug("DummyServer - wait done")
4786
4787     logger.debug("Start WPS ER")
4788     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4789                                 wait_m_search=True)
4790
4791     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4792     # This will wait for 31 seconds..
4793     server.handle_request()
4794
4795     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4796     try:
4797         sock.send("ET / HTTP/1.1\r\n\r\n")
4798         res = sock.recv(100)
4799         sock.close()
4800     except:
4801         pass
4802
4803 def test_ap_wps_er_url_parse(dev, apdev):
4804     """WPS ER and URL parsing special cases"""
4805     try:
4806         _test_ap_wps_er_url_parse(dev, apdev)
4807     finally:
4808         dev[0].request("WPS_ER_STOP")
4809
4810 def _test_ap_wps_er_url_parse(dev, apdev):
4811     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4812     sock.settimeout(1)
4813     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4814     sock.bind(("239.255.255.250", 1900))
4815     dev[0].request("WPS_ER_START ifname=lo")
4816     (msg,addr) = sock.recvfrom(1000)
4817     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4818     if "M-SEARCH" not in msg:
4819         raise Exception("Not an M-SEARCH")
4820     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)
4821     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4822     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)
4823     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4824     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)
4825     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4826
4827     sock.close()
4828
4829 def test_ap_wps_er_link_update(dev, apdev):
4830     """WPS ER and link update special cases"""
4831     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4832         def handle_upnp_info(self):
4833             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4834     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4835
4836     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4837         def handle_others(self, data):
4838             if "GET / " in data:
4839                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4840     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4841                           location_url='http://127.0.0.1:12345')
4842
4843 def test_ap_wps_er_http_client(dev, apdev):
4844     """WPS ER and HTTP client special cases"""
4845     with alloc_fail(dev[0], 1, "http_link_update"):
4846         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4847
4848     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4849         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4850
4851     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4852         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4853
4854     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4855         def handle_upnp_info(self):
4856             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4857     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4858                           no_event_url=True)
4859
4860 def test_ap_wps_init_oom(dev, apdev):
4861     """wps_init OOM cases"""
4862     ssid = "test-wps"
4863     appin = "12345670"
4864     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4865                "ap_pin": appin }
4866     hapd = hostapd.add_ap(apdev[0], params)
4867     pin = dev[0].wps_read_pin()
4868
4869     with alloc_fail(hapd, 1, "wps_init"):
4870         hapd.request("WPS_PIN any " + pin)
4871         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4872         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4873         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4874         if ev is None:
4875             raise Exception("No EAP failure reported")
4876         dev[0].request("WPS_CANCEL")
4877
4878     with alloc_fail(dev[0], 2, "wps_init"):
4879         hapd.request("WPS_PIN any " + pin)
4880         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4881         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4882         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4883         if ev is None:
4884             raise Exception("No EAP failure reported")
4885         dev[0].request("WPS_CANCEL")
4886
4887     with alloc_fail(dev[0], 2, "wps_init"):
4888         hapd.request("WPS_PBC")
4889         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4890         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4891         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4892         if ev is None:
4893             raise Exception("No EAP failure reported")
4894         dev[0].request("WPS_CANCEL")
4895
4896     dev[0].dump_monitor()
4897     new_ssid = "wps-new-ssid"
4898     new_passphrase = "1234567890"
4899     with alloc_fail(dev[0], 3, "wps_init"):
4900         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4901                        new_passphrase, no_wait=True)
4902         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4903         if ev is None:
4904             raise Exception("No EAP failure reported")
4905
4906     dev[0].flush_scan_cache()
4907
4908 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4909     """WPS and invalid IE in Association Request frame"""
4910     ssid = "test-wps"
4911     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4912     hapd = hostapd.add_ap(apdev[0], params)
4913     pin = "12345670"
4914     hapd.request("WPS_PIN any " + pin)
4915     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4916     try:
4917         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4918         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4919         for i in range(5):
4920             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4921             if ev and "vendor=14122" in ev:
4922                 break
4923         if ev is None or "vendor=14122" not in ev:
4924             raise Exception("EAP-WSC not started")
4925         dev[0].request("WPS_CANCEL")
4926     finally:
4927         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4928
4929 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4930     """WPS PBC/PIN mismatch"""
4931     ssid = "test-wps"
4932     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4933     hapd = hostapd.add_ap(apdev[0], params)
4934     hapd.request("SET wps_version_number 0x10")
4935     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4936     hapd.request("WPS_PBC")
4937     pin = dev[0].wps_read_pin()
4938     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4939     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4940     if ev is None:
4941         raise Exception("Scan did not complete")
4942     dev[0].request("WPS_CANCEL")
4943
4944     hapd.request("WPS_CANCEL")
4945     dev[0].flush_scan_cache()
4946
4947 def test_ap_wps_ie_invalid(dev, apdev):
4948     """WPS PIN attempt with AP that has invalid WSC IE"""
4949     ssid = "test-wps"
4950     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4951                "vendor_elements": "dd050050f20410" }
4952     hapd = hostapd.add_ap(apdev[0], params)
4953     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4954     hostapd.add_ap(apdev[1], params)
4955     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4956     pin = dev[0].wps_read_pin()
4957     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4958     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4959     if ev is None:
4960         raise Exception("Scan did not complete")
4961     dev[0].request("WPS_CANCEL")
4962
4963 def test_ap_wps_scan_prio_order(dev, apdev):
4964     """WPS scan priority ordering"""
4965     ssid = "test-wps"
4966     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4967     hapd = hostapd.add_ap(apdev[0], params)
4968     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4969     hostapd.add_ap(apdev[1], params)
4970     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4971     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4972     pin = dev[0].wps_read_pin()
4973     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4974     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4975     if ev is None:
4976         raise Exception("Scan did not complete")
4977     dev[0].request("WPS_CANCEL")
4978
4979 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4980     """WPS ProbeReq IE OOM"""
4981     ssid = "test-wps"
4982     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4983     hapd = hostapd.add_ap(apdev[0], params)
4984     pin = dev[0].wps_read_pin()
4985     hapd.request("WPS_PIN any " + pin)
4986     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4987     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4988         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4989         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4990         if ev is None:
4991             raise Exception("Association not seen")
4992     dev[0].request("WPS_CANCEL")
4993     dev[0].wait_disconnected()
4994
4995     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4996         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4997         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4998         if ev is None:
4999             raise Exception("Association not seen")
5000     dev[0].request("WPS_CANCEL")
5001     hapd.disable()
5002     dev[0].request("REMOVE_NETWORK all")
5003     dev[0].wait_disconnected()
5004     time.sleep(0.2)
5005     dev[0].flush_scan_cache()
5006
5007 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
5008     """WPS AssocReq IE OOM"""
5009     ssid = "test-wps"
5010     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
5011     hapd = hostapd.add_ap(apdev[0], params)
5012     pin = dev[0].wps_read_pin()
5013     hapd.request("WPS_PIN any " + pin)
5014     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5015     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
5016         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
5017         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
5018         if ev is None:
5019             raise Exception("Association not seen")
5020     dev[0].request("WPS_CANCEL")
5021
5022 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
5023     """WPS AssocResp IE OOM"""
5024     ssid = "test-wps"
5025     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
5026     hapd = hostapd.add_ap(apdev[0], params)
5027     pin = dev[0].wps_read_pin()
5028     hapd.request("WPS_PIN any " + pin)
5029     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5030     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
5031         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
5032         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
5033         if ev is None:
5034             raise Exception("Association not seen")
5035     dev[0].request("WPS_CANCEL")
5036
5037 def test_ap_wps_bss_info_errors(dev, apdev):
5038     """WPS BSS info errors"""
5039     params = { "ssid": "1",
5040                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
5041     hostapd.add_ap(apdev[0], params)
5042     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
5043     hostapd.add_ap(apdev[1], params)
5044     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5045     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
5046     bss = dev[0].get_bss(apdev[0]['bssid'])
5047     logger.info("BSS: " + str(bss))
5048     if "wps_state" in bss:
5049         raise Exception("Unexpected wps_state in BSS info")
5050     if 'wps_device_name' not in bss:
5051         raise Exception("No wps_device_name in BSS info")
5052     if bss['wps_device_name'] != '_':
5053         raise Exception("Unexpected wps_device_name value")
5054     bss = dev[0].get_bss(apdev[1]['bssid'])
5055     logger.info("BSS: " + str(bss))
5056
5057     with alloc_fail(dev[0], 1, "=wps_attr_text"):
5058         bss = dev[0].get_bss(apdev[0]['bssid'])
5059         logger.info("BSS(OOM): " + str(bss))
5060
5061 def wps_run_pbc_fail_ap(apdev, dev, hapd):
5062     hapd.request("WPS_PBC")
5063     dev.scan_for_bss(apdev['bssid'], freq="2412")
5064     dev.request("WPS_PBC " + apdev['bssid'])
5065     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5066     if ev is None:
5067         raise Exception("No EAP failure reported")
5068     dev.request("WPS_CANCEL")
5069     dev.wait_disconnected()
5070     for i in range(5):
5071         try:
5072             dev.flush_scan_cache()
5073             break
5074         except Exception, e:
5075             if str(e).startswith("Failed to trigger scan"):
5076                 # Try again
5077                 time.sleep(1)
5078             else:
5079                 raise
5080
5081 def wps_run_pbc_fail(apdev, dev):
5082     hapd = wps_start_ap(apdev)
5083     wps_run_pbc_fail_ap(apdev, dev, hapd)
5084
5085 def test_ap_wps_pk_oom(dev, apdev):
5086     """WPS and public key OOM"""
5087     with alloc_fail(dev[0], 1, "wps_build_public_key"):
5088         wps_run_pbc_fail(apdev[0], dev[0])
5089
5090 def test_ap_wps_pk_oom_ap(dev, apdev):
5091     """WPS and public key OOM on AP"""
5092     hapd = wps_start_ap(apdev[0])
5093     with alloc_fail(hapd, 1, "wps_build_public_key"):
5094         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5095
5096 def test_ap_wps_encr_oom_ap(dev, apdev):
5097     """WPS and encrypted settings decryption OOM on AP"""
5098     hapd = wps_start_ap(apdev[0])
5099     pin = dev[0].wps_read_pin()
5100     hapd.request("WPS_PIN any " + pin)
5101     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5102     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
5103         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
5104         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
5105         if ev is None:
5106             raise Exception("No WPS-FAIL reported")
5107         dev[0].request("WPS_CANCEL")
5108     dev[0].wait_disconnected()
5109
5110 def test_ap_wps_encr_no_random_ap(dev, apdev):
5111     """WPS and no random data available for encryption on AP"""
5112     hapd = wps_start_ap(apdev[0])
5113     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
5114         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5115
5116 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
5117     """WPS and no random data available for e-hash on STA"""
5118     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
5119         wps_run_pbc_fail(apdev[0], dev[0])
5120
5121 def test_ap_wps_m1_no_random(dev, apdev):
5122     """WPS and no random for M1 on STA"""
5123     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
5124         wps_run_pbc_fail(apdev[0], dev[0])
5125
5126 def test_ap_wps_m1_oom(dev, apdev):
5127     """WPS and OOM for M1 on STA"""
5128     with alloc_fail(dev[0], 1, "wps_build_m1"):
5129         wps_run_pbc_fail(apdev[0], dev[0])
5130
5131 def test_ap_wps_m3_oom(dev, apdev):
5132     """WPS and OOM for M3 on STA"""
5133     with alloc_fail(dev[0], 1, "wps_build_m3"):
5134         wps_run_pbc_fail(apdev[0], dev[0])
5135
5136 def test_ap_wps_m5_oom(dev, apdev):
5137     """WPS and OOM for M5 on STA"""
5138     hapd = wps_start_ap(apdev[0])
5139     hapd.request("WPS_PBC")
5140     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5141     for i in range(1, 3):
5142         with alloc_fail(dev[0], i, "wps_build_m5"):
5143             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5144             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5145             if ev is None:
5146                 raise Exception("No EAP failure reported")
5147             dev[0].request("WPS_CANCEL")
5148             dev[0].wait_disconnected()
5149     dev[0].flush_scan_cache()
5150
5151 def test_ap_wps_m5_no_random(dev, apdev):
5152     """WPS and no random for M5 on STA"""
5153     with fail_test(dev[0], 1,
5154                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
5155         wps_run_pbc_fail(apdev[0], dev[0])
5156
5157 def test_ap_wps_m7_oom(dev, apdev):
5158     """WPS and OOM for M7 on STA"""
5159     hapd = wps_start_ap(apdev[0])
5160     hapd.request("WPS_PBC")
5161     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5162     for i in range(1, 3):
5163         with alloc_fail(dev[0], i, "wps_build_m7"):
5164             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5165             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5166             if ev is None:
5167                 raise Exception("No EAP failure reported")
5168             dev[0].request("WPS_CANCEL")
5169             dev[0].wait_disconnected()
5170     dev[0].flush_scan_cache()
5171
5172 def test_ap_wps_m7_no_random(dev, apdev):
5173     """WPS and no random for M7 on STA"""
5174     with fail_test(dev[0], 1,
5175                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
5176         wps_run_pbc_fail(apdev[0], dev[0])
5177
5178 def test_ap_wps_wsc_done_oom(dev, apdev):
5179     """WPS and OOM for WSC_Done on STA"""
5180     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
5181         wps_run_pbc_fail(apdev[0], dev[0])
5182
5183 def test_ap_wps_random_psk_fail(dev, apdev):
5184     """WPS and no random for PSK on AP"""
5185     ssid = "test-wps"
5186     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
5187     appin = "12345670"
5188     try:
5189         os.remove(pskfile)
5190     except:
5191         pass
5192
5193     try:
5194         with open(pskfile, "w") as f:
5195             f.write("# WPA PSKs\n")
5196
5197         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5198                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
5199                    "rsn_pairwise": "CCMP", "ap_pin": appin,
5200                    "wpa_psk_file": pskfile }
5201         hapd = hostapd.add_ap(apdev[0], params)
5202
5203         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5204         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
5205             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
5206             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5207             if ev is None:
5208                 raise Exception("No EAP failure reported")
5209             dev[0].request("WPS_CANCEL")
5210         dev[0].wait_disconnected()
5211
5212         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
5213             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5214
5215         with alloc_fail(hapd, 1, "wps_build_cred"):
5216             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5217
5218         with alloc_fail(hapd, 2, "wps_build_cred"):
5219             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5220     finally:
5221         os.remove(pskfile)
5222
5223 def wps_ext_eap_identity_req(dev, hapd, bssid):
5224     logger.debug("EAP-Identity/Request")
5225     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5226     if ev is None:
5227         raise Exception("Timeout on EAPOL-TX from hostapd")
5228     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
5229     if "OK" not in res:
5230         raise Exception("EAPOL_RX to wpa_supplicant failed")
5231
5232 def wps_ext_eap_identity_resp(hapd, dev, addr):
5233     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5234     if ev is None:
5235         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
5236     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
5237     if "OK" not in res:
5238         raise Exception("EAPOL_RX to hostapd failed")
5239
5240 def wps_ext_eap_wsc(dst, src, src_addr, msg):
5241     logger.debug(msg)
5242     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5243     if ev is None:
5244         raise Exception("Timeout on EAPOL-TX")
5245     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
5246     if "OK" not in res:
5247         raise Exception("EAPOL_RX failed")
5248
5249 def wps_start_ext(apdev, dev, pbc=False, pin=None):
5250     addr = dev.own_addr()
5251     bssid = apdev['bssid']
5252     ssid = "test-wps-conf"
5253     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5254                "wpa_passphrase": "12345678", "wpa": "2",
5255                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5256     hapd = hostapd.add_ap(apdev['ifname'], params)
5257
5258     if pbc:
5259         hapd.request("WPS_PBC")
5260     else:
5261         if pin is None:
5262             pin = dev.wps_read_pin()
5263         hapd.request("WPS_PIN any " + pin)
5264     dev.scan_for_bss(bssid, freq="2412")
5265     hapd.request("SET ext_eapol_frame_io 1")
5266     dev.request("SET ext_eapol_frame_io 1")
5267
5268     if pbc:
5269         dev.request("WPS_PBC " + bssid)
5270     else:
5271         dev.request("WPS_PIN " + bssid + " " + pin)
5272     return addr,bssid,hapd
5273
5274 def wps_auth_corrupt(dst, src, addr):
5275     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5276     if ev is None:
5277         raise Exception("Timeout on EAPOL-TX")
5278     src.request("SET ext_eapol_frame_io 0")
5279     dst.request("SET ext_eapol_frame_io 0")
5280     msg = ev.split(' ')[2]
5281     if msg[-24:-16] != '10050008':
5282         raise Exception("Could not find Authenticator attribute")
5283     # Corrupt Authenticator value
5284     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5285     res = dst.request("EAPOL_RX " + addr + " " + msg)
5286     if "OK" not in res:
5287         raise Exception("EAPOL_RX failed")
5288
5289 def wps_fail_finish(hapd, dev, fail_str):
5290     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5291     if ev is None:
5292         raise Exception("WPS-FAIL not indicated")
5293     if fail_str not in ev:
5294         raise Exception("Unexpected WPS-FAIL value: " + ev)
5295     dev.request("WPS_CANCEL")
5296     dev.wait_disconnected()
5297
5298 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5299     wps_auth_corrupt(dev, hapd, bssid)
5300     wps_fail_finish(hapd, dev, fail_str)
5301
5302 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5303     wps_auth_corrupt(hapd, dev, addr)
5304     wps_fail_finish(hapd, dev, fail_str)
5305
5306 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5307     """WPS and Authenticator attribute mismatch in M2"""
5308     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5309     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5310     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5311     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5312     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5313     logger.debug("M2")
5314     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5315
5316 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5317     """WPS and Authenticator attribute mismatch in M3"""
5318     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5319     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5320     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5321     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5322     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5323     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5324     logger.debug("M3")
5325     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5326
5327 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5328     """WPS and Authenticator attribute mismatch in M4"""
5329     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5330     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5331     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5332     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5333     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5334     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5335     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5336     logger.debug("M4")
5337     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5338
5339 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5340     """WPS and Authenticator attribute mismatch in M5"""
5341     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5342     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5343     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5344     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5345     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5346     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5347     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5348     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5349     logger.debug("M5")
5350     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5351
5352 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5353     """WPS and Authenticator attribute mismatch in M6"""
5354     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5355     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5356     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5357     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5358     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5359     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5360     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5361     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5362     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5363     logger.debug("M6")
5364     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5365
5366 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5367     """WPS and Authenticator attribute mismatch in M7"""
5368     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5369     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5370     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5371     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5372     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5373     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5374     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5375     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5376     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5377     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5378     logger.debug("M7")
5379     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5380
5381 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5382     """WPS and Authenticator attribute mismatch in M8"""
5383     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5384     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5385     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5386     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5387     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5388     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5389     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5390     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5391     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5392     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5393     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5394     logger.debug("M8")
5395     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5396
5397 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5398     """WPS and Authenticator attribute missing from M2"""
5399     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5400     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5401     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5402     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5403     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5404     logger.debug("M2")
5405     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5406     if ev is None:
5407         raise Exception("Timeout on EAPOL-TX")
5408     hapd.request("SET ext_eapol_frame_io 0")
5409     dev[0].request("SET ext_eapol_frame_io 0")
5410     msg = ev.split(' ')[2]
5411     if msg[-24:-16] != '10050008':
5412         raise Exception("Could not find Authenticator attribute")
5413     # Remove Authenticator value
5414     msg = msg[:-24]
5415     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5416     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5417     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5418     if "OK" not in res:
5419         raise Exception("EAPOL_RX failed")
5420     wps_fail_finish(hapd, dev[0], "msg=5")
5421
5422 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5423     """WPS and M2 with different Device Password ID (P2P)"""
5424     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5425     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5426     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5427     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5428     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5429     logger.debug("M2")
5430     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5431     if ev is None:
5432         raise Exception("Timeout on EAPOL-TX")
5433     hapd.request("SET ext_eapol_frame_io 0")
5434     dev[0].request("SET ext_eapol_frame_io 0")
5435     msg = ev.split(' ')[2]
5436     if msg[722:730] != '10120002':
5437         raise Exception("Could not find Device Password ID attribute")
5438     # Replace Device Password ID value. This will fail Authenticator check, but
5439     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5440     # log.
5441     msg = msg[0:730] + "0005" + msg[734:]
5442     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5443     if "OK" not in res:
5444         raise Exception("EAPOL_RX failed")
5445     wps_fail_finish(hapd, dev[0], "msg=5")
5446
5447 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5448     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5449     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5450     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5451     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5452     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5453     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5454     logger.debug("M2")
5455     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5456     if ev is None:
5457         raise Exception("Timeout on EAPOL-TX")
5458     hapd.request("SET ext_eapol_frame_io 0")
5459     dev[0].request("SET ext_eapol_frame_io 0")
5460     msg = ev.split(' ')[2]
5461     if msg[722:730] != '10120002':
5462         raise Exception("Could not find Device Password ID attribute")
5463     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5464     msg = msg[0:730] + "0004" + msg[734:]
5465     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5466     if "OK" not in res:
5467         raise Exception("EAPOL_RX failed")
5468     wps_fail_finish(hapd, dev[0], "msg=5")
5469
5470 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5471     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5472     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5473     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5474     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5475     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5476     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5477     logger.debug("M2")
5478     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5479     if ev is None:
5480         raise Exception("Timeout on EAPOL-TX")
5481     hapd.request("SET ext_eapol_frame_io 0")
5482     dev[0].request("SET ext_eapol_frame_io 0")
5483     msg = ev.split(' ')[2]
5484     if msg[722:730] != '10120002':
5485         raise Exception("Could not find Device Password ID attribute")
5486     # Replace Device Password ID value. This will fail Authenticator check, but
5487     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5488     # log.
5489     msg = msg[0:730] + "0000" + msg[734:]
5490     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5491     if "OK" not in res:
5492         raise Exception("EAPOL_RX failed")
5493     wps_fail_finish(hapd, dev[0], "msg=5")
5494     dev[0].flush_scan_cache()
5495
5496 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5497     """WPS and M2 without Device Password ID"""
5498     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5499     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5500     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5501     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5502     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5503     logger.debug("M2")
5504     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5505     if ev is None:
5506         raise Exception("Timeout on EAPOL-TX")
5507     hapd.request("SET ext_eapol_frame_io 0")
5508     dev[0].request("SET ext_eapol_frame_io 0")
5509     msg = ev.split(' ')[2]
5510     if msg[722:730] != '10120002':
5511         raise Exception("Could not find Device Password ID attribute")
5512     # Remove Device Password ID value. This will fail Authenticator check, but
5513     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5514     # log.
5515     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5516     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5517     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5518     if "OK" not in res:
5519         raise Exception("EAPOL_RX failed")
5520     wps_fail_finish(hapd, dev[0], "msg=5")
5521
5522 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5523     """WPS and M2 without Registrar Nonce"""
5524     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5525     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5526     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5527     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5528     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5529     logger.debug("M2")
5530     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5531     if ev is None:
5532         raise Exception("Timeout on EAPOL-TX")
5533     hapd.request("SET ext_eapol_frame_io 0")
5534     dev[0].request("SET ext_eapol_frame_io 0")
5535     msg = ev.split(' ')[2]
5536     if msg[96:104] != '10390010':
5537         raise Exception("Could not find Registrar Nonce attribute")
5538     # Remove Registrar Nonce. This will fail Authenticator check, but
5539     # allows the code path in wps_process_registrar_nonce() to be checked from
5540     # the debug log.
5541     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5542     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5543     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5544     if "OK" not in res:
5545         raise Exception("EAPOL_RX failed")
5546     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5547     if ev is None:
5548         raise Exception("Disconnect event not seen")
5549     dev[0].request("WPS_CANCEL")
5550     dev[0].flush_scan_cache()
5551
5552 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5553     """WPS and M2 without Enrollee Nonce"""
5554     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5555     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5556     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5557     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5558     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5559     logger.debug("M2")
5560     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5561     if ev is None:
5562         raise Exception("Timeout on EAPOL-TX")
5563     hapd.request("SET ext_eapol_frame_io 0")
5564     dev[0].request("SET ext_eapol_frame_io 0")
5565     msg = ev.split(' ')[2]
5566     if msg[56:64] != '101a0010':
5567         raise Exception("Could not find enrollee Nonce attribute")
5568     # Remove Enrollee Nonce. This will fail Authenticator check, but
5569     # allows the code path in wps_process_enrollee_nonce() to be checked from
5570     # the debug log.
5571     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5572     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5573     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5574     if "OK" not in res:
5575         raise Exception("EAPOL_RX failed")
5576     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5577     if ev is None:
5578         raise Exception("Disconnect event not seen")
5579     dev[0].request("WPS_CANCEL")
5580     dev[0].flush_scan_cache()
5581
5582 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5583     """WPS and M2 without UUID-R"""
5584     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5585     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5586     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5587     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5588     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5589     logger.debug("M2")
5590     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5591     if ev is None:
5592         raise Exception("Timeout on EAPOL-TX")
5593     hapd.request("SET ext_eapol_frame_io 0")
5594     dev[0].request("SET ext_eapol_frame_io 0")
5595     msg = ev.split(' ')[2]
5596     if msg[136:144] != '10480010':
5597         raise Exception("Could not find enrollee Nonce attribute")
5598     # Remove UUID-R. This will fail Authenticator check, but allows the code
5599     # path in wps_process_uuid_r() to be checked from the debug log.
5600     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5601     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5602     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5603     if "OK" not in res:
5604         raise Exception("EAPOL_RX failed")
5605     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5606     if ev is None:
5607         raise Exception("Disconnect event not seen")
5608     dev[0].request("WPS_CANCEL")
5609     dev[0].flush_scan_cache()
5610
5611 def test_ap_wps_m2_invalid(dev, apdev):
5612     """WPS and M2 parsing failure"""
5613     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5614     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5615     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5616     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5617     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5618     logger.debug("M2")
5619     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5620     if ev is None:
5621         raise Exception("Timeout on EAPOL-TX")
5622     hapd.request("SET ext_eapol_frame_io 0")
5623     dev[0].request("SET ext_eapol_frame_io 0")
5624     msg = ev.split(' ')[2]
5625     if msg[136:144] != '10480010':
5626         raise Exception("Could not find enrollee Nonce attribute")
5627     # Remove UUID-R. This will fail Authenticator check, but allows the code
5628     # path in wps_process_uuid_r() to be checked from the debug log.
5629     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5630     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5631     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5632     if "OK" not in res:
5633         raise Exception("EAPOL_RX failed")
5634     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5635     if ev is None:
5636         raise Exception("Disconnect event not seen")
5637     dev[0].request("WPS_CANCEL")
5638     dev[0].flush_scan_cache()
5639
5640 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5641     """WPS and M2 without Message Type"""
5642     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5643     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5644     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5645     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5646     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5647     logger.debug("M2")
5648     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5649     if ev is None:
5650         raise Exception("Timeout on EAPOL-TX")
5651     hapd.request("SET ext_eapol_frame_io 0")
5652     dev[0].request("SET ext_eapol_frame_io 0")
5653     msg = ev.split(' ')[2]
5654     if msg[46:54] != '10220001':
5655         raise Exception("Could not find Message Type attribute")
5656     # Remove Message Type. This will fail Authenticator check, but allows the
5657     # code path in wps_process_wsc_msg() to be checked from the debug log.
5658     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5659     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5660     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5661     if "OK" not in res:
5662         raise Exception("EAPOL_RX failed")
5663     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5664     if ev is None:
5665         raise Exception("Disconnect event not seen")
5666     dev[0].request("WPS_CANCEL")
5667     dev[0].flush_scan_cache()
5668
5669 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5670     """WPS and M2 but unknown Message Type"""
5671     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5672     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5673     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5674     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5675     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5676     logger.debug("M2")
5677     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5678     if ev is None:
5679         raise Exception("Timeout on EAPOL-TX")
5680     hapd.request("SET ext_eapol_frame_io 0")
5681     dev[0].request("SET ext_eapol_frame_io 0")
5682     msg = ev.split(' ')[2]
5683     if msg[46:54] != '10220001':
5684         raise Exception("Could not find Message Type attribute")
5685     # Replace Message Type value. This will be rejected.
5686     msg = msg[0:54] + "00" + msg[56:]
5687     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5688     if "OK" not in res:
5689         raise Exception("EAPOL_RX failed")
5690     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5691     if ev is None:
5692         raise Exception("Disconnect event not seen")
5693     dev[0].request("WPS_CANCEL")
5694     dev[0].flush_scan_cache()
5695
5696 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5697     """WPS and M2 but unknown opcode"""
5698     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5699     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5700     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5701     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5702     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5703     logger.debug("M2")
5704     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5705     if ev is None:
5706         raise Exception("Timeout on EAPOL-TX")
5707     hapd.request("SET ext_eapol_frame_io 0")
5708     dev[0].request("SET ext_eapol_frame_io 0")
5709     msg = ev.split(' ')[2]
5710     # Replace opcode. This will be discarded in EAP-WSC processing.
5711     msg = msg[0:32] + "00" + msg[34:]
5712     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5713     if "OK" not in res:
5714         raise Exception("EAPOL_RX failed")
5715     dev[0].request("WPS_CANCEL")
5716     dev[0].wait_disconnected()
5717     dev[0].flush_scan_cache()
5718
5719 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5720     """WPS and M2 but unknown opcode (WSC_Start)"""
5721     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5722     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5723     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5724     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5725     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5726     logger.debug("M2")
5727     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5728     if ev is None:
5729         raise Exception("Timeout on EAPOL-TX")
5730     hapd.request("SET ext_eapol_frame_io 0")
5731     dev[0].request("SET ext_eapol_frame_io 0")
5732     msg = ev.split(' ')[2]
5733     # Replace opcode. This will be discarded in EAP-WSC processing.
5734     msg = msg[0:32] + "01" + msg[34:]
5735     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5736     if "OK" not in res:
5737         raise Exception("EAPOL_RX failed")
5738     dev[0].request("WPS_CANCEL")
5739     dev[0].wait_disconnected()
5740     dev[0].flush_scan_cache()
5741
5742 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5743     """WPS and M2 but unknown opcode (WSC_Done)"""
5744     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5745     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5746     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5747     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5748     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5749     logger.debug("M2")
5750     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5751     if ev is None:
5752         raise Exception("Timeout on EAPOL-TX")
5753     hapd.request("SET ext_eapol_frame_io 0")
5754     dev[0].request("SET ext_eapol_frame_io 0")
5755     msg = ev.split(' ')[2]
5756     # Replace opcode. This will be discarded in WPS Enrollee processing.
5757     msg = msg[0:32] + "05" + msg[34:]
5758     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5759     if "OK" not in res:
5760         raise Exception("EAPOL_RX failed")
5761     dev[0].request("WPS_CANCEL")
5762     dev[0].wait_disconnected()
5763     dev[0].flush_scan_cache()
5764
5765 def wps_m2_but_other(dev, apdev, title, msgtype):
5766     addr,bssid,hapd = wps_start_ext(apdev, dev)
5767     wps_ext_eap_identity_req(dev, hapd, bssid)
5768     wps_ext_eap_identity_resp(hapd, dev, addr)
5769     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5770     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5771     logger.debug(title)
5772     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5773     if ev is None:
5774         raise Exception("Timeout on EAPOL-TX")
5775     hapd.request("SET ext_eapol_frame_io 0")
5776     dev.request("SET ext_eapol_frame_io 0")
5777     msg = ev.split(' ')[2]
5778     if msg[46:54] != '10220001':
5779         raise Exception("Could not find Message Type attribute")
5780     # Replace Message Type value. This will be rejected.
5781     msg = msg[0:54] + msgtype + msg[56:]
5782     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5783     if "OK" not in res:
5784         raise Exception("EAPOL_RX failed")
5785     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5786     if ev is None:
5787         raise Exception("WPS-FAIL event not seen")
5788     dev.request("WPS_CANCEL")
5789     dev.wait_disconnected()
5790
5791 def wps_m4_but_other(dev, apdev, title, msgtype):
5792     addr,bssid,hapd = wps_start_ext(apdev, dev)
5793     wps_ext_eap_identity_req(dev, hapd, bssid)
5794     wps_ext_eap_identity_resp(hapd, dev, addr)
5795     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5796     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5797     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5798     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5799     logger.debug(title)
5800     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5801     if ev is None:
5802         raise Exception("Timeout on EAPOL-TX")
5803     hapd.request("SET ext_eapol_frame_io 0")
5804     dev.request("SET ext_eapol_frame_io 0")
5805     msg = ev.split(' ')[2]
5806     if msg[46:54] != '10220001':
5807         raise Exception("Could not find Message Type attribute")
5808     # Replace Message Type value. This will be rejected.
5809     msg = msg[0:54] + msgtype + msg[56:]
5810     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5811     if "OK" not in res:
5812         raise Exception("EAPOL_RX failed")
5813     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5814     if ev is None:
5815         raise Exception("WPS-FAIL event not seen")
5816     dev.request("WPS_CANCEL")
5817     dev.wait_disconnected()
5818
5819 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5820     """WPS and M2 but Message Type M4"""
5821     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5822
5823 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5824     """WPS and M2 but Message Type M6"""
5825     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5826
5827 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5828     """WPS and M2 but Message Type M8"""
5829     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5830
5831 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5832     """WPS and M4 but Message Type M2"""
5833     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5834
5835 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5836     """WPS and M4 but Message Type M2D"""
5837     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5838
5839 def test_ap_wps_config_methods(dev, apdev):
5840     """WPS configuration method parsing"""
5841     ssid = "test-wps-conf"
5842     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5843                "wpa_passphrase": "12345678", "wpa": "2",
5844                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5845                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5846     hapd = hostapd.add_ap(apdev[0], params)
5847     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5848                "wpa_passphrase": "12345678", "wpa": "2",
5849                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5850                "config_methods": "display push_button" }
5851     hapd2 = hostapd.add_ap(apdev[1], params)
5852
5853 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5854     """WPS UPnP SetSelectedRegistrar protocol testing"""
5855     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5856     hapd = add_ssdp_ap(apdev[0], ap_uuid)
5857
5858     location = ssdp_get_location(ap_uuid)
5859     urls = upnp_get_urls(location)
5860     eventurl = urlparse.urlparse(urls['event_sub_url'])
5861     ctrlurl = urlparse.urlparse(urls['control_url'])
5862     url = urlparse.urlparse(location)
5863     conn = httplib.HTTPConnection(url.netloc)
5864
5865     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5866         def handle(self):
5867             data = self.rfile.readline().strip()
5868             logger.debug(data)
5869             self.wfile.write(gen_wps_event())
5870
5871     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5872     server.timeout = 1
5873
5874     headers = { "callback": '<http://127.0.0.1:12345/event>',
5875                 "NT": "upnp:event",
5876                 "timeout": "Second-1234" }
5877     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5878     resp = conn.getresponse()
5879     if resp.status != 200:
5880         raise Exception("Unexpected HTTP response: %d" % resp.status)
5881     sid = resp.getheader("sid")
5882     logger.debug("Subscription SID " + sid)
5883     server.handle_request()
5884
5885     tests = [ (500, "10"),
5886               (200, "104a000110" + "1041000101" + "101200020000" +
5887                "105300023148" +
5888                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5889                "10480010362db47ba53a519188fb5458b986b2e4"),
5890               (200, "104a000110" + "1041000100" + "101200020000" +
5891                "105300020000"),
5892               (200, "104a000110" + "1041000100"),
5893               (200, "104a000110") ]
5894     for status,test in tests:
5895         tlvs = binascii.unhexlify(test)
5896         newmsg = base64.b64encode(tlvs)
5897         msg = '<?xml version="1.0"?>\n'
5898         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5899         msg += '<s:Body>'
5900         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5901         msg += '<NewMessage>'
5902         msg += newmsg
5903         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5904         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5905         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5906         conn.request("POST", ctrlurl.path, msg, headers)
5907         resp = conn.getresponse()
5908         if resp.status != status:
5909             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5910
5911 def test_ap_wps_adv_oom(dev, apdev):
5912     """WPS AP and advertisement OOM"""
5913     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5914     hapd = add_ssdp_ap(apdev[0], ap_uuid)
5915
5916     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5917         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5918                           no_recv=True)
5919         time.sleep(0.2)
5920
5921     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5922         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5923                           no_recv=True)
5924         time.sleep(0.2)
5925
5926     with alloc_fail(hapd, 1,
5927                     "next_advertisement;advertisement_state_machine_stop"):
5928         hapd.disable()
5929
5930     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5931         if "FAIL" not in hapd.request("ENABLE"):
5932             raise Exception("ENABLE succeeded during OOM")
5933
5934 def test_wps_config_methods(dev):
5935     """WPS config method update"""
5936     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5937     wpas.interface_add("wlan5")
5938     if "OK" not in wpas.request("SET config_methods display label"):
5939         raise Exception("Failed to set config_methods")
5940     if wpas.request("GET config_methods").strip() != "display label":
5941         raise Exception("config_methods were not updated")
5942     if "OK" not in wpas.request("SET config_methods "):
5943         raise Exception("Failed to clear config_methods")
5944     if wpas.request("GET config_methods").strip() != "":
5945         raise Exception("config_methods were not cleared")
5946
5947 WPS_VENDOR_ID_WFA = 14122
5948 WPS_VENDOR_TYPE = 1
5949
5950 # EAP-WSC Op-Code values
5951 WSC_Start = 0x01
5952 WSC_ACK = 0x02
5953 WSC_NACK = 0x03
5954 WSC_MSG = 0x04
5955 WSC_Done = 0x05
5956 WSC_FRAG_ACK = 0x06
5957
5958 ATTR_AP_CHANNEL = 0x1001
5959 ATTR_ASSOC_STATE = 0x1002
5960 ATTR_AUTH_TYPE = 0x1003
5961 ATTR_AUTH_TYPE_FLAGS = 0x1004
5962 ATTR_AUTHENTICATOR = 0x1005
5963 ATTR_CONFIG_METHODS = 0x1008
5964 ATTR_CONFIG_ERROR = 0x1009
5965 ATTR_CONFIRM_URL4 = 0x100a
5966 ATTR_CONFIRM_URL6 = 0x100b
5967 ATTR_CONN_TYPE = 0x100c
5968 ATTR_CONN_TYPE_FLAGS = 0x100d
5969 ATTR_CRED = 0x100e
5970 ATTR_ENCR_TYPE = 0x100f
5971 ATTR_ENCR_TYPE_FLAGS = 0x1010
5972 ATTR_DEV_NAME = 0x1011
5973 ATTR_DEV_PASSWORD_ID = 0x1012
5974 ATTR_E_HASH1 = 0x1014
5975 ATTR_E_HASH2 = 0x1015
5976 ATTR_E_SNONCE1 = 0x1016
5977 ATTR_E_SNONCE2 = 0x1017
5978 ATTR_ENCR_SETTINGS = 0x1018
5979 ATTR_ENROLLEE_NONCE = 0x101a
5980 ATTR_FEATURE_ID = 0x101b
5981 ATTR_IDENTITY = 0x101c
5982 ATTR_IDENTITY_PROOF = 0x101d
5983 ATTR_KEY_WRAP_AUTH = 0x101e
5984 ATTR_KEY_ID = 0x101f
5985 ATTR_MAC_ADDR = 0x1020
5986 ATTR_MANUFACTURER = 0x1021
5987 ATTR_MSG_TYPE = 0x1022
5988 ATTR_MODEL_NAME = 0x1023
5989 ATTR_MODEL_NUMBER = 0x1024
5990 ATTR_NETWORK_INDEX = 0x1026
5991 ATTR_NETWORK_KEY = 0x1027
5992 ATTR_NETWORK_KEY_INDEX = 0x1028
5993 ATTR_NEW_DEVICE_NAME = 0x1029
5994 ATTR_NEW_PASSWORD = 0x102a
5995 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5996 ATTR_OS_VERSION = 0x102d
5997 ATTR_POWER_LEVEL = 0x102f
5998 ATTR_PSK_CURRENT = 0x1030
5999 ATTR_PSK_MAX = 0x1031
6000 ATTR_PUBLIC_KEY = 0x1032
6001 ATTR_RADIO_ENABLE = 0x1033
6002 ATTR_REBOOT = 0x1034
6003 ATTR_REGISTRAR_CURRENT = 0x1035
6004 ATTR_REGISTRAR_ESTABLISHED = 0x1036
6005 ATTR_REGISTRAR_LIST = 0x1037
6006 ATTR_REGISTRAR_MAX = 0x1038
6007 ATTR_REGISTRAR_NONCE = 0x1039
6008 ATTR_REQUEST_TYPE = 0x103a
6009 ATTR_RESPONSE_TYPE = 0x103b
6010 ATTR_RF_BANDS = 0x103c
6011 ATTR_R_HASH1 = 0x103d
6012 ATTR_R_HASH2 = 0x103e
6013 ATTR_R_SNONCE1 = 0x103f
6014 ATTR_R_SNONCE2 = 0x1040
6015 ATTR_SELECTED_REGISTRAR = 0x1041
6016 ATTR_SERIAL_NUMBER = 0x1042
6017 ATTR_WPS_STATE = 0x1044
6018 ATTR_SSID = 0x1045
6019 ATTR_TOTAL_NETWORKS = 0x1046
6020 ATTR_UUID_E = 0x1047
6021 ATTR_UUID_R = 0x1048
6022 ATTR_VENDOR_EXT = 0x1049
6023 ATTR_VERSION = 0x104a
6024 ATTR_X509_CERT_REQ = 0x104b
6025 ATTR_X509_CERT = 0x104c
6026 ATTR_EAP_IDENTITY = 0x104d
6027 ATTR_MSG_COUNTER = 0x104e
6028 ATTR_PUBKEY_HASH = 0x104f
6029 ATTR_REKEY_KEY = 0x1050
6030 ATTR_KEY_LIFETIME = 0x1051
6031 ATTR_PERMITTED_CFG_METHODS = 0x1052
6032 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
6033 ATTR_PRIMARY_DEV_TYPE = 0x1054
6034 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
6035 ATTR_PORTABLE_DEV = 0x1056
6036 ATTR_AP_SETUP_LOCKED = 0x1057
6037 ATTR_APPLICATION_EXT = 0x1058
6038 ATTR_EAP_TYPE = 0x1059
6039 ATTR_IV = 0x1060
6040 ATTR_KEY_PROVIDED_AUTO = 0x1061
6041 ATTR_802_1X_ENABLED = 0x1062
6042 ATTR_APPSESSIONKEY = 0x1063
6043 ATTR_WEPTRANSMITKEY = 0x1064
6044 ATTR_REQUESTED_DEV_TYPE = 0x106a
6045
6046 # Message Type
6047 WPS_Beacon = 0x01
6048 WPS_ProbeRequest = 0x02
6049 WPS_ProbeResponse = 0x03
6050 WPS_M1 = 0x04
6051 WPS_M2 = 0x05
6052 WPS_M2D = 0x06
6053 WPS_M3 = 0x07
6054 WPS_M4 = 0x08
6055 WPS_M5 = 0x09
6056 WPS_M6 = 0x0a
6057 WPS_M7 = 0x0b
6058 WPS_M8 = 0x0c
6059 WPS_WSC_ACK = 0x0d
6060 WPS_WSC_NACK = 0x0e
6061 WPS_WSC_DONE = 0x0f
6062
6063 def get_wsc_msg(dev):
6064     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
6065     if ev is None:
6066         raise Exception("Timeout on EAPOL-TX")
6067     data = binascii.unhexlify(ev.split(' ')[2])
6068     msg = {}
6069
6070     # Parse EAPOL header
6071     if len(data) < 4:
6072         raise Exception("No room for EAPOL header")
6073     version,type,length = struct.unpack('>BBH', data[0:4])
6074     msg['eapol_version'] = version
6075     msg['eapol_type'] = type
6076     msg['eapol_length'] = length
6077     data = data[4:]
6078     if length != len(data):
6079         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
6080     if type != 0:
6081         raise Exception("Unexpected EAPOL header type: %d" % type)
6082
6083     # Parse EAP header
6084     if len(data) < 4:
6085         raise Exception("No room for EAP header")
6086     code,identifier,length = struct.unpack('>BBH', data[0:4])
6087     msg['eap_code'] = code
6088     msg['eap_identifier'] = identifier
6089     msg['eap_length'] = length
6090     data = data[4:]
6091     if msg['eapol_length'] != msg['eap_length']:
6092         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
6093
6094     # Parse EAP expanded header
6095     if len(data) < 1:
6096         raise Exception("No EAP type included")
6097     msg['eap_type'], = struct.unpack('B', data[0])
6098     data = data[1:]
6099
6100     if msg['eap_type'] == 254:
6101         if len(data) < 3 + 4:
6102             raise Exception("Truncated EAP expanded header")
6103         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
6104         data = data[7:]
6105     else:
6106         raise Exception("Unexpected EAP type")
6107
6108     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
6109         raise Exception("Unexpected Vendor-Id")
6110     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
6111         raise Exception("Unexpected Vendor-Type")
6112
6113     # Parse EAP-WSC header
6114     if len(data) < 2:
6115         raise Exception("Truncated EAP-WSC header")
6116     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
6117     data = data[2:]
6118
6119     # Parse WSC attributes
6120     msg['raw_attrs'] = data
6121     attrs = {}
6122     while len(data) > 0:
6123         if len(data) < 4:
6124             raise Exception("Truncated attribute header")
6125         attr,length = struct.unpack('>HH', data[0:4])
6126         data = data[4:]
6127         if length > len(data):
6128             raise Exception("Truncated attribute 0x%04x" % attr)
6129         attrs[attr] = data[0:length]
6130         data = data[length:]
6131     msg['wsc_attrs'] = attrs
6132
6133     if ATTR_MSG_TYPE in attrs:
6134         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
6135
6136     return msg
6137
6138 def recv_wsc_msg(dev, opcode, msg_type):
6139     msg = get_wsc_msg(dev)
6140     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
6141         raise Exception("Unexpected Op-Code/MsgType")
6142     return msg, msg['wsc_attrs'], msg['raw_attrs']
6143
6144 def build_wsc_attr(attr, payload):
6145     return struct.pack('>HH', attr, len(payload)) + payload
6146
6147 def build_attr_msg_type(msg_type):
6148     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
6149
6150 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
6151     length = 4 + 8 + 2 + len(payload)
6152     # EAPOL header
6153     msg = struct.pack('>BBH', 2, 0, length)
6154     # EAP header
6155     msg += struct.pack('>BBH', eap_code, eap_id, length)
6156     # EAP expanded header for EAP-WSC
6157     msg += struct.pack('B', 254)
6158     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
6159     msg += struct.pack('>L', WPS_VENDOR_TYPE)
6160     # EAP-WSC header
6161     msg += struct.pack('BB', opcode, 0)
6162     # WSC attributes
6163     msg += payload
6164     return msg
6165
6166 def build_eap_success(eap_id):
6167     length = 4
6168     # EAPOL header
6169     msg = struct.pack('>BBH', 2, 0, length)
6170     # EAP header
6171     msg += struct.pack('>BBH', 3, eap_id, length)
6172     return msg
6173
6174 def build_eap_failure(eap_id):
6175     length = 4
6176     # EAPOL header
6177     msg = struct.pack('>BBH', 2, 0, length)
6178     # EAP header
6179     msg += struct.pack('>BBH', 4, eap_id, length)
6180     return msg
6181
6182 def send_wsc_msg(dev, src, msg):
6183     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
6184     if "OK" not in res:
6185         raise Exception("EAPOL_RX failed")
6186
6187 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
6188 group_5_generator = 2
6189
6190 def wsc_kdf(key, label, bits):
6191     result = ''
6192     i = 1
6193     while len(result) * 8 < bits:
6194         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
6195         m = hmac.new(key, data, hashlib.sha256)
6196         result += m.digest()
6197         i += 1
6198     return result[0:bits / 8]
6199
6200 def wsc_keys(kdk):
6201     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
6202     authkey = keys[0:32]
6203     keywrapkey = keys[32:48]
6204     emsk = keys[48:80]
6205     return authkey,keywrapkey,emsk
6206
6207 def wsc_dev_pw_half_psk(authkey, dev_pw):
6208     m = hmac.new(authkey, dev_pw, hashlib.sha256)
6209     return m.digest()[0:16]
6210
6211 def wsc_dev_pw_psk(authkey, dev_pw):
6212     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
6213     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
6214     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
6215     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
6216     return psk1,psk2
6217
6218 def build_attr_authenticator(authkey, prev_msg, curr_msg):
6219     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
6220     auth = m.digest()[0:8]
6221     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
6222
6223 def build_attr_encr_settings(authkey, keywrapkey, data):
6224     m = hmac.new(authkey, data, hashlib.sha256)
6225     kwa = m.digest()[0:8]
6226     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6227     iv = 16*'\x99'
6228     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6229     pad_len = 16 - len(data) % 16
6230     ps = pad_len * struct.pack('B', pad_len)
6231     data += ps
6232     wrapped = aes.encrypt(data)
6233     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6234
6235 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
6236     if len(data) < 32 or len(data) % 16 != 0:
6237         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
6238     iv = data[0:16]
6239     encr = data[16:]
6240     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6241     decrypted = aes.decrypt(encr)
6242     pad_len, = struct.unpack('B', decrypted[-1])
6243     if pad_len > len(decrypted):
6244         raise Exception("Invalid padding in Encrypted Settings")
6245     for i in range(-pad_len, -1):
6246         if decrypted[i] != decrypted[-1]:
6247             raise Exception("Invalid PS value in Encrypted Settings")
6248     
6249     decrypted = decrypted[0:len(decrypted) - pad_len]
6250     if len(decrypted) < 12:
6251         raise Exception("Truncated Encrypted Settings plaintext")
6252     kwa = decrypted[-12:]
6253     attr,length = struct.unpack(">HH", kwa[0:4])
6254     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6255         raise Exception("Invalid KWA header")
6256     kwa = kwa[4:]
6257     decrypted = decrypted[0:len(decrypted) - 12]
6258
6259     m = hmac.new(authkey, decrypted, hashlib.sha256)
6260     calc_kwa = m.digest()[0:8]
6261     if kwa != calc_kwa:
6262         raise Exception("KWA mismatch")
6263
6264     return decrypted
6265
6266 def zeropad_str(val, pad_len):
6267     while len(val) < pad_len * 2:
6268         val = '0' + val
6269     return val
6270
6271 def wsc_dh_init():
6272     # For now, use a hardcoded private key. In theory, this is supposed to be
6273     # randomly selected.
6274     own_private = 0x123456789
6275     own_public = pow(group_5_generator, own_private, group_5_prime)
6276     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6277     return own_private, pk
6278
6279 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6280     peer_public = long(binascii.hexlify(peer_pk), 16)
6281     if peer_public < 2 or peer_public >= group_5_prime:
6282         raise Exception("Invalid peer public key")
6283     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6284         raise Exception("Unexpected Legendre symbol for peer public key")
6285
6286     shared_secret = pow(peer_public, own_private, group_5_prime)
6287     ss = zeropad_str(format(shared_secret, "02x"), 192)
6288     logger.debug("DH shared secret: " + ss)
6289
6290     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6291     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6292
6293     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6294     kdk = m.digest()
6295     logger.debug("KDK: " + binascii.hexlify(kdk))
6296     authkey,keywrapkey,emsk = wsc_keys(kdk)
6297     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6298     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6299     logger.debug("EMSK: " + binascii.hexlify(emsk))
6300     return authkey,keywrapkey
6301
6302 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6303     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6304     logger.debug("PSK1: " + binascii.hexlify(psk1))
6305     logger.debug("PSK2: " + binascii.hexlify(psk2))
6306
6307     # Note: Secret values are supposed to be random, but hardcoded values are
6308     # fine for testing.
6309     s1 = 16*'\x77'
6310     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6311     hash1 = m.digest()
6312     logger.debug("Hash1: " + binascii.hexlify(hash1))
6313
6314     s2 = 16*'\x88'
6315     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6316     hash2 = m.digest()
6317     logger.debug("Hash2: " + binascii.hexlify(hash2))
6318     return s1,s2,hash1,hash2
6319
6320 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6321              manufacturer='', model_name='', config_methods='\x00\x00'):
6322     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6323     attrs += build_attr_msg_type(WPS_M1)
6324     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6325     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6326     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6327     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6328     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6329     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6330     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6331     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6332     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6333     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6334     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6335     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6336     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6337     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6338     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6339     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6340     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6341     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6342     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6343     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6344     m1 = build_eap_wsc(2, eap_id, attrs)
6345     return m1, attrs
6346
6347 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6348              dev_pw_id='\x00\x00', eap_code=1):
6349     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6350     attrs += build_attr_msg_type(WPS_M2)
6351     if e_nonce:
6352         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6353     if r_nonce:
6354         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6355     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6356     if r_pk:
6357         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6358     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6359     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6360     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6361     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6362     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6363     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6364     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6365     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6366     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6367     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6368     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6369     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6370     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6371     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6372     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6373     attrs += build_attr_authenticator(authkey, m1, attrs)
6374     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6375     return m2, attrs
6376
6377 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6378     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6379     attrs += build_attr_msg_type(WPS_M2D)
6380     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6381     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6382     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6383     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6384     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6385     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6386     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6387     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6388     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6389     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6390     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6391     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6392     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6393     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6394     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6395     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6396     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6397     if dev_pw_id:
6398         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6399     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6400     return m2d, attrs
6401
6402 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6403     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6404     if msg_type is not None:
6405         attrs += build_attr_msg_type(msg_type)
6406     if e_nonce:
6407         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6408     if r_nonce:
6409         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6410     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6411     return msg, attrs
6412
6413 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6414                msg_type=WPS_WSC_NACK, eap_code=1):
6415     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6416     if msg_type is not None:
6417         attrs += build_attr_msg_type(msg_type)
6418     if e_nonce:
6419         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6420     if r_nonce:
6421         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6422     if config_error:
6423         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6424     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6425     return msg, attrs
6426
6427 def test_wps_ext(dev, apdev):
6428     """WPS against external implementation"""
6429     pin = "12345670"
6430     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6431     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6432     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6433
6434     logger.debug("Receive WSC/Start from AP")
6435     msg = get_wsc_msg(hapd)
6436     if msg['wsc_opcode'] != WSC_Start:
6437         raise Exception("Unexpected Op-Code for WSC/Start")
6438     wsc_start_id = msg['eap_identifier']
6439
6440     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6441     uuid_e = 16*'\x11'
6442     e_nonce = 16*'\x22'
6443     own_private, e_pk = wsc_dh_init()
6444
6445     logger.debug("Send M1 to AP")
6446     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6447                                 e_nonce, e_pk)
6448     send_wsc_msg(hapd, addr, m1)
6449
6450     logger.debug("Receive M2 from AP")
6451     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6452
6453     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6454                                     mac_addr, e_nonce,
6455                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6456     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6457                                                 m2_attrs[ATTR_PUBLIC_KEY])
6458
6459     logger.debug("Send M3 to AP")
6460     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6461     attrs += build_attr_msg_type(WPS_M3)
6462     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6463                             m2_attrs[ATTR_REGISTRAR_NONCE])
6464     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6465     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6466     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6467     raw_m3_attrs = attrs
6468     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6469     send_wsc_msg(hapd, addr, m3)
6470
6471     logger.debug("Receive M4 from AP")
6472     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6473
6474     logger.debug("Send M5 to AP")
6475     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6476     attrs += build_attr_msg_type(WPS_M5)
6477     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6478                             m2_attrs[ATTR_REGISTRAR_NONCE])
6479     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6480     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6481     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6482     raw_m5_attrs = attrs
6483     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6484     send_wsc_msg(hapd, addr, m5)
6485
6486     logger.debug("Receive M6 from AP")
6487     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6488
6489     logger.debug("Send M7 to AP")
6490     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6491     attrs += build_attr_msg_type(WPS_M7)
6492     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6493                             m2_attrs[ATTR_REGISTRAR_NONCE])
6494     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6495     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6496     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6497     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6498     raw_m7_attrs = attrs
6499     send_wsc_msg(hapd, addr, m7)
6500
6501     logger.debug("Receive M8 from AP")
6502     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6503     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6504                                          m8_attrs[ATTR_ENCR_SETTINGS])
6505     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6506
6507     logger.debug("Prepare WSC_Done")
6508     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6509     attrs += build_attr_msg_type(WPS_WSC_DONE)
6510     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6511     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6512                             m2_attrs[ATTR_REGISTRAR_NONCE])
6513     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6514     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6515     # AP disconnects.
6516
6517     uuid_r = 16*'\x33'
6518     r_nonce = 16*'\x44'
6519
6520     eap_id = wsc_start_id
6521     logger.debug("Send WSC/Start to STA")
6522     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6523     send_wsc_msg(dev[0], bssid, wsc_start)
6524     eap_id = (eap_id + 1) % 256
6525
6526     logger.debug("Receive M1 from STA")
6527     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6528
6529     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6530                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6531                                     r_nonce)
6532     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6533                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6534
6535     logger.debug("Send M2 to STA")
6536     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6537                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6538                                 r_nonce, uuid_r, e_pk)
6539     send_wsc_msg(dev[0], bssid, m2)
6540     eap_id = (eap_id + 1) % 256
6541
6542     logger.debug("Receive M3 from STA")
6543     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6544
6545     logger.debug("Send M4 to STA")
6546     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6547     attrs += build_attr_msg_type(WPS_M4)
6548     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6549     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6550     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6551     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6552     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6553     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6554     raw_m4_attrs = attrs
6555     m4 = build_eap_wsc(1, eap_id, attrs)
6556     send_wsc_msg(dev[0], bssid, m4)
6557     eap_id = (eap_id + 1) % 256
6558
6559     logger.debug("Receive M5 from STA")
6560     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6561
6562     logger.debug("Send M6 to STA")
6563     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6564     attrs += build_attr_msg_type(WPS_M6)
6565     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6566                             m1_attrs[ATTR_ENROLLEE_NONCE])
6567     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6568     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6569     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6570     raw_m6_attrs = attrs
6571     m6 = build_eap_wsc(1, eap_id, attrs)
6572     send_wsc_msg(dev[0], bssid, m6)
6573     eap_id = (eap_id + 1) % 256
6574
6575     logger.debug("Receive M7 from STA")
6576     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6577
6578     logger.debug("Send M8 to STA")
6579     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6580     attrs += build_attr_msg_type(WPS_M8)
6581     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6582                             m1_attrs[ATTR_ENROLLEE_NONCE])
6583     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6584     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6585     raw_m8_attrs = attrs
6586     m8 = build_eap_wsc(1, eap_id, attrs)
6587     send_wsc_msg(dev[0], bssid, m8)
6588     eap_id = (eap_id + 1) % 256
6589
6590     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6591     if ev is None:
6592         raise Exception("wpa_supplicant did not report credential")
6593
6594     logger.debug("Receive WSC_Done from STA")
6595     msg = get_wsc_msg(dev[0])
6596     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6597         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6598
6599     logger.debug("Send WSC_Done to AP")
6600     hapd.request("SET ext_eapol_frame_io 0")
6601     dev[0].request("SET ext_eapol_frame_io 0")
6602     send_wsc_msg(hapd, addr, wsc_done)
6603
6604     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6605     if ev is None:
6606         raise Exception("hostapd did not report WPS success")
6607
6608     dev[0].wait_connected()
6609
6610 def wps_start_kwa(dev, apdev):
6611     pin = "12345670"
6612     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6613     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6614     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6615     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6616
6617     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6618     uuid_r = 16*'\x33'
6619     r_nonce = 16*'\x44'
6620     own_private, e_pk = wsc_dh_init()
6621
6622     logger.debug("Receive M1 from STA")
6623     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6624     eap_id = (msg['eap_identifier'] + 1) % 256
6625
6626     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6627                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6628                                     r_nonce)
6629     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6630                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6631
6632     logger.debug("Send M2 to STA")
6633     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6634                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6635                                 r_nonce, uuid_r, e_pk)
6636     send_wsc_msg(dev[0], bssid, m2)
6637     eap_id = (eap_id + 1) % 256
6638
6639     logger.debug("Receive M3 from STA")
6640     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6641
6642     logger.debug("Send M4 to STA")
6643     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6644     attrs += build_attr_msg_type(WPS_M4)
6645     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6646     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6647     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6648
6649     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6650
6651 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6652     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6653     m4 = build_eap_wsc(1, eap_id, attrs)
6654     send_wsc_msg(dev[0], bssid, m4)
6655     eap_id = (eap_id + 1) % 256
6656
6657     logger.debug("Receive M5 from STA")
6658     msg = get_wsc_msg(dev[0])
6659     if msg['wsc_opcode'] != WSC_NACK:
6660         raise Exception("Unexpected message - expected WSC_Nack")
6661
6662     dev[0].request("WPS_CANCEL")
6663     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6664     dev[0].wait_disconnected()
6665
6666 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6667     """WPS and KWA error: No KWA attribute"""
6668     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6669     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6670     # Encrypted Settings without KWA
6671     iv = 16*'\x99'
6672     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6673     pad_len = 16 - len(data) % 16
6674     ps = pad_len * struct.pack('B', pad_len)
6675     data += ps
6676     wrapped = aes.encrypt(data)
6677     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6678     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6679
6680 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6681     """WPS and KWA error: Data after KWA"""
6682     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6683     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6684     # Encrypted Settings and data after KWA
6685     m = hmac.new(authkey, data, hashlib.sha256)
6686     kwa = m.digest()[0:8]
6687     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6688     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6689     iv = 16*'\x99'
6690     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6691     pad_len = 16 - len(data) % 16
6692     ps = pad_len * struct.pack('B', pad_len)
6693     data += ps
6694     wrapped = aes.encrypt(data)
6695     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6696     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6697
6698 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6699     """WPS and KWA error: KWA mismatch"""
6700     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6701     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6702     # Encrypted Settings and KWA with incorrect value
6703     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6704     iv = 16*'\x99'
6705     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6706     pad_len = 16 - len(data) % 16
6707     ps = pad_len * struct.pack('B', pad_len)
6708     data += ps
6709     wrapped = aes.encrypt(data)
6710     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6711     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6712
6713 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6714     pin = "12345670"
6715     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6716     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6717     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6718     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6719
6720     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6721     uuid_r = 16*'\x33'
6722     r_nonce = 16*'\x44'
6723     own_private, e_pk = wsc_dh_init()
6724
6725     logger.debug("Receive M1 from STA")
6726     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6727     eap_id = (msg['eap_identifier'] + 1) % 256
6728
6729     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6730                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6731                                     r_nonce)
6732     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6733                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6734
6735     logger.debug("Send M2 to STA")
6736     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6737                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6738                                 r_nonce, uuid_r, e_pk)
6739     send_wsc_msg(dev[0], bssid, m2)
6740     eap_id = (eap_id + 1) % 256
6741
6742     logger.debug("Receive M3 from STA")
6743     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6744
6745     logger.debug("Send M4 to STA")
6746     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6747     attrs += build_attr_msg_type(WPS_M4)
6748     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6749     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6750     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6751     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6752     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6753     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6754     raw_m4_attrs = attrs
6755     m4 = build_eap_wsc(1, eap_id, attrs)
6756     send_wsc_msg(dev[0], bssid, m4)
6757     eap_id = (eap_id + 1) % 256
6758
6759     logger.debug("Receive M5 from STA")
6760     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6761
6762     logger.debug("Send M6 to STA")
6763     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6764     attrs += build_attr_msg_type(WPS_M6)
6765     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6766                             m1_attrs[ATTR_ENROLLEE_NONCE])
6767     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6768     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6769     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6770     raw_m6_attrs = attrs
6771     m6 = build_eap_wsc(1, eap_id, attrs)
6772     send_wsc_msg(dev[0], bssid, m6)
6773     eap_id = (eap_id + 1) % 256
6774
6775     logger.debug("Receive M7 from STA")
6776     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6777
6778     logger.debug("Send M8 to STA")
6779     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6780     attrs += build_attr_msg_type(WPS_M8)
6781     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6782                             m1_attrs[ATTR_ENROLLEE_NONCE])
6783     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6784     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6785     raw_m8_attrs = attrs
6786     m8 = build_eap_wsc(1, eap_id, attrs)
6787     send_wsc_msg(dev[0], bssid, m8)
6788     eap_id = (eap_id + 1) % 256
6789
6790     if no_connect:
6791         logger.debug("Receive WSC_Done from STA")
6792         msg = get_wsc_msg(dev[0])
6793         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6794             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6795
6796         hapd.request("SET ext_eapol_frame_io 0")
6797         dev[0].request("SET ext_eapol_frame_io 0")
6798
6799         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6800
6801         dev[0].wait_disconnected()
6802         dev[0].request("REMOVE_NETWORK all")
6803     elif connect:
6804         logger.debug("Receive WSC_Done from STA")
6805         msg = get_wsc_msg(dev[0])
6806         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6807             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6808
6809         hapd.request("SET ext_eapol_frame_io 0")
6810         dev[0].request("SET ext_eapol_frame_io 0")
6811
6812         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6813
6814         dev[0].wait_connected()
6815     else:
6816         # Verify STA NACK's the credential
6817         msg = get_wsc_msg(dev[0])
6818         if msg['wsc_opcode'] != WSC_NACK:
6819             raise Exception("Unexpected message - expected WSC_Nack")
6820         dev[0].request("WPS_CANCEL")
6821         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6822         dev[0].wait_disconnected()
6823
6824 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6825                encr_type='\x00\x08', nw_key="12345678",
6826                mac_addr='\x00\x00\x00\x00\x00\x00'):
6827     attrs = ''
6828     if nw_idx is not None:
6829         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6830     if ssid is not None:
6831         attrs += build_wsc_attr(ATTR_SSID, ssid)
6832     if auth_type is not None:
6833         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6834     if encr_type is not None:
6835         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6836     if nw_key is not None:
6837         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6838     if mac_addr is not None:
6839         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6840     return build_wsc_attr(ATTR_CRED, attrs)
6841
6842 def test_wps_ext_cred_proto_success(dev, apdev):
6843     """WPS and Credential: success"""
6844     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6845     m8_cred = build_cred(mac_addr=mac_addr)
6846     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6847
6848 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6849     """WPS and Credential: MAC Address mismatch"""
6850     m8_cred = build_cred()
6851     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6852
6853 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6854     """WPS and Credential: zeropadded attributes"""
6855     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6856     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6857                          nw_key="12345678\x00")
6858     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6859
6860 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6861     """WPS and Credential: SSID missing"""
6862     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6863     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6864     wps_run_cred_proto(dev, apdev, m8_cred)
6865
6866 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6867     """WPS and Credential: Zero-length SSID"""
6868     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6869     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6870     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6871
6872 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6873     """WPS and Credential: Auth Type missing"""
6874     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6875     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6876     wps_run_cred_proto(dev, apdev, m8_cred)
6877
6878 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6879     """WPS and Credential: Encr Type missing"""
6880     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6881     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6882     wps_run_cred_proto(dev, apdev, m8_cred)
6883
6884 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6885     """WPS and Credential: Network Key missing"""
6886     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6887     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6888     wps_run_cred_proto(dev, apdev, m8_cred)
6889
6890 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6891     """WPS and Credential: Network Key missing (open)"""
6892     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6893     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6894                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6895     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6896
6897 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6898     """WPS and Credential: MAC Address missing"""
6899     m8_cred = build_cred(mac_addr=None)
6900     wps_run_cred_proto(dev, apdev, m8_cred)
6901
6902 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6903     """WPS and Credential: Invalid Encr Type"""
6904     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6905     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6906     wps_run_cred_proto(dev, apdev, m8_cred)
6907
6908 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6909     """WPS and Credential: Missing Credential"""
6910     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6911     m8_cred = ''
6912     wps_run_cred_proto(dev, apdev, m8_cred)
6913
6914 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6915     """WPS and no Public Key in M2"""
6916     pin = "12345670"
6917     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6918     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6919     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6920     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6921
6922     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6923     uuid_r = 16*'\x33'
6924     r_nonce = 16*'\x44'
6925     own_private, e_pk = wsc_dh_init()
6926
6927     logger.debug("Receive M1 from STA")
6928     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6929     eap_id = (msg['eap_identifier'] + 1) % 256
6930
6931     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6932                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6933                                     r_nonce)
6934     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6935                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6936
6937     logger.debug("Send M2 to STA")
6938     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6939                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6940                                 r_nonce, uuid_r, None)
6941     send_wsc_msg(dev[0], bssid, m2)
6942     eap_id = (eap_id + 1) % 256
6943
6944     # Verify STA NACK's the credential
6945     msg = get_wsc_msg(dev[0])
6946     if msg['wsc_opcode'] != WSC_NACK:
6947         raise Exception("Unexpected message - expected WSC_Nack")
6948     dev[0].request("WPS_CANCEL")
6949     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6950     dev[0].wait_disconnected()
6951
6952 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6953     """WPS and invalid Public Key in M2"""
6954     pin = "12345670"
6955     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6956     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6957     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6958     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6959
6960     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6961     uuid_r = 16*'\x33'
6962     r_nonce = 16*'\x44'
6963     own_private, e_pk = wsc_dh_init()
6964
6965     logger.debug("Receive M1 from STA")
6966     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6967     eap_id = (msg['eap_identifier'] + 1) % 256
6968
6969     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6970                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6971                                     r_nonce)
6972     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6973                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6974
6975     logger.debug("Send M2 to STA")
6976     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6977                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6978                                 r_nonce, uuid_r, 192*'\xff')
6979     send_wsc_msg(dev[0], bssid, m2)
6980     eap_id = (eap_id + 1) % 256
6981
6982     # Verify STA NACK's the credential
6983     msg = get_wsc_msg(dev[0])
6984     if msg['wsc_opcode'] != WSC_NACK:
6985         raise Exception("Unexpected message - expected WSC_Nack")
6986     dev[0].request("WPS_CANCEL")
6987     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6988     dev[0].wait_disconnected()
6989
6990 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6991     """WPS and Public Key OOM in M2"""
6992     pin = "12345670"
6993     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6994     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6995     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6996     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6997
6998     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6999     uuid_r = 16*'\x33'
7000     r_nonce = 16*'\x44'
7001     own_private, e_pk = wsc_dh_init()
7002
7003     logger.debug("Receive M1 from STA")
7004     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7005     eap_id = (msg['eap_identifier'] + 1) % 256
7006
7007     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7008                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7009                                     r_nonce)
7010     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7011                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7012
7013     logger.debug("Send M2 to STA")
7014     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7015                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7016                                 r_nonce, uuid_r, e_pk)
7017     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
7018         send_wsc_msg(dev[0], bssid, m2)
7019         eap_id = (eap_id + 1) % 256
7020
7021         # Verify STA NACK's the credential
7022         msg = get_wsc_msg(dev[0])
7023         if msg['wsc_opcode'] != WSC_NACK:
7024             raise Exception("Unexpected message - expected WSC_Nack")
7025         dev[0].request("WPS_CANCEL")
7026         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7027         dev[0].wait_disconnected()
7028
7029 def test_wps_ext_proto_nack_m3(dev, apdev):
7030     """WPS and NACK M3"""
7031     pin = "12345670"
7032     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7033     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7034     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7035     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7036
7037     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7038     uuid_r = 16*'\x33'
7039     r_nonce = 16*'\x44'
7040     own_private, e_pk = wsc_dh_init()
7041
7042     logger.debug("Receive M1 from STA")
7043     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7044     eap_id = (msg['eap_identifier'] + 1) % 256
7045
7046     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7047                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7048                                     r_nonce)
7049     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7050                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7051
7052     logger.debug("Send M2 to STA")
7053     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7054                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7055                                 r_nonce, uuid_r, e_pk)
7056     send_wsc_msg(dev[0], bssid, m2)
7057     eap_id = (eap_id + 1) % 256
7058
7059     logger.debug("Receive M3 from STA")
7060     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7061
7062     logger.debug("Send NACK to STA")
7063     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
7064                             r_nonce, config_error='\x01\x23')
7065     send_wsc_msg(dev[0], bssid, msg)
7066     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
7067     if ev is None:
7068         raise Exception("Failure not reported")
7069     if "msg=7 config_error=291" not in ev:
7070         raise Exception("Unexpected failure reason: " + ev)
7071
7072 def test_wps_ext_proto_nack_m5(dev, apdev):
7073     """WPS and NACK M5"""
7074     pin = "12345670"
7075     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7076     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7077     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7078     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7079
7080     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7081     uuid_r = 16*'\x33'
7082     r_nonce = 16*'\x44'
7083     own_private, e_pk = wsc_dh_init()
7084
7085     logger.debug("Receive M1 from STA")
7086     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7087     eap_id = (msg['eap_identifier'] + 1) % 256
7088
7089     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7090                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7091                                     r_nonce)
7092     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7093                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7094
7095     logger.debug("Send M2 to STA")
7096     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7097                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7098                                 r_nonce, uuid_r, e_pk)
7099     send_wsc_msg(dev[0], bssid, m2)
7100     eap_id = (eap_id + 1) % 256
7101
7102     logger.debug("Receive M3 from STA")
7103     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7104
7105     logger.debug("Send M4 to STA")
7106     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7107     attrs += build_attr_msg_type(WPS_M4)
7108     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7109     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7110     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7111     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7112     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7113     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7114     raw_m4_attrs = attrs
7115     m4 = build_eap_wsc(1, eap_id, attrs)
7116     send_wsc_msg(dev[0], bssid, m4)
7117     eap_id = (eap_id + 1) % 256
7118
7119     logger.debug("Receive M5 from STA")
7120     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7121
7122     logger.debug("Send NACK to STA")
7123     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
7124                             r_nonce, config_error='\x01\x24')
7125     send_wsc_msg(dev[0], bssid, msg)
7126     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
7127     if ev is None:
7128         raise Exception("Failure not reported")
7129     if "msg=9 config_error=292" not in ev:
7130         raise Exception("Unexpected failure reason: " + ev)
7131
7132 def wps_nack_m3(dev, apdev):
7133     pin = "00000000"
7134     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
7135     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7136     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7137     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7138
7139     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7140     uuid_r = 16*'\x33'
7141     r_nonce = 16*'\x44'
7142     own_private, e_pk = wsc_dh_init()
7143
7144     logger.debug("Receive M1 from STA")
7145     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7146     eap_id = (msg['eap_identifier'] + 1) % 256
7147
7148     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7149                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7150                                     r_nonce)
7151     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7152                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7153
7154     logger.debug("Send M2 to STA")
7155     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7156                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7157                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
7158     send_wsc_msg(dev[0], bssid, m2)
7159     eap_id = (eap_id + 1) % 256
7160
7161     logger.debug("Receive M3 from STA")
7162     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7163     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
7164
7165 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
7166     """WPS and NACK M3 missing Config Error"""
7167     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7168     logger.debug("Send NACK to STA")
7169     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
7170     send_wsc_msg(dev[0], bssid, msg)
7171     dev[0].request("WPS_CANCEL")
7172     dev[0].wait_disconnected()
7173     dev[0].flush_scan_cache()
7174
7175 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
7176     """WPS and NACK M3 missing E-Nonce"""
7177     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7178     logger.debug("Send NACK to STA")
7179     msg, attrs = build_nack(eap_id, None, r_nonce)
7180     send_wsc_msg(dev[0], bssid, msg)
7181     dev[0].request("WPS_CANCEL")
7182     dev[0].wait_disconnected()
7183     dev[0].flush_scan_cache()
7184
7185 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
7186     """WPS and NACK M3 E-Nonce mismatch"""
7187     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7188     logger.debug("Send NACK to STA")
7189     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
7190     send_wsc_msg(dev[0], bssid, msg)
7191     dev[0].request("WPS_CANCEL")
7192     dev[0].wait_disconnected()
7193     dev[0].flush_scan_cache()
7194
7195 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
7196     """WPS and NACK M3 missing R-Nonce"""
7197     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7198     logger.debug("Send NACK to STA")
7199     msg, attrs = build_nack(eap_id, e_nonce, None)
7200     send_wsc_msg(dev[0], bssid, msg)
7201     dev[0].request("WPS_CANCEL")
7202     dev[0].wait_disconnected()
7203     dev[0].flush_scan_cache()
7204
7205 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
7206     """WPS and NACK M3 R-Nonce mismatch"""
7207     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7208     logger.debug("Send NACK to STA")
7209     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
7210     send_wsc_msg(dev[0], bssid, msg)
7211     dev[0].request("WPS_CANCEL")
7212     dev[0].wait_disconnected()
7213     dev[0].flush_scan_cache()
7214
7215 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
7216     """WPS and NACK M3 no Message Type"""
7217     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7218     logger.debug("Send NACK to STA")
7219     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
7220     send_wsc_msg(dev[0], bssid, msg)
7221     dev[0].request("WPS_CANCEL")
7222     dev[0].wait_disconnected()
7223     dev[0].flush_scan_cache()
7224
7225 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
7226     """WPS and NACK M3 invalid Message Type"""
7227     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7228     logger.debug("Send NACK to STA")
7229     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
7230     send_wsc_msg(dev[0], bssid, msg)
7231     dev[0].request("WPS_CANCEL")
7232     dev[0].wait_disconnected()
7233     dev[0].flush_scan_cache()
7234
7235 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
7236     """WPS and NACK M3 invalid attribute"""
7237     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7238     logger.debug("Send NACK to STA")
7239     attrs = '\x10\x10\x00'
7240     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
7241     send_wsc_msg(dev[0], bssid, msg)
7242     dev[0].request("WPS_CANCEL")
7243     dev[0].wait_disconnected()
7244     dev[0].flush_scan_cache()
7245
7246 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
7247     """WPS and ACK M3 missing E-Nonce"""
7248     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7249     logger.debug("Send NACK to STA")
7250     msg, attrs = build_ack(eap_id, None, r_nonce)
7251     send_wsc_msg(dev[0], bssid, msg)
7252     dev[0].request("WPS_CANCEL")
7253     dev[0].wait_disconnected()
7254     dev[0].flush_scan_cache()
7255
7256 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7257     """WPS and ACK M3 E-Nonce mismatch"""
7258     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7259     logger.debug("Send NACK to STA")
7260     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7261     send_wsc_msg(dev[0], bssid, msg)
7262     dev[0].request("WPS_CANCEL")
7263     dev[0].wait_disconnected()
7264     dev[0].flush_scan_cache()
7265
7266 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7267     """WPS and ACK M3 missing R-Nonce"""
7268     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7269     logger.debug("Send NACK to STA")
7270     msg, attrs = build_ack(eap_id, e_nonce, None)
7271     send_wsc_msg(dev[0], bssid, msg)
7272     dev[0].request("WPS_CANCEL")
7273     dev[0].wait_disconnected()
7274     dev[0].flush_scan_cache()
7275
7276 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7277     """WPS and ACK M3 R-Nonce mismatch"""
7278     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7279     logger.debug("Send NACK to STA")
7280     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7281     send_wsc_msg(dev[0], bssid, msg)
7282     dev[0].request("WPS_CANCEL")
7283     dev[0].wait_disconnected()
7284     dev[0].flush_scan_cache()
7285
7286 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7287     """WPS and ACK M3 no Message Type"""
7288     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7289     logger.debug("Send NACK to STA")
7290     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7291     send_wsc_msg(dev[0], bssid, msg)
7292     dev[0].request("WPS_CANCEL")
7293     dev[0].wait_disconnected()
7294     dev[0].flush_scan_cache()
7295
7296 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7297     """WPS and ACK M3 invalid Message Type"""
7298     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7299     logger.debug("Send NACK to STA")
7300     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7301     send_wsc_msg(dev[0], bssid, msg)
7302     dev[0].request("WPS_CANCEL")
7303     dev[0].wait_disconnected()
7304     dev[0].flush_scan_cache()
7305
7306 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7307     """WPS and ACK M3 invalid attribute"""
7308     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7309     logger.debug("Send ACK to STA")
7310     attrs = '\x10\x10\x00'
7311     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7312     send_wsc_msg(dev[0], bssid, msg)
7313     dev[0].request("WPS_CANCEL")
7314     dev[0].wait_disconnected()
7315     dev[0].flush_scan_cache()
7316
7317 def test_wps_ext_proto_ack_m3(dev, apdev):
7318     """WPS and ACK M3"""
7319     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7320     logger.debug("Send ACK to STA")
7321     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7322     send_wsc_msg(dev[0], bssid, msg)
7323     dev[0].request("WPS_CANCEL")
7324     dev[0].wait_disconnected()
7325     dev[0].flush_scan_cache()
7326
7327 def wps_to_m3_helper(dev, apdev):
7328     pin = "12345670"
7329     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7330     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7331     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7332     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7333
7334     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7335     uuid_r = 16*'\x33'
7336     r_nonce = 16*'\x44'
7337     own_private, e_pk = wsc_dh_init()
7338
7339     logger.debug("Receive M1 from STA")
7340     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7341     eap_id = (msg['eap_identifier'] + 1) % 256
7342
7343     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7344                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7345                                     r_nonce)
7346     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7347                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7348
7349     logger.debug("Send M2 to STA")
7350     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7351                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7352                                 r_nonce, uuid_r, e_pk)
7353     send_wsc_msg(dev[0], bssid, m2)
7354     eap_id = (eap_id + 1) % 256
7355
7356     logger.debug("Receive M3 from STA")
7357     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7358     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7359
7360 def wps_to_m3(dev, apdev):
7361     eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey = wps_to_m3_helper(dev, apdev)
7362     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7363
7364 def wps_to_m5(dev, apdev):
7365     eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey = wps_to_m3_helper(dev, apdev)
7366
7367     logger.debug("Send M4 to STA")
7368     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7369     attrs += build_attr_msg_type(WPS_M4)
7370     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7371     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7372     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7373     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7374     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7375     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7376     raw_m4_attrs = attrs
7377     m4 = build_eap_wsc(1, eap_id, attrs)
7378     send_wsc_msg(dev[0], bssid, m4)
7379     eap_id = (eap_id + 1) % 256
7380
7381     logger.debug("Receive M5 from STA")
7382     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7383
7384     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7385
7386 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7387     """WPS and no R-Hash1 in M4"""
7388     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7389
7390     logger.debug("Send M4 to STA")
7391     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7392     attrs += build_attr_msg_type(WPS_M4)
7393     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7394     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7395     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7396     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7397     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7398     attrs += build_attr_authenticator(authkey, m3, attrs)
7399     m4 = build_eap_wsc(1, eap_id, attrs)
7400     send_wsc_msg(dev[0], bssid, m4)
7401     eap_id = (eap_id + 1) % 256
7402
7403     logger.debug("Receive M5 (NACK) from STA")
7404     msg = get_wsc_msg(dev[0])
7405     if msg['wsc_opcode'] != WSC_NACK:
7406         raise Exception("Unexpected message - expected WSC_Nack")
7407
7408     dev[0].request("WPS_CANCEL")
7409     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7410     dev[0].wait_disconnected()
7411
7412 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7413     """WPS and no R-Hash2 in M4"""
7414     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7415
7416     logger.debug("Send M4 to STA")
7417     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7418     attrs += build_attr_msg_type(WPS_M4)
7419     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7420     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7421     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7422     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7423     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7424     attrs += build_attr_authenticator(authkey, m3, attrs)
7425     m4 = build_eap_wsc(1, eap_id, attrs)
7426     send_wsc_msg(dev[0], bssid, m4)
7427     eap_id = (eap_id + 1) % 256
7428
7429     logger.debug("Receive M5 (NACK) from STA")
7430     msg = get_wsc_msg(dev[0])
7431     if msg['wsc_opcode'] != WSC_NACK:
7432         raise Exception("Unexpected message - expected WSC_Nack")
7433
7434     dev[0].request("WPS_CANCEL")
7435     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7436     dev[0].wait_disconnected()
7437
7438 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7439     """WPS and no R-SNonce1 in M4"""
7440     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7441
7442     logger.debug("Send M4 to STA")
7443     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7444     attrs += build_attr_msg_type(WPS_M4)
7445     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7446     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7447     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7448     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7449     data = ''
7450     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7451     attrs += build_attr_authenticator(authkey, m3, attrs)
7452     m4 = build_eap_wsc(1, eap_id, attrs)
7453     send_wsc_msg(dev[0], bssid, m4)
7454     eap_id = (eap_id + 1) % 256
7455
7456     logger.debug("Receive M5 (NACK) from STA")
7457     msg = get_wsc_msg(dev[0])
7458     if msg['wsc_opcode'] != WSC_NACK:
7459         raise Exception("Unexpected message - expected WSC_Nack")
7460
7461     dev[0].request("WPS_CANCEL")
7462     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7463     dev[0].wait_disconnected()
7464
7465 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7466     """WPS and invalid pad string in M4"""
7467     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7468
7469     logger.debug("Send M4 to STA")
7470     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7471     attrs += build_attr_msg_type(WPS_M4)
7472     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7473     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7474     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7475     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7476
7477     m = hmac.new(authkey, data, hashlib.sha256)
7478     kwa = m.digest()[0:8]
7479     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7480     iv = 16*'\x99'
7481     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7482     pad_len = 16 - len(data) % 16
7483     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7484     data += ps
7485     wrapped = aes.encrypt(data)
7486     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7487
7488     attrs += build_attr_authenticator(authkey, m3, attrs)
7489     m4 = build_eap_wsc(1, eap_id, attrs)
7490     send_wsc_msg(dev[0], bssid, m4)
7491     eap_id = (eap_id + 1) % 256
7492
7493     logger.debug("Receive M5 (NACK) from STA")
7494     msg = get_wsc_msg(dev[0])
7495     if msg['wsc_opcode'] != WSC_NACK:
7496         raise Exception("Unexpected message - expected WSC_Nack")
7497
7498     dev[0].request("WPS_CANCEL")
7499     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7500     dev[0].wait_disconnected()
7501
7502 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7503     """WPS and invalid pad value in M4"""
7504     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7505
7506     logger.debug("Send M4 to STA")
7507     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7508     attrs += build_attr_msg_type(WPS_M4)
7509     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7510     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7511     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7512     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7513
7514     m = hmac.new(authkey, data, hashlib.sha256)
7515     kwa = m.digest()[0:8]
7516     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7517     iv = 16*'\x99'
7518     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7519     pad_len = 16 - len(data) % 16
7520     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7521     data += ps
7522     wrapped = aes.encrypt(data)
7523     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7524
7525     attrs += build_attr_authenticator(authkey, m3, attrs)
7526     m4 = build_eap_wsc(1, eap_id, attrs)
7527     send_wsc_msg(dev[0], bssid, m4)
7528     eap_id = (eap_id + 1) % 256
7529
7530     logger.debug("Receive M5 (NACK) from STA")
7531     msg = get_wsc_msg(dev[0])
7532     if msg['wsc_opcode'] != WSC_NACK:
7533         raise Exception("Unexpected message - expected WSC_Nack")
7534
7535     dev[0].request("WPS_CANCEL")
7536     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7537     dev[0].wait_disconnected()
7538
7539 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7540     """WPS and no Encr Settings in M4"""
7541     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7542
7543     logger.debug("Send M4 to STA")
7544     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7545     attrs += build_attr_msg_type(WPS_M4)
7546     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7547     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7548     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7549     attrs += build_attr_authenticator(authkey, m3, attrs)
7550     m4 = build_eap_wsc(1, eap_id, attrs)
7551     send_wsc_msg(dev[0], bssid, m4)
7552     eap_id = (eap_id + 1) % 256
7553
7554     logger.debug("Receive M5 (NACK) from STA")
7555     msg = get_wsc_msg(dev[0])
7556     if msg['wsc_opcode'] != WSC_NACK:
7557         raise Exception("Unexpected message - expected WSC_Nack")
7558
7559     dev[0].request("WPS_CANCEL")
7560     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7561     dev[0].wait_disconnected()
7562
7563 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7564     """WPS and no R-SNonce2 in M6"""
7565     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7566
7567     logger.debug("Send M6 to STA")
7568     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7569     attrs += build_attr_msg_type(WPS_M6)
7570     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7571     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7572     data = ''
7573     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7574     attrs += build_attr_authenticator(authkey, m5, attrs)
7575     m6 = build_eap_wsc(1, eap_id, attrs)
7576     send_wsc_msg(dev[0], bssid, m6)
7577     eap_id = (eap_id + 1) % 256
7578
7579     logger.debug("Receive M7 (NACK) from STA")
7580     msg = get_wsc_msg(dev[0])
7581     if msg['wsc_opcode'] != WSC_NACK:
7582         raise Exception("Unexpected message - expected WSC_Nack")
7583
7584     dev[0].request("WPS_CANCEL")
7585     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7586     dev[0].wait_disconnected()
7587
7588 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7589     """WPS and no Encr Settings in M6"""
7590     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7591
7592     logger.debug("Send M6 to STA")
7593     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7594     attrs += build_attr_msg_type(WPS_M6)
7595     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7596     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7597     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7598     attrs += build_attr_authenticator(authkey, m5, attrs)
7599     m6 = build_eap_wsc(1, eap_id, attrs)
7600     send_wsc_msg(dev[0], bssid, m6)
7601     eap_id = (eap_id + 1) % 256
7602
7603     logger.debug("Receive M7 (NACK) from STA")
7604     msg = get_wsc_msg(dev[0])
7605     if msg['wsc_opcode'] != WSC_NACK:
7606         raise Exception("Unexpected message - expected WSC_Nack")
7607
7608     dev[0].request("WPS_CANCEL")
7609     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7610     dev[0].wait_disconnected()
7611
7612 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7613     """WPS and no Encr Settings in M6"""
7614     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7615
7616     logger.debug("Send M6 to STA")
7617     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7618     attrs += build_attr_msg_type(WPS_M6)
7619     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7620     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7621     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7622     attrs += build_attr_authenticator(authkey, m5, attrs)
7623     raw_m6_attrs = attrs
7624     m6 = build_eap_wsc(1, eap_id, attrs)
7625     send_wsc_msg(dev[0], bssid, m6)
7626     eap_id = (eap_id + 1) % 256
7627
7628     logger.debug("Receive M7 from STA")
7629     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7630
7631     logger.debug("Send M8 to STA")
7632     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7633     attrs += build_attr_msg_type(WPS_M8)
7634     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7635     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7636     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7637     raw_m8_attrs = attrs
7638     m8 = build_eap_wsc(1, eap_id, attrs)
7639     send_wsc_msg(dev[0], bssid, m8)
7640
7641     logger.debug("Receive WSC_Done (NACK) from STA")
7642     msg = get_wsc_msg(dev[0])
7643     if msg['wsc_opcode'] != WSC_NACK:
7644         raise Exception("Unexpected message - expected WSC_Nack")
7645
7646     dev[0].request("WPS_CANCEL")
7647     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7648     dev[0].wait_disconnected()
7649
7650 def wps_start_ext_reg(apdev, dev):
7651     addr = dev.own_addr()
7652     bssid = apdev['bssid']
7653     ssid = "test-wps-conf"
7654     appin = "12345670"
7655     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7656                "wpa_passphrase": "12345678", "wpa": "2",
7657                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7658                "ap_pin": appin }
7659     hapd = hostapd.add_ap(apdev['ifname'], params)
7660
7661     dev.scan_for_bss(bssid, freq="2412")
7662     hapd.request("SET ext_eapol_frame_io 1")
7663     dev.request("SET ext_eapol_frame_io 1")
7664
7665     dev.request("WPS_REG " + bssid + " " + appin)
7666
7667     return addr,bssid,hapd
7668
7669 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7670     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7671     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7672     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7673
7674     logger.debug("Receive M1 from AP")
7675     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7676     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7677     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7678     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7679
7680     appin = '12345670'
7681     uuid_r = 16*'\x33'
7682     r_nonce = 16*'\x44'
7683     own_private, r_pk = wsc_dh_init()
7684     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7685                                     r_nonce)
7686     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7687
7688     logger.debug("Send M2 to AP")
7689     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7690                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7691     send_wsc_msg(hapd, addr, m2)
7692
7693     logger.debug("Receive M3 from AP")
7694     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7695
7696     logger.debug("Send M4 to AP")
7697     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7698     attrs += build_attr_msg_type(WPS_M4)
7699     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7700     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7701     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7702     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7703     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7704     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7705     raw_m4_attrs = attrs
7706     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7707     send_wsc_msg(hapd, addr, m4)
7708
7709     logger.debug("Receive M5 from AP")
7710     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7711
7712     logger.debug("Send M6 to STA")
7713     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7714     attrs += build_attr_msg_type(WPS_M6)
7715     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7716     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7717     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7718     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7719     raw_m6_attrs = attrs
7720     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7721     send_wsc_msg(hapd, addr, m6)
7722
7723     logger.debug("Receive M7 from AP")
7724     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7725
7726     logger.debug("Send M8 to STA")
7727     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7728     attrs += build_attr_msg_type(WPS_M8)
7729     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7730     if ap_settings:
7731         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7732     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7733     raw_m8_attrs = attrs
7734     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7735     send_wsc_msg(hapd, addr, m8)
7736
7737     if success:
7738         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7739         if ev is None:
7740             raise Exception("New AP settings not reported")
7741         logger.debug("Receive WSC_Done from AP")
7742         msg = get_wsc_msg(hapd)
7743         if msg['wsc_opcode'] != WSC_Done:
7744             raise Exception("Unexpected message - expected WSC_Done")
7745
7746         logger.debug("Send WSC_ACK to AP")
7747         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7748                               eap_code=2)
7749         send_wsc_msg(hapd, addr, ack)
7750         dev[0].wait_disconnected()
7751     else:
7752         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7753         if ev is None:
7754             raise Exception("WPS failure not reported")
7755         logger.debug("Receive WSC_NACK from AP")
7756         msg = get_wsc_msg(hapd)
7757         if msg['wsc_opcode'] != WSC_NACK:
7758             raise Exception("Unexpected message - expected WSC_NACK")
7759
7760         logger.debug("Send WSC_NACK to AP")
7761         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7762                                 eap_code=2)
7763         send_wsc_msg(hapd, addr, nack)
7764         dev[0].wait_disconnected()
7765
7766 def test_wps_ext_ap_settings_success(dev, apdev):
7767     """WPS and AP Settings: success"""
7768     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7769     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7770     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7771     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7772     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7773     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7774     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7775
7776 def test_wps_ext_ap_settings_missing(dev, apdev):
7777     """WPS and AP Settings: missing"""
7778     wps_run_ap_settings_proto(dev, apdev, None, False)
7779
7780 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7781     """WPS and AP Settings: MAC Address mismatch"""
7782     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7783     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7784     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7785     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7786     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7787     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7788     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7789
7790 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7791     """WPS and AP Settings: missing MAC Address"""
7792     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7793     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7794     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7795     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7796     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7797     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7798
7799 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7800     """WPS and AP Settings: reject Encr Type"""
7801     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7802     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7803     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7804     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7805     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7806     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7807     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7808
7809 def test_wps_ext_ap_settings_m2d(dev, apdev):
7810     """WPS and AP Settings: M2D"""
7811     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7812     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7813     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7814
7815     logger.debug("Receive M1 from AP")
7816     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7817     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7818
7819     r_nonce = 16*'\x44'
7820     uuid_r = 16*'\x33'
7821
7822     logger.debug("Send M2D to AP")
7823     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7824                                    e_nonce, r_nonce, uuid_r,
7825                                    dev_pw_id='\x00\x00', eap_code=2)
7826     send_wsc_msg(hapd, addr, m2d)
7827
7828     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7829     if ev is None:
7830         raise Exception("M2D not reported")
7831
7832     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7833
7834 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7835     logger.debug("Receive WSC_NACK from AP")
7836     msg = get_wsc_msg(hapd)
7837     if msg['wsc_opcode'] != WSC_NACK:
7838         raise Exception("Unexpected message - expected WSC_NACK")
7839
7840     logger.debug("Send WSC_NACK to AP")
7841     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7842                             eap_code=2)
7843     send_wsc_msg(hapd, dev.own_addr(), nack)
7844     dev.wait_disconnected()
7845
7846 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7847     """WPS proto: M3 missing E-Hash1"""
7848     pin = "12345670"
7849     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7850     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7851     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7852
7853     logger.debug("Receive WSC/Start from AP")
7854     msg = get_wsc_msg(hapd)
7855     if msg['wsc_opcode'] != WSC_Start:
7856         raise Exception("Unexpected Op-Code for WSC/Start")
7857
7858     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7859     uuid_e = 16*'\x11'
7860     e_nonce = 16*'\x22'
7861     own_private, e_pk = wsc_dh_init()
7862
7863     logger.debug("Send M1 to AP")
7864     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7865                                 e_nonce, e_pk)
7866     send_wsc_msg(hapd, addr, m1)
7867
7868     logger.debug("Receive M2 from AP")
7869     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7870     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7871     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7872
7873     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7874                                     r_nonce)
7875     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7876
7877     logger.debug("Send M3 to AP")
7878     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7879     attrs += build_attr_msg_type(WPS_M3)
7880     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7881     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7882     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7883     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7884     raw_m3_attrs = attrs
7885     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7886     send_wsc_msg(hapd, addr, m3)
7887
7888     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7889
7890 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7891     """WPS proto: M3 missing E-Hash2"""
7892     pin = "12345670"
7893     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7894     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7895     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7896
7897     logger.debug("Receive WSC/Start from AP")
7898     msg = get_wsc_msg(hapd)
7899     if msg['wsc_opcode'] != WSC_Start:
7900         raise Exception("Unexpected Op-Code for WSC/Start")
7901
7902     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7903     uuid_e = 16*'\x11'
7904     e_nonce = 16*'\x22'
7905     own_private, e_pk = wsc_dh_init()
7906
7907     logger.debug("Send M1 to AP")
7908     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7909                                 e_nonce, e_pk)
7910     send_wsc_msg(hapd, addr, m1)
7911
7912     logger.debug("Receive M2 from AP")
7913     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7914     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7915     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7916
7917     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7918                                     r_nonce)
7919     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7920
7921     logger.debug("Send M3 to AP")
7922     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7923     attrs += build_attr_msg_type(WPS_M3)
7924     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7925     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7926     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7927     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7928     raw_m3_attrs = attrs
7929     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7930     send_wsc_msg(hapd, addr, m3)
7931
7932     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7933
7934 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7935     """WPS proto: M5 missing E-SNonce1"""
7936     pin = "12345670"
7937     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7938     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7939     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7940
7941     logger.debug("Receive WSC/Start from AP")
7942     msg = get_wsc_msg(hapd)
7943     if msg['wsc_opcode'] != WSC_Start:
7944         raise Exception("Unexpected Op-Code for WSC/Start")
7945
7946     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7947     uuid_e = 16*'\x11'
7948     e_nonce = 16*'\x22'
7949     own_private, e_pk = wsc_dh_init()
7950
7951     logger.debug("Send M1 to AP")
7952     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7953                                 e_nonce, e_pk)
7954     send_wsc_msg(hapd, addr, m1)
7955
7956     logger.debug("Receive M2 from AP")
7957     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7958     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7959     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7960
7961     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7962                                     r_nonce)
7963     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7964
7965     logger.debug("Send M3 to AP")
7966     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7967     attrs += build_attr_msg_type(WPS_M3)
7968     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7969     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7970     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7971     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7972     raw_m3_attrs = attrs
7973     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7974     send_wsc_msg(hapd, addr, m3)
7975
7976     logger.debug("Receive M4 from AP")
7977     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7978
7979     logger.debug("Send M5 to AP")
7980     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7981     attrs += build_attr_msg_type(WPS_M5)
7982     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7983     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7984     data = ''
7985     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7986     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7987     raw_m5_attrs = attrs
7988     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7989     send_wsc_msg(hapd, addr, m5)
7990
7991     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7992
7993 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7994     """WPS proto: M5 E-SNonce1 mismatch"""
7995     pin = "12345670"
7996     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7997     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7998     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7999
8000     logger.debug("Receive WSC/Start from AP")
8001     msg = get_wsc_msg(hapd)
8002     if msg['wsc_opcode'] != WSC_Start:
8003         raise Exception("Unexpected Op-Code for WSC/Start")
8004
8005     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8006     uuid_e = 16*'\x11'
8007     e_nonce = 16*'\x22'
8008     own_private, e_pk = wsc_dh_init()
8009
8010     logger.debug("Send M1 to AP")
8011     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8012                                 e_nonce, e_pk)
8013     send_wsc_msg(hapd, addr, m1)
8014
8015     logger.debug("Receive M2 from AP")
8016     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8017     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8018     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8019
8020     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8021                                     r_nonce)
8022     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8023
8024     logger.debug("Send M3 to AP")
8025     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8026     attrs += build_attr_msg_type(WPS_M3)
8027     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8028     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8029     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8030     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8031     raw_m3_attrs = attrs
8032     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8033     send_wsc_msg(hapd, addr, m3)
8034
8035     logger.debug("Receive M4 from AP")
8036     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8037
8038     logger.debug("Send M5 to AP")
8039     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8040     attrs += build_attr_msg_type(WPS_M5)
8041     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8042     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
8043     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8044     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8045     raw_m5_attrs = attrs
8046     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8047     send_wsc_msg(hapd, addr, m5)
8048
8049     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8050
8051 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
8052     """WPS proto: M7 missing E-SNonce2"""
8053     pin = "12345670"
8054     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8055     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8056     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8057
8058     logger.debug("Receive WSC/Start from AP")
8059     msg = get_wsc_msg(hapd)
8060     if msg['wsc_opcode'] != WSC_Start:
8061         raise Exception("Unexpected Op-Code for WSC/Start")
8062
8063     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8064     uuid_e = 16*'\x11'
8065     e_nonce = 16*'\x22'
8066     own_private, e_pk = wsc_dh_init()
8067
8068     logger.debug("Send M1 to AP")
8069     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8070                                 e_nonce, e_pk)
8071     send_wsc_msg(hapd, addr, m1)
8072
8073     logger.debug("Receive M2 from AP")
8074     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8075     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8076     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8077
8078     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8079                                     r_nonce)
8080     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8081
8082     logger.debug("Send M3 to AP")
8083     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8084     attrs += build_attr_msg_type(WPS_M3)
8085     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8086     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8087     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8088     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8089     raw_m3_attrs = attrs
8090     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8091     send_wsc_msg(hapd, addr, m3)
8092
8093     logger.debug("Receive M4 from AP")
8094     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8095
8096     logger.debug("Send M5 to AP")
8097     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8098     attrs += build_attr_msg_type(WPS_M5)
8099     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8100     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8101     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8102     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8103     raw_m5_attrs = attrs
8104     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8105     send_wsc_msg(hapd, addr, m5)
8106
8107     logger.debug("Receive M6 from AP")
8108     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8109
8110     logger.debug("Send M7 to AP")
8111     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8112     attrs += build_attr_msg_type(WPS_M7)
8113     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8114     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8115     data = ''
8116     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8117     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8118     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8119     raw_m7_attrs = attrs
8120     send_wsc_msg(hapd, addr, m7)
8121
8122     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8123
8124 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
8125     """WPS proto: M7 E-SNonce2 mismatch"""
8126     pin = "12345670"
8127     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8128     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8129     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8130
8131     logger.debug("Receive WSC/Start from AP")
8132     msg = get_wsc_msg(hapd)
8133     if msg['wsc_opcode'] != WSC_Start:
8134         raise Exception("Unexpected Op-Code for WSC/Start")
8135
8136     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8137     uuid_e = 16*'\x11'
8138     e_nonce = 16*'\x22'
8139     own_private, e_pk = wsc_dh_init()
8140
8141     logger.debug("Send M1 to AP")
8142     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8143                                 e_nonce, e_pk)
8144     send_wsc_msg(hapd, addr, m1)
8145
8146     logger.debug("Receive M2 from AP")
8147     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8148     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8149     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8150
8151     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8152                                     r_nonce)
8153     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8154
8155     logger.debug("Send M3 to AP")
8156     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8157     attrs += build_attr_msg_type(WPS_M3)
8158     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8159     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8160     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8161     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8162     raw_m3_attrs = attrs
8163     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8164     send_wsc_msg(hapd, addr, m3)
8165
8166     logger.debug("Receive M4 from AP")
8167     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8168
8169     logger.debug("Send M5 to AP")
8170     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8171     attrs += build_attr_msg_type(WPS_M5)
8172     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8173     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8174     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8175     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8176     raw_m5_attrs = attrs
8177     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8178     send_wsc_msg(hapd, addr, m5)
8179
8180     logger.debug("Receive M6 from AP")
8181     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8182
8183     logger.debug("Send M7 to AP")
8184     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8185     attrs += build_attr_msg_type(WPS_M7)
8186     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8187     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
8188     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8189     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8190     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8191     raw_m7_attrs = attrs
8192     send_wsc_msg(hapd, addr, m7)
8193
8194     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8195
8196 def test_wps_ext_m1_pubkey_oom(dev, apdev):
8197     """WPS proto: M1 PubKey OOM"""
8198     pin = "12345670"
8199     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8200     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8201     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8202
8203     logger.debug("Receive WSC/Start from AP")
8204     msg = get_wsc_msg(hapd)
8205     if msg['wsc_opcode'] != WSC_Start:
8206         raise Exception("Unexpected Op-Code for WSC/Start")
8207
8208     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8209     uuid_e = 16*'\x11'
8210     e_nonce = 16*'\x22'
8211     own_private, e_pk = wsc_dh_init()
8212
8213     logger.debug("Send M1 to AP")
8214     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
8215         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8216                                     e_nonce, e_pk)
8217         send_wsc_msg(hapd, addr, m1)
8218         wps_wait_eap_failure(hapd, dev[0])
8219
8220 def wps_wait_eap_failure(hapd, dev):
8221     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8222     if ev is None:
8223         raise Exception("EAP-Failure not reported")
8224     dev.wait_disconnected()
8225
8226 def test_wps_ext_m3_m1(dev, apdev):
8227     """WPS proto: M3 replaced with M1"""
8228     pin = "12345670"
8229     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8230     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8231     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8232
8233     logger.debug("Receive WSC/Start from AP")
8234     msg = get_wsc_msg(hapd)
8235     if msg['wsc_opcode'] != WSC_Start:
8236         raise Exception("Unexpected Op-Code for WSC/Start")
8237
8238     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8239     uuid_e = 16*'\x11'
8240     e_nonce = 16*'\x22'
8241     own_private, e_pk = wsc_dh_init()
8242
8243     logger.debug("Send M1 to AP")
8244     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8245                                 e_nonce, e_pk)
8246     send_wsc_msg(hapd, addr, m1)
8247
8248     logger.debug("Receive M2 from AP")
8249     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8250     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8251     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8252
8253     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8254                                     r_nonce)
8255     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8256
8257     logger.debug("Send M3(M1) to AP")
8258     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8259     attrs += build_attr_msg_type(WPS_M1)
8260     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8261     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8262     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8263     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8264     raw_m3_attrs = attrs
8265     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8266     send_wsc_msg(hapd, addr, m3)
8267
8268     wps_wait_eap_failure(hapd, dev[0])
8269
8270 def test_wps_ext_m5_m3(dev, apdev):
8271     """WPS proto: M5 replaced with M3"""
8272     pin = "12345670"
8273     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8274     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8275     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8276
8277     logger.debug("Receive WSC/Start from AP")
8278     msg = get_wsc_msg(hapd)
8279     if msg['wsc_opcode'] != WSC_Start:
8280         raise Exception("Unexpected Op-Code for WSC/Start")
8281
8282     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8283     uuid_e = 16*'\x11'
8284     e_nonce = 16*'\x22'
8285     own_private, e_pk = wsc_dh_init()
8286
8287     logger.debug("Send M1 to AP")
8288     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8289                                 e_nonce, e_pk)
8290     send_wsc_msg(hapd, addr, m1)
8291
8292     logger.debug("Receive M2 from AP")
8293     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8294     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8295     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8296
8297     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8298                                     r_nonce)
8299     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8300
8301     logger.debug("Send M3 to AP")
8302     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8303     attrs += build_attr_msg_type(WPS_M3)
8304     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8305     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8306     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8307     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8308     raw_m3_attrs = attrs
8309     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8310     send_wsc_msg(hapd, addr, m3)
8311
8312     logger.debug("Receive M4 from AP")
8313     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8314
8315     logger.debug("Send M5(M3) to AP")
8316     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8317     attrs += build_attr_msg_type(WPS_M3)
8318     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8319     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8320     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8321     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8322     raw_m5_attrs = attrs
8323     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8324     send_wsc_msg(hapd, addr, m5)
8325
8326     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8327
8328 def test_wps_ext_m3_m2(dev, apdev):
8329     """WPS proto: M3 replaced with M2"""
8330     pin = "12345670"
8331     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8332     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8333     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8334
8335     logger.debug("Receive WSC/Start from AP")
8336     msg = get_wsc_msg(hapd)
8337     if msg['wsc_opcode'] != WSC_Start:
8338         raise Exception("Unexpected Op-Code for WSC/Start")
8339
8340     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8341     uuid_e = 16*'\x11'
8342     e_nonce = 16*'\x22'
8343     own_private, e_pk = wsc_dh_init()
8344
8345     logger.debug("Send M1 to AP")
8346     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8347                                 e_nonce, e_pk)
8348     send_wsc_msg(hapd, addr, m1)
8349
8350     logger.debug("Receive M2 from AP")
8351     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8352     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8353     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8354
8355     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8356                                     r_nonce)
8357     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8358
8359     logger.debug("Send M3(M2) to AP")
8360     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8361     attrs += build_attr_msg_type(WPS_M2)
8362     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8363     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8364     raw_m3_attrs = attrs
8365     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8366     send_wsc_msg(hapd, addr, m3)
8367
8368     wps_wait_eap_failure(hapd, dev[0])
8369
8370 def test_wps_ext_m3_m5(dev, apdev):
8371     """WPS proto: M3 replaced with M5"""
8372     pin = "12345670"
8373     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8374     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8375     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8376
8377     logger.debug("Receive WSC/Start from AP")
8378     msg = get_wsc_msg(hapd)
8379     if msg['wsc_opcode'] != WSC_Start:
8380         raise Exception("Unexpected Op-Code for WSC/Start")
8381
8382     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8383     uuid_e = 16*'\x11'
8384     e_nonce = 16*'\x22'
8385     own_private, e_pk = wsc_dh_init()
8386
8387     logger.debug("Send M1 to AP")
8388     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8389                                 e_nonce, e_pk)
8390     send_wsc_msg(hapd, addr, m1)
8391
8392     logger.debug("Receive M2 from AP")
8393     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8394     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8395     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8396
8397     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8398                                     r_nonce)
8399     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8400
8401     logger.debug("Send M3(M5) to AP")
8402     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8403     attrs += build_attr_msg_type(WPS_M5)
8404     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8405     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8406     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8407     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8408     raw_m3_attrs = attrs
8409     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8410     send_wsc_msg(hapd, addr, m3)
8411
8412     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8413
8414 def test_wps_ext_m3_m7(dev, apdev):
8415     """WPS proto: M3 replaced with M7"""
8416     pin = "12345670"
8417     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8418     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8419     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8420
8421     logger.debug("Receive WSC/Start from AP")
8422     msg = get_wsc_msg(hapd)
8423     if msg['wsc_opcode'] != WSC_Start:
8424         raise Exception("Unexpected Op-Code for WSC/Start")
8425
8426     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8427     uuid_e = 16*'\x11'
8428     e_nonce = 16*'\x22'
8429     own_private, e_pk = wsc_dh_init()
8430
8431     logger.debug("Send M1 to AP")
8432     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8433                                 e_nonce, e_pk)
8434     send_wsc_msg(hapd, addr, m1)
8435
8436     logger.debug("Receive M2 from AP")
8437     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8438     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8439     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8440
8441     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8442                                     r_nonce)
8443     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8444
8445     logger.debug("Send M3(M7) to AP")
8446     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8447     attrs += build_attr_msg_type(WPS_M7)
8448     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8449     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8450     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8451     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8452     raw_m3_attrs = attrs
8453     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8454     send_wsc_msg(hapd, addr, m3)
8455
8456     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8457
8458 def test_wps_ext_m3_done(dev, apdev):
8459     """WPS proto: M3 replaced with WSC_Done"""
8460     pin = "12345670"
8461     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8462     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8463     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8464
8465     logger.debug("Receive WSC/Start from AP")
8466     msg = get_wsc_msg(hapd)
8467     if msg['wsc_opcode'] != WSC_Start:
8468         raise Exception("Unexpected Op-Code for WSC/Start")
8469
8470     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8471     uuid_e = 16*'\x11'
8472     e_nonce = 16*'\x22'
8473     own_private, e_pk = wsc_dh_init()
8474
8475     logger.debug("Send M1 to AP")
8476     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8477                                 e_nonce, e_pk)
8478     send_wsc_msg(hapd, addr, m1)
8479
8480     logger.debug("Receive M2 from AP")
8481     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8482     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8483     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8484
8485     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8486                                     r_nonce)
8487     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8488
8489     logger.debug("Send M3(WSC_Done) to AP")
8490     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8491     attrs += build_attr_msg_type(WPS_WSC_DONE)
8492     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8493     raw_m3_attrs = attrs
8494     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8495     send_wsc_msg(hapd, addr, m3)
8496
8497     wps_wait_eap_failure(hapd, dev[0])
8498
8499 def test_wps_ext_m2_nack_invalid(dev, apdev):
8500     """WPS proto: M2 followed by invalid NACK"""
8501     pin = "12345670"
8502     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8503     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8504     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8505
8506     logger.debug("Receive WSC/Start from AP")
8507     msg = get_wsc_msg(hapd)
8508     if msg['wsc_opcode'] != WSC_Start:
8509         raise Exception("Unexpected Op-Code for WSC/Start")
8510
8511     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8512     uuid_e = 16*'\x11'
8513     e_nonce = 16*'\x22'
8514     own_private, e_pk = wsc_dh_init()
8515
8516     logger.debug("Send M1 to AP")
8517     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8518                                 e_nonce, e_pk)
8519     send_wsc_msg(hapd, addr, m1)
8520
8521     logger.debug("Receive M2 from AP")
8522     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8523     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8524     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8525
8526     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8527                                     r_nonce)
8528     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8529
8530     logger.debug("Send WSC_NACK to AP")
8531     attrs = '\x10\x00\x00'
8532     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8533     send_wsc_msg(hapd, addr, nack)
8534
8535     wps_wait_eap_failure(hapd, dev[0])
8536
8537 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8538     """WPS proto: M2 followed by NACK without Msg Type"""
8539     pin = "12345670"
8540     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8541     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8542     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8543
8544     logger.debug("Receive WSC/Start from AP")
8545     msg = get_wsc_msg(hapd)
8546     if msg['wsc_opcode'] != WSC_Start:
8547         raise Exception("Unexpected Op-Code for WSC/Start")
8548
8549     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8550     uuid_e = 16*'\x11'
8551     e_nonce = 16*'\x22'
8552     own_private, e_pk = wsc_dh_init()
8553
8554     logger.debug("Send M1 to AP")
8555     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8556                                 e_nonce, e_pk)
8557     send_wsc_msg(hapd, addr, m1)
8558
8559     logger.debug("Receive M2 from AP")
8560     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8561     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8562     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8563
8564     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8565                                     r_nonce)
8566     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8567
8568     logger.debug("Send WSC_NACK to AP")
8569     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8570                             msg_type=None, eap_code=2)
8571     send_wsc_msg(hapd, addr, nack)
8572
8573     wps_wait_eap_failure(hapd, dev[0])
8574
8575 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8576     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8577     pin = "12345670"
8578     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8579     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8580     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8581
8582     logger.debug("Receive WSC/Start from AP")
8583     msg = get_wsc_msg(hapd)
8584     if msg['wsc_opcode'] != WSC_Start:
8585         raise Exception("Unexpected Op-Code for WSC/Start")
8586
8587     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8588     uuid_e = 16*'\x11'
8589     e_nonce = 16*'\x22'
8590     own_private, e_pk = wsc_dh_init()
8591
8592     logger.debug("Send M1 to AP")
8593     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8594                                 e_nonce, e_pk)
8595     send_wsc_msg(hapd, addr, m1)
8596
8597     logger.debug("Receive M2 from AP")
8598     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8599     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8600     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8601
8602     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8603                                     r_nonce)
8604     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8605
8606     logger.debug("Send WSC_NACK to AP")
8607     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8608                             msg_type=WPS_WSC_ACK, eap_code=2)
8609     send_wsc_msg(hapd, addr, nack)
8610
8611     wps_wait_eap_failure(hapd, dev[0])
8612
8613 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8614     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8615     pin = "12345670"
8616     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8617     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8618     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8619
8620     logger.debug("Receive WSC/Start from AP")
8621     msg = get_wsc_msg(hapd)
8622     if msg['wsc_opcode'] != WSC_Start:
8623         raise Exception("Unexpected Op-Code for WSC/Start")
8624
8625     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8626     uuid_e = 16*'\x11'
8627     e_nonce = 16*'\x22'
8628     own_private, e_pk = wsc_dh_init()
8629
8630     logger.debug("Send M1 to AP")
8631     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8632                                 e_nonce, e_pk)
8633     send_wsc_msg(hapd, addr, m1)
8634
8635     logger.debug("Receive M2 from AP")
8636     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8637     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8638     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8639
8640     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8641                                     r_nonce)
8642     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8643
8644     logger.debug("Send WSC_NACK to AP")
8645     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8646                             eap_code=2)
8647     send_wsc_msg(hapd, addr, nack)
8648
8649     wps_wait_eap_failure(hapd, dev[0])
8650
8651 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8652     """WPS proto: M2 followed by NACK without Config Error"""
8653     pin = "12345670"
8654     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8655     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8656     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8657
8658     logger.debug("Receive WSC/Start from AP")
8659     msg = get_wsc_msg(hapd)
8660     if msg['wsc_opcode'] != WSC_Start:
8661         raise Exception("Unexpected Op-Code for WSC/Start")
8662
8663     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8664     uuid_e = 16*'\x11'
8665     e_nonce = 16*'\x22'
8666     own_private, e_pk = wsc_dh_init()
8667
8668     logger.debug("Send M1 to AP")
8669     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8670                                 e_nonce, e_pk)
8671     send_wsc_msg(hapd, addr, m1)
8672
8673     logger.debug("Receive M2 from AP")
8674     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8675     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8676     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8677
8678     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8679                                     r_nonce)
8680     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8681
8682     logger.debug("Send WSC_NACK to AP")
8683     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8684                             config_error=None, eap_code=2)
8685     send_wsc_msg(hapd, addr, nack)
8686
8687     wps_wait_eap_failure(hapd, dev[0])
8688
8689 def test_wps_ext_m2_ack_invalid(dev, apdev):
8690     """WPS proto: M2 followed by invalid ACK"""
8691     pin = "12345670"
8692     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8693     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8694     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8695
8696     logger.debug("Receive WSC/Start from AP")
8697     msg = get_wsc_msg(hapd)
8698     if msg['wsc_opcode'] != WSC_Start:
8699         raise Exception("Unexpected Op-Code for WSC/Start")
8700
8701     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8702     uuid_e = 16*'\x11'
8703     e_nonce = 16*'\x22'
8704     own_private, e_pk = wsc_dh_init()
8705
8706     logger.debug("Send M1 to AP")
8707     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8708                                 e_nonce, e_pk)
8709     send_wsc_msg(hapd, addr, m1)
8710
8711     logger.debug("Receive M2 from AP")
8712     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8713     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8714     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8715
8716     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8717                                     r_nonce)
8718     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8719
8720     logger.debug("Send WSC_ACK to AP")
8721     attrs = '\x10\x00\x00'
8722     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8723     send_wsc_msg(hapd, addr, ack)
8724
8725     wps_wait_eap_failure(hapd, dev[0])
8726
8727 def test_wps_ext_m2_ack(dev, apdev):
8728     """WPS proto: M2 followed by ACK"""
8729     pin = "12345670"
8730     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8731     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8732     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8733
8734     logger.debug("Receive WSC/Start from AP")
8735     msg = get_wsc_msg(hapd)
8736     if msg['wsc_opcode'] != WSC_Start:
8737         raise Exception("Unexpected Op-Code for WSC/Start")
8738
8739     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8740     uuid_e = 16*'\x11'
8741     e_nonce = 16*'\x22'
8742     own_private, e_pk = wsc_dh_init()
8743
8744     logger.debug("Send M1 to AP")
8745     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8746                                 e_nonce, e_pk)
8747     send_wsc_msg(hapd, addr, m1)
8748
8749     logger.debug("Receive M2 from AP")
8750     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8751     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8752     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8753
8754     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8755                                     r_nonce)
8756     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8757
8758     logger.debug("Send WSC_ACK to AP")
8759     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8760     send_wsc_msg(hapd, addr, ack)
8761
8762     wps_wait_eap_failure(hapd, dev[0])
8763
8764 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8765     """WPS proto: M2 followed by ACK missing Msg Type"""
8766     pin = "12345670"
8767     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8768     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8769     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8770
8771     logger.debug("Receive WSC/Start from AP")
8772     msg = get_wsc_msg(hapd)
8773     if msg['wsc_opcode'] != WSC_Start:
8774         raise Exception("Unexpected Op-Code for WSC/Start")
8775
8776     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8777     uuid_e = 16*'\x11'
8778     e_nonce = 16*'\x22'
8779     own_private, e_pk = wsc_dh_init()
8780
8781     logger.debug("Send M1 to AP")
8782     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8783                                 e_nonce, e_pk)
8784     send_wsc_msg(hapd, addr, m1)
8785
8786     logger.debug("Receive M2 from AP")
8787     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8788     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8789     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8790
8791     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8792                                     r_nonce)
8793     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8794
8795     logger.debug("Send WSC_ACK to AP")
8796     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8797                           msg_type=None, eap_code=2)
8798     send_wsc_msg(hapd, addr, ack)
8799
8800     wps_wait_eap_failure(hapd, dev[0])
8801
8802 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8803     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8804     pin = "12345670"
8805     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8806     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8807     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8808
8809     logger.debug("Receive WSC/Start from AP")
8810     msg = get_wsc_msg(hapd)
8811     if msg['wsc_opcode'] != WSC_Start:
8812         raise Exception("Unexpected Op-Code for WSC/Start")
8813
8814     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8815     uuid_e = 16*'\x11'
8816     e_nonce = 16*'\x22'
8817     own_private, e_pk = wsc_dh_init()
8818
8819     logger.debug("Send M1 to AP")
8820     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8821                                 e_nonce, e_pk)
8822     send_wsc_msg(hapd, addr, m1)
8823
8824     logger.debug("Receive M2 from AP")
8825     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8826     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8827     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8828
8829     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8830                                     r_nonce)
8831     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8832
8833     logger.debug("Send WSC_ACK to AP")
8834     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8835                           msg_type=WPS_WSC_NACK, eap_code=2)
8836     send_wsc_msg(hapd, addr, ack)
8837
8838     wps_wait_eap_failure(hapd, dev[0])
8839
8840 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8841     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8842     pin = "12345670"
8843     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8844     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8845     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8846
8847     logger.debug("Receive WSC/Start from AP")
8848     msg = get_wsc_msg(hapd)
8849     if msg['wsc_opcode'] != WSC_Start:
8850         raise Exception("Unexpected Op-Code for WSC/Start")
8851
8852     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8853     uuid_e = 16*'\x11'
8854     e_nonce = 16*'\x22'
8855     own_private, e_pk = wsc_dh_init()
8856
8857     logger.debug("Send M1 to AP")
8858     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8859                                 e_nonce, e_pk)
8860     send_wsc_msg(hapd, addr, m1)
8861
8862     logger.debug("Receive M2 from AP")
8863     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8864     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8865     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8866
8867     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8868                                     r_nonce)
8869     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8870
8871     logger.debug("Send WSC_ACK to AP")
8872     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8873                           eap_code=2)
8874     send_wsc_msg(hapd, addr, ack)
8875
8876     wps_wait_eap_failure(hapd, dev[0])
8877
8878 def test_wps_ext_m1_invalid(dev, apdev):
8879     """WPS proto: M1 failing parsing"""
8880     pin = "12345670"
8881     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8882     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8883     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8884
8885     logger.debug("Receive WSC/Start from AP")
8886     msg = get_wsc_msg(hapd)
8887     if msg['wsc_opcode'] != WSC_Start:
8888         raise Exception("Unexpected Op-Code for WSC/Start")
8889
8890     logger.debug("Send M1 to AP")
8891     attrs = '\x10\x00\x00'
8892     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8893     send_wsc_msg(hapd, addr, m1)
8894
8895     wps_wait_eap_failure(hapd, dev[0])
8896
8897 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8898     """WPS proto: M1 missing Msg Type"""
8899     pin = "12345670"
8900     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8901     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8902     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8903
8904     logger.debug("Receive WSC/Start from AP")
8905     msg = get_wsc_msg(hapd)
8906     if msg['wsc_opcode'] != WSC_Start:
8907         raise Exception("Unexpected Op-Code for WSC/Start")
8908
8909     logger.debug("Send M1 to AP")
8910     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8911     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8912     send_wsc_msg(hapd, addr, m1)
8913
8914     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8915
8916 def wps_ext_wsc_done(dev, apdev):
8917     pin = "12345670"
8918     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8919     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8920     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8921
8922     logger.debug("Receive WSC/Start from AP")
8923     msg = get_wsc_msg(hapd)
8924     if msg['wsc_opcode'] != WSC_Start:
8925         raise Exception("Unexpected Op-Code for WSC/Start")
8926
8927     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8928     uuid_e = 16*'\x11'
8929     e_nonce = 16*'\x22'
8930     own_private, e_pk = wsc_dh_init()
8931
8932     logger.debug("Send M1 to AP")
8933     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8934                                 e_nonce, e_pk)
8935     send_wsc_msg(hapd, addr, m1)
8936
8937     logger.debug("Receive M2 from AP")
8938     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8939     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8940     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8941
8942     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8943                                     r_nonce)
8944     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8945
8946     logger.debug("Send M3 to AP")
8947     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8948     attrs += build_attr_msg_type(WPS_M3)
8949     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8950     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8951     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8952     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8953     raw_m3_attrs = attrs
8954     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8955     send_wsc_msg(hapd, addr, m3)
8956
8957     logger.debug("Receive M4 from AP")
8958     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8959
8960     logger.debug("Send M5 to AP")
8961     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8962     attrs += build_attr_msg_type(WPS_M5)
8963     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8964     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8965     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8966     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8967     raw_m5_attrs = attrs
8968     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8969     send_wsc_msg(hapd, addr, m5)
8970
8971     logger.debug("Receive M6 from AP")
8972     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8973
8974     logger.debug("Send M7 to AP")
8975     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8976     attrs += build_attr_msg_type(WPS_M7)
8977     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8978     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8979     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8980     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8981     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8982     raw_m7_attrs = attrs
8983     send_wsc_msg(hapd, addr, m7)
8984
8985     logger.debug("Receive M8 from AP")
8986     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8987     return hapd, msg, e_nonce, r_nonce
8988
8989 def test_wps_ext_wsc_done_invalid(dev, apdev):
8990     """WPS proto: invalid WSC_Done"""
8991     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8992
8993     logger.debug("Send WSC_Done to AP")
8994     attrs = '\x10\x00\x00'
8995     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8996     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8997
8998     wps_wait_eap_failure(hapd, dev[0])
8999
9000 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
9001     """WPS proto: invalid WSC_Done"""
9002     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9003
9004     logger.debug("Send WSC_Done to AP")
9005     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9006     #attrs += build_attr_msg_type(WPS_WSC_DONE)
9007     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9008     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9009     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9010     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9011
9012     wps_wait_eap_failure(hapd, dev[0])
9013
9014 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
9015     """WPS proto: WSC_Done with wrong Msg Type"""
9016     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9017
9018     logger.debug("Send WSC_Done to AP")
9019     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9020     attrs += build_attr_msg_type(WPS_WSC_ACK)
9021     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9022     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9023     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9024     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9025
9026     wps_wait_eap_failure(hapd, dev[0])
9027
9028 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
9029     """WPS proto: WSC_Done without e_nonce"""
9030     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9031
9032     logger.debug("Send WSC_Done to AP")
9033     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9034     attrs += build_attr_msg_type(WPS_WSC_DONE)
9035     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9036     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9037     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9038     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9039
9040     wps_wait_eap_failure(hapd, dev[0])
9041
9042 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
9043     """WPS proto: WSC_Done without r_nonce"""
9044     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9045
9046     logger.debug("Send WSC_Done to AP")
9047     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9048     attrs += build_attr_msg_type(WPS_WSC_DONE)
9049     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9050     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9051     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9052     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9053
9054     wps_wait_eap_failure(hapd, dev[0])
9055
9056 def test_wps_ext_m7_no_encr_settings(dev, apdev):
9057     """WPS proto: M7 without Encr Settings"""
9058     pin = "12345670"
9059     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
9060     wps_ext_eap_identity_req(dev[0], hapd, bssid)
9061     wps_ext_eap_identity_resp(hapd, dev[0], addr)
9062
9063     logger.debug("Receive WSC/Start from AP")
9064     msg = get_wsc_msg(hapd)
9065     if msg['wsc_opcode'] != WSC_Start:
9066         raise Exception("Unexpected Op-Code for WSC/Start")
9067
9068     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
9069     uuid_e = 16*'\x11'
9070     e_nonce = 16*'\x22'
9071     own_private, e_pk = wsc_dh_init()
9072
9073     logger.debug("Send M1 to AP")
9074     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
9075                                 e_nonce, e_pk)
9076     send_wsc_msg(hapd, addr, m1)
9077
9078     logger.debug("Receive M2 from AP")
9079     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
9080     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
9081     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
9082
9083     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
9084                                     r_nonce)
9085     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
9086
9087     logger.debug("Send M3 to AP")
9088     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9089     attrs += build_attr_msg_type(WPS_M3)
9090     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9091     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
9092     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
9093     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
9094     raw_m3_attrs = attrs
9095     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9096     send_wsc_msg(hapd, addr, m3)
9097
9098     logger.debug("Receive M4 from AP")
9099     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
9100
9101     logger.debug("Send M5 to AP")
9102     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9103     attrs += build_attr_msg_type(WPS_M5)
9104     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9105     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
9106     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9107     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
9108     raw_m5_attrs = attrs
9109     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9110     send_wsc_msg(hapd, addr, m5)
9111
9112     logger.debug("Receive M6 from AP")
9113     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
9114
9115     logger.debug("Send M7 to AP")
9116     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9117     attrs += build_attr_msg_type(WPS_M7)
9118     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9119     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
9120     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9121     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
9122     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9123     raw_m7_attrs = attrs
9124     send_wsc_msg(hapd, addr, m7)
9125
9126     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
9127
9128 def test_wps_ext_m1_workaround(dev, apdev):
9129     """WPS proto: M1 Manufacturer/Model workaround"""
9130     pin = "12345670"
9131     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
9132     wps_ext_eap_identity_req(dev[0], hapd, bssid)
9133     wps_ext_eap_identity_resp(hapd, dev[0], addr)
9134
9135     logger.debug("Receive WSC/Start from AP")
9136     msg = get_wsc_msg(hapd)
9137     if msg['wsc_opcode'] != WSC_Start:
9138         raise Exception("Unexpected Op-Code for WSC/Start")
9139
9140     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
9141     uuid_e = 16*'\x11'
9142     e_nonce = 16*'\x22'
9143     own_private, e_pk = wsc_dh_init()
9144
9145     logger.debug("Send M1 to AP")
9146     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
9147                                 e_nonce, e_pk, manufacturer='Apple TEST',
9148                                 model_name='AirPort', config_methods='\xff\xff')
9149     send_wsc_msg(hapd, addr, m1)
9150
9151     logger.debug("Receive M2 from AP")
9152     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
9153
9154 def test_ap_wps_disable_enable(dev, apdev):
9155     """WPS and DISABLE/ENABLE AP"""
9156     hapd = wps_start_ap(apdev[0])
9157     hapd.disable()
9158     hapd.enable()
9159     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
9160
9161 def test_ap_wps_upnp_web_oom(dev, apdev, params):
9162     """hostapd WPS UPnP web OOM"""
9163     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
9164     hapd = add_ssdp_ap(apdev[0], ap_uuid)
9165
9166     location = ssdp_get_location(ap_uuid)
9167     url = urlparse.urlparse(location)
9168     urls = upnp_get_urls(location)
9169     eventurl = urlparse.urlparse(urls['event_sub_url'])
9170     ctrlurl = urlparse.urlparse(urls['control_url'])
9171
9172     conn = httplib.HTTPConnection(url.netloc)
9173     with alloc_fail(hapd, 1, "web_connection_parse_get"):
9174         conn.request("GET", "/wps_device.xml")
9175         try:
9176             resp = conn.getresponse()
9177         except:
9178             pass
9179
9180     conn = httplib.HTTPConnection(url.netloc)
9181     conn.request("GET", "/unknown")
9182     resp = conn.getresponse()
9183     if resp.status != 404:
9184         raise Exception("Unexpected HTTP result for unknown URL: %d" + resp.status)
9185
9186     with alloc_fail(hapd, 1, "web_connection_parse_get"):
9187         conn.request("GET", "/unknown")
9188         try:
9189             resp = conn.getresponse()
9190             print resp.status
9191         except:
9192             pass
9193
9194     conn = httplib.HTTPConnection(url.netloc)
9195     conn.request("GET", "/wps_device.xml")
9196     resp = conn.getresponse()
9197     if resp.status != 200:
9198         raise Exception("GET /wps_device.xml failed")
9199
9200     conn = httplib.HTTPConnection(url.netloc)
9201     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9202     if resp.status != 200:
9203         raise Exception("GetDeviceInfo failed")
9204
9205     with alloc_fail(hapd, 1, "web_process_get_device_info"):
9206         conn = httplib.HTTPConnection(url.netloc)
9207         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9208         if resp.status != 500:
9209             raise Exception("Internal error not reported from GetDeviceInfo OOM")
9210
9211     with alloc_fail(hapd, 1, "wps_build_m1;web_process_get_device_info"):
9212         conn = httplib.HTTPConnection(url.netloc)
9213         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9214         if resp.status != 500:
9215             raise Exception("Internal error not reported from GetDeviceInfo OOM")
9216
9217     with alloc_fail(hapd, 1, "wpabuf_alloc;web_connection_send_reply"):
9218         conn = httplib.HTTPConnection(url.netloc)
9219         try:
9220             resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9221         except:
9222             pass
9223
9224     conn = httplib.HTTPConnection(url.netloc)
9225     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9226     if resp.status != 200:
9227         raise Exception("GetDeviceInfo failed")
9228
9229     # No NewWLANEventType in PutWLANResponse NewMessage
9230     conn = httplib.HTTPConnection(url.netloc)
9231     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse", newmsg="foo")
9232     if resp.status != 600:
9233         raise Exception("Unexpected HTTP response: %d" % resp.status)
9234
9235     # No NewWLANEventMAC in PutWLANResponse NewMessage
9236     conn = httplib.HTTPConnection(url.netloc)
9237     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9238                             newmsg="foo", neweventtype="1")
9239     if resp.status != 600:
9240         raise Exception("Unexpected HTTP response: %d" % resp.status)
9241
9242     # Invalid NewWLANEventMAC in PutWLANResponse NewMessage
9243     conn = httplib.HTTPConnection(url.netloc)
9244     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9245                             newmsg="foo", neweventtype="1",
9246                             neweventmac="foo")
9247     if resp.status != 600:
9248         raise Exception("Unexpected HTTP response: %d" % resp.status)
9249
9250     # Workaround for NewWLANEventMAC in PutWLANResponse NewMessage
9251     # Ignored unexpected PutWLANResponse WLANEventType 1
9252     conn = httplib.HTTPConnection(url.netloc)
9253     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9254                             newmsg="foo", neweventtype="1",
9255                             neweventmac="00.11.22.33.44.55")
9256     if resp.status != 500:
9257         raise Exception("Unexpected HTTP response: %d" % resp.status)
9258
9259     # PutWLANResponse NewMessage with invalid EAP message
9260     conn = httplib.HTTPConnection(url.netloc)
9261     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9262                             newmsg="foo", neweventtype="2",
9263                             neweventmac="00:11:22:33:44:55")
9264     if resp.status != 200:
9265         raise Exception("Unexpected HTTP response: %d" % resp.status)
9266
9267     with alloc_fail(hapd, 1, "web_connection_parse_subscribe"):
9268         conn = httplib.HTTPConnection(url.netloc)
9269         headers = { "callback": '<http://127.0.0.1:12345/event>',
9270                     "NT": "upnp:event",
9271                     "timeout": "Second-1234" }
9272         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
9273         try:
9274             resp = conn.getresponse()
9275         except:
9276             pass
9277
9278     with alloc_fail(hapd, 1, "dup_binstr;web_connection_parse_subscribe"):
9279         conn = httplib.HTTPConnection(url.netloc)
9280         headers = { "callback": '<http://127.0.0.1:12345/event>',
9281                     "NT": "upnp:event",
9282                     "timeout": "Second-1234" }
9283         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
9284         resp = conn.getresponse()
9285         if resp.status != 500:
9286             raise Exception("Unexpected HTTP response: %d" % resp.status)
9287
9288     with alloc_fail(hapd, 1, "wpabuf_alloc;web_connection_parse_unsubscribe"):
9289         conn = httplib.HTTPConnection(url.netloc)
9290         headers = { "callback": '<http://127.0.0.1:12345/event>',
9291                     "NT": "upnp:event",
9292                     "timeout": "Second-1234" }
9293         conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
9294         try:
9295             resp = conn.getresponse()
9296         except:
9297             pass
9298
9299     with alloc_fail(hapd, 1, "web_connection_unimplemented"):
9300         conn = httplib.HTTPConnection(url.netloc)
9301         conn.request("HEAD", "/wps_device.xml")
9302         try:
9303             resp = conn.getresponse()
9304         except:
9305             pass
9306
9307 def test_ap_wps_frag_ack_oom(dev, apdev):
9308     """WPS and fragment ack OOM"""
9309     dev[0].request("SET wps_fragment_size 50")
9310     hapd = wps_start_ap(apdev[0])
9311     with alloc_fail(hapd, 1, "eap_wsc_build_frag_ack"):
9312         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
9313
9314 def wait_scan_stopped(dev):
9315     dev.request("ABORT_SCAN")
9316     for i in range(50):
9317         res = dev.get_driver_status_field("scan_state")
9318         if "SCAN_STARTED" not in res and "SCAN_REQUESTED" not in res:
9319             break
9320         logger.debug("Waiting for scan to complete")
9321         time.sleep(0.1)
9322
9323 def test_ap_wps_eap_wsc_errors(dev, apdev):
9324     """WPS and EAP-WSC error cases"""
9325     ssid = "test-wps-conf-pin"
9326     appin = "12345670"
9327     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
9328                "wpa_passphrase": "12345678", "wpa": "2",
9329                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
9330                "fragment_size": "300", "ap_pin": appin }
9331     hapd = hostapd.add_ap(apdev[0], params)
9332     bssid = apdev[0]['bssid']
9333
9334     pin = dev[0].wps_read_pin()
9335     hapd.request("WPS_PIN any " + pin)
9336     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
9337     dev[0].dump_monitor()
9338
9339     dev[0].wps_reg(bssid, appin + " new_ssid=a", "new ssid", "WPA2PSK", "CCMP",
9340                    "new passphrase", no_wait=True)
9341     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9342     if ev is None:
9343         raise Exception("WPS-FAIL not reported")
9344     dev[0].request("WPS_CANCEL")
9345     dev[0].wait_disconnected()
9346     wait_scan_stopped(dev[0])
9347     dev[0].dump_monitor()
9348
9349     dev[0].wps_reg(bssid, appin, "new ssid", "FOO", "CCMP",
9350                    "new passphrase", no_wait=True)
9351     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9352     if ev is None:
9353         raise Exception("WPS-FAIL not reported")
9354     dev[0].request("WPS_CANCEL")
9355     dev[0].wait_disconnected()
9356     wait_scan_stopped(dev[0])
9357     dev[0].dump_monitor()
9358
9359     dev[0].wps_reg(bssid, appin, "new ssid", "WPA2PSK", "FOO",
9360                    "new passphrase", no_wait=True)
9361     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9362     if ev is None:
9363         raise Exception("WPS-FAIL not reported")
9364     dev[0].request("WPS_CANCEL")
9365     dev[0].wait_disconnected()
9366     wait_scan_stopped(dev[0])
9367     dev[0].dump_monitor()
9368
9369     dev[0].wps_reg(bssid, appin + "new_key=a", "new ssid", "WPA2PSK", "CCMP",
9370                    "new passphrase", no_wait=True)
9371     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9372     if ev is None:
9373         raise Exception("WPS-FAIL not reported")
9374     dev[0].request("WPS_CANCEL")
9375     dev[0].wait_disconnected()
9376     wait_scan_stopped(dev[0])
9377     dev[0].dump_monitor()
9378
9379     tests = [ "eap_wsc_init",
9380               "eap_msg_alloc;eap_wsc_build_msg",
9381               "wpabuf_alloc;eap_wsc_process_fragment" ]
9382     for func in tests:
9383         with alloc_fail(dev[0], 1, func):
9384             dev[0].request("WPS_PIN %s %s" % (bssid, pin))
9385             wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
9386             dev[0].request("WPS_CANCEL")
9387             dev[0].wait_disconnected()
9388             wait_scan_stopped(dev[0])
9389             dev[0].dump_monitor()
9390
9391     with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_build_expanded_nak"):
9392         dev[0].wps_reg(bssid, appin + " new_ssid=a", "new ssid", "WPA2PSK",
9393                        "CCMP", "new passphrase", no_wait=True)
9394         wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
9395         dev[0].request("WPS_CANCEL")
9396         dev[0].wait_disconnected()
9397         wait_scan_stopped(dev[0])
9398         dev[0].dump_monitor()
9399
9400 def test_ap_wps_eap_wsc(dev, apdev):
9401     """WPS and EAP-WSC in network profile"""
9402     params = int_eap_server_params()
9403     params["wps_state"] = "2"
9404     hapd = hostapd.add_ap(apdev[0], params)
9405     bssid = apdev[0]['bssid']
9406
9407     logger.info("Unexpected identity")
9408     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9409                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-unexpected",
9410                    wait_connect=False)
9411     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9412     if ev is None:
9413         raise Exception("No EAP-Failure seen")
9414     dev[0].request("REMOVE_NETWORK all")
9415     dev[0].wait_disconnected()
9416
9417     logger.info("No phase1 parameter")
9418     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9419                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9420                    wait_connect=False)
9421     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9422     if ev is None:
9423         raise Exception("Timeout on EAP method start")
9424     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9425     if ev is None:
9426         raise Exception("No EAP-Failure seen")
9427     dev[0].request("REMOVE_NETWORK all")
9428     dev[0].wait_disconnected()
9429
9430     logger.info("No PIN/PBC in phase1")
9431     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9432                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9433                    phase1="foo", wait_connect=False)
9434     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9435     if ev is None:
9436         raise Exception("Timeout on EAP method start")
9437     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9438     if ev is None:
9439         raise Exception("No EAP-Failure seen")
9440     dev[0].request("REMOVE_NETWORK all")
9441     dev[0].wait_disconnected()
9442
9443     logger.info("Invalid pkhash in phase1")
9444     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9445                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9446                    phase1="foo pkhash=q pbc=1", wait_connect=False)
9447     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9448     if ev is None:
9449         raise Exception("Timeout on EAP method start")
9450     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9451     if ev is None:
9452         raise Exception("No EAP-Failure seen")
9453     dev[0].request("REMOVE_NETWORK all")
9454     dev[0].wait_disconnected()
9455
9456     logger.info("Zero fragment_size")
9457     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9458                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9459                    fragment_size="0", phase1="pin=12345670", wait_connect=False)
9460     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9461     if ev is None:
9462         raise Exception("Timeout on EAP method start")
9463     ev = dev[0].wait_event(["WPS-M2D"], timeout=5)
9464     if ev is None:
9465         raise Exception("No M2D seen")
9466     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9467     if ev is None:
9468         raise Exception("No EAP-Failure seen")
9469     dev[0].request("REMOVE_NETWORK all")
9470     dev[0].wait_disconnected()
9471
9472     logger.info("Missing new_auth")
9473     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9474                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9475                    phase1="pin=12345670 new_ssid=aa", wait_connect=False)
9476     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9477     if ev is None:
9478         raise Exception("Timeout on EAP method start")
9479     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9480     if ev is None:
9481         raise Exception("No EAP-Failure seen")
9482     dev[0].request("REMOVE_NETWORK all")
9483     dev[0].wait_disconnected()
9484
9485     logger.info("Missing new_encr")
9486     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9487                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9488                    phase1="pin=12345670 new_auth=WPA2PSK new_ssid=aa", wait_connect=False)
9489     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9490     if ev is None:
9491         raise Exception("Timeout on EAP method start")
9492     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9493     if ev is None:
9494         raise Exception("No EAP-Failure seen")
9495     dev[0].request("REMOVE_NETWORK all")
9496     dev[0].wait_disconnected()
9497
9498     logger.info("Missing new_key")
9499     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9500                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9501                    phase1="pin=12345670 new_auth=WPA2PSK new_ssid=aa new_encr=CCMP",
9502                    wait_connect=False)
9503     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9504     if ev is None:
9505         raise Exception("Timeout on EAP method start")
9506     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9507     if ev is None:
9508         raise Exception("No EAP-Failure seen")
9509     dev[0].request("REMOVE_NETWORK all")
9510     dev[0].wait_disconnected()