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