Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / 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
33 def wps_start_ap(apdev, ssid="test-wps-conf"):
34     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
35                "wpa_passphrase": "12345678", "wpa": "2",
36                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
37     return hostapd.add_ap(apdev['ifname'], params)
38
39 def test_ap_wps_init(dev, apdev):
40     """Initial AP configuration with first WPS Enrollee"""
41     ssid = "test-wps"
42     hostapd.add_ap(apdev[0]['ifname'],
43                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
44     hapd = hostapd.Hostapd(apdev[0]['ifname'])
45     logger.info("WPS provisioning step")
46     hapd.request("WPS_PBC")
47     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
48         raise Exception("PBC status not shown correctly")
49
50     id = dev[0].add_network()
51     dev[0].set_network_quoted(id, "ssid", "home")
52     dev[0].set_network_quoted(id, "psk", "12345678")
53     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
54
55     id = dev[0].add_network()
56     dev[0].set_network_quoted(id, "ssid", "home2")
57     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
58     dev[0].set_network(id, "key_mgmt", "NONE")
59     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
60
61     dev[0].request("WPS_PBC")
62     dev[0].wait_connected(timeout=30)
63     status = dev[0].get_status()
64     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
65         raise Exception("Not fully connected")
66     if status['ssid'] != ssid:
67         raise Exception("Unexpected SSID")
68     if status['pairwise_cipher'] != 'CCMP':
69         raise Exception("Unexpected encryption configuration")
70     if status['key_mgmt'] != 'WPA2-PSK':
71         raise Exception("Unexpected key_mgmt")
72
73     status = hapd.request("WPS_GET_STATUS")
74     if "PBC Status: Disabled" not in status:
75         raise Exception("PBC status not shown correctly")
76     if "Last WPS result: Success" not in status:
77         raise Exception("Last WPS result not shown correctly")
78     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
79         raise Exception("Peer address not shown correctly")
80     conf = hapd.request("GET_CONFIG")
81     if "wps_state=configured" not in conf:
82         raise Exception("AP not in WPS configured state")
83     if "wpa=3" not in conf:
84         raise Exception("AP not in WPA+WPA2 configuration")
85     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
86         raise Exception("Unexpected rsn_pairwise_cipher")
87     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
88         raise Exception("Unexpected wpa_pairwise_cipher")
89     if "group_cipher=TKIP" not in conf:
90         raise Exception("Unexpected group_cipher")
91
92     if len(dev[0].list_networks()) != 3:
93         raise Exception("Unexpected number of network blocks")
94
95 def test_ap_wps_init_2ap_pbc(dev, apdev):
96     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
97     ssid = "test-wps"
98     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
99     hostapd.add_ap(apdev[0]['ifname'], params)
100     hostapd.add_ap(apdev[1]['ifname'], params)
101     hapd = hostapd.Hostapd(apdev[0]['ifname'])
102     logger.info("WPS provisioning step")
103     hapd.request("WPS_PBC")
104     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
105     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
106     bss = dev[0].get_bss(apdev[0]['bssid'])
107     if "[WPS-PBC]" not in bss['flags']:
108         raise Exception("WPS-PBC flag missing from AP1")
109     bss = dev[0].get_bss(apdev[1]['bssid'])
110     if "[WPS-PBC]" not in bss['flags']:
111         raise Exception("WPS-PBC flag missing from AP2")
112     dev[0].dump_monitor()
113     dev[0].request("SET wps_cred_processing 2")
114     dev[0].request("WPS_PBC")
115     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
116     dev[0].request("SET wps_cred_processing 0")
117     if ev is None:
118         raise Exception("WPS cred event not seen")
119     if "100e" not in ev:
120         raise Exception("WPS attributes not included in the cred event")
121     dev[0].wait_connected(timeout=30)
122
123     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
124     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
125     bss = dev[1].get_bss(apdev[0]['bssid'])
126     if "[WPS-PBC]" in bss['flags']:
127         raise Exception("WPS-PBC flag not cleared from AP1")
128     bss = dev[1].get_bss(apdev[1]['bssid'])
129     if "[WPS-PBC]" in bss['flags']:
130         raise Exception("WPS-PBC flag not cleared from AP2")
131
132 def test_ap_wps_init_2ap_pin(dev, apdev):
133     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
134     ssid = "test-wps"
135     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
136     hostapd.add_ap(apdev[0]['ifname'], params)
137     hostapd.add_ap(apdev[1]['ifname'], params)
138     hapd = hostapd.Hostapd(apdev[0]['ifname'])
139     logger.info("WPS provisioning step")
140     pin = dev[0].wps_read_pin()
141     hapd.request("WPS_PIN any " + pin)
142     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
143     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
144     bss = dev[0].get_bss(apdev[0]['bssid'])
145     if "[WPS-AUTH]" not in bss['flags']:
146         raise Exception("WPS-AUTH flag missing from AP1")
147     bss = dev[0].get_bss(apdev[1]['bssid'])
148     if "[WPS-AUTH]" not in bss['flags']:
149         raise Exception("WPS-AUTH flag missing from AP2")
150     dev[0].dump_monitor()
151     dev[0].request("WPS_PIN any " + pin)
152     dev[0].wait_connected(timeout=30)
153
154     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
155     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
156     bss = dev[1].get_bss(apdev[0]['bssid'])
157     if "[WPS-AUTH]" in bss['flags']:
158         raise Exception("WPS-AUTH flag not cleared from AP1")
159     bss = dev[1].get_bss(apdev[1]['bssid'])
160     if "[WPS-AUTH]" in bss['flags']:
161         raise Exception("WPS-AUTH flag not cleared from AP2")
162
163 def test_ap_wps_init_through_wps_config(dev, apdev):
164     """Initial AP configuration using wps_config command"""
165     ssid = "test-wps-init-config"
166     hostapd.add_ap(apdev[0]['ifname'],
167                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
168     hapd = hostapd.Hostapd(apdev[0]['ifname'])
169     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
170         raise Exception("WPS_CONFIG command failed")
171     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
172     if ev is None:
173         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
174     # It takes some time for the AP to update Beacon and Probe Response frames,
175     # so wait here before requesting the scan to be started to avoid adding
176     # extra five second wait to the test due to fetching obsolete scan results.
177     hapd.ping()
178     time.sleep(0.2)
179     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
180                    pairwise="CCMP", group="CCMP")
181
182 def test_ap_wps_init_through_wps_config_2(dev, apdev):
183     """AP configuration using wps_config and wps_cred_processing=2"""
184     ssid = "test-wps-init-config"
185     hostapd.add_ap(apdev[0]['ifname'],
186                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
187                      "wps_cred_processing": "2" })
188     hapd = hostapd.Hostapd(apdev[0]['ifname'])
189     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
190         raise Exception("WPS_CONFIG command failed")
191     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
192     if ev is None:
193         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
194     if "100e" not in ev:
195         raise Exception("WPS-NEW-AP-SETTINGS did not include Credential")
196
197 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
198     """AP configuration using wps_config command with invalid passphrase"""
199     ssid = "test-wps-init-config"
200     hostapd.add_ap(apdev[0]['ifname'],
201                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
202     hapd = hostapd.Hostapd(apdev[0]['ifname'])
203     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
204         raise Exception("Invalid WPS_CONFIG command accepted")
205
206 def test_ap_wps_conf(dev, apdev):
207     """WPS PBC provisioning with configured AP"""
208     ssid = "test-wps-conf"
209     hostapd.add_ap(apdev[0]['ifname'],
210                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
211                      "wpa_passphrase": "12345678", "wpa": "2",
212                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
213     hapd = hostapd.Hostapd(apdev[0]['ifname'])
214     logger.info("WPS provisioning step")
215     hapd.request("WPS_PBC")
216     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
217     dev[0].dump_monitor()
218     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
219     dev[0].wait_connected(timeout=30)
220     status = dev[0].get_status()
221     if status['wpa_state'] != 'COMPLETED':
222         raise Exception("Not fully connected")
223     if status['bssid'] != apdev[0]['bssid']:
224         raise Exception("Unexpected BSSID")
225     if status['ssid'] != ssid:
226         raise Exception("Unexpected SSID")
227     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
228         raise Exception("Unexpected encryption configuration")
229     if status['key_mgmt'] != 'WPA2-PSK':
230         raise Exception("Unexpected key_mgmt")
231
232     sta = hapd.get_sta(dev[0].p2p_interface_addr())
233     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
234         raise Exception("Device name not available in STA command")
235
236 def test_ap_wps_conf_5ghz(dev, apdev):
237     """WPS PBC provisioning with configured AP on 5 GHz band"""
238     try:
239         hapd = None
240         ssid = "test-wps-conf"
241         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
242                    "wpa_passphrase": "12345678", "wpa": "2",
243                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
244                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
245         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
246         logger.info("WPS provisioning step")
247         hapd.request("WPS_PBC")
248         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
249         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
250         dev[0].wait_connected(timeout=30)
251
252         sta = hapd.get_sta(dev[0].p2p_interface_addr())
253         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
254             raise Exception("Device name not available in STA command")
255     finally:
256         dev[0].request("DISCONNECT")
257         if hapd:
258             hapd.request("DISABLE")
259         subprocess.call(['iw', 'reg', 'set', '00'])
260         dev[0].flush_scan_cache()
261
262 def test_ap_wps_conf_chan14(dev, apdev):
263     """WPS PBC provisioning with configured AP on channel 14"""
264     try:
265         hapd = None
266         ssid = "test-wps-conf"
267         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
268                    "wpa_passphrase": "12345678", "wpa": "2",
269                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
270                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
271         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
272         logger.info("WPS provisioning step")
273         hapd.request("WPS_PBC")
274         dev[0].request("WPS_PBC")
275         dev[0].wait_connected(timeout=30)
276
277         sta = hapd.get_sta(dev[0].p2p_interface_addr())
278         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
279             raise Exception("Device name not available in STA command")
280     finally:
281         dev[0].request("DISCONNECT")
282         if hapd:
283             hapd.request("DISABLE")
284         subprocess.call(['iw', 'reg', 'set', '00'])
285         dev[0].flush_scan_cache()
286
287 def test_ap_wps_twice(dev, apdev):
288     """WPS provisioning with twice to change passphrase"""
289     ssid = "test-wps-twice"
290     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
291                "wpa_passphrase": "12345678", "wpa": "2",
292                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
293     hostapd.add_ap(apdev[0]['ifname'], params)
294     hapd = hostapd.Hostapd(apdev[0]['ifname'])
295     logger.info("WPS provisioning step")
296     hapd.request("WPS_PBC")
297     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
298     dev[0].dump_monitor()
299     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
300     dev[0].wait_connected(timeout=30)
301     dev[0].request("DISCONNECT")
302
303     logger.info("Restart AP with different passphrase and re-run WPS")
304     hapd_global = hostapd.HostapdGlobal()
305     hapd_global.remove(apdev[0]['ifname'])
306     params['wpa_passphrase'] = 'another passphrase'
307     hostapd.add_ap(apdev[0]['ifname'], params)
308     hapd = hostapd.Hostapd(apdev[0]['ifname'])
309     logger.info("WPS provisioning step")
310     hapd.request("WPS_PBC")
311     dev[0].dump_monitor()
312     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
313     dev[0].wait_connected(timeout=30)
314     networks = dev[0].list_networks()
315     if len(networks) > 1:
316         raise Exception("Unexpected duplicated network block present")
317
318 def test_ap_wps_incorrect_pin(dev, apdev):
319     """WPS PIN provisioning with incorrect PIN"""
320     ssid = "test-wps-incorrect-pin"
321     hostapd.add_ap(apdev[0]['ifname'],
322                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
323                      "wpa_passphrase": "12345678", "wpa": "2",
324                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
325     hapd = hostapd.Hostapd(apdev[0]['ifname'])
326
327     logger.info("WPS provisioning attempt 1")
328     hapd.request("WPS_PIN any 12345670")
329     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
330     dev[0].dump_monitor()
331     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
332     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
333     if ev is None:
334         raise Exception("WPS operation timed out")
335     if "config_error=18" not in ev:
336         raise Exception("Incorrect config_error reported")
337     if "msg=8" not in ev:
338         raise Exception("PIN error detected on incorrect message")
339     dev[0].wait_disconnected(timeout=10)
340     dev[0].request("WPS_CANCEL")
341     # if a scan was in progress, wait for it to complete before trying WPS again
342     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
343
344     status = hapd.request("WPS_GET_STATUS")
345     if "Last WPS result: Failed" not in status:
346         raise Exception("WPS failure result not shown correctly")
347
348     logger.info("WPS provisioning attempt 2")
349     hapd.request("WPS_PIN any 12345670")
350     dev[0].dump_monitor()
351     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
352     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
353     if ev is None:
354         raise Exception("WPS operation timed out")
355     if "config_error=18" not in ev:
356         raise Exception("Incorrect config_error reported")
357     if "msg=10" not in ev:
358         raise Exception("PIN error detected on incorrect message")
359     dev[0].wait_disconnected(timeout=10)
360
361 def test_ap_wps_conf_pin(dev, apdev):
362     """WPS PIN provisioning with configured AP"""
363     ssid = "test-wps-conf-pin"
364     hostapd.add_ap(apdev[0]['ifname'],
365                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
366                      "wpa_passphrase": "12345678", "wpa": "2",
367                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
368     hapd = hostapd.Hostapd(apdev[0]['ifname'])
369     logger.info("WPS provisioning step")
370     pin = dev[0].wps_read_pin()
371     hapd.request("WPS_PIN any " + pin)
372     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
373     dev[0].dump_monitor()
374     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
375     dev[0].wait_connected(timeout=30)
376     status = dev[0].get_status()
377     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
378         raise Exception("Not fully connected")
379     if status['ssid'] != ssid:
380         raise Exception("Unexpected SSID")
381     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
382         raise Exception("Unexpected encryption configuration")
383     if status['key_mgmt'] != 'WPA2-PSK':
384         raise Exception("Unexpected key_mgmt")
385
386     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
387     bss = dev[1].get_bss(apdev[0]['bssid'])
388     if "[WPS-AUTH]" in bss['flags']:
389         raise Exception("WPS-AUTH flag not cleared")
390     logger.info("Try to connect from another station using the same PIN")
391     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
392     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
393     if ev is None:
394         raise Exception("Operation timed out")
395     if "WPS-M2D" not in ev:
396         raise Exception("Unexpected WPS operation started")
397     hapd.request("WPS_PIN any " + pin)
398     dev[1].wait_connected(timeout=30)
399
400 def test_ap_wps_conf_pin_v1(dev, apdev):
401     """WPS PIN provisioning with configured WPS v1.0 AP"""
402     ssid = "test-wps-conf-pin-v1"
403     hostapd.add_ap(apdev[0]['ifname'],
404                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
405                      "wpa_passphrase": "12345678", "wpa": "2",
406                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
407     hapd = hostapd.Hostapd(apdev[0]['ifname'])
408     logger.info("WPS provisioning step")
409     pin = dev[0].wps_read_pin()
410     hapd.request("SET wps_version_number 0x10")
411     hapd.request("WPS_PIN any " + pin)
412     found = False
413     for i in range(0, 10):
414         dev[0].scan(freq="2412")
415         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
416             found = True
417             break
418     if not found:
419         hapd.request("SET wps_version_number 0x20")
420         raise Exception("WPS-PIN flag not seen in scan results")
421     dev[0].dump_monitor()
422     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
423     dev[0].wait_connected(timeout=30)
424     hapd.request("SET wps_version_number 0x20")
425
426 def test_ap_wps_conf_pin_2sta(dev, apdev):
427     """Two stations trying to use WPS PIN at the same time"""
428     ssid = "test-wps-conf-pin2"
429     hostapd.add_ap(apdev[0]['ifname'],
430                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
431                      "wpa_passphrase": "12345678", "wpa": "2",
432                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
433     hapd = hostapd.Hostapd(apdev[0]['ifname'])
434     logger.info("WPS provisioning step")
435     pin = "12345670"
436     pin2 = "55554444"
437     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
438     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
439     dev[0].dump_monitor()
440     dev[1].dump_monitor()
441     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
442     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
443     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
444     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
445     dev[0].wait_connected(timeout=30)
446     dev[1].wait_connected(timeout=30)
447
448 def test_ap_wps_conf_pin_timeout(dev, apdev):
449     """WPS PIN provisioning with configured AP timing out PIN"""
450     ssid = "test-wps-conf-pin"
451     hostapd.add_ap(apdev[0]['ifname'],
452                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
453                      "wpa_passphrase": "12345678", "wpa": "2",
454                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
455     hapd = hostapd.Hostapd(apdev[0]['ifname'])
456     addr = dev[0].p2p_interface_addr()
457     pin = dev[0].wps_read_pin()
458     if "FAIL" not in hapd.request("WPS_PIN "):
459         raise Exception("Unexpected success on invalid WPS_PIN")
460     hapd.request("WPS_PIN any " + pin + " 1")
461     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
462     time.sleep(1.1)
463     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
464     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
465     if ev is None:
466         raise Exception("WPS-PIN-NEEDED event timed out")
467     ev = dev[0].wait_event(["WPS-M2D"])
468     if ev is None:
469         raise Exception("M2D not reported")
470     dev[0].request("WPS_CANCEL")
471
472     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
473     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
474     dev[0].wait_connected(timeout=30)
475
476 def test_ap_wps_reg_connect(dev, apdev):
477     """WPS registrar using AP PIN to connect"""
478     ssid = "test-wps-reg-ap-pin"
479     appin = "12345670"
480     hostapd.add_ap(apdev[0]['ifname'],
481                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
482                      "wpa_passphrase": "12345678", "wpa": "2",
483                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
484                      "ap_pin": appin})
485     logger.info("WPS provisioning step")
486     dev[0].dump_monitor()
487     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
488     dev[0].wps_reg(apdev[0]['bssid'], appin)
489     status = dev[0].get_status()
490     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
491         raise Exception("Not fully connected")
492     if status['ssid'] != ssid:
493         raise Exception("Unexpected SSID")
494     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
495         raise Exception("Unexpected encryption configuration")
496     if status['key_mgmt'] != 'WPA2-PSK':
497         raise Exception("Unexpected key_mgmt")
498
499 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
500     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
501     ssid = "test-wps-reg-ap-pin"
502     appin = "12345670"
503     hostapd.add_ap(apdev[0]['ifname'],
504                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
505                      "wpa_passphrase": "12345678", "wpa": "3",
506                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
507                      "wpa_pairwise": "TKIP", "ap_pin": appin})
508     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
509     dev[0].wps_reg(apdev[0]['bssid'], appin)
510     status = dev[0].get_status()
511     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
512         raise Exception("Not fully connected")
513     if status['ssid'] != ssid:
514         raise Exception("Unexpected SSID")
515     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
516         raise Exception("Unexpected encryption configuration")
517     if status['key_mgmt'] != 'WPA2-PSK':
518         raise Exception("Unexpected key_mgmt")
519
520 def test_ap_wps_reg_override_ap_settings(dev, apdev):
521     """WPS registrar and ap_settings override"""
522     ap_settings = "/tmp/ap_wps_reg_override_ap_settings"
523     try:
524         os.remove(ap_settings)
525     except:
526         pass
527     # Override AP Settings with values that point to another AP
528     data = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
529     data += build_wsc_attr(ATTR_SSID, "test")
530     data += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
531     data += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
532     data += build_wsc_attr(ATTR_NETWORK_KEY, '')
533     data += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[1]['bssid'].replace(':', '')))
534     with open(ap_settings, "w") as f:
535         f.write(data)
536     ssid = "test-wps-reg-ap-pin"
537     appin = "12345670"
538     hostapd.add_ap(apdev[0]['ifname'],
539                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
540                      "wpa_passphrase": "12345678", "wpa": "2",
541                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
542                      "ap_pin": appin, "ap_settings": ap_settings })
543     hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "test" })
544     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
545     dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
546     dev[0].wps_reg(apdev[0]['bssid'], appin)
547     ev = hapd2.wait_event(['AP-STA-CONNECTED'], timeout=10)
548     os.remove(ap_settings)
549     if ev is None:
550         raise Exception("No connection with the other AP")
551
552 def check_wps_reg_failure(dev, ap, appin):
553     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
554     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
555     if ev is None:
556         raise Exception("WPS operation timed out")
557     if "WPS-SUCCESS" in ev:
558         raise Exception("WPS operation succeeded unexpectedly")
559     if "config_error=15" not in ev:
560         raise Exception("WPS setup locked state was not reported correctly")
561
562 def test_ap_wps_random_ap_pin(dev, apdev):
563     """WPS registrar using random AP PIN"""
564     ssid = "test-wps-reg-random-ap-pin"
565     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
566     hostapd.add_ap(apdev[0]['ifname'],
567                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
568                      "wpa_passphrase": "12345678", "wpa": "2",
569                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
570                      "device_name": "Wireless AP", "manufacturer": "Company",
571                      "model_name": "WAP", "model_number": "123",
572                      "serial_number": "12345", "device_type": "6-0050F204-1",
573                      "os_version": "01020300",
574                      "config_methods": "label push_button",
575                      "uuid": ap_uuid, "upnp_iface": "lo" })
576     hapd = hostapd.Hostapd(apdev[0]['ifname'])
577     appin = hapd.request("WPS_AP_PIN random")
578     if "FAIL" in appin:
579         raise Exception("Could not generate random AP PIN")
580     if appin not in hapd.request("WPS_AP_PIN get"):
581         raise Exception("Could not fetch current AP PIN")
582     logger.info("WPS provisioning step")
583     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
584     dev[0].wps_reg(apdev[0]['bssid'], appin)
585
586     hapd.request("WPS_AP_PIN disable")
587     logger.info("WPS provisioning step with AP PIN disabled")
588     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
589     check_wps_reg_failure(dev[1], apdev[0], appin)
590
591     logger.info("WPS provisioning step with AP PIN reset")
592     appin = "12345670"
593     hapd.request("WPS_AP_PIN set " + appin)
594     dev[1].wps_reg(apdev[0]['bssid'], appin)
595     dev[0].request("REMOVE_NETWORK all")
596     dev[1].request("REMOVE_NETWORK all")
597     dev[0].wait_disconnected(timeout=10)
598     dev[1].wait_disconnected(timeout=10)
599
600     logger.info("WPS provisioning step after AP PIN timeout")
601     hapd.request("WPS_AP_PIN disable")
602     appin = hapd.request("WPS_AP_PIN random 1")
603     time.sleep(1.1)
604     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
605         raise Exception("AP PIN unexpectedly still enabled")
606     check_wps_reg_failure(dev[0], apdev[0], appin)
607
608     logger.info("WPS provisioning step after AP PIN timeout(2)")
609     hapd.request("WPS_AP_PIN disable")
610     appin = "12345670"
611     hapd.request("WPS_AP_PIN set " + appin + " 1")
612     time.sleep(1.1)
613     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
614         raise Exception("AP PIN unexpectedly still enabled")
615     check_wps_reg_failure(dev[1], apdev[0], appin)
616
617     with fail_test(hapd, 1, "os_get_random;wps_generate_pin"):
618         if "FAIL" in hapd.request("WPS_AP_PIN random 1"):
619             raise Exception("Failed to generate PIN during OOM")
620         hapd.request("WPS_AP_PIN disable")
621
622     with alloc_fail(hapd, 1, "upnp_wps_set_ap_pin"):
623         hapd.request("WPS_AP_PIN set 12345670")
624         hapd.request("WPS_AP_PIN disable")
625
626 def test_ap_wps_reg_config(dev, apdev):
627     """WPS registrar configuring an AP using AP PIN"""
628     ssid = "test-wps-init-ap-pin"
629     appin = "12345670"
630     hostapd.add_ap(apdev[0]['ifname'],
631                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
632                      "ap_pin": appin})
633     logger.info("WPS configuration step")
634     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
635     dev[0].dump_monitor()
636     new_ssid = "wps-new-ssid"
637     new_passphrase = "1234567890"
638     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
639                    new_passphrase)
640     status = dev[0].get_status()
641     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
642         raise Exception("Not fully connected")
643     if status['ssid'] != new_ssid:
644         raise Exception("Unexpected SSID")
645     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
646         raise Exception("Unexpected encryption configuration")
647     if status['key_mgmt'] != 'WPA2-PSK':
648         raise Exception("Unexpected key_mgmt")
649
650     logger.info("Re-configure back to open")
651     dev[0].request("REMOVE_NETWORK all")
652     dev[0].flush_scan_cache()
653     dev[0].dump_monitor()
654     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
655     status = dev[0].get_status()
656     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
657         raise Exception("Not fully connected")
658     if status['ssid'] != "wps-open":
659         raise Exception("Unexpected SSID")
660     if status['key_mgmt'] != 'NONE':
661         raise Exception("Unexpected key_mgmt")
662
663 def test_ap_wps_reg_config_ext_processing(dev, apdev):
664     """WPS registrar configuring an AP with external config processing"""
665     ssid = "test-wps-init-ap-pin"
666     appin = "12345670"
667     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
668                "wps_cred_processing": "1", "ap_pin": appin}
669     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
670     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
671     new_ssid = "wps-new-ssid"
672     new_passphrase = "1234567890"
673     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
674                    new_passphrase, no_wait=True)
675     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
676     if ev is None:
677         raise Exception("WPS registrar operation timed out")
678     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
679     if ev is None:
680         raise Exception("WPS configuration timed out")
681     if "1026" not in ev:
682         raise Exception("AP Settings missing from event")
683     hapd.request("SET wps_cred_processing 0")
684     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
685         raise Exception("WPS_CONFIG command failed")
686     dev[0].wait_connected(timeout=15)
687
688 def test_ap_wps_reg_config_tkip(dev, apdev):
689     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
690     skip_with_fips(dev[0])
691     ssid = "test-wps-init-ap"
692     appin = "12345670"
693     hostapd.add_ap(apdev[0]['ifname'],
694                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
695                      "ap_pin": appin})
696     logger.info("WPS configuration step")
697     dev[0].request("SET wps_version_number 0x10")
698     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
699     dev[0].dump_monitor()
700     new_ssid = "wps-new-ssid-with-tkip"
701     new_passphrase = "1234567890"
702     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
703                    new_passphrase)
704     logger.info("Re-connect to verify WPA2 mixed mode")
705     dev[0].request("DISCONNECT")
706     id = 0
707     dev[0].set_network(id, "pairwise", "CCMP")
708     dev[0].set_network(id, "proto", "RSN")
709     dev[0].connect_network(id)
710     status = dev[0].get_status()
711     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
712         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
713     if status['ssid'] != new_ssid:
714         raise Exception("Unexpected SSID")
715     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
716         raise Exception("Unexpected encryption configuration")
717     if status['key_mgmt'] != 'WPA2-PSK':
718         raise Exception("Unexpected key_mgmt")
719
720 def test_ap_wps_setup_locked(dev, apdev):
721     """WPS registrar locking up AP setup on AP PIN failures"""
722     ssid = "test-wps-incorrect-ap-pin"
723     appin = "12345670"
724     hostapd.add_ap(apdev[0]['ifname'],
725                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
726                      "wpa_passphrase": "12345678", "wpa": "2",
727                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
728                      "ap_pin": appin})
729     new_ssid = "wps-new-ssid-test"
730     new_passphrase = "1234567890"
731
732     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
733     ap_setup_locked=False
734     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
735         dev[0].dump_monitor()
736         logger.info("Try incorrect AP PIN - attempt " + pin)
737         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
738                        "CCMP", new_passphrase, no_wait=True)
739         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
740         if ev is None:
741             raise Exception("Timeout on receiving WPS operation failure event")
742         if "CTRL-EVENT-CONNECTED" in ev:
743             raise Exception("Unexpected connection")
744         if "config_error=15" in ev:
745             logger.info("AP Setup Locked")
746             ap_setup_locked=True
747         elif "config_error=18" not in ev:
748             raise Exception("config_error=18 not reported")
749         dev[0].wait_disconnected(timeout=10)
750         time.sleep(0.1)
751     if not ap_setup_locked:
752         raise Exception("AP setup was not locked")
753     dev[0].request("WPS_CANCEL")
754     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True,
755                         only_new=True)
756     bss = dev[0].get_bss(apdev[0]['bssid'])
757     if 'wps_ap_setup_locked' not in bss or bss['wps_ap_setup_locked'] != '1':
758         logger.info("BSS: " + str(bss))
759         raise Exception("AP Setup Locked not indicated in scan results")
760
761     hapd = hostapd.Hostapd(apdev[0]['ifname'])
762     status = hapd.request("WPS_GET_STATUS")
763     if "Last WPS result: Failed" not in status:
764         raise Exception("WPS failure result not shown correctly")
765     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
766         raise Exception("Peer address not shown correctly")
767
768     time.sleep(0.5)
769     dev[0].dump_monitor()
770     logger.info("WPS provisioning step")
771     pin = dev[0].wps_read_pin()
772     hapd = hostapd.Hostapd(apdev[0]['ifname'])
773     hapd.request("WPS_PIN any " + pin)
774     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
775     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
776     if ev is None:
777         raise Exception("WPS success was not reported")
778     dev[0].wait_connected(timeout=30)
779
780     appin = hapd.request("WPS_AP_PIN random")
781     if "FAIL" in appin:
782         raise Exception("Could not generate random AP PIN")
783     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
784     if ev is None:
785         raise Exception("Failed to unlock AP PIN")
786
787 def test_ap_wps_setup_locked_timeout(dev, apdev):
788     """WPS re-enabling AP PIN after timeout"""
789     ssid = "test-wps-incorrect-ap-pin"
790     appin = "12345670"
791     hostapd.add_ap(apdev[0]['ifname'],
792                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
793                      "wpa_passphrase": "12345678", "wpa": "2",
794                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
795                      "ap_pin": appin})
796     new_ssid = "wps-new-ssid-test"
797     new_passphrase = "1234567890"
798
799     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
800     ap_setup_locked=False
801     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
802         dev[0].dump_monitor()
803         logger.info("Try incorrect AP PIN - attempt " + pin)
804         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
805                        "CCMP", new_passphrase, no_wait=True)
806         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
807         if ev is None:
808             raise Exception("Timeout on receiving WPS operation failure event")
809         if "CTRL-EVENT-CONNECTED" in ev:
810             raise Exception("Unexpected connection")
811         if "config_error=15" in ev:
812             logger.info("AP Setup Locked")
813             ap_setup_locked=True
814             break
815         elif "config_error=18" not in ev:
816             raise Exception("config_error=18 not reported")
817         dev[0].wait_disconnected(timeout=10)
818         time.sleep(0.1)
819     if not ap_setup_locked:
820         raise Exception("AP setup was not locked")
821     hapd = hostapd.Hostapd(apdev[0]['ifname'])
822     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
823     if ev is None:
824         raise Exception("AP PIN did not get unlocked on 60 second timeout")
825
826 def test_ap_wps_setup_locked_2(dev, apdev):
827     """WPS AP configured for special ap_setup_locked=2 mode"""
828     ssid = "test-wps-ap-pin"
829     appin = "12345670"
830     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
831                "wpa_passphrase": "12345678", "wpa": "2",
832                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
833                "ap_pin": appin, "ap_setup_locked": "2" }
834     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
835     new_ssid = "wps-new-ssid-test"
836     new_passphrase = "1234567890"
837
838     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
839     dev[0].wps_reg(apdev[0]['bssid'], appin)
840     dev[0].request("REMOVE_NETWORK all")
841     dev[0].wait_disconnected()
842
843     hapd.dump_monitor()
844     dev[0].dump_monitor()
845     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK",
846                    "CCMP", new_passphrase, no_wait=True)
847
848     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
849     if ev is None:
850         raise Exception("hostapd did not report WPS failure")
851     if "msg=12 config_error=15" not in ev:
852         raise Exception("Unexpected failure reason (AP): " + ev)
853
854     ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
855     if ev is None:
856         raise Exception("Timeout on receiving WPS operation failure event")
857     if "CTRL-EVENT-CONNECTED" in ev:
858         raise Exception("Unexpected connection")
859     if "config_error=15" not in ev:
860         raise Exception("Unexpected failure reason (STA): " + ev)
861     dev[0].request("WPS_CANCEL")
862     dev[0].wait_disconnected()
863
864 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
865     """WPS PBC session overlap with two active APs"""
866     hostapd.add_ap(apdev[0]['ifname'],
867                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
868                      "wpa_passphrase": "12345678", "wpa": "2",
869                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
870                      "wps_independent": "1"})
871     hostapd.add_ap(apdev[1]['ifname'],
872                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
873                      "wpa_passphrase": "123456789", "wpa": "2",
874                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
875                      "wps_independent": "1"})
876     hapd = hostapd.Hostapd(apdev[0]['ifname'])
877     hapd.request("WPS_PBC")
878     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
879     hapd2.request("WPS_PBC")
880     logger.info("WPS provisioning step")
881     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
882     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
883     dev[0].request("WPS_PBC")
884     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
885     if ev is None:
886         raise Exception("PBC session overlap not detected")
887     hapd.request("DISABLE")
888     hapd2.request("DISABLE")
889     dev[0].flush_scan_cache()
890
891 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
892     """WPS PBC session overlap with two active STAs"""
893     ssid = "test-wps-pbc-overlap"
894     hostapd.add_ap(apdev[0]['ifname'],
895                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
896                      "wpa_passphrase": "12345678", "wpa": "2",
897                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
898     hapd = hostapd.Hostapd(apdev[0]['ifname'])
899     logger.info("WPS provisioning step")
900     hapd.request("WPS_PBC")
901     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
902     dev[0].dump_monitor()
903     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
904     dev[1].dump_monitor()
905     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
906     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
907     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
908     if ev is None:
909         raise Exception("PBC session overlap not detected (dev0)")
910     if "config_error=12" not in ev:
911         raise Exception("PBC session overlap not correctly reported (dev0)")
912     dev[0].request("WPS_CANCEL")
913     dev[0].request("DISCONNECT")
914     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
915     if ev is None:
916         raise Exception("PBC session overlap not detected (dev1)")
917     if "config_error=12" not in ev:
918         raise Exception("PBC session overlap not correctly reported (dev1)")
919     dev[1].request("WPS_CANCEL")
920     dev[1].request("DISCONNECT")
921     hapd.request("WPS_CANCEL")
922     ret = hapd.request("WPS_PBC")
923     if "FAIL" not in ret:
924         raise Exception("PBC mode allowed to be started while PBC overlap still active")
925     hapd.request("DISABLE")
926     dev[0].flush_scan_cache()
927     dev[1].flush_scan_cache()
928
929 def test_ap_wps_cancel(dev, apdev):
930     """WPS AP cancelling enabled config method"""
931     ssid = "test-wps-ap-cancel"
932     hostapd.add_ap(apdev[0]['ifname'],
933                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
934                      "wpa_passphrase": "12345678", "wpa": "2",
935                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
936     bssid = apdev[0]['bssid']
937     hapd = hostapd.Hostapd(apdev[0]['ifname'])
938
939     logger.info("Verify PBC enable/cancel")
940     hapd.request("WPS_PBC")
941     dev[0].scan(freq="2412")
942     dev[0].scan(freq="2412")
943     bss = dev[0].get_bss(apdev[0]['bssid'])
944     if "[WPS-PBC]" not in bss['flags']:
945         raise Exception("WPS-PBC flag missing")
946     if "FAIL" in hapd.request("WPS_CANCEL"):
947         raise Exception("WPS_CANCEL failed")
948     dev[0].scan(freq="2412")
949     dev[0].scan(freq="2412")
950     bss = dev[0].get_bss(apdev[0]['bssid'])
951     if "[WPS-PBC]" in bss['flags']:
952         raise Exception("WPS-PBC flag not cleared")
953
954     logger.info("Verify PIN enable/cancel")
955     hapd.request("WPS_PIN any 12345670")
956     dev[0].scan(freq="2412")
957     dev[0].scan(freq="2412")
958     bss = dev[0].get_bss(apdev[0]['bssid'])
959     if "[WPS-AUTH]" not in bss['flags']:
960         raise Exception("WPS-AUTH flag missing")
961     if "FAIL" in hapd.request("WPS_CANCEL"):
962         raise Exception("WPS_CANCEL failed")
963     dev[0].scan(freq="2412")
964     dev[0].scan(freq="2412")
965     bss = dev[0].get_bss(apdev[0]['bssid'])
966     if "[WPS-AUTH]" in bss['flags']:
967         raise Exception("WPS-AUTH flag not cleared")
968
969 def test_ap_wps_er_add_enrollee(dev, apdev):
970     """WPS ER configuring AP and adding a new enrollee using PIN"""
971     try:
972         _test_ap_wps_er_add_enrollee(dev, apdev)
973     finally:
974         dev[0].request("WPS_ER_STOP")
975
976 def _test_ap_wps_er_add_enrollee(dev, apdev):
977     ssid = "wps-er-add-enrollee"
978     ap_pin = "12345670"
979     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
980     hostapd.add_ap(apdev[0]['ifname'],
981                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
982                      "device_name": "Wireless AP", "manufacturer": "Company",
983                      "model_name": "WAP", "model_number": "123",
984                      "serial_number": "12345", "device_type": "6-0050F204-1",
985                      "os_version": "01020300",
986                      'friendly_name': "WPS AP - <>&'\" - TEST",
987                      "config_methods": "label push_button",
988                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
989     logger.info("WPS configuration step")
990     new_passphrase = "1234567890"
991     dev[0].dump_monitor()
992     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
993     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
994                    new_passphrase)
995     status = dev[0].get_status()
996     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
997         raise Exception("Not fully connected")
998     if status['ssid'] != ssid:
999         raise Exception("Unexpected SSID")
1000     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
1001         raise Exception("Unexpected encryption configuration")
1002     if status['key_mgmt'] != 'WPA2-PSK':
1003         raise Exception("Unexpected key_mgmt")
1004
1005     logger.info("Start ER")
1006     dev[0].request("WPS_ER_START ifname=lo")
1007     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1008     if ev is None:
1009         raise Exception("AP discovery timed out")
1010     if ap_uuid not in ev:
1011         raise Exception("Expected AP UUID not found")
1012     if "|WPS AP - &lt;&gt;&amp;&apos;&quot; - TEST|Company|" not in ev:
1013         raise Exception("Expected friendly name not found")
1014
1015     logger.info("Learn AP configuration through UPnP")
1016     dev[0].dump_monitor()
1017     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1018     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1019     if ev is None:
1020         raise Exception("AP learn timed out")
1021     if ap_uuid not in ev:
1022         raise Exception("Expected AP UUID not in settings")
1023     if "ssid=" + ssid not in ev:
1024         raise Exception("Expected SSID not in settings")
1025     if "key=" + new_passphrase not in ev:
1026         raise Exception("Expected passphrase not in settings")
1027     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1028     if ev is None:
1029         raise Exception("WPS-FAIL after AP learn timed out")
1030     time.sleep(0.1)
1031
1032     logger.info("Add Enrollee using ER")
1033     pin = dev[1].wps_read_pin()
1034     dev[0].dump_monitor()
1035     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1036     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1037     dev[1].dump_monitor()
1038     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1039     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1040     if ev is None:
1041         raise Exception("Enrollee did not report success")
1042     dev[1].wait_connected(timeout=15)
1043     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1044     if ev is None:
1045         raise Exception("WPS ER did not report success")
1046     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1047
1048     logger.info("Add a specific Enrollee using ER")
1049     pin = dev[2].wps_read_pin()
1050     addr2 = dev[2].p2p_interface_addr()
1051     dev[0].dump_monitor()
1052     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1053     dev[2].dump_monitor()
1054     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1055     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1056     if ev is None:
1057         raise Exception("Enrollee not seen")
1058     if addr2 not in ev:
1059         raise Exception("Unexpected Enrollee MAC address")
1060     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
1061     dev[2].wait_connected(timeout=30)
1062     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1063     if ev is None:
1064         raise Exception("WPS ER did not report success")
1065
1066     logger.info("Verify registrar selection behavior")
1067     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1068     dev[1].request("DISCONNECT")
1069     dev[1].wait_disconnected(timeout=10)
1070     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1071     dev[1].scan(freq="2412")
1072     bss = dev[1].get_bss(apdev[0]['bssid'])
1073     if "[WPS-AUTH]" not in bss['flags']:
1074         # It is possible for scan to miss an update especially when running
1075         # tests under load with multiple VMs, so allow another attempt.
1076         dev[1].scan(freq="2412")
1077         bss = dev[1].get_bss(apdev[0]['bssid'])
1078         if "[WPS-AUTH]" not in bss['flags']:
1079             raise Exception("WPS-AUTH flag missing")
1080
1081     logger.info("Stop ER")
1082     dev[0].dump_monitor()
1083     dev[0].request("WPS_ER_STOP")
1084     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
1085     if ev is None:
1086         raise Exception("WPS ER unsubscription timed out")
1087     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
1088     # a bit before verifying that the scan results have changed.
1089     time.sleep(0.2)
1090
1091     for i in range(0, 10):
1092         dev[1].request("BSS_FLUSH 0")
1093         dev[1].scan(freq="2412", only_new=True)
1094         bss = dev[1].get_bss(apdev[0]['bssid'])
1095         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
1096             break
1097         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
1098         time.sleep(0.1)
1099     if "[WPS-AUTH]" in bss['flags']:
1100         raise Exception("WPS-AUTH flag not removed")
1101
1102 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1103     """WPS ER adding a new enrollee identified by UUID"""
1104     try:
1105         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
1106     finally:
1107         dev[0].request("WPS_ER_STOP")
1108
1109 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1110     ssid = "wps-er-add-enrollee"
1111     ap_pin = "12345670"
1112     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1113     hostapd.add_ap(apdev[0]['ifname'],
1114                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1115                      "wpa_passphrase": "12345678", "wpa": "2",
1116                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1117                      "device_name": "Wireless AP", "manufacturer": "Company",
1118                      "model_name": "WAP", "model_number": "123",
1119                      "serial_number": "12345", "device_type": "6-0050F204-1",
1120                      "os_version": "01020300",
1121                      "config_methods": "label push_button",
1122                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1123     logger.info("WPS configuration step")
1124     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1125     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1126
1127     logger.info("Start ER")
1128     dev[0].request("WPS_ER_START ifname=lo")
1129     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1130     if ev is None:
1131         raise Exception("AP discovery timed out")
1132     if ap_uuid not in ev:
1133         raise Exception("Expected AP UUID not found")
1134
1135     logger.info("Learn AP configuration through UPnP")
1136     dev[0].dump_monitor()
1137     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1138     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1139     if ev is None:
1140         raise Exception("AP learn timed out")
1141     if ap_uuid not in ev:
1142         raise Exception("Expected AP UUID not in settings")
1143     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1144     if ev is None:
1145         raise Exception("WPS-FAIL after AP learn timed out")
1146     time.sleep(0.1)
1147
1148     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1149     addr1 = dev[1].p2p_interface_addr()
1150     dev[0].dump_monitor()
1151     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1152     dev[1].dump_monitor()
1153     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1154     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1155     if ev is None:
1156         raise Exception("Enrollee not seen")
1157     if addr1 not in ev:
1158         raise Exception("Unexpected Enrollee MAC address")
1159     uuid = ev.split(' ')[1]
1160     dev[0].request("WPS_ER_PBC " + uuid)
1161     dev[1].wait_connected(timeout=30)
1162     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1163     if ev is None:
1164         raise Exception("WPS ER did not report success")
1165
1166     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1167     pin = dev[2].wps_read_pin()
1168     addr2 = dev[2].p2p_interface_addr()
1169     dev[0].dump_monitor()
1170     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1171     dev[2].dump_monitor()
1172     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1173     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1174     if ev is None:
1175         raise Exception("Enrollee not seen")
1176     if addr2 not in ev:
1177         raise Exception("Unexpected Enrollee MAC address")
1178     uuid = ev.split(' ')[1]
1179     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1180     dev[2].wait_connected(timeout=30)
1181     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1182     if ev is None:
1183         raise Exception("WPS ER did not report success")
1184
1185     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-REMOVE"], timeout=15)
1186     if ev is None:
1187         raise Exception("No Enrollee STA entry timeout seen")
1188
1189     logger.info("Stop ER")
1190     dev[0].dump_monitor()
1191     dev[0].request("WPS_ER_STOP")
1192
1193 def test_ap_wps_er_multi_add_enrollee(dev, apdev):
1194     """Multiple WPS ERs adding a new enrollee using PIN"""
1195     try:
1196         _test_ap_wps_er_multi_add_enrollee(dev, apdev)
1197     finally:
1198         dev[0].request("WPS_ER_STOP")
1199
1200 def _test_ap_wps_er_multi_add_enrollee(dev, apdev):
1201     ssid = "wps-er-add-enrollee"
1202     ap_pin = "12345670"
1203     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1204     hostapd.add_ap(apdev[0]['ifname'],
1205                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1206                      "wpa_passphrase": "12345678", "wpa": "2",
1207                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1208                      "device_name": "Wireless AP", "manufacturer": "Company",
1209                      "model_name": "WAP", "model_number": "123",
1210                      "serial_number": "12345", "device_type": "6-0050F204-1",
1211                      "os_version": "01020300",
1212                      'friendly_name': "WPS AP",
1213                      "config_methods": "label push_button",
1214                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1215
1216     for i in range(2):
1217         dev[i].scan_for_bss(apdev[0]['bssid'], freq=2412)
1218         dev[i].wps_reg(apdev[0]['bssid'], ap_pin)
1219         dev[i].request("WPS_ER_START ifname=lo")
1220     for i in range(2):
1221         ev = dev[i].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1222         if ev is None:
1223             raise Exception("AP discovery timed out")
1224         dev[i].dump_monitor()
1225         dev[i].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1226         ev = dev[i].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1227         if ev is None:
1228             raise Exception("AP learn timed out")
1229         ev = dev[i].wait_event(["WPS-FAIL"], timeout=15)
1230         if ev is None:
1231             raise Exception("WPS-FAIL after AP learn timed out")
1232
1233     time.sleep(0.1)
1234
1235     pin = dev[2].wps_read_pin()
1236     addr = dev[2].own_addr()
1237     dev[0].dump_monitor()
1238     dev[0].request("WPS_ER_PIN any " + pin + " " + addr)
1239     dev[1].dump_monitor()
1240     dev[1].request("WPS_ER_PIN any " + pin + " " + addr)
1241
1242     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1243     dev[2].dump_monitor()
1244     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1245     ev = dev[2].wait_event(["WPS-SUCCESS"], timeout=30)
1246     if ev is None:
1247         raise Exception("Enrollee did not report success")
1248     dev[2].wait_connected(timeout=15)
1249
1250 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1251     """WPS ER connected to AP and adding a new enrollee using PBC"""
1252     try:
1253         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1254     finally:
1255         dev[0].request("WPS_ER_STOP")
1256
1257 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1258     ssid = "wps-er-add-enrollee-pbc"
1259     ap_pin = "12345670"
1260     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1261     hostapd.add_ap(apdev[0]['ifname'],
1262                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1263                      "wpa_passphrase": "12345678", "wpa": "2",
1264                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1265                      "device_name": "Wireless AP", "manufacturer": "Company",
1266                      "model_name": "WAP", "model_number": "123",
1267                      "serial_number": "12345", "device_type": "6-0050F204-1",
1268                      "os_version": "01020300",
1269                      "config_methods": "label push_button",
1270                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1271     logger.info("Learn AP configuration")
1272     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1273     dev[0].dump_monitor()
1274     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1275     status = dev[0].get_status()
1276     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1277         raise Exception("Not fully connected")
1278
1279     logger.info("Start ER")
1280     dev[0].request("WPS_ER_START ifname=lo")
1281     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1282     if ev is None:
1283         raise Exception("AP discovery timed out")
1284     if ap_uuid not in ev:
1285         raise Exception("Expected AP UUID not found")
1286
1287     enrollee = dev[1].p2p_interface_addr()
1288
1289     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1290         raise Exception("Unknown UUID not reported")
1291
1292     logger.info("Add Enrollee using ER and PBC")
1293     dev[0].dump_monitor()
1294     dev[1].dump_monitor()
1295     dev[1].request("WPS_PBC")
1296
1297     for i in range(0, 2):
1298         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1299         if ev is None:
1300             raise Exception("Enrollee discovery timed out")
1301         if enrollee in ev:
1302             break
1303         if i == 1:
1304             raise Exception("Expected Enrollee not found")
1305     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1306         raise Exception("Unknown UUID not reported")
1307     logger.info("Use learned network configuration on ER")
1308     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1309     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1310         raise Exception("WPS_ER_PBC failed")
1311
1312     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1313     if ev is None:
1314         raise Exception("Enrollee did not report success")
1315     dev[1].wait_connected(timeout=15)
1316     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1317     if ev is None:
1318         raise Exception("WPS ER did not report success")
1319     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1320
1321 def test_ap_wps_er_pbc_overlap(dev, apdev):
1322     """WPS ER connected to AP and PBC session overlap"""
1323     try:
1324         _test_ap_wps_er_pbc_overlap(dev, apdev)
1325     finally:
1326         dev[0].request("WPS_ER_STOP")
1327
1328 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1329     ssid = "wps-er-add-enrollee-pbc"
1330     ap_pin = "12345670"
1331     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1332     hostapd.add_ap(apdev[0]['ifname'],
1333                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1334                      "wpa_passphrase": "12345678", "wpa": "2",
1335                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1336                      "device_name": "Wireless AP", "manufacturer": "Company",
1337                      "model_name": "WAP", "model_number": "123",
1338                      "serial_number": "12345", "device_type": "6-0050F204-1",
1339                      "os_version": "01020300",
1340                      "config_methods": "label push_button",
1341                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1342     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1343     dev[0].dump_monitor()
1344     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1345
1346     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1347     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1348     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1349     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1350
1351     dev[0].dump_monitor()
1352     dev[0].request("WPS_ER_START ifname=lo")
1353
1354     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1355     if ev is None:
1356         raise Exception("AP discovery timed out")
1357     if ap_uuid not in ev:
1358         raise Exception("Expected AP UUID not found")
1359
1360     # verify BSSID selection of the AP instead of UUID
1361     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1362         raise Exception("Could not select AP based on BSSID")
1363
1364     dev[0].dump_monitor()
1365     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1366     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1367     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1368     if ev is None:
1369         raise Exception("PBC scan failed")
1370     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1371     if ev is None:
1372         raise Exception("PBC scan failed")
1373     found1 = False
1374     found2 = False
1375     addr1 = dev[1].own_addr()
1376     addr2 = dev[2].own_addr()
1377     for i in range(3):
1378         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1379         if ev is None:
1380             raise Exception("Enrollee discovery timed out")
1381         if addr1 in ev:
1382             found1 = True
1383             if found2:
1384                 break
1385         if addr2 in ev:
1386             found2 = True
1387             if found1:
1388                 break
1389     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1390         raise Exception("PBC overlap not reported")
1391     dev[1].request("WPS_CANCEL")
1392     dev[2].request("WPS_CANCEL")
1393     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1394         raise Exception("Invalid WPS_ER_PBC accepted")
1395
1396 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1397     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1398     try:
1399         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1400     finally:
1401         dev[0].request("WPS_ER_STOP")
1402
1403 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1404     ssid = "wps-er-add-enrollee-pbc"
1405     ap_pin = "12345670"
1406     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1407     hostapd.add_ap(apdev[0]['ifname'],
1408                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1409                      "wpa_passphrase": "12345678", "wpa": "2",
1410                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1411                      "device_name": "Wireless AP", "manufacturer": "Company",
1412                      "model_name": "WAP", "model_number": "123",
1413                      "serial_number": "12345", "device_type": "6-0050F204-1",
1414                      "os_version": "01020300",
1415                      "config_methods": "label push_button",
1416                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1417     logger.info("Learn AP configuration")
1418     dev[0].request("SET wps_version_number 0x10")
1419     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1420     dev[0].dump_monitor()
1421     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1422     status = dev[0].get_status()
1423     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1424         raise Exception("Not fully connected")
1425
1426     logger.info("Start ER")
1427     dev[0].request("WPS_ER_START ifname=lo")
1428     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1429     if ev is None:
1430         raise Exception("AP discovery timed out")
1431     if ap_uuid not in ev:
1432         raise Exception("Expected AP UUID not found")
1433
1434     logger.info("Use learned network configuration on ER")
1435     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1436
1437     logger.info("Add Enrollee using ER and PIN")
1438     enrollee = dev[1].p2p_interface_addr()
1439     pin = dev[1].wps_read_pin()
1440     dev[0].dump_monitor()
1441     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1442     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1443     dev[1].dump_monitor()
1444     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1445     dev[1].wait_connected(timeout=30)
1446     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1447     if ev is None:
1448         raise Exception("WPS ER did not report success")
1449
1450 def test_ap_wps_er_config_ap(dev, apdev):
1451     """WPS ER configuring AP over UPnP"""
1452     try:
1453         _test_ap_wps_er_config_ap(dev, apdev)
1454     finally:
1455         dev[0].request("WPS_ER_STOP")
1456
1457 def _test_ap_wps_er_config_ap(dev, apdev):
1458     ssid = "wps-er-ap-config"
1459     ap_pin = "12345670"
1460     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1461     hostapd.add_ap(apdev[0]['ifname'],
1462                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1463                      "wpa_passphrase": "12345678", "wpa": "2",
1464                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1465                      "device_name": "Wireless AP", "manufacturer": "Company",
1466                      "model_name": "WAP", "model_number": "123",
1467                      "serial_number": "12345", "device_type": "6-0050F204-1",
1468                      "os_version": "01020300",
1469                      "config_methods": "label push_button",
1470                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1471
1472     logger.info("Connect ER to the AP")
1473     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1474
1475     logger.info("WPS configuration step")
1476     dev[0].request("WPS_ER_START ifname=lo")
1477     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1478     if ev is None:
1479         raise Exception("AP discovery timed out")
1480     if ap_uuid not in ev:
1481         raise Exception("Expected AP UUID not found")
1482     new_passphrase = "1234567890"
1483     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1484                    ssid.encode("hex") + " WPA2PSK CCMP " +
1485                    new_passphrase.encode("hex"))
1486     ev = dev[0].wait_event(["WPS-SUCCESS"])
1487     if ev is None:
1488         raise Exception("WPS ER configuration operation timed out")
1489     dev[0].wait_disconnected(timeout=10)
1490     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1491
1492     logger.info("WPS ER restart")
1493     dev[0].request("WPS_ER_START")
1494     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1495     if ev is None:
1496         raise Exception("AP discovery timed out on ER restart")
1497     if ap_uuid not in ev:
1498         raise Exception("Expected AP UUID not found on ER restart")
1499     if "OK" not in dev[0].request("WPS_ER_STOP"):
1500         raise Exception("WPS_ER_STOP failed")
1501     if "OK" not in dev[0].request("WPS_ER_STOP"):
1502         raise Exception("WPS_ER_STOP failed")
1503
1504 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1505     """WPS ER caching AP settings"""
1506     try:
1507         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1508     finally:
1509         dev[0].request("WPS_ER_STOP")
1510
1511 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1512     ssid = "wps-er-add-enrollee"
1513     ap_pin = "12345670"
1514     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1515     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1516                "wpa_passphrase": "12345678", "wpa": "2",
1517                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1518                "device_name": "Wireless AP", "manufacturer": "Company",
1519                "model_name": "WAP", "model_number": "123",
1520                "serial_number": "12345", "device_type": "6-0050F204-1",
1521                "os_version": "01020300",
1522                "config_methods": "label push_button",
1523                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1524     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1525     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1526     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1527     id = int(dev[0].list_networks()[0]['id'])
1528     dev[0].set_network(id, "scan_freq", "2412")
1529
1530     dev[0].request("WPS_ER_START ifname=lo")
1531     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1532     if ev is None:
1533         raise Exception("AP discovery timed out")
1534     if ap_uuid not in ev:
1535         raise Exception("Expected AP UUID not found")
1536
1537     dev[0].dump_monitor()
1538     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1539     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1540     if ev is None:
1541         raise Exception("AP learn timed out")
1542     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1543     if ev is None:
1544         raise Exception("WPS-FAIL after AP learn timed out")
1545     time.sleep(0.1)
1546
1547     hapd.disable()
1548
1549     for i in range(2):
1550         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1551                                  "CTRL-EVENT-DISCONNECTED" ],
1552                                timeout=15)
1553         if ev is None:
1554             raise Exception("AP removal or disconnection timed out")
1555
1556     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1557     for i in range(2):
1558         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1559                                timeout=15)
1560         if ev is None:
1561             raise Exception("AP discovery or connection timed out")
1562
1563     pin = dev[1].wps_read_pin()
1564     dev[0].dump_monitor()
1565     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1566
1567     time.sleep(0.2)
1568
1569     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1570     dev[1].dump_monitor()
1571     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1572     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1573     if ev is None:
1574         raise Exception("Enrollee did not report success")
1575     dev[1].wait_connected(timeout=15)
1576     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1577     if ev is None:
1578         raise Exception("WPS ER did not report success")
1579
1580     dev[0].dump_monitor()
1581     dev[0].request("WPS_ER_STOP")
1582
1583 def test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1584     """WPS ER caching AP settings (OOM)"""
1585     try:
1586         _test_ap_wps_er_cache_ap_settings_oom(dev, apdev)
1587     finally:
1588         dev[0].request("WPS_ER_STOP")
1589
1590 def _test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1591     ssid = "wps-er-add-enrollee"
1592     ap_pin = "12345670"
1593     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1594     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1595                "wpa_passphrase": "12345678", "wpa": "2",
1596                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1597                "device_name": "Wireless AP", "manufacturer": "Company",
1598                "model_name": "WAP", "model_number": "123",
1599                "serial_number": "12345", "device_type": "6-0050F204-1",
1600                "os_version": "01020300",
1601                "config_methods": "label push_button",
1602                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1603     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1604     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1605     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1606     id = int(dev[0].list_networks()[0]['id'])
1607     dev[0].set_network(id, "scan_freq", "2412")
1608
1609     dev[0].request("WPS_ER_START ifname=lo")
1610     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1611     if ev is None:
1612         raise Exception("AP discovery timed out")
1613     if ap_uuid not in ev:
1614         raise Exception("Expected AP UUID not found")
1615
1616     dev[0].dump_monitor()
1617     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1618     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1619     if ev is None:
1620         raise Exception("AP learn timed out")
1621     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1622     if ev is None:
1623         raise Exception("WPS-FAIL after AP learn timed out")
1624     time.sleep(0.1)
1625
1626     with alloc_fail(dev[0], 1, "=wps_er_ap_use_cached_settings"):
1627         hapd.disable()
1628
1629         for i in range(2):
1630             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1631                                      "CTRL-EVENT-DISCONNECTED" ],
1632                                    timeout=15)
1633             if ev is None:
1634                 raise Exception("AP removal or disconnection timed out")
1635
1636         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1637         for i in range(2):
1638             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1639                                    timeout=15)
1640             if ev is None:
1641                 raise Exception("AP discovery or connection timed out")
1642
1643     dev[0].request("WPS_ER_STOP")
1644
1645 def test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1646     """WPS ER caching AP settings (OOM 2)"""
1647     try:
1648         _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev)
1649     finally:
1650         dev[0].request("WPS_ER_STOP")
1651
1652 def _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1653     ssid = "wps-er-add-enrollee"
1654     ap_pin = "12345670"
1655     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1656     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1657                "wpa_passphrase": "12345678", "wpa": "2",
1658                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1659                "device_name": "Wireless AP", "manufacturer": "Company",
1660                "model_name": "WAP", "model_number": "123",
1661                "serial_number": "12345", "device_type": "6-0050F204-1",
1662                "os_version": "01020300",
1663                "config_methods": "label push_button",
1664                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1665     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1666     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1667     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1668     id = int(dev[0].list_networks()[0]['id'])
1669     dev[0].set_network(id, "scan_freq", "2412")
1670
1671     dev[0].request("WPS_ER_START ifname=lo")
1672     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1673     if ev is None:
1674         raise Exception("AP discovery timed out")
1675     if ap_uuid not in ev:
1676         raise Exception("Expected AP UUID not found")
1677
1678     dev[0].dump_monitor()
1679     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1680     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1681     if ev is None:
1682         raise Exception("AP learn timed out")
1683     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1684     if ev is None:
1685         raise Exception("WPS-FAIL after AP learn timed out")
1686     time.sleep(0.1)
1687
1688     with alloc_fail(dev[0], 1, "=wps_er_ap_cache_settings"):
1689         hapd.disable()
1690
1691         for i in range(2):
1692             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1693                                      "CTRL-EVENT-DISCONNECTED" ],
1694                                    timeout=15)
1695             if ev is None:
1696                 raise Exception("AP removal or disconnection timed out")
1697
1698         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1699         for i in range(2):
1700             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1701                                    timeout=15)
1702             if ev is None:
1703                 raise Exception("AP discovery or connection timed out")
1704
1705     dev[0].request("WPS_ER_STOP")
1706
1707 def test_ap_wps_er_subscribe_oom(dev, apdev):
1708     """WPS ER subscribe OOM"""
1709     try:
1710         _test_ap_wps_er_subscribe_oom(dev, apdev)
1711     finally:
1712         dev[0].request("WPS_ER_STOP")
1713
1714 def _test_ap_wps_er_subscribe_oom(dev, apdev):
1715     ssid = "wps-er-add-enrollee"
1716     ap_pin = "12345670"
1717     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1718     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1719                "wpa_passphrase": "12345678", "wpa": "2",
1720                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1721                "device_name": "Wireless AP", "manufacturer": "Company",
1722                "model_name": "WAP", "model_number": "123",
1723                "serial_number": "12345", "device_type": "6-0050F204-1",
1724                "os_version": "01020300",
1725                "config_methods": "label push_button",
1726                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1727     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1728     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1729     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1730     id = int(dev[0].list_networks()[0]['id'])
1731     dev[0].set_network(id, "scan_freq", "2412")
1732
1733     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_subscribe"):
1734         dev[0].request("WPS_ER_START ifname=lo")
1735         for i in range(50):
1736             res = dev[0].request("GET_ALLOC_FAIL")
1737             if res.startswith("0:"):
1738                 break
1739             time.sleep(0.1)
1740         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=0)
1741         if ev:
1742             raise Exception("Unexpected AP discovery during OOM")
1743
1744     dev[0].request("WPS_ER_STOP")
1745
1746 def test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1747     """WPS ER SetSelectedRegistrar OOM"""
1748     try:
1749         _test_ap_wps_er_set_sel_reg_oom(dev, apdev)
1750     finally:
1751         dev[0].request("WPS_ER_STOP")
1752
1753 def _test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1754     ssid = "wps-er-add-enrollee"
1755     ap_pin = "12345670"
1756     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1757     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1758                "wpa_passphrase": "12345678", "wpa": "2",
1759                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1760                "device_name": "Wireless AP", "manufacturer": "Company",
1761                "model_name": "WAP", "model_number": "123",
1762                "serial_number": "12345", "device_type": "6-0050F204-1",
1763                "os_version": "01020300",
1764                "config_methods": "label push_button",
1765                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1766     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1767     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1768     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1769
1770     dev[0].request("WPS_ER_START ifname=lo")
1771     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1772     if ev is None:
1773         raise Exception("AP not discovered")
1774
1775     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1776     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1777     if ev is None:
1778         raise Exception("AP learn timed out")
1779     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1780     if ev is None:
1781         raise Exception("WPS-FAIL timed out")
1782     time.sleep(0.1)
1783
1784     for func in [ "http_client_url_parse;wps_er_send_set_sel_reg",
1785                   "wps_er_soap_hdr;wps_er_send_set_sel_reg",
1786                   "http_client_addr;wps_er_send_set_sel_reg",
1787                   "wpabuf_alloc;wps_er_set_sel_reg" ]:
1788         with alloc_fail(dev[0], 1, func):
1789             if "OK" not in dev[0].request("WPS_ER_PBC " + ap_uuid):
1790                 raise Exception("WPS_ER_PBC failed")
1791             ev = dev[0].wait_event(["WPS-PBC-ACTIVE"], timeout=3)
1792             if ev is None:
1793                 raise Exception("WPS-PBC-ACTIVE not seen")
1794
1795     dev[0].request("WPS_ER_STOP")
1796
1797 def test_ap_wps_er_learn_oom(dev, apdev):
1798     """WPS ER learn OOM"""
1799     try:
1800         _test_ap_wps_er_learn_oom(dev, apdev)
1801     finally:
1802         dev[0].request("WPS_ER_STOP")
1803
1804 def _test_ap_wps_er_learn_oom(dev, apdev):
1805     ssid = "wps-er-add-enrollee"
1806     ap_pin = "12345670"
1807     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1808     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1809                "wpa_passphrase": "12345678", "wpa": "2",
1810                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1811                "device_name": "Wireless AP", "manufacturer": "Company",
1812                "model_name": "WAP", "model_number": "123",
1813                "serial_number": "12345", "device_type": "6-0050F204-1",
1814                "os_version": "01020300",
1815                "config_methods": "label push_button",
1816                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1817     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1818     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1819     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1820
1821     dev[0].request("WPS_ER_START ifname=lo")
1822     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1823     if ev is None:
1824         raise Exception("AP not discovered")
1825
1826     for func in [ "wps_er_http_put_message_cb",
1827                   "xml_get_base64_item;wps_er_http_put_message_cb",
1828                   "http_client_url_parse;wps_er_ap_put_message",
1829                   "wps_er_soap_hdr;wps_er_ap_put_message",
1830                   "http_client_addr;wps_er_ap_put_message" ]:
1831         with alloc_fail(dev[0], 1, func):
1832             dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1833             ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=1)
1834             if ev is not None:
1835                 raise Exception("AP learn succeeded during OOM")
1836
1837     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1838     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=10)
1839     if ev is None:
1840         raise Exception("AP learn did not succeed")
1841
1842     if "FAIL" not in dev[0].request("WPS_ER_LEARN 00000000-9e5c-4e73-bd82-f89cbcd10d7e " + ap_pin):
1843         raise Exception("WPS_ER_LEARN for unknown AP accepted")
1844
1845     dev[0].request("WPS_ER_STOP")
1846
1847 def test_ap_wps_fragmentation(dev, apdev):
1848     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1849     ssid = "test-wps-fragmentation"
1850     appin = "12345670"
1851     hostapd.add_ap(apdev[0]['ifname'],
1852                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1853                      "wpa_passphrase": "12345678", "wpa": "3",
1854                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1855                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1856                      "fragment_size": "50" })
1857     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1858     logger.info("WPS provisioning step (PBC)")
1859     hapd.request("WPS_PBC")
1860     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1861     dev[0].dump_monitor()
1862     dev[0].request("SET wps_fragment_size 50")
1863     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1864     dev[0].wait_connected(timeout=30)
1865     status = dev[0].get_status()
1866     if status['wpa_state'] != 'COMPLETED':
1867         raise Exception("Not fully connected")
1868     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1869         raise Exception("Unexpected encryption configuration")
1870     if status['key_mgmt'] != 'WPA2-PSK':
1871         raise Exception("Unexpected key_mgmt")
1872
1873     logger.info("WPS provisioning step (PIN)")
1874     pin = dev[1].wps_read_pin()
1875     hapd.request("WPS_PIN any " + pin)
1876     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1877     dev[1].request("SET wps_fragment_size 50")
1878     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1879     dev[1].wait_connected(timeout=30)
1880     status = dev[1].get_status()
1881     if status['wpa_state'] != 'COMPLETED':
1882         raise Exception("Not fully connected")
1883     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1884         raise Exception("Unexpected encryption configuration")
1885     if status['key_mgmt'] != 'WPA2-PSK':
1886         raise Exception("Unexpected key_mgmt")
1887
1888     logger.info("WPS connection as registrar")
1889     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1890     dev[2].request("SET wps_fragment_size 50")
1891     dev[2].wps_reg(apdev[0]['bssid'], appin)
1892     status = dev[2].get_status()
1893     if status['wpa_state'] != 'COMPLETED':
1894         raise Exception("Not fully connected")
1895     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1896         raise Exception("Unexpected encryption configuration")
1897     if status['key_mgmt'] != 'WPA2-PSK':
1898         raise Exception("Unexpected key_mgmt")
1899
1900 def test_ap_wps_new_version_sta(dev, apdev):
1901     """WPS compatibility with new version number on the station"""
1902     ssid = "test-wps-ver"
1903     hostapd.add_ap(apdev[0]['ifname'],
1904                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1905                      "wpa_passphrase": "12345678", "wpa": "2",
1906                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1907     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1908     logger.info("WPS provisioning step")
1909     hapd.request("WPS_PBC")
1910     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1911     dev[0].dump_monitor()
1912     dev[0].request("SET wps_version_number 0x43")
1913     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1914     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1915     dev[0].wait_connected(timeout=30)
1916
1917 def test_ap_wps_new_version_ap(dev, apdev):
1918     """WPS compatibility with new version number on the AP"""
1919     ssid = "test-wps-ver"
1920     hostapd.add_ap(apdev[0]['ifname'],
1921                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1922                      "wpa_passphrase": "12345678", "wpa": "2",
1923                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1924     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1925     logger.info("WPS provisioning step")
1926     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1927         raise Exception("Failed to enable test functionality")
1928     hapd.request("WPS_PBC")
1929     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1930     dev[0].dump_monitor()
1931     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1932     dev[0].wait_connected(timeout=30)
1933     hapd.request("SET wps_version_number 0x20")
1934
1935 def test_ap_wps_check_pin(dev, apdev):
1936     """Verify PIN checking through control interface"""
1937     hostapd.add_ap(apdev[0]['ifname'],
1938                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1939                      "wpa_passphrase": "12345678", "wpa": "2",
1940                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1941     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1942     for t in [ ("12345670", "12345670"),
1943                ("12345678", "FAIL-CHECKSUM"),
1944                ("12345", "FAIL"),
1945                ("123456789", "FAIL"),
1946                ("1234-5670", "12345670"),
1947                ("1234 5670", "12345670"),
1948                ("1-2.3:4 5670", "12345670") ]:
1949         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1950         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1951         if res != res2:
1952             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1953         if res != t[1]:
1954             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1955
1956     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1957         raise Exception("Unexpected WPS_CHECK_PIN success")
1958     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1959         raise Exception("Unexpected WPS_CHECK_PIN success")
1960
1961     for i in range(0, 10):
1962         pin = dev[0].request("WPS_PIN get")
1963         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1964         if pin != rpin:
1965             raise Exception("Random PIN validation failed for " + pin)
1966
1967 def test_ap_wps_wep_config(dev, apdev):
1968     """WPS 2.0 AP rejecting WEP configuration"""
1969     ssid = "test-wps-config"
1970     appin = "12345670"
1971     hostapd.add_ap(apdev[0]['ifname'],
1972                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1973                      "ap_pin": appin})
1974     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1975     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1976     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1977                    "hello", no_wait=True)
1978     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1979     if ev is None:
1980         raise Exception("WPS-FAIL timed out")
1981     if "reason=2" not in ev:
1982         raise Exception("Unexpected reason code in WPS-FAIL")
1983     status = hapd.request("WPS_GET_STATUS")
1984     if "Last WPS result: Failed" not in status:
1985         raise Exception("WPS failure result not shown correctly")
1986     if "Failure Reason: WEP Prohibited" not in status:
1987         raise Exception("Failure reason not reported correctly")
1988     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1989         raise Exception("Peer address not shown correctly")
1990
1991 def test_ap_wps_wep_enroll(dev, apdev):
1992     """WPS 2.0 STA rejecting WEP configuration"""
1993     ssid = "test-wps-wep"
1994     hostapd.add_ap(apdev[0]['ifname'],
1995                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1996                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1997     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1998     hapd.request("WPS_PBC")
1999     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2000     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2001     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
2002     if ev is None:
2003         raise Exception("WPS-FAIL event timed out")
2004     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
2005         raise Exception("Unexpected WPS-FAIL event: " + ev)
2006
2007 def test_ap_wps_ie_fragmentation(dev, apdev):
2008     """WPS AP using fragmented WPS IE"""
2009     ssid = "test-wps-ie-fragmentation"
2010     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2011                "wpa_passphrase": "12345678", "wpa": "2",
2012                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2013                "device_name": "1234567890abcdef1234567890abcdef",
2014                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
2015                "model_name": "1234567890abcdef1234567890abcdef",
2016                "model_number": "1234567890abcdef1234567890abcdef",
2017                "serial_number": "1234567890abcdef1234567890abcdef" }
2018     hostapd.add_ap(apdev[0]['ifname'], params)
2019     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2020     hapd.request("WPS_PBC")
2021     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2022     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2023     dev[0].wait_connected(timeout=30)
2024     bss = dev[0].get_bss(apdev[0]['bssid'])
2025     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
2026         logger.info("Device Name not received correctly")
2027         logger.info(bss)
2028         # This can fail if Probe Response frame is missed and Beacon frame was
2029         # used to fill in the BSS entry. This can happen, e.g., during heavy
2030         # load every now and then and is not really an error, so try to
2031         # workaround by runnign another scan.
2032         dev[0].scan(freq="2412", only_new=True)
2033         bss = dev[0].get_bss(apdev[0]['bssid'])
2034         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
2035             logger.info(bss)
2036             raise Exception("Device Name not received correctly")
2037     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
2038         raise Exception("Unexpected number of WPS IEs")
2039
2040 def get_psk(pskfile):
2041     psks = {}
2042     with open(pskfile, "r") as f:
2043         lines = f.read().splitlines()
2044         for l in lines:
2045             if l == "# WPA PSKs":
2046                 continue
2047             (addr,psk) = l.split(' ')
2048             psks[addr] = psk
2049     return psks
2050
2051 def test_ap_wps_per_station_psk(dev, apdev):
2052     """WPS PBC provisioning with per-station PSK"""
2053     addr0 = dev[0].own_addr()
2054     addr1 = dev[1].own_addr()
2055     addr2 = dev[2].own_addr()
2056     ssid = "wps"
2057     appin = "12345670"
2058     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2059     try:
2060         os.remove(pskfile)
2061     except:
2062         pass
2063
2064     try:
2065         with open(pskfile, "w") as f:
2066             f.write("# WPA PSKs\n")
2067
2068         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2069                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2070                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2071                    "wpa_psk_file": pskfile }
2072         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2073
2074         logger.info("First enrollee")
2075         hapd.request("WPS_PBC")
2076         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2077         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2078         dev[0].wait_connected(timeout=30)
2079
2080         logger.info("Second enrollee")
2081         hapd.request("WPS_PBC")
2082         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2083         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2084         dev[1].wait_connected(timeout=30)
2085
2086         logger.info("External registrar")
2087         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2088         dev[2].wps_reg(apdev[0]['bssid'], appin)
2089
2090         logger.info("Verifying PSK results")
2091         psks = get_psk(pskfile)
2092         if addr0 not in psks:
2093             raise Exception("No PSK recorded for sta0")
2094         if addr1 not in psks:
2095             raise Exception("No PSK recorded for sta1")
2096         if addr2 not in psks:
2097             raise Exception("No PSK recorded for sta2")
2098         if psks[addr0] == psks[addr1]:
2099             raise Exception("Same PSK recorded for sta0 and sta1")
2100         if psks[addr0] == psks[addr2]:
2101             raise Exception("Same PSK recorded for sta0 and sta2")
2102         if psks[addr1] == psks[addr2]:
2103             raise Exception("Same PSK recorded for sta1 and sta2")
2104
2105         dev[0].request("REMOVE_NETWORK all")
2106         logger.info("Second external registrar")
2107         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2108         dev[0].wps_reg(apdev[0]['bssid'], appin)
2109         psks2 = get_psk(pskfile)
2110         if addr0 not in psks2:
2111             raise Exception("No PSK recorded for sta0(reg)")
2112         if psks[addr0] == psks2[addr0]:
2113             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
2114     finally:
2115         os.remove(pskfile)
2116
2117 def test_ap_wps_per_station_psk_failure(dev, apdev):
2118     """WPS PBC provisioning with per-station PSK (file not writable)"""
2119     addr0 = dev[0].p2p_dev_addr()
2120     addr1 = dev[1].p2p_dev_addr()
2121     addr2 = dev[2].p2p_dev_addr()
2122     ssid = "wps"
2123     appin = "12345670"
2124     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2125     try:
2126         os.remove(pskfile)
2127     except:
2128         pass
2129
2130     try:
2131         with open(pskfile, "w") as f:
2132             f.write("# WPA PSKs\n")
2133
2134         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2135                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2136                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2137                    "wpa_psk_file": pskfile }
2138         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2139         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2140             raise Exception("Failed to set wpa_psk_file")
2141
2142         logger.info("First enrollee")
2143         hapd.request("WPS_PBC")
2144         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2145         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2146         dev[0].wait_connected(timeout=30)
2147
2148         logger.info("Second enrollee")
2149         hapd.request("WPS_PBC")
2150         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2151         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2152         dev[1].wait_connected(timeout=30)
2153
2154         logger.info("External registrar")
2155         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2156         dev[2].wps_reg(apdev[0]['bssid'], appin)
2157
2158         logger.info("Verifying PSK results")
2159         psks = get_psk(pskfile)
2160         if len(psks) > 0:
2161             raise Exception("PSK recorded unexpectedly")
2162     finally:
2163         os.remove(pskfile)
2164
2165 def test_ap_wps_pin_request_file(dev, apdev):
2166     """WPS PIN provisioning with configured AP"""
2167     ssid = "wps"
2168     pinfile = "/tmp/ap_wps_pin_request_file.log"
2169     if os.path.exists(pinfile):
2170         os.remove(pinfile)
2171     hostapd.add_ap(apdev[0]['ifname'],
2172                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2173                      "wps_pin_requests": pinfile,
2174                      "wpa_passphrase": "12345678", "wpa": "2",
2175                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2176     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2177     uuid = dev[0].get_status_field("uuid")
2178     pin = dev[0].wps_read_pin()
2179     try:
2180         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2181         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2182         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2183         if ev is None:
2184             raise Exception("PIN needed event not shown")
2185         if uuid not in ev:
2186             raise Exception("UUID mismatch")
2187         dev[0].request("WPS_CANCEL")
2188         success = False
2189         with open(pinfile, "r") as f:
2190             lines = f.readlines()
2191             for l in lines:
2192                 if uuid in l:
2193                     success = True
2194                     break
2195         if not success:
2196             raise Exception("PIN request entry not in the log file")
2197     finally:
2198         try:
2199             os.remove(pinfile)
2200         except:
2201             pass
2202
2203 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2204     """WPS auto-setup with configuration file"""
2205     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2206     ifname = apdev[0]['ifname']
2207     try:
2208         with open(conffile, "w") as f:
2209             f.write("driver=nl80211\n")
2210             f.write("hw_mode=g\n")
2211             f.write("channel=1\n")
2212             f.write("ieee80211n=1\n")
2213             f.write("interface=%s\n" % ifname)
2214             f.write("ctrl_interface=/var/run/hostapd\n")
2215             f.write("ssid=wps\n")
2216             f.write("eap_server=1\n")
2217             f.write("wps_state=1\n")
2218         hostapd.add_bss('phy3', ifname, conffile)
2219         hapd = hostapd.Hostapd(ifname)
2220         hapd.request("WPS_PBC")
2221         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2222         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2223         dev[0].wait_connected(timeout=30)
2224         with open(conffile, "r") as f:
2225             lines = f.read().splitlines()
2226             vals = dict()
2227             for l in lines:
2228                 try:
2229                     [name,value] = l.split('=', 1)
2230                     vals[name] = value
2231                 except ValueError, e:
2232                     if "# WPS configuration" in l:
2233                         pass
2234                     else:
2235                         raise Exception("Unexpected configuration line: " + l)
2236         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2237             raise Exception("Incorrect configuration: " + str(vals))
2238     finally:
2239         try:
2240             os.remove(conffile)
2241         except:
2242             pass
2243
2244 def test_ap_wps_pbc_timeout(dev, apdev, params):
2245     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2246     if not params['long']:
2247         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2248     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2249     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2250
2251     location = ssdp_get_location(ap_uuid)
2252     urls = upnp_get_urls(location)
2253     eventurl = urlparse.urlparse(urls['event_sub_url'])
2254     ctrlurl = urlparse.urlparse(urls['control_url'])
2255
2256     url = urlparse.urlparse(location)
2257     conn = httplib.HTTPConnection(url.netloc)
2258
2259     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2260         def handle(self):
2261             data = self.rfile.readline().strip()
2262             logger.debug(data)
2263             self.wfile.write(gen_wps_event())
2264
2265     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2266     server.timeout = 1
2267
2268     headers = { "callback": '<http://127.0.0.1:12345/event>',
2269                 "NT": "upnp:event",
2270                 "timeout": "Second-1234" }
2271     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2272     resp = conn.getresponse()
2273     if resp.status != 200:
2274         raise Exception("Unexpected HTTP response: %d" % resp.status)
2275     sid = resp.getheader("sid")
2276     logger.debug("Subscription SID " + sid)
2277
2278     msg = '''<?xml version="1.0"?>
2279 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2280 <s:Body>
2281 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2282 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2283 VFi5hrLk
2284 </NewMessage>
2285 </u:SetSelectedRegistrar>
2286 </s:Body>
2287 </s:Envelope>'''
2288     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2289     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2290     conn.request("POST", ctrlurl.path, msg, headers)
2291     resp = conn.getresponse()
2292     if resp.status != 200:
2293         raise Exception("Unexpected HTTP response: %d" % resp.status)
2294
2295     server.handle_request()
2296
2297     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2298     if "OK" not in dev[0].request("WPS_PBC"):
2299         raise Exception("WPS_PBC failed")
2300
2301     start = os.times()[4]
2302
2303     server.handle_request()
2304     dev[1].request("BSS_FLUSH 0")
2305     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2306                         only_new=True)
2307     bss = dev[1].get_bss(apdev[0]['bssid'])
2308     logger.debug("BSS: " + str(bss))
2309     if '[WPS-AUTH]' not in bss['flags']:
2310         raise Exception("WPS not indicated authorized")
2311
2312     server.handle_request()
2313
2314     wps_timeout_seen = False
2315
2316     while True:
2317         hapd.dump_monitor()
2318         dev[1].dump_monitor()
2319         if not wps_timeout_seen:
2320             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2321             if ev is not None:
2322                 logger.info("PBC timeout seen")
2323                 wps_timeout_seen = True
2324         else:
2325             dev[0].dump_monitor()
2326         now = os.times()[4]
2327         if now - start > 130:
2328             raise Exception("Selected registration information not removed")
2329         dev[1].request("BSS_FLUSH 0")
2330         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2331                             only_new=True)
2332         bss = dev[1].get_bss(apdev[0]['bssid'])
2333         logger.debug("BSS: " + str(bss))
2334         if '[WPS-AUTH]' not in bss['flags']:
2335             break
2336         server.handle_request()
2337
2338     server.server_close()
2339
2340     if wps_timeout_seen:
2341         return
2342
2343     now = os.times()[4]
2344     if now < start + 150:
2345         dur = start + 150 - now
2346     else:
2347         dur = 1
2348     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2349     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2350     if ev is None:
2351         raise Exception("WPS-TIMEOUT not reported")
2352
2353 def add_ssdp_ap(ifname, ap_uuid):
2354     ssid = "wps-ssdp"
2355     ap_pin = "12345670"
2356     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2357                "wpa_passphrase": "12345678", "wpa": "2",
2358                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2359                "device_name": "Wireless AP", "manufacturer": "Company",
2360                "model_name": "WAP", "model_number": "123",
2361                "serial_number": "12345", "device_type": "6-0050F204-1",
2362                "os_version": "01020300",
2363                "config_methods": "label push_button",
2364                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2365                "friendly_name": "WPS Access Point",
2366                "manufacturer_url": "http://www.example.com/",
2367                "model_description": "Wireless Access Point",
2368                "model_url": "http://www.example.com/model/",
2369                "upc": "123456789012" }
2370     return hostapd.add_ap(ifname, params)
2371
2372 def ssdp_send(msg, no_recv=False):
2373     socket.setdefaulttimeout(1)
2374     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2375     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2376     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2377     sock.bind(("127.0.0.1", 0))
2378     sock.sendto(msg, ("239.255.255.250", 1900))
2379     if no_recv:
2380         return None
2381     return sock.recv(1000)
2382
2383 def ssdp_send_msearch(st, no_recv=False):
2384     msg = '\r\n'.join([
2385             'M-SEARCH * HTTP/1.1',
2386             'HOST: 239.255.255.250:1900',
2387             'MX: 1',
2388             'MAN: "ssdp:discover"',
2389             'ST: ' + st,
2390             '', ''])
2391     return ssdp_send(msg, no_recv=no_recv)
2392
2393 def test_ap_wps_ssdp_msearch(dev, apdev):
2394     """WPS AP and SSDP M-SEARCH messages"""
2395     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2396     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2397
2398     msg = '\r\n'.join([
2399             'M-SEARCH * HTTP/1.1',
2400             'Host: 239.255.255.250:1900',
2401             'Mx: 1',
2402             'Man: "ssdp:discover"',
2403             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2404             '', ''])
2405     ssdp_send(msg)
2406
2407     msg = '\r\n'.join([
2408             'M-SEARCH * HTTP/1.1',
2409             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2410             'mx: \t1\t\t   ',
2411             'man: \t \t "ssdp:discover"   ',
2412             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2413             '', ''])
2414     ssdp_send(msg)
2415
2416     ssdp_send_msearch("ssdp:all")
2417     ssdp_send_msearch("upnp:rootdevice")
2418     ssdp_send_msearch("uuid:" + ap_uuid)
2419     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2420     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2421
2422     msg = '\r\n'.join([
2423             'M-SEARCH * HTTP/1.1',
2424             'HOST:\t239.255.255.250:1900',
2425             'MAN: "ssdp:discover"',
2426             'MX: 130',
2427             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2428             '', ''])
2429     ssdp_send(msg, no_recv=True)
2430
2431 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2432     """WPS AP and invalid SSDP M-SEARCH messages"""
2433     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2434     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2435
2436     socket.setdefaulttimeout(1)
2437     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2438     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2439     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2440     sock.bind(("127.0.0.1", 0))
2441
2442     logger.debug("Missing MX")
2443     msg = '\r\n'.join([
2444             'M-SEARCH * HTTP/1.1',
2445             'HOST: 239.255.255.250:1900',
2446             'MAN: "ssdp:discover"',
2447             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2448             '', ''])
2449     sock.sendto(msg, ("239.255.255.250", 1900))
2450
2451     logger.debug("Negative MX")
2452     msg = '\r\n'.join([
2453             'M-SEARCH * HTTP/1.1',
2454             'HOST: 239.255.255.250:1900',
2455             'MX: -1',
2456             'MAN: "ssdp:discover"',
2457             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2458             '', ''])
2459     sock.sendto(msg, ("239.255.255.250", 1900))
2460
2461     logger.debug("Invalid MX")
2462     msg = '\r\n'.join([
2463             'M-SEARCH * HTTP/1.1',
2464             'HOST: 239.255.255.250:1900',
2465             'MX; 1',
2466             'MAN: "ssdp:discover"',
2467             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2468             '', ''])
2469     sock.sendto(msg, ("239.255.255.250", 1900))
2470
2471     logger.debug("Missing MAN")
2472     msg = '\r\n'.join([
2473             'M-SEARCH * HTTP/1.1',
2474             'HOST: 239.255.255.250:1900',
2475             'MX: 1',
2476             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2477             '', ''])
2478     sock.sendto(msg, ("239.255.255.250", 1900))
2479
2480     logger.debug("Invalid MAN")
2481     msg = '\r\n'.join([
2482             'M-SEARCH * HTTP/1.1',
2483             'HOST: 239.255.255.250:1900',
2484             'MX: 1',
2485             'MAN: foo',
2486             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2487             '', ''])
2488     sock.sendto(msg, ("239.255.255.250", 1900))
2489     msg = '\r\n'.join([
2490             'M-SEARCH * HTTP/1.1',
2491             'HOST: 239.255.255.250:1900',
2492             'MX: 1',
2493             'MAN; "ssdp:discover"',
2494             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2495             '', ''])
2496     sock.sendto(msg, ("239.255.255.250", 1900))
2497
2498     logger.debug("Missing HOST")
2499     msg = '\r\n'.join([
2500             'M-SEARCH * HTTP/1.1',
2501             'MAN: "ssdp:discover"',
2502             'MX: 1',
2503             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2504             '', ''])
2505     sock.sendto(msg, ("239.255.255.250", 1900))
2506
2507     logger.debug("Missing ST")
2508     msg = '\r\n'.join([
2509             'M-SEARCH * HTTP/1.1',
2510             'HOST: 239.255.255.250:1900',
2511             'MAN: "ssdp:discover"',
2512             'MX: 1',
2513             '', ''])
2514     sock.sendto(msg, ("239.255.255.250", 1900))
2515
2516     logger.debug("Mismatching ST")
2517     msg = '\r\n'.join([
2518             'M-SEARCH * HTTP/1.1',
2519             'HOST: 239.255.255.250:1900',
2520             'MAN: "ssdp:discover"',
2521             'MX: 1',
2522             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2523             '', ''])
2524     sock.sendto(msg, ("239.255.255.250", 1900))
2525     msg = '\r\n'.join([
2526             'M-SEARCH * HTTP/1.1',
2527             'HOST: 239.255.255.250:1900',
2528             'MAN: "ssdp:discover"',
2529             'MX: 1',
2530             'ST: foo:bar',
2531             '', ''])
2532     sock.sendto(msg, ("239.255.255.250", 1900))
2533     msg = '\r\n'.join([
2534             'M-SEARCH * HTTP/1.1',
2535             'HOST: 239.255.255.250:1900',
2536             'MAN: "ssdp:discover"',
2537             'MX: 1',
2538             'ST: foobar',
2539             '', ''])
2540     sock.sendto(msg, ("239.255.255.250", 1900))
2541
2542     logger.debug("Invalid ST")
2543     msg = '\r\n'.join([
2544             'M-SEARCH * HTTP/1.1',
2545             'HOST: 239.255.255.250:1900',
2546             'MAN: "ssdp:discover"',
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 M-SEARCH")
2553     msg = '\r\n'.join([
2554             'M+SEARCH * HTTP/1.1',
2555             'HOST: 239.255.255.250:1900',
2556             'MAN: "ssdp:discover"',
2557             'MX: 1',
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             'MAN: "ssdp:discover"',
2565             'MX: 1',
2566             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2567             '', ''])
2568     sock.sendto(msg, ("239.255.255.250", 1900))
2569
2570     logger.debug("Invalid message format")
2571     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2572     msg = '\r'.join([
2573             'M-SEARCH * HTTP/1.1',
2574             'HOST: 239.255.255.250:1900',
2575             'MAN: "ssdp:discover"',
2576             'MX: 1',
2577             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2578             '', ''])
2579     sock.sendto(msg, ("239.255.255.250", 1900))
2580
2581     try:
2582         r = sock.recv(1000)
2583         raise Exception("Unexpected M-SEARCH response: " + r)
2584     except socket.timeout:
2585         pass
2586
2587     logger.debug("Valid M-SEARCH")
2588     msg = '\r\n'.join([
2589             'M-SEARCH * HTTP/1.1',
2590             'HOST: 239.255.255.250:1900',
2591             'MAN: "ssdp:discover"',
2592             'MX: 1',
2593             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2594             '', ''])
2595     sock.sendto(msg, ("239.255.255.250", 1900))
2596
2597     try:
2598         r = sock.recv(1000)
2599         pass
2600     except socket.timeout:
2601         raise Exception("No SSDP response")
2602
2603 def test_ap_wps_ssdp_burst(dev, apdev):
2604     """WPS AP and SSDP burst"""
2605     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2606     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2607
2608     msg = '\r\n'.join([
2609             'M-SEARCH * HTTP/1.1',
2610             'HOST: 239.255.255.250:1900',
2611             'MAN: "ssdp:discover"',
2612             'MX: 1',
2613             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2614             '', ''])
2615     socket.setdefaulttimeout(1)
2616     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2617     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2618     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2619     sock.bind(("127.0.0.1", 0))
2620     for i in range(0, 25):
2621         sock.sendto(msg, ("239.255.255.250", 1900))
2622     resp = 0
2623     while True:
2624         try:
2625             r = sock.recv(1000)
2626             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2627                 raise Exception("Unexpected message: " + r)
2628             resp += 1
2629         except socket.timeout:
2630             break
2631     if resp < 20:
2632         raise Exception("Too few SSDP responses")
2633
2634     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2635     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2636     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2637     sock.bind(("127.0.0.1", 0))
2638     for i in range(0, 25):
2639         sock.sendto(msg, ("239.255.255.250", 1900))
2640     while True:
2641         try:
2642             r = sock.recv(1000)
2643             if ap_uuid in r:
2644                 break
2645         except socket.timeout:
2646             raise Exception("No SSDP response")
2647
2648 def ssdp_get_location(uuid):
2649     res = ssdp_send_msearch("uuid:" + uuid)
2650     location = None
2651     for l in res.splitlines():
2652         if l.lower().startswith("location:"):
2653             location = l.split(':', 1)[1].strip()
2654             break
2655     if location is None:
2656         raise Exception("No UPnP location found")
2657     return location
2658
2659 def upnp_get_urls(location):
2660     conn = urllib.urlopen(location)
2661     tree = ET.parse(conn)
2662     root = tree.getroot()
2663     urn = '{urn:schemas-upnp-org:device-1-0}'
2664     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2665     res = {}
2666     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2667     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2668     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2669     return res
2670
2671 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2672     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2673     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2674     ET.register_namespace('soapenv', soapns)
2675     ET.register_namespace('wfa', wpsns)
2676     attrib = {}
2677     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2678     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2679     body = ET.SubElement(root, "{%s}Body" % soapns)
2680     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2681     tree = ET.ElementTree(root)
2682     soap = StringIO.StringIO()
2683     tree.write(soap, xml_declaration=True, encoding='utf-8')
2684
2685     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2686     if include_soap_action:
2687         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2688     elif soap_action_override:
2689         headers["SOAPAction"] = soap_action_override
2690     conn.request("POST", path, soap.getvalue(), headers)
2691     return conn.getresponse()
2692
2693 def test_ap_wps_upnp(dev, apdev):
2694     """WPS AP and UPnP operations"""
2695     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2696     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2697
2698     location = ssdp_get_location(ap_uuid)
2699     urls = upnp_get_urls(location)
2700
2701     conn = urllib.urlopen(urls['scpd_url'])
2702     scpd = conn.read()
2703
2704     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2705     if conn.getcode() != 404:
2706         raise Exception("Unexpected HTTP response to GET unknown URL")
2707
2708     url = urlparse.urlparse(location)
2709     conn = httplib.HTTPConnection(url.netloc)
2710     #conn.set_debuglevel(1)
2711     headers = { "Content-type": 'text/xml; charset="utf-8"',
2712                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2713     conn.request("POST", "hello", "\r\n\r\n", headers)
2714     resp = conn.getresponse()
2715     if resp.status != 404:
2716         raise Exception("Unexpected HTTP response: %d" % resp.status)
2717
2718     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2719     resp = conn.getresponse()
2720     if resp.status != 501:
2721         raise Exception("Unexpected HTTP response: %d" % resp.status)
2722
2723     headers = { "Content-type": 'text/xml; charset="utf-8"',
2724                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2725     ctrlurl = urlparse.urlparse(urls['control_url'])
2726     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2727     resp = conn.getresponse()
2728     if resp.status != 401:
2729         raise Exception("Unexpected HTTP response: %d" % resp.status)
2730
2731     logger.debug("GetDeviceInfo without SOAPAction header")
2732     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2733                             include_soap_action=False)
2734     if resp.status != 401:
2735         raise Exception("Unexpected HTTP response: %d" % resp.status)
2736
2737     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2738     for act in [ "foo",
2739                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2740                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2741                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2742         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2743                                 include_soap_action=False,
2744                                 soap_action_override=act)
2745         if resp.status != 401:
2746             raise Exception("Unexpected HTTP response: %d" % resp.status)
2747
2748     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2749     if resp.status != 200:
2750         raise Exception("Unexpected HTTP response: %d" % resp.status)
2751     dev = resp.read()
2752     if "NewDeviceInfo" not in dev:
2753         raise Exception("Unexpected GetDeviceInfo response")
2754
2755     logger.debug("PutMessage without required parameters")
2756     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2757     if resp.status != 600:
2758         raise Exception("Unexpected HTTP response: %d" % resp.status)
2759
2760     logger.debug("PutWLANResponse without required parameters")
2761     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2762     if resp.status != 600:
2763         raise Exception("Unexpected HTTP response: %d" % resp.status)
2764
2765     logger.debug("SetSelectedRegistrar from unregistered ER")
2766     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2767     if resp.status != 501:
2768         raise Exception("Unexpected HTTP response: %d" % resp.status)
2769
2770     logger.debug("Unknown action")
2771     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2772     if resp.status != 401:
2773         raise Exception("Unexpected HTTP response: %d" % resp.status)
2774
2775 def test_ap_wps_upnp_subscribe(dev, apdev):
2776     """WPS AP and UPnP event subscription"""
2777     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2778     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2779
2780     location = ssdp_get_location(ap_uuid)
2781     urls = upnp_get_urls(location)
2782     eventurl = urlparse.urlparse(urls['event_sub_url'])
2783
2784     url = urlparse.urlparse(location)
2785     conn = httplib.HTTPConnection(url.netloc)
2786     #conn.set_debuglevel(1)
2787     headers = { "callback": '<http://127.0.0.1:12345/event>',
2788                 "timeout": "Second-1234" }
2789     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2790     resp = conn.getresponse()
2791     if resp.status != 412:
2792         raise Exception("Unexpected HTTP response: %d" % resp.status)
2793
2794     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2795     resp = conn.getresponse()
2796     if resp.status != 412:
2797         raise Exception("Unexpected HTTP response: %d" % resp.status)
2798
2799     headers = { "NT": "upnp:event",
2800                 "timeout": "Second-1234" }
2801     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2802     resp = conn.getresponse()
2803     if resp.status != 412:
2804         raise Exception("Unexpected HTTP response: %d" % resp.status)
2805
2806     headers = { "callback": '<http://127.0.0.1:12345/event>',
2807                 "NT": "upnp:foobar",
2808                 "timeout": "Second-1234" }
2809     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2810     resp = conn.getresponse()
2811     if resp.status != 400:
2812         raise Exception("Unexpected HTTP response: %d" % resp.status)
2813
2814     logger.debug("Valid subscription")
2815     headers = { "callback": '<http://127.0.0.1:12345/event>',
2816                 "NT": "upnp:event",
2817                 "timeout": "Second-1234" }
2818     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2819     resp = conn.getresponse()
2820     if resp.status != 200:
2821         raise Exception("Unexpected HTTP response: %d" % resp.status)
2822     sid = resp.getheader("sid")
2823     logger.debug("Subscription SID " + sid)
2824
2825     logger.debug("Invalid re-subscription")
2826     headers = { "NT": "upnp:event",
2827                 "sid": "123456734567854",
2828                 "timeout": "Second-1234" }
2829     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2830     resp = conn.getresponse()
2831     if resp.status != 400:
2832         raise Exception("Unexpected HTTP response: %d" % resp.status)
2833
2834     logger.debug("Invalid re-subscription")
2835     headers = { "NT": "upnp:event",
2836                 "sid": "uuid:123456734567854",
2837                 "timeout": "Second-1234" }
2838     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2839     resp = conn.getresponse()
2840     if resp.status != 400:
2841         raise Exception("Unexpected HTTP response: %d" % resp.status)
2842
2843     logger.debug("Invalid re-subscription")
2844     headers = { "callback": '<http://127.0.0.1:12345/event>',
2845                 "NT": "upnp:event",
2846                 "sid": sid,
2847                 "timeout": "Second-1234" }
2848     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2849     resp = conn.getresponse()
2850     if resp.status != 400:
2851         raise Exception("Unexpected HTTP response: %d" % resp.status)
2852
2853     logger.debug("SID mismatch in re-subscription")
2854     headers = { "NT": "upnp:event",
2855                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2856                 "timeout": "Second-1234" }
2857     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2858     resp = conn.getresponse()
2859     if resp.status != 412:
2860         raise Exception("Unexpected HTTP response: %d" % resp.status)
2861
2862     logger.debug("Valid re-subscription")
2863     headers = { "NT": "upnp:event",
2864                 "sid": sid,
2865                 "timeout": "Second-1234" }
2866     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2867     resp = conn.getresponse()
2868     if resp.status != 200:
2869         raise Exception("Unexpected HTTP response: %d" % resp.status)
2870     sid2 = resp.getheader("sid")
2871     logger.debug("Subscription SID " + sid2)
2872
2873     if sid != sid2:
2874         raise Exception("Unexpected SID change")
2875
2876     logger.debug("Valid re-subscription")
2877     headers = { "NT": "upnp:event",
2878                 "sid": "uuid: \t \t" + sid.split(':')[1],
2879                 "timeout": "Second-1234" }
2880     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2881     resp = conn.getresponse()
2882     if resp.status != 200:
2883         raise Exception("Unexpected HTTP response: %d" % resp.status)
2884
2885     logger.debug("Invalid unsubscription")
2886     headers = { "sid": sid }
2887     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2888     resp = conn.getresponse()
2889     if resp.status != 412:
2890         raise Exception("Unexpected HTTP response: %d" % resp.status)
2891     headers = { "foo": "bar" }
2892     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2893     resp = conn.getresponse()
2894     if resp.status != 412:
2895         raise Exception("Unexpected HTTP response: %d" % resp.status)
2896
2897     logger.debug("Valid unsubscription")
2898     headers = { "sid": sid }
2899     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2900     resp = conn.getresponse()
2901     if resp.status != 200:
2902         raise Exception("Unexpected HTTP response: %d" % resp.status)
2903
2904     logger.debug("Unsubscription for not existing SID")
2905     headers = { "sid": sid }
2906     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2907     resp = conn.getresponse()
2908     if resp.status != 412:
2909         raise Exception("Unexpected HTTP response: %d" % resp.status)
2910
2911     logger.debug("Invalid unsubscription")
2912     headers = { "sid": " \t \tfoo" }
2913     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2914     resp = conn.getresponse()
2915     if resp.status != 400:
2916         raise Exception("Unexpected HTTP response: %d" % resp.status)
2917
2918     logger.debug("Invalid unsubscription")
2919     headers = { "sid": "uuid:\t \tfoo" }
2920     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2921     resp = conn.getresponse()
2922     if resp.status != 400:
2923         raise Exception("Unexpected HTTP response: %d" % resp.status)
2924
2925     logger.debug("Invalid unsubscription")
2926     headers = { "NT": "upnp:event",
2927                 "sid": sid }
2928     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2929     resp = conn.getresponse()
2930     if resp.status != 400:
2931         raise Exception("Unexpected HTTP response: %d" % resp.status)
2932     headers = { "callback": '<http://127.0.0.1:12345/event>',
2933                 "sid": sid }
2934     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2935     resp = conn.getresponse()
2936     if resp.status != 400:
2937         raise Exception("Unexpected HTTP response: %d" % resp.status)
2938
2939     logger.debug("Valid subscription with multiple callbacks")
2940     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>',
2941                 "NT": "upnp:event",
2942                 "timeout": "Second-1234" }
2943     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2944     resp = conn.getresponse()
2945     if resp.status != 200:
2946         raise Exception("Unexpected HTTP response: %d" % resp.status)
2947     sid = resp.getheader("sid")
2948     logger.debug("Subscription SID " + sid)
2949
2950     # Force subscription to be deleted due to errors
2951     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2952     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2953     with alloc_fail(hapd, 1, "event_build_message"):
2954         for i in range(10):
2955             dev[1].dump_monitor()
2956             dev[2].dump_monitor()
2957             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2958             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2959             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2960             dev[1].request("WPS_CANCEL")
2961             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2962             dev[2].request("WPS_CANCEL")
2963             if i % 4 == 1:
2964                 time.sleep(1)
2965             else:
2966                 time.sleep(0.1)
2967     time.sleep(0.2)
2968
2969     headers = { "sid": sid }
2970     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2971     resp = conn.getresponse()
2972     if resp.status != 200 and resp.status != 412:
2973         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2974
2975     headers = { "callback": '<http://127.0.0.1:12345/event>',
2976                 "NT": "upnp:event",
2977                 "timeout": "Second-1234" }
2978     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2979         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2980         resp = conn.getresponse()
2981         if resp.status != 200:
2982             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2983         sid = resp.getheader("sid")
2984         logger.debug("Subscription SID " + sid)
2985
2986     headers = { "sid": sid }
2987     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2988     resp = conn.getresponse()
2989     if resp.status != 200:
2990         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2991
2992     headers = { "callback": '<http://127.0.0.1:12345/event>',
2993                 "NT": "upnp:event",
2994                 "timeout": "Second-1234" }
2995     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2996     resp = conn.getresponse()
2997     if resp.status != 200:
2998         raise Exception("Unexpected HTTP response: %d" % resp.status)
2999     sid = resp.getheader("sid")
3000     logger.debug("Subscription SID " + sid)
3001
3002     with alloc_fail(hapd, 1, "=event_add"):
3003         for i in range(2):
3004             dev[1].dump_monitor()
3005             dev[2].dump_monitor()
3006             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3007             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3008             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3009             dev[1].request("WPS_CANCEL")
3010             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3011             dev[2].request("WPS_CANCEL")
3012             if i == 0:
3013                 time.sleep(1)
3014             else:
3015                 time.sleep(0.1)
3016
3017     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3018     resp = conn.getresponse()
3019     if resp.status != 200:
3020         raise Exception("Unexpected HTTP response: %d" % resp.status)
3021
3022     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
3023         dev[1].dump_monitor()
3024         dev[2].dump_monitor()
3025         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3026         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3027         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3028         dev[1].request("WPS_CANCEL")
3029         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3030         dev[2].request("WPS_CANCEL")
3031         time.sleep(0.1)
3032
3033     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
3034         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3035         resp = conn.getresponse()
3036         if resp.status != 500:
3037             raise Exception("Unexpected HTTP response: %d" % resp.status)
3038
3039     with alloc_fail(hapd, 1, "=subscription_start"):
3040         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3041         resp = conn.getresponse()
3042         if resp.status != 500:
3043             raise Exception("Unexpected HTTP response: %d" % resp.status)
3044
3045     headers = { "callback": '',
3046                 "NT": "upnp:event",
3047                 "timeout": "Second-1234" }
3048     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3049     resp = conn.getresponse()
3050     if resp.status != 500:
3051         raise Exception("Unexpected HTTP response: %d" % resp.status)
3052
3053     headers = { "callback": ' <',
3054                 "NT": "upnp:event",
3055                 "timeout": "Second-1234" }
3056     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3057     resp = conn.getresponse()
3058     if resp.status != 500:
3059         raise Exception("Unexpected HTTP response: %d" % resp.status)
3060
3061     headers = { "callback": '<http://127.0.0.1:12345/event>',
3062                 "NT": "upnp:event",
3063                 "timeout": "Second-1234" }
3064     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
3065         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3066         resp = conn.getresponse()
3067         if resp.status != 500:
3068             raise Exception("Unexpected HTTP response: %d" % resp.status)
3069
3070     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
3071         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3072         resp = conn.getresponse()
3073         if resp.status != 500:
3074             raise Exception("Unexpected HTTP response: %d" % resp.status)
3075
3076     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
3077         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3078         resp = conn.getresponse()
3079         if resp.status != 500:
3080             raise Exception("Unexpected HTTP response: %d" % resp.status)
3081
3082     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
3083         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3084         resp = conn.getresponse()
3085         if resp.status != 500:
3086             raise Exception("Unexpected HTTP response: %d" % resp.status)
3087
3088     for i in range(6):
3089         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
3090                     "NT": "upnp:event",
3091                     "timeout": "Second-1234" }
3092         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3093         resp = conn.getresponse()
3094         if resp.status != 200:
3095             raise Exception("Unexpected HTTP response: %d" % resp.status)
3096
3097     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
3098         dev[1].dump_monitor()
3099         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3100         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3101         dev[1].request("WPS_CANCEL")
3102         time.sleep(0.1)
3103
3104     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
3105         dev[1].dump_monitor()
3106         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3107         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3108         dev[1].request("WPS_CANCEL")
3109         time.sleep(0.1)
3110
3111     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
3112         dev[1].dump_monitor()
3113         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3114         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3115         dev[1].request("WPS_CANCEL")
3116         time.sleep(0.1)
3117
3118     hapd.disable()
3119     with alloc_fail(hapd, 1, "get_netif_info"):
3120         if "FAIL" not in hapd.request("ENABLE"):
3121             raise Exception("ENABLE succeeded during OOM")
3122
3123 def test_ap_wps_upnp_subscribe_events(dev, apdev):
3124     """WPS AP and UPnP event subscription and many events"""
3125     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3126     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3127
3128     location = ssdp_get_location(ap_uuid)
3129     urls = upnp_get_urls(location)
3130     eventurl = urlparse.urlparse(urls['event_sub_url'])
3131
3132     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
3133         def handle(self):
3134             data = self.rfile.readline().strip()
3135             logger.debug(data)
3136             self.wfile.write(gen_wps_event())
3137
3138     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
3139     server.timeout = 1
3140
3141     url = urlparse.urlparse(location)
3142     conn = httplib.HTTPConnection(url.netloc)
3143
3144     headers = { "callback": '<http://127.0.0.1:12345/event>',
3145                 "NT": "upnp:event",
3146                 "timeout": "Second-1234" }
3147     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3148     resp = conn.getresponse()
3149     if resp.status != 200:
3150         raise Exception("Unexpected HTTP response: %d" % resp.status)
3151     sid = resp.getheader("sid")
3152     logger.debug("Subscription SID " + sid)
3153
3154     # Fetch the first event message
3155     server.handle_request()
3156
3157     # Force subscription event queue to reach the maximum length by generating
3158     # new proxied events without the ER fetching any of the pending events.
3159     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3160     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3161     for i in range(16):
3162         dev[1].dump_monitor()
3163         dev[2].dump_monitor()
3164         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3165         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3166         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3167         dev[1].request("WPS_CANCEL")
3168         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3169         dev[2].request("WPS_CANCEL")
3170         if i % 4 == 1:
3171             time.sleep(1)
3172         else:
3173             time.sleep(0.1)
3174
3175     hapd.request("WPS_PIN any 12345670")
3176     dev[1].dump_monitor()
3177     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3178     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3179     if ev is None:
3180         raise Exception("WPS success not reported")
3181
3182     # Close the WPS ER HTTP server without fetching all the pending events.
3183     # This tests hostapd code path that clears subscription and the remaining
3184     # event queue when the interface is deinitialized.
3185     server.handle_request()
3186     server.server_close()
3187
3188     dev[1].wait_connected()
3189
3190 def test_ap_wps_upnp_http_proto(dev, apdev):
3191     """WPS AP and UPnP/HTTP protocol testing"""
3192     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3193     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3194
3195     location = ssdp_get_location(ap_uuid)
3196
3197     url = urlparse.urlparse(location)
3198     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3199     #conn.set_debuglevel(1)
3200
3201     conn.request("HEAD", "hello")
3202     resp = conn.getresponse()
3203     if resp.status != 501:
3204         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3205     conn.close()
3206
3207     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3208         try:
3209             conn.request(cmd, "hello")
3210             resp = conn.getresponse()
3211         except Exception, e:
3212             pass
3213         conn.close()
3214
3215     headers = { "Content-Length": 'abc' }
3216     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3217     try:
3218         resp = conn.getresponse()
3219     except Exception, e:
3220         pass
3221     conn.close()
3222
3223     headers = { "Content-Length": '-10' }
3224     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3225     try:
3226         resp = conn.getresponse()
3227     except Exception, e:
3228         pass
3229     conn.close()
3230
3231     headers = { "Content-Length": '10000000000000' }
3232     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3233     try:
3234         resp = conn.getresponse()
3235     except Exception, e:
3236         pass
3237     conn.close()
3238
3239     headers = { "Transfer-Encoding": 'abc' }
3240     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3241     resp = conn.getresponse()
3242     if resp.status != 501:
3243         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3244     conn.close()
3245
3246     headers = { "Transfer-Encoding": 'chunked' }
3247     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3248     resp = conn.getresponse()
3249     if resp.status != 501:
3250         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3251     conn.close()
3252
3253     # Too long a header
3254     conn.request("HEAD", 5000 * 'A')
3255     try:
3256         resp = conn.getresponse()
3257     except Exception, e:
3258         pass
3259     conn.close()
3260
3261     # Long URL but within header length limits
3262     conn.request("HEAD", 3000 * 'A')
3263     resp = conn.getresponse()
3264     if resp.status != 501:
3265         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3266     conn.close()
3267
3268     headers = { "Content-Length": '20' }
3269     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3270     try:
3271         resp = conn.getresponse()
3272     except Exception, e:
3273         pass
3274     conn.close()
3275
3276     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3277     resp = conn.getresponse()
3278     if resp.status != 404:
3279         raise Exception("Unexpected HTTP response: %d" % resp.status)
3280     conn.close()
3281
3282     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3283     try:
3284         resp = conn.getresponse()
3285     except Exception, e:
3286         pass
3287     conn.close()
3288
3289 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3290     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3291     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3292     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3293
3294     location = ssdp_get_location(ap_uuid)
3295
3296     url = urlparse.urlparse(location)
3297     conn = httplib.HTTPConnection(url.netloc)
3298     #conn.set_debuglevel(1)
3299
3300     headers = { "Transfer-Encoding": 'chunked' }
3301     conn.request("POST", "hello",
3302                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3303                  headers)
3304     resp = conn.getresponse()
3305     if resp.status != 404:
3306         raise Exception("Unexpected HTTP response: %d" % resp.status)
3307     conn.close()
3308
3309     conn.putrequest("POST", "hello")
3310     conn.putheader('Transfer-Encoding', 'chunked')
3311     conn.endheaders()
3312     conn.send("a\r\nabcdefghij\r\n")
3313     time.sleep(0.1)
3314     conn.send("2\r\nkl\r\n")
3315     conn.send("0\r\n\r\n")
3316     resp = conn.getresponse()
3317     if resp.status != 404:
3318         raise Exception("Unexpected HTTP response: %d" % resp.status)
3319     conn.close()
3320
3321     conn.putrequest("POST", "hello")
3322     conn.putheader('Transfer-Encoding', 'chunked')
3323     conn.endheaders()
3324     completed = False
3325     try:
3326         for i in range(20000):
3327             conn.send("1\r\nZ\r\n")
3328         conn.send("0\r\n\r\n")
3329         resp = conn.getresponse()
3330         completed = True
3331     except Exception, e:
3332         pass
3333     conn.close()
3334     if completed:
3335         raise Exception("Too long chunked request did not result in connection reset")
3336
3337     headers = { "Transfer-Encoding": 'chunked' }
3338     conn.request("POST", "hello", "80000000\r\na", headers)
3339     try:
3340         resp = conn.getresponse()
3341     except Exception, e:
3342         pass
3343     conn.close()
3344
3345     conn.request("POST", "hello", "10000000\r\na", headers)
3346     try:
3347         resp = conn.getresponse()
3348     except Exception, e:
3349         pass
3350     conn.close()
3351
3352 def test_ap_wps_disabled(dev, apdev):
3353     """WPS operations while WPS is disabled"""
3354     ssid = "test-wps-disabled"
3355     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
3356     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3357     if "FAIL" not in hapd.request("WPS_PBC"):
3358         raise Exception("WPS_PBC succeeded unexpectedly")
3359     if "FAIL" not in hapd.request("WPS_CANCEL"):
3360         raise Exception("WPS_CANCEL succeeded unexpectedly")
3361
3362 def test_ap_wps_mixed_cred(dev, apdev):
3363     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3364     ssid = "test-wps-wep"
3365     hostapd.add_ap(apdev[0]['ifname'],
3366                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3367                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
3368     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3369     hapd.request("WPS_PBC")
3370     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3371     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3372     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3373     if ev is None:
3374         raise Exception("WPS-SUCCESS event timed out")
3375     nets = dev[0].list_networks()
3376     if len(nets) != 1:
3377         raise Exception("Unexpected number of network blocks")
3378     id = nets[0]['id']
3379     proto = dev[0].get_network(id, "proto")
3380     if proto != "WPA RSN":
3381         raise Exception("Unexpected merged proto field value: " + proto)
3382     pairwise = dev[0].get_network(id, "pairwise")
3383     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3384         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3385
3386 def test_ap_wps_while_connected(dev, apdev):
3387     """WPS PBC provisioning while connected to another AP"""
3388     ssid = "test-wps-conf"
3389     hostapd.add_ap(apdev[0]['ifname'],
3390                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3391                      "wpa_passphrase": "12345678", "wpa": "2",
3392                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3393     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3394
3395     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3396     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3397
3398     logger.info("WPS provisioning step")
3399     hapd.request("WPS_PBC")
3400     dev[0].dump_monitor()
3401     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3402     dev[0].wait_connected(timeout=30)
3403     status = dev[0].get_status()
3404     if status['bssid'] != apdev[0]['bssid']:
3405         raise Exception("Unexpected BSSID")
3406
3407 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3408     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3409     ssid = "test-wps-conf"
3410     hostapd.add_ap(apdev[0]['ifname'],
3411                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3412                      "wpa_passphrase": "12345678", "wpa": "2",
3413                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3414     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3415
3416     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3417
3418     try:
3419         dev[0].request("STA_AUTOCONNECT 0")
3420         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3421
3422         logger.info("WPS provisioning step")
3423         hapd.request("WPS_PBC")
3424         dev[0].dump_monitor()
3425         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3426         dev[0].wait_connected(timeout=30)
3427         status = dev[0].get_status()
3428         if status['bssid'] != apdev[0]['bssid']:
3429             raise Exception("Unexpected BSSID")
3430     finally:
3431         dev[0].request("STA_AUTOCONNECT 1")
3432
3433 def test_ap_wps_from_event(dev, apdev):
3434     """WPS PBC event on AP to enable PBC"""
3435     ssid = "test-wps-conf"
3436     hapd = hostapd.add_ap(apdev[0]['ifname'],
3437                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3438                             "wpa_passphrase": "12345678", "wpa": "2",
3439                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3440     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3441     dev[0].dump_monitor()
3442     hapd.dump_monitor()
3443     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3444
3445     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3446     if ev is None:
3447         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3448     vals = ev.split(' ')
3449     if vals[1] != dev[0].p2p_interface_addr():
3450         raise Exception("Unexpected enrollee address: " + vals[1])
3451     if vals[5] != '4':
3452         raise Exception("Unexpected Device Password Id: " + vals[5])
3453     hapd.request("WPS_PBC")
3454     dev[0].wait_connected(timeout=30)
3455
3456 def test_ap_wps_ap_scan_2(dev, apdev):
3457     """AP_SCAN 2 for WPS"""
3458     ssid = "test-wps-conf"
3459     hapd = hostapd.add_ap(apdev[0]['ifname'],
3460                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3461                             "wpa_passphrase": "12345678", "wpa": "2",
3462                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3463     hapd.request("WPS_PBC")
3464
3465     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3466     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3467
3468     if "OK" not in wpas.request("AP_SCAN 2"):
3469         raise Exception("Failed to set AP_SCAN 2")
3470
3471     wpas.flush_scan_cache()
3472     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3473     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3474     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3475     if ev is None:
3476         raise Exception("WPS-SUCCESS event timed out")
3477     wpas.wait_connected(timeout=30)
3478     wpas.request("DISCONNECT")
3479     wpas.request("BSS_FLUSH 0")
3480     wpas.dump_monitor()
3481     wpas.request("REASSOCIATE")
3482     wpas.wait_connected(timeout=30)
3483
3484 def test_ap_wps_eapol_workaround(dev, apdev):
3485     """EAPOL workaround code path for 802.1X header length mismatch"""
3486     ssid = "test-wps"
3487     hostapd.add_ap(apdev[0]['ifname'],
3488                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3489     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3490     bssid = apdev[0]['bssid']
3491     hapd.request("SET ext_eapol_frame_io 1")
3492     dev[0].request("SET ext_eapol_frame_io 1")
3493     hapd.request("WPS_PBC")
3494     dev[0].request("WPS_PBC")
3495
3496     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3497     if ev is None:
3498         raise Exception("Timeout on EAPOL-TX from hostapd")
3499
3500     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3501     if "OK" not in res:
3502         raise Exception("EAPOL_RX to wpa_supplicant failed")
3503
3504 def test_ap_wps_iteration(dev, apdev):
3505     """WPS PIN and iterate through APs without selected registrar"""
3506     ssid = "test-wps-conf"
3507     hapd = hostapd.add_ap(apdev[0]['ifname'],
3508                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3509                             "wpa_passphrase": "12345678", "wpa": "2",
3510                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3511
3512     ssid2 = "test-wps-conf2"
3513     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3514                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3515                              "wpa_passphrase": "12345678", "wpa": "2",
3516                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3517
3518     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3519     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3520     dev[0].dump_monitor()
3521     pin = dev[0].request("WPS_PIN any")
3522
3523     # Wait for iteration through all WPS APs to happen before enabling any
3524     # Registrar.
3525     for i in range(2):
3526         ev = dev[0].wait_event(["Associated with"], timeout=30)
3527         if ev is None:
3528             raise Exception("No association seen")
3529         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3530         if ev is None:
3531             raise Exception("No M2D from AP")
3532         dev[0].wait_disconnected()
3533
3534     # Verify that each AP requested PIN
3535     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3536     if ev is None:
3537         raise Exception("No WPS-PIN-NEEDED event from AP")
3538     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3539     if ev is None:
3540         raise Exception("No WPS-PIN-NEEDED event from AP2")
3541
3542     # Provide PIN to one of the APs and verify that connection gets formed
3543     hapd.request("WPS_PIN any " + pin)
3544     dev[0].wait_connected(timeout=30)
3545
3546 def test_ap_wps_iteration_error(dev, apdev):
3547     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3548     ssid = "test-wps-conf-pin"
3549     hapd = hostapd.add_ap(apdev[0]['ifname'],
3550                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3551                             "wpa_passphrase": "12345678", "wpa": "2",
3552                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3553                             "wps_independent": "1" })
3554     hapd.request("SET ext_eapol_frame_io 1")
3555     bssid = apdev[0]['bssid']
3556     pin = dev[0].wps_read_pin()
3557     dev[0].request("WPS_PIN any " + pin)
3558
3559     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3560     if ev is None:
3561         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3562     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3563
3564     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3565     if ev is None:
3566         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3567     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3568     if ev is None:
3569         raise Exception("No CTRL-EVENT-EAP-STARTED")
3570
3571     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3572     # a case with an incorrectly behaving WPS AP.
3573
3574     # Start the real target AP and activate registrar on it.
3575     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3576                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3577                             "wpa_passphrase": "12345678", "wpa": "2",
3578                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3579                             "wps_independent": "1" })
3580     hapd2.request("WPS_PIN any " + pin)
3581
3582     dev[0].wait_disconnected(timeout=15)
3583     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3584     if ev is None:
3585         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3586     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3587     if ev is None:
3588         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3589     dev[0].wait_connected(timeout=15)
3590
3591 def test_ap_wps_priority(dev, apdev):
3592     """WPS PIN provisioning with configured AP and wps_priority"""
3593     ssid = "test-wps-conf-pin"
3594     hostapd.add_ap(apdev[0]['ifname'],
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     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3599     logger.info("WPS provisioning step")
3600     pin = dev[0].wps_read_pin()
3601     hapd.request("WPS_PIN any " + pin)
3602     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3603     dev[0].dump_monitor()
3604     try:
3605         dev[0].request("SET wps_priority 6")
3606         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3607         dev[0].wait_connected(timeout=30)
3608         netw = dev[0].list_networks()
3609         prio = dev[0].get_network(netw[0]['id'], 'priority')
3610         if prio != '6':
3611             raise Exception("Unexpected network priority: " + prio)
3612     finally:
3613         dev[0].request("SET wps_priority 0")
3614
3615 def test_ap_wps_and_non_wps(dev, apdev):
3616     """WPS and non-WPS AP in single hostapd process"""
3617     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3618     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3619
3620     params = { "ssid": "no wps" }
3621     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3622
3623     appin = hapd.request("WPS_AP_PIN random")
3624     if "FAIL" in appin:
3625         raise Exception("Could not generate random AP PIN")
3626     if appin not in hapd.request("WPS_AP_PIN get"):
3627         raise Exception("Could not fetch current AP PIN")
3628
3629     if "FAIL" in hapd.request("WPS_PBC"):
3630         raise Exception("WPS_PBC failed")
3631     if "FAIL" in hapd.request("WPS_CANCEL"):
3632         raise Exception("WPS_CANCEL failed")
3633
3634 def test_ap_wps_init_oom(dev, apdev):
3635     """Initial AP configuration and OOM during PSK generation"""
3636     ssid = "test-wps"
3637     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3638     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3639
3640     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3641         pin = dev[0].wps_read_pin()
3642         hapd.request("WPS_PIN any " + pin)
3643         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3644         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3645         dev[0].wait_disconnected()
3646
3647     hapd.request("WPS_PIN any " + pin)
3648     dev[0].wait_connected(timeout=30)
3649
3650 def test_ap_wps_er_oom(dev, apdev):
3651     """WPS ER OOM in XML processing"""
3652     try:
3653         _test_ap_wps_er_oom(dev, apdev)
3654     finally:
3655         dev[0].request("WPS_ER_STOP")
3656         dev[1].request("WPS_CANCEL")
3657         dev[0].request("DISCONNECT")
3658
3659 def _test_ap_wps_er_oom(dev, apdev):
3660     ssid = "wps-er-ap-config"
3661     ap_pin = "12345670"
3662     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3663     hostapd.add_ap(apdev[0]['ifname'],
3664                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3665                      "wpa_passphrase": "12345678", "wpa": "2",
3666                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3667                      "device_name": "Wireless AP", "manufacturer": "Company",
3668                      "model_name": "WAP", "model_number": "123",
3669                      "serial_number": "12345", "device_type": "6-0050F204-1",
3670                      "os_version": "01020300",
3671                      "config_methods": "label push_button",
3672                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3673
3674     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3675
3676     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3677         dev[0].request("WPS_ER_START ifname=lo")
3678         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3679         if ev is not None:
3680             raise Exception("Unexpected AP discovery")
3681
3682     dev[0].request("WPS_ER_STOP")
3683     dev[0].request("WPS_ER_START ifname=lo")
3684     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3685     if ev is None:
3686         raise Exception("AP discovery timed out")
3687
3688     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3689     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3690         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3691         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3692         if ev is None:
3693             raise Exception("PBC scan failed")
3694         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3695         if ev is None:
3696             raise Exception("Enrollee discovery timed out")
3697
3698 def test_ap_wps_er_init_oom(dev, apdev):
3699     """WPS ER and OOM during init"""
3700     try:
3701         _test_ap_wps_er_init_oom(dev, apdev)
3702     finally:
3703         dev[0].request("WPS_ER_STOP")
3704
3705 def _test_ap_wps_er_init_oom(dev, apdev):
3706     with alloc_fail(dev[0], 1, "wps_er_init"):
3707         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3708             raise Exception("WPS_ER_START succeeded during OOM")
3709     with alloc_fail(dev[0], 1, "http_server_init"):
3710         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3711             raise Exception("WPS_ER_START succeeded during OOM")
3712     with alloc_fail(dev[0], 2, "http_server_init"):
3713         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3714             raise Exception("WPS_ER_START succeeded during OOM")
3715     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3716         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3717             raise Exception("WPS_ER_START succeeded during OOM")
3718     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3719         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3720             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3721
3722 def test_ap_wps_er_init_fail(dev, apdev):
3723     """WPS ER init failure"""
3724     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3725         dev[0].request("WPS_ER_STOP")
3726         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3727
3728 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3729     """WPS events and wpa_cli action script"""
3730     logdir = os.path.abspath(test_params['logdir'])
3731     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3732     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3733     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3734
3735     with open(actionfile, 'w') as f:
3736         f.write('#!/bin/sh\n')
3737         f.write('echo $* >> %s\n' % logfile)
3738         # Kill the process and wait some time before returning to allow all the
3739         # pending events to be processed with some of this happening after the
3740         # eloop SIGALRM signal has been scheduled.
3741         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3742
3743     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3744              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3745
3746     ssid = "test-wps-conf"
3747     hostapd.add_ap(apdev[0]['ifname'],
3748                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3749                      "wpa_passphrase": "12345678", "wpa": "2",
3750                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3751     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3752
3753     prg = os.path.join(test_params['logdir'],
3754                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3755     if not os.path.exists(prg):
3756         prg = '../../wpa_supplicant/wpa_cli'
3757     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3758     subprocess.call(arg)
3759
3760     arg = [ 'ps', 'ax' ]
3761     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3762     out = cmd.communicate()[0]
3763     cmd.wait()
3764     logger.debug("Processes:\n" + out)
3765     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3766         raise Exception("Did not see wpa_cli running")
3767
3768     hapd.request("WPS_PIN any 12345670")
3769     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3770     dev[0].dump_monitor()
3771     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3772     dev[0].wait_connected(timeout=30)
3773
3774     for i in range(30):
3775         if not os.path.exists(pidfile):
3776             break
3777         time.sleep(0.1)
3778
3779     if not os.path.exists(logfile):
3780         raise Exception("wpa_cli action results file not found")
3781     with open(logfile, 'r') as f:
3782         res = f.read()
3783     if "WPS-SUCCESS" not in res:
3784         raise Exception("WPS-SUCCESS event not seen in action file")
3785
3786     arg = [ 'ps', 'ax' ]
3787     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3788     out = cmd.communicate()[0]
3789     cmd.wait()
3790     logger.debug("Remaining processes:\n" + out)
3791     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3792         raise Exception("wpa_cli still running")
3793
3794     if os.path.exists(pidfile):
3795         raise Exception("PID file not removed")
3796
3797 def test_ap_wps_er_ssdp_proto(dev, apdev):
3798     """WPS ER SSDP protocol testing"""
3799     try:
3800         _test_ap_wps_er_ssdp_proto(dev, apdev)
3801     finally:
3802         dev[0].request("WPS_ER_STOP")
3803
3804 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3805     socket.setdefaulttimeout(1)
3806     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3807     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3808     sock.bind(("239.255.255.250", 1900))
3809     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3810         raise Exception("Invalid filter accepted")
3811     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3812         raise Exception("WPS_ER_START with filter failed")
3813     (msg,addr) = sock.recvfrom(1000)
3814     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3815     if "M-SEARCH" not in msg:
3816         raise Exception("Not an M-SEARCH")
3817     sock.sendto("FOO", addr)
3818     time.sleep(0.1)
3819     dev[0].request("WPS_ER_STOP")
3820
3821     dev[0].request("WPS_ER_START ifname=lo")
3822     (msg,addr) = sock.recvfrom(1000)
3823     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3824     if "M-SEARCH" not in msg:
3825         raise Exception("Not an M-SEARCH")
3826     sock.sendto("FOO", addr)
3827     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3828     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3829     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3830     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3831     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3832     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3833     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3834     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3835     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3836     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3837     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3838     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)
3839     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3840     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3841         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)
3842         time.sleep(0.1)
3843     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3844         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)
3845         time.sleep(0.1)
3846
3847     # Add an AP with bogus URL
3848     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)
3849     # Update timeout on AP without updating URL
3850     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)
3851     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3852     if ev is None:
3853         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3854
3855     # Add an AP with a valid URL (but no server listing to it)
3856     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)
3857     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3858     if ev is None:
3859         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3860
3861     sock.close()
3862
3863 wps_event_url = None
3864
3865 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3866                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3867     payload = '''<?xml version="1.0"?>
3868 <root xmlns="urn:schemas-upnp-org:device-1-0">
3869 <specVersion>
3870 <major>1</major>
3871 <minor>0</minor>
3872 </specVersion>
3873 <device>
3874 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3875 <friendlyName>WPS Access Point</friendlyName>
3876 <manufacturer>Company</manufacturer>
3877 <modelName>WAP</modelName>
3878 <modelNumber>123</modelNumber>
3879 <serialNumber>12345</serialNumber>
3880 '''
3881     if udn:
3882         payload += '<UDN>' + udn + '</UDN>'
3883     payload += '''<serviceList>
3884 <service>
3885 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3886 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3887 <SCPDURL>wps_scpd.xml</SCPDURL>
3888 '''
3889     if controlURL:
3890         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3891     if eventSubURL:
3892         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3893     payload += '''</service>
3894 </serviceList>
3895 </device>
3896 </root>
3897 '''
3898     hdr = 'HTTP/1.1 200 OK\r\n' + \
3899           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3900           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3901           'Connection: close\r\n' + \
3902           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3903           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3904     return hdr + payload
3905
3906 def gen_wps_control(payload_override=None):
3907     payload = '''<?xml version="1.0"?>
3908 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3909 <s:Body>
3910 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3911 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3912 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3913 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3914 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3915 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3916 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3917 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3918 AAYANyoAASA=
3919 </NewDeviceInfo>
3920 </u:GetDeviceInfoResponse>
3921 </s:Body>
3922 </s:Envelope>
3923 '''
3924     if payload_override:
3925         payload = payload_override
3926     hdr = 'HTTP/1.1 200 OK\r\n' + \
3927           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3928           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3929           'Connection: close\r\n' + \
3930           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3931           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3932     return hdr + payload
3933
3934 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3935     payload = ""
3936     hdr = 'HTTP/1.1 200 OK\r\n' + \
3937           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3938           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3939           'Connection: close\r\n' + \
3940           'Content-Length: ' + str(len(payload)) + '\r\n'
3941     if sid:
3942         hdr += 'SID: ' + sid + '\r\n'
3943     hdr += 'Timeout: Second-1801\r\n' + \
3944           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3945     return hdr + payload
3946
3947 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3948     def handle(self):
3949         data = self.rfile.readline().strip()
3950         logger.info("HTTP server received: " + data)
3951         while True:
3952             hdr = self.rfile.readline().strip()
3953             if len(hdr) == 0:
3954                 break
3955             logger.info("HTTP header: " + hdr)
3956             if "CALLBACK:" in hdr:
3957                 global wps_event_url
3958                 wps_event_url = hdr.split(' ')[1].strip('<>')
3959
3960         if "GET /foo.xml" in data:
3961             self.handle_upnp_info()
3962         elif "POST /wps_control" in data:
3963             self.handle_wps_control()
3964         elif "SUBSCRIBE /wps_event" in data:
3965             self.handle_wps_event()
3966         else:
3967             self.handle_others(data)
3968
3969     def handle_upnp_info(self):
3970         self.wfile.write(gen_upnp_info())
3971
3972     def handle_wps_control(self):
3973         self.wfile.write(gen_wps_control())
3974
3975     def handle_wps_event(self):
3976         self.wfile.write(gen_wps_event())
3977
3978     def handle_others(self, data):
3979         logger.info("Ignore HTTP request: " + data)
3980
3981 class MyTCPServer(SocketServer.TCPServer):
3982     def __init__(self, addr, handler):
3983         self.allow_reuse_address = True
3984         SocketServer.TCPServer.__init__(self, addr, handler)
3985
3986 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3987                  location_url=None):
3988     socket.setdefaulttimeout(1)
3989     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3990     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3991     sock.bind(("239.255.255.250", 1900))
3992     dev.request("WPS_ER_START ifname=lo")
3993     for i in range(100):
3994         (msg,addr) = sock.recvfrom(1000)
3995         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3996         if "M-SEARCH" in msg:
3997             break
3998         if not wait_m_search:
3999             raise Exception("Not an M-SEARCH")
4000         if i == 99:
4001             raise Exception("No M-SEARCH seen")
4002
4003     # Add an AP with a valid URL and server listing to it
4004     server = MyTCPServer(("127.0.0.1", 12345), http_server)
4005     if not location_url:
4006         location_url = 'http://127.0.0.1:12345/foo.xml'
4007     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)
4008     server.timeout = 1
4009     return server,sock
4010
4011 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
4012     sock.close()
4013     server.server_close()
4014
4015     if on_alloc_fail:
4016         done = False
4017         for i in range(50):
4018             res = dev.request("GET_ALLOC_FAIL")
4019             if res.startswith("0:"):
4020                 done = True
4021                 break
4022             time.sleep(0.1)
4023         if not done:
4024             raise Exception("No allocation failure reported")
4025     else:
4026         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
4027         if ev is None:
4028             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
4029     dev.request("WPS_ER_STOP")
4030
4031 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
4032     try:
4033         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4034         server,sock = wps_er_start(dev, handler, location_url=location_url)
4035         global wps_event_url
4036         wps_event_url = None
4037         server.handle_request()
4038         server.handle_request()
4039         server.handle_request()
4040         server.server_close()
4041         if no_event_url:
4042             if wps_event_url:
4043                 raise Exception("Received event URL unexpectedly")
4044             return
4045         if wps_event_url is None:
4046             raise Exception("Did not get event URL")
4047         logger.info("Event URL: " + wps_event_url)
4048     finally:
4049             dev.request("WPS_ER_STOP")
4050
4051 def send_wlanevent(url, uuid, data, no_response=False):
4052     conn = httplib.HTTPConnection(url.netloc)
4053     payload = '''<?xml version="1.0" encoding="utf-8"?>
4054 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4055 <e:property><STAStatus>1</STAStatus></e:property>
4056 <e:property><APStatus>1</APStatus></e:property>
4057 <e:property><WLANEvent>'''
4058     payload += base64.b64encode(data)
4059     payload += '</WLANEvent></e:property></e:propertyset>'
4060     headers = { "Content-type": 'text/xml; charset="utf-8"',
4061                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4062                 "HOST": url.netloc,
4063                 "NT": "upnp:event",
4064                 "SID": "uuid:" + uuid,
4065                 "SEQ": "0",
4066                 "Content-Length": str(len(payload)) }
4067     conn.request("NOTIFY", url.path, payload, headers)
4068     if no_response:
4069         try:
4070             conn.getresponse()
4071         except Exception, e:
4072             pass
4073         return
4074     resp = conn.getresponse()
4075     if resp.status != 200:
4076         raise Exception("Unexpected HTTP response: %d" % resp.status)
4077
4078 def test_ap_wps_er_http_proto(dev, apdev):
4079     """WPS ER HTTP protocol testing"""
4080     try:
4081         _test_ap_wps_er_http_proto(dev, apdev)
4082     finally:
4083         dev[0].request("WPS_ER_STOP")
4084
4085 def _test_ap_wps_er_http_proto(dev, apdev):
4086     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4087     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
4088     global wps_event_url
4089     wps_event_url = None
4090     server.handle_request()
4091     server.handle_request()
4092     server.handle_request()
4093     server.server_close()
4094     if wps_event_url is None:
4095         raise Exception("Did not get event URL")
4096     logger.info("Event URL: " + wps_event_url)
4097
4098     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
4099     if ev is None:
4100         raise Exception("No WPS-ER-AP-ADD event")
4101     if uuid not in ev:
4102         raise Exception("UUID mismatch")
4103
4104     sock.close()
4105
4106     logger.info("Valid Probe Request notification")
4107     url = urlparse.urlparse(wps_event_url)
4108     conn = httplib.HTTPConnection(url.netloc)
4109     payload = '''<?xml version="1.0" encoding="utf-8"?>
4110 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4111 <e:property><STAStatus>1</STAStatus></e:property>
4112 <e:property><APStatus>1</APStatus></e:property>
4113 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
4114 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
4115 RGV2aWNlIEEQSQAGADcqAAEg
4116 </WLANEvent></e:property>
4117 </e:propertyset>
4118 '''
4119     headers = { "Content-type": 'text/xml; charset="utf-8"',
4120                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4121                 "HOST": url.netloc,
4122                 "NT": "upnp:event",
4123                 "SID": "uuid:" + uuid,
4124                 "SEQ": "0",
4125                 "Content-Length": str(len(payload)) }
4126     conn.request("NOTIFY", url.path, payload, headers)
4127     resp = conn.getresponse()
4128     if resp.status != 200:
4129         raise Exception("Unexpected HTTP response: %d" % resp.status)
4130
4131     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
4132     if ev is None:
4133         raise Exception("No WPS-ER-ENROLLEE-ADD event")
4134     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
4135         raise Exception("No Enrollee UUID match")
4136
4137     logger.info("Incorrect event URL AP id")
4138     conn = httplib.HTTPConnection(url.netloc)
4139     conn.request("NOTIFY", url.path + '123', payload, headers)
4140     resp = conn.getresponse()
4141     if resp.status != 404:
4142         raise Exception("Unexpected HTTP response: %d" % resp.status)
4143
4144     logger.info("Missing AP id")
4145     conn = httplib.HTTPConnection(url.netloc)
4146     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4147                  payload, headers)
4148     time.sleep(0.1)
4149
4150     logger.info("Incorrect event URL event id")
4151     conn = httplib.HTTPConnection(url.netloc)
4152     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4153     time.sleep(0.1)
4154
4155     logger.info("Incorrect event URL prefix")
4156     conn = httplib.HTTPConnection(url.netloc)
4157     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4158     resp = conn.getresponse()
4159     if resp.status != 404:
4160         raise Exception("Unexpected HTTP response: %d" % resp.status)
4161
4162     logger.info("Unsupported request")
4163     conn = httplib.HTTPConnection(url.netloc)
4164     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4165     resp = conn.getresponse()
4166     if resp.status != 501:
4167         raise Exception("Unexpected HTTP response: %d" % resp.status)
4168
4169     logger.info("Unsupported request and OOM")
4170     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4171         conn = httplib.HTTPConnection(url.netloc)
4172         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4173         time.sleep(0.5)
4174
4175     logger.info("Too short WLANEvent")
4176     data = '\x00'
4177     send_wlanevent(url, uuid, data)
4178
4179     logger.info("Invalid WLANEventMAC")
4180     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4181     send_wlanevent(url, uuid, data)
4182
4183     logger.info("Unknown WLANEventType")
4184     data = '\xff02:00:00:00:00:00'
4185     send_wlanevent(url, uuid, data)
4186
4187     logger.info("Probe Request notification without any attributes")
4188     data = '\x0102:00:00:00:00:00'
4189     send_wlanevent(url, uuid, data)
4190
4191     logger.info("Probe Request notification with invalid attribute")
4192     data = '\x0102:00:00:00:00:00\xff'
4193     send_wlanevent(url, uuid, data)
4194
4195     logger.info("EAP message without any attributes")
4196     data = '\x0202:00:00:00:00:00'
4197     send_wlanevent(url, uuid, data)
4198
4199     logger.info("EAP message with invalid attribute")
4200     data = '\x0202:00:00:00:00:00\xff'
4201     send_wlanevent(url, uuid, data)
4202
4203     logger.info("EAP message from new STA and not M1")
4204     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4205     send_wlanevent(url, uuid, data)
4206
4207     logger.info("EAP message: M1")
4208     data = '\x0202:00:00:00:00:00'
4209     data += '\x10\x22\x00\x01\x04'
4210     data += '\x10\x47\x00\x10' + 16*'\x00'
4211     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4212     data += '\x10\x1a\x00\x10' + 16*'\x00'
4213     data += '\x10\x32\x00\xc0' + 192*'\x00'
4214     data += '\x10\x04\x00\x02\x00\x00'
4215     data += '\x10\x10\x00\x02\x00\x00'
4216     data += '\x10\x0d\x00\x01\x00'
4217     data += '\x10\x08\x00\x02\x00\x00'
4218     data += '\x10\x44\x00\x01\x00'
4219     data += '\x10\x21\x00\x00'
4220     data += '\x10\x23\x00\x00'
4221     data += '\x10\x24\x00\x00'
4222     data += '\x10\x42\x00\x00'
4223     data += '\x10\x54\x00\x08' + 8*'\x00'
4224     data += '\x10\x11\x00\x00'
4225     data += '\x10\x3c\x00\x01\x00'
4226     data += '\x10\x02\x00\x02\x00\x00'
4227     data += '\x10\x12\x00\x02\x00\x00'
4228     data += '\x10\x09\x00\x02\x00\x00'
4229     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4230     m1 = data
4231     send_wlanevent(url, uuid, data)
4232
4233     logger.info("EAP message: WSC_ACK")
4234     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4235     send_wlanevent(url, uuid, data)
4236
4237     logger.info("EAP message: M1")
4238     send_wlanevent(url, uuid, m1)
4239
4240     logger.info("EAP message: WSC_NACK")
4241     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4242     send_wlanevent(url, uuid, data)
4243
4244     logger.info("EAP message: M1 - Too long attribute values")
4245     data = '\x0202:00:00:00:00:00'
4246     data += '\x10\x11\x00\x21' + 33*'\x00'
4247     data += '\x10\x45\x00\x21' + 33*'\x00'
4248     data += '\x10\x42\x00\x21' + 33*'\x00'
4249     data += '\x10\x24\x00\x21' + 33*'\x00'
4250     data += '\x10\x23\x00\x21' + 33*'\x00'
4251     data += '\x10\x21\x00\x41' + 65*'\x00'
4252     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4253     send_wlanevent(url, uuid, data)
4254
4255     logger.info("EAP message: M1 missing UUID-E")
4256     data = '\x0202:00:00:00:00:00'
4257     data += '\x10\x22\x00\x01\x04'
4258     send_wlanevent(url, uuid, data)
4259
4260     logger.info("EAP message: M1 missing MAC Address")
4261     data += '\x10\x47\x00\x10' + 16*'\x00'
4262     send_wlanevent(url, uuid, data)
4263
4264     logger.info("EAP message: M1 missing Enrollee Nonce")
4265     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4266     send_wlanevent(url, uuid, data)
4267
4268     logger.info("EAP message: M1 missing Public Key")
4269     data += '\x10\x1a\x00\x10' + 16*'\x00'
4270     send_wlanevent(url, uuid, data)
4271
4272     logger.info("EAP message: M1 missing Authentication Type flags")
4273     data += '\x10\x32\x00\xc0' + 192*'\x00'
4274     send_wlanevent(url, uuid, data)
4275
4276     logger.info("EAP message: M1 missing Encryption Type Flags")
4277     data += '\x10\x04\x00\x02\x00\x00'
4278     send_wlanevent(url, uuid, data)
4279
4280     logger.info("EAP message: M1 missing Connection Type flags")
4281     data += '\x10\x10\x00\x02\x00\x00'
4282     send_wlanevent(url, uuid, data)
4283
4284     logger.info("EAP message: M1 missing Config Methods")
4285     data += '\x10\x0d\x00\x01\x00'
4286     send_wlanevent(url, uuid, data)
4287
4288     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4289     data += '\x10\x08\x00\x02\x00\x00'
4290     send_wlanevent(url, uuid, data)
4291
4292     logger.info("EAP message: M1 missing Manufacturer")
4293     data += '\x10\x44\x00\x01\x00'
4294     send_wlanevent(url, uuid, data)
4295
4296     logger.info("EAP message: M1 missing Model Name")
4297     data += '\x10\x21\x00\x00'
4298     send_wlanevent(url, uuid, data)
4299
4300     logger.info("EAP message: M1 missing Model Number")
4301     data += '\x10\x23\x00\x00'
4302     send_wlanevent(url, uuid, data)
4303
4304     logger.info("EAP message: M1 missing Serial Number")
4305     data += '\x10\x24\x00\x00'
4306     send_wlanevent(url, uuid, data)
4307
4308     logger.info("EAP message: M1 missing Primary Device Type")
4309     data += '\x10\x42\x00\x00'
4310     send_wlanevent(url, uuid, data)
4311
4312     logger.info("EAP message: M1 missing Device Name")
4313     data += '\x10\x54\x00\x08' + 8*'\x00'
4314     send_wlanevent(url, uuid, data)
4315
4316     logger.info("EAP message: M1 missing RF Bands")
4317     data += '\x10\x11\x00\x00'
4318     send_wlanevent(url, uuid, data)
4319
4320     logger.info("EAP message: M1 missing Association State")
4321     data += '\x10\x3c\x00\x01\x00'
4322     send_wlanevent(url, uuid, data)
4323
4324     logger.info("EAP message: M1 missing Device Password ID")
4325     data += '\x10\x02\x00\x02\x00\x00'
4326     send_wlanevent(url, uuid, data)
4327
4328     logger.info("EAP message: M1 missing Configuration Error")
4329     data += '\x10\x12\x00\x02\x00\x00'
4330     send_wlanevent(url, uuid, data)
4331
4332     logger.info("EAP message: M1 missing OS Version")
4333     data += '\x10\x09\x00\x02\x00\x00'
4334     send_wlanevent(url, uuid, data)
4335
4336     logger.info("Check max concurrent requests")
4337     addr = (url.hostname, url.port)
4338     socks = {}
4339     for i in range(20):
4340         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4341                                  socket.IPPROTO_TCP)
4342         socks[i].connect(addr)
4343     for i in range(20):
4344         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4345     count = 0
4346     for i in range(20):
4347         try:
4348             res = socks[i].recv(100)
4349             if "HTTP/1" in res:
4350                 count += 1
4351         except:
4352             pass
4353         socks[i].close()
4354     logger.info("%d concurrent HTTP GET operations returned response" % count)
4355     if count < 10:
4356         raise Exception("Too few concurrent HTTP connections accepted")
4357
4358     logger.info("OOM in HTTP server")
4359     for func in [ "http_request_init", "httpread_create",
4360                   "eloop_register_timeout;httpread_create",
4361                   "eloop_register_sock;httpread_create",
4362                   "httpread_hdr_analyze" ]:
4363         with alloc_fail(dev[0], 1, func):
4364             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4365                                  socket.IPPROTO_TCP)
4366             sock.connect(addr)
4367             sock.send("GET / HTTP/1.1\r\n\r\n")
4368             try:
4369                 sock.recv(100)
4370             except:
4371                 pass
4372             sock.close()
4373
4374     logger.info("Invalid HTTP header")
4375     for req in [ " GET / HTTP/1.1\r\n\r\n",
4376                  "HTTP/1.1 200 OK\r\n\r\n",
4377                  "HTTP/\r\n\r\n",
4378                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4379                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4380                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4381                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4382                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4383                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4384                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4385                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4386         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4387                              socket.IPPROTO_TCP)
4388         sock.settimeout(0.1)
4389         sock.connect(addr)
4390         sock.send(req)
4391         try:
4392             sock.recv(100)
4393         except:
4394             pass
4395         sock.close()
4396
4397     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4398         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4399                              socket.IPPROTO_TCP)
4400         sock.connect(addr)
4401         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4402         try:
4403             sock.recv(100)
4404         except:
4405             pass
4406         sock.close()
4407
4408     conn = httplib.HTTPConnection(url.netloc)
4409     payload = '<foo'
4410     headers = { "Content-type": 'text/xml; charset="utf-8"',
4411                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4412                 "HOST": url.netloc,
4413                 "NT": "upnp:event",
4414                 "SID": "uuid:" + uuid,
4415                 "SEQ": "0",
4416                 "Content-Length": str(len(payload)) }
4417     conn.request("NOTIFY", url.path, payload, headers)
4418     resp = conn.getresponse()
4419     if resp.status != 200:
4420         raise Exception("Unexpected HTTP response: %d" % resp.status)
4421
4422     conn = httplib.HTTPConnection(url.netloc)
4423     payload = '<WLANEvent foo></WLANEvent>'
4424     headers = { "Content-type": 'text/xml; charset="utf-8"',
4425                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4426                 "HOST": url.netloc,
4427                 "NT": "upnp:event",
4428                 "SID": "uuid:" + uuid,
4429                 "SEQ": "0",
4430                 "Content-Length": str(len(payload)) }
4431     conn.request("NOTIFY", url.path, payload, headers)
4432     resp = conn.getresponse()
4433     if resp.status != 200:
4434         raise Exception("Unexpected HTTP response: %d" % resp.status)
4435
4436     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4437         send_wlanevent(url, uuid, '')
4438
4439     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4440         send_wlanevent(url, uuid, 'foo')
4441
4442     for func in [ "wps_init",
4443                   "wps_process_manufacturer",
4444                   "wps_process_model_name",
4445                   "wps_process_model_number",
4446                   "wps_process_serial_number",
4447                   "wps_process_dev_name" ]:
4448         with alloc_fail(dev[0], 1, func):
4449             send_wlanevent(url, uuid, m1)
4450
4451     with alloc_fail(dev[0], 1, "wps_er_http_resp_ok"):
4452         send_wlanevent(url, uuid, m1, no_response=True)
4453
4454     with alloc_fail(dev[0], 1, "wps_er_http_resp_not_found"):
4455         url2 = urlparse.urlparse(wps_event_url.replace('/event/', '/notfound/'))
4456         send_wlanevent(url2, uuid, m1, no_response=True)
4457
4458     logger.info("EAP message: M1")
4459     data = '\x0202:11:22:00:00:00'
4460     data += '\x10\x22\x00\x01\x04'
4461     data += '\x10\x47\x00\x10' + 16*'\x00'
4462     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4463     data += '\x10\x1a\x00\x10' + 16*'\x00'
4464     data += '\x10\x32\x00\xc0' + 192*'\x00'
4465     data += '\x10\x04\x00\x02\x00\x00'
4466     data += '\x10\x10\x00\x02\x00\x00'
4467     data += '\x10\x0d\x00\x01\x00'
4468     data += '\x10\x08\x00\x02\x00\x00'
4469     data += '\x10\x44\x00\x01\x00'
4470     data += '\x10\x21\x00\x00'
4471     data += '\x10\x23\x00\x00'
4472     data += '\x10\x24\x00\x00'
4473     data += '\x10\x42\x00\x00'
4474     data += '\x10\x54\x00\x08' + 8*'\x00'
4475     data += '\x10\x11\x00\x00'
4476     data += '\x10\x3c\x00\x01\x00'
4477     data += '\x10\x02\x00\x02\x00\x00'
4478     data += '\x10\x12\x00\x02\x00\x00'
4479     data += '\x10\x09\x00\x02\x00\x00'
4480     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4481     dev[0].dump_monitor()
4482     with alloc_fail(dev[0], 1, "wps_er_add_sta_data"):
4483         send_wlanevent(url, uuid, data)
4484         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=0.1)
4485         if ev is not None:
4486             raise Exception("Unexpected enrollee add event")
4487     send_wlanevent(url, uuid, data)
4488     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=2)
4489     if ev is None:
4490         raise Exception("Enrollee add event not seen")
4491
4492     with alloc_fail(dev[0], 1, "base64_encode;wps_er_soap_hdr"):
4493         send_wlanevent(url, uuid, data)
4494
4495     with alloc_fail(dev[0], 1, "wpabuf_alloc;wps_er_soap_hdr"):
4496         send_wlanevent(url, uuid, data)
4497
4498     with alloc_fail(dev[0], 1, "http_client_url_parse;wps_er_sta_send_msg"):
4499         send_wlanevent(url, uuid, data)
4500
4501     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_sta_send_msg"):
4502         send_wlanevent(url, uuid, data)
4503
4504 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4505     """WPS ER HTTP protocol testing - no eventSubURL"""
4506     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4507         def handle_upnp_info(self):
4508             self.wfile.write(gen_upnp_info(eventSubURL=None))
4509     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4510                           no_event_url=True)
4511
4512 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4513     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4514     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4515         def handle_upnp_info(self):
4516             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4517     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4518                           no_event_url=True)
4519
4520 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4521     """WPS ER HTTP protocol testing - subscribe OOM"""
4522     try:
4523         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4524     finally:
4525         dev[0].request("WPS_ER_STOP")
4526
4527 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4528     tests = [ (1, "http_client_url_parse"),
4529               (1, "wpabuf_alloc;wps_er_subscribe"),
4530               (1, "http_client_addr"),
4531               (1, "eloop_register_sock;http_client_addr"),
4532               (1, "eloop_register_timeout;http_client_addr") ]
4533     for count,func in tests:
4534         with alloc_fail(dev[0], count, func):
4535             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4536             server.handle_request()
4537             server.handle_request()
4538             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4539
4540 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4541     """WPS ER HTTP protocol testing - no SID"""
4542     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4543         def handle_wps_event(self):
4544             self.wfile.write(gen_wps_event(sid=None))
4545     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4546
4547 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4548     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4549     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4550         def handle_wps_event(self):
4551             self.wfile.write(gen_wps_event(sid='FOO'))
4552     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4553
4554 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4555     """WPS ER HTTP protocol testing - invalid SID UUID"""
4556     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4557         def handle_wps_event(self):
4558             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4559     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4560
4561 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4562     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4563     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4564         def handle_wps_event(self):
4565             payload = ""
4566             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4567                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4568                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4569                   'Connection: close\r\n' + \
4570                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4571                   'Timeout: Second-1801\r\n' + \
4572                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4573             self.wfile.write(hdr + payload)
4574     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4575
4576 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4577     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4578     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4579         def handle_wps_event(self):
4580             payload = ""
4581             hdr = 'HTTP/1.1 FOO\r\n' + \
4582                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4583                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4584                   'Connection: close\r\n' + \
4585                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4586                   'Timeout: Second-1801\r\n' + \
4587                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4588             self.wfile.write(hdr + payload)
4589     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4590
4591 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4592     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4593     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4594         def handle_wps_control(self):
4595             payload = '''<?xml version="1.0"?>
4596 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4597 <s:Body>
4598 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4599 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4600 </u:GetDeviceInfoResponse>
4601 </s:Body>
4602 </s:Envelope>
4603 '''
4604             self.wfile.write(gen_wps_control(payload_override=payload))
4605     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4606
4607 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4608     """WPS ER HTTP protocol testing - No device in UPnP info"""
4609     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4610         def handle_upnp_info(self):
4611             payload = '''<?xml version="1.0"?>
4612 <root xmlns="urn:schemas-upnp-org:device-1-0">
4613 <specVersion>
4614 <major>1</major>
4615 <minor>0</minor>
4616 </specVersion>
4617 </root>
4618 '''
4619             hdr = 'HTTP/1.1 200 OK\r\n' + \
4620                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4621                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4622                   'Connection: close\r\n' + \
4623                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4624                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4625             self.wfile.write(hdr + payload)
4626     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4627
4628 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4629     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4630     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4631         def handle_upnp_info(self):
4632             payload = '''<?xml version="1.0"?>
4633 <root xmlns="urn:schemas-upnp-org:device-1-0">
4634 <specVersion>
4635 <major>1</major>
4636 <minor>0</minor>
4637 </specVersion>
4638 <device>
4639 </device>
4640 </root>
4641 '''
4642             hdr = 'HTTP/1.1 200 OK\r\n' + \
4643                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4644                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4645                   'Connection: close\r\n' + \
4646                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4647                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4648             self.wfile.write(hdr + payload)
4649     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4650
4651 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4652     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4653     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4654         def handle_upnp_info(self):
4655             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4656     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4657
4658 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4659     """WPS ER HTTP protocol testing - no controlURL"""
4660     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4661         def handle_upnp_info(self):
4662             self.wfile.write(gen_upnp_info(controlURL=None))
4663     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4664                           no_event_url=True)
4665
4666 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4667     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4668     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4669         def handle_upnp_info(self):
4670             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4671     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4672                           no_event_url=True)
4673
4674 def test_ap_wps_http_timeout(dev, apdev):
4675     """WPS AP/ER and HTTP timeout"""
4676     try:
4677         _test_ap_wps_http_timeout(dev, apdev)
4678     finally:
4679         dev[0].request("WPS_ER_STOP")
4680
4681 def _test_ap_wps_http_timeout(dev, apdev):
4682     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4683     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4684
4685     location = ssdp_get_location(ap_uuid)
4686     url = urlparse.urlparse(location)
4687     addr = (url.hostname, url.port)
4688     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4689     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4690                          socket.IPPROTO_TCP)
4691     sock.connect(addr)
4692     sock.send("G")
4693
4694     class DummyServer(SocketServer.StreamRequestHandler):
4695         def handle(self):
4696             logger.debug("DummyServer - start 31 sec wait")
4697             time.sleep(31)
4698             logger.debug("DummyServer - wait done")
4699
4700     logger.debug("Start WPS ER")
4701     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4702                                 wait_m_search=True)
4703
4704     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4705     # This will wait for 31 seconds..
4706     server.handle_request()
4707
4708     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4709     try:
4710         sock.send("ET / HTTP/1.1\r\n\r\n")
4711         res = sock.recv(100)
4712         sock.close()
4713     except:
4714         pass
4715
4716 def test_ap_wps_er_url_parse(dev, apdev):
4717     """WPS ER and URL parsing special cases"""
4718     try:
4719         _test_ap_wps_er_url_parse(dev, apdev)
4720     finally:
4721         dev[0].request("WPS_ER_STOP")
4722
4723 def _test_ap_wps_er_url_parse(dev, apdev):
4724     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4725     sock.settimeout(1)
4726     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4727     sock.bind(("239.255.255.250", 1900))
4728     dev[0].request("WPS_ER_START ifname=lo")
4729     (msg,addr) = sock.recvfrom(1000)
4730     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4731     if "M-SEARCH" not in msg:
4732         raise Exception("Not an M-SEARCH")
4733     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)
4734     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4735     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)
4736     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4737     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)
4738     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4739
4740     sock.close()
4741
4742 def test_ap_wps_er_link_update(dev, apdev):
4743     """WPS ER and link update special cases"""
4744     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4745         def handle_upnp_info(self):
4746             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4747     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4748
4749     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4750         def handle_others(self, data):
4751             if "GET / " in data:
4752                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4753     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4754                           location_url='http://127.0.0.1:12345')
4755
4756 def test_ap_wps_er_http_client(dev, apdev):
4757     """WPS ER and HTTP client special cases"""
4758     with alloc_fail(dev[0], 1, "http_link_update"):
4759         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4760
4761     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4762         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4763
4764     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4765         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4766
4767     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4768         def handle_upnp_info(self):
4769             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4770     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4771                           no_event_url=True)
4772
4773 def test_ap_wps_init_oom(dev, apdev):
4774     """wps_init OOM cases"""
4775     ssid = "test-wps"
4776     appin = "12345670"
4777     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4778                "ap_pin": appin }
4779     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4780     pin = dev[0].wps_read_pin()
4781
4782     with alloc_fail(hapd, 1, "wps_init"):
4783         hapd.request("WPS_PIN any " + pin)
4784         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4785         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4786         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4787         if ev is None:
4788             raise Exception("No EAP failure reported")
4789         dev[0].request("WPS_CANCEL")
4790
4791     with alloc_fail(dev[0], 2, "wps_init"):
4792         hapd.request("WPS_PIN any " + pin)
4793         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4794         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4795         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4796         if ev is None:
4797             raise Exception("No EAP failure reported")
4798         dev[0].request("WPS_CANCEL")
4799
4800     with alloc_fail(dev[0], 2, "wps_init"):
4801         hapd.request("WPS_PBC")
4802         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4803         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4804         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4805         if ev is None:
4806             raise Exception("No EAP failure reported")
4807         dev[0].request("WPS_CANCEL")
4808
4809     dev[0].dump_monitor()
4810     new_ssid = "wps-new-ssid"
4811     new_passphrase = "1234567890"
4812     with alloc_fail(dev[0], 3, "wps_init"):
4813         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4814                        new_passphrase, no_wait=True)
4815         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4816         if ev is None:
4817             raise Exception("No EAP failure reported")
4818
4819     dev[0].flush_scan_cache()
4820
4821 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4822     """WPS and invalid IE in Association Request frame"""
4823     ssid = "test-wps"
4824     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4825     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4826     pin = "12345670"
4827     hapd.request("WPS_PIN any " + pin)
4828     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4829     try:
4830         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4831         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4832         for i in range(5):
4833             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4834             if ev and "vendor=14122" in ev:
4835                 break
4836         if ev is None or "vendor=14122" not in ev:
4837             raise Exception("EAP-WSC not started")
4838         dev[0].request("WPS_CANCEL")
4839     finally:
4840         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4841
4842 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4843     """WPS PBC/PIN mismatch"""
4844     ssid = "test-wps"
4845     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4846     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4847     hapd.request("SET wps_version_number 0x10")
4848     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4849     hapd.request("WPS_PBC")
4850     pin = dev[0].wps_read_pin()
4851     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4852     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4853     if ev is None:
4854         raise Exception("Scan did not complete")
4855     dev[0].request("WPS_CANCEL")
4856
4857     hapd.request("WPS_CANCEL")
4858     dev[0].flush_scan_cache()
4859
4860 def test_ap_wps_ie_invalid(dev, apdev):
4861     """WPS PIN attempt with AP that has invalid WSC IE"""
4862     ssid = "test-wps"
4863     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4864                "vendor_elements": "dd050050f20410" }
4865     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4866     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4867     hostapd.add_ap(apdev[1]['ifname'], params)
4868     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4869     pin = dev[0].wps_read_pin()
4870     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4871     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4872     if ev is None:
4873         raise Exception("Scan did not complete")
4874     dev[0].request("WPS_CANCEL")
4875
4876 def test_ap_wps_scan_prio_order(dev, apdev):
4877     """WPS scan priority ordering"""
4878     ssid = "test-wps"
4879     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4880     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4881     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4882     hostapd.add_ap(apdev[1]['ifname'], params)
4883     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4884     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4885     pin = dev[0].wps_read_pin()
4886     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4887     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4888     if ev is None:
4889         raise Exception("Scan did not complete")
4890     dev[0].request("WPS_CANCEL")
4891
4892 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4893     """WPS ProbeReq IE OOM"""
4894     ssid = "test-wps"
4895     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4896     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4897     pin = dev[0].wps_read_pin()
4898     hapd.request("WPS_PIN any " + pin)
4899     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4900     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4901         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4902         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4903         if ev is None:
4904             raise Exception("Association not seen")
4905     dev[0].request("WPS_CANCEL")
4906
4907     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4908         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4909         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4910         if ev is None:
4911             raise Exception("Association not seen")
4912     dev[0].request("WPS_CANCEL")
4913
4914 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4915     """WPS AssocReq IE OOM"""
4916     ssid = "test-wps"
4917     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4918     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4919     pin = dev[0].wps_read_pin()
4920     hapd.request("WPS_PIN any " + pin)
4921     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4922     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4923         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4924         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4925         if ev is None:
4926             raise Exception("Association not seen")
4927     dev[0].request("WPS_CANCEL")
4928
4929 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4930     """WPS AssocResp IE OOM"""
4931     ssid = "test-wps"
4932     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4933     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4934     pin = dev[0].wps_read_pin()
4935     hapd.request("WPS_PIN any " + pin)
4936     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4937     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4938         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4939         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4940         if ev is None:
4941             raise Exception("Association not seen")
4942     dev[0].request("WPS_CANCEL")
4943
4944 def test_ap_wps_bss_info_errors(dev, apdev):
4945     """WPS BSS info errors"""
4946     params = { "ssid": "1",
4947                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4948     hostapd.add_ap(apdev[0]['ifname'], params)
4949     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4950     hostapd.add_ap(apdev[1]['ifname'], params)
4951     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4952     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4953     bss = dev[0].get_bss(apdev[0]['bssid'])
4954     logger.info("BSS: " + str(bss))
4955     if "wps_state" in bss:
4956         raise Exception("Unexpected wps_state in BSS info")
4957     if 'wps_device_name' not in bss:
4958         raise Exception("No wps_device_name in BSS info")
4959     if bss['wps_device_name'] != '_':
4960         raise Exception("Unexpected wps_device_name value")
4961     bss = dev[0].get_bss(apdev[1]['bssid'])
4962     logger.info("BSS: " + str(bss))
4963
4964     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4965         bss = dev[0].get_bss(apdev[0]['bssid'])
4966         logger.info("BSS(OOM): " + str(bss))
4967
4968 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4969     hapd.request("WPS_PBC")
4970     dev.scan_for_bss(apdev['bssid'], freq="2412")
4971     dev.request("WPS_PBC " + apdev['bssid'])
4972     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4973     if ev is None:
4974         raise Exception("No EAP failure reported")
4975     dev.request("WPS_CANCEL")
4976     dev.wait_disconnected()
4977     for i in range(5):
4978         try:
4979             dev.flush_scan_cache()
4980             break
4981         except Exception, e:
4982             if str(e).startswith("Failed to trigger scan"):
4983                 # Try again
4984                 time.sleep(1)
4985             else:
4986                 raise
4987
4988 def wps_run_pbc_fail(apdev, dev):
4989     hapd = wps_start_ap(apdev)
4990     wps_run_pbc_fail_ap(apdev, dev, hapd)
4991
4992 def test_ap_wps_pk_oom(dev, apdev):
4993     """WPS and public key OOM"""
4994     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4995         wps_run_pbc_fail(apdev[0], dev[0])
4996
4997 def test_ap_wps_pk_oom_ap(dev, apdev):
4998     """WPS and public key OOM on AP"""
4999     hapd = wps_start_ap(apdev[0])
5000     with alloc_fail(hapd, 1, "wps_build_public_key"):
5001         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5002
5003 def test_ap_wps_encr_oom_ap(dev, apdev):
5004     """WPS and encrypted settings decryption OOM on AP"""
5005     hapd = wps_start_ap(apdev[0])
5006     pin = dev[0].wps_read_pin()
5007     hapd.request("WPS_PIN any " + pin)
5008     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5009     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
5010         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
5011         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
5012         if ev is None:
5013             raise Exception("No WPS-FAIL reported")
5014         dev[0].request("WPS_CANCEL")
5015     dev[0].wait_disconnected()
5016
5017 def test_ap_wps_encr_no_random_ap(dev, apdev):
5018     """WPS and no random data available for encryption on AP"""
5019     hapd = wps_start_ap(apdev[0])
5020     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
5021         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5022
5023 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
5024     """WPS and no random data available for e-hash on STA"""
5025     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
5026         wps_run_pbc_fail(apdev[0], dev[0])
5027
5028 def test_ap_wps_m1_no_random(dev, apdev):
5029     """WPS and no random for M1 on STA"""
5030     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
5031         wps_run_pbc_fail(apdev[0], dev[0])
5032
5033 def test_ap_wps_m1_oom(dev, apdev):
5034     """WPS and OOM for M1 on STA"""
5035     with alloc_fail(dev[0], 1, "wps_build_m1"):
5036         wps_run_pbc_fail(apdev[0], dev[0])
5037
5038 def test_ap_wps_m3_oom(dev, apdev):
5039     """WPS and OOM for M3 on STA"""
5040     with alloc_fail(dev[0], 1, "wps_build_m3"):
5041         wps_run_pbc_fail(apdev[0], dev[0])
5042
5043 def test_ap_wps_m5_oom(dev, apdev):
5044     """WPS and OOM for M5 on STA"""
5045     hapd = wps_start_ap(apdev[0])
5046     hapd.request("WPS_PBC")
5047     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5048     for i in range(1, 3):
5049         with alloc_fail(dev[0], i, "wps_build_m5"):
5050             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5051             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5052             if ev is None:
5053                 raise Exception("No EAP failure reported")
5054             dev[0].request("WPS_CANCEL")
5055             dev[0].wait_disconnected()
5056     dev[0].flush_scan_cache()
5057
5058 def test_ap_wps_m5_no_random(dev, apdev):
5059     """WPS and no random for M5 on STA"""
5060     with fail_test(dev[0], 1,
5061                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
5062         wps_run_pbc_fail(apdev[0], dev[0])
5063
5064 def test_ap_wps_m7_oom(dev, apdev):
5065     """WPS and OOM for M7 on STA"""
5066     hapd = wps_start_ap(apdev[0])
5067     hapd.request("WPS_PBC")
5068     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5069     for i in range(1, 3):
5070         with alloc_fail(dev[0], i, "wps_build_m7"):
5071             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5072             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5073             if ev is None:
5074                 raise Exception("No EAP failure reported")
5075             dev[0].request("WPS_CANCEL")
5076             dev[0].wait_disconnected()
5077     dev[0].flush_scan_cache()
5078
5079 def test_ap_wps_m7_no_random(dev, apdev):
5080     """WPS and no random for M7 on STA"""
5081     with fail_test(dev[0], 1,
5082                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
5083         wps_run_pbc_fail(apdev[0], dev[0])
5084
5085 def test_ap_wps_wsc_done_oom(dev, apdev):
5086     """WPS and OOM for WSC_Done on STA"""
5087     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
5088         wps_run_pbc_fail(apdev[0], dev[0])
5089
5090 def test_ap_wps_random_psk_fail(dev, apdev):
5091     """WPS and no random for PSK on AP"""
5092     ssid = "test-wps"
5093     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
5094     appin = "12345670"
5095     try:
5096         os.remove(pskfile)
5097     except:
5098         pass
5099
5100     try:
5101         with open(pskfile, "w") as f:
5102             f.write("# WPA PSKs\n")
5103
5104         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5105                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
5106                    "rsn_pairwise": "CCMP", "ap_pin": appin,
5107                    "wpa_psk_file": pskfile }
5108         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5109
5110         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5111         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
5112             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
5113             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5114             if ev is None:
5115                 raise Exception("No EAP failure reported")
5116             dev[0].request("WPS_CANCEL")
5117         dev[0].wait_disconnected()
5118
5119         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
5120             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5121
5122         with alloc_fail(hapd, 1, "wps_build_cred"):
5123             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5124
5125         with alloc_fail(hapd, 2, "wps_build_cred"):
5126             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5127     finally:
5128         os.remove(pskfile)
5129
5130 def wps_ext_eap_identity_req(dev, hapd, bssid):
5131     logger.debug("EAP-Identity/Request")
5132     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5133     if ev is None:
5134         raise Exception("Timeout on EAPOL-TX from hostapd")
5135     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
5136     if "OK" not in res:
5137         raise Exception("EAPOL_RX to wpa_supplicant failed")
5138
5139 def wps_ext_eap_identity_resp(hapd, dev, addr):
5140     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5141     if ev is None:
5142         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
5143     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
5144     if "OK" not in res:
5145         raise Exception("EAPOL_RX to hostapd failed")
5146
5147 def wps_ext_eap_wsc(dst, src, src_addr, msg):
5148     logger.debug(msg)
5149     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5150     if ev is None:
5151         raise Exception("Timeout on EAPOL-TX")
5152     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
5153     if "OK" not in res:
5154         raise Exception("EAPOL_RX failed")
5155
5156 def wps_start_ext(apdev, dev, pbc=False, pin=None):
5157     addr = dev.own_addr()
5158     bssid = apdev['bssid']
5159     ssid = "test-wps-conf"
5160     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5161                "wpa_passphrase": "12345678", "wpa": "2",
5162                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5163     hapd = hostapd.add_ap(apdev['ifname'], params)
5164
5165     if pbc:
5166         hapd.request("WPS_PBC")
5167     else:
5168         if pin is None:
5169             pin = dev.wps_read_pin()
5170         hapd.request("WPS_PIN any " + pin)
5171     dev.scan_for_bss(bssid, freq="2412")
5172     hapd.request("SET ext_eapol_frame_io 1")
5173     dev.request("SET ext_eapol_frame_io 1")
5174
5175     if pbc:
5176         dev.request("WPS_PBC " + bssid)
5177     else:
5178         dev.request("WPS_PIN " + bssid + " " + pin)
5179     return addr,bssid,hapd
5180
5181 def wps_auth_corrupt(dst, src, addr):
5182     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5183     if ev is None:
5184         raise Exception("Timeout on EAPOL-TX")
5185     src.request("SET ext_eapol_frame_io 0")
5186     dst.request("SET ext_eapol_frame_io 0")
5187     msg = ev.split(' ')[2]
5188     if msg[-24:-16] != '10050008':
5189         raise Exception("Could not find Authenticator attribute")
5190     # Corrupt Authenticator value
5191     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5192     res = dst.request("EAPOL_RX " + addr + " " + msg)
5193     if "OK" not in res:
5194         raise Exception("EAPOL_RX failed")
5195
5196 def wps_fail_finish(hapd, dev, fail_str):
5197     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5198     if ev is None:
5199         raise Exception("WPS-FAIL not indicated")
5200     if fail_str not in ev:
5201         raise Exception("Unexpected WPS-FAIL value: " + ev)
5202     dev.request("WPS_CANCEL")
5203     dev.wait_disconnected()
5204
5205 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5206     wps_auth_corrupt(dev, hapd, bssid)
5207     wps_fail_finish(hapd, dev, fail_str)
5208
5209 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5210     wps_auth_corrupt(hapd, dev, addr)
5211     wps_fail_finish(hapd, dev, fail_str)
5212
5213 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5214     """WPS and Authenticator attribute mismatch in M2"""
5215     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5216     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5217     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5218     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5219     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5220     logger.debug("M2")
5221     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5222
5223 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5224     """WPS and Authenticator attribute mismatch in M3"""
5225     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5226     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5227     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5228     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5229     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5230     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5231     logger.debug("M3")
5232     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5233
5234 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5235     """WPS and Authenticator attribute mismatch in M4"""
5236     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5237     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5238     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5239     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5240     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5241     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5242     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5243     logger.debug("M4")
5244     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5245
5246 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5247     """WPS and Authenticator attribute mismatch in M5"""
5248     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5249     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5250     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5251     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5252     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5253     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5254     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5255     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5256     logger.debug("M5")
5257     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5258
5259 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5260     """WPS and Authenticator attribute mismatch in M6"""
5261     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5262     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5263     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5264     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5265     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5266     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5267     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5268     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5269     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5270     logger.debug("M6")
5271     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5272
5273 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5274     """WPS and Authenticator attribute mismatch in M7"""
5275     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5276     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5277     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5278     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5279     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5280     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5281     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5282     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5283     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5284     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5285     logger.debug("M7")
5286     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5287
5288 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5289     """WPS and Authenticator attribute mismatch in M8"""
5290     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5291     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5292     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5293     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5294     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5295     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5296     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5297     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5298     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5299     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5300     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5301     logger.debug("M8")
5302     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5303
5304 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5305     """WPS and Authenticator attribute missing from M2"""
5306     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5307     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5308     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5309     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5310     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5311     logger.debug("M2")
5312     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5313     if ev is None:
5314         raise Exception("Timeout on EAPOL-TX")
5315     hapd.request("SET ext_eapol_frame_io 0")
5316     dev[0].request("SET ext_eapol_frame_io 0")
5317     msg = ev.split(' ')[2]
5318     if msg[-24:-16] != '10050008':
5319         raise Exception("Could not find Authenticator attribute")
5320     # Remove Authenticator value
5321     msg = msg[:-24]
5322     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5323     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5324     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5325     if "OK" not in res:
5326         raise Exception("EAPOL_RX failed")
5327     wps_fail_finish(hapd, dev[0], "msg=5")
5328
5329 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5330     """WPS and M2 with different Device Password ID (P2P)"""
5331     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5332     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5333     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5334     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5335     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5336     logger.debug("M2")
5337     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5338     if ev is None:
5339         raise Exception("Timeout on EAPOL-TX")
5340     hapd.request("SET ext_eapol_frame_io 0")
5341     dev[0].request("SET ext_eapol_frame_io 0")
5342     msg = ev.split(' ')[2]
5343     if msg[722:730] != '10120002':
5344         raise Exception("Could not find Device Password ID attribute")
5345     # Replace Device Password ID value. This will fail Authenticator check, but
5346     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5347     # log.
5348     msg = msg[0:730] + "0005" + msg[734:]
5349     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5350     if "OK" not in res:
5351         raise Exception("EAPOL_RX failed")
5352     wps_fail_finish(hapd, dev[0], "msg=5")
5353
5354 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5355     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5356     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5357     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5358     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5359     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5360     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5361     logger.debug("M2")
5362     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5363     if ev is None:
5364         raise Exception("Timeout on EAPOL-TX")
5365     hapd.request("SET ext_eapol_frame_io 0")
5366     dev[0].request("SET ext_eapol_frame_io 0")
5367     msg = ev.split(' ')[2]
5368     if msg[722:730] != '10120002':
5369         raise Exception("Could not find Device Password ID attribute")
5370     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5371     msg = msg[0:730] + "0004" + msg[734:]
5372     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5373     if "OK" not in res:
5374         raise Exception("EAPOL_RX failed")
5375     wps_fail_finish(hapd, dev[0], "msg=5")
5376
5377 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5378     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5379     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5380     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5381     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5382     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5383     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5384     logger.debug("M2")
5385     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5386     if ev is None:
5387         raise Exception("Timeout on EAPOL-TX")
5388     hapd.request("SET ext_eapol_frame_io 0")
5389     dev[0].request("SET ext_eapol_frame_io 0")
5390     msg = ev.split(' ')[2]
5391     if msg[722:730] != '10120002':
5392         raise Exception("Could not find Device Password ID attribute")
5393     # Replace Device Password ID value. This will fail Authenticator check, but
5394     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5395     # log.
5396     msg = msg[0:730] + "0000" + msg[734:]
5397     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5398     if "OK" not in res:
5399         raise Exception("EAPOL_RX failed")
5400     wps_fail_finish(hapd, dev[0], "msg=5")
5401     dev[0].flush_scan_cache()
5402
5403 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5404     """WPS and M2 without Device Password ID"""
5405     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5406     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5407     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5408     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5409     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5410     logger.debug("M2")
5411     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5412     if ev is None:
5413         raise Exception("Timeout on EAPOL-TX")
5414     hapd.request("SET ext_eapol_frame_io 0")
5415     dev[0].request("SET ext_eapol_frame_io 0")
5416     msg = ev.split(' ')[2]
5417     if msg[722:730] != '10120002':
5418         raise Exception("Could not find Device Password ID attribute")
5419     # Remove Device Password ID value. This will fail Authenticator check, but
5420     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5421     # log.
5422     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5423     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5424     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5425     if "OK" not in res:
5426         raise Exception("EAPOL_RX failed")
5427     wps_fail_finish(hapd, dev[0], "msg=5")
5428
5429 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5430     """WPS and M2 without Registrar Nonce"""
5431     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5432     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5433     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5434     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5435     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5436     logger.debug("M2")
5437     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5438     if ev is None:
5439         raise Exception("Timeout on EAPOL-TX")
5440     hapd.request("SET ext_eapol_frame_io 0")
5441     dev[0].request("SET ext_eapol_frame_io 0")
5442     msg = ev.split(' ')[2]
5443     if msg[96:104] != '10390010':
5444         raise Exception("Could not find Registrar Nonce attribute")
5445     # Remove Registrar Nonce. This will fail Authenticator check, but
5446     # allows the code path in wps_process_registrar_nonce() to be checked from
5447     # the debug log.
5448     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5449     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5450     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5451     if "OK" not in res:
5452         raise Exception("EAPOL_RX failed")
5453     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5454     if ev is None:
5455         raise Exception("Disconnect event not seen")
5456     dev[0].request("WPS_CANCEL")
5457     dev[0].flush_scan_cache()
5458
5459 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5460     """WPS and M2 without Enrollee Nonce"""
5461     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5462     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5463     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5464     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5465     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5466     logger.debug("M2")
5467     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5468     if ev is None:
5469         raise Exception("Timeout on EAPOL-TX")
5470     hapd.request("SET ext_eapol_frame_io 0")
5471     dev[0].request("SET ext_eapol_frame_io 0")
5472     msg = ev.split(' ')[2]
5473     if msg[56:64] != '101a0010':
5474         raise Exception("Could not find enrollee Nonce attribute")
5475     # Remove Enrollee Nonce. This will fail Authenticator check, but
5476     # allows the code path in wps_process_enrollee_nonce() to be checked from
5477     # the debug log.
5478     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5479     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5480     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5481     if "OK" not in res:
5482         raise Exception("EAPOL_RX failed")
5483     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5484     if ev is None:
5485         raise Exception("Disconnect event not seen")
5486     dev[0].request("WPS_CANCEL")
5487     dev[0].flush_scan_cache()
5488
5489 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5490     """WPS and M2 without UUID-R"""
5491     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5492     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5493     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5494     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5495     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5496     logger.debug("M2")
5497     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5498     if ev is None:
5499         raise Exception("Timeout on EAPOL-TX")
5500     hapd.request("SET ext_eapol_frame_io 0")
5501     dev[0].request("SET ext_eapol_frame_io 0")
5502     msg = ev.split(' ')[2]
5503     if msg[136:144] != '10480010':
5504         raise Exception("Could not find enrollee Nonce attribute")
5505     # Remove UUID-R. This will fail Authenticator check, but allows the code
5506     # path in wps_process_uuid_r() to be checked from the debug log.
5507     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5508     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5509     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5510     if "OK" not in res:
5511         raise Exception("EAPOL_RX failed")
5512     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5513     if ev is None:
5514         raise Exception("Disconnect event not seen")
5515     dev[0].request("WPS_CANCEL")
5516     dev[0].flush_scan_cache()
5517
5518 def test_ap_wps_m2_invalid(dev, apdev):
5519     """WPS and M2 parsing failure"""
5520     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5521     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5522     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5523     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5524     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5525     logger.debug("M2")
5526     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5527     if ev is None:
5528         raise Exception("Timeout on EAPOL-TX")
5529     hapd.request("SET ext_eapol_frame_io 0")
5530     dev[0].request("SET ext_eapol_frame_io 0")
5531     msg = ev.split(' ')[2]
5532     if msg[136:144] != '10480010':
5533         raise Exception("Could not find enrollee Nonce attribute")
5534     # Remove UUID-R. This will fail Authenticator check, but allows the code
5535     # path in wps_process_uuid_r() to be checked from the debug log.
5536     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5537     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5538     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5539     if "OK" not in res:
5540         raise Exception("EAPOL_RX failed")
5541     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5542     if ev is None:
5543         raise Exception("Disconnect event not seen")
5544     dev[0].request("WPS_CANCEL")
5545     dev[0].flush_scan_cache()
5546
5547 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5548     """WPS and M2 without Message Type"""
5549     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5550     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5551     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5552     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5553     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5554     logger.debug("M2")
5555     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5556     if ev is None:
5557         raise Exception("Timeout on EAPOL-TX")
5558     hapd.request("SET ext_eapol_frame_io 0")
5559     dev[0].request("SET ext_eapol_frame_io 0")
5560     msg = ev.split(' ')[2]
5561     if msg[46:54] != '10220001':
5562         raise Exception("Could not find Message Type attribute")
5563     # Remove Message Type. This will fail Authenticator check, but allows the
5564     # code path in wps_process_wsc_msg() to be checked from the debug log.
5565     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5566     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5567     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5568     if "OK" not in res:
5569         raise Exception("EAPOL_RX failed")
5570     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5571     if ev is None:
5572         raise Exception("Disconnect event not seen")
5573     dev[0].request("WPS_CANCEL")
5574     dev[0].flush_scan_cache()
5575
5576 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5577     """WPS and M2 but unknown Message Type"""
5578     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5579     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5580     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5581     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5582     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5583     logger.debug("M2")
5584     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5585     if ev is None:
5586         raise Exception("Timeout on EAPOL-TX")
5587     hapd.request("SET ext_eapol_frame_io 0")
5588     dev[0].request("SET ext_eapol_frame_io 0")
5589     msg = ev.split(' ')[2]
5590     if msg[46:54] != '10220001':
5591         raise Exception("Could not find Message Type attribute")
5592     # Replace Message Type value. This will be rejected.
5593     msg = msg[0:54] + "00" + msg[56:]
5594     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5595     if "OK" not in res:
5596         raise Exception("EAPOL_RX failed")
5597     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5598     if ev is None:
5599         raise Exception("Disconnect event not seen")
5600     dev[0].request("WPS_CANCEL")
5601     dev[0].flush_scan_cache()
5602
5603 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5604     """WPS and M2 but unknown opcode"""
5605     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5606     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5607     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5608     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5609     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5610     logger.debug("M2")
5611     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5612     if ev is None:
5613         raise Exception("Timeout on EAPOL-TX")
5614     hapd.request("SET ext_eapol_frame_io 0")
5615     dev[0].request("SET ext_eapol_frame_io 0")
5616     msg = ev.split(' ')[2]
5617     # Replace opcode. This will be discarded in EAP-WSC processing.
5618     msg = msg[0:32] + "00" + msg[34:]
5619     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5620     if "OK" not in res:
5621         raise Exception("EAPOL_RX failed")
5622     dev[0].request("WPS_CANCEL")
5623     dev[0].wait_disconnected()
5624     dev[0].flush_scan_cache()
5625
5626 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5627     """WPS and M2 but unknown opcode (WSC_Start)"""
5628     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5629     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5630     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5631     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5632     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5633     logger.debug("M2")
5634     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5635     if ev is None:
5636         raise Exception("Timeout on EAPOL-TX")
5637     hapd.request("SET ext_eapol_frame_io 0")
5638     dev[0].request("SET ext_eapol_frame_io 0")
5639     msg = ev.split(' ')[2]
5640     # Replace opcode. This will be discarded in EAP-WSC processing.
5641     msg = msg[0:32] + "01" + msg[34:]
5642     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5643     if "OK" not in res:
5644         raise Exception("EAPOL_RX failed")
5645     dev[0].request("WPS_CANCEL")
5646     dev[0].wait_disconnected()
5647     dev[0].flush_scan_cache()
5648
5649 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5650     """WPS and M2 but unknown opcode (WSC_Done)"""
5651     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5652     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5653     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5654     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5655     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5656     logger.debug("M2")
5657     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5658     if ev is None:
5659         raise Exception("Timeout on EAPOL-TX")
5660     hapd.request("SET ext_eapol_frame_io 0")
5661     dev[0].request("SET ext_eapol_frame_io 0")
5662     msg = ev.split(' ')[2]
5663     # Replace opcode. This will be discarded in WPS Enrollee processing.
5664     msg = msg[0:32] + "05" + msg[34:]
5665     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5666     if "OK" not in res:
5667         raise Exception("EAPOL_RX failed")
5668     dev[0].request("WPS_CANCEL")
5669     dev[0].wait_disconnected()
5670     dev[0].flush_scan_cache()
5671
5672 def wps_m2_but_other(dev, apdev, title, msgtype):
5673     addr,bssid,hapd = wps_start_ext(apdev, dev)
5674     wps_ext_eap_identity_req(dev, hapd, bssid)
5675     wps_ext_eap_identity_resp(hapd, dev, addr)
5676     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5677     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5678     logger.debug(title)
5679     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5680     if ev is None:
5681         raise Exception("Timeout on EAPOL-TX")
5682     hapd.request("SET ext_eapol_frame_io 0")
5683     dev.request("SET ext_eapol_frame_io 0")
5684     msg = ev.split(' ')[2]
5685     if msg[46:54] != '10220001':
5686         raise Exception("Could not find Message Type attribute")
5687     # Replace Message Type value. This will be rejected.
5688     msg = msg[0:54] + msgtype + msg[56:]
5689     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5690     if "OK" not in res:
5691         raise Exception("EAPOL_RX failed")
5692     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5693     if ev is None:
5694         raise Exception("WPS-FAIL event not seen")
5695     dev.request("WPS_CANCEL")
5696     dev.wait_disconnected()
5697
5698 def wps_m4_but_other(dev, apdev, title, msgtype):
5699     addr,bssid,hapd = wps_start_ext(apdev, dev)
5700     wps_ext_eap_identity_req(dev, hapd, bssid)
5701     wps_ext_eap_identity_resp(hapd, dev, addr)
5702     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5703     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5704     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5705     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5706     logger.debug(title)
5707     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5708     if ev is None:
5709         raise Exception("Timeout on EAPOL-TX")
5710     hapd.request("SET ext_eapol_frame_io 0")
5711     dev.request("SET ext_eapol_frame_io 0")
5712     msg = ev.split(' ')[2]
5713     if msg[46:54] != '10220001':
5714         raise Exception("Could not find Message Type attribute")
5715     # Replace Message Type value. This will be rejected.
5716     msg = msg[0:54] + msgtype + msg[56:]
5717     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5718     if "OK" not in res:
5719         raise Exception("EAPOL_RX failed")
5720     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5721     if ev is None:
5722         raise Exception("WPS-FAIL event not seen")
5723     dev.request("WPS_CANCEL")
5724     dev.wait_disconnected()
5725
5726 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5727     """WPS and M2 but Message Type M4"""
5728     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5729
5730 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5731     """WPS and M2 but Message Type M6"""
5732     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5733
5734 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5735     """WPS and M2 but Message Type M8"""
5736     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5737
5738 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5739     """WPS and M4 but Message Type M2"""
5740     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5741
5742 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5743     """WPS and M4 but Message Type M2D"""
5744     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5745
5746 def test_ap_wps_config_methods(dev, apdev):
5747     """WPS configuration method parsing"""
5748     ssid = "test-wps-conf"
5749     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5750                "wpa_passphrase": "12345678", "wpa": "2",
5751                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5752                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5753     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5754     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5755                "wpa_passphrase": "12345678", "wpa": "2",
5756                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5757                "config_methods": "display push_button" }
5758     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
5759
5760 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5761     """WPS UPnP SetSelectedRegistrar protocol testing"""
5762     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5763     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5764
5765     location = ssdp_get_location(ap_uuid)
5766     urls = upnp_get_urls(location)
5767     eventurl = urlparse.urlparse(urls['event_sub_url'])
5768     ctrlurl = urlparse.urlparse(urls['control_url'])
5769     url = urlparse.urlparse(location)
5770     conn = httplib.HTTPConnection(url.netloc)
5771
5772     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5773         def handle(self):
5774             data = self.rfile.readline().strip()
5775             logger.debug(data)
5776             self.wfile.write(gen_wps_event())
5777
5778     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5779     server.timeout = 1
5780
5781     headers = { "callback": '<http://127.0.0.1:12345/event>',
5782                 "NT": "upnp:event",
5783                 "timeout": "Second-1234" }
5784     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5785     resp = conn.getresponse()
5786     if resp.status != 200:
5787         raise Exception("Unexpected HTTP response: %d" % resp.status)
5788     sid = resp.getheader("sid")
5789     logger.debug("Subscription SID " + sid)
5790     server.handle_request()
5791
5792     tests = [ (500, "10"),
5793               (200, "104a000110" + "1041000101" + "101200020000" +
5794                "105300023148" +
5795                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5796                "10480010362db47ba53a519188fb5458b986b2e4"),
5797               (200, "104a000110" + "1041000100" + "101200020000" +
5798                "105300020000"),
5799               (200, "104a000110" + "1041000100"),
5800               (200, "104a000110") ]
5801     for status,test in tests:
5802         tlvs = binascii.unhexlify(test)
5803         newmsg = base64.b64encode(tlvs)
5804         msg = '<?xml version="1.0"?>\n'
5805         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5806         msg += '<s:Body>'
5807         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5808         msg += '<NewMessage>'
5809         msg += newmsg
5810         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5811         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5812         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5813         conn.request("POST", ctrlurl.path, msg, headers)
5814         resp = conn.getresponse()
5815         if resp.status != status:
5816             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5817
5818 def test_ap_wps_adv_oom(dev, apdev):
5819     """WPS AP and advertisement OOM"""
5820     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5821     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5822
5823     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5824         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5825                           no_recv=True)
5826         time.sleep(0.2)
5827
5828     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5829         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5830                           no_recv=True)
5831         time.sleep(0.2)
5832
5833     with alloc_fail(hapd, 1,
5834                     "next_advertisement;advertisement_state_machine_stop"):
5835         hapd.disable()
5836
5837     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5838         if "FAIL" not in hapd.request("ENABLE"):
5839             raise Exception("ENABLE succeeded during OOM")
5840
5841 def test_wps_config_methods(dev):
5842     """WPS config method update"""
5843     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5844     wpas.interface_add("wlan5")
5845     if "OK" not in wpas.request("SET config_methods display label"):
5846         raise Exception("Failed to set config_methods")
5847     if wpas.request("GET config_methods").strip() != "display label":
5848         raise Exception("config_methods were not updated")
5849     if "OK" not in wpas.request("SET config_methods "):
5850         raise Exception("Failed to clear config_methods")
5851     if wpas.request("GET config_methods").strip() != "":
5852         raise Exception("config_methods were not cleared")
5853
5854 WPS_VENDOR_ID_WFA = 14122
5855 WPS_VENDOR_TYPE = 1
5856
5857 # EAP-WSC Op-Code values
5858 WSC_Start = 0x01
5859 WSC_ACK = 0x02
5860 WSC_NACK = 0x03
5861 WSC_MSG = 0x04
5862 WSC_Done = 0x05
5863 WSC_FRAG_ACK = 0x06
5864
5865 ATTR_AP_CHANNEL = 0x1001
5866 ATTR_ASSOC_STATE = 0x1002
5867 ATTR_AUTH_TYPE = 0x1003
5868 ATTR_AUTH_TYPE_FLAGS = 0x1004
5869 ATTR_AUTHENTICATOR = 0x1005
5870 ATTR_CONFIG_METHODS = 0x1008
5871 ATTR_CONFIG_ERROR = 0x1009
5872 ATTR_CONFIRM_URL4 = 0x100a
5873 ATTR_CONFIRM_URL6 = 0x100b
5874 ATTR_CONN_TYPE = 0x100c
5875 ATTR_CONN_TYPE_FLAGS = 0x100d
5876 ATTR_CRED = 0x100e
5877 ATTR_ENCR_TYPE = 0x100f
5878 ATTR_ENCR_TYPE_FLAGS = 0x1010
5879 ATTR_DEV_NAME = 0x1011
5880 ATTR_DEV_PASSWORD_ID = 0x1012
5881 ATTR_E_HASH1 = 0x1014
5882 ATTR_E_HASH2 = 0x1015
5883 ATTR_E_SNONCE1 = 0x1016
5884 ATTR_E_SNONCE2 = 0x1017
5885 ATTR_ENCR_SETTINGS = 0x1018
5886 ATTR_ENROLLEE_NONCE = 0x101a
5887 ATTR_FEATURE_ID = 0x101b
5888 ATTR_IDENTITY = 0x101c
5889 ATTR_IDENTITY_PROOF = 0x101d
5890 ATTR_KEY_WRAP_AUTH = 0x101e
5891 ATTR_KEY_ID = 0x101f
5892 ATTR_MAC_ADDR = 0x1020
5893 ATTR_MANUFACTURER = 0x1021
5894 ATTR_MSG_TYPE = 0x1022
5895 ATTR_MODEL_NAME = 0x1023
5896 ATTR_MODEL_NUMBER = 0x1024
5897 ATTR_NETWORK_INDEX = 0x1026
5898 ATTR_NETWORK_KEY = 0x1027
5899 ATTR_NETWORK_KEY_INDEX = 0x1028
5900 ATTR_NEW_DEVICE_NAME = 0x1029
5901 ATTR_NEW_PASSWORD = 0x102a
5902 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5903 ATTR_OS_VERSION = 0x102d
5904 ATTR_POWER_LEVEL = 0x102f
5905 ATTR_PSK_CURRENT = 0x1030
5906 ATTR_PSK_MAX = 0x1031
5907 ATTR_PUBLIC_KEY = 0x1032
5908 ATTR_RADIO_ENABLE = 0x1033
5909 ATTR_REBOOT = 0x1034
5910 ATTR_REGISTRAR_CURRENT = 0x1035
5911 ATTR_REGISTRAR_ESTABLISHED = 0x1036
5912 ATTR_REGISTRAR_LIST = 0x1037
5913 ATTR_REGISTRAR_MAX = 0x1038
5914 ATTR_REGISTRAR_NONCE = 0x1039
5915 ATTR_REQUEST_TYPE = 0x103a
5916 ATTR_RESPONSE_TYPE = 0x103b
5917 ATTR_RF_BANDS = 0x103c
5918 ATTR_R_HASH1 = 0x103d
5919 ATTR_R_HASH2 = 0x103e
5920 ATTR_R_SNONCE1 = 0x103f
5921 ATTR_R_SNONCE2 = 0x1040
5922 ATTR_SELECTED_REGISTRAR = 0x1041
5923 ATTR_SERIAL_NUMBER = 0x1042
5924 ATTR_WPS_STATE = 0x1044
5925 ATTR_SSID = 0x1045
5926 ATTR_TOTAL_NETWORKS = 0x1046
5927 ATTR_UUID_E = 0x1047
5928 ATTR_UUID_R = 0x1048
5929 ATTR_VENDOR_EXT = 0x1049
5930 ATTR_VERSION = 0x104a
5931 ATTR_X509_CERT_REQ = 0x104b
5932 ATTR_X509_CERT = 0x104c
5933 ATTR_EAP_IDENTITY = 0x104d
5934 ATTR_MSG_COUNTER = 0x104e
5935 ATTR_PUBKEY_HASH = 0x104f
5936 ATTR_REKEY_KEY = 0x1050
5937 ATTR_KEY_LIFETIME = 0x1051
5938 ATTR_PERMITTED_CFG_METHODS = 0x1052
5939 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
5940 ATTR_PRIMARY_DEV_TYPE = 0x1054
5941 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
5942 ATTR_PORTABLE_DEV = 0x1056
5943 ATTR_AP_SETUP_LOCKED = 0x1057
5944 ATTR_APPLICATION_EXT = 0x1058
5945 ATTR_EAP_TYPE = 0x1059
5946 ATTR_IV = 0x1060
5947 ATTR_KEY_PROVIDED_AUTO = 0x1061
5948 ATTR_802_1X_ENABLED = 0x1062
5949 ATTR_APPSESSIONKEY = 0x1063
5950 ATTR_WEPTRANSMITKEY = 0x1064
5951 ATTR_REQUESTED_DEV_TYPE = 0x106a
5952
5953 # Message Type
5954 WPS_Beacon = 0x01
5955 WPS_ProbeRequest = 0x02
5956 WPS_ProbeResponse = 0x03
5957 WPS_M1 = 0x04
5958 WPS_M2 = 0x05
5959 WPS_M2D = 0x06
5960 WPS_M3 = 0x07
5961 WPS_M4 = 0x08
5962 WPS_M5 = 0x09
5963 WPS_M6 = 0x0a
5964 WPS_M7 = 0x0b
5965 WPS_M8 = 0x0c
5966 WPS_WSC_ACK = 0x0d
5967 WPS_WSC_NACK = 0x0e
5968 WPS_WSC_DONE = 0x0f
5969
5970 def get_wsc_msg(dev):
5971     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5972     if ev is None:
5973         raise Exception("Timeout on EAPOL-TX")
5974     data = binascii.unhexlify(ev.split(' ')[2])
5975     msg = {}
5976
5977     # Parse EAPOL header
5978     if len(data) < 4:
5979         raise Exception("No room for EAPOL header")
5980     version,type,length = struct.unpack('>BBH', data[0:4])
5981     msg['eapol_version'] = version
5982     msg['eapol_type'] = type
5983     msg['eapol_length'] = length
5984     data = data[4:]
5985     if length != len(data):
5986         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
5987     if type != 0:
5988         raise Exception("Unexpected EAPOL header type: %d" % type)
5989
5990     # Parse EAP header
5991     if len(data) < 4:
5992         raise Exception("No room for EAP header")
5993     code,identifier,length = struct.unpack('>BBH', data[0:4])
5994     msg['eap_code'] = code
5995     msg['eap_identifier'] = identifier
5996     msg['eap_length'] = length
5997     data = data[4:]
5998     if msg['eapol_length'] != msg['eap_length']:
5999         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
6000
6001     # Parse EAP expanded header
6002     if len(data) < 1:
6003         raise Exception("No EAP type included")
6004     msg['eap_type'], = struct.unpack('B', data[0])
6005     data = data[1:]
6006
6007     if msg['eap_type'] == 254:
6008         if len(data) < 3 + 4:
6009             raise Exception("Truncated EAP expanded header")
6010         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
6011         data = data[7:]
6012     else:
6013         raise Exception("Unexpected EAP type")
6014
6015     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
6016         raise Exception("Unexpected Vendor-Id")
6017     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
6018         raise Exception("Unexpected Vendor-Type")
6019
6020     # Parse EAP-WSC header
6021     if len(data) < 2:
6022         raise Exception("Truncated EAP-WSC header")
6023     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
6024     data = data[2:]
6025
6026     # Parse WSC attributes
6027     msg['raw_attrs'] = data
6028     attrs = {}
6029     while len(data) > 0:
6030         if len(data) < 4:
6031             raise Exception("Truncated attribute header")
6032         attr,length = struct.unpack('>HH', data[0:4])
6033         data = data[4:]
6034         if length > len(data):
6035             raise Exception("Truncated attribute 0x%04x" % attr)
6036         attrs[attr] = data[0:length]
6037         data = data[length:]
6038     msg['wsc_attrs'] = attrs
6039
6040     if ATTR_MSG_TYPE in attrs:
6041         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
6042
6043     return msg
6044
6045 def recv_wsc_msg(dev, opcode, msg_type):
6046     msg = get_wsc_msg(dev)
6047     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
6048         raise Exception("Unexpected Op-Code/MsgType")
6049     return msg, msg['wsc_attrs'], msg['raw_attrs']
6050
6051 def build_wsc_attr(attr, payload):
6052     return struct.pack('>HH', attr, len(payload)) + payload
6053
6054 def build_attr_msg_type(msg_type):
6055     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
6056
6057 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
6058     length = 4 + 8 + 2 + len(payload)
6059     # EAPOL header
6060     msg = struct.pack('>BBH', 2, 0, length)
6061     # EAP header
6062     msg += struct.pack('>BBH', eap_code, eap_id, length)
6063     # EAP expanded header for EAP-WSC
6064     msg += struct.pack('B', 254)
6065     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
6066     msg += struct.pack('>L', WPS_VENDOR_TYPE)
6067     # EAP-WSC header
6068     msg += struct.pack('BB', opcode, 0)
6069     # WSC attributes
6070     msg += payload
6071     return msg
6072
6073 def build_eap_success(eap_id):
6074     length = 4
6075     # EAPOL header
6076     msg = struct.pack('>BBH', 2, 0, length)
6077     # EAP header
6078     msg += struct.pack('>BBH', 3, eap_id, length)
6079     return msg
6080
6081 def build_eap_failure(eap_id):
6082     length = 4
6083     # EAPOL header
6084     msg = struct.pack('>BBH', 2, 0, length)
6085     # EAP header
6086     msg += struct.pack('>BBH', 4, eap_id, length)
6087     return msg
6088
6089 def send_wsc_msg(dev, src, msg):
6090     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
6091     if "OK" not in res:
6092         raise Exception("EAPOL_RX failed")
6093
6094 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
6095 group_5_generator = 2
6096
6097 def wsc_kdf(key, label, bits):
6098     result = ''
6099     i = 1
6100     while len(result) * 8 < bits:
6101         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
6102         m = hmac.new(key, data, hashlib.sha256)
6103         result += m.digest()
6104         i += 1
6105     return result[0:bits / 8]
6106
6107 def wsc_keys(kdk):
6108     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
6109     authkey = keys[0:32]
6110     keywrapkey = keys[32:48]
6111     emsk = keys[48:80]
6112     return authkey,keywrapkey,emsk
6113
6114 def wsc_dev_pw_half_psk(authkey, dev_pw):
6115     m = hmac.new(authkey, dev_pw, hashlib.sha256)
6116     return m.digest()[0:16]
6117
6118 def wsc_dev_pw_psk(authkey, dev_pw):
6119     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
6120     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
6121     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
6122     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
6123     return psk1,psk2
6124
6125 def build_attr_authenticator(authkey, prev_msg, curr_msg):
6126     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
6127     auth = m.digest()[0:8]
6128     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
6129
6130 def build_attr_encr_settings(authkey, keywrapkey, data):
6131     m = hmac.new(authkey, data, hashlib.sha256)
6132     kwa = m.digest()[0:8]
6133     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6134     iv = 16*'\x99'
6135     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6136     pad_len = 16 - len(data) % 16
6137     ps = pad_len * struct.pack('B', pad_len)
6138     data += ps
6139     wrapped = aes.encrypt(data)
6140     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6141
6142 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
6143     if len(data) < 32 or len(data) % 16 != 0:
6144         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
6145     iv = data[0:16]
6146     encr = data[16:]
6147     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6148     decrypted = aes.decrypt(encr)
6149     pad_len, = struct.unpack('B', decrypted[-1])
6150     if pad_len > len(decrypted):
6151         raise Exception("Invalid padding in Encrypted Settings")
6152     for i in range(-pad_len, -1):
6153         if decrypted[i] != decrypted[-1]:
6154             raise Exception("Invalid PS value in Encrypted Settings")
6155     
6156     decrypted = decrypted[0:len(decrypted) - pad_len]
6157     if len(decrypted) < 12:
6158         raise Exception("Truncated Encrypted Settings plaintext")
6159     kwa = decrypted[-12:]
6160     attr,length = struct.unpack(">HH", kwa[0:4])
6161     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6162         raise Exception("Invalid KWA header")
6163     kwa = kwa[4:]
6164     decrypted = decrypted[0:len(decrypted) - 12]
6165
6166     m = hmac.new(authkey, decrypted, hashlib.sha256)
6167     calc_kwa = m.digest()[0:8]
6168     if kwa != calc_kwa:
6169         raise Exception("KWA mismatch")
6170
6171     return decrypted
6172
6173 def zeropad_str(val, pad_len):
6174     while len(val) < pad_len * 2:
6175         val = '0' + val
6176     return val
6177
6178 def wsc_dh_init():
6179     # For now, use a hardcoded private key. In theory, this is supposed to be
6180     # randomly selected.
6181     own_private = 0x123456789
6182     own_public = pow(group_5_generator, own_private, group_5_prime)
6183     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6184     return own_private, pk
6185
6186 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6187     peer_public = long(binascii.hexlify(peer_pk), 16)
6188     if peer_public < 2 or peer_public >= group_5_prime:
6189         raise Exception("Invalid peer public key")
6190     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6191         raise Exception("Unexpected Legendre symbol for peer public key")
6192
6193     shared_secret = pow(peer_public, own_private, group_5_prime)
6194     ss = zeropad_str(format(shared_secret, "02x"), 192)
6195     logger.debug("DH shared secret: " + ss)
6196
6197     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6198     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6199
6200     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6201     kdk = m.digest()
6202     logger.debug("KDK: " + binascii.hexlify(kdk))
6203     authkey,keywrapkey,emsk = wsc_keys(kdk)
6204     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6205     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6206     logger.debug("EMSK: " + binascii.hexlify(emsk))
6207     return authkey,keywrapkey
6208
6209 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6210     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6211     logger.debug("PSK1: " + binascii.hexlify(psk1))
6212     logger.debug("PSK2: " + binascii.hexlify(psk2))
6213
6214     # Note: Secret values are supposed to be random, but hardcoded values are
6215     # fine for testing.
6216     s1 = 16*'\x77'
6217     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6218     hash1 = m.digest()
6219     logger.debug("Hash1: " + binascii.hexlify(hash1))
6220
6221     s2 = 16*'\x88'
6222     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6223     hash2 = m.digest()
6224     logger.debug("Hash2: " + binascii.hexlify(hash2))
6225     return s1,s2,hash1,hash2
6226
6227 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6228              manufacturer='', model_name='', config_methods='\x00\x00'):
6229     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6230     attrs += build_attr_msg_type(WPS_M1)
6231     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6232     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6233     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6234     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6235     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6236     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6237     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6238     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6239     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6240     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6241     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6242     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6243     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6244     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6245     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6246     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6247     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6248     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6249     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6250     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6251     m1 = build_eap_wsc(2, eap_id, attrs)
6252     return m1, attrs
6253
6254 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6255              dev_pw_id='\x00\x00', eap_code=1):
6256     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6257     attrs += build_attr_msg_type(WPS_M2)
6258     if e_nonce:
6259         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6260     if r_nonce:
6261         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6262     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6263     if r_pk:
6264         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6265     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6266     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6267     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6268     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6269     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6270     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6271     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6272     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6273     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6274     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6275     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6276     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6277     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6278     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6279     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6280     attrs += build_attr_authenticator(authkey, m1, attrs)
6281     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6282     return m2, attrs
6283
6284 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6285     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6286     attrs += build_attr_msg_type(WPS_M2D)
6287     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6288     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6289     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6290     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6291     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6292     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6293     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6294     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6295     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6296     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6297     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6298     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6299     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6300     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6301     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6302     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6303     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6304     if dev_pw_id:
6305         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6306     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6307     return m2d, attrs
6308
6309 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6310     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6311     if msg_type is not None:
6312         attrs += build_attr_msg_type(msg_type)
6313     if e_nonce:
6314         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6315     if r_nonce:
6316         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6317     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6318     return msg, attrs
6319
6320 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6321                msg_type=WPS_WSC_NACK, eap_code=1):
6322     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6323     if msg_type is not None:
6324         attrs += build_attr_msg_type(msg_type)
6325     if e_nonce:
6326         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6327     if r_nonce:
6328         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6329     if config_error:
6330         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6331     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6332     return msg, attrs
6333
6334 def test_wps_ext(dev, apdev):
6335     """WPS against external implementation"""
6336     pin = "12345670"
6337     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6338     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6339     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6340
6341     logger.debug("Receive WSC/Start from AP")
6342     msg = get_wsc_msg(hapd)
6343     if msg['wsc_opcode'] != WSC_Start:
6344         raise Exception("Unexpected Op-Code for WSC/Start")
6345     wsc_start_id = msg['eap_identifier']
6346
6347     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6348     uuid_e = 16*'\x11'
6349     e_nonce = 16*'\x22'
6350     own_private, e_pk = wsc_dh_init()
6351
6352     logger.debug("Send M1 to AP")
6353     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6354                                 e_nonce, e_pk)
6355     send_wsc_msg(hapd, addr, m1)
6356
6357     logger.debug("Receive M2 from AP")
6358     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6359
6360     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6361                                     mac_addr, e_nonce,
6362                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6363     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6364                                                 m2_attrs[ATTR_PUBLIC_KEY])
6365
6366     logger.debug("Send M3 to AP")
6367     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6368     attrs += build_attr_msg_type(WPS_M3)
6369     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6370                             m2_attrs[ATTR_REGISTRAR_NONCE])
6371     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6372     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6373     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6374     raw_m3_attrs = attrs
6375     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6376     send_wsc_msg(hapd, addr, m3)
6377
6378     logger.debug("Receive M4 from AP")
6379     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6380
6381     logger.debug("Send M5 to AP")
6382     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6383     attrs += build_attr_msg_type(WPS_M5)
6384     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6385                             m2_attrs[ATTR_REGISTRAR_NONCE])
6386     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6387     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6388     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6389     raw_m5_attrs = attrs
6390     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6391     send_wsc_msg(hapd, addr, m5)
6392
6393     logger.debug("Receive M6 from AP")
6394     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6395
6396     logger.debug("Send M7 to AP")
6397     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6398     attrs += build_attr_msg_type(WPS_M7)
6399     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6400                             m2_attrs[ATTR_REGISTRAR_NONCE])
6401     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6402     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6403     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6404     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6405     raw_m7_attrs = attrs
6406     send_wsc_msg(hapd, addr, m7)
6407
6408     logger.debug("Receive M8 from AP")
6409     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6410     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6411                                          m8_attrs[ATTR_ENCR_SETTINGS])
6412     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6413
6414     logger.debug("Prepare WSC_Done")
6415     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6416     attrs += build_attr_msg_type(WPS_WSC_DONE)
6417     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6418     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6419                             m2_attrs[ATTR_REGISTRAR_NONCE])
6420     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6421     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6422     # AP disconnects.
6423
6424     uuid_r = 16*'\x33'
6425     r_nonce = 16*'\x44'
6426
6427     eap_id = wsc_start_id
6428     logger.debug("Send WSC/Start to STA")
6429     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6430     send_wsc_msg(dev[0], bssid, wsc_start)
6431     eap_id = (eap_id + 1) % 256
6432
6433     logger.debug("Receive M1 from STA")
6434     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6435
6436     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6437                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6438                                     r_nonce)
6439     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6440                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6441
6442     logger.debug("Send M2 to STA")
6443     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6444                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6445                                 r_nonce, uuid_r, e_pk)
6446     send_wsc_msg(dev[0], bssid, m2)
6447     eap_id = (eap_id + 1) % 256
6448
6449     logger.debug("Receive M3 from STA")
6450     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6451
6452     logger.debug("Send M4 to STA")
6453     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6454     attrs += build_attr_msg_type(WPS_M4)
6455     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6456     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6457     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6458     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6459     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6460     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6461     raw_m4_attrs = attrs
6462     m4 = build_eap_wsc(1, eap_id, attrs)
6463     send_wsc_msg(dev[0], bssid, m4)
6464     eap_id = (eap_id + 1) % 256
6465
6466     logger.debug("Receive M5 from STA")
6467     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6468
6469     logger.debug("Send M6 to STA")
6470     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6471     attrs += build_attr_msg_type(WPS_M6)
6472     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6473                             m1_attrs[ATTR_ENROLLEE_NONCE])
6474     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6475     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6476     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6477     raw_m6_attrs = attrs
6478     m6 = build_eap_wsc(1, eap_id, attrs)
6479     send_wsc_msg(dev[0], bssid, m6)
6480     eap_id = (eap_id + 1) % 256
6481
6482     logger.debug("Receive M7 from STA")
6483     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6484
6485     logger.debug("Send M8 to STA")
6486     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6487     attrs += build_attr_msg_type(WPS_M8)
6488     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6489                             m1_attrs[ATTR_ENROLLEE_NONCE])
6490     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6491     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6492     raw_m8_attrs = attrs
6493     m8 = build_eap_wsc(1, eap_id, attrs)
6494     send_wsc_msg(dev[0], bssid, m8)
6495     eap_id = (eap_id + 1) % 256
6496
6497     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6498     if ev is None:
6499         raise Exception("wpa_supplicant did not report credential")
6500
6501     logger.debug("Receive WSC_Done from STA")
6502     msg = get_wsc_msg(dev[0])
6503     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6504         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6505
6506     logger.debug("Send WSC_Done to AP")
6507     hapd.request("SET ext_eapol_frame_io 0")
6508     dev[0].request("SET ext_eapol_frame_io 0")
6509     send_wsc_msg(hapd, addr, wsc_done)
6510
6511     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6512     if ev is None:
6513         raise Exception("hostapd did not report WPS success")
6514
6515     dev[0].wait_connected()
6516
6517 def wps_start_kwa(dev, apdev):
6518     pin = "12345670"
6519     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6520     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6521     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6522     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6523
6524     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6525     uuid_r = 16*'\x33'
6526     r_nonce = 16*'\x44'
6527     own_private, e_pk = wsc_dh_init()
6528
6529     logger.debug("Receive M1 from STA")
6530     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6531     eap_id = (msg['eap_identifier'] + 1) % 256
6532
6533     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6534                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6535                                     r_nonce)
6536     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6537                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6538
6539     logger.debug("Send M2 to STA")
6540     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6541                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6542                                 r_nonce, uuid_r, e_pk)
6543     send_wsc_msg(dev[0], bssid, m2)
6544     eap_id = (eap_id + 1) % 256
6545
6546     logger.debug("Receive M3 from STA")
6547     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6548
6549     logger.debug("Send M4 to STA")
6550     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6551     attrs += build_attr_msg_type(WPS_M4)
6552     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6553     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6554     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6555
6556     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6557
6558 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6559     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6560     m4 = build_eap_wsc(1, eap_id, attrs)
6561     send_wsc_msg(dev[0], bssid, m4)
6562     eap_id = (eap_id + 1) % 256
6563
6564     logger.debug("Receive M5 from STA")
6565     msg = get_wsc_msg(dev[0])
6566     if msg['wsc_opcode'] != WSC_NACK:
6567         raise Exception("Unexpected message - expected WSC_Nack")
6568
6569     dev[0].request("WPS_CANCEL")
6570     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6571     dev[0].wait_disconnected()
6572
6573 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6574     """WPS and KWA error: No KWA attribute"""
6575     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6576     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6577     # Encrypted Settings without KWA
6578     iv = 16*'\x99'
6579     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6580     pad_len = 16 - len(data) % 16
6581     ps = pad_len * struct.pack('B', pad_len)
6582     data += ps
6583     wrapped = aes.encrypt(data)
6584     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6585     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6586
6587 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6588     """WPS and KWA error: Data after KWA"""
6589     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6590     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6591     # Encrypted Settings and data after KWA
6592     m = hmac.new(authkey, data, hashlib.sha256)
6593     kwa = m.digest()[0:8]
6594     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6595     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6596     iv = 16*'\x99'
6597     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6598     pad_len = 16 - len(data) % 16
6599     ps = pad_len * struct.pack('B', pad_len)
6600     data += ps
6601     wrapped = aes.encrypt(data)
6602     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6603     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6604
6605 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6606     """WPS and KWA error: KWA mismatch"""
6607     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6608     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6609     # Encrypted Settings and KWA with incorrect value
6610     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6611     iv = 16*'\x99'
6612     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6613     pad_len = 16 - len(data) % 16
6614     ps = pad_len * struct.pack('B', pad_len)
6615     data += ps
6616     wrapped = aes.encrypt(data)
6617     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6618     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6619
6620 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6621     pin = "12345670"
6622     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6623     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6624     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6625     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6626
6627     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6628     uuid_r = 16*'\x33'
6629     r_nonce = 16*'\x44'
6630     own_private, e_pk = wsc_dh_init()
6631
6632     logger.debug("Receive M1 from STA")
6633     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6634     eap_id = (msg['eap_identifier'] + 1) % 256
6635
6636     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6637                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6638                                     r_nonce)
6639     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6640                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6641
6642     logger.debug("Send M2 to STA")
6643     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6644                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6645                                 r_nonce, uuid_r, e_pk)
6646     send_wsc_msg(dev[0], bssid, m2)
6647     eap_id = (eap_id + 1) % 256
6648
6649     logger.debug("Receive M3 from STA")
6650     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6651
6652     logger.debug("Send M4 to STA")
6653     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6654     attrs += build_attr_msg_type(WPS_M4)
6655     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6656     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6657     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6658     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6659     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6660     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6661     raw_m4_attrs = attrs
6662     m4 = build_eap_wsc(1, eap_id, attrs)
6663     send_wsc_msg(dev[0], bssid, m4)
6664     eap_id = (eap_id + 1) % 256
6665
6666     logger.debug("Receive M5 from STA")
6667     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6668
6669     logger.debug("Send M6 to STA")
6670     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6671     attrs += build_attr_msg_type(WPS_M6)
6672     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6673                             m1_attrs[ATTR_ENROLLEE_NONCE])
6674     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6675     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6676     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6677     raw_m6_attrs = attrs
6678     m6 = build_eap_wsc(1, eap_id, attrs)
6679     send_wsc_msg(dev[0], bssid, m6)
6680     eap_id = (eap_id + 1) % 256
6681
6682     logger.debug("Receive M7 from STA")
6683     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6684
6685     logger.debug("Send M8 to STA")
6686     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6687     attrs += build_attr_msg_type(WPS_M8)
6688     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6689                             m1_attrs[ATTR_ENROLLEE_NONCE])
6690     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6691     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6692     raw_m8_attrs = attrs
6693     m8 = build_eap_wsc(1, eap_id, attrs)
6694     send_wsc_msg(dev[0], bssid, m8)
6695     eap_id = (eap_id + 1) % 256
6696
6697     if no_connect:
6698         logger.debug("Receive WSC_Done from STA")
6699         msg = get_wsc_msg(dev[0])
6700         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6701             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6702
6703         hapd.request("SET ext_eapol_frame_io 0")
6704         dev[0].request("SET ext_eapol_frame_io 0")
6705
6706         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6707
6708         dev[0].wait_disconnected()
6709         dev[0].request("REMOVE_NETWORK all")
6710     elif connect:
6711         logger.debug("Receive WSC_Done from STA")
6712         msg = get_wsc_msg(dev[0])
6713         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6714             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6715
6716         hapd.request("SET ext_eapol_frame_io 0")
6717         dev[0].request("SET ext_eapol_frame_io 0")
6718
6719         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6720
6721         dev[0].wait_connected()
6722     else:
6723         # Verify STA NACK's the credential
6724         msg = get_wsc_msg(dev[0])
6725         if msg['wsc_opcode'] != WSC_NACK:
6726             raise Exception("Unexpected message - expected WSC_Nack")
6727         dev[0].request("WPS_CANCEL")
6728         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6729         dev[0].wait_disconnected()
6730
6731 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6732                encr_type='\x00\x08', nw_key="12345678",
6733                mac_addr='\x00\x00\x00\x00\x00\x00'):
6734     attrs = ''
6735     if nw_idx is not None:
6736         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6737     if ssid is not None:
6738         attrs += build_wsc_attr(ATTR_SSID, ssid)
6739     if auth_type is not None:
6740         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6741     if encr_type is not None:
6742         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6743     if nw_key is not None:
6744         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6745     if mac_addr is not None:
6746         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6747     return build_wsc_attr(ATTR_CRED, attrs)
6748
6749 def test_wps_ext_cred_proto_success(dev, apdev):
6750     """WPS and Credential: success"""
6751     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6752     m8_cred = build_cred(mac_addr=mac_addr)
6753     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6754
6755 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6756     """WPS and Credential: MAC Address mismatch"""
6757     m8_cred = build_cred()
6758     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6759
6760 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6761     """WPS and Credential: zeropadded attributes"""
6762     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6763     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6764                          nw_key="12345678\x00")
6765     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6766
6767 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6768     """WPS and Credential: SSID missing"""
6769     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6770     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6771     wps_run_cred_proto(dev, apdev, m8_cred)
6772
6773 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6774     """WPS and Credential: Zero-length SSID"""
6775     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6776     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6777     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6778
6779 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6780     """WPS and Credential: Auth Type missing"""
6781     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6782     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6783     wps_run_cred_proto(dev, apdev, m8_cred)
6784
6785 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6786     """WPS and Credential: Encr Type missing"""
6787     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6788     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6789     wps_run_cred_proto(dev, apdev, m8_cred)
6790
6791 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6792     """WPS and Credential: Network Key missing"""
6793     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6794     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6795     wps_run_cred_proto(dev, apdev, m8_cred)
6796
6797 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6798     """WPS and Credential: Network Key missing (open)"""
6799     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6800     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6801                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6802     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6803
6804 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6805     """WPS and Credential: MAC Address missing"""
6806     m8_cred = build_cred(mac_addr=None)
6807     wps_run_cred_proto(dev, apdev, m8_cred)
6808
6809 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6810     """WPS and Credential: Invalid Encr Type"""
6811     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6812     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6813     wps_run_cred_proto(dev, apdev, m8_cred)
6814
6815 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6816     """WPS and Credential: Missing Credential"""
6817     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6818     m8_cred = ''
6819     wps_run_cred_proto(dev, apdev, m8_cred)
6820
6821 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6822     """WPS and no Public Key in M2"""
6823     pin = "12345670"
6824     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6825     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6826     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6827     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6828
6829     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6830     uuid_r = 16*'\x33'
6831     r_nonce = 16*'\x44'
6832     own_private, e_pk = wsc_dh_init()
6833
6834     logger.debug("Receive M1 from STA")
6835     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6836     eap_id = (msg['eap_identifier'] + 1) % 256
6837
6838     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6839                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6840                                     r_nonce)
6841     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6842                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6843
6844     logger.debug("Send M2 to STA")
6845     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6846                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6847                                 r_nonce, uuid_r, None)
6848     send_wsc_msg(dev[0], bssid, m2)
6849     eap_id = (eap_id + 1) % 256
6850
6851     # Verify STA NACK's the credential
6852     msg = get_wsc_msg(dev[0])
6853     if msg['wsc_opcode'] != WSC_NACK:
6854         raise Exception("Unexpected message - expected WSC_Nack")
6855     dev[0].request("WPS_CANCEL")
6856     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6857     dev[0].wait_disconnected()
6858
6859 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6860     """WPS and invalid Public Key in M2"""
6861     pin = "12345670"
6862     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6863     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6864     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6865     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6866
6867     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6868     uuid_r = 16*'\x33'
6869     r_nonce = 16*'\x44'
6870     own_private, e_pk = wsc_dh_init()
6871
6872     logger.debug("Receive M1 from STA")
6873     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6874     eap_id = (msg['eap_identifier'] + 1) % 256
6875
6876     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6877                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6878                                     r_nonce)
6879     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6880                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6881
6882     logger.debug("Send M2 to STA")
6883     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6884                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6885                                 r_nonce, uuid_r, 192*'\xff')
6886     send_wsc_msg(dev[0], bssid, m2)
6887     eap_id = (eap_id + 1) % 256
6888
6889     # Verify STA NACK's the credential
6890     msg = get_wsc_msg(dev[0])
6891     if msg['wsc_opcode'] != WSC_NACK:
6892         raise Exception("Unexpected message - expected WSC_Nack")
6893     dev[0].request("WPS_CANCEL")
6894     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6895     dev[0].wait_disconnected()
6896
6897 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6898     """WPS and Public Key OOM in M2"""
6899     pin = "12345670"
6900     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6901     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6902     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6903     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6904
6905     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6906     uuid_r = 16*'\x33'
6907     r_nonce = 16*'\x44'
6908     own_private, e_pk = wsc_dh_init()
6909
6910     logger.debug("Receive M1 from STA")
6911     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6912     eap_id = (msg['eap_identifier'] + 1) % 256
6913
6914     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6915                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6916                                     r_nonce)
6917     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6918                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6919
6920     logger.debug("Send M2 to STA")
6921     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6922                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6923                                 r_nonce, uuid_r, e_pk)
6924     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
6925         send_wsc_msg(dev[0], bssid, m2)
6926         eap_id = (eap_id + 1) % 256
6927
6928         # Verify STA NACK's the credential
6929         msg = get_wsc_msg(dev[0])
6930         if msg['wsc_opcode'] != WSC_NACK:
6931             raise Exception("Unexpected message - expected WSC_Nack")
6932         dev[0].request("WPS_CANCEL")
6933         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6934         dev[0].wait_disconnected()
6935
6936 def test_wps_ext_proto_nack_m3(dev, apdev):
6937     """WPS and NACK M3"""
6938     pin = "12345670"
6939     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6940     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6941     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6942     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6943
6944     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6945     uuid_r = 16*'\x33'
6946     r_nonce = 16*'\x44'
6947     own_private, e_pk = wsc_dh_init()
6948
6949     logger.debug("Receive M1 from STA")
6950     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6951     eap_id = (msg['eap_identifier'] + 1) % 256
6952
6953     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6954                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6955                                     r_nonce)
6956     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6957                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6958
6959     logger.debug("Send M2 to STA")
6960     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6961                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6962                                 r_nonce, uuid_r, e_pk)
6963     send_wsc_msg(dev[0], bssid, m2)
6964     eap_id = (eap_id + 1) % 256
6965
6966     logger.debug("Receive M3 from STA")
6967     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6968
6969     logger.debug("Send NACK to STA")
6970     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6971                             r_nonce, config_error='\x01\x23')
6972     send_wsc_msg(dev[0], bssid, msg)
6973     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6974     if ev is None:
6975         raise Exception("Failure not reported")
6976     if "msg=7 config_error=291" not in ev:
6977         raise Exception("Unexpected failure reason: " + ev)
6978
6979 def test_wps_ext_proto_nack_m5(dev, apdev):
6980     """WPS and NACK M5"""
6981     pin = "12345670"
6982     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6983     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6984     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6985     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6986
6987     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6988     uuid_r = 16*'\x33'
6989     r_nonce = 16*'\x44'
6990     own_private, e_pk = wsc_dh_init()
6991
6992     logger.debug("Receive M1 from STA")
6993     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6994     eap_id = (msg['eap_identifier'] + 1) % 256
6995
6996     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6997                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6998                                     r_nonce)
6999     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7000                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7001
7002     logger.debug("Send M2 to STA")
7003     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7004                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7005                                 r_nonce, uuid_r, e_pk)
7006     send_wsc_msg(dev[0], bssid, m2)
7007     eap_id = (eap_id + 1) % 256
7008
7009     logger.debug("Receive M3 from STA")
7010     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7011
7012     logger.debug("Send M4 to STA")
7013     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7014     attrs += build_attr_msg_type(WPS_M4)
7015     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7016     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7017     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7018     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7019     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7020     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7021     raw_m4_attrs = attrs
7022     m4 = build_eap_wsc(1, eap_id, attrs)
7023     send_wsc_msg(dev[0], bssid, m4)
7024     eap_id = (eap_id + 1) % 256
7025
7026     logger.debug("Receive M5 from STA")
7027     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7028
7029     logger.debug("Send NACK to STA")
7030     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
7031                             r_nonce, config_error='\x01\x24')
7032     send_wsc_msg(dev[0], bssid, msg)
7033     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
7034     if ev is None:
7035         raise Exception("Failure not reported")
7036     if "msg=9 config_error=292" not in ev:
7037         raise Exception("Unexpected failure reason: " + ev)
7038
7039 def wps_nack_m3(dev, apdev):
7040     pin = "00000000"
7041     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
7042     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7043     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7044     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7045
7046     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7047     uuid_r = 16*'\x33'
7048     r_nonce = 16*'\x44'
7049     own_private, e_pk = wsc_dh_init()
7050
7051     logger.debug("Receive M1 from STA")
7052     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7053     eap_id = (msg['eap_identifier'] + 1) % 256
7054
7055     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7056                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7057                                     r_nonce)
7058     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7059                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7060
7061     logger.debug("Send M2 to STA")
7062     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7063                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7064                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
7065     send_wsc_msg(dev[0], bssid, m2)
7066     eap_id = (eap_id + 1) % 256
7067
7068     logger.debug("Receive M3 from STA")
7069     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7070     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
7071
7072 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
7073     """WPS and NACK M3 missing Config Error"""
7074     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7075     logger.debug("Send NACK to STA")
7076     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
7077     send_wsc_msg(dev[0], bssid, msg)
7078     dev[0].request("WPS_CANCEL")
7079     dev[0].wait_disconnected()
7080     dev[0].flush_scan_cache()
7081
7082 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
7083     """WPS and NACK M3 missing E-Nonce"""
7084     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7085     logger.debug("Send NACK to STA")
7086     msg, attrs = build_nack(eap_id, None, r_nonce)
7087     send_wsc_msg(dev[0], bssid, msg)
7088     dev[0].request("WPS_CANCEL")
7089     dev[0].wait_disconnected()
7090     dev[0].flush_scan_cache()
7091
7092 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
7093     """WPS and NACK M3 E-Nonce mismatch"""
7094     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7095     logger.debug("Send NACK to STA")
7096     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
7097     send_wsc_msg(dev[0], bssid, msg)
7098     dev[0].request("WPS_CANCEL")
7099     dev[0].wait_disconnected()
7100     dev[0].flush_scan_cache()
7101
7102 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
7103     """WPS and NACK M3 missing R-Nonce"""
7104     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7105     logger.debug("Send NACK to STA")
7106     msg, attrs = build_nack(eap_id, e_nonce, None)
7107     send_wsc_msg(dev[0], bssid, msg)
7108     dev[0].request("WPS_CANCEL")
7109     dev[0].wait_disconnected()
7110     dev[0].flush_scan_cache()
7111
7112 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
7113     """WPS and NACK M3 R-Nonce mismatch"""
7114     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7115     logger.debug("Send NACK to STA")
7116     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
7117     send_wsc_msg(dev[0], bssid, msg)
7118     dev[0].request("WPS_CANCEL")
7119     dev[0].wait_disconnected()
7120     dev[0].flush_scan_cache()
7121
7122 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
7123     """WPS and NACK M3 no Message Type"""
7124     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7125     logger.debug("Send NACK to STA")
7126     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
7127     send_wsc_msg(dev[0], bssid, msg)
7128     dev[0].request("WPS_CANCEL")
7129     dev[0].wait_disconnected()
7130     dev[0].flush_scan_cache()
7131
7132 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
7133     """WPS and NACK M3 invalid Message Type"""
7134     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7135     logger.debug("Send NACK to STA")
7136     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
7137     send_wsc_msg(dev[0], bssid, msg)
7138     dev[0].request("WPS_CANCEL")
7139     dev[0].wait_disconnected()
7140     dev[0].flush_scan_cache()
7141
7142 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
7143     """WPS and NACK M3 invalid attribute"""
7144     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7145     logger.debug("Send NACK to STA")
7146     attrs = '\x10\x10\x00'
7147     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
7148     send_wsc_msg(dev[0], bssid, msg)
7149     dev[0].request("WPS_CANCEL")
7150     dev[0].wait_disconnected()
7151     dev[0].flush_scan_cache()
7152
7153 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
7154     """WPS and ACK M3 missing E-Nonce"""
7155     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7156     logger.debug("Send NACK to STA")
7157     msg, attrs = build_ack(eap_id, None, r_nonce)
7158     send_wsc_msg(dev[0], bssid, msg)
7159     dev[0].request("WPS_CANCEL")
7160     dev[0].wait_disconnected()
7161     dev[0].flush_scan_cache()
7162
7163 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7164     """WPS and ACK M3 E-Nonce mismatch"""
7165     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7166     logger.debug("Send NACK to STA")
7167     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7168     send_wsc_msg(dev[0], bssid, msg)
7169     dev[0].request("WPS_CANCEL")
7170     dev[0].wait_disconnected()
7171     dev[0].flush_scan_cache()
7172
7173 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7174     """WPS and ACK M3 missing R-Nonce"""
7175     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7176     logger.debug("Send NACK to STA")
7177     msg, attrs = build_ack(eap_id, e_nonce, None)
7178     send_wsc_msg(dev[0], bssid, msg)
7179     dev[0].request("WPS_CANCEL")
7180     dev[0].wait_disconnected()
7181     dev[0].flush_scan_cache()
7182
7183 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7184     """WPS and ACK M3 R-Nonce mismatch"""
7185     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7186     logger.debug("Send NACK to STA")
7187     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7188     send_wsc_msg(dev[0], bssid, msg)
7189     dev[0].request("WPS_CANCEL")
7190     dev[0].wait_disconnected()
7191     dev[0].flush_scan_cache()
7192
7193 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7194     """WPS and ACK M3 no Message Type"""
7195     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7196     logger.debug("Send NACK to STA")
7197     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7198     send_wsc_msg(dev[0], bssid, msg)
7199     dev[0].request("WPS_CANCEL")
7200     dev[0].wait_disconnected()
7201     dev[0].flush_scan_cache()
7202
7203 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7204     """WPS and ACK M3 invalid Message Type"""
7205     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7206     logger.debug("Send NACK to STA")
7207     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7208     send_wsc_msg(dev[0], bssid, msg)
7209     dev[0].request("WPS_CANCEL")
7210     dev[0].wait_disconnected()
7211     dev[0].flush_scan_cache()
7212
7213 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7214     """WPS and ACK M3 invalid attribute"""
7215     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7216     logger.debug("Send ACK to STA")
7217     attrs = '\x10\x10\x00'
7218     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7219     send_wsc_msg(dev[0], bssid, msg)
7220     dev[0].request("WPS_CANCEL")
7221     dev[0].wait_disconnected()
7222     dev[0].flush_scan_cache()
7223
7224 def test_wps_ext_proto_ack_m3(dev, apdev):
7225     """WPS and ACK M3"""
7226     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7227     logger.debug("Send ACK to STA")
7228     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7229     send_wsc_msg(dev[0], bssid, msg)
7230     dev[0].request("WPS_CANCEL")
7231     dev[0].wait_disconnected()
7232     dev[0].flush_scan_cache()
7233
7234 def wps_to_m3_helper(dev, apdev):
7235     pin = "12345670"
7236     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7237     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7238     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7239     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7240
7241     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7242     uuid_r = 16*'\x33'
7243     r_nonce = 16*'\x44'
7244     own_private, e_pk = wsc_dh_init()
7245
7246     logger.debug("Receive M1 from STA")
7247     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7248     eap_id = (msg['eap_identifier'] + 1) % 256
7249
7250     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7251                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7252                                     r_nonce)
7253     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7254                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7255
7256     logger.debug("Send M2 to STA")
7257     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7258                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7259                                 r_nonce, uuid_r, e_pk)
7260     send_wsc_msg(dev[0], bssid, m2)
7261     eap_id = (eap_id + 1) % 256
7262
7263     logger.debug("Receive M3 from STA")
7264     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7265     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7266
7267 def wps_to_m3(dev, apdev):
7268     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)
7269     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7270
7271 def wps_to_m5(dev, apdev):
7272     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)
7273
7274     logger.debug("Send M4 to STA")
7275     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7276     attrs += build_attr_msg_type(WPS_M4)
7277     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7278     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7279     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7280     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7281     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7282     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7283     raw_m4_attrs = attrs
7284     m4 = build_eap_wsc(1, eap_id, attrs)
7285     send_wsc_msg(dev[0], bssid, m4)
7286     eap_id = (eap_id + 1) % 256
7287
7288     logger.debug("Receive M5 from STA")
7289     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7290
7291     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7292
7293 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7294     """WPS and no R-Hash1 in M4"""
7295     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7296
7297     logger.debug("Send M4 to STA")
7298     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7299     attrs += build_attr_msg_type(WPS_M4)
7300     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7301     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7302     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7303     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7304     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7305     attrs += build_attr_authenticator(authkey, m3, attrs)
7306     m4 = build_eap_wsc(1, eap_id, attrs)
7307     send_wsc_msg(dev[0], bssid, m4)
7308     eap_id = (eap_id + 1) % 256
7309
7310     logger.debug("Receive M5 (NACK) from STA")
7311     msg = get_wsc_msg(dev[0])
7312     if msg['wsc_opcode'] != WSC_NACK:
7313         raise Exception("Unexpected message - expected WSC_Nack")
7314
7315     dev[0].request("WPS_CANCEL")
7316     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7317     dev[0].wait_disconnected()
7318
7319 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7320     """WPS and no R-Hash2 in M4"""
7321     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7322
7323     logger.debug("Send M4 to STA")
7324     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7325     attrs += build_attr_msg_type(WPS_M4)
7326     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7327     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7328     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7329     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7330     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7331     attrs += build_attr_authenticator(authkey, m3, attrs)
7332     m4 = build_eap_wsc(1, eap_id, attrs)
7333     send_wsc_msg(dev[0], bssid, m4)
7334     eap_id = (eap_id + 1) % 256
7335
7336     logger.debug("Receive M5 (NACK) from STA")
7337     msg = get_wsc_msg(dev[0])
7338     if msg['wsc_opcode'] != WSC_NACK:
7339         raise Exception("Unexpected message - expected WSC_Nack")
7340
7341     dev[0].request("WPS_CANCEL")
7342     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7343     dev[0].wait_disconnected()
7344
7345 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7346     """WPS and no R-SNonce1 in M4"""
7347     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7348
7349     logger.debug("Send M4 to STA")
7350     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7351     attrs += build_attr_msg_type(WPS_M4)
7352     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7353     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7354     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7355     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7356     data = ''
7357     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7358     attrs += build_attr_authenticator(authkey, m3, attrs)
7359     m4 = build_eap_wsc(1, eap_id, attrs)
7360     send_wsc_msg(dev[0], bssid, m4)
7361     eap_id = (eap_id + 1) % 256
7362
7363     logger.debug("Receive M5 (NACK) from STA")
7364     msg = get_wsc_msg(dev[0])
7365     if msg['wsc_opcode'] != WSC_NACK:
7366         raise Exception("Unexpected message - expected WSC_Nack")
7367
7368     dev[0].request("WPS_CANCEL")
7369     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7370     dev[0].wait_disconnected()
7371
7372 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7373     """WPS and invalid pad string in M4"""
7374     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7375
7376     logger.debug("Send M4 to STA")
7377     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7378     attrs += build_attr_msg_type(WPS_M4)
7379     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7380     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7381     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7382     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7383
7384     m = hmac.new(authkey, data, hashlib.sha256)
7385     kwa = m.digest()[0:8]
7386     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7387     iv = 16*'\x99'
7388     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7389     pad_len = 16 - len(data) % 16
7390     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7391     data += ps
7392     wrapped = aes.encrypt(data)
7393     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7394
7395     attrs += build_attr_authenticator(authkey, m3, attrs)
7396     m4 = build_eap_wsc(1, eap_id, attrs)
7397     send_wsc_msg(dev[0], bssid, m4)
7398     eap_id = (eap_id + 1) % 256
7399
7400     logger.debug("Receive M5 (NACK) from STA")
7401     msg = get_wsc_msg(dev[0])
7402     if msg['wsc_opcode'] != WSC_NACK:
7403         raise Exception("Unexpected message - expected WSC_Nack")
7404
7405     dev[0].request("WPS_CANCEL")
7406     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7407     dev[0].wait_disconnected()
7408
7409 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7410     """WPS and invalid pad value in M4"""
7411     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7412
7413     logger.debug("Send M4 to STA")
7414     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7415     attrs += build_attr_msg_type(WPS_M4)
7416     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7417     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7418     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7419     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7420
7421     m = hmac.new(authkey, data, hashlib.sha256)
7422     kwa = m.digest()[0:8]
7423     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7424     iv = 16*'\x99'
7425     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7426     pad_len = 16 - len(data) % 16
7427     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7428     data += ps
7429     wrapped = aes.encrypt(data)
7430     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7431
7432     attrs += build_attr_authenticator(authkey, m3, attrs)
7433     m4 = build_eap_wsc(1, eap_id, attrs)
7434     send_wsc_msg(dev[0], bssid, m4)
7435     eap_id = (eap_id + 1) % 256
7436
7437     logger.debug("Receive M5 (NACK) from STA")
7438     msg = get_wsc_msg(dev[0])
7439     if msg['wsc_opcode'] != WSC_NACK:
7440         raise Exception("Unexpected message - expected WSC_Nack")
7441
7442     dev[0].request("WPS_CANCEL")
7443     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7444     dev[0].wait_disconnected()
7445
7446 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7447     """WPS and no Encr Settings in M4"""
7448     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7449
7450     logger.debug("Send M4 to STA")
7451     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7452     attrs += build_attr_msg_type(WPS_M4)
7453     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7454     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7455     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7456     attrs += build_attr_authenticator(authkey, m3, attrs)
7457     m4 = build_eap_wsc(1, eap_id, attrs)
7458     send_wsc_msg(dev[0], bssid, m4)
7459     eap_id = (eap_id + 1) % 256
7460
7461     logger.debug("Receive M5 (NACK) from STA")
7462     msg = get_wsc_msg(dev[0])
7463     if msg['wsc_opcode'] != WSC_NACK:
7464         raise Exception("Unexpected message - expected WSC_Nack")
7465
7466     dev[0].request("WPS_CANCEL")
7467     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7468     dev[0].wait_disconnected()
7469
7470 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7471     """WPS and no R-SNonce2 in M6"""
7472     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7473
7474     logger.debug("Send M6 to STA")
7475     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7476     attrs += build_attr_msg_type(WPS_M6)
7477     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7478     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7479     data = ''
7480     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7481     attrs += build_attr_authenticator(authkey, m5, attrs)
7482     m6 = build_eap_wsc(1, eap_id, attrs)
7483     send_wsc_msg(dev[0], bssid, m6)
7484     eap_id = (eap_id + 1) % 256
7485
7486     logger.debug("Receive M7 (NACK) from STA")
7487     msg = get_wsc_msg(dev[0])
7488     if msg['wsc_opcode'] != WSC_NACK:
7489         raise Exception("Unexpected message - expected WSC_Nack")
7490
7491     dev[0].request("WPS_CANCEL")
7492     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7493     dev[0].wait_disconnected()
7494
7495 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7496     """WPS and no Encr Settings in M6"""
7497     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7498
7499     logger.debug("Send M6 to STA")
7500     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7501     attrs += build_attr_msg_type(WPS_M6)
7502     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7503     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7504     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7505     attrs += build_attr_authenticator(authkey, m5, attrs)
7506     m6 = build_eap_wsc(1, eap_id, attrs)
7507     send_wsc_msg(dev[0], bssid, m6)
7508     eap_id = (eap_id + 1) % 256
7509
7510     logger.debug("Receive M7 (NACK) from STA")
7511     msg = get_wsc_msg(dev[0])
7512     if msg['wsc_opcode'] != WSC_NACK:
7513         raise Exception("Unexpected message - expected WSC_Nack")
7514
7515     dev[0].request("WPS_CANCEL")
7516     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7517     dev[0].wait_disconnected()
7518
7519 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7520     """WPS and no Encr Settings in M6"""
7521     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7522
7523     logger.debug("Send M6 to STA")
7524     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7525     attrs += build_attr_msg_type(WPS_M6)
7526     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7527     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7528     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7529     attrs += build_attr_authenticator(authkey, m5, attrs)
7530     raw_m6_attrs = attrs
7531     m6 = build_eap_wsc(1, eap_id, attrs)
7532     send_wsc_msg(dev[0], bssid, m6)
7533     eap_id = (eap_id + 1) % 256
7534
7535     logger.debug("Receive M7 from STA")
7536     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7537
7538     logger.debug("Send M8 to STA")
7539     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7540     attrs += build_attr_msg_type(WPS_M8)
7541     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7542     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7543     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7544     raw_m8_attrs = attrs
7545     m8 = build_eap_wsc(1, eap_id, attrs)
7546     send_wsc_msg(dev[0], bssid, m8)
7547
7548     logger.debug("Receive WSC_Done (NACK) from STA")
7549     msg = get_wsc_msg(dev[0])
7550     if msg['wsc_opcode'] != WSC_NACK:
7551         raise Exception("Unexpected message - expected WSC_Nack")
7552
7553     dev[0].request("WPS_CANCEL")
7554     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7555     dev[0].wait_disconnected()
7556
7557 def wps_start_ext_reg(apdev, dev):
7558     addr = dev.own_addr()
7559     bssid = apdev['bssid']
7560     ssid = "test-wps-conf"
7561     appin = "12345670"
7562     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7563                "wpa_passphrase": "12345678", "wpa": "2",
7564                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7565                "ap_pin": appin }
7566     hapd = hostapd.add_ap(apdev['ifname'], params)
7567
7568     dev.scan_for_bss(bssid, freq="2412")
7569     hapd.request("SET ext_eapol_frame_io 1")
7570     dev.request("SET ext_eapol_frame_io 1")
7571
7572     dev.request("WPS_REG " + bssid + " " + appin)
7573
7574     return addr,bssid,hapd
7575
7576 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7577     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7578     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7579     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7580
7581     logger.debug("Receive M1 from AP")
7582     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7583     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7584     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7585     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7586
7587     appin = '12345670'
7588     uuid_r = 16*'\x33'
7589     r_nonce = 16*'\x44'
7590     own_private, r_pk = wsc_dh_init()
7591     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7592                                     r_nonce)
7593     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7594
7595     logger.debug("Send M2 to AP")
7596     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7597                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7598     send_wsc_msg(hapd, addr, m2)
7599
7600     logger.debug("Receive M3 from AP")
7601     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7602
7603     logger.debug("Send M4 to AP")
7604     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7605     attrs += build_attr_msg_type(WPS_M4)
7606     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7607     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7608     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7609     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7610     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7611     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7612     raw_m4_attrs = attrs
7613     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7614     send_wsc_msg(hapd, addr, m4)
7615
7616     logger.debug("Receive M5 from AP")
7617     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7618
7619     logger.debug("Send M6 to STA")
7620     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7621     attrs += build_attr_msg_type(WPS_M6)
7622     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7623     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7624     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7625     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7626     raw_m6_attrs = attrs
7627     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7628     send_wsc_msg(hapd, addr, m6)
7629
7630     logger.debug("Receive M7 from AP")
7631     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7632
7633     logger.debug("Send M8 to STA")
7634     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7635     attrs += build_attr_msg_type(WPS_M8)
7636     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7637     if ap_settings:
7638         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7639     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7640     raw_m8_attrs = attrs
7641     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7642     send_wsc_msg(hapd, addr, m8)
7643
7644     if success:
7645         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7646         if ev is None:
7647             raise Exception("New AP settings not reported")
7648         logger.debug("Receive WSC_Done from AP")
7649         msg = get_wsc_msg(hapd)
7650         if msg['wsc_opcode'] != WSC_Done:
7651             raise Exception("Unexpected message - expected WSC_Done")
7652
7653         logger.debug("Send WSC_ACK to AP")
7654         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7655                               eap_code=2)
7656         send_wsc_msg(hapd, addr, ack)
7657         dev[0].wait_disconnected()
7658     else:
7659         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7660         if ev is None:
7661             raise Exception("WPS failure not reported")
7662         logger.debug("Receive WSC_NACK from AP")
7663         msg = get_wsc_msg(hapd)
7664         if msg['wsc_opcode'] != WSC_NACK:
7665             raise Exception("Unexpected message - expected WSC_NACK")
7666
7667         logger.debug("Send WSC_NACK to AP")
7668         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7669                                 eap_code=2)
7670         send_wsc_msg(hapd, addr, nack)
7671         dev[0].wait_disconnected()
7672
7673 def test_wps_ext_ap_settings_success(dev, apdev):
7674     """WPS and AP Settings: success"""
7675     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7676     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7677     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7678     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7679     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7680     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7681     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7682
7683 def test_wps_ext_ap_settings_missing(dev, apdev):
7684     """WPS and AP Settings: missing"""
7685     wps_run_ap_settings_proto(dev, apdev, None, False)
7686
7687 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7688     """WPS and AP Settings: MAC Address mismatch"""
7689     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7690     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7691     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7692     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7693     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7694     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7695     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7696
7697 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7698     """WPS and AP Settings: missing MAC Address"""
7699     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7700     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7701     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7702     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7703     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7704     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7705
7706 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7707     """WPS and AP Settings: reject Encr Type"""
7708     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7709     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7710     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7711     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7712     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7713     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7714     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7715
7716 def test_wps_ext_ap_settings_m2d(dev, apdev):
7717     """WPS and AP Settings: M2D"""
7718     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7719     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7720     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7721
7722     logger.debug("Receive M1 from AP")
7723     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7724     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7725
7726     r_nonce = 16*'\x44'
7727     uuid_r = 16*'\x33'
7728
7729     logger.debug("Send M2D to AP")
7730     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7731                                    e_nonce, r_nonce, uuid_r,
7732                                    dev_pw_id='\x00\x00', eap_code=2)
7733     send_wsc_msg(hapd, addr, m2d)
7734
7735     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7736     if ev is None:
7737         raise Exception("M2D not reported")
7738
7739     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7740
7741 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7742     logger.debug("Receive WSC_NACK from AP")
7743     msg = get_wsc_msg(hapd)
7744     if msg['wsc_opcode'] != WSC_NACK:
7745         raise Exception("Unexpected message - expected WSC_NACK")
7746
7747     logger.debug("Send WSC_NACK to AP")
7748     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7749                             eap_code=2)
7750     send_wsc_msg(hapd, dev.own_addr(), nack)
7751     dev.wait_disconnected()
7752
7753 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7754     """WPS proto: M3 missing E-Hash1"""
7755     pin = "12345670"
7756     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7757     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7758     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7759
7760     logger.debug("Receive WSC/Start from AP")
7761     msg = get_wsc_msg(hapd)
7762     if msg['wsc_opcode'] != WSC_Start:
7763         raise Exception("Unexpected Op-Code for WSC/Start")
7764
7765     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7766     uuid_e = 16*'\x11'
7767     e_nonce = 16*'\x22'
7768     own_private, e_pk = wsc_dh_init()
7769
7770     logger.debug("Send M1 to AP")
7771     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7772                                 e_nonce, e_pk)
7773     send_wsc_msg(hapd, addr, m1)
7774
7775     logger.debug("Receive M2 from AP")
7776     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7777     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7778     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7779
7780     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7781                                     r_nonce)
7782     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7783
7784     logger.debug("Send M3 to AP")
7785     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7786     attrs += build_attr_msg_type(WPS_M3)
7787     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7788     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7789     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7790     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7791     raw_m3_attrs = attrs
7792     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7793     send_wsc_msg(hapd, addr, m3)
7794
7795     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7796
7797 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7798     """WPS proto: M3 missing E-Hash2"""
7799     pin = "12345670"
7800     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7801     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7802     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7803
7804     logger.debug("Receive WSC/Start from AP")
7805     msg = get_wsc_msg(hapd)
7806     if msg['wsc_opcode'] != WSC_Start:
7807         raise Exception("Unexpected Op-Code for WSC/Start")
7808
7809     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7810     uuid_e = 16*'\x11'
7811     e_nonce = 16*'\x22'
7812     own_private, e_pk = wsc_dh_init()
7813
7814     logger.debug("Send M1 to AP")
7815     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7816                                 e_nonce, e_pk)
7817     send_wsc_msg(hapd, addr, m1)
7818
7819     logger.debug("Receive M2 from AP")
7820     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7821     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7822     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7823
7824     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7825                                     r_nonce)
7826     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7827
7828     logger.debug("Send M3 to AP")
7829     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7830     attrs += build_attr_msg_type(WPS_M3)
7831     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7832     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7833     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7834     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7835     raw_m3_attrs = attrs
7836     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7837     send_wsc_msg(hapd, addr, m3)
7838
7839     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7840
7841 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7842     """WPS proto: M5 missing E-SNonce1"""
7843     pin = "12345670"
7844     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7845     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7846     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7847
7848     logger.debug("Receive WSC/Start from AP")
7849     msg = get_wsc_msg(hapd)
7850     if msg['wsc_opcode'] != WSC_Start:
7851         raise Exception("Unexpected Op-Code for WSC/Start")
7852
7853     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7854     uuid_e = 16*'\x11'
7855     e_nonce = 16*'\x22'
7856     own_private, e_pk = wsc_dh_init()
7857
7858     logger.debug("Send M1 to AP")
7859     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7860                                 e_nonce, e_pk)
7861     send_wsc_msg(hapd, addr, m1)
7862
7863     logger.debug("Receive M2 from AP")
7864     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7865     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7866     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7867
7868     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7869                                     r_nonce)
7870     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7871
7872     logger.debug("Send M3 to AP")
7873     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7874     attrs += build_attr_msg_type(WPS_M3)
7875     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7876     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7877     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7878     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7879     raw_m3_attrs = attrs
7880     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7881     send_wsc_msg(hapd, addr, m3)
7882
7883     logger.debug("Receive M4 from AP")
7884     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7885
7886     logger.debug("Send M5 to AP")
7887     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7888     attrs += build_attr_msg_type(WPS_M5)
7889     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7890     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7891     data = ''
7892     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7893     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7894     raw_m5_attrs = attrs
7895     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7896     send_wsc_msg(hapd, addr, m5)
7897
7898     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7899
7900 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7901     """WPS proto: M5 E-SNonce1 mismatch"""
7902     pin = "12345670"
7903     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7904     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7905     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7906
7907     logger.debug("Receive WSC/Start from AP")
7908     msg = get_wsc_msg(hapd)
7909     if msg['wsc_opcode'] != WSC_Start:
7910         raise Exception("Unexpected Op-Code for WSC/Start")
7911
7912     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7913     uuid_e = 16*'\x11'
7914     e_nonce = 16*'\x22'
7915     own_private, e_pk = wsc_dh_init()
7916
7917     logger.debug("Send M1 to AP")
7918     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7919                                 e_nonce, e_pk)
7920     send_wsc_msg(hapd, addr, m1)
7921
7922     logger.debug("Receive M2 from AP")
7923     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7924     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7925     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7926
7927     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7928                                     r_nonce)
7929     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7930
7931     logger.debug("Send M3 to AP")
7932     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7933     attrs += build_attr_msg_type(WPS_M3)
7934     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7935     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7936     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7937     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7938     raw_m3_attrs = attrs
7939     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7940     send_wsc_msg(hapd, addr, m3)
7941
7942     logger.debug("Receive M4 from AP")
7943     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7944
7945     logger.debug("Send M5 to AP")
7946     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7947     attrs += build_attr_msg_type(WPS_M5)
7948     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7949     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
7950     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7951     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7952     raw_m5_attrs = attrs
7953     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7954     send_wsc_msg(hapd, addr, m5)
7955
7956     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7957
7958 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
7959     """WPS proto: M7 missing E-SNonce2"""
7960     pin = "12345670"
7961     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7962     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7963     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7964
7965     logger.debug("Receive WSC/Start from AP")
7966     msg = get_wsc_msg(hapd)
7967     if msg['wsc_opcode'] != WSC_Start:
7968         raise Exception("Unexpected Op-Code for WSC/Start")
7969
7970     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7971     uuid_e = 16*'\x11'
7972     e_nonce = 16*'\x22'
7973     own_private, e_pk = wsc_dh_init()
7974
7975     logger.debug("Send M1 to AP")
7976     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7977                                 e_nonce, e_pk)
7978     send_wsc_msg(hapd, addr, m1)
7979
7980     logger.debug("Receive M2 from AP")
7981     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7982     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7983     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7984
7985     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7986                                     r_nonce)
7987     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7988
7989     logger.debug("Send M3 to AP")
7990     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7991     attrs += build_attr_msg_type(WPS_M3)
7992     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7993     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7994     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7995     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7996     raw_m3_attrs = attrs
7997     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7998     send_wsc_msg(hapd, addr, m3)
7999
8000     logger.debug("Receive M4 from AP")
8001     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8002
8003     logger.debug("Send M5 to AP")
8004     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8005     attrs += build_attr_msg_type(WPS_M5)
8006     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8007     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8008     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8009     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8010     raw_m5_attrs = attrs
8011     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8012     send_wsc_msg(hapd, addr, m5)
8013
8014     logger.debug("Receive M6 from AP")
8015     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8016
8017     logger.debug("Send M7 to AP")
8018     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8019     attrs += build_attr_msg_type(WPS_M7)
8020     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8021     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8022     data = ''
8023     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8024     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8025     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8026     raw_m7_attrs = attrs
8027     send_wsc_msg(hapd, addr, m7)
8028
8029     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8030
8031 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
8032     """WPS proto: M7 E-SNonce2 mismatch"""
8033     pin = "12345670"
8034     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8035     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8036     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8037
8038     logger.debug("Receive WSC/Start from AP")
8039     msg = get_wsc_msg(hapd)
8040     if msg['wsc_opcode'] != WSC_Start:
8041         raise Exception("Unexpected Op-Code for WSC/Start")
8042
8043     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8044     uuid_e = 16*'\x11'
8045     e_nonce = 16*'\x22'
8046     own_private, e_pk = wsc_dh_init()
8047
8048     logger.debug("Send M1 to AP")
8049     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8050                                 e_nonce, e_pk)
8051     send_wsc_msg(hapd, addr, m1)
8052
8053     logger.debug("Receive M2 from AP")
8054     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8055     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8056     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8057
8058     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8059                                     r_nonce)
8060     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8061
8062     logger.debug("Send M3 to AP")
8063     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8064     attrs += build_attr_msg_type(WPS_M3)
8065     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8066     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8067     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8068     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8069     raw_m3_attrs = attrs
8070     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8071     send_wsc_msg(hapd, addr, m3)
8072
8073     logger.debug("Receive M4 from AP")
8074     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8075
8076     logger.debug("Send M5 to AP")
8077     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8078     attrs += build_attr_msg_type(WPS_M5)
8079     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8080     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8081     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8082     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8083     raw_m5_attrs = attrs
8084     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8085     send_wsc_msg(hapd, addr, m5)
8086
8087     logger.debug("Receive M6 from AP")
8088     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8089
8090     logger.debug("Send M7 to AP")
8091     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8092     attrs += build_attr_msg_type(WPS_M7)
8093     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8094     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
8095     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8096     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8097     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8098     raw_m7_attrs = attrs
8099     send_wsc_msg(hapd, addr, m7)
8100
8101     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8102
8103 def test_wps_ext_m1_pubkey_oom(dev, apdev):
8104     """WPS proto: M1 PubKey OOM"""
8105     pin = "12345670"
8106     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8107     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8108     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8109
8110     logger.debug("Receive WSC/Start from AP")
8111     msg = get_wsc_msg(hapd)
8112     if msg['wsc_opcode'] != WSC_Start:
8113         raise Exception("Unexpected Op-Code for WSC/Start")
8114
8115     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8116     uuid_e = 16*'\x11'
8117     e_nonce = 16*'\x22'
8118     own_private, e_pk = wsc_dh_init()
8119
8120     logger.debug("Send M1 to AP")
8121     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
8122         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8123                                     e_nonce, e_pk)
8124         send_wsc_msg(hapd, addr, m1)
8125         wps_wait_eap_failure(hapd, dev[0])
8126
8127 def wps_wait_eap_failure(hapd, dev):
8128     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8129     if ev is None:
8130         raise Exception("EAP-Failure not reported")
8131     dev.wait_disconnected()
8132
8133 def test_wps_ext_m3_m1(dev, apdev):
8134     """WPS proto: M3 replaced with M1"""
8135     pin = "12345670"
8136     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8137     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8138     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8139
8140     logger.debug("Receive WSC/Start from AP")
8141     msg = get_wsc_msg(hapd)
8142     if msg['wsc_opcode'] != WSC_Start:
8143         raise Exception("Unexpected Op-Code for WSC/Start")
8144
8145     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8146     uuid_e = 16*'\x11'
8147     e_nonce = 16*'\x22'
8148     own_private, e_pk = wsc_dh_init()
8149
8150     logger.debug("Send M1 to AP")
8151     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8152                                 e_nonce, e_pk)
8153     send_wsc_msg(hapd, addr, m1)
8154
8155     logger.debug("Receive M2 from AP")
8156     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8157     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8158     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8159
8160     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8161                                     r_nonce)
8162     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8163
8164     logger.debug("Send M3(M1) to AP")
8165     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8166     attrs += build_attr_msg_type(WPS_M1)
8167     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8168     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8169     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8170     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8171     raw_m3_attrs = attrs
8172     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8173     send_wsc_msg(hapd, addr, m3)
8174
8175     wps_wait_eap_failure(hapd, dev[0])
8176
8177 def test_wps_ext_m5_m3(dev, apdev):
8178     """WPS proto: M5 replaced with M3"""
8179     pin = "12345670"
8180     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8181     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8182     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8183
8184     logger.debug("Receive WSC/Start from AP")
8185     msg = get_wsc_msg(hapd)
8186     if msg['wsc_opcode'] != WSC_Start:
8187         raise Exception("Unexpected Op-Code for WSC/Start")
8188
8189     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8190     uuid_e = 16*'\x11'
8191     e_nonce = 16*'\x22'
8192     own_private, e_pk = wsc_dh_init()
8193
8194     logger.debug("Send M1 to AP")
8195     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8196                                 e_nonce, e_pk)
8197     send_wsc_msg(hapd, addr, m1)
8198
8199     logger.debug("Receive M2 from AP")
8200     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8201     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8202     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8203
8204     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8205                                     r_nonce)
8206     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8207
8208     logger.debug("Send M3 to AP")
8209     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8210     attrs += build_attr_msg_type(WPS_M3)
8211     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8212     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8213     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8214     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8215     raw_m3_attrs = attrs
8216     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8217     send_wsc_msg(hapd, addr, m3)
8218
8219     logger.debug("Receive M4 from AP")
8220     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8221
8222     logger.debug("Send M5(M3) to AP")
8223     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8224     attrs += build_attr_msg_type(WPS_M3)
8225     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8226     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8227     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8228     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8229     raw_m5_attrs = attrs
8230     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8231     send_wsc_msg(hapd, addr, m5)
8232
8233     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8234
8235 def test_wps_ext_m3_m2(dev, apdev):
8236     """WPS proto: M3 replaced with M2"""
8237     pin = "12345670"
8238     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8239     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8240     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8241
8242     logger.debug("Receive WSC/Start from AP")
8243     msg = get_wsc_msg(hapd)
8244     if msg['wsc_opcode'] != WSC_Start:
8245         raise Exception("Unexpected Op-Code for WSC/Start")
8246
8247     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8248     uuid_e = 16*'\x11'
8249     e_nonce = 16*'\x22'
8250     own_private, e_pk = wsc_dh_init()
8251
8252     logger.debug("Send M1 to AP")
8253     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8254                                 e_nonce, e_pk)
8255     send_wsc_msg(hapd, addr, m1)
8256
8257     logger.debug("Receive M2 from AP")
8258     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8259     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8260     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8261
8262     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8263                                     r_nonce)
8264     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8265
8266     logger.debug("Send M3(M2) to AP")
8267     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8268     attrs += build_attr_msg_type(WPS_M2)
8269     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8270     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8271     raw_m3_attrs = attrs
8272     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8273     send_wsc_msg(hapd, addr, m3)
8274
8275     wps_wait_eap_failure(hapd, dev[0])
8276
8277 def test_wps_ext_m3_m5(dev, apdev):
8278     """WPS proto: M3 replaced with M5"""
8279     pin = "12345670"
8280     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8281     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8282     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8283
8284     logger.debug("Receive WSC/Start from AP")
8285     msg = get_wsc_msg(hapd)
8286     if msg['wsc_opcode'] != WSC_Start:
8287         raise Exception("Unexpected Op-Code for WSC/Start")
8288
8289     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8290     uuid_e = 16*'\x11'
8291     e_nonce = 16*'\x22'
8292     own_private, e_pk = wsc_dh_init()
8293
8294     logger.debug("Send M1 to AP")
8295     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8296                                 e_nonce, e_pk)
8297     send_wsc_msg(hapd, addr, m1)
8298
8299     logger.debug("Receive M2 from AP")
8300     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8301     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8302     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8303
8304     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8305                                     r_nonce)
8306     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8307
8308     logger.debug("Send M3(M5) to AP")
8309     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8310     attrs += build_attr_msg_type(WPS_M5)
8311     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8312     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8313     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8314     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8315     raw_m3_attrs = attrs
8316     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8317     send_wsc_msg(hapd, addr, m3)
8318
8319     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8320
8321 def test_wps_ext_m3_m7(dev, apdev):
8322     """WPS proto: M3 replaced with M7"""
8323     pin = "12345670"
8324     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8325     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8326     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8327
8328     logger.debug("Receive WSC/Start from AP")
8329     msg = get_wsc_msg(hapd)
8330     if msg['wsc_opcode'] != WSC_Start:
8331         raise Exception("Unexpected Op-Code for WSC/Start")
8332
8333     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8334     uuid_e = 16*'\x11'
8335     e_nonce = 16*'\x22'
8336     own_private, e_pk = wsc_dh_init()
8337
8338     logger.debug("Send M1 to AP")
8339     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8340                                 e_nonce, e_pk)
8341     send_wsc_msg(hapd, addr, m1)
8342
8343     logger.debug("Receive M2 from AP")
8344     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8345     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8346     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8347
8348     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8349                                     r_nonce)
8350     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8351
8352     logger.debug("Send M3(M7) to AP")
8353     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8354     attrs += build_attr_msg_type(WPS_M7)
8355     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8356     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8357     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8358     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8359     raw_m3_attrs = attrs
8360     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8361     send_wsc_msg(hapd, addr, m3)
8362
8363     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8364
8365 def test_wps_ext_m3_done(dev, apdev):
8366     """WPS proto: M3 replaced with WSC_Done"""
8367     pin = "12345670"
8368     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8369     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8370     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8371
8372     logger.debug("Receive WSC/Start from AP")
8373     msg = get_wsc_msg(hapd)
8374     if msg['wsc_opcode'] != WSC_Start:
8375         raise Exception("Unexpected Op-Code for WSC/Start")
8376
8377     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8378     uuid_e = 16*'\x11'
8379     e_nonce = 16*'\x22'
8380     own_private, e_pk = wsc_dh_init()
8381
8382     logger.debug("Send M1 to AP")
8383     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8384                                 e_nonce, e_pk)
8385     send_wsc_msg(hapd, addr, m1)
8386
8387     logger.debug("Receive M2 from AP")
8388     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8389     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8390     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8391
8392     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8393                                     r_nonce)
8394     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8395
8396     logger.debug("Send M3(WSC_Done) to AP")
8397     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8398     attrs += build_attr_msg_type(WPS_WSC_DONE)
8399     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8400     raw_m3_attrs = attrs
8401     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8402     send_wsc_msg(hapd, addr, m3)
8403
8404     wps_wait_eap_failure(hapd, dev[0])
8405
8406 def test_wps_ext_m2_nack_invalid(dev, apdev):
8407     """WPS proto: M2 followed by invalid NACK"""
8408     pin = "12345670"
8409     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8410     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8411     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8412
8413     logger.debug("Receive WSC/Start from AP")
8414     msg = get_wsc_msg(hapd)
8415     if msg['wsc_opcode'] != WSC_Start:
8416         raise Exception("Unexpected Op-Code for WSC/Start")
8417
8418     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8419     uuid_e = 16*'\x11'
8420     e_nonce = 16*'\x22'
8421     own_private, e_pk = wsc_dh_init()
8422
8423     logger.debug("Send M1 to AP")
8424     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8425                                 e_nonce, e_pk)
8426     send_wsc_msg(hapd, addr, m1)
8427
8428     logger.debug("Receive M2 from AP")
8429     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8430     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8431     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8432
8433     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8434                                     r_nonce)
8435     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8436
8437     logger.debug("Send WSC_NACK to AP")
8438     attrs = '\x10\x00\x00'
8439     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8440     send_wsc_msg(hapd, addr, nack)
8441
8442     wps_wait_eap_failure(hapd, dev[0])
8443
8444 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8445     """WPS proto: M2 followed by NACK without Msg Type"""
8446     pin = "12345670"
8447     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8448     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8449     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8450
8451     logger.debug("Receive WSC/Start from AP")
8452     msg = get_wsc_msg(hapd)
8453     if msg['wsc_opcode'] != WSC_Start:
8454         raise Exception("Unexpected Op-Code for WSC/Start")
8455
8456     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8457     uuid_e = 16*'\x11'
8458     e_nonce = 16*'\x22'
8459     own_private, e_pk = wsc_dh_init()
8460
8461     logger.debug("Send M1 to AP")
8462     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8463                                 e_nonce, e_pk)
8464     send_wsc_msg(hapd, addr, m1)
8465
8466     logger.debug("Receive M2 from AP")
8467     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8468     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8469     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8470
8471     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8472                                     r_nonce)
8473     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8474
8475     logger.debug("Send WSC_NACK to AP")
8476     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8477                             msg_type=None, eap_code=2)
8478     send_wsc_msg(hapd, addr, nack)
8479
8480     wps_wait_eap_failure(hapd, dev[0])
8481
8482 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8483     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8484     pin = "12345670"
8485     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8486     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8487     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8488
8489     logger.debug("Receive WSC/Start from AP")
8490     msg = get_wsc_msg(hapd)
8491     if msg['wsc_opcode'] != WSC_Start:
8492         raise Exception("Unexpected Op-Code for WSC/Start")
8493
8494     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8495     uuid_e = 16*'\x11'
8496     e_nonce = 16*'\x22'
8497     own_private, e_pk = wsc_dh_init()
8498
8499     logger.debug("Send M1 to AP")
8500     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8501                                 e_nonce, e_pk)
8502     send_wsc_msg(hapd, addr, m1)
8503
8504     logger.debug("Receive M2 from AP")
8505     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8506     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8507     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8508
8509     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8510                                     r_nonce)
8511     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8512
8513     logger.debug("Send WSC_NACK to AP")
8514     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8515                             msg_type=WPS_WSC_ACK, eap_code=2)
8516     send_wsc_msg(hapd, addr, nack)
8517
8518     wps_wait_eap_failure(hapd, dev[0])
8519
8520 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8521     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8522     pin = "12345670"
8523     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8524     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8525     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8526
8527     logger.debug("Receive WSC/Start from AP")
8528     msg = get_wsc_msg(hapd)
8529     if msg['wsc_opcode'] != WSC_Start:
8530         raise Exception("Unexpected Op-Code for WSC/Start")
8531
8532     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8533     uuid_e = 16*'\x11'
8534     e_nonce = 16*'\x22'
8535     own_private, e_pk = wsc_dh_init()
8536
8537     logger.debug("Send M1 to AP")
8538     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8539                                 e_nonce, e_pk)
8540     send_wsc_msg(hapd, addr, m1)
8541
8542     logger.debug("Receive M2 from AP")
8543     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8544     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8545     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8546
8547     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8548                                     r_nonce)
8549     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8550
8551     logger.debug("Send WSC_NACK to AP")
8552     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8553                             eap_code=2)
8554     send_wsc_msg(hapd, addr, nack)
8555
8556     wps_wait_eap_failure(hapd, dev[0])
8557
8558 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8559     """WPS proto: M2 followed by NACK without Config Error"""
8560     pin = "12345670"
8561     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8562     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8563     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8564
8565     logger.debug("Receive WSC/Start from AP")
8566     msg = get_wsc_msg(hapd)
8567     if msg['wsc_opcode'] != WSC_Start:
8568         raise Exception("Unexpected Op-Code for WSC/Start")
8569
8570     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8571     uuid_e = 16*'\x11'
8572     e_nonce = 16*'\x22'
8573     own_private, e_pk = wsc_dh_init()
8574
8575     logger.debug("Send M1 to AP")
8576     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8577                                 e_nonce, e_pk)
8578     send_wsc_msg(hapd, addr, m1)
8579
8580     logger.debug("Receive M2 from AP")
8581     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8582     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8583     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8584
8585     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8586                                     r_nonce)
8587     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8588
8589     logger.debug("Send WSC_NACK to AP")
8590     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8591                             config_error=None, eap_code=2)
8592     send_wsc_msg(hapd, addr, nack)
8593
8594     wps_wait_eap_failure(hapd, dev[0])
8595
8596 def test_wps_ext_m2_ack_invalid(dev, apdev):
8597     """WPS proto: M2 followed by invalid ACK"""
8598     pin = "12345670"
8599     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8600     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8601     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8602
8603     logger.debug("Receive WSC/Start from AP")
8604     msg = get_wsc_msg(hapd)
8605     if msg['wsc_opcode'] != WSC_Start:
8606         raise Exception("Unexpected Op-Code for WSC/Start")
8607
8608     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8609     uuid_e = 16*'\x11'
8610     e_nonce = 16*'\x22'
8611     own_private, e_pk = wsc_dh_init()
8612
8613     logger.debug("Send M1 to AP")
8614     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8615                                 e_nonce, e_pk)
8616     send_wsc_msg(hapd, addr, m1)
8617
8618     logger.debug("Receive M2 from AP")
8619     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8620     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8621     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8622
8623     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8624                                     r_nonce)
8625     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8626
8627     logger.debug("Send WSC_ACK to AP")
8628     attrs = '\x10\x00\x00'
8629     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8630     send_wsc_msg(hapd, addr, ack)
8631
8632     wps_wait_eap_failure(hapd, dev[0])
8633
8634 def test_wps_ext_m2_ack(dev, apdev):
8635     """WPS proto: M2 followed by ACK"""
8636     pin = "12345670"
8637     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8638     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8639     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8640
8641     logger.debug("Receive WSC/Start from AP")
8642     msg = get_wsc_msg(hapd)
8643     if msg['wsc_opcode'] != WSC_Start:
8644         raise Exception("Unexpected Op-Code for WSC/Start")
8645
8646     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8647     uuid_e = 16*'\x11'
8648     e_nonce = 16*'\x22'
8649     own_private, e_pk = wsc_dh_init()
8650
8651     logger.debug("Send M1 to AP")
8652     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8653                                 e_nonce, e_pk)
8654     send_wsc_msg(hapd, addr, m1)
8655
8656     logger.debug("Receive M2 from AP")
8657     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8658     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8659     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8660
8661     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8662                                     r_nonce)
8663     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8664
8665     logger.debug("Send WSC_ACK to AP")
8666     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8667     send_wsc_msg(hapd, addr, ack)
8668
8669     wps_wait_eap_failure(hapd, dev[0])
8670
8671 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8672     """WPS proto: M2 followed by ACK missing Msg Type"""
8673     pin = "12345670"
8674     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8675     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8676     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8677
8678     logger.debug("Receive WSC/Start from AP")
8679     msg = get_wsc_msg(hapd)
8680     if msg['wsc_opcode'] != WSC_Start:
8681         raise Exception("Unexpected Op-Code for WSC/Start")
8682
8683     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8684     uuid_e = 16*'\x11'
8685     e_nonce = 16*'\x22'
8686     own_private, e_pk = wsc_dh_init()
8687
8688     logger.debug("Send M1 to AP")
8689     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8690                                 e_nonce, e_pk)
8691     send_wsc_msg(hapd, addr, m1)
8692
8693     logger.debug("Receive M2 from AP")
8694     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8695     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8696     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8697
8698     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8699                                     r_nonce)
8700     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8701
8702     logger.debug("Send WSC_ACK to AP")
8703     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8704                           msg_type=None, eap_code=2)
8705     send_wsc_msg(hapd, addr, ack)
8706
8707     wps_wait_eap_failure(hapd, dev[0])
8708
8709 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8710     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8711     pin = "12345670"
8712     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8713     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8714     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8715
8716     logger.debug("Receive WSC/Start from AP")
8717     msg = get_wsc_msg(hapd)
8718     if msg['wsc_opcode'] != WSC_Start:
8719         raise Exception("Unexpected Op-Code for WSC/Start")
8720
8721     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8722     uuid_e = 16*'\x11'
8723     e_nonce = 16*'\x22'
8724     own_private, e_pk = wsc_dh_init()
8725
8726     logger.debug("Send M1 to AP")
8727     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8728                                 e_nonce, e_pk)
8729     send_wsc_msg(hapd, addr, m1)
8730
8731     logger.debug("Receive M2 from AP")
8732     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8733     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8734     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8735
8736     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8737                                     r_nonce)
8738     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8739
8740     logger.debug("Send WSC_ACK to AP")
8741     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8742                           msg_type=WPS_WSC_NACK, eap_code=2)
8743     send_wsc_msg(hapd, addr, ack)
8744
8745     wps_wait_eap_failure(hapd, dev[0])
8746
8747 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8748     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8749     pin = "12345670"
8750     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8751     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8752     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8753
8754     logger.debug("Receive WSC/Start from AP")
8755     msg = get_wsc_msg(hapd)
8756     if msg['wsc_opcode'] != WSC_Start:
8757         raise Exception("Unexpected Op-Code for WSC/Start")
8758
8759     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8760     uuid_e = 16*'\x11'
8761     e_nonce = 16*'\x22'
8762     own_private, e_pk = wsc_dh_init()
8763
8764     logger.debug("Send M1 to AP")
8765     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8766                                 e_nonce, e_pk)
8767     send_wsc_msg(hapd, addr, m1)
8768
8769     logger.debug("Receive M2 from AP")
8770     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8771     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8772     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8773
8774     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8775                                     r_nonce)
8776     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8777
8778     logger.debug("Send WSC_ACK to AP")
8779     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8780                           eap_code=2)
8781     send_wsc_msg(hapd, addr, ack)
8782
8783     wps_wait_eap_failure(hapd, dev[0])
8784
8785 def test_wps_ext_m1_invalid(dev, apdev):
8786     """WPS proto: M1 failing parsing"""
8787     pin = "12345670"
8788     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8789     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8790     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8791
8792     logger.debug("Receive WSC/Start from AP")
8793     msg = get_wsc_msg(hapd)
8794     if msg['wsc_opcode'] != WSC_Start:
8795         raise Exception("Unexpected Op-Code for WSC/Start")
8796
8797     logger.debug("Send M1 to AP")
8798     attrs = '\x10\x00\x00'
8799     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8800     send_wsc_msg(hapd, addr, m1)
8801
8802     wps_wait_eap_failure(hapd, dev[0])
8803
8804 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8805     """WPS proto: M1 missing Msg Type"""
8806     pin = "12345670"
8807     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8808     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8809     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8810
8811     logger.debug("Receive WSC/Start from AP")
8812     msg = get_wsc_msg(hapd)
8813     if msg['wsc_opcode'] != WSC_Start:
8814         raise Exception("Unexpected Op-Code for WSC/Start")
8815
8816     logger.debug("Send M1 to AP")
8817     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8818     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8819     send_wsc_msg(hapd, addr, m1)
8820
8821     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8822
8823 def wps_ext_wsc_done(dev, apdev):
8824     pin = "12345670"
8825     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8826     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8827     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8828
8829     logger.debug("Receive WSC/Start from AP")
8830     msg = get_wsc_msg(hapd)
8831     if msg['wsc_opcode'] != WSC_Start:
8832         raise Exception("Unexpected Op-Code for WSC/Start")
8833
8834     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8835     uuid_e = 16*'\x11'
8836     e_nonce = 16*'\x22'
8837     own_private, e_pk = wsc_dh_init()
8838
8839     logger.debug("Send M1 to AP")
8840     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8841                                 e_nonce, e_pk)
8842     send_wsc_msg(hapd, addr, m1)
8843
8844     logger.debug("Receive M2 from AP")
8845     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8846     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8847     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8848
8849     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8850                                     r_nonce)
8851     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8852
8853     logger.debug("Send M3 to AP")
8854     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8855     attrs += build_attr_msg_type(WPS_M3)
8856     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8857     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8858     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8859     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8860     raw_m3_attrs = attrs
8861     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8862     send_wsc_msg(hapd, addr, m3)
8863
8864     logger.debug("Receive M4 from AP")
8865     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8866
8867     logger.debug("Send M5 to AP")
8868     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8869     attrs += build_attr_msg_type(WPS_M5)
8870     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8871     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8872     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8873     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8874     raw_m5_attrs = attrs
8875     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8876     send_wsc_msg(hapd, addr, m5)
8877
8878     logger.debug("Receive M6 from AP")
8879     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8880
8881     logger.debug("Send M7 to AP")
8882     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8883     attrs += build_attr_msg_type(WPS_M7)
8884     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8885     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8886     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8887     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8888     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8889     raw_m7_attrs = attrs
8890     send_wsc_msg(hapd, addr, m7)
8891
8892     logger.debug("Receive M8 from AP")
8893     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8894     return hapd, msg, e_nonce, r_nonce
8895
8896 def test_wps_ext_wsc_done_invalid(dev, apdev):
8897     """WPS proto: invalid WSC_Done"""
8898     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8899
8900     logger.debug("Send WSC_Done to AP")
8901     attrs = '\x10\x00\x00'
8902     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8903     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8904
8905     wps_wait_eap_failure(hapd, dev[0])
8906
8907 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
8908     """WPS proto: invalid WSC_Done"""
8909     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8910
8911     logger.debug("Send WSC_Done to AP")
8912     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8913     #attrs += build_attr_msg_type(WPS_WSC_DONE)
8914     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8915     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8916     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8917     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8918
8919     wps_wait_eap_failure(hapd, dev[0])
8920
8921 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
8922     """WPS proto: WSC_Done with wrong Msg Type"""
8923     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8924
8925     logger.debug("Send WSC_Done to AP")
8926     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8927     attrs += build_attr_msg_type(WPS_WSC_ACK)
8928     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8929     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8930     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8931     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8932
8933     wps_wait_eap_failure(hapd, dev[0])
8934
8935 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
8936     """WPS proto: WSC_Done without e_nonce"""
8937     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8938
8939     logger.debug("Send WSC_Done to AP")
8940     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8941     attrs += build_attr_msg_type(WPS_WSC_DONE)
8942     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8943     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8944     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8945     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8946
8947     wps_wait_eap_failure(hapd, dev[0])
8948
8949 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
8950     """WPS proto: WSC_Done without r_nonce"""
8951     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8952
8953     logger.debug("Send WSC_Done to AP")
8954     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8955     attrs += build_attr_msg_type(WPS_WSC_DONE)
8956     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8957     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8958     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8959     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8960
8961     wps_wait_eap_failure(hapd, dev[0])
8962
8963 def test_wps_ext_m7_no_encr_settings(dev, apdev):
8964     """WPS proto: M7 without Encr Settings"""
8965     pin = "12345670"
8966     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8967     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8968     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8969
8970     logger.debug("Receive WSC/Start from AP")
8971     msg = get_wsc_msg(hapd)
8972     if msg['wsc_opcode'] != WSC_Start:
8973         raise Exception("Unexpected Op-Code for WSC/Start")
8974
8975     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8976     uuid_e = 16*'\x11'
8977     e_nonce = 16*'\x22'
8978     own_private, e_pk = wsc_dh_init()
8979
8980     logger.debug("Send M1 to AP")
8981     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8982                                 e_nonce, e_pk)
8983     send_wsc_msg(hapd, addr, m1)
8984
8985     logger.debug("Receive M2 from AP")
8986     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8987     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8988     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8989
8990     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8991                                     r_nonce)
8992     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8993
8994     logger.debug("Send M3 to AP")
8995     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8996     attrs += build_attr_msg_type(WPS_M3)
8997     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8998     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8999     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
9000     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
9001     raw_m3_attrs = attrs
9002     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9003     send_wsc_msg(hapd, addr, m3)
9004
9005     logger.debug("Receive M4 from AP")
9006     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
9007
9008     logger.debug("Send M5 to AP")
9009     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9010     attrs += build_attr_msg_type(WPS_M5)
9011     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9012     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
9013     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9014     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
9015     raw_m5_attrs = attrs
9016     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9017     send_wsc_msg(hapd, addr, m5)
9018
9019     logger.debug("Receive M6 from AP")
9020     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
9021
9022     logger.debug("Send M7 to AP")
9023     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9024     attrs += build_attr_msg_type(WPS_M7)
9025     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9026     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
9027     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9028     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
9029     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9030     raw_m7_attrs = attrs
9031     send_wsc_msg(hapd, addr, m7)
9032
9033     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
9034
9035 def test_wps_ext_m1_workaround(dev, apdev):
9036     """WPS proto: M1 Manufacturer/Model workaround"""
9037     pin = "12345670"
9038     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
9039     wps_ext_eap_identity_req(dev[0], hapd, bssid)
9040     wps_ext_eap_identity_resp(hapd, dev[0], addr)
9041
9042     logger.debug("Receive WSC/Start from AP")
9043     msg = get_wsc_msg(hapd)
9044     if msg['wsc_opcode'] != WSC_Start:
9045         raise Exception("Unexpected Op-Code for WSC/Start")
9046
9047     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
9048     uuid_e = 16*'\x11'
9049     e_nonce = 16*'\x22'
9050     own_private, e_pk = wsc_dh_init()
9051
9052     logger.debug("Send M1 to AP")
9053     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
9054                                 e_nonce, e_pk, manufacturer='Apple TEST',
9055                                 model_name='AirPort', config_methods='\xff\xff')
9056     send_wsc_msg(hapd, addr, m1)
9057
9058     logger.debug("Receive M2 from AP")
9059     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
9060
9061 def test_ap_wps_disable_enable(dev, apdev):
9062     """WPS and DISABLE/ENABLE AP"""
9063     hapd = wps_start_ap(apdev[0])
9064     hapd.disable()
9065     hapd.enable()
9066     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")