3a48d345dc324d491ef0e30462b590ad7db21044
[mech_eap.git] / tests / hwsim / test_ap_wps.py
1 # WPS tests
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import base64
8 import binascii
9 from Crypto.Cipher import AES
10 import hashlib
11 import hmac
12 import os
13 import time
14 import stat
15 import subprocess
16 import logging
17 logger = logging.getLogger()
18 import re
19 import socket
20 import struct
21 import httplib
22 import urlparse
23 import urllib
24 import xml.etree.ElementTree as ET
25 import StringIO
26 import SocketServer
27
28 import hwsim_utils
29 import hostapd
30 from wpasupplicant import WpaSupplicant
31 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
32
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_fragmentation(dev, apdev):
1708     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1709     ssid = "test-wps-fragmentation"
1710     appin = "12345670"
1711     hostapd.add_ap(apdev[0]['ifname'],
1712                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1713                      "wpa_passphrase": "12345678", "wpa": "3",
1714                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1715                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1716                      "fragment_size": "50" })
1717     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1718     logger.info("WPS provisioning step (PBC)")
1719     hapd.request("WPS_PBC")
1720     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1721     dev[0].dump_monitor()
1722     dev[0].request("SET wps_fragment_size 50")
1723     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1724     dev[0].wait_connected(timeout=30)
1725     status = dev[0].get_status()
1726     if status['wpa_state'] != 'COMPLETED':
1727         raise Exception("Not fully connected")
1728     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1729         raise Exception("Unexpected encryption configuration")
1730     if status['key_mgmt'] != 'WPA2-PSK':
1731         raise Exception("Unexpected key_mgmt")
1732
1733     logger.info("WPS provisioning step (PIN)")
1734     pin = dev[1].wps_read_pin()
1735     hapd.request("WPS_PIN any " + pin)
1736     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1737     dev[1].request("SET wps_fragment_size 50")
1738     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1739     dev[1].wait_connected(timeout=30)
1740     status = dev[1].get_status()
1741     if status['wpa_state'] != 'COMPLETED':
1742         raise Exception("Not fully connected")
1743     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1744         raise Exception("Unexpected encryption configuration")
1745     if status['key_mgmt'] != 'WPA2-PSK':
1746         raise Exception("Unexpected key_mgmt")
1747
1748     logger.info("WPS connection as registrar")
1749     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1750     dev[2].request("SET wps_fragment_size 50")
1751     dev[2].wps_reg(apdev[0]['bssid'], appin)
1752     status = dev[2].get_status()
1753     if status['wpa_state'] != 'COMPLETED':
1754         raise Exception("Not fully connected")
1755     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1756         raise Exception("Unexpected encryption configuration")
1757     if status['key_mgmt'] != 'WPA2-PSK':
1758         raise Exception("Unexpected key_mgmt")
1759
1760 def test_ap_wps_new_version_sta(dev, apdev):
1761     """WPS compatibility with new version number on the station"""
1762     ssid = "test-wps-ver"
1763     hostapd.add_ap(apdev[0]['ifname'],
1764                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1765                      "wpa_passphrase": "12345678", "wpa": "2",
1766                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1767     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1768     logger.info("WPS provisioning step")
1769     hapd.request("WPS_PBC")
1770     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1771     dev[0].dump_monitor()
1772     dev[0].request("SET wps_version_number 0x43")
1773     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1774     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1775     dev[0].wait_connected(timeout=30)
1776
1777 def test_ap_wps_new_version_ap(dev, apdev):
1778     """WPS compatibility with new version number on the AP"""
1779     ssid = "test-wps-ver"
1780     hostapd.add_ap(apdev[0]['ifname'],
1781                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1782                      "wpa_passphrase": "12345678", "wpa": "2",
1783                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1784     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1785     logger.info("WPS provisioning step")
1786     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1787         raise Exception("Failed to enable test functionality")
1788     hapd.request("WPS_PBC")
1789     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1790     dev[0].dump_monitor()
1791     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1792     dev[0].wait_connected(timeout=30)
1793     hapd.request("SET wps_version_number 0x20")
1794
1795 def test_ap_wps_check_pin(dev, apdev):
1796     """Verify PIN checking through control interface"""
1797     hostapd.add_ap(apdev[0]['ifname'],
1798                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1799                      "wpa_passphrase": "12345678", "wpa": "2",
1800                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1801     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1802     for t in [ ("12345670", "12345670"),
1803                ("12345678", "FAIL-CHECKSUM"),
1804                ("12345", "FAIL"),
1805                ("123456789", "FAIL"),
1806                ("1234-5670", "12345670"),
1807                ("1234 5670", "12345670"),
1808                ("1-2.3:4 5670", "12345670") ]:
1809         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1810         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1811         if res != res2:
1812             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1813         if res != t[1]:
1814             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1815
1816     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1817         raise Exception("Unexpected WPS_CHECK_PIN success")
1818     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1819         raise Exception("Unexpected WPS_CHECK_PIN success")
1820
1821     for i in range(0, 10):
1822         pin = dev[0].request("WPS_PIN get")
1823         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1824         if pin != rpin:
1825             raise Exception("Random PIN validation failed for " + pin)
1826
1827 def test_ap_wps_wep_config(dev, apdev):
1828     """WPS 2.0 AP rejecting WEP configuration"""
1829     ssid = "test-wps-config"
1830     appin = "12345670"
1831     hostapd.add_ap(apdev[0]['ifname'],
1832                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1833                      "ap_pin": appin})
1834     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1835     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1836     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1837                    "hello", no_wait=True)
1838     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1839     if ev is None:
1840         raise Exception("WPS-FAIL timed out")
1841     if "reason=2" not in ev:
1842         raise Exception("Unexpected reason code in WPS-FAIL")
1843     status = hapd.request("WPS_GET_STATUS")
1844     if "Last WPS result: Failed" not in status:
1845         raise Exception("WPS failure result not shown correctly")
1846     if "Failure Reason: WEP Prohibited" not in status:
1847         raise Exception("Failure reason not reported correctly")
1848     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1849         raise Exception("Peer address not shown correctly")
1850
1851 def test_ap_wps_wep_enroll(dev, apdev):
1852     """WPS 2.0 STA rejecting WEP configuration"""
1853     ssid = "test-wps-wep"
1854     hostapd.add_ap(apdev[0]['ifname'],
1855                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1856                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1857     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1858     hapd.request("WPS_PBC")
1859     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1860     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1861     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1862     if ev is None:
1863         raise Exception("WPS-FAIL event timed out")
1864     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1865         raise Exception("Unexpected WPS-FAIL event: " + ev)
1866
1867 def test_ap_wps_ie_fragmentation(dev, apdev):
1868     """WPS AP using fragmented WPS IE"""
1869     ssid = "test-wps-ie-fragmentation"
1870     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1871                "wpa_passphrase": "12345678", "wpa": "2",
1872                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1873                "device_name": "1234567890abcdef1234567890abcdef",
1874                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1875                "model_name": "1234567890abcdef1234567890abcdef",
1876                "model_number": "1234567890abcdef1234567890abcdef",
1877                "serial_number": "1234567890abcdef1234567890abcdef" }
1878     hostapd.add_ap(apdev[0]['ifname'], params)
1879     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1880     hapd.request("WPS_PBC")
1881     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1882     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1883     dev[0].wait_connected(timeout=30)
1884     bss = dev[0].get_bss(apdev[0]['bssid'])
1885     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1886         logger.info("Device Name not received correctly")
1887         logger.info(bss)
1888         # This can fail if Probe Response frame is missed and Beacon frame was
1889         # used to fill in the BSS entry. This can happen, e.g., during heavy
1890         # load every now and then and is not really an error, so try to
1891         # workaround by runnign another scan.
1892         dev[0].scan(freq="2412", only_new=True)
1893         bss = dev[0].get_bss(apdev[0]['bssid'])
1894         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1895             logger.info(bss)
1896             raise Exception("Device Name not received correctly")
1897     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1898         raise Exception("Unexpected number of WPS IEs")
1899
1900 def get_psk(pskfile):
1901     psks = {}
1902     with open(pskfile, "r") as f:
1903         lines = f.read().splitlines()
1904         for l in lines:
1905             if l == "# WPA PSKs":
1906                 continue
1907             (addr,psk) = l.split(' ')
1908             psks[addr] = psk
1909     return psks
1910
1911 def test_ap_wps_per_station_psk(dev, apdev):
1912     """WPS PBC provisioning with per-station PSK"""
1913     addr0 = dev[0].own_addr()
1914     addr1 = dev[1].own_addr()
1915     addr2 = dev[2].own_addr()
1916     ssid = "wps"
1917     appin = "12345670"
1918     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1919     try:
1920         os.remove(pskfile)
1921     except:
1922         pass
1923
1924     try:
1925         with open(pskfile, "w") as f:
1926             f.write("# WPA PSKs\n")
1927
1928         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1929                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1930                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1931                    "wpa_psk_file": pskfile }
1932         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1933
1934         logger.info("First enrollee")
1935         hapd.request("WPS_PBC")
1936         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1937         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1938         dev[0].wait_connected(timeout=30)
1939
1940         logger.info("Second enrollee")
1941         hapd.request("WPS_PBC")
1942         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1943         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1944         dev[1].wait_connected(timeout=30)
1945
1946         logger.info("External registrar")
1947         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1948         dev[2].wps_reg(apdev[0]['bssid'], appin)
1949
1950         logger.info("Verifying PSK results")
1951         psks = get_psk(pskfile)
1952         if addr0 not in psks:
1953             raise Exception("No PSK recorded for sta0")
1954         if addr1 not in psks:
1955             raise Exception("No PSK recorded for sta1")
1956         if addr2 not in psks:
1957             raise Exception("No PSK recorded for sta2")
1958         if psks[addr0] == psks[addr1]:
1959             raise Exception("Same PSK recorded for sta0 and sta1")
1960         if psks[addr0] == psks[addr2]:
1961             raise Exception("Same PSK recorded for sta0 and sta2")
1962         if psks[addr1] == psks[addr2]:
1963             raise Exception("Same PSK recorded for sta1 and sta2")
1964
1965         dev[0].request("REMOVE_NETWORK all")
1966         logger.info("Second external registrar")
1967         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1968         dev[0].wps_reg(apdev[0]['bssid'], appin)
1969         psks2 = get_psk(pskfile)
1970         if addr0 not in psks2:
1971             raise Exception("No PSK recorded for sta0(reg)")
1972         if psks[addr0] == psks2[addr0]:
1973             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
1974     finally:
1975         os.remove(pskfile)
1976
1977 def test_ap_wps_per_station_psk_failure(dev, apdev):
1978     """WPS PBC provisioning with per-station PSK (file not writable)"""
1979     addr0 = dev[0].p2p_dev_addr()
1980     addr1 = dev[1].p2p_dev_addr()
1981     addr2 = dev[2].p2p_dev_addr()
1982     ssid = "wps"
1983     appin = "12345670"
1984     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1985     try:
1986         os.remove(pskfile)
1987     except:
1988         pass
1989
1990     try:
1991         with open(pskfile, "w") as f:
1992             f.write("# WPA PSKs\n")
1993
1994         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1995                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1996                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1997                    "wpa_psk_file": pskfile }
1998         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1999         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2000             raise Exception("Failed to set wpa_psk_file")
2001
2002         logger.info("First enrollee")
2003         hapd.request("WPS_PBC")
2004         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2005         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2006         dev[0].wait_connected(timeout=30)
2007
2008         logger.info("Second enrollee")
2009         hapd.request("WPS_PBC")
2010         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2011         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2012         dev[1].wait_connected(timeout=30)
2013
2014         logger.info("External registrar")
2015         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2016         dev[2].wps_reg(apdev[0]['bssid'], appin)
2017
2018         logger.info("Verifying PSK results")
2019         psks = get_psk(pskfile)
2020         if len(psks) > 0:
2021             raise Exception("PSK recorded unexpectedly")
2022     finally:
2023         os.remove(pskfile)
2024
2025 def test_ap_wps_pin_request_file(dev, apdev):
2026     """WPS PIN provisioning with configured AP"""
2027     ssid = "wps"
2028     pinfile = "/tmp/ap_wps_pin_request_file.log"
2029     if os.path.exists(pinfile):
2030         os.remove(pinfile)
2031     hostapd.add_ap(apdev[0]['ifname'],
2032                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2033                      "wps_pin_requests": pinfile,
2034                      "wpa_passphrase": "12345678", "wpa": "2",
2035                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2036     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2037     uuid = dev[0].get_status_field("uuid")
2038     pin = dev[0].wps_read_pin()
2039     try:
2040         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2041         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2042         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2043         if ev is None:
2044             raise Exception("PIN needed event not shown")
2045         if uuid not in ev:
2046             raise Exception("UUID mismatch")
2047         dev[0].request("WPS_CANCEL")
2048         success = False
2049         with open(pinfile, "r") as f:
2050             lines = f.readlines()
2051             for l in lines:
2052                 if uuid in l:
2053                     success = True
2054                     break
2055         if not success:
2056             raise Exception("PIN request entry not in the log file")
2057     finally:
2058         try:
2059             os.remove(pinfile)
2060         except:
2061             pass
2062
2063 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2064     """WPS auto-setup with configuration file"""
2065     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2066     ifname = apdev[0]['ifname']
2067     try:
2068         with open(conffile, "w") as f:
2069             f.write("driver=nl80211\n")
2070             f.write("hw_mode=g\n")
2071             f.write("channel=1\n")
2072             f.write("ieee80211n=1\n")
2073             f.write("interface=%s\n" % ifname)
2074             f.write("ctrl_interface=/var/run/hostapd\n")
2075             f.write("ssid=wps\n")
2076             f.write("eap_server=1\n")
2077             f.write("wps_state=1\n")
2078         hostapd.add_bss('phy3', ifname, conffile)
2079         hapd = hostapd.Hostapd(ifname)
2080         hapd.request("WPS_PBC")
2081         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2082         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2083         dev[0].wait_connected(timeout=30)
2084         with open(conffile, "r") as f:
2085             lines = f.read().splitlines()
2086             vals = dict()
2087             for l in lines:
2088                 try:
2089                     [name,value] = l.split('=', 1)
2090                     vals[name] = value
2091                 except ValueError, e:
2092                     if "# WPS configuration" in l:
2093                         pass
2094                     else:
2095                         raise Exception("Unexpected configuration line: " + l)
2096         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2097             raise Exception("Incorrect configuration: " + str(vals))
2098     finally:
2099         try:
2100             os.remove(conffile)
2101         except:
2102             pass
2103
2104 def test_ap_wps_pbc_timeout(dev, apdev, params):
2105     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2106     if not params['long']:
2107         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2108     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2109     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2110
2111     location = ssdp_get_location(ap_uuid)
2112     urls = upnp_get_urls(location)
2113     eventurl = urlparse.urlparse(urls['event_sub_url'])
2114     ctrlurl = urlparse.urlparse(urls['control_url'])
2115
2116     url = urlparse.urlparse(location)
2117     conn = httplib.HTTPConnection(url.netloc)
2118
2119     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2120         def handle(self):
2121             data = self.rfile.readline().strip()
2122             logger.debug(data)
2123             self.wfile.write(gen_wps_event())
2124
2125     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2126     server.timeout = 1
2127
2128     headers = { "callback": '<http://127.0.0.1:12345/event>',
2129                 "NT": "upnp:event",
2130                 "timeout": "Second-1234" }
2131     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2132     resp = conn.getresponse()
2133     if resp.status != 200:
2134         raise Exception("Unexpected HTTP response: %d" % resp.status)
2135     sid = resp.getheader("sid")
2136     logger.debug("Subscription SID " + sid)
2137
2138     msg = '''<?xml version="1.0"?>
2139 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2140 <s:Body>
2141 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2142 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2143 VFi5hrLk
2144 </NewMessage>
2145 </u:SetSelectedRegistrar>
2146 </s:Body>
2147 </s:Envelope>'''
2148     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2149     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2150     conn.request("POST", ctrlurl.path, msg, headers)
2151     resp = conn.getresponse()
2152     if resp.status != 200:
2153         raise Exception("Unexpected HTTP response: %d" % resp.status)
2154
2155     server.handle_request()
2156
2157     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2158     if "OK" not in dev[0].request("WPS_PBC"):
2159         raise Exception("WPS_PBC failed")
2160
2161     start = os.times()[4]
2162
2163     server.handle_request()
2164     dev[1].request("BSS_FLUSH 0")
2165     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2166                         only_new=True)
2167     bss = dev[1].get_bss(apdev[0]['bssid'])
2168     logger.debug("BSS: " + str(bss))
2169     if '[WPS-AUTH]' not in bss['flags']:
2170         raise Exception("WPS not indicated authorized")
2171
2172     server.handle_request()
2173
2174     wps_timeout_seen = False
2175
2176     while True:
2177         hapd.dump_monitor()
2178         dev[1].dump_monitor()
2179         if not wps_timeout_seen:
2180             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2181             if ev is not None:
2182                 logger.info("PBC timeout seen")
2183                 wps_timeout_seen = True
2184         else:
2185             dev[0].dump_monitor()
2186         now = os.times()[4]
2187         if now - start > 130:
2188             raise Exception("Selected registration information not removed")
2189         dev[1].request("BSS_FLUSH 0")
2190         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2191                             only_new=True)
2192         bss = dev[1].get_bss(apdev[0]['bssid'])
2193         logger.debug("BSS: " + str(bss))
2194         if '[WPS-AUTH]' not in bss['flags']:
2195             break
2196         server.handle_request()
2197
2198     server.server_close()
2199
2200     if wps_timeout_seen:
2201         return
2202
2203     now = os.times()[4]
2204     if now < start + 150:
2205         dur = start + 150 - now
2206     else:
2207         dur = 1
2208     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2209     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2210     if ev is None:
2211         raise Exception("WPS-TIMEOUT not reported")
2212
2213 def add_ssdp_ap(ifname, ap_uuid):
2214     ssid = "wps-ssdp"
2215     ap_pin = "12345670"
2216     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2217                "wpa_passphrase": "12345678", "wpa": "2",
2218                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2219                "device_name": "Wireless AP", "manufacturer": "Company",
2220                "model_name": "WAP", "model_number": "123",
2221                "serial_number": "12345", "device_type": "6-0050F204-1",
2222                "os_version": "01020300",
2223                "config_methods": "label push_button",
2224                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2225                "friendly_name": "WPS Access Point",
2226                "manufacturer_url": "http://www.example.com/",
2227                "model_description": "Wireless Access Point",
2228                "model_url": "http://www.example.com/model/",
2229                "upc": "123456789012" }
2230     return hostapd.add_ap(ifname, params)
2231
2232 def ssdp_send(msg, no_recv=False):
2233     socket.setdefaulttimeout(1)
2234     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2235     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2236     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2237     sock.bind(("127.0.0.1", 0))
2238     sock.sendto(msg, ("239.255.255.250", 1900))
2239     if no_recv:
2240         return None
2241     return sock.recv(1000)
2242
2243 def ssdp_send_msearch(st, no_recv=False):
2244     msg = '\r\n'.join([
2245             'M-SEARCH * HTTP/1.1',
2246             'HOST: 239.255.255.250:1900',
2247             'MX: 1',
2248             'MAN: "ssdp:discover"',
2249             'ST: ' + st,
2250             '', ''])
2251     return ssdp_send(msg, no_recv=no_recv)
2252
2253 def test_ap_wps_ssdp_msearch(dev, apdev):
2254     """WPS AP and SSDP M-SEARCH messages"""
2255     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2256     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2257
2258     msg = '\r\n'.join([
2259             'M-SEARCH * HTTP/1.1',
2260             'Host: 239.255.255.250:1900',
2261             'Mx: 1',
2262             'Man: "ssdp:discover"',
2263             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2264             '', ''])
2265     ssdp_send(msg)
2266
2267     msg = '\r\n'.join([
2268             'M-SEARCH * HTTP/1.1',
2269             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2270             'mx: \t1\t\t   ',
2271             'man: \t \t "ssdp:discover"   ',
2272             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2273             '', ''])
2274     ssdp_send(msg)
2275
2276     ssdp_send_msearch("ssdp:all")
2277     ssdp_send_msearch("upnp:rootdevice")
2278     ssdp_send_msearch("uuid:" + ap_uuid)
2279     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2280     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2281
2282     msg = '\r\n'.join([
2283             'M-SEARCH * HTTP/1.1',
2284             'HOST:\t239.255.255.250:1900',
2285             'MAN: "ssdp:discover"',
2286             'MX: 130',
2287             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2288             '', ''])
2289     ssdp_send(msg, no_recv=True)
2290
2291 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2292     """WPS AP and invalid SSDP M-SEARCH messages"""
2293     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2294     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2295
2296     socket.setdefaulttimeout(1)
2297     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2298     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2299     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2300     sock.bind(("127.0.0.1", 0))
2301
2302     logger.debug("Missing MX")
2303     msg = '\r\n'.join([
2304             'M-SEARCH * HTTP/1.1',
2305             'HOST: 239.255.255.250:1900',
2306             'MAN: "ssdp:discover"',
2307             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2308             '', ''])
2309     sock.sendto(msg, ("239.255.255.250", 1900))
2310
2311     logger.debug("Negative MX")
2312     msg = '\r\n'.join([
2313             'M-SEARCH * HTTP/1.1',
2314             'HOST: 239.255.255.250:1900',
2315             'MX: -1',
2316             'MAN: "ssdp:discover"',
2317             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2318             '', ''])
2319     sock.sendto(msg, ("239.255.255.250", 1900))
2320
2321     logger.debug("Invalid MX")
2322     msg = '\r\n'.join([
2323             'M-SEARCH * HTTP/1.1',
2324             'HOST: 239.255.255.250:1900',
2325             'MX; 1',
2326             'MAN: "ssdp:discover"',
2327             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2328             '', ''])
2329     sock.sendto(msg, ("239.255.255.250", 1900))
2330
2331     logger.debug("Missing MAN")
2332     msg = '\r\n'.join([
2333             'M-SEARCH * HTTP/1.1',
2334             'HOST: 239.255.255.250:1900',
2335             'MX: 1',
2336             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2337             '', ''])
2338     sock.sendto(msg, ("239.255.255.250", 1900))
2339
2340     logger.debug("Invalid MAN")
2341     msg = '\r\n'.join([
2342             'M-SEARCH * HTTP/1.1',
2343             'HOST: 239.255.255.250:1900',
2344             'MX: 1',
2345             'MAN: foo',
2346             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2347             '', ''])
2348     sock.sendto(msg, ("239.255.255.250", 1900))
2349     msg = '\r\n'.join([
2350             'M-SEARCH * HTTP/1.1',
2351             'HOST: 239.255.255.250:1900',
2352             'MX: 1',
2353             'MAN; "ssdp:discover"',
2354             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2355             '', ''])
2356     sock.sendto(msg, ("239.255.255.250", 1900))
2357
2358     logger.debug("Missing HOST")
2359     msg = '\r\n'.join([
2360             'M-SEARCH * HTTP/1.1',
2361             'MAN: "ssdp:discover"',
2362             'MX: 1',
2363             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2364             '', ''])
2365     sock.sendto(msg, ("239.255.255.250", 1900))
2366
2367     logger.debug("Missing ST")
2368     msg = '\r\n'.join([
2369             'M-SEARCH * HTTP/1.1',
2370             'HOST: 239.255.255.250:1900',
2371             'MAN: "ssdp:discover"',
2372             'MX: 1',
2373             '', ''])
2374     sock.sendto(msg, ("239.255.255.250", 1900))
2375
2376     logger.debug("Mismatching ST")
2377     msg = '\r\n'.join([
2378             'M-SEARCH * HTTP/1.1',
2379             'HOST: 239.255.255.250:1900',
2380             'MAN: "ssdp:discover"',
2381             'MX: 1',
2382             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2383             '', ''])
2384     sock.sendto(msg, ("239.255.255.250", 1900))
2385     msg = '\r\n'.join([
2386             'M-SEARCH * HTTP/1.1',
2387             'HOST: 239.255.255.250:1900',
2388             'MAN: "ssdp:discover"',
2389             'MX: 1',
2390             'ST: foo:bar',
2391             '', ''])
2392     sock.sendto(msg, ("239.255.255.250", 1900))
2393     msg = '\r\n'.join([
2394             'M-SEARCH * HTTP/1.1',
2395             'HOST: 239.255.255.250:1900',
2396             'MAN: "ssdp:discover"',
2397             'MX: 1',
2398             'ST: foobar',
2399             '', ''])
2400     sock.sendto(msg, ("239.255.255.250", 1900))
2401
2402     logger.debug("Invalid ST")
2403     msg = '\r\n'.join([
2404             'M-SEARCH * HTTP/1.1',
2405             'HOST: 239.255.255.250:1900',
2406             'MAN: "ssdp:discover"',
2407             'MX: 1',
2408             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2409             '', ''])
2410     sock.sendto(msg, ("239.255.255.250", 1900))
2411
2412     logger.debug("Invalid M-SEARCH")
2413     msg = '\r\n'.join([
2414             'M+SEARCH * HTTP/1.1',
2415             'HOST: 239.255.255.250:1900',
2416             'MAN: "ssdp:discover"',
2417             'MX: 1',
2418             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2419             '', ''])
2420     sock.sendto(msg, ("239.255.255.250", 1900))
2421     msg = '\r\n'.join([
2422             'M-SEARCH-* HTTP/1.1',
2423             'HOST: 239.255.255.250:1900',
2424             'MAN: "ssdp:discover"',
2425             'MX: 1',
2426             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2427             '', ''])
2428     sock.sendto(msg, ("239.255.255.250", 1900))
2429
2430     logger.debug("Invalid message format")
2431     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2432     msg = '\r'.join([
2433             'M-SEARCH * HTTP/1.1',
2434             'HOST: 239.255.255.250:1900',
2435             'MAN: "ssdp:discover"',
2436             'MX: 1',
2437             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2438             '', ''])
2439     sock.sendto(msg, ("239.255.255.250", 1900))
2440
2441     try:
2442         r = sock.recv(1000)
2443         raise Exception("Unexpected M-SEARCH response: " + r)
2444     except socket.timeout:
2445         pass
2446
2447     logger.debug("Valid M-SEARCH")
2448     msg = '\r\n'.join([
2449             'M-SEARCH * HTTP/1.1',
2450             'HOST: 239.255.255.250:1900',
2451             'MAN: "ssdp:discover"',
2452             'MX: 1',
2453             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2454             '', ''])
2455     sock.sendto(msg, ("239.255.255.250", 1900))
2456
2457     try:
2458         r = sock.recv(1000)
2459         pass
2460     except socket.timeout:
2461         raise Exception("No SSDP response")
2462
2463 def test_ap_wps_ssdp_burst(dev, apdev):
2464     """WPS AP and SSDP burst"""
2465     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2466     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2467
2468     msg = '\r\n'.join([
2469             'M-SEARCH * HTTP/1.1',
2470             'HOST: 239.255.255.250:1900',
2471             'MAN: "ssdp:discover"',
2472             'MX: 1',
2473             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2474             '', ''])
2475     socket.setdefaulttimeout(1)
2476     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2477     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2478     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2479     sock.bind(("127.0.0.1", 0))
2480     for i in range(0, 25):
2481         sock.sendto(msg, ("239.255.255.250", 1900))
2482     resp = 0
2483     while True:
2484         try:
2485             r = sock.recv(1000)
2486             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2487                 raise Exception("Unexpected message: " + r)
2488             resp += 1
2489         except socket.timeout:
2490             break
2491     if resp < 20:
2492         raise Exception("Too few SSDP responses")
2493
2494     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2495     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2496     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2497     sock.bind(("127.0.0.1", 0))
2498     for i in range(0, 25):
2499         sock.sendto(msg, ("239.255.255.250", 1900))
2500     while True:
2501         try:
2502             r = sock.recv(1000)
2503             if ap_uuid in r:
2504                 break
2505         except socket.timeout:
2506             raise Exception("No SSDP response")
2507
2508 def ssdp_get_location(uuid):
2509     res = ssdp_send_msearch("uuid:" + uuid)
2510     location = None
2511     for l in res.splitlines():
2512         if l.lower().startswith("location:"):
2513             location = l.split(':', 1)[1].strip()
2514             break
2515     if location is None:
2516         raise Exception("No UPnP location found")
2517     return location
2518
2519 def upnp_get_urls(location):
2520     conn = urllib.urlopen(location)
2521     tree = ET.parse(conn)
2522     root = tree.getroot()
2523     urn = '{urn:schemas-upnp-org:device-1-0}'
2524     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2525     res = {}
2526     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2527     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2528     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2529     return res
2530
2531 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2532     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2533     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2534     ET.register_namespace('soapenv', soapns)
2535     ET.register_namespace('wfa', wpsns)
2536     attrib = {}
2537     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2538     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2539     body = ET.SubElement(root, "{%s}Body" % soapns)
2540     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2541     tree = ET.ElementTree(root)
2542     soap = StringIO.StringIO()
2543     tree.write(soap, xml_declaration=True, encoding='utf-8')
2544
2545     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2546     if include_soap_action:
2547         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2548     elif soap_action_override:
2549         headers["SOAPAction"] = soap_action_override
2550     conn.request("POST", path, soap.getvalue(), headers)
2551     return conn.getresponse()
2552
2553 def test_ap_wps_upnp(dev, apdev):
2554     """WPS AP and UPnP operations"""
2555     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2556     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2557
2558     location = ssdp_get_location(ap_uuid)
2559     urls = upnp_get_urls(location)
2560
2561     conn = urllib.urlopen(urls['scpd_url'])
2562     scpd = conn.read()
2563
2564     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2565     if conn.getcode() != 404:
2566         raise Exception("Unexpected HTTP response to GET unknown URL")
2567
2568     url = urlparse.urlparse(location)
2569     conn = httplib.HTTPConnection(url.netloc)
2570     #conn.set_debuglevel(1)
2571     headers = { "Content-type": 'text/xml; charset="utf-8"',
2572                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2573     conn.request("POST", "hello", "\r\n\r\n", headers)
2574     resp = conn.getresponse()
2575     if resp.status != 404:
2576         raise Exception("Unexpected HTTP response: %d" % resp.status)
2577
2578     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2579     resp = conn.getresponse()
2580     if resp.status != 501:
2581         raise Exception("Unexpected HTTP response: %d" % resp.status)
2582
2583     headers = { "Content-type": 'text/xml; charset="utf-8"',
2584                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2585     ctrlurl = urlparse.urlparse(urls['control_url'])
2586     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2587     resp = conn.getresponse()
2588     if resp.status != 401:
2589         raise Exception("Unexpected HTTP response: %d" % resp.status)
2590
2591     logger.debug("GetDeviceInfo without SOAPAction header")
2592     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2593                             include_soap_action=False)
2594     if resp.status != 401:
2595         raise Exception("Unexpected HTTP response: %d" % resp.status)
2596
2597     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2598     for act in [ "foo",
2599                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2600                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2601                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2602         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2603                                 include_soap_action=False,
2604                                 soap_action_override=act)
2605         if resp.status != 401:
2606             raise Exception("Unexpected HTTP response: %d" % resp.status)
2607
2608     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2609     if resp.status != 200:
2610         raise Exception("Unexpected HTTP response: %d" % resp.status)
2611     dev = resp.read()
2612     if "NewDeviceInfo" not in dev:
2613         raise Exception("Unexpected GetDeviceInfo response")
2614
2615     logger.debug("PutMessage without required parameters")
2616     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2617     if resp.status != 600:
2618         raise Exception("Unexpected HTTP response: %d" % resp.status)
2619
2620     logger.debug("PutWLANResponse without required parameters")
2621     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2622     if resp.status != 600:
2623         raise Exception("Unexpected HTTP response: %d" % resp.status)
2624
2625     logger.debug("SetSelectedRegistrar from unregistered ER")
2626     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2627     if resp.status != 501:
2628         raise Exception("Unexpected HTTP response: %d" % resp.status)
2629
2630     logger.debug("Unknown action")
2631     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2632     if resp.status != 401:
2633         raise Exception("Unexpected HTTP response: %d" % resp.status)
2634
2635 def test_ap_wps_upnp_subscribe(dev, apdev):
2636     """WPS AP and UPnP event subscription"""
2637     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2638     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2639
2640     location = ssdp_get_location(ap_uuid)
2641     urls = upnp_get_urls(location)
2642     eventurl = urlparse.urlparse(urls['event_sub_url'])
2643
2644     url = urlparse.urlparse(location)
2645     conn = httplib.HTTPConnection(url.netloc)
2646     #conn.set_debuglevel(1)
2647     headers = { "callback": '<http://127.0.0.1:12345/event>',
2648                 "timeout": "Second-1234" }
2649     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2650     resp = conn.getresponse()
2651     if resp.status != 412:
2652         raise Exception("Unexpected HTTP response: %d" % resp.status)
2653
2654     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2655     resp = conn.getresponse()
2656     if resp.status != 412:
2657         raise Exception("Unexpected HTTP response: %d" % resp.status)
2658
2659     headers = { "NT": "upnp:event",
2660                 "timeout": "Second-1234" }
2661     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2662     resp = conn.getresponse()
2663     if resp.status != 412:
2664         raise Exception("Unexpected HTTP response: %d" % resp.status)
2665
2666     headers = { "callback": '<http://127.0.0.1:12345/event>',
2667                 "NT": "upnp:foobar",
2668                 "timeout": "Second-1234" }
2669     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2670     resp = conn.getresponse()
2671     if resp.status != 400:
2672         raise Exception("Unexpected HTTP response: %d" % resp.status)
2673
2674     logger.debug("Valid subscription")
2675     headers = { "callback": '<http://127.0.0.1:12345/event>',
2676                 "NT": "upnp:event",
2677                 "timeout": "Second-1234" }
2678     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2679     resp = conn.getresponse()
2680     if resp.status != 200:
2681         raise Exception("Unexpected HTTP response: %d" % resp.status)
2682     sid = resp.getheader("sid")
2683     logger.debug("Subscription SID " + sid)
2684
2685     logger.debug("Invalid re-subscription")
2686     headers = { "NT": "upnp:event",
2687                 "sid": "123456734567854",
2688                 "timeout": "Second-1234" }
2689     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2690     resp = conn.getresponse()
2691     if resp.status != 400:
2692         raise Exception("Unexpected HTTP response: %d" % resp.status)
2693
2694     logger.debug("Invalid re-subscription")
2695     headers = { "NT": "upnp:event",
2696                 "sid": "uuid:123456734567854",
2697                 "timeout": "Second-1234" }
2698     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2699     resp = conn.getresponse()
2700     if resp.status != 400:
2701         raise Exception("Unexpected HTTP response: %d" % resp.status)
2702
2703     logger.debug("Invalid re-subscription")
2704     headers = { "callback": '<http://127.0.0.1:12345/event>',
2705                 "NT": "upnp:event",
2706                 "sid": sid,
2707                 "timeout": "Second-1234" }
2708     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2709     resp = conn.getresponse()
2710     if resp.status != 400:
2711         raise Exception("Unexpected HTTP response: %d" % resp.status)
2712
2713     logger.debug("SID mismatch in re-subscription")
2714     headers = { "NT": "upnp:event",
2715                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2716                 "timeout": "Second-1234" }
2717     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2718     resp = conn.getresponse()
2719     if resp.status != 412:
2720         raise Exception("Unexpected HTTP response: %d" % resp.status)
2721
2722     logger.debug("Valid re-subscription")
2723     headers = { "NT": "upnp:event",
2724                 "sid": sid,
2725                 "timeout": "Second-1234" }
2726     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2727     resp = conn.getresponse()
2728     if resp.status != 200:
2729         raise Exception("Unexpected HTTP response: %d" % resp.status)
2730     sid2 = resp.getheader("sid")
2731     logger.debug("Subscription SID " + sid2)
2732
2733     if sid != sid2:
2734         raise Exception("Unexpected SID change")
2735
2736     logger.debug("Valid re-subscription")
2737     headers = { "NT": "upnp:event",
2738                 "sid": "uuid: \t \t" + sid.split(':')[1],
2739                 "timeout": "Second-1234" }
2740     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2741     resp = conn.getresponse()
2742     if resp.status != 200:
2743         raise Exception("Unexpected HTTP response: %d" % resp.status)
2744
2745     logger.debug("Invalid unsubscription")
2746     headers = { "sid": sid }
2747     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2748     resp = conn.getresponse()
2749     if resp.status != 412:
2750         raise Exception("Unexpected HTTP response: %d" % resp.status)
2751     headers = { "foo": "bar" }
2752     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2753     resp = conn.getresponse()
2754     if resp.status != 412:
2755         raise Exception("Unexpected HTTP response: %d" % resp.status)
2756
2757     logger.debug("Valid unsubscription")
2758     headers = { "sid": sid }
2759     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2760     resp = conn.getresponse()
2761     if resp.status != 200:
2762         raise Exception("Unexpected HTTP response: %d" % resp.status)
2763
2764     logger.debug("Unsubscription for not existing SID")
2765     headers = { "sid": sid }
2766     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2767     resp = conn.getresponse()
2768     if resp.status != 412:
2769         raise Exception("Unexpected HTTP response: %d" % resp.status)
2770
2771     logger.debug("Invalid unsubscription")
2772     headers = { "sid": " \t \tfoo" }
2773     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2774     resp = conn.getresponse()
2775     if resp.status != 400:
2776         raise Exception("Unexpected HTTP response: %d" % resp.status)
2777
2778     logger.debug("Invalid unsubscription")
2779     headers = { "sid": "uuid:\t \tfoo" }
2780     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2781     resp = conn.getresponse()
2782     if resp.status != 400:
2783         raise Exception("Unexpected HTTP response: %d" % resp.status)
2784
2785     logger.debug("Invalid unsubscription")
2786     headers = { "NT": "upnp:event",
2787                 "sid": sid }
2788     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2789     resp = conn.getresponse()
2790     if resp.status != 400:
2791         raise Exception("Unexpected HTTP response: %d" % resp.status)
2792     headers = { "callback": '<http://127.0.0.1:12345/event>',
2793                 "sid": sid }
2794     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2795     resp = conn.getresponse()
2796     if resp.status != 400:
2797         raise Exception("Unexpected HTTP response: %d" % resp.status)
2798
2799     logger.debug("Valid subscription with multiple callbacks")
2800     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>',
2801                 "NT": "upnp:event",
2802                 "timeout": "Second-1234" }
2803     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2804     resp = conn.getresponse()
2805     if resp.status != 200:
2806         raise Exception("Unexpected HTTP response: %d" % resp.status)
2807     sid = resp.getheader("sid")
2808     logger.debug("Subscription SID " + sid)
2809
2810     # Force subscription to be deleted due to errors
2811     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2812     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2813     with alloc_fail(hapd, 1, "event_build_message"):
2814         for i in range(10):
2815             dev[1].dump_monitor()
2816             dev[2].dump_monitor()
2817             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2818             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2819             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2820             dev[1].request("WPS_CANCEL")
2821             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2822             dev[2].request("WPS_CANCEL")
2823             if i % 4 == 1:
2824                 time.sleep(1)
2825             else:
2826                 time.sleep(0.1)
2827     time.sleep(0.2)
2828
2829     headers = { "sid": sid }
2830     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2831     resp = conn.getresponse()
2832     if resp.status != 200 and resp.status != 412:
2833         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2834
2835     headers = { "callback": '<http://127.0.0.1:12345/event>',
2836                 "NT": "upnp:event",
2837                 "timeout": "Second-1234" }
2838     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2839         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2840         resp = conn.getresponse()
2841         if resp.status != 200:
2842             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2843         sid = resp.getheader("sid")
2844         logger.debug("Subscription SID " + sid)
2845
2846     headers = { "sid": sid }
2847     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2848     resp = conn.getresponse()
2849     if resp.status != 200:
2850         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2851
2852     headers = { "callback": '<http://127.0.0.1:12345/event>',
2853                 "NT": "upnp:event",
2854                 "timeout": "Second-1234" }
2855     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2856     resp = conn.getresponse()
2857     if resp.status != 200:
2858         raise Exception("Unexpected HTTP response: %d" % resp.status)
2859     sid = resp.getheader("sid")
2860     logger.debug("Subscription SID " + sid)
2861
2862     with alloc_fail(hapd, 1, "=event_add"):
2863         for i in range(2):
2864             dev[1].dump_monitor()
2865             dev[2].dump_monitor()
2866             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2867             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2868             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2869             dev[1].request("WPS_CANCEL")
2870             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2871             dev[2].request("WPS_CANCEL")
2872             if i == 0:
2873                 time.sleep(1)
2874             else:
2875                 time.sleep(0.1)
2876
2877     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2878     resp = conn.getresponse()
2879     if resp.status != 200:
2880         raise Exception("Unexpected HTTP response: %d" % resp.status)
2881
2882     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
2883         dev[1].dump_monitor()
2884         dev[2].dump_monitor()
2885         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2886         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2887         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2888         dev[1].request("WPS_CANCEL")
2889         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2890         dev[2].request("WPS_CANCEL")
2891         time.sleep(0.1)
2892
2893     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
2894         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2895         resp = conn.getresponse()
2896         if resp.status != 500:
2897             raise Exception("Unexpected HTTP response: %d" % resp.status)
2898
2899     with alloc_fail(hapd, 1, "=subscription_start"):
2900         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2901         resp = conn.getresponse()
2902         if resp.status != 500:
2903             raise Exception("Unexpected HTTP response: %d" % resp.status)
2904
2905     headers = { "callback": '',
2906                 "NT": "upnp:event",
2907                 "timeout": "Second-1234" }
2908     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2909     resp = conn.getresponse()
2910     if resp.status != 500:
2911         raise Exception("Unexpected HTTP response: %d" % resp.status)
2912
2913     headers = { "callback": ' <',
2914                 "NT": "upnp:event",
2915                 "timeout": "Second-1234" }
2916     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2917     resp = conn.getresponse()
2918     if resp.status != 500:
2919         raise Exception("Unexpected HTTP response: %d" % resp.status)
2920
2921     headers = { "callback": '<http://127.0.0.1:12345/event>',
2922                 "NT": "upnp:event",
2923                 "timeout": "Second-1234" }
2924     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
2925         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2926         resp = conn.getresponse()
2927         if resp.status != 500:
2928             raise Exception("Unexpected HTTP response: %d" % resp.status)
2929
2930     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
2931         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2932         resp = conn.getresponse()
2933         if resp.status != 500:
2934             raise Exception("Unexpected HTTP response: %d" % resp.status)
2935
2936     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
2937         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2938         resp = conn.getresponse()
2939         if resp.status != 500:
2940             raise Exception("Unexpected HTTP response: %d" % resp.status)
2941
2942     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
2943         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2944         resp = conn.getresponse()
2945         if resp.status != 500:
2946             raise Exception("Unexpected HTTP response: %d" % resp.status)
2947
2948     for i in range(6):
2949         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
2950                     "NT": "upnp:event",
2951                     "timeout": "Second-1234" }
2952         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2953         resp = conn.getresponse()
2954         if resp.status != 200:
2955             raise Exception("Unexpected HTTP response: %d" % resp.status)
2956
2957     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
2958         dev[1].dump_monitor()
2959         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2960         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2961         dev[1].request("WPS_CANCEL")
2962         time.sleep(0.1)
2963
2964     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
2965         dev[1].dump_monitor()
2966         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2967         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2968         dev[1].request("WPS_CANCEL")
2969         time.sleep(0.1)
2970
2971     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
2972         dev[1].dump_monitor()
2973         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2974         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2975         dev[1].request("WPS_CANCEL")
2976         time.sleep(0.1)
2977
2978     hapd.disable()
2979     with alloc_fail(hapd, 1, "get_netif_info"):
2980         if "FAIL" not in hapd.request("ENABLE"):
2981             raise Exception("ENABLE succeeded during OOM")
2982
2983 def test_ap_wps_upnp_subscribe_events(dev, apdev):
2984     """WPS AP and UPnP event subscription and many events"""
2985     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2986     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2987
2988     location = ssdp_get_location(ap_uuid)
2989     urls = upnp_get_urls(location)
2990     eventurl = urlparse.urlparse(urls['event_sub_url'])
2991
2992     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2993         def handle(self):
2994             data = self.rfile.readline().strip()
2995             logger.debug(data)
2996             self.wfile.write(gen_wps_event())
2997
2998     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2999     server.timeout = 1
3000
3001     url = urlparse.urlparse(location)
3002     conn = httplib.HTTPConnection(url.netloc)
3003
3004     headers = { "callback": '<http://127.0.0.1:12345/event>',
3005                 "NT": "upnp:event",
3006                 "timeout": "Second-1234" }
3007     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3008     resp = conn.getresponse()
3009     if resp.status != 200:
3010         raise Exception("Unexpected HTTP response: %d" % resp.status)
3011     sid = resp.getheader("sid")
3012     logger.debug("Subscription SID " + sid)
3013
3014     # Fetch the first event message
3015     server.handle_request()
3016
3017     # Force subscription event queue to reach the maximum length by generating
3018     # new proxied events without the ER fetching any of the pending events.
3019     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3020     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3021     for i in range(16):
3022         dev[1].dump_monitor()
3023         dev[2].dump_monitor()
3024         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3025         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3026         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3027         dev[1].request("WPS_CANCEL")
3028         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3029         dev[2].request("WPS_CANCEL")
3030         if i % 4 == 1:
3031             time.sleep(1)
3032         else:
3033             time.sleep(0.1)
3034
3035     hapd.request("WPS_PIN any 12345670")
3036     dev[1].dump_monitor()
3037     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3038     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3039     if ev is None:
3040         raise Exception("WPS success not reported")
3041
3042     # Close the WPS ER HTTP server without fetching all the pending events.
3043     # This tests hostapd code path that clears subscription and the remaining
3044     # event queue when the interface is deinitialized.
3045     server.handle_request()
3046     server.server_close()
3047
3048     dev[1].wait_connected()
3049
3050 def test_ap_wps_upnp_http_proto(dev, apdev):
3051     """WPS AP and UPnP/HTTP protocol testing"""
3052     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3053     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3054
3055     location = ssdp_get_location(ap_uuid)
3056
3057     url = urlparse.urlparse(location)
3058     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3059     #conn.set_debuglevel(1)
3060
3061     conn.request("HEAD", "hello")
3062     resp = conn.getresponse()
3063     if resp.status != 501:
3064         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3065     conn.close()
3066
3067     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3068         try:
3069             conn.request(cmd, "hello")
3070             resp = conn.getresponse()
3071         except Exception, e:
3072             pass
3073         conn.close()
3074
3075     headers = { "Content-Length": 'abc' }
3076     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3077     try:
3078         resp = conn.getresponse()
3079     except Exception, e:
3080         pass
3081     conn.close()
3082
3083     headers = { "Content-Length": '-10' }
3084     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3085     try:
3086         resp = conn.getresponse()
3087     except Exception, e:
3088         pass
3089     conn.close()
3090
3091     headers = { "Content-Length": '10000000000000' }
3092     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3093     try:
3094         resp = conn.getresponse()
3095     except Exception, e:
3096         pass
3097     conn.close()
3098
3099     headers = { "Transfer-Encoding": 'abc' }
3100     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3101     resp = conn.getresponse()
3102     if resp.status != 501:
3103         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3104     conn.close()
3105
3106     headers = { "Transfer-Encoding": 'chunked' }
3107     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3108     resp = conn.getresponse()
3109     if resp.status != 501:
3110         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3111     conn.close()
3112
3113     # Too long a header
3114     conn.request("HEAD", 5000 * 'A')
3115     try:
3116         resp = conn.getresponse()
3117     except Exception, e:
3118         pass
3119     conn.close()
3120
3121     # Long URL but within header length limits
3122     conn.request("HEAD", 3000 * 'A')
3123     resp = conn.getresponse()
3124     if resp.status != 501:
3125         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3126     conn.close()
3127
3128     headers = { "Content-Length": '20' }
3129     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3130     try:
3131         resp = conn.getresponse()
3132     except Exception, e:
3133         pass
3134     conn.close()
3135
3136     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3137     resp = conn.getresponse()
3138     if resp.status != 404:
3139         raise Exception("Unexpected HTTP response: %d" % resp.status)
3140     conn.close()
3141
3142     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3143     try:
3144         resp = conn.getresponse()
3145     except Exception, e:
3146         pass
3147     conn.close()
3148
3149 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3150     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3151     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3152     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3153
3154     location = ssdp_get_location(ap_uuid)
3155
3156     url = urlparse.urlparse(location)
3157     conn = httplib.HTTPConnection(url.netloc)
3158     #conn.set_debuglevel(1)
3159
3160     headers = { "Transfer-Encoding": 'chunked' }
3161     conn.request("POST", "hello",
3162                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3163                  headers)
3164     resp = conn.getresponse()
3165     if resp.status != 404:
3166         raise Exception("Unexpected HTTP response: %d" % resp.status)
3167     conn.close()
3168
3169     conn.putrequest("POST", "hello")
3170     conn.putheader('Transfer-Encoding', 'chunked')
3171     conn.endheaders()
3172     conn.send("a\r\nabcdefghij\r\n")
3173     time.sleep(0.1)
3174     conn.send("2\r\nkl\r\n")
3175     conn.send("0\r\n\r\n")
3176     resp = conn.getresponse()
3177     if resp.status != 404:
3178         raise Exception("Unexpected HTTP response: %d" % resp.status)
3179     conn.close()
3180
3181     conn.putrequest("POST", "hello")
3182     conn.putheader('Transfer-Encoding', 'chunked')
3183     conn.endheaders()
3184     completed = False
3185     try:
3186         for i in range(20000):
3187             conn.send("1\r\nZ\r\n")
3188         conn.send("0\r\n\r\n")
3189         resp = conn.getresponse()
3190         completed = True
3191     except Exception, e:
3192         pass
3193     conn.close()
3194     if completed:
3195         raise Exception("Too long chunked request did not result in connection reset")
3196
3197     headers = { "Transfer-Encoding": 'chunked' }
3198     conn.request("POST", "hello", "80000000\r\na", headers)
3199     try:
3200         resp = conn.getresponse()
3201     except Exception, e:
3202         pass
3203     conn.close()
3204
3205     conn.request("POST", "hello", "10000000\r\na", headers)
3206     try:
3207         resp = conn.getresponse()
3208     except Exception, e:
3209         pass
3210     conn.close()
3211
3212 def test_ap_wps_disabled(dev, apdev):
3213     """WPS operations while WPS is disabled"""
3214     ssid = "test-wps-disabled"
3215     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
3216     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3217     if "FAIL" not in hapd.request("WPS_PBC"):
3218         raise Exception("WPS_PBC succeeded unexpectedly")
3219     if "FAIL" not in hapd.request("WPS_CANCEL"):
3220         raise Exception("WPS_CANCEL succeeded unexpectedly")
3221
3222 def test_ap_wps_mixed_cred(dev, apdev):
3223     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3224     ssid = "test-wps-wep"
3225     hostapd.add_ap(apdev[0]['ifname'],
3226                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3227                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
3228     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3229     hapd.request("WPS_PBC")
3230     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3231     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3232     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3233     if ev is None:
3234         raise Exception("WPS-SUCCESS event timed out")
3235     nets = dev[0].list_networks()
3236     if len(nets) != 1:
3237         raise Exception("Unexpected number of network blocks")
3238     id = nets[0]['id']
3239     proto = dev[0].get_network(id, "proto")
3240     if proto != "WPA RSN":
3241         raise Exception("Unexpected merged proto field value: " + proto)
3242     pairwise = dev[0].get_network(id, "pairwise")
3243     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3244         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3245
3246 def test_ap_wps_while_connected(dev, apdev):
3247     """WPS PBC provisioning while connected to another AP"""
3248     ssid = "test-wps-conf"
3249     hostapd.add_ap(apdev[0]['ifname'],
3250                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3251                      "wpa_passphrase": "12345678", "wpa": "2",
3252                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3253     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3254
3255     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3256     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3257
3258     logger.info("WPS provisioning step")
3259     hapd.request("WPS_PBC")
3260     dev[0].dump_monitor()
3261     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3262     dev[0].wait_connected(timeout=30)
3263     status = dev[0].get_status()
3264     if status['bssid'] != apdev[0]['bssid']:
3265         raise Exception("Unexpected BSSID")
3266
3267 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3268     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3269     ssid = "test-wps-conf"
3270     hostapd.add_ap(apdev[0]['ifname'],
3271                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3272                      "wpa_passphrase": "12345678", "wpa": "2",
3273                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3274     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3275
3276     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3277
3278     try:
3279         dev[0].request("STA_AUTOCONNECT 0")
3280         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3281
3282         logger.info("WPS provisioning step")
3283         hapd.request("WPS_PBC")
3284         dev[0].dump_monitor()
3285         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3286         dev[0].wait_connected(timeout=30)
3287         status = dev[0].get_status()
3288         if status['bssid'] != apdev[0]['bssid']:
3289             raise Exception("Unexpected BSSID")
3290     finally:
3291         dev[0].request("STA_AUTOCONNECT 1")
3292
3293 def test_ap_wps_from_event(dev, apdev):
3294     """WPS PBC event on AP to enable PBC"""
3295     ssid = "test-wps-conf"
3296     hapd = hostapd.add_ap(apdev[0]['ifname'],
3297                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3298                             "wpa_passphrase": "12345678", "wpa": "2",
3299                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3300     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3301     dev[0].dump_monitor()
3302     hapd.dump_monitor()
3303     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3304
3305     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3306     if ev is None:
3307         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3308     vals = ev.split(' ')
3309     if vals[1] != dev[0].p2p_interface_addr():
3310         raise Exception("Unexpected enrollee address: " + vals[1])
3311     if vals[5] != '4':
3312         raise Exception("Unexpected Device Password Id: " + vals[5])
3313     hapd.request("WPS_PBC")
3314     dev[0].wait_connected(timeout=30)
3315
3316 def test_ap_wps_ap_scan_2(dev, apdev):
3317     """AP_SCAN 2 for WPS"""
3318     ssid = "test-wps-conf"
3319     hapd = hostapd.add_ap(apdev[0]['ifname'],
3320                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3321                             "wpa_passphrase": "12345678", "wpa": "2",
3322                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3323     hapd.request("WPS_PBC")
3324
3325     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3326     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3327
3328     if "OK" not in wpas.request("AP_SCAN 2"):
3329         raise Exception("Failed to set AP_SCAN 2")
3330
3331     wpas.flush_scan_cache()
3332     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3333     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3334     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3335     if ev is None:
3336         raise Exception("WPS-SUCCESS event timed out")
3337     wpas.wait_connected(timeout=30)
3338     wpas.request("DISCONNECT")
3339     wpas.request("BSS_FLUSH 0")
3340     wpas.dump_monitor()
3341     wpas.request("REASSOCIATE")
3342     wpas.wait_connected(timeout=30)
3343
3344 def test_ap_wps_eapol_workaround(dev, apdev):
3345     """EAPOL workaround code path for 802.1X header length mismatch"""
3346     ssid = "test-wps"
3347     hostapd.add_ap(apdev[0]['ifname'],
3348                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3349     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3350     bssid = apdev[0]['bssid']
3351     hapd.request("SET ext_eapol_frame_io 1")
3352     dev[0].request("SET ext_eapol_frame_io 1")
3353     hapd.request("WPS_PBC")
3354     dev[0].request("WPS_PBC")
3355
3356     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3357     if ev is None:
3358         raise Exception("Timeout on EAPOL-TX from hostapd")
3359
3360     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3361     if "OK" not in res:
3362         raise Exception("EAPOL_RX to wpa_supplicant failed")
3363
3364 def test_ap_wps_iteration(dev, apdev):
3365     """WPS PIN and iterate through APs without selected registrar"""
3366     ssid = "test-wps-conf"
3367     hapd = hostapd.add_ap(apdev[0]['ifname'],
3368                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3369                             "wpa_passphrase": "12345678", "wpa": "2",
3370                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3371
3372     ssid2 = "test-wps-conf2"
3373     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3374                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3375                              "wpa_passphrase": "12345678", "wpa": "2",
3376                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3377
3378     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3379     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3380     dev[0].dump_monitor()
3381     pin = dev[0].request("WPS_PIN any")
3382
3383     # Wait for iteration through all WPS APs to happen before enabling any
3384     # Registrar.
3385     for i in range(2):
3386         ev = dev[0].wait_event(["Associated with"], timeout=30)
3387         if ev is None:
3388             raise Exception("No association seen")
3389         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3390         if ev is None:
3391             raise Exception("No M2D from AP")
3392         dev[0].wait_disconnected()
3393
3394     # Verify that each AP requested PIN
3395     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3396     if ev is None:
3397         raise Exception("No WPS-PIN-NEEDED event from AP")
3398     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3399     if ev is None:
3400         raise Exception("No WPS-PIN-NEEDED event from AP2")
3401
3402     # Provide PIN to one of the APs and verify that connection gets formed
3403     hapd.request("WPS_PIN any " + pin)
3404     dev[0].wait_connected(timeout=30)
3405
3406 def test_ap_wps_iteration_error(dev, apdev):
3407     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3408     ssid = "test-wps-conf-pin"
3409     hapd = hostapd.add_ap(apdev[0]['ifname'],
3410                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3411                             "wpa_passphrase": "12345678", "wpa": "2",
3412                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3413                             "wps_independent": "1" })
3414     hapd.request("SET ext_eapol_frame_io 1")
3415     bssid = apdev[0]['bssid']
3416     pin = dev[0].wps_read_pin()
3417     dev[0].request("WPS_PIN any " + pin)
3418
3419     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3420     if ev is None:
3421         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3422     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3423
3424     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3425     if ev is None:
3426         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3427     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3428     if ev is None:
3429         raise Exception("No CTRL-EVENT-EAP-STARTED")
3430
3431     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3432     # a case with an incorrectly behaving WPS AP.
3433
3434     # Start the real target AP and activate registrar on it.
3435     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3436                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3437                             "wpa_passphrase": "12345678", "wpa": "2",
3438                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3439                             "wps_independent": "1" })
3440     hapd2.request("WPS_PIN any " + pin)
3441
3442     dev[0].wait_disconnected(timeout=15)
3443     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3444     if ev is None:
3445         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3446     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3447     if ev is None:
3448         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3449     dev[0].wait_connected(timeout=15)
3450
3451 def test_ap_wps_priority(dev, apdev):
3452     """WPS PIN provisioning with configured AP and wps_priority"""
3453     ssid = "test-wps-conf-pin"
3454     hostapd.add_ap(apdev[0]['ifname'],
3455                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3456                      "wpa_passphrase": "12345678", "wpa": "2",
3457                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3458     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3459     logger.info("WPS provisioning step")
3460     pin = dev[0].wps_read_pin()
3461     hapd.request("WPS_PIN any " + pin)
3462     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3463     dev[0].dump_monitor()
3464     try:
3465         dev[0].request("SET wps_priority 6")
3466         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3467         dev[0].wait_connected(timeout=30)
3468         netw = dev[0].list_networks()
3469         prio = dev[0].get_network(netw[0]['id'], 'priority')
3470         if prio != '6':
3471             raise Exception("Unexpected network priority: " + prio)
3472     finally:
3473         dev[0].request("SET wps_priority 0")
3474
3475 def test_ap_wps_and_non_wps(dev, apdev):
3476     """WPS and non-WPS AP in single hostapd process"""
3477     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3478     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3479
3480     params = { "ssid": "no wps" }
3481     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3482
3483     appin = hapd.request("WPS_AP_PIN random")
3484     if "FAIL" in appin:
3485         raise Exception("Could not generate random AP PIN")
3486     if appin not in hapd.request("WPS_AP_PIN get"):
3487         raise Exception("Could not fetch current AP PIN")
3488
3489     if "FAIL" in hapd.request("WPS_PBC"):
3490         raise Exception("WPS_PBC failed")
3491     if "FAIL" in hapd.request("WPS_CANCEL"):
3492         raise Exception("WPS_CANCEL failed")
3493
3494 def test_ap_wps_init_oom(dev, apdev):
3495     """Initial AP configuration and OOM during PSK generation"""
3496     ssid = "test-wps"
3497     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3498     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3499
3500     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3501         pin = dev[0].wps_read_pin()
3502         hapd.request("WPS_PIN any " + pin)
3503         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3504         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3505         dev[0].wait_disconnected()
3506
3507     hapd.request("WPS_PIN any " + pin)
3508     dev[0].wait_connected(timeout=30)
3509
3510 def test_ap_wps_er_oom(dev, apdev):
3511     """WPS ER OOM in XML processing"""
3512     try:
3513         _test_ap_wps_er_oom(dev, apdev)
3514     finally:
3515         dev[0].request("WPS_ER_STOP")
3516         dev[1].request("WPS_CANCEL")
3517         dev[0].request("DISCONNECT")
3518
3519 def _test_ap_wps_er_oom(dev, apdev):
3520     ssid = "wps-er-ap-config"
3521     ap_pin = "12345670"
3522     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3523     hostapd.add_ap(apdev[0]['ifname'],
3524                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3525                      "wpa_passphrase": "12345678", "wpa": "2",
3526                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3527                      "device_name": "Wireless AP", "manufacturer": "Company",
3528                      "model_name": "WAP", "model_number": "123",
3529                      "serial_number": "12345", "device_type": "6-0050F204-1",
3530                      "os_version": "01020300",
3531                      "config_methods": "label push_button",
3532                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3533
3534     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3535
3536     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3537         dev[0].request("WPS_ER_START ifname=lo")
3538         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3539         if ev is not None:
3540             raise Exception("Unexpected AP discovery")
3541
3542     dev[0].request("WPS_ER_STOP")
3543     dev[0].request("WPS_ER_START ifname=lo")
3544     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3545     if ev is None:
3546         raise Exception("AP discovery timed out")
3547
3548     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3549     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3550         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3551         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3552         if ev is None:
3553             raise Exception("PBC scan failed")
3554         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3555         if ev is None:
3556             raise Exception("Enrollee discovery timed out")
3557
3558 def test_ap_wps_er_init_oom(dev, apdev):
3559     """WPS ER and OOM during init"""
3560     try:
3561         _test_ap_wps_er_init_oom(dev, apdev)
3562     finally:
3563         dev[0].request("WPS_ER_STOP")
3564
3565 def _test_ap_wps_er_init_oom(dev, apdev):
3566     with alloc_fail(dev[0], 1, "wps_er_init"):
3567         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3568             raise Exception("WPS_ER_START succeeded during OOM")
3569     with alloc_fail(dev[0], 1, "http_server_init"):
3570         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3571             raise Exception("WPS_ER_START succeeded during OOM")
3572     with alloc_fail(dev[0], 2, "http_server_init"):
3573         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3574             raise Exception("WPS_ER_START succeeded during OOM")
3575     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3576         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3577             raise Exception("WPS_ER_START succeeded during OOM")
3578     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3579         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3580             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3581
3582 def test_ap_wps_er_init_fail(dev, apdev):
3583     """WPS ER init failure"""
3584     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3585         dev[0].request("WPS_ER_STOP")
3586         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3587
3588 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3589     """WPS events and wpa_cli action script"""
3590     logdir = os.path.abspath(test_params['logdir'])
3591     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3592     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3593     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3594
3595     with open(actionfile, 'w') as f:
3596         f.write('#!/bin/sh\n')
3597         f.write('echo $* >> %s\n' % logfile)
3598         # Kill the process and wait some time before returning to allow all the
3599         # pending events to be processed with some of this happening after the
3600         # eloop SIGALRM signal has been scheduled.
3601         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3602
3603     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3604              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3605
3606     ssid = "test-wps-conf"
3607     hostapd.add_ap(apdev[0]['ifname'],
3608                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3609                      "wpa_passphrase": "12345678", "wpa": "2",
3610                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3611     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3612
3613     prg = os.path.join(test_params['logdir'],
3614                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3615     if not os.path.exists(prg):
3616         prg = '../../wpa_supplicant/wpa_cli'
3617     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3618     subprocess.call(arg)
3619
3620     arg = [ 'ps', 'ax' ]
3621     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3622     out = cmd.communicate()[0]
3623     cmd.wait()
3624     logger.debug("Processes:\n" + out)
3625     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3626         raise Exception("Did not see wpa_cli running")
3627
3628     hapd.request("WPS_PIN any 12345670")
3629     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3630     dev[0].dump_monitor()
3631     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3632     dev[0].wait_connected(timeout=30)
3633
3634     for i in range(30):
3635         if not os.path.exists(pidfile):
3636             break
3637         time.sleep(0.1)
3638
3639     if not os.path.exists(logfile):
3640         raise Exception("wpa_cli action results file not found")
3641     with open(logfile, 'r') as f:
3642         res = f.read()
3643     if "WPS-SUCCESS" not in res:
3644         raise Exception("WPS-SUCCESS event not seen in action file")
3645
3646     arg = [ 'ps', 'ax' ]
3647     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3648     out = cmd.communicate()[0]
3649     cmd.wait()
3650     logger.debug("Remaining processes:\n" + out)
3651     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3652         raise Exception("wpa_cli still running")
3653
3654     if os.path.exists(pidfile):
3655         raise Exception("PID file not removed")
3656
3657 def test_ap_wps_er_ssdp_proto(dev, apdev):
3658     """WPS ER SSDP protocol testing"""
3659     try:
3660         _test_ap_wps_er_ssdp_proto(dev, apdev)
3661     finally:
3662         dev[0].request("WPS_ER_STOP")
3663
3664 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3665     socket.setdefaulttimeout(1)
3666     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3667     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3668     sock.bind(("239.255.255.250", 1900))
3669     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3670         raise Exception("Invalid filter accepted")
3671     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3672         raise Exception("WPS_ER_START with filter failed")
3673     (msg,addr) = sock.recvfrom(1000)
3674     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3675     if "M-SEARCH" not in msg:
3676         raise Exception("Not an M-SEARCH")
3677     sock.sendto("FOO", addr)
3678     time.sleep(0.1)
3679     dev[0].request("WPS_ER_STOP")
3680
3681     dev[0].request("WPS_ER_START ifname=lo")
3682     (msg,addr) = sock.recvfrom(1000)
3683     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3684     if "M-SEARCH" not in msg:
3685         raise Exception("Not an M-SEARCH")
3686     sock.sendto("FOO", addr)
3687     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3688     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3689     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3690     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3691     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3692     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3693     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3694     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3695     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3696     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3697     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3698     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)
3699     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3700     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3701         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)
3702         time.sleep(0.1)
3703     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3704         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)
3705         time.sleep(0.1)
3706
3707     # Add an AP with bogus URL
3708     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)
3709     # Update timeout on AP without updating URL
3710     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)
3711     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3712     if ev is None:
3713         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3714
3715     # Add an AP with a valid URL (but no server listing to it)
3716     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)
3717     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3718     if ev is None:
3719         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3720
3721     sock.close()
3722
3723 wps_event_url = None
3724
3725 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3726                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3727     payload = '''<?xml version="1.0"?>
3728 <root xmlns="urn:schemas-upnp-org:device-1-0">
3729 <specVersion>
3730 <major>1</major>
3731 <minor>0</minor>
3732 </specVersion>
3733 <device>
3734 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3735 <friendlyName>WPS Access Point</friendlyName>
3736 <manufacturer>Company</manufacturer>
3737 <modelName>WAP</modelName>
3738 <modelNumber>123</modelNumber>
3739 <serialNumber>12345</serialNumber>
3740 '''
3741     if udn:
3742         payload += '<UDN>' + udn + '</UDN>'
3743     payload += '''<serviceList>
3744 <service>
3745 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3746 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3747 <SCPDURL>wps_scpd.xml</SCPDURL>
3748 '''
3749     if controlURL:
3750         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3751     if eventSubURL:
3752         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3753     payload += '''</service>
3754 </serviceList>
3755 </device>
3756 </root>
3757 '''
3758     hdr = 'HTTP/1.1 200 OK\r\n' + \
3759           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3760           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3761           'Connection: close\r\n' + \
3762           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3763           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3764     return hdr + payload
3765
3766 def gen_wps_control(payload_override=None):
3767     payload = '''<?xml version="1.0"?>
3768 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3769 <s:Body>
3770 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3771 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3772 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3773 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3774 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3775 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3776 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3777 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3778 AAYANyoAASA=
3779 </NewDeviceInfo>
3780 </u:GetDeviceInfoResponse>
3781 </s:Body>
3782 </s:Envelope>
3783 '''
3784     if payload_override:
3785         payload = payload_override
3786     hdr = 'HTTP/1.1 200 OK\r\n' + \
3787           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3788           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3789           'Connection: close\r\n' + \
3790           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3791           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3792     return hdr + payload
3793
3794 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3795     payload = ""
3796     hdr = 'HTTP/1.1 200 OK\r\n' + \
3797           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3798           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3799           'Connection: close\r\n' + \
3800           'Content-Length: ' + str(len(payload)) + '\r\n'
3801     if sid:
3802         hdr += 'SID: ' + sid + '\r\n'
3803     hdr += 'Timeout: Second-1801\r\n' + \
3804           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3805     return hdr + payload
3806
3807 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3808     def handle(self):
3809         data = self.rfile.readline().strip()
3810         logger.info("HTTP server received: " + data)
3811         while True:
3812             hdr = self.rfile.readline().strip()
3813             if len(hdr) == 0:
3814                 break
3815             logger.info("HTTP header: " + hdr)
3816             if "CALLBACK:" in hdr:
3817                 global wps_event_url
3818                 wps_event_url = hdr.split(' ')[1].strip('<>')
3819
3820         if "GET /foo.xml" in data:
3821             self.handle_upnp_info()
3822         elif "POST /wps_control" in data:
3823             self.handle_wps_control()
3824         elif "SUBSCRIBE /wps_event" in data:
3825             self.handle_wps_event()
3826         else:
3827             self.handle_others(data)
3828
3829     def handle_upnp_info(self):
3830         self.wfile.write(gen_upnp_info())
3831
3832     def handle_wps_control(self):
3833         self.wfile.write(gen_wps_control())
3834
3835     def handle_wps_event(self):
3836         self.wfile.write(gen_wps_event())
3837
3838     def handle_others(self, data):
3839         logger.info("Ignore HTTP request: " + data)
3840
3841 class MyTCPServer(SocketServer.TCPServer):
3842     def __init__(self, addr, handler):
3843         self.allow_reuse_address = True
3844         SocketServer.TCPServer.__init__(self, addr, handler)
3845
3846 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3847                  location_url=None):
3848     socket.setdefaulttimeout(1)
3849     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3850     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3851     sock.bind(("239.255.255.250", 1900))
3852     dev.request("WPS_ER_START ifname=lo")
3853     for i in range(100):
3854         (msg,addr) = sock.recvfrom(1000)
3855         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3856         if "M-SEARCH" in msg:
3857             break
3858         if not wait_m_search:
3859             raise Exception("Not an M-SEARCH")
3860         if i == 99:
3861             raise Exception("No M-SEARCH seen")
3862
3863     # Add an AP with a valid URL and server listing to it
3864     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3865     if not location_url:
3866         location_url = 'http://127.0.0.1:12345/foo.xml'
3867     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)
3868     server.timeout = 1
3869     return server,sock
3870
3871 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3872     sock.close()
3873     server.server_close()
3874
3875     if on_alloc_fail:
3876         done = False
3877         for i in range(50):
3878             res = dev.request("GET_ALLOC_FAIL")
3879             if res.startswith("0:"):
3880                 done = True
3881                 break
3882             time.sleep(0.1)
3883         if not done:
3884             raise Exception("No allocation failure reported")
3885     else:
3886         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3887         if ev is None:
3888             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3889     dev.request("WPS_ER_STOP")
3890
3891 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
3892     try:
3893         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3894         server,sock = wps_er_start(dev, handler, location_url=location_url)
3895         global wps_event_url
3896         wps_event_url = None
3897         server.handle_request()
3898         server.handle_request()
3899         server.handle_request()
3900         server.server_close()
3901         if no_event_url:
3902             if wps_event_url:
3903                 raise Exception("Received event URL unexpectedly")
3904             return
3905         if wps_event_url is None:
3906             raise Exception("Did not get event URL")
3907         logger.info("Event URL: " + wps_event_url)
3908     finally:
3909             dev.request("WPS_ER_STOP")
3910
3911 def send_wlanevent(url, uuid, data):
3912     conn = httplib.HTTPConnection(url.netloc)
3913     payload = '''<?xml version="1.0" encoding="utf-8"?>
3914 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3915 <e:property><STAStatus>1</STAStatus></e:property>
3916 <e:property><APStatus>1</APStatus></e:property>
3917 <e:property><WLANEvent>'''
3918     payload += base64.b64encode(data)
3919     payload += '</WLANEvent></e:property></e:propertyset>'
3920     headers = { "Content-type": 'text/xml; charset="utf-8"',
3921                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3922                 "HOST": url.netloc,
3923                 "NT": "upnp:event",
3924                 "SID": "uuid:" + uuid,
3925                 "SEQ": "0",
3926                 "Content-Length": str(len(payload)) }
3927     conn.request("NOTIFY", url.path, payload, headers)
3928     resp = conn.getresponse()
3929     if resp.status != 200:
3930         raise Exception("Unexpected HTTP response: %d" % resp.status)
3931
3932 def test_ap_wps_er_http_proto(dev, apdev):
3933     """WPS ER HTTP protocol testing"""
3934     try:
3935         _test_ap_wps_er_http_proto(dev, apdev)
3936     finally:
3937         dev[0].request("WPS_ER_STOP")
3938
3939 def _test_ap_wps_er_http_proto(dev, apdev):
3940     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3941     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
3942     global wps_event_url
3943     wps_event_url = None
3944     server.handle_request()
3945     server.handle_request()
3946     server.handle_request()
3947     server.server_close()
3948     if wps_event_url is None:
3949         raise Exception("Did not get event URL")
3950     logger.info("Event URL: " + wps_event_url)
3951
3952     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3953     if ev is None:
3954         raise Exception("No WPS-ER-AP-ADD event")
3955     if uuid not in ev:
3956         raise Exception("UUID mismatch")
3957
3958     sock.close()
3959
3960     logger.info("Valid Probe Request notification")
3961     url = urlparse.urlparse(wps_event_url)
3962     conn = httplib.HTTPConnection(url.netloc)
3963     payload = '''<?xml version="1.0" encoding="utf-8"?>
3964 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3965 <e:property><STAStatus>1</STAStatus></e:property>
3966 <e:property><APStatus>1</APStatus></e:property>
3967 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
3968 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
3969 RGV2aWNlIEEQSQAGADcqAAEg
3970 </WLANEvent></e:property>
3971 </e:propertyset>
3972 '''
3973     headers = { "Content-type": 'text/xml; charset="utf-8"',
3974                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3975                 "HOST": url.netloc,
3976                 "NT": "upnp:event",
3977                 "SID": "uuid:" + uuid,
3978                 "SEQ": "0",
3979                 "Content-Length": str(len(payload)) }
3980     conn.request("NOTIFY", url.path, payload, headers)
3981     resp = conn.getresponse()
3982     if resp.status != 200:
3983         raise Exception("Unexpected HTTP response: %d" % resp.status)
3984
3985     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
3986     if ev is None:
3987         raise Exception("No WPS-ER-ENROLLEE-ADD event")
3988     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
3989         raise Exception("No Enrollee UUID match")
3990
3991     logger.info("Incorrect event URL AP id")
3992     conn = httplib.HTTPConnection(url.netloc)
3993     conn.request("NOTIFY", url.path + '123', payload, headers)
3994     resp = conn.getresponse()
3995     if resp.status != 404:
3996         raise Exception("Unexpected HTTP response: %d" % resp.status)
3997
3998     logger.info("Missing AP id")
3999     conn = httplib.HTTPConnection(url.netloc)
4000     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4001                  payload, headers)
4002     time.sleep(0.1)
4003
4004     logger.info("Incorrect event URL event id")
4005     conn = httplib.HTTPConnection(url.netloc)
4006     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4007     time.sleep(0.1)
4008
4009     logger.info("Incorrect event URL prefix")
4010     conn = httplib.HTTPConnection(url.netloc)
4011     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4012     resp = conn.getresponse()
4013     if resp.status != 404:
4014         raise Exception("Unexpected HTTP response: %d" % resp.status)
4015
4016     logger.info("Unsupported request")
4017     conn = httplib.HTTPConnection(url.netloc)
4018     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4019     resp = conn.getresponse()
4020     if resp.status != 501:
4021         raise Exception("Unexpected HTTP response: %d" % resp.status)
4022
4023     logger.info("Unsupported request and OOM")
4024     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4025         conn = httplib.HTTPConnection(url.netloc)
4026         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4027         time.sleep(0.5)
4028
4029     logger.info("Too short WLANEvent")
4030     data = '\x00'
4031     send_wlanevent(url, uuid, data)
4032
4033     logger.info("Invalid WLANEventMAC")
4034     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4035     send_wlanevent(url, uuid, data)
4036
4037     logger.info("Unknown WLANEventType")
4038     data = '\xff02:00:00:00:00:00'
4039     send_wlanevent(url, uuid, data)
4040
4041     logger.info("Probe Request notification without any attributes")
4042     data = '\x0102:00:00:00:00:00'
4043     send_wlanevent(url, uuid, data)
4044
4045     logger.info("Probe Request notification with invalid attribute")
4046     data = '\x0102:00:00:00:00:00\xff'
4047     send_wlanevent(url, uuid, data)
4048
4049     logger.info("EAP message without any attributes")
4050     data = '\x0202:00:00:00:00:00'
4051     send_wlanevent(url, uuid, data)
4052
4053     logger.info("EAP message with invalid attribute")
4054     data = '\x0202:00:00:00:00:00\xff'
4055     send_wlanevent(url, uuid, data)
4056
4057     logger.info("EAP message from new STA and not M1")
4058     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4059     send_wlanevent(url, uuid, data)
4060
4061     logger.info("EAP message: M1")
4062     data = '\x0202:00:00:00:00:00'
4063     data += '\x10\x22\x00\x01\x04'
4064     data += '\x10\x47\x00\x10' + 16*'\x00'
4065     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4066     data += '\x10\x1a\x00\x10' + 16*'\x00'
4067     data += '\x10\x32\x00\xc0' + 192*'\x00'
4068     data += '\x10\x04\x00\x02\x00\x00'
4069     data += '\x10\x10\x00\x02\x00\x00'
4070     data += '\x10\x0d\x00\x01\x00'
4071     data += '\x10\x08\x00\x02\x00\x00'
4072     data += '\x10\x44\x00\x01\x00'
4073     data += '\x10\x21\x00\x00'
4074     data += '\x10\x23\x00\x00'
4075     data += '\x10\x24\x00\x00'
4076     data += '\x10\x42\x00\x00'
4077     data += '\x10\x54\x00\x08' + 8*'\x00'
4078     data += '\x10\x11\x00\x00'
4079     data += '\x10\x3c\x00\x01\x00'
4080     data += '\x10\x02\x00\x02\x00\x00'
4081     data += '\x10\x12\x00\x02\x00\x00'
4082     data += '\x10\x09\x00\x02\x00\x00'
4083     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4084     m1 = data
4085     send_wlanevent(url, uuid, data)
4086
4087     logger.info("EAP message: WSC_ACK")
4088     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4089     send_wlanevent(url, uuid, data)
4090
4091     logger.info("EAP message: M1")
4092     send_wlanevent(url, uuid, m1)
4093
4094     logger.info("EAP message: WSC_NACK")
4095     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4096     send_wlanevent(url, uuid, data)
4097
4098     logger.info("EAP message: M1 - Too long attribute values")
4099     data = '\x0202:00:00:00:00:00'
4100     data += '\x10\x11\x00\x21' + 33*'\x00'
4101     data += '\x10\x45\x00\x21' + 33*'\x00'
4102     data += '\x10\x42\x00\x21' + 33*'\x00'
4103     data += '\x10\x24\x00\x21' + 33*'\x00'
4104     data += '\x10\x23\x00\x21' + 33*'\x00'
4105     data += '\x10\x21\x00\x41' + 65*'\x00'
4106     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4107     send_wlanevent(url, uuid, data)
4108
4109     logger.info("EAP message: M1 missing UUID-E")
4110     data = '\x0202:00:00:00:00:00'
4111     data += '\x10\x22\x00\x01\x04'
4112     send_wlanevent(url, uuid, data)
4113
4114     logger.info("EAP message: M1 missing MAC Address")
4115     data += '\x10\x47\x00\x10' + 16*'\x00'
4116     send_wlanevent(url, uuid, data)
4117
4118     logger.info("EAP message: M1 missing Enrollee Nonce")
4119     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4120     send_wlanevent(url, uuid, data)
4121
4122     logger.info("EAP message: M1 missing Public Key")
4123     data += '\x10\x1a\x00\x10' + 16*'\x00'
4124     send_wlanevent(url, uuid, data)
4125
4126     logger.info("EAP message: M1 missing Authentication Type flags")
4127     data += '\x10\x32\x00\xc0' + 192*'\x00'
4128     send_wlanevent(url, uuid, data)
4129
4130     logger.info("EAP message: M1 missing Encryption Type Flags")
4131     data += '\x10\x04\x00\x02\x00\x00'
4132     send_wlanevent(url, uuid, data)
4133
4134     logger.info("EAP message: M1 missing Connection Type flags")
4135     data += '\x10\x10\x00\x02\x00\x00'
4136     send_wlanevent(url, uuid, data)
4137
4138     logger.info("EAP message: M1 missing Config Methods")
4139     data += '\x10\x0d\x00\x01\x00'
4140     send_wlanevent(url, uuid, data)
4141
4142     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4143     data += '\x10\x08\x00\x02\x00\x00'
4144     send_wlanevent(url, uuid, data)
4145
4146     logger.info("EAP message: M1 missing Manufacturer")
4147     data += '\x10\x44\x00\x01\x00'
4148     send_wlanevent(url, uuid, data)
4149
4150     logger.info("EAP message: M1 missing Model Name")
4151     data += '\x10\x21\x00\x00'
4152     send_wlanevent(url, uuid, data)
4153
4154     logger.info("EAP message: M1 missing Model Number")
4155     data += '\x10\x23\x00\x00'
4156     send_wlanevent(url, uuid, data)
4157
4158     logger.info("EAP message: M1 missing Serial Number")
4159     data += '\x10\x24\x00\x00'
4160     send_wlanevent(url, uuid, data)
4161
4162     logger.info("EAP message: M1 missing Primary Device Type")
4163     data += '\x10\x42\x00\x00'
4164     send_wlanevent(url, uuid, data)
4165
4166     logger.info("EAP message: M1 missing Device Name")
4167     data += '\x10\x54\x00\x08' + 8*'\x00'
4168     send_wlanevent(url, uuid, data)
4169
4170     logger.info("EAP message: M1 missing RF Bands")
4171     data += '\x10\x11\x00\x00'
4172     send_wlanevent(url, uuid, data)
4173
4174     logger.info("EAP message: M1 missing Association State")
4175     data += '\x10\x3c\x00\x01\x00'
4176     send_wlanevent(url, uuid, data)
4177
4178     logger.info("EAP message: M1 missing Device Password ID")
4179     data += '\x10\x02\x00\x02\x00\x00'
4180     send_wlanevent(url, uuid, data)
4181
4182     logger.info("EAP message: M1 missing Configuration Error")
4183     data += '\x10\x12\x00\x02\x00\x00'
4184     send_wlanevent(url, uuid, data)
4185
4186     logger.info("EAP message: M1 missing OS Version")
4187     data += '\x10\x09\x00\x02\x00\x00'
4188     send_wlanevent(url, uuid, data)
4189
4190     logger.info("Check max concurrent requests")
4191     addr = (url.hostname, url.port)
4192     socks = {}
4193     for i in range(20):
4194         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4195                                  socket.IPPROTO_TCP)
4196         socks[i].connect(addr)
4197     for i in range(20):
4198         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4199     count = 0
4200     for i in range(20):
4201         try:
4202             res = socks[i].recv(100)
4203             if "HTTP/1" in res:
4204                 count += 1
4205         except:
4206             pass
4207         socks[i].close()
4208     logger.info("%d concurrent HTTP GET operations returned response" % count)
4209     if count < 10:
4210         raise Exception("Too few concurrent HTTP connections accepted")
4211
4212     logger.info("OOM in HTTP server")
4213     for func in [ "http_request_init", "httpread_create",
4214                   "eloop_register_timeout;httpread_create",
4215                   "eloop_register_sock;httpread_create",
4216                   "httpread_hdr_analyze" ]:
4217         with alloc_fail(dev[0], 1, func):
4218             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4219                                  socket.IPPROTO_TCP)
4220             sock.connect(addr)
4221             sock.send("GET / HTTP/1.1\r\n\r\n")
4222             try:
4223                 sock.recv(100)
4224             except:
4225                 pass
4226             sock.close()
4227
4228     logger.info("Invalid HTTP header")
4229     for req in [ " GET / HTTP/1.1\r\n\r\n",
4230                  "HTTP/1.1 200 OK\r\n\r\n",
4231                  "HTTP/\r\n\r\n",
4232                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4233                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4234                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4235                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4236                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4237                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4238                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4239                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4240         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4241                              socket.IPPROTO_TCP)
4242         sock.settimeout(0.1)
4243         sock.connect(addr)
4244         sock.send(req)
4245         try:
4246             sock.recv(100)
4247         except:
4248             pass
4249         sock.close()
4250
4251     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4252         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4253                              socket.IPPROTO_TCP)
4254         sock.connect(addr)
4255         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4256         try:
4257             sock.recv(100)
4258         except:
4259             pass
4260         sock.close()
4261
4262     conn = httplib.HTTPConnection(url.netloc)
4263     payload = '<foo'
4264     headers = { "Content-type": 'text/xml; charset="utf-8"',
4265                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4266                 "HOST": url.netloc,
4267                 "NT": "upnp:event",
4268                 "SID": "uuid:" + uuid,
4269                 "SEQ": "0",
4270                 "Content-Length": str(len(payload)) }
4271     conn.request("NOTIFY", url.path, payload, headers)
4272     resp = conn.getresponse()
4273     if resp.status != 200:
4274         raise Exception("Unexpected HTTP response: %d" % resp.status)
4275
4276     conn = httplib.HTTPConnection(url.netloc)
4277     payload = '<WLANEvent foo></WLANEvent>'
4278     headers = { "Content-type": 'text/xml; charset="utf-8"',
4279                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4280                 "HOST": url.netloc,
4281                 "NT": "upnp:event",
4282                 "SID": "uuid:" + uuid,
4283                 "SEQ": "0",
4284                 "Content-Length": str(len(payload)) }
4285     conn.request("NOTIFY", url.path, payload, headers)
4286     resp = conn.getresponse()
4287     if resp.status != 200:
4288         raise Exception("Unexpected HTTP response: %d" % resp.status)
4289
4290     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4291         send_wlanevent(url, uuid, '')
4292
4293     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4294         send_wlanevent(url, uuid, 'foo')
4295
4296     for func in [ "wps_init",
4297                   "wps_process_manufacturer",
4298                   "wps_process_model_name",
4299                   "wps_process_model_number",
4300                   "wps_process_serial_number",
4301                   "wps_process_dev_name" ]:
4302         with alloc_fail(dev[0], 1, func):
4303             send_wlanevent(url, uuid, m1)
4304
4305 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4306     """WPS ER HTTP protocol testing - no eventSubURL"""
4307     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4308         def handle_upnp_info(self):
4309             self.wfile.write(gen_upnp_info(eventSubURL=None))
4310     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4311                           no_event_url=True)
4312
4313 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4314     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4315     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4316         def handle_upnp_info(self):
4317             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4318     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4319                           no_event_url=True)
4320
4321 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4322     """WPS ER HTTP protocol testing - subscribe OOM"""
4323     try:
4324         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4325     finally:
4326         dev[0].request("WPS_ER_STOP")
4327
4328 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4329     tests = [ (1, "http_client_url_parse"),
4330               (1, "wpabuf_alloc;wps_er_subscribe"),
4331               (1, "http_client_addr"),
4332               (1, "eloop_register_sock;http_client_addr"),
4333               (1, "eloop_register_timeout;http_client_addr") ]
4334     for count,func in tests:
4335         with alloc_fail(dev[0], count, func):
4336             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4337             server.handle_request()
4338             server.handle_request()
4339             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4340
4341 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4342     """WPS ER HTTP protocol testing - no SID"""
4343     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4344         def handle_wps_event(self):
4345             self.wfile.write(gen_wps_event(sid=None))
4346     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4347
4348 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4349     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4350     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4351         def handle_wps_event(self):
4352             self.wfile.write(gen_wps_event(sid='FOO'))
4353     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4354
4355 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4356     """WPS ER HTTP protocol testing - invalid SID UUID"""
4357     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4358         def handle_wps_event(self):
4359             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4360     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4361
4362 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4363     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4364     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4365         def handle_wps_event(self):
4366             payload = ""
4367             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4368                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4369                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4370                   'Connection: close\r\n' + \
4371                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4372                   'Timeout: Second-1801\r\n' + \
4373                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4374             self.wfile.write(hdr + payload)
4375     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4376
4377 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4378     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4379     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4380         def handle_wps_event(self):
4381             payload = ""
4382             hdr = 'HTTP/1.1 FOO\r\n' + \
4383                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4384                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4385                   'Connection: close\r\n' + \
4386                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4387                   'Timeout: Second-1801\r\n' + \
4388                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4389             self.wfile.write(hdr + payload)
4390     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4391
4392 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4393     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4394     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4395         def handle_wps_control(self):
4396             payload = '''<?xml version="1.0"?>
4397 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4398 <s:Body>
4399 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4400 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4401 </u:GetDeviceInfoResponse>
4402 </s:Body>
4403 </s:Envelope>
4404 '''
4405             self.wfile.write(gen_wps_control(payload_override=payload))
4406     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4407
4408 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4409     """WPS ER HTTP protocol testing - No device in UPnP info"""
4410     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4411         def handle_upnp_info(self):
4412             payload = '''<?xml version="1.0"?>
4413 <root xmlns="urn:schemas-upnp-org:device-1-0">
4414 <specVersion>
4415 <major>1</major>
4416 <minor>0</minor>
4417 </specVersion>
4418 </root>
4419 '''
4420             hdr = 'HTTP/1.1 200 OK\r\n' + \
4421                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4422                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4423                   'Connection: close\r\n' + \
4424                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4425                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4426             self.wfile.write(hdr + payload)
4427     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4428
4429 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4430     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4431     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4432         def handle_upnp_info(self):
4433             payload = '''<?xml version="1.0"?>
4434 <root xmlns="urn:schemas-upnp-org:device-1-0">
4435 <specVersion>
4436 <major>1</major>
4437 <minor>0</minor>
4438 </specVersion>
4439 <device>
4440 </device>
4441 </root>
4442 '''
4443             hdr = 'HTTP/1.1 200 OK\r\n' + \
4444                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4445                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4446                   'Connection: close\r\n' + \
4447                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4448                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4449             self.wfile.write(hdr + payload)
4450     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4451
4452 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4453     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4454     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4455         def handle_upnp_info(self):
4456             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4457     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4458
4459 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4460     """WPS ER HTTP protocol testing - no controlURL"""
4461     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4462         def handle_upnp_info(self):
4463             self.wfile.write(gen_upnp_info(controlURL=None))
4464     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4465                           no_event_url=True)
4466
4467 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4468     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4469     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4470         def handle_upnp_info(self):
4471             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4472     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4473                           no_event_url=True)
4474
4475 def test_ap_wps_http_timeout(dev, apdev):
4476     """WPS AP/ER and HTTP timeout"""
4477     try:
4478         _test_ap_wps_http_timeout(dev, apdev)
4479     finally:
4480         dev[0].request("WPS_ER_STOP")
4481
4482 def _test_ap_wps_http_timeout(dev, apdev):
4483     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4484     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4485
4486     location = ssdp_get_location(ap_uuid)
4487     url = urlparse.urlparse(location)
4488     addr = (url.hostname, url.port)
4489     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4490     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4491                          socket.IPPROTO_TCP)
4492     sock.connect(addr)
4493     sock.send("G")
4494
4495     class DummyServer(SocketServer.StreamRequestHandler):
4496         def handle(self):
4497             logger.debug("DummyServer - start 31 sec wait")
4498             time.sleep(31)
4499             logger.debug("DummyServer - wait done")
4500
4501     logger.debug("Start WPS ER")
4502     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4503                                 wait_m_search=True)
4504
4505     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4506     # This will wait for 31 seconds..
4507     server.handle_request()
4508
4509     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4510     try:
4511         sock.send("ET / HTTP/1.1\r\n\r\n")
4512         res = sock.recv(100)
4513         sock.close()
4514     except:
4515         pass
4516
4517 def test_ap_wps_er_url_parse(dev, apdev):
4518     """WPS ER and URL parsing special cases"""
4519     try:
4520         _test_ap_wps_er_url_parse(dev, apdev)
4521     finally:
4522         dev[0].request("WPS_ER_STOP")
4523
4524 def _test_ap_wps_er_url_parse(dev, apdev):
4525     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4526     sock.settimeout(1)
4527     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4528     sock.bind(("239.255.255.250", 1900))
4529     dev[0].request("WPS_ER_START ifname=lo")
4530     (msg,addr) = sock.recvfrom(1000)
4531     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4532     if "M-SEARCH" not in msg:
4533         raise Exception("Not an M-SEARCH")
4534     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)
4535     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4536     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)
4537     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4538     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)
4539     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4540
4541     sock.close()
4542
4543 def test_ap_wps_er_link_update(dev, apdev):
4544     """WPS ER and link update special cases"""
4545     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4546         def handle_upnp_info(self):
4547             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4548     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4549
4550     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4551         def handle_others(self, data):
4552             if "GET / " in data:
4553                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4554     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4555                           location_url='http://127.0.0.1:12345')
4556
4557 def test_ap_wps_er_http_client(dev, apdev):
4558     """WPS ER and HTTP client special cases"""
4559     with alloc_fail(dev[0], 1, "http_link_update"):
4560         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4561
4562     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4563         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4564
4565     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4566         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4567
4568     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4569         def handle_upnp_info(self):
4570             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4571     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4572                           no_event_url=True)
4573
4574 def test_ap_wps_init_oom(dev, apdev):
4575     """wps_init OOM cases"""
4576     ssid = "test-wps"
4577     appin = "12345670"
4578     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4579                "ap_pin": appin }
4580     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4581     pin = dev[0].wps_read_pin()
4582
4583     with alloc_fail(hapd, 1, "wps_init"):
4584         hapd.request("WPS_PIN any " + pin)
4585         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4586         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4587         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4588         if ev is None:
4589             raise Exception("No EAP failure reported")
4590         dev[0].request("WPS_CANCEL")
4591
4592     with alloc_fail(dev[0], 2, "wps_init"):
4593         hapd.request("WPS_PIN any " + pin)
4594         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4595         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4596         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4597         if ev is None:
4598             raise Exception("No EAP failure reported")
4599         dev[0].request("WPS_CANCEL")
4600
4601     with alloc_fail(dev[0], 2, "wps_init"):
4602         hapd.request("WPS_PBC")
4603         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4604         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4605         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4606         if ev is None:
4607             raise Exception("No EAP failure reported")
4608         dev[0].request("WPS_CANCEL")
4609
4610     dev[0].dump_monitor()
4611     new_ssid = "wps-new-ssid"
4612     new_passphrase = "1234567890"
4613     with alloc_fail(dev[0], 3, "wps_init"):
4614         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4615                        new_passphrase, no_wait=True)
4616         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4617         if ev is None:
4618             raise Exception("No EAP failure reported")
4619
4620     dev[0].flush_scan_cache()
4621
4622 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4623     """WPS and invalid IE in Association Request frame"""
4624     ssid = "test-wps"
4625     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4626     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4627     pin = "12345670"
4628     hapd.request("WPS_PIN any " + pin)
4629     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4630     try:
4631         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4632         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4633         for i in range(5):
4634             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4635             if ev and "vendor=14122" in ev:
4636                 break
4637         if ev is None or "vendor=14122" not in ev:
4638             raise Exception("EAP-WSC not started")
4639         dev[0].request("WPS_CANCEL")
4640     finally:
4641         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4642
4643 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4644     """WPS PBC/PIN mismatch"""
4645     ssid = "test-wps"
4646     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4647     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4648     hapd.request("SET wps_version_number 0x10")
4649     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4650     hapd.request("WPS_PBC")
4651     pin = dev[0].wps_read_pin()
4652     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4653     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4654     if ev is None:
4655         raise Exception("Scan did not complete")
4656     dev[0].request("WPS_CANCEL")
4657
4658     hapd.request("WPS_CANCEL")
4659     dev[0].flush_scan_cache()
4660
4661 def test_ap_wps_ie_invalid(dev, apdev):
4662     """WPS PIN attempt with AP that has invalid WSC IE"""
4663     ssid = "test-wps"
4664     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4665                "vendor_elements": "dd050050f20410" }
4666     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4667     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4668     hostapd.add_ap(apdev[1]['ifname'], params)
4669     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4670     pin = dev[0].wps_read_pin()
4671     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4672     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4673     if ev is None:
4674         raise Exception("Scan did not complete")
4675     dev[0].request("WPS_CANCEL")
4676
4677 def test_ap_wps_scan_prio_order(dev, apdev):
4678     """WPS scan priority ordering"""
4679     ssid = "test-wps"
4680     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4681     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4682     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4683     hostapd.add_ap(apdev[1]['ifname'], params)
4684     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4685     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4686     pin = dev[0].wps_read_pin()
4687     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4688     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4689     if ev is None:
4690         raise Exception("Scan did not complete")
4691     dev[0].request("WPS_CANCEL")
4692
4693 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4694     """WPS ProbeReq IE OOM"""
4695     ssid = "test-wps"
4696     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4697     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4698     pin = dev[0].wps_read_pin()
4699     hapd.request("WPS_PIN any " + pin)
4700     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4701     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4702         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4703         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4704         if ev is None:
4705             raise Exception("Association not seen")
4706     dev[0].request("WPS_CANCEL")
4707
4708     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4709         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4710         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4711         if ev is None:
4712             raise Exception("Association not seen")
4713     dev[0].request("WPS_CANCEL")
4714
4715 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4716     """WPS AssocReq IE OOM"""
4717     ssid = "test-wps"
4718     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4719     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4720     pin = dev[0].wps_read_pin()
4721     hapd.request("WPS_PIN any " + pin)
4722     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4723     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4724         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4725         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4726         if ev is None:
4727             raise Exception("Association not seen")
4728     dev[0].request("WPS_CANCEL")
4729
4730 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4731     """WPS AssocResp IE OOM"""
4732     ssid = "test-wps"
4733     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4734     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4735     pin = dev[0].wps_read_pin()
4736     hapd.request("WPS_PIN any " + pin)
4737     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4738     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4739         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4740         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4741         if ev is None:
4742             raise Exception("Association not seen")
4743     dev[0].request("WPS_CANCEL")
4744
4745 def test_ap_wps_bss_info_errors(dev, apdev):
4746     """WPS BSS info errors"""
4747     params = { "ssid": "1",
4748                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4749     hostapd.add_ap(apdev[0]['ifname'], params)
4750     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4751     hostapd.add_ap(apdev[1]['ifname'], params)
4752     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4753     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4754     bss = dev[0].get_bss(apdev[0]['bssid'])
4755     logger.info("BSS: " + str(bss))
4756     if "wps_state" in bss:
4757         raise Exception("Unexpected wps_state in BSS info")
4758     if 'wps_device_name' not in bss:
4759         raise Exception("No wps_device_name in BSS info")
4760     if bss['wps_device_name'] != '_':
4761         raise Exception("Unexpected wps_device_name value")
4762     bss = dev[0].get_bss(apdev[1]['bssid'])
4763     logger.info("BSS: " + str(bss))
4764
4765     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4766         bss = dev[0].get_bss(apdev[0]['bssid'])
4767         logger.info("BSS(OOM): " + str(bss))
4768
4769 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4770     hapd.request("WPS_PBC")
4771     dev.scan_for_bss(apdev['bssid'], freq="2412")
4772     dev.request("WPS_PBC " + apdev['bssid'])
4773     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4774     if ev is None:
4775         raise Exception("No EAP failure reported")
4776     dev.request("WPS_CANCEL")
4777     dev.wait_disconnected()
4778     for i in range(5):
4779         try:
4780             dev.flush_scan_cache()
4781             break
4782         except Exception, e:
4783             if str(e).startswith("Failed to trigger scan"):
4784                 # Try again
4785                 time.sleep(1)
4786             else:
4787                 raise
4788
4789 def wps_run_pbc_fail(apdev, dev):
4790     hapd = wps_start_ap(apdev)
4791     wps_run_pbc_fail_ap(apdev, dev, hapd)
4792
4793 def test_ap_wps_pk_oom(dev, apdev):
4794     """WPS and public key OOM"""
4795     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4796         wps_run_pbc_fail(apdev[0], dev[0])
4797
4798 def test_ap_wps_pk_oom_ap(dev, apdev):
4799     """WPS and public key OOM on AP"""
4800     hapd = wps_start_ap(apdev[0])
4801     with alloc_fail(hapd, 1, "wps_build_public_key"):
4802         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4803
4804 def test_ap_wps_encr_oom_ap(dev, apdev):
4805     """WPS and encrypted settings decryption OOM on AP"""
4806     hapd = wps_start_ap(apdev[0])
4807     pin = dev[0].wps_read_pin()
4808     hapd.request("WPS_PIN any " + pin)
4809     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4810     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4811         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4812         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4813         if ev is None:
4814             raise Exception("No WPS-FAIL reported")
4815         dev[0].request("WPS_CANCEL")
4816     dev[0].wait_disconnected()
4817
4818 def test_ap_wps_encr_no_random_ap(dev, apdev):
4819     """WPS and no random data available for encryption on AP"""
4820     hapd = wps_start_ap(apdev[0])
4821     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4822         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4823
4824 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4825     """WPS and no random data available for e-hash on STA"""
4826     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4827         wps_run_pbc_fail(apdev[0], dev[0])
4828
4829 def test_ap_wps_m1_no_random(dev, apdev):
4830     """WPS and no random for M1 on STA"""
4831     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4832         wps_run_pbc_fail(apdev[0], dev[0])
4833
4834 def test_ap_wps_m1_oom(dev, apdev):
4835     """WPS and OOM for M1 on STA"""
4836     with alloc_fail(dev[0], 1, "wps_build_m1"):
4837         wps_run_pbc_fail(apdev[0], dev[0])
4838
4839 def test_ap_wps_m3_oom(dev, apdev):
4840     """WPS and OOM for M3 on STA"""
4841     with alloc_fail(dev[0], 1, "wps_build_m3"):
4842         wps_run_pbc_fail(apdev[0], dev[0])
4843
4844 def test_ap_wps_m5_oom(dev, apdev):
4845     """WPS and OOM for M5 on STA"""
4846     hapd = wps_start_ap(apdev[0])
4847     hapd.request("WPS_PBC")
4848     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4849     for i in range(1, 3):
4850         with alloc_fail(dev[0], i, "wps_build_m5"):
4851             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4852             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4853             if ev is None:
4854                 raise Exception("No EAP failure reported")
4855             dev[0].request("WPS_CANCEL")
4856             dev[0].wait_disconnected()
4857     dev[0].flush_scan_cache()
4858
4859 def test_ap_wps_m5_no_random(dev, apdev):
4860     """WPS and no random for M5 on STA"""
4861     with fail_test(dev[0], 1,
4862                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
4863         wps_run_pbc_fail(apdev[0], dev[0])
4864
4865 def test_ap_wps_m7_oom(dev, apdev):
4866     """WPS and OOM for M7 on STA"""
4867     hapd = wps_start_ap(apdev[0])
4868     hapd.request("WPS_PBC")
4869     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4870     for i in range(1, 3):
4871         with alloc_fail(dev[0], i, "wps_build_m7"):
4872             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4873             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4874             if ev is None:
4875                 raise Exception("No EAP failure reported")
4876             dev[0].request("WPS_CANCEL")
4877             dev[0].wait_disconnected()
4878     dev[0].flush_scan_cache()
4879
4880 def test_ap_wps_m7_no_random(dev, apdev):
4881     """WPS and no random for M7 on STA"""
4882     with fail_test(dev[0], 1,
4883                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
4884         wps_run_pbc_fail(apdev[0], dev[0])
4885
4886 def test_ap_wps_wsc_done_oom(dev, apdev):
4887     """WPS and OOM for WSC_Done on STA"""
4888     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
4889         wps_run_pbc_fail(apdev[0], dev[0])
4890
4891 def test_ap_wps_random_psk_fail(dev, apdev):
4892     """WPS and no random for PSK on AP"""
4893     ssid = "test-wps"
4894     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
4895     appin = "12345670"
4896     try:
4897         os.remove(pskfile)
4898     except:
4899         pass
4900
4901     try:
4902         with open(pskfile, "w") as f:
4903             f.write("# WPA PSKs\n")
4904
4905         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4906                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
4907                    "rsn_pairwise": "CCMP", "ap_pin": appin,
4908                    "wpa_psk_file": pskfile }
4909         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4910
4911         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4912         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
4913             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
4914             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4915             if ev is None:
4916                 raise Exception("No EAP failure reported")
4917             dev[0].request("WPS_CANCEL")
4918         dev[0].wait_disconnected()
4919
4920         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
4921             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4922
4923         with alloc_fail(hapd, 1, "wps_build_cred"):
4924             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4925
4926         with alloc_fail(hapd, 2, "wps_build_cred"):
4927             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4928     finally:
4929         os.remove(pskfile)
4930
4931 def wps_ext_eap_identity_req(dev, hapd, bssid):
4932     logger.debug("EAP-Identity/Request")
4933     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4934     if ev is None:
4935         raise Exception("Timeout on EAPOL-TX from hostapd")
4936     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
4937     if "OK" not in res:
4938         raise Exception("EAPOL_RX to wpa_supplicant failed")
4939
4940 def wps_ext_eap_identity_resp(hapd, dev, addr):
4941     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
4942     if ev is None:
4943         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
4944     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
4945     if "OK" not in res:
4946         raise Exception("EAPOL_RX to hostapd failed")
4947
4948 def wps_ext_eap_wsc(dst, src, src_addr, msg):
4949     logger.debug(msg)
4950     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4951     if ev is None:
4952         raise Exception("Timeout on EAPOL-TX")
4953     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
4954     if "OK" not in res:
4955         raise Exception("EAPOL_RX failed")
4956
4957 def wps_start_ext(apdev, dev, pbc=False, pin=None):
4958     addr = dev.own_addr()
4959     bssid = apdev['bssid']
4960     ssid = "test-wps-conf"
4961     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4962                "wpa_passphrase": "12345678", "wpa": "2",
4963                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
4964     hapd = hostapd.add_ap(apdev['ifname'], params)
4965
4966     if pbc:
4967         hapd.request("WPS_PBC")
4968     else:
4969         if pin is None:
4970             pin = dev.wps_read_pin()
4971         hapd.request("WPS_PIN any " + pin)
4972     dev.scan_for_bss(bssid, freq="2412")
4973     hapd.request("SET ext_eapol_frame_io 1")
4974     dev.request("SET ext_eapol_frame_io 1")
4975
4976     if pbc:
4977         dev.request("WPS_PBC " + bssid)
4978     else:
4979         dev.request("WPS_PIN " + bssid + " " + pin)
4980     return addr,bssid,hapd
4981
4982 def wps_auth_corrupt(dst, src, addr):
4983     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4984     if ev is None:
4985         raise Exception("Timeout on EAPOL-TX")
4986     src.request("SET ext_eapol_frame_io 0")
4987     dst.request("SET ext_eapol_frame_io 0")
4988     msg = ev.split(' ')[2]
4989     if msg[-24:-16] != '10050008':
4990         raise Exception("Could not find Authenticator attribute")
4991     # Corrupt Authenticator value
4992     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
4993     res = dst.request("EAPOL_RX " + addr + " " + msg)
4994     if "OK" not in res:
4995         raise Exception("EAPOL_RX failed")
4996
4997 def wps_fail_finish(hapd, dev, fail_str):
4998     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
4999     if ev is None:
5000         raise Exception("WPS-FAIL not indicated")
5001     if fail_str not in ev:
5002         raise Exception("Unexpected WPS-FAIL value: " + ev)
5003     dev.request("WPS_CANCEL")
5004     dev.wait_disconnected()
5005
5006 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5007     wps_auth_corrupt(dev, hapd, bssid)
5008     wps_fail_finish(hapd, dev, fail_str)
5009
5010 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5011     wps_auth_corrupt(hapd, dev, addr)
5012     wps_fail_finish(hapd, dev, fail_str)
5013
5014 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5015     """WPS and Authenticator attribute mismatch in M2"""
5016     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5017     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5018     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5019     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5020     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5021     logger.debug("M2")
5022     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5023
5024 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5025     """WPS and Authenticator attribute mismatch in M3"""
5026     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5027     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5028     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5029     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5030     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5031     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5032     logger.debug("M3")
5033     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5034
5035 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5036     """WPS and Authenticator attribute mismatch in M4"""
5037     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5038     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5039     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5040     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5041     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5042     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5043     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5044     logger.debug("M4")
5045     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5046
5047 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5048     """WPS and Authenticator attribute mismatch in M5"""
5049     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5050     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5051     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5052     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5053     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5054     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5055     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5056     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5057     logger.debug("M5")
5058     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5059
5060 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5061     """WPS and Authenticator attribute mismatch in M6"""
5062     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5063     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5064     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5065     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5066     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5067     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5068     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5069     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5070     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5071     logger.debug("M6")
5072     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5073
5074 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5075     """WPS and Authenticator attribute mismatch in M7"""
5076     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5077     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5078     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5079     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5080     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5081     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5082     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5083     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5084     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5085     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5086     logger.debug("M7")
5087     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5088
5089 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5090     """WPS and Authenticator attribute mismatch in M8"""
5091     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5092     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5093     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5094     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5095     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5096     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5097     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5098     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5099     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5100     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5101     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5102     logger.debug("M8")
5103     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5104
5105 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5106     """WPS and Authenticator attribute missing from M2"""
5107     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5108     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5109     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5110     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5111     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5112     logger.debug("M2")
5113     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5114     if ev is None:
5115         raise Exception("Timeout on EAPOL-TX")
5116     hapd.request("SET ext_eapol_frame_io 0")
5117     dev[0].request("SET ext_eapol_frame_io 0")
5118     msg = ev.split(' ')[2]
5119     if msg[-24:-16] != '10050008':
5120         raise Exception("Could not find Authenticator attribute")
5121     # Remove Authenticator value
5122     msg = msg[:-24]
5123     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5124     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5125     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5126     if "OK" not in res:
5127         raise Exception("EAPOL_RX failed")
5128     wps_fail_finish(hapd, dev[0], "msg=5")
5129
5130 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5131     """WPS and M2 with different Device Password ID (P2P)"""
5132     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5133     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5134     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5135     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5136     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5137     logger.debug("M2")
5138     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5139     if ev is None:
5140         raise Exception("Timeout on EAPOL-TX")
5141     hapd.request("SET ext_eapol_frame_io 0")
5142     dev[0].request("SET ext_eapol_frame_io 0")
5143     msg = ev.split(' ')[2]
5144     if msg[722:730] != '10120002':
5145         raise Exception("Could not find Device Password ID attribute")
5146     # Replace Device Password ID value. This will fail Authenticator check, but
5147     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5148     # log.
5149     msg = msg[0:730] + "0005" + msg[734:]
5150     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5151     if "OK" not in res:
5152         raise Exception("EAPOL_RX failed")
5153     wps_fail_finish(hapd, dev[0], "msg=5")
5154
5155 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5156     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5157     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5158     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5159     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5160     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5161     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5162     logger.debug("M2")
5163     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5164     if ev is None:
5165         raise Exception("Timeout on EAPOL-TX")
5166     hapd.request("SET ext_eapol_frame_io 0")
5167     dev[0].request("SET ext_eapol_frame_io 0")
5168     msg = ev.split(' ')[2]
5169     if msg[722:730] != '10120002':
5170         raise Exception("Could not find Device Password ID attribute")
5171     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5172     msg = msg[0:730] + "0004" + msg[734:]
5173     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5174     if "OK" not in res:
5175         raise Exception("EAPOL_RX failed")
5176     wps_fail_finish(hapd, dev[0], "msg=5")
5177
5178 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5179     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5180     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5181     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5182     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5183     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5184     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5185     logger.debug("M2")
5186     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5187     if ev is None:
5188         raise Exception("Timeout on EAPOL-TX")
5189     hapd.request("SET ext_eapol_frame_io 0")
5190     dev[0].request("SET ext_eapol_frame_io 0")
5191     msg = ev.split(' ')[2]
5192     if msg[722:730] != '10120002':
5193         raise Exception("Could not find Device Password ID attribute")
5194     # Replace Device Password ID value. This will fail Authenticator check, but
5195     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5196     # log.
5197     msg = msg[0:730] + "0000" + msg[734:]
5198     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5199     if "OK" not in res:
5200         raise Exception("EAPOL_RX failed")
5201     wps_fail_finish(hapd, dev[0], "msg=5")
5202     dev[0].flush_scan_cache()
5203
5204 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5205     """WPS and M2 without Device Password ID"""
5206     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5207     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5208     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5209     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5210     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5211     logger.debug("M2")
5212     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5213     if ev is None:
5214         raise Exception("Timeout on EAPOL-TX")
5215     hapd.request("SET ext_eapol_frame_io 0")
5216     dev[0].request("SET ext_eapol_frame_io 0")
5217     msg = ev.split(' ')[2]
5218     if msg[722:730] != '10120002':
5219         raise Exception("Could not find Device Password ID attribute")
5220     # Remove Device Password ID value. This will fail Authenticator check, but
5221     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5222     # log.
5223     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5224     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5225     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5226     if "OK" not in res:
5227         raise Exception("EAPOL_RX failed")
5228     wps_fail_finish(hapd, dev[0], "msg=5")
5229
5230 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5231     """WPS and M2 without Registrar Nonce"""
5232     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5233     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5234     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5235     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5236     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5237     logger.debug("M2")
5238     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5239     if ev is None:
5240         raise Exception("Timeout on EAPOL-TX")
5241     hapd.request("SET ext_eapol_frame_io 0")
5242     dev[0].request("SET ext_eapol_frame_io 0")
5243     msg = ev.split(' ')[2]
5244     if msg[96:104] != '10390010':
5245         raise Exception("Could not find Registrar Nonce attribute")
5246     # Remove Registrar Nonce. This will fail Authenticator check, but
5247     # allows the code path in wps_process_registrar_nonce() to be checked from
5248     # the debug log.
5249     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5250     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5251     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5252     if "OK" not in res:
5253         raise Exception("EAPOL_RX failed")
5254     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5255     if ev is None:
5256         raise Exception("Disconnect event not seen")
5257     dev[0].request("WPS_CANCEL")
5258     dev[0].flush_scan_cache()
5259
5260 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5261     """WPS and M2 without Enrollee Nonce"""
5262     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5263     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5264     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5265     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5266     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5267     logger.debug("M2")
5268     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5269     if ev is None:
5270         raise Exception("Timeout on EAPOL-TX")
5271     hapd.request("SET ext_eapol_frame_io 0")
5272     dev[0].request("SET ext_eapol_frame_io 0")
5273     msg = ev.split(' ')[2]
5274     if msg[56:64] != '101a0010':
5275         raise Exception("Could not find enrollee Nonce attribute")
5276     # Remove Enrollee Nonce. This will fail Authenticator check, but
5277     # allows the code path in wps_process_enrollee_nonce() to be checked from
5278     # the debug log.
5279     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5280     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5281     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5282     if "OK" not in res:
5283         raise Exception("EAPOL_RX failed")
5284     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5285     if ev is None:
5286         raise Exception("Disconnect event not seen")
5287     dev[0].request("WPS_CANCEL")
5288     dev[0].flush_scan_cache()
5289
5290 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5291     """WPS and M2 without UUID-R"""
5292     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5293     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5294     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5295     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5296     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5297     logger.debug("M2")
5298     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5299     if ev is None:
5300         raise Exception("Timeout on EAPOL-TX")
5301     hapd.request("SET ext_eapol_frame_io 0")
5302     dev[0].request("SET ext_eapol_frame_io 0")
5303     msg = ev.split(' ')[2]
5304     if msg[136:144] != '10480010':
5305         raise Exception("Could not find enrollee Nonce attribute")
5306     # Remove UUID-R. This will fail Authenticator check, but allows the code
5307     # path in wps_process_uuid_r() to be checked from the debug log.
5308     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5309     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5310     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5311     if "OK" not in res:
5312         raise Exception("EAPOL_RX failed")
5313     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5314     if ev is None:
5315         raise Exception("Disconnect event not seen")
5316     dev[0].request("WPS_CANCEL")
5317     dev[0].flush_scan_cache()
5318
5319 def test_ap_wps_m2_invalid(dev, apdev):
5320     """WPS and M2 parsing failure"""
5321     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5322     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5323     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5324     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5325     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5326     logger.debug("M2")
5327     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5328     if ev is None:
5329         raise Exception("Timeout on EAPOL-TX")
5330     hapd.request("SET ext_eapol_frame_io 0")
5331     dev[0].request("SET ext_eapol_frame_io 0")
5332     msg = ev.split(' ')[2]
5333     if msg[136:144] != '10480010':
5334         raise Exception("Could not find enrollee Nonce attribute")
5335     # Remove UUID-R. This will fail Authenticator check, but allows the code
5336     # path in wps_process_uuid_r() to be checked from the debug log.
5337     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5338     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5339     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5340     if "OK" not in res:
5341         raise Exception("EAPOL_RX failed")
5342     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5343     if ev is None:
5344         raise Exception("Disconnect event not seen")
5345     dev[0].request("WPS_CANCEL")
5346     dev[0].flush_scan_cache()
5347
5348 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5349     """WPS and M2 without Message Type"""
5350     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5351     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5352     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5353     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5354     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5355     logger.debug("M2")
5356     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5357     if ev is None:
5358         raise Exception("Timeout on EAPOL-TX")
5359     hapd.request("SET ext_eapol_frame_io 0")
5360     dev[0].request("SET ext_eapol_frame_io 0")
5361     msg = ev.split(' ')[2]
5362     if msg[46:54] != '10220001':
5363         raise Exception("Could not find Message Type attribute")
5364     # Remove Message Type. This will fail Authenticator check, but allows the
5365     # code path in wps_process_wsc_msg() to be checked from the debug log.
5366     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5367     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5368     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5369     if "OK" not in res:
5370         raise Exception("EAPOL_RX failed")
5371     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5372     if ev is None:
5373         raise Exception("Disconnect event not seen")
5374     dev[0].request("WPS_CANCEL")
5375     dev[0].flush_scan_cache()
5376
5377 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5378     """WPS and M2 but unknown Message Type"""
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[46:54] != '10220001':
5392         raise Exception("Could not find Message Type attribute")
5393     # Replace Message Type value. This will be rejected.
5394     msg = msg[0:54] + "00" + msg[56:]
5395     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5396     if "OK" not in res:
5397         raise Exception("EAPOL_RX failed")
5398     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5399     if ev is None:
5400         raise Exception("Disconnect event not seen")
5401     dev[0].request("WPS_CANCEL")
5402     dev[0].flush_scan_cache()
5403
5404 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5405     """WPS and M2 but unknown opcode"""
5406     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5407     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5408     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5409     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5410     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5411     logger.debug("M2")
5412     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5413     if ev is None:
5414         raise Exception("Timeout on EAPOL-TX")
5415     hapd.request("SET ext_eapol_frame_io 0")
5416     dev[0].request("SET ext_eapol_frame_io 0")
5417     msg = ev.split(' ')[2]
5418     # Replace opcode. This will be discarded in EAP-WSC processing.
5419     msg = msg[0:32] + "00" + msg[34:]
5420     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5421     if "OK" not in res:
5422         raise Exception("EAPOL_RX failed")
5423     dev[0].request("WPS_CANCEL")
5424     dev[0].wait_disconnected()
5425     dev[0].flush_scan_cache()
5426
5427 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5428     """WPS and M2 but unknown opcode (WSC_Start)"""
5429     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5430     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5431     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5432     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5433     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5434     logger.debug("M2")
5435     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5436     if ev is None:
5437         raise Exception("Timeout on EAPOL-TX")
5438     hapd.request("SET ext_eapol_frame_io 0")
5439     dev[0].request("SET ext_eapol_frame_io 0")
5440     msg = ev.split(' ')[2]
5441     # Replace opcode. This will be discarded in EAP-WSC processing.
5442     msg = msg[0:32] + "01" + msg[34:]
5443     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5444     if "OK" not in res:
5445         raise Exception("EAPOL_RX failed")
5446     dev[0].request("WPS_CANCEL")
5447     dev[0].wait_disconnected()
5448     dev[0].flush_scan_cache()
5449
5450 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5451     """WPS and M2 but unknown opcode (WSC_Done)"""
5452     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5453     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5454     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5455     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5456     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5457     logger.debug("M2")
5458     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5459     if ev is None:
5460         raise Exception("Timeout on EAPOL-TX")
5461     hapd.request("SET ext_eapol_frame_io 0")
5462     dev[0].request("SET ext_eapol_frame_io 0")
5463     msg = ev.split(' ')[2]
5464     # Replace opcode. This will be discarded in WPS Enrollee processing.
5465     msg = msg[0:32] + "05" + msg[34:]
5466     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5467     if "OK" not in res:
5468         raise Exception("EAPOL_RX failed")
5469     dev[0].request("WPS_CANCEL")
5470     dev[0].wait_disconnected()
5471     dev[0].flush_scan_cache()
5472
5473 def wps_m2_but_other(dev, apdev, title, msgtype):
5474     addr,bssid,hapd = wps_start_ext(apdev, dev)
5475     wps_ext_eap_identity_req(dev, hapd, bssid)
5476     wps_ext_eap_identity_resp(hapd, dev, addr)
5477     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5478     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5479     logger.debug(title)
5480     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5481     if ev is None:
5482         raise Exception("Timeout on EAPOL-TX")
5483     hapd.request("SET ext_eapol_frame_io 0")
5484     dev.request("SET ext_eapol_frame_io 0")
5485     msg = ev.split(' ')[2]
5486     if msg[46:54] != '10220001':
5487         raise Exception("Could not find Message Type attribute")
5488     # Replace Message Type value. This will be rejected.
5489     msg = msg[0:54] + msgtype + msg[56:]
5490     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5491     if "OK" not in res:
5492         raise Exception("EAPOL_RX failed")
5493     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5494     if ev is None:
5495         raise Exception("WPS-FAIL event not seen")
5496     dev.request("WPS_CANCEL")
5497     dev.wait_disconnected()
5498
5499 def wps_m4_but_other(dev, apdev, title, msgtype):
5500     addr,bssid,hapd = wps_start_ext(apdev, dev)
5501     wps_ext_eap_identity_req(dev, hapd, bssid)
5502     wps_ext_eap_identity_resp(hapd, dev, addr)
5503     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5504     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5505     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5506     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5507     logger.debug(title)
5508     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5509     if ev is None:
5510         raise Exception("Timeout on EAPOL-TX")
5511     hapd.request("SET ext_eapol_frame_io 0")
5512     dev.request("SET ext_eapol_frame_io 0")
5513     msg = ev.split(' ')[2]
5514     if msg[46:54] != '10220001':
5515         raise Exception("Could not find Message Type attribute")
5516     # Replace Message Type value. This will be rejected.
5517     msg = msg[0:54] + msgtype + msg[56:]
5518     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5519     if "OK" not in res:
5520         raise Exception("EAPOL_RX failed")
5521     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5522     if ev is None:
5523         raise Exception("WPS-FAIL event not seen")
5524     dev.request("WPS_CANCEL")
5525     dev.wait_disconnected()
5526
5527 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5528     """WPS and M2 but Message Type M4"""
5529     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5530
5531 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5532     """WPS and M2 but Message Type M6"""
5533     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5534
5535 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5536     """WPS and M2 but Message Type M8"""
5537     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5538
5539 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5540     """WPS and M4 but Message Type M2"""
5541     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5542
5543 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5544     """WPS and M4 but Message Type M2D"""
5545     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5546
5547 def test_ap_wps_config_methods(dev, apdev):
5548     """WPS configuration method parsing"""
5549     ssid = "test-wps-conf"
5550     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5551                "wpa_passphrase": "12345678", "wpa": "2",
5552                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5553                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5554     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5555     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5556                "wpa_passphrase": "12345678", "wpa": "2",
5557                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5558                "config_methods": "display push_button" }
5559     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
5560
5561 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5562     """WPS UPnP SetSelectedRegistrar protocol testing"""
5563     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5564     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5565
5566     location = ssdp_get_location(ap_uuid)
5567     urls = upnp_get_urls(location)
5568     eventurl = urlparse.urlparse(urls['event_sub_url'])
5569     ctrlurl = urlparse.urlparse(urls['control_url'])
5570     url = urlparse.urlparse(location)
5571     conn = httplib.HTTPConnection(url.netloc)
5572
5573     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5574         def handle(self):
5575             data = self.rfile.readline().strip()
5576             logger.debug(data)
5577             self.wfile.write(gen_wps_event())
5578
5579     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5580     server.timeout = 1
5581
5582     headers = { "callback": '<http://127.0.0.1:12345/event>',
5583                 "NT": "upnp:event",
5584                 "timeout": "Second-1234" }
5585     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5586     resp = conn.getresponse()
5587     if resp.status != 200:
5588         raise Exception("Unexpected HTTP response: %d" % resp.status)
5589     sid = resp.getheader("sid")
5590     logger.debug("Subscription SID " + sid)
5591     server.handle_request()
5592
5593     tests = [ (500, "10"),
5594               (200, "104a000110" + "1041000101" + "101200020000" +
5595                "105300023148" +
5596                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5597                "10480010362db47ba53a519188fb5458b986b2e4"),
5598               (200, "104a000110" + "1041000100" + "101200020000" +
5599                "105300020000"),
5600               (200, "104a000110" + "1041000100"),
5601               (200, "104a000110") ]
5602     for status,test in tests:
5603         tlvs = binascii.unhexlify(test)
5604         newmsg = base64.b64encode(tlvs)
5605         msg = '<?xml version="1.0"?>\n'
5606         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5607         msg += '<s:Body>'
5608         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5609         msg += '<NewMessage>'
5610         msg += newmsg
5611         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5612         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5613         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5614         conn.request("POST", ctrlurl.path, msg, headers)
5615         resp = conn.getresponse()
5616         if resp.status != status:
5617             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5618
5619 def test_ap_wps_adv_oom(dev, apdev):
5620     """WPS AP and advertisement OOM"""
5621     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5622     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5623
5624     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5625         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5626                           no_recv=True)
5627         time.sleep(0.2)
5628
5629     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5630         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5631                           no_recv=True)
5632         time.sleep(0.2)
5633
5634     with alloc_fail(hapd, 1,
5635                     "next_advertisement;advertisement_state_machine_stop"):
5636         hapd.disable()
5637
5638     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5639         if "FAIL" not in hapd.request("ENABLE"):
5640             raise Exception("ENABLE succeeded during OOM")
5641
5642 def test_wps_config_methods(dev):
5643     """WPS config method update"""
5644     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5645     wpas.interface_add("wlan5")
5646     if "OK" not in wpas.request("SET config_methods display label"):
5647         raise Exception("Failed to set config_methods")
5648     if wpas.request("GET config_methods").strip() != "display label":
5649         raise Exception("config_methods were not updated")
5650     if "OK" not in wpas.request("SET config_methods "):
5651         raise Exception("Failed to clear config_methods")
5652     if wpas.request("GET config_methods").strip() != "":
5653         raise Exception("config_methods were not cleared")
5654
5655 WPS_VENDOR_ID_WFA = 14122
5656 WPS_VENDOR_TYPE = 1
5657
5658 # EAP-WSC Op-Code values
5659 WSC_Start = 0x01
5660 WSC_ACK = 0x02
5661 WSC_NACK = 0x03
5662 WSC_MSG = 0x04
5663 WSC_Done = 0x05
5664 WSC_FRAG_ACK = 0x06
5665
5666 ATTR_AP_CHANNEL = 0x1001
5667 ATTR_ASSOC_STATE = 0x1002
5668 ATTR_AUTH_TYPE = 0x1003
5669 ATTR_AUTH_TYPE_FLAGS = 0x1004
5670 ATTR_AUTHENTICATOR = 0x1005
5671 ATTR_CONFIG_METHODS = 0x1008
5672 ATTR_CONFIG_ERROR = 0x1009
5673 ATTR_CONFIRM_URL4 = 0x100a
5674 ATTR_CONFIRM_URL6 = 0x100b
5675 ATTR_CONN_TYPE = 0x100c
5676 ATTR_CONN_TYPE_FLAGS = 0x100d
5677 ATTR_CRED = 0x100e
5678 ATTR_ENCR_TYPE = 0x100f
5679 ATTR_ENCR_TYPE_FLAGS = 0x1010
5680 ATTR_DEV_NAME = 0x1011
5681 ATTR_DEV_PASSWORD_ID = 0x1012
5682 ATTR_E_HASH1 = 0x1014
5683 ATTR_E_HASH2 = 0x1015
5684 ATTR_E_SNONCE1 = 0x1016
5685 ATTR_E_SNONCE2 = 0x1017
5686 ATTR_ENCR_SETTINGS = 0x1018
5687 ATTR_ENROLLEE_NONCE = 0x101a
5688 ATTR_FEATURE_ID = 0x101b
5689 ATTR_IDENTITY = 0x101c
5690 ATTR_IDENTITY_PROOF = 0x101d
5691 ATTR_KEY_WRAP_AUTH = 0x101e
5692 ATTR_KEY_ID = 0x101f
5693 ATTR_MAC_ADDR = 0x1020
5694 ATTR_MANUFACTURER = 0x1021
5695 ATTR_MSG_TYPE = 0x1022
5696 ATTR_MODEL_NAME = 0x1023
5697 ATTR_MODEL_NUMBER = 0x1024
5698 ATTR_NETWORK_INDEX = 0x1026
5699 ATTR_NETWORK_KEY = 0x1027
5700 ATTR_NETWORK_KEY_INDEX = 0x1028
5701 ATTR_NEW_DEVICE_NAME = 0x1029
5702 ATTR_NEW_PASSWORD = 0x102a
5703 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5704 ATTR_OS_VERSION = 0x102d
5705 ATTR_POWER_LEVEL = 0x102f
5706 ATTR_PSK_CURRENT = 0x1030
5707 ATTR_PSK_MAX = 0x1031
5708 ATTR_PUBLIC_KEY = 0x1032
5709 ATTR_RADIO_ENABLE = 0x1033
5710 ATTR_REBOOT = 0x1034
5711 ATTR_REGISTRAR_CURRENT = 0x1035
5712 ATTR_REGISTRAR_ESTABLISHED = 0x1036
5713 ATTR_REGISTRAR_LIST = 0x1037
5714 ATTR_REGISTRAR_MAX = 0x1038
5715 ATTR_REGISTRAR_NONCE = 0x1039
5716 ATTR_REQUEST_TYPE = 0x103a
5717 ATTR_RESPONSE_TYPE = 0x103b
5718 ATTR_RF_BANDS = 0x103c
5719 ATTR_R_HASH1 = 0x103d
5720 ATTR_R_HASH2 = 0x103e
5721 ATTR_R_SNONCE1 = 0x103f
5722 ATTR_R_SNONCE2 = 0x1040
5723 ATTR_SELECTED_REGISTRAR = 0x1041
5724 ATTR_SERIAL_NUMBER = 0x1042
5725 ATTR_WPS_STATE = 0x1044
5726 ATTR_SSID = 0x1045
5727 ATTR_TOTAL_NETWORKS = 0x1046
5728 ATTR_UUID_E = 0x1047
5729 ATTR_UUID_R = 0x1048
5730 ATTR_VENDOR_EXT = 0x1049
5731 ATTR_VERSION = 0x104a
5732 ATTR_X509_CERT_REQ = 0x104b
5733 ATTR_X509_CERT = 0x104c
5734 ATTR_EAP_IDENTITY = 0x104d
5735 ATTR_MSG_COUNTER = 0x104e
5736 ATTR_PUBKEY_HASH = 0x104f
5737 ATTR_REKEY_KEY = 0x1050
5738 ATTR_KEY_LIFETIME = 0x1051
5739 ATTR_PERMITTED_CFG_METHODS = 0x1052
5740 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
5741 ATTR_PRIMARY_DEV_TYPE = 0x1054
5742 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
5743 ATTR_PORTABLE_DEV = 0x1056
5744 ATTR_AP_SETUP_LOCKED = 0x1057
5745 ATTR_APPLICATION_EXT = 0x1058
5746 ATTR_EAP_TYPE = 0x1059
5747 ATTR_IV = 0x1060
5748 ATTR_KEY_PROVIDED_AUTO = 0x1061
5749 ATTR_802_1X_ENABLED = 0x1062
5750 ATTR_APPSESSIONKEY = 0x1063
5751 ATTR_WEPTRANSMITKEY = 0x1064
5752 ATTR_REQUESTED_DEV_TYPE = 0x106a
5753
5754 # Message Type
5755 WPS_Beacon = 0x01
5756 WPS_ProbeRequest = 0x02
5757 WPS_ProbeResponse = 0x03
5758 WPS_M1 = 0x04
5759 WPS_M2 = 0x05
5760 WPS_M2D = 0x06
5761 WPS_M3 = 0x07
5762 WPS_M4 = 0x08
5763 WPS_M5 = 0x09
5764 WPS_M6 = 0x0a
5765 WPS_M7 = 0x0b
5766 WPS_M8 = 0x0c
5767 WPS_WSC_ACK = 0x0d
5768 WPS_WSC_NACK = 0x0e
5769 WPS_WSC_DONE = 0x0f
5770
5771 def get_wsc_msg(dev):
5772     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5773     if ev is None:
5774         raise Exception("Timeout on EAPOL-TX")
5775     data = binascii.unhexlify(ev.split(' ')[2])
5776     msg = {}
5777
5778     # Parse EAPOL header
5779     if len(data) < 4:
5780         raise Exception("No room for EAPOL header")
5781     version,type,length = struct.unpack('>BBH', data[0:4])
5782     msg['eapol_version'] = version
5783     msg['eapol_type'] = type
5784     msg['eapol_length'] = length
5785     data = data[4:]
5786     if length != len(data):
5787         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
5788     if type != 0:
5789         raise Exception("Unexpected EAPOL header type: %d" % type)
5790
5791     # Parse EAP header
5792     if len(data) < 4:
5793         raise Exception("No room for EAP header")
5794     code,identifier,length = struct.unpack('>BBH', data[0:4])
5795     msg['eap_code'] = code
5796     msg['eap_identifier'] = identifier
5797     msg['eap_length'] = length
5798     data = data[4:]
5799     if msg['eapol_length'] != msg['eap_length']:
5800         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
5801
5802     # Parse EAP expanded header
5803     if len(data) < 1:
5804         raise Exception("No EAP type included")
5805     msg['eap_type'], = struct.unpack('B', data[0])
5806     data = data[1:]
5807
5808     if msg['eap_type'] == 254:
5809         if len(data) < 3 + 4:
5810             raise Exception("Truncated EAP expanded header")
5811         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
5812         data = data[7:]
5813     else:
5814         raise Exception("Unexpected EAP type")
5815
5816     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
5817         raise Exception("Unexpected Vendor-Id")
5818     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
5819         raise Exception("Unexpected Vendor-Type")
5820
5821     # Parse EAP-WSC header
5822     if len(data) < 2:
5823         raise Exception("Truncated EAP-WSC header")
5824     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
5825     data = data[2:]
5826
5827     # Parse WSC attributes
5828     msg['raw_attrs'] = data
5829     attrs = {}
5830     while len(data) > 0:
5831         if len(data) < 4:
5832             raise Exception("Truncated attribute header")
5833         attr,length = struct.unpack('>HH', data[0:4])
5834         data = data[4:]
5835         if length > len(data):
5836             raise Exception("Truncated attribute 0x%04x" % attr)
5837         attrs[attr] = data[0:length]
5838         data = data[length:]
5839     msg['wsc_attrs'] = attrs
5840
5841     if ATTR_MSG_TYPE in attrs:
5842         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
5843
5844     return msg
5845
5846 def recv_wsc_msg(dev, opcode, msg_type):
5847     msg = get_wsc_msg(dev)
5848     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
5849         raise Exception("Unexpected Op-Code/MsgType")
5850     return msg, msg['wsc_attrs'], msg['raw_attrs']
5851
5852 def build_wsc_attr(attr, payload):
5853     return struct.pack('>HH', attr, len(payload)) + payload
5854
5855 def build_attr_msg_type(msg_type):
5856     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
5857
5858 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
5859     length = 4 + 8 + 2 + len(payload)
5860     # EAPOL header
5861     msg = struct.pack('>BBH', 2, 0, length)
5862     # EAP header
5863     msg += struct.pack('>BBH', eap_code, eap_id, length)
5864     # EAP expanded header for EAP-WSC
5865     msg += struct.pack('B', 254)
5866     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
5867     msg += struct.pack('>L', WPS_VENDOR_TYPE)
5868     # EAP-WSC header
5869     msg += struct.pack('BB', opcode, 0)
5870     # WSC attributes
5871     msg += payload
5872     return msg
5873
5874 def build_eap_success(eap_id):
5875     length = 4
5876     # EAPOL header
5877     msg = struct.pack('>BBH', 2, 0, length)
5878     # EAP header
5879     msg += struct.pack('>BBH', 3, eap_id, length)
5880     return msg
5881
5882 def build_eap_failure(eap_id):
5883     length = 4
5884     # EAPOL header
5885     msg = struct.pack('>BBH', 2, 0, length)
5886     # EAP header
5887     msg += struct.pack('>BBH', 4, eap_id, length)
5888     return msg
5889
5890 def send_wsc_msg(dev, src, msg):
5891     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
5892     if "OK" not in res:
5893         raise Exception("EAPOL_RX failed")
5894
5895 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
5896 group_5_generator = 2
5897
5898 def wsc_kdf(key, label, bits):
5899     result = ''
5900     i = 1
5901     while len(result) * 8 < bits:
5902         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
5903         m = hmac.new(key, data, hashlib.sha256)
5904         result += m.digest()
5905         i += 1
5906     return result[0:bits / 8]
5907
5908 def wsc_keys(kdk):
5909     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
5910     authkey = keys[0:32]
5911     keywrapkey = keys[32:48]
5912     emsk = keys[48:80]
5913     return authkey,keywrapkey,emsk
5914
5915 def wsc_dev_pw_half_psk(authkey, dev_pw):
5916     m = hmac.new(authkey, dev_pw, hashlib.sha256)
5917     return m.digest()[0:16]
5918
5919 def wsc_dev_pw_psk(authkey, dev_pw):
5920     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
5921     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
5922     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
5923     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
5924     return psk1,psk2
5925
5926 def build_attr_authenticator(authkey, prev_msg, curr_msg):
5927     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
5928     auth = m.digest()[0:8]
5929     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
5930
5931 def build_attr_encr_settings(authkey, keywrapkey, data):
5932     m = hmac.new(authkey, data, hashlib.sha256)
5933     kwa = m.digest()[0:8]
5934     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
5935     iv = 16*'\x99'
5936     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
5937     pad_len = 16 - len(data) % 16
5938     ps = pad_len * struct.pack('B', pad_len)
5939     data += ps
5940     wrapped = aes.encrypt(data)
5941     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
5942
5943 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
5944     if len(data) < 32 or len(data) % 16 != 0:
5945         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
5946     iv = data[0:16]
5947     encr = data[16:]
5948     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
5949     decrypted = aes.decrypt(encr)
5950     pad_len, = struct.unpack('B', decrypted[-1])
5951     if pad_len > len(decrypted):
5952         raise Exception("Invalid padding in Encrypted Settings")
5953     for i in range(-pad_len, -1):
5954         if decrypted[i] != decrypted[-1]:
5955             raise Exception("Invalid PS value in Encrypted Settings")
5956     
5957     decrypted = decrypted[0:len(decrypted) - pad_len]
5958     if len(decrypted) < 12:
5959         raise Exception("Truncated Encrypted Settings plaintext")
5960     kwa = decrypted[-12:]
5961     attr,length = struct.unpack(">HH", kwa[0:4])
5962     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
5963         raise Exception("Invalid KWA header")
5964     kwa = kwa[4:]
5965     decrypted = decrypted[0:len(decrypted) - 12]
5966
5967     m = hmac.new(authkey, decrypted, hashlib.sha256)
5968     calc_kwa = m.digest()[0:8]
5969     if kwa != calc_kwa:
5970         raise Exception("KWA mismatch")
5971
5972     return decrypted
5973
5974 def zeropad_str(val, pad_len):
5975     while len(val) < pad_len * 2:
5976         val = '0' + val
5977     return val
5978
5979 def wsc_dh_init():
5980     # For now, use a hardcoded private key. In theory, this is supposed to be
5981     # randomly selected.
5982     own_private = 0x123456789
5983     own_public = pow(group_5_generator, own_private, group_5_prime)
5984     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
5985     return own_private, pk
5986
5987 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
5988     peer_public = long(binascii.hexlify(peer_pk), 16)
5989     if peer_public < 2 or peer_public >= group_5_prime:
5990         raise Exception("Invalid peer public key")
5991     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
5992         raise Exception("Unexpected Legendre symbol for peer public key")
5993
5994     shared_secret = pow(peer_public, own_private, group_5_prime)
5995     ss = zeropad_str(format(shared_secret, "02x"), 192)
5996     logger.debug("DH shared secret: " + ss)
5997
5998     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
5999     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6000
6001     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6002     kdk = m.digest()
6003     logger.debug("KDK: " + binascii.hexlify(kdk))
6004     authkey,keywrapkey,emsk = wsc_keys(kdk)
6005     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6006     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6007     logger.debug("EMSK: " + binascii.hexlify(emsk))
6008     return authkey,keywrapkey
6009
6010 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6011     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6012     logger.debug("PSK1: " + binascii.hexlify(psk1))
6013     logger.debug("PSK2: " + binascii.hexlify(psk2))
6014
6015     # Note: Secret values are supposed to be random, but hardcoded values are
6016     # fine for testing.
6017     s1 = 16*'\x77'
6018     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6019     hash1 = m.digest()
6020     logger.debug("Hash1: " + binascii.hexlify(hash1))
6021
6022     s2 = 16*'\x88'
6023     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6024     hash2 = m.digest()
6025     logger.debug("Hash2: " + binascii.hexlify(hash2))
6026     return s1,s2,hash1,hash2
6027
6028 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6029              manufacturer='', model_name='', config_methods='\x00\x00'):
6030     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6031     attrs += build_attr_msg_type(WPS_M1)
6032     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6033     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6034     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6035     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6036     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6037     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6038     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6039     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6040     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6041     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6042     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6043     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6044     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6045     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6046     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6047     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6048     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6049     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6050     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6051     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6052     m1 = build_eap_wsc(2, eap_id, attrs)
6053     return m1, attrs
6054
6055 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6056              dev_pw_id='\x00\x00', eap_code=1):
6057     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6058     attrs += build_attr_msg_type(WPS_M2)
6059     if e_nonce:
6060         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6061     if r_nonce:
6062         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6063     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6064     if r_pk:
6065         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6066     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6067     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6068     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6069     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6070     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6071     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6072     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6073     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6074     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6075     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6076     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6077     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6078     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6079     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6080     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6081     attrs += build_attr_authenticator(authkey, m1, attrs)
6082     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6083     return m2, attrs
6084
6085 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6086     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6087     attrs += build_attr_msg_type(WPS_M2D)
6088     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6089     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6090     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6091     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6092     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6093     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6094     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6095     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6096     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6097     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6098     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6099     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6100     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6101     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6102     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6103     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6104     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6105     if dev_pw_id:
6106         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6107     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6108     return m2d, attrs
6109
6110 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6111     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6112     if msg_type is not None:
6113         attrs += build_attr_msg_type(msg_type)
6114     if e_nonce:
6115         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6116     if r_nonce:
6117         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6118     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6119     return msg, attrs
6120
6121 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6122                msg_type=WPS_WSC_NACK, eap_code=1):
6123     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6124     if msg_type is not None:
6125         attrs += build_attr_msg_type(msg_type)
6126     if e_nonce:
6127         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6128     if r_nonce:
6129         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6130     if config_error:
6131         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6132     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6133     return msg, attrs
6134
6135 def test_wps_ext(dev, apdev):
6136     """WPS against external implementation"""
6137     pin = "12345670"
6138     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6139     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6140     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6141
6142     logger.debug("Receive WSC/Start from AP")
6143     msg = get_wsc_msg(hapd)
6144     if msg['wsc_opcode'] != WSC_Start:
6145         raise Exception("Unexpected Op-Code for WSC/Start")
6146     wsc_start_id = msg['eap_identifier']
6147
6148     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6149     uuid_e = 16*'\x11'
6150     e_nonce = 16*'\x22'
6151     own_private, e_pk = wsc_dh_init()
6152
6153     logger.debug("Send M1 to AP")
6154     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6155                                 e_nonce, e_pk)
6156     send_wsc_msg(hapd, addr, m1)
6157
6158     logger.debug("Receive M2 from AP")
6159     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6160
6161     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6162                                     mac_addr, e_nonce,
6163                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6164     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6165                                                 m2_attrs[ATTR_PUBLIC_KEY])
6166
6167     logger.debug("Send M3 to AP")
6168     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6169     attrs += build_attr_msg_type(WPS_M3)
6170     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6171                             m2_attrs[ATTR_REGISTRAR_NONCE])
6172     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6173     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6174     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6175     raw_m3_attrs = attrs
6176     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6177     send_wsc_msg(hapd, addr, m3)
6178
6179     logger.debug("Receive M4 from AP")
6180     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6181
6182     logger.debug("Send M5 to AP")
6183     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6184     attrs += build_attr_msg_type(WPS_M5)
6185     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6186                             m2_attrs[ATTR_REGISTRAR_NONCE])
6187     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6188     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6189     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6190     raw_m5_attrs = attrs
6191     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6192     send_wsc_msg(hapd, addr, m5)
6193
6194     logger.debug("Receive M6 from AP")
6195     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6196
6197     logger.debug("Send M7 to AP")
6198     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6199     attrs += build_attr_msg_type(WPS_M7)
6200     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6201                             m2_attrs[ATTR_REGISTRAR_NONCE])
6202     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6203     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6204     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6205     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6206     raw_m7_attrs = attrs
6207     send_wsc_msg(hapd, addr, m7)
6208
6209     logger.debug("Receive M8 from AP")
6210     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6211     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6212                                          m8_attrs[ATTR_ENCR_SETTINGS])
6213     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6214
6215     logger.debug("Prepare WSC_Done")
6216     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6217     attrs += build_attr_msg_type(WPS_WSC_DONE)
6218     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6219     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6220                             m2_attrs[ATTR_REGISTRAR_NONCE])
6221     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6222     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6223     # AP disconnects.
6224
6225     uuid_r = 16*'\x33'
6226     r_nonce = 16*'\x44'
6227
6228     eap_id = wsc_start_id
6229     logger.debug("Send WSC/Start to STA")
6230     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6231     send_wsc_msg(dev[0], bssid, wsc_start)
6232     eap_id = (eap_id + 1) % 256
6233
6234     logger.debug("Receive M1 from STA")
6235     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6236
6237     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6238                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6239                                     r_nonce)
6240     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6241                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6242
6243     logger.debug("Send M2 to STA")
6244     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6245                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6246                                 r_nonce, uuid_r, e_pk)
6247     send_wsc_msg(dev[0], bssid, m2)
6248     eap_id = (eap_id + 1) % 256
6249
6250     logger.debug("Receive M3 from STA")
6251     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6252
6253     logger.debug("Send M4 to STA")
6254     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6255     attrs += build_attr_msg_type(WPS_M4)
6256     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6257     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6258     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6259     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6260     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6261     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6262     raw_m4_attrs = attrs
6263     m4 = build_eap_wsc(1, eap_id, attrs)
6264     send_wsc_msg(dev[0], bssid, m4)
6265     eap_id = (eap_id + 1) % 256
6266
6267     logger.debug("Receive M5 from STA")
6268     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6269
6270     logger.debug("Send M6 to STA")
6271     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6272     attrs += build_attr_msg_type(WPS_M6)
6273     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6274                             m1_attrs[ATTR_ENROLLEE_NONCE])
6275     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6276     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6277     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6278     raw_m6_attrs = attrs
6279     m6 = build_eap_wsc(1, eap_id, attrs)
6280     send_wsc_msg(dev[0], bssid, m6)
6281     eap_id = (eap_id + 1) % 256
6282
6283     logger.debug("Receive M7 from STA")
6284     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6285
6286     logger.debug("Send M8 to STA")
6287     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6288     attrs += build_attr_msg_type(WPS_M8)
6289     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6290                             m1_attrs[ATTR_ENROLLEE_NONCE])
6291     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6292     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6293     raw_m8_attrs = attrs
6294     m8 = build_eap_wsc(1, eap_id, attrs)
6295     send_wsc_msg(dev[0], bssid, m8)
6296     eap_id = (eap_id + 1) % 256
6297
6298     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6299     if ev is None:
6300         raise Exception("wpa_supplicant did not report credential")
6301
6302     logger.debug("Receive WSC_Done from STA")
6303     msg = get_wsc_msg(dev[0])
6304     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6305         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6306
6307     logger.debug("Send WSC_Done to AP")
6308     hapd.request("SET ext_eapol_frame_io 0")
6309     dev[0].request("SET ext_eapol_frame_io 0")
6310     send_wsc_msg(hapd, addr, wsc_done)
6311
6312     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6313     if ev is None:
6314         raise Exception("hostapd did not report WPS success")
6315
6316     dev[0].wait_connected()
6317
6318 def wps_start_kwa(dev, apdev):
6319     pin = "12345670"
6320     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6321     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6322     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6323     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6324
6325     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6326     uuid_r = 16*'\x33'
6327     r_nonce = 16*'\x44'
6328     own_private, e_pk = wsc_dh_init()
6329
6330     logger.debug("Receive M1 from STA")
6331     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6332     eap_id = (msg['eap_identifier'] + 1) % 256
6333
6334     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6335                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6336                                     r_nonce)
6337     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6338                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6339
6340     logger.debug("Send M2 to STA")
6341     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6342                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6343                                 r_nonce, uuid_r, e_pk)
6344     send_wsc_msg(dev[0], bssid, m2)
6345     eap_id = (eap_id + 1) % 256
6346
6347     logger.debug("Receive M3 from STA")
6348     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6349
6350     logger.debug("Send M4 to STA")
6351     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6352     attrs += build_attr_msg_type(WPS_M4)
6353     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6354     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6355     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6356
6357     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6358
6359 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6360     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6361     m4 = build_eap_wsc(1, eap_id, attrs)
6362     send_wsc_msg(dev[0], bssid, m4)
6363     eap_id = (eap_id + 1) % 256
6364
6365     logger.debug("Receive M5 from STA")
6366     msg = get_wsc_msg(dev[0])
6367     if msg['wsc_opcode'] != WSC_NACK:
6368         raise Exception("Unexpected message - expected WSC_Nack")
6369
6370     dev[0].request("WPS_CANCEL")
6371     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6372     dev[0].wait_disconnected()
6373
6374 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6375     """WPS and KWA error: No KWA attribute"""
6376     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6377     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6378     # Encrypted Settings without KWA
6379     iv = 16*'\x99'
6380     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6381     pad_len = 16 - len(data) % 16
6382     ps = pad_len * struct.pack('B', pad_len)
6383     data += ps
6384     wrapped = aes.encrypt(data)
6385     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6386     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6387
6388 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6389     """WPS and KWA error: Data after KWA"""
6390     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6391     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6392     # Encrypted Settings and data after KWA
6393     m = hmac.new(authkey, data, hashlib.sha256)
6394     kwa = m.digest()[0:8]
6395     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6396     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6397     iv = 16*'\x99'
6398     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6399     pad_len = 16 - len(data) % 16
6400     ps = pad_len * struct.pack('B', pad_len)
6401     data += ps
6402     wrapped = aes.encrypt(data)
6403     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6404     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6405
6406 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6407     """WPS and KWA error: KWA mismatch"""
6408     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6409     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6410     # Encrypted Settings and KWA with incorrect value
6411     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6412     iv = 16*'\x99'
6413     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6414     pad_len = 16 - len(data) % 16
6415     ps = pad_len * struct.pack('B', pad_len)
6416     data += ps
6417     wrapped = aes.encrypt(data)
6418     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6419     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6420
6421 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6422     pin = "12345670"
6423     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6424     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6425     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6426     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6427
6428     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6429     uuid_r = 16*'\x33'
6430     r_nonce = 16*'\x44'
6431     own_private, e_pk = wsc_dh_init()
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     eap_id = (msg['eap_identifier'] + 1) % 256
6436
6437     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6438                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6439                                     r_nonce)
6440     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6441                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6442
6443     logger.debug("Send M2 to STA")
6444     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6445                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6446                                 r_nonce, uuid_r, e_pk)
6447     send_wsc_msg(dev[0], bssid, m2)
6448     eap_id = (eap_id + 1) % 256
6449
6450     logger.debug("Receive M3 from STA")
6451     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6452
6453     logger.debug("Send M4 to STA")
6454     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6455     attrs += build_attr_msg_type(WPS_M4)
6456     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6457     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6458     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6459     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6460     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6461     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6462     raw_m4_attrs = attrs
6463     m4 = build_eap_wsc(1, eap_id, attrs)
6464     send_wsc_msg(dev[0], bssid, m4)
6465     eap_id = (eap_id + 1) % 256
6466
6467     logger.debug("Receive M5 from STA")
6468     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6469
6470     logger.debug("Send M6 to STA")
6471     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6472     attrs += build_attr_msg_type(WPS_M6)
6473     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6474                             m1_attrs[ATTR_ENROLLEE_NONCE])
6475     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6476     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6477     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6478     raw_m6_attrs = attrs
6479     m6 = build_eap_wsc(1, eap_id, attrs)
6480     send_wsc_msg(dev[0], bssid, m6)
6481     eap_id = (eap_id + 1) % 256
6482
6483     logger.debug("Receive M7 from STA")
6484     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6485
6486     logger.debug("Send M8 to STA")
6487     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6488     attrs += build_attr_msg_type(WPS_M8)
6489     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6490                             m1_attrs[ATTR_ENROLLEE_NONCE])
6491     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6492     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6493     raw_m8_attrs = attrs
6494     m8 = build_eap_wsc(1, eap_id, attrs)
6495     send_wsc_msg(dev[0], bssid, m8)
6496     eap_id = (eap_id + 1) % 256
6497
6498     if no_connect:
6499         logger.debug("Receive WSC_Done from STA")
6500         msg = get_wsc_msg(dev[0])
6501         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6502             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6503
6504         hapd.request("SET ext_eapol_frame_io 0")
6505         dev[0].request("SET ext_eapol_frame_io 0")
6506
6507         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6508
6509         dev[0].wait_disconnected()
6510         dev[0].request("REMOVE_NETWORK all")
6511     elif connect:
6512         logger.debug("Receive WSC_Done from STA")
6513         msg = get_wsc_msg(dev[0])
6514         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6515             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6516
6517         hapd.request("SET ext_eapol_frame_io 0")
6518         dev[0].request("SET ext_eapol_frame_io 0")
6519
6520         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6521
6522         dev[0].wait_connected()
6523     else:
6524         # Verify STA NACK's the credential
6525         msg = get_wsc_msg(dev[0])
6526         if msg['wsc_opcode'] != WSC_NACK:
6527             raise Exception("Unexpected message - expected WSC_Nack")
6528         dev[0].request("WPS_CANCEL")
6529         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6530         dev[0].wait_disconnected()
6531
6532 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6533                encr_type='\x00\x08', nw_key="12345678",
6534                mac_addr='\x00\x00\x00\x00\x00\x00'):
6535     attrs = ''
6536     if nw_idx is not None:
6537         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6538     if ssid is not None:
6539         attrs += build_wsc_attr(ATTR_SSID, ssid)
6540     if auth_type is not None:
6541         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6542     if encr_type is not None:
6543         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6544     if nw_key is not None:
6545         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6546     if mac_addr is not None:
6547         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6548     return build_wsc_attr(ATTR_CRED, attrs)
6549
6550 def test_wps_ext_cred_proto_success(dev, apdev):
6551     """WPS and Credential: success"""
6552     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6553     m8_cred = build_cred(mac_addr=mac_addr)
6554     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6555
6556 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6557     """WPS and Credential: MAC Address mismatch"""
6558     m8_cred = build_cred()
6559     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6560
6561 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6562     """WPS and Credential: zeropadded attributes"""
6563     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6564     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6565                          nw_key="12345678\x00")
6566     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6567
6568 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6569     """WPS and Credential: SSID missing"""
6570     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6571     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6572     wps_run_cred_proto(dev, apdev, m8_cred)
6573
6574 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6575     """WPS and Credential: Zero-length SSID"""
6576     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6577     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6578     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6579
6580 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6581     """WPS and Credential: Auth Type missing"""
6582     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6583     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6584     wps_run_cred_proto(dev, apdev, m8_cred)
6585
6586 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6587     """WPS and Credential: Encr Type missing"""
6588     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6589     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6590     wps_run_cred_proto(dev, apdev, m8_cred)
6591
6592 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6593     """WPS and Credential: Network Key missing"""
6594     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6595     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6596     wps_run_cred_proto(dev, apdev, m8_cred)
6597
6598 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6599     """WPS and Credential: Network Key missing (open)"""
6600     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6601     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6602                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6603     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6604
6605 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6606     """WPS and Credential: MAC Address missing"""
6607     m8_cred = build_cred(mac_addr=None)
6608     wps_run_cred_proto(dev, apdev, m8_cred)
6609
6610 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6611     """WPS and Credential: Invalid Encr Type"""
6612     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6613     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6614     wps_run_cred_proto(dev, apdev, m8_cred)
6615
6616 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6617     """WPS and Credential: Missing Credential"""
6618     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6619     m8_cred = ''
6620     wps_run_cred_proto(dev, apdev, m8_cred)
6621
6622 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6623     """WPS and no Public Key in M2"""
6624     pin = "12345670"
6625     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6626     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6627     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6628     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6629
6630     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6631     uuid_r = 16*'\x33'
6632     r_nonce = 16*'\x44'
6633     own_private, e_pk = wsc_dh_init()
6634
6635     logger.debug("Receive M1 from STA")
6636     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6637     eap_id = (msg['eap_identifier'] + 1) % 256
6638
6639     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6640                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6641                                     r_nonce)
6642     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6643                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6644
6645     logger.debug("Send M2 to STA")
6646     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6647                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6648                                 r_nonce, uuid_r, None)
6649     send_wsc_msg(dev[0], bssid, m2)
6650     eap_id = (eap_id + 1) % 256
6651
6652     # Verify STA NACK's the credential
6653     msg = get_wsc_msg(dev[0])
6654     if msg['wsc_opcode'] != WSC_NACK:
6655         raise Exception("Unexpected message - expected WSC_Nack")
6656     dev[0].request("WPS_CANCEL")
6657     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6658     dev[0].wait_disconnected()
6659
6660 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6661     """WPS and invalid Public Key in M2"""
6662     pin = "12345670"
6663     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6664     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6665     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6666     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6667
6668     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6669     uuid_r = 16*'\x33'
6670     r_nonce = 16*'\x44'
6671     own_private, e_pk = wsc_dh_init()
6672
6673     logger.debug("Receive M1 from STA")
6674     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6675     eap_id = (msg['eap_identifier'] + 1) % 256
6676
6677     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6678                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6679                                     r_nonce)
6680     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6681                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6682
6683     logger.debug("Send M2 to STA")
6684     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6685                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6686                                 r_nonce, uuid_r, 192*'\xff')
6687     send_wsc_msg(dev[0], bssid, m2)
6688     eap_id = (eap_id + 1) % 256
6689
6690     # Verify STA NACK's the credential
6691     msg = get_wsc_msg(dev[0])
6692     if msg['wsc_opcode'] != WSC_NACK:
6693         raise Exception("Unexpected message - expected WSC_Nack")
6694     dev[0].request("WPS_CANCEL")
6695     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6696     dev[0].wait_disconnected()
6697
6698 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6699     """WPS and Public Key OOM in M2"""
6700     pin = "12345670"
6701     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6702     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6703     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6704     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6705
6706     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6707     uuid_r = 16*'\x33'
6708     r_nonce = 16*'\x44'
6709     own_private, e_pk = wsc_dh_init()
6710
6711     logger.debug("Receive M1 from STA")
6712     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6713     eap_id = (msg['eap_identifier'] + 1) % 256
6714
6715     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6716                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6717                                     r_nonce)
6718     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6719                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6720
6721     logger.debug("Send M2 to STA")
6722     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6723                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6724                                 r_nonce, uuid_r, e_pk)
6725     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
6726         send_wsc_msg(dev[0], bssid, m2)
6727         eap_id = (eap_id + 1) % 256
6728
6729         # Verify STA NACK's the credential
6730         msg = get_wsc_msg(dev[0])
6731         if msg['wsc_opcode'] != WSC_NACK:
6732             raise Exception("Unexpected message - expected WSC_Nack")
6733         dev[0].request("WPS_CANCEL")
6734         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6735         dev[0].wait_disconnected()
6736
6737 def test_wps_ext_proto_nack_m3(dev, apdev):
6738     """WPS and NACK M3"""
6739     pin = "12345670"
6740     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6741     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6742     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6743     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6744
6745     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6746     uuid_r = 16*'\x33'
6747     r_nonce = 16*'\x44'
6748     own_private, e_pk = wsc_dh_init()
6749
6750     logger.debug("Receive M1 from STA")
6751     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6752     eap_id = (msg['eap_identifier'] + 1) % 256
6753
6754     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6755                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6756                                     r_nonce)
6757     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6758                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6759
6760     logger.debug("Send M2 to STA")
6761     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6762                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6763                                 r_nonce, uuid_r, e_pk)
6764     send_wsc_msg(dev[0], bssid, m2)
6765     eap_id = (eap_id + 1) % 256
6766
6767     logger.debug("Receive M3 from STA")
6768     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6769
6770     logger.debug("Send NACK to STA")
6771     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6772                             r_nonce, config_error='\x01\x23')
6773     send_wsc_msg(dev[0], bssid, msg)
6774     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6775     if ev is None:
6776         raise Exception("Failure not reported")
6777     if "msg=7 config_error=291" not in ev:
6778         raise Exception("Unexpected failure reason: " + ev)
6779
6780 def test_wps_ext_proto_nack_m5(dev, apdev):
6781     """WPS and NACK M5"""
6782     pin = "12345670"
6783     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6784     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6785     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6786     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6787
6788     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6789     uuid_r = 16*'\x33'
6790     r_nonce = 16*'\x44'
6791     own_private, e_pk = wsc_dh_init()
6792
6793     logger.debug("Receive M1 from STA")
6794     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6795     eap_id = (msg['eap_identifier'] + 1) % 256
6796
6797     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6798                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6799                                     r_nonce)
6800     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6801                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6802
6803     logger.debug("Send M2 to STA")
6804     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6805                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6806                                 r_nonce, uuid_r, e_pk)
6807     send_wsc_msg(dev[0], bssid, m2)
6808     eap_id = (eap_id + 1) % 256
6809
6810     logger.debug("Receive M3 from STA")
6811     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6812
6813     logger.debug("Send M4 to STA")
6814     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6815     attrs += build_attr_msg_type(WPS_M4)
6816     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6817     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6818     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6819     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6820     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6821     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6822     raw_m4_attrs = attrs
6823     m4 = build_eap_wsc(1, eap_id, attrs)
6824     send_wsc_msg(dev[0], bssid, m4)
6825     eap_id = (eap_id + 1) % 256
6826
6827     logger.debug("Receive M5 from STA")
6828     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6829
6830     logger.debug("Send NACK to STA")
6831     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6832                             r_nonce, config_error='\x01\x24')
6833     send_wsc_msg(dev[0], bssid, msg)
6834     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6835     if ev is None:
6836         raise Exception("Failure not reported")
6837     if "msg=9 config_error=292" not in ev:
6838         raise Exception("Unexpected failure reason: " + ev)
6839
6840 def wps_nack_m3(dev, apdev):
6841     pin = "00000000"
6842     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
6843     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6844     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6845     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6846
6847     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6848     uuid_r = 16*'\x33'
6849     r_nonce = 16*'\x44'
6850     own_private, e_pk = wsc_dh_init()
6851
6852     logger.debug("Receive M1 from STA")
6853     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6854     eap_id = (msg['eap_identifier'] + 1) % 256
6855
6856     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6857                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6858                                     r_nonce)
6859     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6860                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6861
6862     logger.debug("Send M2 to STA")
6863     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6864                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6865                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
6866     send_wsc_msg(dev[0], bssid, m2)
6867     eap_id = (eap_id + 1) % 256
6868
6869     logger.debug("Receive M3 from STA")
6870     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6871     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
6872
6873 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
6874     """WPS and NACK M3 missing Config Error"""
6875     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6876     logger.debug("Send NACK to STA")
6877     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
6878     send_wsc_msg(dev[0], bssid, msg)
6879     dev[0].request("WPS_CANCEL")
6880     dev[0].wait_disconnected()
6881     dev[0].flush_scan_cache()
6882
6883 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
6884     """WPS and NACK M3 missing E-Nonce"""
6885     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6886     logger.debug("Send NACK to STA")
6887     msg, attrs = build_nack(eap_id, None, r_nonce)
6888     send_wsc_msg(dev[0], bssid, msg)
6889     dev[0].request("WPS_CANCEL")
6890     dev[0].wait_disconnected()
6891     dev[0].flush_scan_cache()
6892
6893 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
6894     """WPS and NACK M3 E-Nonce mismatch"""
6895     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6896     logger.debug("Send NACK to STA")
6897     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
6898     send_wsc_msg(dev[0], bssid, msg)
6899     dev[0].request("WPS_CANCEL")
6900     dev[0].wait_disconnected()
6901     dev[0].flush_scan_cache()
6902
6903 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
6904     """WPS and NACK M3 missing R-Nonce"""
6905     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6906     logger.debug("Send NACK to STA")
6907     msg, attrs = build_nack(eap_id, e_nonce, None)
6908     send_wsc_msg(dev[0], bssid, msg)
6909     dev[0].request("WPS_CANCEL")
6910     dev[0].wait_disconnected()
6911     dev[0].flush_scan_cache()
6912
6913 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
6914     """WPS and NACK M3 R-Nonce mismatch"""
6915     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6916     logger.debug("Send NACK to STA")
6917     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
6918     send_wsc_msg(dev[0], bssid, msg)
6919     dev[0].request("WPS_CANCEL")
6920     dev[0].wait_disconnected()
6921     dev[0].flush_scan_cache()
6922
6923 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
6924     """WPS and NACK M3 no Message Type"""
6925     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6926     logger.debug("Send NACK to STA")
6927     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
6928     send_wsc_msg(dev[0], bssid, msg)
6929     dev[0].request("WPS_CANCEL")
6930     dev[0].wait_disconnected()
6931     dev[0].flush_scan_cache()
6932
6933 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
6934     """WPS and NACK M3 invalid Message Type"""
6935     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6936     logger.debug("Send NACK to STA")
6937     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
6938     send_wsc_msg(dev[0], bssid, msg)
6939     dev[0].request("WPS_CANCEL")
6940     dev[0].wait_disconnected()
6941     dev[0].flush_scan_cache()
6942
6943 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
6944     """WPS and NACK M3 invalid attribute"""
6945     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6946     logger.debug("Send NACK to STA")
6947     attrs = '\x10\x10\x00'
6948     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
6949     send_wsc_msg(dev[0], bssid, msg)
6950     dev[0].request("WPS_CANCEL")
6951     dev[0].wait_disconnected()
6952     dev[0].flush_scan_cache()
6953
6954 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
6955     """WPS and ACK M3 missing E-Nonce"""
6956     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6957     logger.debug("Send NACK to STA")
6958     msg, attrs = build_ack(eap_id, None, r_nonce)
6959     send_wsc_msg(dev[0], bssid, msg)
6960     dev[0].request("WPS_CANCEL")
6961     dev[0].wait_disconnected()
6962     dev[0].flush_scan_cache()
6963
6964 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
6965     """WPS and ACK M3 E-Nonce mismatch"""
6966     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6967     logger.debug("Send NACK to STA")
6968     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
6969     send_wsc_msg(dev[0], bssid, msg)
6970     dev[0].request("WPS_CANCEL")
6971     dev[0].wait_disconnected()
6972     dev[0].flush_scan_cache()
6973
6974 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
6975     """WPS and ACK M3 missing R-Nonce"""
6976     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6977     logger.debug("Send NACK to STA")
6978     msg, attrs = build_ack(eap_id, e_nonce, None)
6979     send_wsc_msg(dev[0], bssid, msg)
6980     dev[0].request("WPS_CANCEL")
6981     dev[0].wait_disconnected()
6982     dev[0].flush_scan_cache()
6983
6984 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
6985     """WPS and ACK M3 R-Nonce mismatch"""
6986     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6987     logger.debug("Send NACK to STA")
6988     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
6989     send_wsc_msg(dev[0], bssid, msg)
6990     dev[0].request("WPS_CANCEL")
6991     dev[0].wait_disconnected()
6992     dev[0].flush_scan_cache()
6993
6994 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
6995     """WPS and ACK M3 no Message Type"""
6996     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6997     logger.debug("Send NACK to STA")
6998     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
6999     send_wsc_msg(dev[0], bssid, msg)
7000     dev[0].request("WPS_CANCEL")
7001     dev[0].wait_disconnected()
7002     dev[0].flush_scan_cache()
7003
7004 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7005     """WPS and ACK M3 invalid Message Type"""
7006     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7007     logger.debug("Send NACK to STA")
7008     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7009     send_wsc_msg(dev[0], bssid, msg)
7010     dev[0].request("WPS_CANCEL")
7011     dev[0].wait_disconnected()
7012     dev[0].flush_scan_cache()
7013
7014 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7015     """WPS and ACK M3 invalid attribute"""
7016     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7017     logger.debug("Send ACK to STA")
7018     attrs = '\x10\x10\x00'
7019     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7020     send_wsc_msg(dev[0], bssid, msg)
7021     dev[0].request("WPS_CANCEL")
7022     dev[0].wait_disconnected()
7023     dev[0].flush_scan_cache()
7024
7025 def test_wps_ext_proto_ack_m3(dev, apdev):
7026     """WPS and ACK M3"""
7027     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7028     logger.debug("Send ACK to STA")
7029     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7030     send_wsc_msg(dev[0], bssid, msg)
7031     dev[0].request("WPS_CANCEL")
7032     dev[0].wait_disconnected()
7033     dev[0].flush_scan_cache()
7034
7035 def wps_to_m3_helper(dev, apdev):
7036     pin = "12345670"
7037     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7038     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7039     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7040     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7041
7042     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7043     uuid_r = 16*'\x33'
7044     r_nonce = 16*'\x44'
7045     own_private, e_pk = wsc_dh_init()
7046
7047     logger.debug("Receive M1 from STA")
7048     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7049     eap_id = (msg['eap_identifier'] + 1) % 256
7050
7051     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7052                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7053                                     r_nonce)
7054     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7055                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7056
7057     logger.debug("Send M2 to STA")
7058     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7059                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7060                                 r_nonce, uuid_r, e_pk)
7061     send_wsc_msg(dev[0], bssid, m2)
7062     eap_id = (eap_id + 1) % 256
7063
7064     logger.debug("Receive M3 from STA")
7065     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7066     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7067
7068 def wps_to_m3(dev, apdev):
7069     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)
7070     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7071
7072 def wps_to_m5(dev, apdev):
7073     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)
7074
7075     logger.debug("Send M4 to STA")
7076     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7077     attrs += build_attr_msg_type(WPS_M4)
7078     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7079     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7080     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7081     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7082     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7083     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7084     raw_m4_attrs = attrs
7085     m4 = build_eap_wsc(1, eap_id, attrs)
7086     send_wsc_msg(dev[0], bssid, m4)
7087     eap_id = (eap_id + 1) % 256
7088
7089     logger.debug("Receive M5 from STA")
7090     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7091
7092     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7093
7094 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7095     """WPS and no R-Hash1 in M4"""
7096     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7097
7098     logger.debug("Send M4 to STA")
7099     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7100     attrs += build_attr_msg_type(WPS_M4)
7101     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7102     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7103     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7104     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7105     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7106     attrs += build_attr_authenticator(authkey, m3, attrs)
7107     m4 = build_eap_wsc(1, eap_id, attrs)
7108     send_wsc_msg(dev[0], bssid, m4)
7109     eap_id = (eap_id + 1) % 256
7110
7111     logger.debug("Receive M5 (NACK) from STA")
7112     msg = get_wsc_msg(dev[0])
7113     if msg['wsc_opcode'] != WSC_NACK:
7114         raise Exception("Unexpected message - expected WSC_Nack")
7115
7116     dev[0].request("WPS_CANCEL")
7117     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7118     dev[0].wait_disconnected()
7119
7120 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7121     """WPS and no R-Hash2 in M4"""
7122     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7123
7124     logger.debug("Send M4 to STA")
7125     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7126     attrs += build_attr_msg_type(WPS_M4)
7127     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7128     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7129     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7130     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7131     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7132     attrs += build_attr_authenticator(authkey, m3, attrs)
7133     m4 = build_eap_wsc(1, eap_id, attrs)
7134     send_wsc_msg(dev[0], bssid, m4)
7135     eap_id = (eap_id + 1) % 256
7136
7137     logger.debug("Receive M5 (NACK) from STA")
7138     msg = get_wsc_msg(dev[0])
7139     if msg['wsc_opcode'] != WSC_NACK:
7140         raise Exception("Unexpected message - expected WSC_Nack")
7141
7142     dev[0].request("WPS_CANCEL")
7143     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7144     dev[0].wait_disconnected()
7145
7146 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7147     """WPS and no R-SNonce1 in M4"""
7148     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7149
7150     logger.debug("Send M4 to STA")
7151     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7152     attrs += build_attr_msg_type(WPS_M4)
7153     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7154     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7155     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7156     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7157     data = ''
7158     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7159     attrs += build_attr_authenticator(authkey, m3, attrs)
7160     m4 = build_eap_wsc(1, eap_id, attrs)
7161     send_wsc_msg(dev[0], bssid, m4)
7162     eap_id = (eap_id + 1) % 256
7163
7164     logger.debug("Receive M5 (NACK) from STA")
7165     msg = get_wsc_msg(dev[0])
7166     if msg['wsc_opcode'] != WSC_NACK:
7167         raise Exception("Unexpected message - expected WSC_Nack")
7168
7169     dev[0].request("WPS_CANCEL")
7170     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7171     dev[0].wait_disconnected()
7172
7173 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7174     """WPS and invalid pad string in M4"""
7175     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7176
7177     logger.debug("Send M4 to STA")
7178     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7179     attrs += build_attr_msg_type(WPS_M4)
7180     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7181     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7182     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7183     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7184
7185     m = hmac.new(authkey, data, hashlib.sha256)
7186     kwa = m.digest()[0:8]
7187     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7188     iv = 16*'\x99'
7189     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7190     pad_len = 16 - len(data) % 16
7191     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7192     data += ps
7193     wrapped = aes.encrypt(data)
7194     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7195
7196     attrs += build_attr_authenticator(authkey, m3, attrs)
7197     m4 = build_eap_wsc(1, eap_id, attrs)
7198     send_wsc_msg(dev[0], bssid, m4)
7199     eap_id = (eap_id + 1) % 256
7200
7201     logger.debug("Receive M5 (NACK) from STA")
7202     msg = get_wsc_msg(dev[0])
7203     if msg['wsc_opcode'] != WSC_NACK:
7204         raise Exception("Unexpected message - expected WSC_Nack")
7205
7206     dev[0].request("WPS_CANCEL")
7207     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7208     dev[0].wait_disconnected()
7209
7210 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7211     """WPS and invalid pad value in M4"""
7212     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7213
7214     logger.debug("Send M4 to STA")
7215     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7216     attrs += build_attr_msg_type(WPS_M4)
7217     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7218     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7219     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7220     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7221
7222     m = hmac.new(authkey, data, hashlib.sha256)
7223     kwa = m.digest()[0:8]
7224     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7225     iv = 16*'\x99'
7226     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7227     pad_len = 16 - len(data) % 16
7228     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7229     data += ps
7230     wrapped = aes.encrypt(data)
7231     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7232
7233     attrs += build_attr_authenticator(authkey, m3, attrs)
7234     m4 = build_eap_wsc(1, eap_id, attrs)
7235     send_wsc_msg(dev[0], bssid, m4)
7236     eap_id = (eap_id + 1) % 256
7237
7238     logger.debug("Receive M5 (NACK) from STA")
7239     msg = get_wsc_msg(dev[0])
7240     if msg['wsc_opcode'] != WSC_NACK:
7241         raise Exception("Unexpected message - expected WSC_Nack")
7242
7243     dev[0].request("WPS_CANCEL")
7244     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7245     dev[0].wait_disconnected()
7246
7247 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7248     """WPS and no Encr Settings in M4"""
7249     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7250
7251     logger.debug("Send M4 to STA")
7252     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7253     attrs += build_attr_msg_type(WPS_M4)
7254     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7255     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7256     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7257     attrs += build_attr_authenticator(authkey, m3, attrs)
7258     m4 = build_eap_wsc(1, eap_id, attrs)
7259     send_wsc_msg(dev[0], bssid, m4)
7260     eap_id = (eap_id + 1) % 256
7261
7262     logger.debug("Receive M5 (NACK) from STA")
7263     msg = get_wsc_msg(dev[0])
7264     if msg['wsc_opcode'] != WSC_NACK:
7265         raise Exception("Unexpected message - expected WSC_Nack")
7266
7267     dev[0].request("WPS_CANCEL")
7268     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7269     dev[0].wait_disconnected()
7270
7271 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7272     """WPS and no R-SNonce2 in M6"""
7273     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7274
7275     logger.debug("Send M6 to STA")
7276     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7277     attrs += build_attr_msg_type(WPS_M6)
7278     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7279     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7280     data = ''
7281     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7282     attrs += build_attr_authenticator(authkey, m5, attrs)
7283     m6 = build_eap_wsc(1, eap_id, attrs)
7284     send_wsc_msg(dev[0], bssid, m6)
7285     eap_id = (eap_id + 1) % 256
7286
7287     logger.debug("Receive M7 (NACK) from STA")
7288     msg = get_wsc_msg(dev[0])
7289     if msg['wsc_opcode'] != WSC_NACK:
7290         raise Exception("Unexpected message - expected WSC_Nack")
7291
7292     dev[0].request("WPS_CANCEL")
7293     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7294     dev[0].wait_disconnected()
7295
7296 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7297     """WPS and no Encr Settings in M6"""
7298     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7299
7300     logger.debug("Send M6 to STA")
7301     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7302     attrs += build_attr_msg_type(WPS_M6)
7303     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7304     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7305     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7306     attrs += build_attr_authenticator(authkey, m5, attrs)
7307     m6 = build_eap_wsc(1, eap_id, attrs)
7308     send_wsc_msg(dev[0], bssid, m6)
7309     eap_id = (eap_id + 1) % 256
7310
7311     logger.debug("Receive M7 (NACK) from STA")
7312     msg = get_wsc_msg(dev[0])
7313     if msg['wsc_opcode'] != WSC_NACK:
7314         raise Exception("Unexpected message - expected WSC_Nack")
7315
7316     dev[0].request("WPS_CANCEL")
7317     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7318     dev[0].wait_disconnected()
7319
7320 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7321     """WPS and no Encr Settings in M6"""
7322     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7323
7324     logger.debug("Send M6 to STA")
7325     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7326     attrs += build_attr_msg_type(WPS_M6)
7327     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7328     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7329     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7330     attrs += build_attr_authenticator(authkey, m5, attrs)
7331     raw_m6_attrs = attrs
7332     m6 = build_eap_wsc(1, eap_id, attrs)
7333     send_wsc_msg(dev[0], bssid, m6)
7334     eap_id = (eap_id + 1) % 256
7335
7336     logger.debug("Receive M7 from STA")
7337     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7338
7339     logger.debug("Send M8 to STA")
7340     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7341     attrs += build_attr_msg_type(WPS_M8)
7342     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7343     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7344     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7345     raw_m8_attrs = attrs
7346     m8 = build_eap_wsc(1, eap_id, attrs)
7347     send_wsc_msg(dev[0], bssid, m8)
7348
7349     logger.debug("Receive WSC_Done (NACK) from STA")
7350     msg = get_wsc_msg(dev[0])
7351     if msg['wsc_opcode'] != WSC_NACK:
7352         raise Exception("Unexpected message - expected WSC_Nack")
7353
7354     dev[0].request("WPS_CANCEL")
7355     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7356     dev[0].wait_disconnected()
7357
7358 def wps_start_ext_reg(apdev, dev):
7359     addr = dev.own_addr()
7360     bssid = apdev['bssid']
7361     ssid = "test-wps-conf"
7362     appin = "12345670"
7363     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7364                "wpa_passphrase": "12345678", "wpa": "2",
7365                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7366                "ap_pin": appin }
7367     hapd = hostapd.add_ap(apdev['ifname'], params)
7368
7369     dev.scan_for_bss(bssid, freq="2412")
7370     hapd.request("SET ext_eapol_frame_io 1")
7371     dev.request("SET ext_eapol_frame_io 1")
7372
7373     dev.request("WPS_REG " + bssid + " " + appin)
7374
7375     return addr,bssid,hapd
7376
7377 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7378     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7379     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7380     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7381
7382     logger.debug("Receive M1 from AP")
7383     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7384     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7385     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7386     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7387
7388     appin = '12345670'
7389     uuid_r = 16*'\x33'
7390     r_nonce = 16*'\x44'
7391     own_private, r_pk = wsc_dh_init()
7392     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7393                                     r_nonce)
7394     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7395
7396     logger.debug("Send M2 to AP")
7397     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7398                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7399     send_wsc_msg(hapd, addr, m2)
7400
7401     logger.debug("Receive M3 from AP")
7402     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7403
7404     logger.debug("Send M4 to AP")
7405     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7406     attrs += build_attr_msg_type(WPS_M4)
7407     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7408     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7409     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7410     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7411     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7412     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7413     raw_m4_attrs = attrs
7414     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7415     send_wsc_msg(hapd, addr, m4)
7416
7417     logger.debug("Receive M5 from AP")
7418     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7419
7420     logger.debug("Send M6 to STA")
7421     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7422     attrs += build_attr_msg_type(WPS_M6)
7423     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7424     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7425     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7426     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7427     raw_m6_attrs = attrs
7428     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7429     send_wsc_msg(hapd, addr, m6)
7430
7431     logger.debug("Receive M7 from AP")
7432     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7433
7434     logger.debug("Send M8 to STA")
7435     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7436     attrs += build_attr_msg_type(WPS_M8)
7437     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7438     if ap_settings:
7439         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7440     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7441     raw_m8_attrs = attrs
7442     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7443     send_wsc_msg(hapd, addr, m8)
7444
7445     if success:
7446         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7447         if ev is None:
7448             raise Exception("New AP settings not reported")
7449         logger.debug("Receive WSC_Done from AP")
7450         msg = get_wsc_msg(hapd)
7451         if msg['wsc_opcode'] != WSC_Done:
7452             raise Exception("Unexpected message - expected WSC_Done")
7453
7454         logger.debug("Send WSC_ACK to AP")
7455         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7456                               eap_code=2)
7457         send_wsc_msg(hapd, addr, ack)
7458         dev[0].wait_disconnected()
7459     else:
7460         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7461         if ev is None:
7462             raise Exception("WPS failure not reported")
7463         logger.debug("Receive WSC_NACK from AP")
7464         msg = get_wsc_msg(hapd)
7465         if msg['wsc_opcode'] != WSC_NACK:
7466             raise Exception("Unexpected message - expected WSC_NACK")
7467
7468         logger.debug("Send WSC_NACK to AP")
7469         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7470                                 eap_code=2)
7471         send_wsc_msg(hapd, addr, nack)
7472         dev[0].wait_disconnected()
7473
7474 def test_wps_ext_ap_settings_success(dev, apdev):
7475     """WPS and AP Settings: success"""
7476     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7477     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7478     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7479     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7480     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7481     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7482     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7483
7484 def test_wps_ext_ap_settings_missing(dev, apdev):
7485     """WPS and AP Settings: missing"""
7486     wps_run_ap_settings_proto(dev, apdev, None, False)
7487
7488 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7489     """WPS and AP Settings: MAC Address mismatch"""
7490     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7491     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7492     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7493     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7494     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7495     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7496     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7497
7498 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7499     """WPS and AP Settings: missing MAC Address"""
7500     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7501     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7502     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7503     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7504     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7505     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7506
7507 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7508     """WPS and AP Settings: reject Encr Type"""
7509     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7510     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7511     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7512     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7513     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7514     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7515     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7516
7517 def test_wps_ext_ap_settings_m2d(dev, apdev):
7518     """WPS and AP Settings: M2D"""
7519     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7520     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7521     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7522
7523     logger.debug("Receive M1 from AP")
7524     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7525     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7526
7527     r_nonce = 16*'\x44'
7528     uuid_r = 16*'\x33'
7529
7530     logger.debug("Send M2D to AP")
7531     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7532                                    e_nonce, r_nonce, uuid_r,
7533                                    dev_pw_id='\x00\x00', eap_code=2)
7534     send_wsc_msg(hapd, addr, m2d)
7535
7536     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7537     if ev is None:
7538         raise Exception("M2D not reported")
7539
7540     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7541
7542 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7543     logger.debug("Receive WSC_NACK from AP")
7544     msg = get_wsc_msg(hapd)
7545     if msg['wsc_opcode'] != WSC_NACK:
7546         raise Exception("Unexpected message - expected WSC_NACK")
7547
7548     logger.debug("Send WSC_NACK to AP")
7549     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7550                             eap_code=2)
7551     send_wsc_msg(hapd, dev.own_addr(), nack)
7552     dev.wait_disconnected()
7553
7554 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7555     """WPS proto: M3 missing E-Hash1"""
7556     pin = "12345670"
7557     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7558     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7559     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7560
7561     logger.debug("Receive WSC/Start from AP")
7562     msg = get_wsc_msg(hapd)
7563     if msg['wsc_opcode'] != WSC_Start:
7564         raise Exception("Unexpected Op-Code for WSC/Start")
7565
7566     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7567     uuid_e = 16*'\x11'
7568     e_nonce = 16*'\x22'
7569     own_private, e_pk = wsc_dh_init()
7570
7571     logger.debug("Send M1 to AP")
7572     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7573                                 e_nonce, e_pk)
7574     send_wsc_msg(hapd, addr, m1)
7575
7576     logger.debug("Receive M2 from AP")
7577     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7578     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7579     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7580
7581     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7582                                     r_nonce)
7583     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7584
7585     logger.debug("Send M3 to AP")
7586     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7587     attrs += build_attr_msg_type(WPS_M3)
7588     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7589     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7590     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7591     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7592     raw_m3_attrs = attrs
7593     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7594     send_wsc_msg(hapd, addr, m3)
7595
7596     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7597
7598 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7599     """WPS proto: M3 missing E-Hash2"""
7600     pin = "12345670"
7601     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7602     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7603     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7604
7605     logger.debug("Receive WSC/Start from AP")
7606     msg = get_wsc_msg(hapd)
7607     if msg['wsc_opcode'] != WSC_Start:
7608         raise Exception("Unexpected Op-Code for WSC/Start")
7609
7610     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7611     uuid_e = 16*'\x11'
7612     e_nonce = 16*'\x22'
7613     own_private, e_pk = wsc_dh_init()
7614
7615     logger.debug("Send M1 to AP")
7616     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7617                                 e_nonce, e_pk)
7618     send_wsc_msg(hapd, addr, m1)
7619
7620     logger.debug("Receive M2 from AP")
7621     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7622     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7623     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7624
7625     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7626                                     r_nonce)
7627     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7628
7629     logger.debug("Send M3 to AP")
7630     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7631     attrs += build_attr_msg_type(WPS_M3)
7632     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7633     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7634     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7635     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7636     raw_m3_attrs = attrs
7637     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7638     send_wsc_msg(hapd, addr, m3)
7639
7640     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7641
7642 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7643     """WPS proto: M5 missing E-SNonce1"""
7644     pin = "12345670"
7645     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7646     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7647     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7648
7649     logger.debug("Receive WSC/Start from AP")
7650     msg = get_wsc_msg(hapd)
7651     if msg['wsc_opcode'] != WSC_Start:
7652         raise Exception("Unexpected Op-Code for WSC/Start")
7653
7654     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7655     uuid_e = 16*'\x11'
7656     e_nonce = 16*'\x22'
7657     own_private, e_pk = wsc_dh_init()
7658
7659     logger.debug("Send M1 to AP")
7660     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7661                                 e_nonce, e_pk)
7662     send_wsc_msg(hapd, addr, m1)
7663
7664     logger.debug("Receive M2 from AP")
7665     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7666     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7667     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7668
7669     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7670                                     r_nonce)
7671     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7672
7673     logger.debug("Send M3 to AP")
7674     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7675     attrs += build_attr_msg_type(WPS_M3)
7676     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7677     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7678     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7679     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7680     raw_m3_attrs = attrs
7681     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7682     send_wsc_msg(hapd, addr, m3)
7683
7684     logger.debug("Receive M4 from AP")
7685     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7686
7687     logger.debug("Send M5 to AP")
7688     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7689     attrs += build_attr_msg_type(WPS_M5)
7690     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7691     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7692     data = ''
7693     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7694     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7695     raw_m5_attrs = attrs
7696     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7697     send_wsc_msg(hapd, addr, m5)
7698
7699     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7700
7701 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7702     """WPS proto: M5 E-SNonce1 mismatch"""
7703     pin = "12345670"
7704     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7705     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7706     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7707
7708     logger.debug("Receive WSC/Start from AP")
7709     msg = get_wsc_msg(hapd)
7710     if msg['wsc_opcode'] != WSC_Start:
7711         raise Exception("Unexpected Op-Code for WSC/Start")
7712
7713     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7714     uuid_e = 16*'\x11'
7715     e_nonce = 16*'\x22'
7716     own_private, e_pk = wsc_dh_init()
7717
7718     logger.debug("Send M1 to AP")
7719     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7720                                 e_nonce, e_pk)
7721     send_wsc_msg(hapd, addr, m1)
7722
7723     logger.debug("Receive M2 from AP")
7724     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7725     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7726     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7727
7728     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7729                                     r_nonce)
7730     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7731
7732     logger.debug("Send M3 to AP")
7733     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7734     attrs += build_attr_msg_type(WPS_M3)
7735     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7736     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7737     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7738     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7739     raw_m3_attrs = attrs
7740     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7741     send_wsc_msg(hapd, addr, m3)
7742
7743     logger.debug("Receive M4 from AP")
7744     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7745
7746     logger.debug("Send M5 to AP")
7747     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7748     attrs += build_attr_msg_type(WPS_M5)
7749     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7750     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
7751     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7752     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7753     raw_m5_attrs = attrs
7754     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7755     send_wsc_msg(hapd, addr, m5)
7756
7757     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7758
7759 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
7760     """WPS proto: M7 missing E-SNonce2"""
7761     pin = "12345670"
7762     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7763     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7764     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7765
7766     logger.debug("Receive WSC/Start from AP")
7767     msg = get_wsc_msg(hapd)
7768     if msg['wsc_opcode'] != WSC_Start:
7769         raise Exception("Unexpected Op-Code for WSC/Start")
7770
7771     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7772     uuid_e = 16*'\x11'
7773     e_nonce = 16*'\x22'
7774     own_private, e_pk = wsc_dh_init()
7775
7776     logger.debug("Send M1 to AP")
7777     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7778                                 e_nonce, e_pk)
7779     send_wsc_msg(hapd, addr, m1)
7780
7781     logger.debug("Receive M2 from AP")
7782     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7783     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7784     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7785
7786     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7787                                     r_nonce)
7788     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7789
7790     logger.debug("Send M3 to AP")
7791     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7792     attrs += build_attr_msg_type(WPS_M3)
7793     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7794     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7795     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7796     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7797     raw_m3_attrs = attrs
7798     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7799     send_wsc_msg(hapd, addr, m3)
7800
7801     logger.debug("Receive M4 from AP")
7802     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7803
7804     logger.debug("Send M5 to AP")
7805     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7806     attrs += build_attr_msg_type(WPS_M5)
7807     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7808     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7809     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7810     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7811     raw_m5_attrs = attrs
7812     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7813     send_wsc_msg(hapd, addr, m5)
7814
7815     logger.debug("Receive M6 from AP")
7816     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7817
7818     logger.debug("Send M7 to AP")
7819     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7820     attrs += build_attr_msg_type(WPS_M7)
7821     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7822     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
7823     data = ''
7824     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7825     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7826     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7827     raw_m7_attrs = attrs
7828     send_wsc_msg(hapd, addr, m7)
7829
7830     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7831
7832 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
7833     """WPS proto: M7 E-SNonce2 mismatch"""
7834     pin = "12345670"
7835     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7836     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7837     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7838
7839     logger.debug("Receive WSC/Start from AP")
7840     msg = get_wsc_msg(hapd)
7841     if msg['wsc_opcode'] != WSC_Start:
7842         raise Exception("Unexpected Op-Code for WSC/Start")
7843
7844     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7845     uuid_e = 16*'\x11'
7846     e_nonce = 16*'\x22'
7847     own_private, e_pk = wsc_dh_init()
7848
7849     logger.debug("Send M1 to AP")
7850     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7851                                 e_nonce, e_pk)
7852     send_wsc_msg(hapd, addr, m1)
7853
7854     logger.debug("Receive M2 from AP")
7855     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7856     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7857     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7858
7859     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7860                                     r_nonce)
7861     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7862
7863     logger.debug("Send M3 to AP")
7864     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7865     attrs += build_attr_msg_type(WPS_M3)
7866     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7867     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7868     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7869     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7870     raw_m3_attrs = attrs
7871     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7872     send_wsc_msg(hapd, addr, m3)
7873
7874     logger.debug("Receive M4 from AP")
7875     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7876
7877     logger.debug("Send M5 to AP")
7878     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7879     attrs += build_attr_msg_type(WPS_M5)
7880     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7881     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7882     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7883     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7884     raw_m5_attrs = attrs
7885     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7886     send_wsc_msg(hapd, addr, m5)
7887
7888     logger.debug("Receive M6 from AP")
7889     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7890
7891     logger.debug("Send M7 to AP")
7892     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7893     attrs += build_attr_msg_type(WPS_M7)
7894     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7895     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
7896     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7897     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7898     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7899     raw_m7_attrs = attrs
7900     send_wsc_msg(hapd, addr, m7)
7901
7902     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7903
7904 def test_wps_ext_m1_pubkey_oom(dev, apdev):
7905     """WPS proto: M1 PubKey OOM"""
7906     pin = "12345670"
7907     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7908     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7909     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7910
7911     logger.debug("Receive WSC/Start from AP")
7912     msg = get_wsc_msg(hapd)
7913     if msg['wsc_opcode'] != WSC_Start:
7914         raise Exception("Unexpected Op-Code for WSC/Start")
7915
7916     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7917     uuid_e = 16*'\x11'
7918     e_nonce = 16*'\x22'
7919     own_private, e_pk = wsc_dh_init()
7920
7921     logger.debug("Send M1 to AP")
7922     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
7923         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7924                                     e_nonce, e_pk)
7925         send_wsc_msg(hapd, addr, m1)
7926         wps_wait_eap_failure(hapd, dev[0])
7927
7928 def wps_wait_eap_failure(hapd, dev):
7929     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7930     if ev is None:
7931         raise Exception("EAP-Failure not reported")
7932     dev.wait_disconnected()
7933
7934 def test_wps_ext_m3_m1(dev, apdev):
7935     """WPS proto: M3 replaced with M1"""
7936     pin = "12345670"
7937     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7938     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7939     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7940
7941     logger.debug("Receive WSC/Start from AP")
7942     msg = get_wsc_msg(hapd)
7943     if msg['wsc_opcode'] != WSC_Start:
7944         raise Exception("Unexpected Op-Code for WSC/Start")
7945
7946     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7947     uuid_e = 16*'\x11'
7948     e_nonce = 16*'\x22'
7949     own_private, e_pk = wsc_dh_init()
7950
7951     logger.debug("Send M1 to AP")
7952     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7953                                 e_nonce, e_pk)
7954     send_wsc_msg(hapd, addr, m1)
7955
7956     logger.debug("Receive M2 from AP")
7957     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7958     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7959     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7960
7961     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7962                                     r_nonce)
7963     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7964
7965     logger.debug("Send M3(M1) to AP")
7966     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7967     attrs += build_attr_msg_type(WPS_M1)
7968     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7969     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7970     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7971     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7972     raw_m3_attrs = attrs
7973     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7974     send_wsc_msg(hapd, addr, m3)
7975
7976     wps_wait_eap_failure(hapd, dev[0])
7977
7978 def test_wps_ext_m5_m3(dev, apdev):
7979     """WPS proto: M5 replaced with M3"""
7980     pin = "12345670"
7981     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7982     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7983     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7984
7985     logger.debug("Receive WSC/Start from AP")
7986     msg = get_wsc_msg(hapd)
7987     if msg['wsc_opcode'] != WSC_Start:
7988         raise Exception("Unexpected Op-Code for WSC/Start")
7989
7990     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7991     uuid_e = 16*'\x11'
7992     e_nonce = 16*'\x22'
7993     own_private, e_pk = wsc_dh_init()
7994
7995     logger.debug("Send M1 to AP")
7996     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7997                                 e_nonce, e_pk)
7998     send_wsc_msg(hapd, addr, m1)
7999
8000     logger.debug("Receive M2 from AP")
8001     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8002     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8003     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8004
8005     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8006                                     r_nonce)
8007     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8008
8009     logger.debug("Send M3 to AP")
8010     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8011     attrs += build_attr_msg_type(WPS_M3)
8012     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8013     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8014     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8015     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8016     raw_m3_attrs = attrs
8017     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8018     send_wsc_msg(hapd, addr, m3)
8019
8020     logger.debug("Receive M4 from AP")
8021     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8022
8023     logger.debug("Send M5(M3) to AP")
8024     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8025     attrs += build_attr_msg_type(WPS_M3)
8026     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8027     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8028     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8029     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8030     raw_m5_attrs = attrs
8031     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8032     send_wsc_msg(hapd, addr, m5)
8033
8034     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8035
8036 def test_wps_ext_m3_m2(dev, apdev):
8037     """WPS proto: M3 replaced with M2"""
8038     pin = "12345670"
8039     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8040     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8041     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8042
8043     logger.debug("Receive WSC/Start from AP")
8044     msg = get_wsc_msg(hapd)
8045     if msg['wsc_opcode'] != WSC_Start:
8046         raise Exception("Unexpected Op-Code for WSC/Start")
8047
8048     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8049     uuid_e = 16*'\x11'
8050     e_nonce = 16*'\x22'
8051     own_private, e_pk = wsc_dh_init()
8052
8053     logger.debug("Send M1 to AP")
8054     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8055                                 e_nonce, e_pk)
8056     send_wsc_msg(hapd, addr, m1)
8057
8058     logger.debug("Receive M2 from AP")
8059     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8060     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8061     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8062
8063     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8064                                     r_nonce)
8065     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8066
8067     logger.debug("Send M3(M2) to AP")
8068     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8069     attrs += build_attr_msg_type(WPS_M2)
8070     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8071     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8072     raw_m3_attrs = attrs
8073     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8074     send_wsc_msg(hapd, addr, m3)
8075
8076     wps_wait_eap_failure(hapd, dev[0])
8077
8078 def test_wps_ext_m3_m5(dev, apdev):
8079     """WPS proto: M3 replaced with M5"""
8080     pin = "12345670"
8081     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8082     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8083     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8084
8085     logger.debug("Receive WSC/Start from AP")
8086     msg = get_wsc_msg(hapd)
8087     if msg['wsc_opcode'] != WSC_Start:
8088         raise Exception("Unexpected Op-Code for WSC/Start")
8089
8090     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8091     uuid_e = 16*'\x11'
8092     e_nonce = 16*'\x22'
8093     own_private, e_pk = wsc_dh_init()
8094
8095     logger.debug("Send M1 to AP")
8096     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8097                                 e_nonce, e_pk)
8098     send_wsc_msg(hapd, addr, m1)
8099
8100     logger.debug("Receive M2 from AP")
8101     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8102     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8103     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8104
8105     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8106                                     r_nonce)
8107     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8108
8109     logger.debug("Send M3(M5) to AP")
8110     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8111     attrs += build_attr_msg_type(WPS_M5)
8112     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8113     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8114     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8115     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8116     raw_m3_attrs = attrs
8117     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8118     send_wsc_msg(hapd, addr, m3)
8119
8120     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8121
8122 def test_wps_ext_m3_m7(dev, apdev):
8123     """WPS proto: M3 replaced with M7"""
8124     pin = "12345670"
8125     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8126     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8127     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8128
8129     logger.debug("Receive WSC/Start from AP")
8130     msg = get_wsc_msg(hapd)
8131     if msg['wsc_opcode'] != WSC_Start:
8132         raise Exception("Unexpected Op-Code for WSC/Start")
8133
8134     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8135     uuid_e = 16*'\x11'
8136     e_nonce = 16*'\x22'
8137     own_private, e_pk = wsc_dh_init()
8138
8139     logger.debug("Send M1 to AP")
8140     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8141                                 e_nonce, e_pk)
8142     send_wsc_msg(hapd, addr, m1)
8143
8144     logger.debug("Receive M2 from AP")
8145     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8146     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8147     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8148
8149     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8150                                     r_nonce)
8151     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8152
8153     logger.debug("Send M3(M7) to AP")
8154     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8155     attrs += build_attr_msg_type(WPS_M7)
8156     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8157     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8158     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8159     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8160     raw_m3_attrs = attrs
8161     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8162     send_wsc_msg(hapd, addr, m3)
8163
8164     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8165
8166 def test_wps_ext_m3_done(dev, apdev):
8167     """WPS proto: M3 replaced with WSC_Done"""
8168     pin = "12345670"
8169     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8170     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8171     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8172
8173     logger.debug("Receive WSC/Start from AP")
8174     msg = get_wsc_msg(hapd)
8175     if msg['wsc_opcode'] != WSC_Start:
8176         raise Exception("Unexpected Op-Code for WSC/Start")
8177
8178     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8179     uuid_e = 16*'\x11'
8180     e_nonce = 16*'\x22'
8181     own_private, e_pk = wsc_dh_init()
8182
8183     logger.debug("Send M1 to AP")
8184     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8185                                 e_nonce, e_pk)
8186     send_wsc_msg(hapd, addr, m1)
8187
8188     logger.debug("Receive M2 from AP")
8189     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8190     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8191     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8192
8193     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8194                                     r_nonce)
8195     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8196
8197     logger.debug("Send M3(WSC_Done) to AP")
8198     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8199     attrs += build_attr_msg_type(WPS_WSC_DONE)
8200     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8201     raw_m3_attrs = attrs
8202     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8203     send_wsc_msg(hapd, addr, m3)
8204
8205     wps_wait_eap_failure(hapd, dev[0])
8206
8207 def test_wps_ext_m2_nack_invalid(dev, apdev):
8208     """WPS proto: M2 followed by invalid NACK"""
8209     pin = "12345670"
8210     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8211     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8212     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8213
8214     logger.debug("Receive WSC/Start from AP")
8215     msg = get_wsc_msg(hapd)
8216     if msg['wsc_opcode'] != WSC_Start:
8217         raise Exception("Unexpected Op-Code for WSC/Start")
8218
8219     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8220     uuid_e = 16*'\x11'
8221     e_nonce = 16*'\x22'
8222     own_private, e_pk = wsc_dh_init()
8223
8224     logger.debug("Send M1 to AP")
8225     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8226                                 e_nonce, e_pk)
8227     send_wsc_msg(hapd, addr, m1)
8228
8229     logger.debug("Receive M2 from AP")
8230     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8231     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8232     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8233
8234     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8235                                     r_nonce)
8236     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8237
8238     logger.debug("Send WSC_NACK to AP")
8239     attrs = '\x10\x00\x00'
8240     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8241     send_wsc_msg(hapd, addr, nack)
8242
8243     wps_wait_eap_failure(hapd, dev[0])
8244
8245 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8246     """WPS proto: M2 followed by NACK without Msg Type"""
8247     pin = "12345670"
8248     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8249     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8250     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8251
8252     logger.debug("Receive WSC/Start from AP")
8253     msg = get_wsc_msg(hapd)
8254     if msg['wsc_opcode'] != WSC_Start:
8255         raise Exception("Unexpected Op-Code for WSC/Start")
8256
8257     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8258     uuid_e = 16*'\x11'
8259     e_nonce = 16*'\x22'
8260     own_private, e_pk = wsc_dh_init()
8261
8262     logger.debug("Send M1 to AP")
8263     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8264                                 e_nonce, e_pk)
8265     send_wsc_msg(hapd, addr, m1)
8266
8267     logger.debug("Receive M2 from AP")
8268     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8269     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8270     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8271
8272     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8273                                     r_nonce)
8274     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8275
8276     logger.debug("Send WSC_NACK to AP")
8277     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8278                             msg_type=None, eap_code=2)
8279     send_wsc_msg(hapd, addr, nack)
8280
8281     wps_wait_eap_failure(hapd, dev[0])
8282
8283 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8284     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8285     pin = "12345670"
8286     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8287     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8288     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8289
8290     logger.debug("Receive WSC/Start from AP")
8291     msg = get_wsc_msg(hapd)
8292     if msg['wsc_opcode'] != WSC_Start:
8293         raise Exception("Unexpected Op-Code for WSC/Start")
8294
8295     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8296     uuid_e = 16*'\x11'
8297     e_nonce = 16*'\x22'
8298     own_private, e_pk = wsc_dh_init()
8299
8300     logger.debug("Send M1 to AP")
8301     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8302                                 e_nonce, e_pk)
8303     send_wsc_msg(hapd, addr, m1)
8304
8305     logger.debug("Receive M2 from AP")
8306     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8307     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8308     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8309
8310     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8311                                     r_nonce)
8312     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8313
8314     logger.debug("Send WSC_NACK to AP")
8315     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8316                             msg_type=WPS_WSC_ACK, eap_code=2)
8317     send_wsc_msg(hapd, addr, nack)
8318
8319     wps_wait_eap_failure(hapd, dev[0])
8320
8321 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8322     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
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 WSC_NACK to AP")
8353     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8354                             eap_code=2)
8355     send_wsc_msg(hapd, addr, nack)
8356
8357     wps_wait_eap_failure(hapd, dev[0])
8358
8359 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8360     """WPS proto: M2 followed by NACK without Config Error"""
8361     pin = "12345670"
8362     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8363     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8364     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8365
8366     logger.debug("Receive WSC/Start from AP")
8367     msg = get_wsc_msg(hapd)
8368     if msg['wsc_opcode'] != WSC_Start:
8369         raise Exception("Unexpected Op-Code for WSC/Start")
8370
8371     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8372     uuid_e = 16*'\x11'
8373     e_nonce = 16*'\x22'
8374     own_private, e_pk = wsc_dh_init()
8375
8376     logger.debug("Send M1 to AP")
8377     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8378                                 e_nonce, e_pk)
8379     send_wsc_msg(hapd, addr, m1)
8380
8381     logger.debug("Receive M2 from AP")
8382     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8383     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8384     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8385
8386     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8387                                     r_nonce)
8388     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8389
8390     logger.debug("Send WSC_NACK to AP")
8391     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8392                             config_error=None, eap_code=2)
8393     send_wsc_msg(hapd, addr, nack)
8394
8395     wps_wait_eap_failure(hapd, dev[0])
8396
8397 def test_wps_ext_m2_ack_invalid(dev, apdev):
8398     """WPS proto: M2 followed by invalid ACK"""
8399     pin = "12345670"
8400     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8401     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8402     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8403
8404     logger.debug("Receive WSC/Start from AP")
8405     msg = get_wsc_msg(hapd)
8406     if msg['wsc_opcode'] != WSC_Start:
8407         raise Exception("Unexpected Op-Code for WSC/Start")
8408
8409     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8410     uuid_e = 16*'\x11'
8411     e_nonce = 16*'\x22'
8412     own_private, e_pk = wsc_dh_init()
8413
8414     logger.debug("Send M1 to AP")
8415     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8416                                 e_nonce, e_pk)
8417     send_wsc_msg(hapd, addr, m1)
8418
8419     logger.debug("Receive M2 from AP")
8420     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8421     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8422     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8423
8424     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8425                                     r_nonce)
8426     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8427
8428     logger.debug("Send WSC_ACK to AP")
8429     attrs = '\x10\x00\x00'
8430     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8431     send_wsc_msg(hapd, addr, ack)
8432
8433     wps_wait_eap_failure(hapd, dev[0])
8434
8435 def test_wps_ext_m2_ack(dev, apdev):
8436     """WPS proto: M2 followed by ACK"""
8437     pin = "12345670"
8438     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8439     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8440     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8441
8442     logger.debug("Receive WSC/Start from AP")
8443     msg = get_wsc_msg(hapd)
8444     if msg['wsc_opcode'] != WSC_Start:
8445         raise Exception("Unexpected Op-Code for WSC/Start")
8446
8447     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8448     uuid_e = 16*'\x11'
8449     e_nonce = 16*'\x22'
8450     own_private, e_pk = wsc_dh_init()
8451
8452     logger.debug("Send M1 to AP")
8453     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8454                                 e_nonce, e_pk)
8455     send_wsc_msg(hapd, addr, m1)
8456
8457     logger.debug("Receive M2 from AP")
8458     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8459     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8460     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8461
8462     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8463                                     r_nonce)
8464     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8465
8466     logger.debug("Send WSC_ACK to AP")
8467     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8468     send_wsc_msg(hapd, addr, ack)
8469
8470     wps_wait_eap_failure(hapd, dev[0])
8471
8472 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8473     """WPS proto: M2 followed by ACK missing Msg Type"""
8474     pin = "12345670"
8475     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8476     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8477     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8478
8479     logger.debug("Receive WSC/Start from AP")
8480     msg = get_wsc_msg(hapd)
8481     if msg['wsc_opcode'] != WSC_Start:
8482         raise Exception("Unexpected Op-Code for WSC/Start")
8483
8484     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8485     uuid_e = 16*'\x11'
8486     e_nonce = 16*'\x22'
8487     own_private, e_pk = wsc_dh_init()
8488
8489     logger.debug("Send M1 to AP")
8490     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8491                                 e_nonce, e_pk)
8492     send_wsc_msg(hapd, addr, m1)
8493
8494     logger.debug("Receive M2 from AP")
8495     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8496     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8497     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8498
8499     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8500                                     r_nonce)
8501     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8502
8503     logger.debug("Send WSC_ACK to AP")
8504     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8505                           msg_type=None, eap_code=2)
8506     send_wsc_msg(hapd, addr, ack)
8507
8508     wps_wait_eap_failure(hapd, dev[0])
8509
8510 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8511     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8512     pin = "12345670"
8513     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8514     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8515     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8516
8517     logger.debug("Receive WSC/Start from AP")
8518     msg = get_wsc_msg(hapd)
8519     if msg['wsc_opcode'] != WSC_Start:
8520         raise Exception("Unexpected Op-Code for WSC/Start")
8521
8522     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8523     uuid_e = 16*'\x11'
8524     e_nonce = 16*'\x22'
8525     own_private, e_pk = wsc_dh_init()
8526
8527     logger.debug("Send M1 to AP")
8528     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8529                                 e_nonce, e_pk)
8530     send_wsc_msg(hapd, addr, m1)
8531
8532     logger.debug("Receive M2 from AP")
8533     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8534     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8535     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8536
8537     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8538                                     r_nonce)
8539     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8540
8541     logger.debug("Send WSC_ACK to AP")
8542     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8543                           msg_type=WPS_WSC_NACK, eap_code=2)
8544     send_wsc_msg(hapd, addr, ack)
8545
8546     wps_wait_eap_failure(hapd, dev[0])
8547
8548 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8549     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8550     pin = "12345670"
8551     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8552     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8553     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8554
8555     logger.debug("Receive WSC/Start from AP")
8556     msg = get_wsc_msg(hapd)
8557     if msg['wsc_opcode'] != WSC_Start:
8558         raise Exception("Unexpected Op-Code for WSC/Start")
8559
8560     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8561     uuid_e = 16*'\x11'
8562     e_nonce = 16*'\x22'
8563     own_private, e_pk = wsc_dh_init()
8564
8565     logger.debug("Send M1 to AP")
8566     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8567                                 e_nonce, e_pk)
8568     send_wsc_msg(hapd, addr, m1)
8569
8570     logger.debug("Receive M2 from AP")
8571     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8572     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8573     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8574
8575     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8576                                     r_nonce)
8577     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8578
8579     logger.debug("Send WSC_ACK to AP")
8580     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8581                           eap_code=2)
8582     send_wsc_msg(hapd, addr, ack)
8583
8584     wps_wait_eap_failure(hapd, dev[0])
8585
8586 def test_wps_ext_m1_invalid(dev, apdev):
8587     """WPS proto: M1 failing parsing"""
8588     pin = "12345670"
8589     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8590     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8591     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8592
8593     logger.debug("Receive WSC/Start from AP")
8594     msg = get_wsc_msg(hapd)
8595     if msg['wsc_opcode'] != WSC_Start:
8596         raise Exception("Unexpected Op-Code for WSC/Start")
8597
8598     logger.debug("Send M1 to AP")
8599     attrs = '\x10\x00\x00'
8600     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8601     send_wsc_msg(hapd, addr, m1)
8602
8603     wps_wait_eap_failure(hapd, dev[0])
8604
8605 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8606     """WPS proto: M1 missing Msg Type"""
8607     pin = "12345670"
8608     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8609     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8610     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8611
8612     logger.debug("Receive WSC/Start from AP")
8613     msg = get_wsc_msg(hapd)
8614     if msg['wsc_opcode'] != WSC_Start:
8615         raise Exception("Unexpected Op-Code for WSC/Start")
8616
8617     logger.debug("Send M1 to AP")
8618     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8619     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8620     send_wsc_msg(hapd, addr, m1)
8621
8622     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8623
8624 def wps_ext_wsc_done(dev, apdev):
8625     pin = "12345670"
8626     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8627     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8628     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8629
8630     logger.debug("Receive WSC/Start from AP")
8631     msg = get_wsc_msg(hapd)
8632     if msg['wsc_opcode'] != WSC_Start:
8633         raise Exception("Unexpected Op-Code for WSC/Start")
8634
8635     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8636     uuid_e = 16*'\x11'
8637     e_nonce = 16*'\x22'
8638     own_private, e_pk = wsc_dh_init()
8639
8640     logger.debug("Send M1 to AP")
8641     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8642                                 e_nonce, e_pk)
8643     send_wsc_msg(hapd, addr, m1)
8644
8645     logger.debug("Receive M2 from AP")
8646     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8647     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8648     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8649
8650     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8651                                     r_nonce)
8652     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8653
8654     logger.debug("Send M3 to AP")
8655     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8656     attrs += build_attr_msg_type(WPS_M3)
8657     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8658     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8659     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8660     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8661     raw_m3_attrs = attrs
8662     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8663     send_wsc_msg(hapd, addr, m3)
8664
8665     logger.debug("Receive M4 from AP")
8666     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8667
8668     logger.debug("Send M5 to AP")
8669     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8670     attrs += build_attr_msg_type(WPS_M5)
8671     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8672     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8673     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8674     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8675     raw_m5_attrs = attrs
8676     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8677     send_wsc_msg(hapd, addr, m5)
8678
8679     logger.debug("Receive M6 from AP")
8680     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8681
8682     logger.debug("Send M7 to AP")
8683     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8684     attrs += build_attr_msg_type(WPS_M7)
8685     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8686     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8687     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8688     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8689     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8690     raw_m7_attrs = attrs
8691     send_wsc_msg(hapd, addr, m7)
8692
8693     logger.debug("Receive M8 from AP")
8694     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8695     return hapd, msg, e_nonce, r_nonce
8696
8697 def test_wps_ext_wsc_done_invalid(dev, apdev):
8698     """WPS proto: invalid WSC_Done"""
8699     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8700
8701     logger.debug("Send WSC_Done to AP")
8702     attrs = '\x10\x00\x00'
8703     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8704     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8705
8706     wps_wait_eap_failure(hapd, dev[0])
8707
8708 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
8709     """WPS proto: invalid WSC_Done"""
8710     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8711
8712     logger.debug("Send WSC_Done to AP")
8713     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8714     #attrs += build_attr_msg_type(WPS_WSC_DONE)
8715     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8716     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8717     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8718     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8719
8720     wps_wait_eap_failure(hapd, dev[0])
8721
8722 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
8723     """WPS proto: WSC_Done with wrong Msg Type"""
8724     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8725
8726     logger.debug("Send WSC_Done to AP")
8727     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8728     attrs += build_attr_msg_type(WPS_WSC_ACK)
8729     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8730     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8731     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8732     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8733
8734     wps_wait_eap_failure(hapd, dev[0])
8735
8736 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
8737     """WPS proto: WSC_Done without e_nonce"""
8738     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8739
8740     logger.debug("Send WSC_Done to AP")
8741     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8742     attrs += build_attr_msg_type(WPS_WSC_DONE)
8743     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8744     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8745     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8746     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8747
8748     wps_wait_eap_failure(hapd, dev[0])
8749
8750 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
8751     """WPS proto: WSC_Done without r_nonce"""
8752     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8753
8754     logger.debug("Send WSC_Done to AP")
8755     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8756     attrs += build_attr_msg_type(WPS_WSC_DONE)
8757     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8758     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8759     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8760     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8761
8762     wps_wait_eap_failure(hapd, dev[0])
8763
8764 def test_wps_ext_m7_no_encr_settings(dev, apdev):
8765     """WPS proto: M7 without Encr Settings"""
8766     pin = "12345670"
8767     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8768     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8769     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8770
8771     logger.debug("Receive WSC/Start from AP")
8772     msg = get_wsc_msg(hapd)
8773     if msg['wsc_opcode'] != WSC_Start:
8774         raise Exception("Unexpected Op-Code for WSC/Start")
8775
8776     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8777     uuid_e = 16*'\x11'
8778     e_nonce = 16*'\x22'
8779     own_private, e_pk = wsc_dh_init()
8780
8781     logger.debug("Send M1 to AP")
8782     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8783                                 e_nonce, e_pk)
8784     send_wsc_msg(hapd, addr, m1)
8785
8786     logger.debug("Receive M2 from AP")
8787     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8788     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8789     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8790
8791     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8792                                     r_nonce)
8793     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8794
8795     logger.debug("Send M3 to AP")
8796     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8797     attrs += build_attr_msg_type(WPS_M3)
8798     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8799     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8800     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8801     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8802     raw_m3_attrs = attrs
8803     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8804     send_wsc_msg(hapd, addr, m3)
8805
8806     logger.debug("Receive M4 from AP")
8807     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8808
8809     logger.debug("Send M5 to AP")
8810     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8811     attrs += build_attr_msg_type(WPS_M5)
8812     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8813     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8814     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8815     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8816     raw_m5_attrs = attrs
8817     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8818     send_wsc_msg(hapd, addr, m5)
8819
8820     logger.debug("Receive M6 from AP")
8821     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8822
8823     logger.debug("Send M7 to AP")
8824     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8825     attrs += build_attr_msg_type(WPS_M7)
8826     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8827     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8828     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8829     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8830     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8831     raw_m7_attrs = attrs
8832     send_wsc_msg(hapd, addr, m7)
8833
8834     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8835
8836 def test_wps_ext_m1_workaround(dev, apdev):
8837     """WPS proto: M1 Manufacturer/Model workaround"""
8838     pin = "12345670"
8839     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8840     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8841     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8842
8843     logger.debug("Receive WSC/Start from AP")
8844     msg = get_wsc_msg(hapd)
8845     if msg['wsc_opcode'] != WSC_Start:
8846         raise Exception("Unexpected Op-Code for WSC/Start")
8847
8848     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8849     uuid_e = 16*'\x11'
8850     e_nonce = 16*'\x22'
8851     own_private, e_pk = wsc_dh_init()
8852
8853     logger.debug("Send M1 to AP")
8854     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8855                                 e_nonce, e_pk, manufacturer='Apple TEST',
8856                                 model_name='AirPort', config_methods='\xff\xff')
8857     send_wsc_msg(hapd, addr, m1)
8858
8859     logger.debug("Receive M2 from AP")
8860     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)