Updated to hostap_2_6
[mech_eap.git] / libeap / tests / hwsim / test_ap_wps.py
1 # WPS tests
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 from remotehost import remote_compatible
8 import base64
9 import binascii
10 from Crypto.Cipher import AES
11 import hashlib
12 import hmac
13 import os
14 import time
15 import stat
16 import subprocess
17 import logging
18 logger = logging.getLogger()
19 import re
20 import socket
21 import struct
22 import httplib
23 import urlparse
24 import urllib
25 import xml.etree.ElementTree as ET
26 import StringIO
27 import SocketServer
28
29 import hwsim_utils
30 import hostapd
31 from wpasupplicant import WpaSupplicant
32 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
33 from utils import wait_fail_trigger
34 from test_ap_eap import int_eap_server_params
35
36 def wps_start_ap(apdev, ssid="test-wps-conf"):
37     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
38                "wpa_passphrase": "12345678", "wpa": "2",
39                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
40     return hostapd.add_ap(apdev, params)
41
42 @remote_compatible
43 def test_ap_wps_init(dev, apdev):
44     """Initial AP configuration with first WPS Enrollee"""
45     ssid = "test-wps"
46     hapd = hostapd.add_ap(apdev[0],
47                           { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
48     logger.info("WPS provisioning step")
49     hapd.request("WPS_PBC")
50     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
51         raise Exception("PBC status not shown correctly")
52
53     id = dev[0].add_network()
54     dev[0].set_network_quoted(id, "ssid", "home")
55     dev[0].set_network_quoted(id, "psk", "12345678")
56     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
57
58     id = dev[0].add_network()
59     dev[0].set_network_quoted(id, "ssid", "home2")
60     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
61     dev[0].set_network(id, "key_mgmt", "NONE")
62     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
63
64     dev[0].request("WPS_PBC")
65     dev[0].wait_connected(timeout=30)
66     status = dev[0].get_status()
67     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
68         raise Exception("Not fully connected")
69     if status['ssid'] != ssid:
70         raise Exception("Unexpected SSID")
71     if status['pairwise_cipher'] != 'CCMP':
72         raise Exception("Unexpected encryption configuration")
73     if status['key_mgmt'] != 'WPA2-PSK':
74         raise Exception("Unexpected key_mgmt")
75
76     status = hapd.request("WPS_GET_STATUS")
77     if "PBC Status: Disabled" not in status:
78         raise Exception("PBC status not shown correctly")
79     if "Last WPS result: Success" not in status:
80         raise Exception("Last WPS result not shown correctly")
81     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
82         raise Exception("Peer address not shown correctly")
83     conf = hapd.request("GET_CONFIG")
84     if "wps_state=configured" not in conf:
85         raise Exception("AP not in WPS configured state")
86     if "wpa=3" not in conf:
87         raise Exception("AP not in WPA+WPA2 configuration")
88     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
89         raise Exception("Unexpected rsn_pairwise_cipher")
90     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
91         raise Exception("Unexpected wpa_pairwise_cipher")
92     if "group_cipher=TKIP" not in conf:
93         raise Exception("Unexpected group_cipher")
94
95     if len(dev[0].list_networks()) != 3:
96         raise Exception("Unexpected number of network blocks")
97
98 def test_ap_wps_init_2ap_pbc(dev, apdev):
99     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
100     ssid = "test-wps"
101     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
102     hapd = hostapd.add_ap(apdev[0], params)
103     hostapd.add_ap(apdev[1], params)
104     logger.info("WPS provisioning step")
105     hapd.request("WPS_PBC")
106     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
107     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
108     bss = dev[0].get_bss(apdev[0]['bssid'])
109     if "[WPS-PBC]" not in bss['flags']:
110         raise Exception("WPS-PBC flag missing from AP1")
111     bss = dev[0].get_bss(apdev[1]['bssid'])
112     if "[WPS-PBC]" not in bss['flags']:
113         raise Exception("WPS-PBC flag missing from AP2")
114     dev[0].dump_monitor()
115     dev[0].request("SET wps_cred_processing 2")
116     dev[0].request("WPS_PBC")
117     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
118     dev[0].request("SET wps_cred_processing 0")
119     if ev is None:
120         raise Exception("WPS cred event not seen")
121     if "100e" not in ev:
122         raise Exception("WPS attributes not included in the cred event")
123     dev[0].wait_connected(timeout=30)
124
125     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
126     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
127     bss = dev[1].get_bss(apdev[0]['bssid'])
128     if "[WPS-PBC]" in bss['flags']:
129         raise Exception("WPS-PBC flag not cleared from AP1")
130     bss = dev[1].get_bss(apdev[1]['bssid'])
131     if "[WPS-PBC]" in bss['flags']:
132         raise Exception("WPS-PBC flag not cleared from AP2")
133
134 def test_ap_wps_init_2ap_pin(dev, apdev):
135     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
136     ssid = "test-wps"
137     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
138     hapd = hostapd.add_ap(apdev[0], params)
139     hostapd.add_ap(apdev[1], params)
140     logger.info("WPS provisioning step")
141     pin = dev[0].wps_read_pin()
142     hapd.request("WPS_PIN any " + pin)
143     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
144     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
145     bss = dev[0].get_bss(apdev[0]['bssid'])
146     if "[WPS-AUTH]" not in bss['flags']:
147         raise Exception("WPS-AUTH flag missing from AP1")
148     bss = dev[0].get_bss(apdev[1]['bssid'])
149     if "[WPS-AUTH]" not in bss['flags']:
150         raise Exception("WPS-AUTH flag missing from AP2")
151     dev[0].dump_monitor()
152     dev[0].request("WPS_PIN any " + pin)
153     dev[0].wait_connected(timeout=30)
154
155     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
156     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
157     bss = dev[1].get_bss(apdev[0]['bssid'])
158     if "[WPS-AUTH]" in bss['flags']:
159         raise Exception("WPS-AUTH flag not cleared from AP1")
160     bss = dev[1].get_bss(apdev[1]['bssid'])
161     if "[WPS-AUTH]" in bss['flags']:
162         raise Exception("WPS-AUTH flag not cleared from AP2")
163
164 @remote_compatible
165 def test_ap_wps_init_through_wps_config(dev, apdev):
166     """Initial AP configuration using wps_config command"""
167     ssid = "test-wps-init-config"
168     hapd = hostapd.add_ap(apdev[0],
169                           { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
170     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
171         raise Exception("WPS_CONFIG command failed")
172     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
173     if ev is None:
174         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
175     # It takes some time for the AP to update Beacon and Probe Response frames,
176     # so wait here before requesting the scan to be started to avoid adding
177     # extra five second wait to the test due to fetching obsolete scan results.
178     hapd.ping()
179     time.sleep(0.2)
180     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
181                    pairwise="CCMP", group="CCMP")
182
183 @remote_compatible
184 def test_ap_wps_init_through_wps_config_2(dev, apdev):
185     """AP configuration using wps_config and wps_cred_processing=2"""
186     ssid = "test-wps-init-config"
187     hapd = hostapd.add_ap(apdev[0],
188                           { "ssid": ssid, "eap_server": "1", "wps_state": "1",
189                           "wps_cred_processing": "2" })
190     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
191         raise Exception("WPS_CONFIG command failed")
192     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
193     if ev is None:
194         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
195     if "100e" not in ev:
196         raise Exception("WPS-NEW-AP-SETTINGS did not include Credential")
197
198 @remote_compatible
199 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
200     """AP configuration using wps_config command with invalid passphrase"""
201     ssid = "test-wps-init-config"
202     hapd = hostapd.add_ap(apdev[0],
203                           { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
204     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
205         raise Exception("Invalid WPS_CONFIG command accepted")
206
207 def test_ap_wps_conf(dev, apdev):
208     """WPS PBC provisioning with configured AP"""
209     ssid = "test-wps-conf"
210     hapd = hostapd.add_ap(apdev[0],
211                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
212                           "wpa_passphrase": "12345678", "wpa": "2",
213                           "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
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], 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], 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 @remote_compatible
288 def test_ap_wps_twice(dev, apdev):
289     """WPS provisioning with twice to change passphrase"""
290     ssid = "test-wps-twice"
291     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
292                "wpa_passphrase": "12345678", "wpa": "2",
293                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
294     hapd = hostapd.add_ap(apdev[0], params)
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     hostapd.remove_bss(apdev[0])
305     params['wpa_passphrase'] = 'another passphrase'
306     hapd = hostapd.add_ap(apdev[0], params)
307     logger.info("WPS provisioning step")
308     hapd.request("WPS_PBC")
309     dev[0].dump_monitor()
310     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
311     dev[0].wait_connected(timeout=30)
312     networks = dev[0].list_networks()
313     if len(networks) > 1:
314         raise Exception("Unexpected duplicated network block present")
315
316 @remote_compatible
317 def test_ap_wps_incorrect_pin(dev, apdev):
318     """WPS PIN provisioning with incorrect PIN"""
319     ssid = "test-wps-incorrect-pin"
320     hapd = hostapd.add_ap(apdev[0],
321                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
322                           "wpa_passphrase": "12345678", "wpa": "2",
323                           "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
324
325     logger.info("WPS provisioning attempt 1")
326     hapd.request("WPS_PIN any 12345670")
327     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
328     dev[0].dump_monitor()
329     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
330     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
331     if ev is None:
332         raise Exception("WPS operation timed out")
333     if "config_error=18" not in ev:
334         raise Exception("Incorrect config_error reported")
335     if "msg=8" not in ev:
336         raise Exception("PIN error detected on incorrect message")
337     dev[0].wait_disconnected(timeout=10)
338     dev[0].request("WPS_CANCEL")
339     # if a scan was in progress, wait for it to complete before trying WPS again
340     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
341
342     status = hapd.request("WPS_GET_STATUS")
343     if "Last WPS result: Failed" not in status:
344         raise Exception("WPS failure result not shown correctly")
345
346     logger.info("WPS provisioning attempt 2")
347     hapd.request("WPS_PIN any 12345670")
348     dev[0].dump_monitor()
349     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
350     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
351     if ev is None:
352         raise Exception("WPS operation timed out")
353     if "config_error=18" not in ev:
354         raise Exception("Incorrect config_error reported")
355     if "msg=10" not in ev:
356         raise Exception("PIN error detected on incorrect message")
357     dev[0].wait_disconnected(timeout=10)
358
359 @remote_compatible
360 def test_ap_wps_conf_pin(dev, apdev):
361     """WPS PIN provisioning with configured AP"""
362     ssid = "test-wps-conf-pin"
363     hapd = hostapd.add_ap(apdev[0],
364                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
365                             "wpa_passphrase": "12345678", "wpa": "2",
366                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
367     logger.info("WPS provisioning step")
368     pin = dev[0].wps_read_pin()
369     hapd.request("WPS_PIN any " + pin)
370     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
371     dev[0].dump_monitor()
372     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
373     dev[0].wait_connected(timeout=30)
374     status = dev[0].get_status()
375     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
376         raise Exception("Not fully connected")
377     if status['ssid'] != ssid:
378         raise Exception("Unexpected SSID")
379     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
380         raise Exception("Unexpected encryption configuration")
381     if status['key_mgmt'] != 'WPA2-PSK':
382         raise Exception("Unexpected key_mgmt")
383
384     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
385     bss = dev[1].get_bss(apdev[0]['bssid'])
386     if "[WPS-AUTH]" in bss['flags']:
387         raise Exception("WPS-AUTH flag not cleared")
388     logger.info("Try to connect from another station using the same PIN")
389     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
390     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
391     if ev is None:
392         raise Exception("Operation timed out")
393     if "WPS-M2D" not in ev:
394         raise Exception("Unexpected WPS operation started")
395     hapd.request("WPS_PIN any " + pin)
396     dev[1].wait_connected(timeout=30)
397
398 def test_ap_wps_conf_pin_mixed_mode(dev, apdev):
399     """WPS PIN provisioning with configured AP (WPA+WPA2)"""
400     ssid = "test-wps-conf-pin-mixed"
401     hapd = hostapd.add_ap(apdev[0],
402                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
403                             "wpa_passphrase": "12345678", "wpa": "3",
404                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
405                             "wpa_pairwise": "TKIP" })
406
407     logger.info("WPS provisioning step")
408     pin = dev[0].wps_read_pin()
409     hapd.request("WPS_PIN any " + pin)
410     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
411     dev[0].dump_monitor()
412     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
413     dev[0].wait_connected(timeout=30)
414     status = dev[0].get_status()
415     dev[0].request("REMOVE_NETWORK all")
416     dev[0].wait_disconnected()
417     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP' or status['key_mgmt'] != 'WPA2-PSK':
418         raise Exception("Unexpected encryption/key_mgmt configuration: pairwise=%s group=%s key_mgmt=%s" % (status['pairwise_cipher'], status['group_cipher'], status['key_mgmt']))
419
420     logger.info("WPS provisioning step (auth_types=0x1b)")
421     if "OK" not in dev[0].request("SET wps_force_auth_types 0x1b"):
422         raise Exception("Failed to set wps_force_auth_types 0x1b")
423     pin = dev[0].wps_read_pin()
424     hapd.request("WPS_PIN any " + pin)
425     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
426     dev[0].dump_monitor()
427     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
428     dev[0].wait_connected(timeout=30)
429     status = dev[0].get_status()
430     dev[0].request("REMOVE_NETWORK all")
431     dev[0].wait_disconnected()
432     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP' or status['key_mgmt'] != 'WPA2-PSK':
433         raise Exception("Unexpected encryption/key_mgmt configuration: pairwise=%s group=%s key_mgmt=%s" % (status['pairwise_cipher'], status['group_cipher'], status['key_mgmt']))
434
435     logger.info("WPS provisioning step (auth_types=0 encr_types=0)")
436     if "OK" not in dev[0].request("SET wps_force_auth_types 0"):
437         raise Exception("Failed to set wps_force_auth_types 0")
438     if "OK" not in dev[0].request("SET wps_force_encr_types 0"):
439         raise Exception("Failed to set wps_force_encr_types 0")
440     pin = dev[0].wps_read_pin()
441     hapd.request("WPS_PIN any " + pin)
442     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
443     dev[0].dump_monitor()
444     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
445     dev[0].wait_connected(timeout=30)
446     status = dev[0].get_status()
447     dev[0].request("REMOVE_NETWORK all")
448     dev[0].wait_disconnected()
449     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP' or status['key_mgmt'] != 'WPA2-PSK':
450         raise Exception("Unexpected encryption/key_mgmt configuration: pairwise=%s group=%s key_mgmt=%s" % (status['pairwise_cipher'], status['group_cipher'], status['key_mgmt']))
451
452     dev[0].request("SET wps_force_auth_types ")
453     dev[0].request("SET wps_force_encr_types ")
454
455 @remote_compatible
456 def test_ap_wps_conf_pin_v1(dev, apdev):
457     """WPS PIN provisioning with configured WPS v1.0 AP"""
458     ssid = "test-wps-conf-pin-v1"
459     hapd = hostapd.add_ap(apdev[0],
460                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
461                             "wpa_passphrase": "12345678", "wpa": "2",
462                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
463     logger.info("WPS provisioning step")
464     pin = dev[0].wps_read_pin()
465     hapd.request("SET wps_version_number 0x10")
466     hapd.request("WPS_PIN any " + pin)
467     found = False
468     for i in range(0, 10):
469         dev[0].scan(freq="2412")
470         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
471             found = True
472             break
473     if not found:
474         hapd.request("SET wps_version_number 0x20")
475         raise Exception("WPS-PIN flag not seen in scan results")
476     dev[0].dump_monitor()
477     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
478     dev[0].wait_connected(timeout=30)
479     hapd.request("SET wps_version_number 0x20")
480
481 @remote_compatible
482 def test_ap_wps_conf_pin_2sta(dev, apdev):
483     """Two stations trying to use WPS PIN at the same time"""
484     ssid = "test-wps-conf-pin2"
485     hapd = hostapd.add_ap(apdev[0],
486                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
487                             "wpa_passphrase": "12345678", "wpa": "2",
488                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
489     logger.info("WPS provisioning step")
490     pin = "12345670"
491     pin2 = "55554444"
492     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
493     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
494     dev[0].dump_monitor()
495     dev[1].dump_monitor()
496     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
497     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
498     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
499     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
500     dev[0].wait_connected(timeout=30)
501     dev[1].wait_connected(timeout=30)
502
503 @remote_compatible
504 def test_ap_wps_conf_pin_timeout(dev, apdev):
505     """WPS PIN provisioning with configured AP timing out PIN"""
506     ssid = "test-wps-conf-pin"
507     hapd = hostapd.add_ap(apdev[0],
508                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
509                             "wpa_passphrase": "12345678", "wpa": "2",
510                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
511     addr = dev[0].p2p_interface_addr()
512     pin = dev[0].wps_read_pin()
513     if "FAIL" not in hapd.request("WPS_PIN "):
514         raise Exception("Unexpected success on invalid WPS_PIN")
515     hapd.request("WPS_PIN any " + pin + " 1")
516     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
517     time.sleep(1.1)
518     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
519     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
520     if ev is None:
521         raise Exception("WPS-PIN-NEEDED event timed out")
522     ev = dev[0].wait_event(["WPS-M2D"])
523     if ev is None:
524         raise Exception("M2D not reported")
525     dev[0].request("WPS_CANCEL")
526
527     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
528     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
529     dev[0].wait_connected(timeout=30)
530
531 def test_ap_wps_reg_connect(dev, apdev):
532     """WPS registrar using AP PIN to connect"""
533     ssid = "test-wps-reg-ap-pin"
534     appin = "12345670"
535     hostapd.add_ap(apdev[0],
536                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
537                      "wpa_passphrase": "12345678", "wpa": "2",
538                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
539                      "ap_pin": appin})
540     logger.info("WPS provisioning step")
541     dev[0].dump_monitor()
542     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
543     dev[0].wps_reg(apdev[0]['bssid'], appin)
544     status = dev[0].get_status()
545     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
546         raise Exception("Not fully connected")
547     if status['ssid'] != ssid:
548         raise Exception("Unexpected SSID")
549     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
550         raise Exception("Unexpected encryption configuration")
551     if status['key_mgmt'] != 'WPA2-PSK':
552         raise Exception("Unexpected key_mgmt")
553
554 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
555     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
556     ssid = "test-wps-reg-ap-pin"
557     appin = "12345670"
558     hostapd.add_ap(apdev[0],
559                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
560                      "wpa_passphrase": "12345678", "wpa": "3",
561                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
562                      "wpa_pairwise": "TKIP", "ap_pin": appin})
563     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
564     dev[0].wps_reg(apdev[0]['bssid'], appin)
565     status = dev[0].get_status()
566     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
567         raise Exception("Not fully connected")
568     if status['ssid'] != ssid:
569         raise Exception("Unexpected SSID")
570     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
571         raise Exception("Unexpected encryption configuration")
572     if status['key_mgmt'] != 'WPA2-PSK':
573         raise Exception("Unexpected key_mgmt")
574
575 def test_ap_wps_reg_override_ap_settings(dev, apdev):
576     """WPS registrar and ap_settings override"""
577     ap_settings = "/tmp/ap_wps_reg_override_ap_settings"
578     try:
579         os.remove(ap_settings)
580     except:
581         pass
582     # Override AP Settings with values that point to another AP
583     data = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
584     data += build_wsc_attr(ATTR_SSID, "test")
585     data += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
586     data += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
587     data += build_wsc_attr(ATTR_NETWORK_KEY, '')
588     data += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[1]['bssid'].replace(':', '')))
589     with open(ap_settings, "w") as f:
590         f.write(data)
591     ssid = "test-wps-reg-ap-pin"
592     appin = "12345670"
593     hostapd.add_ap(apdev[0],
594                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
595                      "wpa_passphrase": "12345678", "wpa": "2",
596                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
597                      "ap_pin": appin, "ap_settings": ap_settings })
598     hapd2 = hostapd.add_ap(apdev[1], { "ssid": "test" })
599     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
600     dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
601     dev[0].wps_reg(apdev[0]['bssid'], appin)
602     ev = hapd2.wait_event(['AP-STA-CONNECTED'], timeout=10)
603     os.remove(ap_settings)
604     if ev is None:
605         raise Exception("No connection with the other AP")
606
607 def check_wps_reg_failure(dev, ap, appin):
608     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
609     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
610     if ev is None:
611         raise Exception("WPS operation timed out")
612     if "WPS-SUCCESS" in ev:
613         raise Exception("WPS operation succeeded unexpectedly")
614     if "config_error=15" not in ev:
615         raise Exception("WPS setup locked state was not reported correctly")
616
617 def test_ap_wps_random_ap_pin(dev, apdev):
618     """WPS registrar using random AP PIN"""
619     ssid = "test-wps-reg-random-ap-pin"
620     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
621     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
622                "wpa_passphrase": "12345678", "wpa": "2",
623                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
624                "device_name": "Wireless AP", "manufacturer": "Company",
625                "model_name": "WAP", "model_number": "123",
626                "serial_number": "12345", "device_type": "6-0050F204-1",
627                "os_version": "01020300",
628                "config_methods": "label push_button",
629                "uuid": ap_uuid, "upnp_iface": "lo" }
630     hapd = hostapd.add_ap(apdev[0], params)
631     appin = hapd.request("WPS_AP_PIN random")
632     if "FAIL" in appin:
633         raise Exception("Could not generate random AP PIN")
634     if appin not in hapd.request("WPS_AP_PIN get"):
635         raise Exception("Could not fetch current AP PIN")
636     logger.info("WPS provisioning step")
637     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
638     dev[0].wps_reg(apdev[0]['bssid'], appin)
639
640     hapd.request("WPS_AP_PIN disable")
641     logger.info("WPS provisioning step with AP PIN disabled")
642     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
643     check_wps_reg_failure(dev[1], apdev[0], appin)
644
645     logger.info("WPS provisioning step with AP PIN reset")
646     appin = "12345670"
647     hapd.request("WPS_AP_PIN set " + appin)
648     dev[1].wps_reg(apdev[0]['bssid'], appin)
649     dev[0].request("REMOVE_NETWORK all")
650     dev[1].request("REMOVE_NETWORK all")
651     dev[0].wait_disconnected(timeout=10)
652     dev[1].wait_disconnected(timeout=10)
653
654     logger.info("WPS provisioning step after AP PIN timeout")
655     hapd.request("WPS_AP_PIN disable")
656     appin = hapd.request("WPS_AP_PIN random 1")
657     time.sleep(1.1)
658     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
659         raise Exception("AP PIN unexpectedly still enabled")
660     check_wps_reg_failure(dev[0], apdev[0], appin)
661
662     logger.info("WPS provisioning step after AP PIN timeout(2)")
663     hapd.request("WPS_AP_PIN disable")
664     appin = "12345670"
665     hapd.request("WPS_AP_PIN set " + appin + " 1")
666     time.sleep(1.1)
667     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
668         raise Exception("AP PIN unexpectedly still enabled")
669     check_wps_reg_failure(dev[1], apdev[0], appin)
670
671     with fail_test(hapd, 1, "os_get_random;wps_generate_pin"):
672         hapd.request("WPS_AP_PIN random 1")
673         hapd.request("WPS_AP_PIN disable")
674
675     with alloc_fail(hapd, 1, "upnp_wps_set_ap_pin"):
676         hapd.request("WPS_AP_PIN set 12345670")
677         hapd.request("WPS_AP_PIN disable")
678
679 def test_ap_wps_reg_config(dev, apdev):
680     """WPS registrar configuring an AP using AP PIN"""
681     ssid = "test-wps-init-ap-pin"
682     appin = "12345670"
683     hostapd.add_ap(apdev[0],
684                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
685                      "ap_pin": appin})
686     logger.info("WPS configuration step")
687     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
688     dev[0].dump_monitor()
689     new_ssid = "wps-new-ssid"
690     new_passphrase = "1234567890"
691     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
692                    new_passphrase)
693     status = dev[0].get_status()
694     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
695         raise Exception("Not fully connected")
696     if status['ssid'] != new_ssid:
697         raise Exception("Unexpected SSID")
698     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
699         raise Exception("Unexpected encryption configuration")
700     if status['key_mgmt'] != 'WPA2-PSK':
701         raise Exception("Unexpected key_mgmt")
702
703     logger.info("Re-configure back to open")
704     dev[0].request("REMOVE_NETWORK all")
705     dev[0].flush_scan_cache()
706     dev[0].dump_monitor()
707     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
708     status = dev[0].get_status()
709     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
710         raise Exception("Not fully connected")
711     if status['ssid'] != "wps-open":
712         raise Exception("Unexpected SSID")
713     if status['key_mgmt'] != 'NONE':
714         raise Exception("Unexpected key_mgmt")
715
716 def test_ap_wps_reg_config_ext_processing(dev, apdev):
717     """WPS registrar configuring an AP with external config processing"""
718     ssid = "test-wps-init-ap-pin"
719     appin = "12345670"
720     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
721                "wps_cred_processing": "1", "ap_pin": appin}
722     hapd = hostapd.add_ap(apdev[0], params)
723     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
724     new_ssid = "wps-new-ssid"
725     new_passphrase = "1234567890"
726     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
727                    new_passphrase, no_wait=True)
728     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
729     if ev is None:
730         raise Exception("WPS registrar operation timed out")
731     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
732     if ev is None:
733         raise Exception("WPS configuration timed out")
734     if "1026" not in ev:
735         raise Exception("AP Settings missing from event")
736     hapd.request("SET wps_cred_processing 0")
737     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
738         raise Exception("WPS_CONFIG command failed")
739     dev[0].wait_connected(timeout=15)
740
741 def test_ap_wps_reg_config_tkip(dev, apdev):
742     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
743     skip_with_fips(dev[0])
744     ssid = "test-wps-init-ap"
745     appin = "12345670"
746     hostapd.add_ap(apdev[0],
747                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
748                      "ap_pin": appin})
749     logger.info("WPS configuration step")
750     dev[0].request("SET wps_version_number 0x10")
751     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
752     dev[0].dump_monitor()
753     new_ssid = "wps-new-ssid-with-tkip"
754     new_passphrase = "1234567890"
755     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
756                    new_passphrase)
757     logger.info("Re-connect to verify WPA2 mixed mode")
758     dev[0].request("DISCONNECT")
759     id = 0
760     dev[0].set_network(id, "pairwise", "CCMP")
761     dev[0].set_network(id, "proto", "RSN")
762     dev[0].connect_network(id)
763     status = dev[0].get_status()
764     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
765         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
766     if status['ssid'] != new_ssid:
767         raise Exception("Unexpected SSID")
768     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
769         raise Exception("Unexpected encryption configuration")
770     if status['key_mgmt'] != 'WPA2-PSK':
771         raise Exception("Unexpected key_mgmt")
772
773 def test_ap_wps_setup_locked(dev, apdev):
774     """WPS registrar locking up AP setup on AP PIN failures"""
775     ssid = "test-wps-incorrect-ap-pin"
776     appin = "12345670"
777     hapd = hostapd.add_ap(apdev[0],
778                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
779                             "wpa_passphrase": "12345678", "wpa": "2",
780                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
781                             "ap_pin": appin})
782     new_ssid = "wps-new-ssid-test"
783     new_passphrase = "1234567890"
784
785     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
786     ap_setup_locked=False
787     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
788         dev[0].dump_monitor()
789         logger.info("Try incorrect AP PIN - attempt " + pin)
790         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
791                        "CCMP", new_passphrase, no_wait=True)
792         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
793         if ev is None:
794             raise Exception("Timeout on receiving WPS operation failure event")
795         if "CTRL-EVENT-CONNECTED" in ev:
796             raise Exception("Unexpected connection")
797         if "config_error=15" in ev:
798             logger.info("AP Setup Locked")
799             ap_setup_locked=True
800         elif "config_error=18" not in ev:
801             raise Exception("config_error=18 not reported")
802         dev[0].wait_disconnected(timeout=10)
803         time.sleep(0.1)
804     if not ap_setup_locked:
805         raise Exception("AP setup was not locked")
806     dev[0].request("WPS_CANCEL")
807     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True,
808                         only_new=True)
809     bss = dev[0].get_bss(apdev[0]['bssid'])
810     if 'wps_ap_setup_locked' not in bss or bss['wps_ap_setup_locked'] != '1':
811         logger.info("BSS: " + str(bss))
812         raise Exception("AP Setup Locked not indicated in scan results")
813
814     status = hapd.request("WPS_GET_STATUS")
815     if "Last WPS result: Failed" not in status:
816         raise Exception("WPS failure result not shown correctly")
817     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
818         raise Exception("Peer address not shown correctly")
819
820     time.sleep(0.5)
821     dev[0].dump_monitor()
822     logger.info("WPS provisioning step")
823     pin = dev[0].wps_read_pin()
824     hapd.request("WPS_PIN any " + pin)
825     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
826     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
827     if ev is None:
828         raise Exception("WPS success was not reported")
829     dev[0].wait_connected(timeout=30)
830
831     appin = hapd.request("WPS_AP_PIN random")
832     if "FAIL" in appin:
833         raise Exception("Could not generate random AP PIN")
834     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
835     if ev is None:
836         raise Exception("Failed to unlock AP PIN")
837
838 def test_ap_wps_setup_locked_timeout(dev, apdev):
839     """WPS re-enabling AP PIN after timeout"""
840     ssid = "test-wps-incorrect-ap-pin"
841     appin = "12345670"
842     hapd = hostapd.add_ap(apdev[0],
843                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
844                             "wpa_passphrase": "12345678", "wpa": "2",
845                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
846                             "ap_pin": appin})
847     new_ssid = "wps-new-ssid-test"
848     new_passphrase = "1234567890"
849
850     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
851     ap_setup_locked=False
852     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
853         dev[0].dump_monitor()
854         logger.info("Try incorrect AP PIN - attempt " + pin)
855         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
856                        "CCMP", new_passphrase, no_wait=True)
857         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
858         if ev is None:
859             raise Exception("Timeout on receiving WPS operation failure event")
860         if "CTRL-EVENT-CONNECTED" in ev:
861             raise Exception("Unexpected connection")
862         if "config_error=15" in ev:
863             logger.info("AP Setup Locked")
864             ap_setup_locked=True
865             break
866         elif "config_error=18" not in ev:
867             raise Exception("config_error=18 not reported")
868         dev[0].wait_disconnected(timeout=10)
869         time.sleep(0.1)
870     if not ap_setup_locked:
871         raise Exception("AP setup was not locked")
872     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
873     if ev is None:
874         raise Exception("AP PIN did not get unlocked on 60 second timeout")
875
876 def test_ap_wps_setup_locked_2(dev, apdev):
877     """WPS AP configured for special ap_setup_locked=2 mode"""
878     ssid = "test-wps-ap-pin"
879     appin = "12345670"
880     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
881                "wpa_passphrase": "12345678", "wpa": "2",
882                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
883                "ap_pin": appin, "ap_setup_locked": "2" }
884     hapd = hostapd.add_ap(apdev[0], params)
885     new_ssid = "wps-new-ssid-test"
886     new_passphrase = "1234567890"
887
888     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
889     dev[0].wps_reg(apdev[0]['bssid'], appin)
890     dev[0].request("REMOVE_NETWORK all")
891     dev[0].wait_disconnected()
892
893     hapd.dump_monitor()
894     dev[0].dump_monitor()
895     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK",
896                    "CCMP", new_passphrase, no_wait=True)
897
898     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
899     if ev is None:
900         raise Exception("hostapd did not report WPS failure")
901     if "msg=12 config_error=15" not in ev:
902         raise Exception("Unexpected failure reason (AP): " + ev)
903
904     ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
905     if ev is None:
906         raise Exception("Timeout on receiving WPS operation failure event")
907     if "CTRL-EVENT-CONNECTED" in ev:
908         raise Exception("Unexpected connection")
909     if "config_error=15" not in ev:
910         raise Exception("Unexpected failure reason (STA): " + ev)
911     dev[0].request("WPS_CANCEL")
912     dev[0].wait_disconnected()
913
914 @remote_compatible
915 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
916     """WPS PBC session overlap with two active APs"""
917     params = { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
918                "wpa_passphrase": "12345678", "wpa": "2",
919                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
920                "wps_independent": "1"}
921     hapd = hostapd.add_ap(apdev[0], params)
922     params = { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
923                "wpa_passphrase": "123456789", "wpa": "2",
924                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
925                "wps_independent": "1"}
926     hapd2 = hostapd.add_ap(apdev[1], params)
927     hapd.request("WPS_PBC")
928     hapd2.request("WPS_PBC")
929     logger.info("WPS provisioning step")
930     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
931     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
932     dev[0].request("WPS_PBC")
933     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
934     if ev is None:
935         raise Exception("PBC session overlap not detected")
936     hapd.request("DISABLE")
937     hapd2.request("DISABLE")
938     dev[0].flush_scan_cache()
939
940 @remote_compatible
941 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
942     """WPS PBC session overlap with two active STAs"""
943     ssid = "test-wps-pbc-overlap"
944     hapd = hostapd.add_ap(apdev[0],
945                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
946                             "wpa_passphrase": "12345678", "wpa": "2",
947                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
948     logger.info("WPS provisioning step")
949     hapd.request("WPS_PBC")
950     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
951     dev[0].dump_monitor()
952     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
953     dev[1].dump_monitor()
954     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
955     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
956     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
957     if ev is None:
958         raise Exception("PBC session overlap not detected (dev0)")
959     if "config_error=12" not in ev:
960         raise Exception("PBC session overlap not correctly reported (dev0)")
961     dev[0].request("WPS_CANCEL")
962     dev[0].request("DISCONNECT")
963     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
964     if ev is None:
965         raise Exception("PBC session overlap not detected (dev1)")
966     if "config_error=12" not in ev:
967         raise Exception("PBC session overlap not correctly reported (dev1)")
968     dev[1].request("WPS_CANCEL")
969     dev[1].request("DISCONNECT")
970     hapd.request("WPS_CANCEL")
971     ret = hapd.request("WPS_PBC")
972     if "FAIL" not in ret:
973         raise Exception("PBC mode allowed to be started while PBC overlap still active")
974     hapd.request("DISABLE")
975     dev[0].flush_scan_cache()
976     dev[1].flush_scan_cache()
977
978 @remote_compatible
979 def test_ap_wps_cancel(dev, apdev):
980     """WPS AP cancelling enabled config method"""
981     ssid = "test-wps-ap-cancel"
982     hapd = hostapd.add_ap(apdev[0],
983                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
984                             "wpa_passphrase": "12345678", "wpa": "2",
985                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
986     bssid = apdev[0]['bssid']
987
988     logger.info("Verify PBC enable/cancel")
989     hapd.request("WPS_PBC")
990     dev[0].scan(freq="2412")
991     dev[0].scan(freq="2412")
992     bss = dev[0].get_bss(apdev[0]['bssid'])
993     if "[WPS-PBC]" not in bss['flags']:
994         raise Exception("WPS-PBC flag missing")
995     if "FAIL" in hapd.request("WPS_CANCEL"):
996         raise Exception("WPS_CANCEL failed")
997     dev[0].scan(freq="2412")
998     dev[0].scan(freq="2412")
999     bss = dev[0].get_bss(apdev[0]['bssid'])
1000     if "[WPS-PBC]" in bss['flags']:
1001         raise Exception("WPS-PBC flag not cleared")
1002
1003     logger.info("Verify PIN enable/cancel")
1004     hapd.request("WPS_PIN any 12345670")
1005     dev[0].scan(freq="2412")
1006     dev[0].scan(freq="2412")
1007     bss = dev[0].get_bss(apdev[0]['bssid'])
1008     if "[WPS-AUTH]" not in bss['flags']:
1009         raise Exception("WPS-AUTH flag missing")
1010     if "FAIL" in hapd.request("WPS_CANCEL"):
1011         raise Exception("WPS_CANCEL failed")
1012     dev[0].scan(freq="2412")
1013     dev[0].scan(freq="2412")
1014     bss = dev[0].get_bss(apdev[0]['bssid'])
1015     if "[WPS-AUTH]" in bss['flags']:
1016         raise Exception("WPS-AUTH flag not cleared")
1017
1018 def test_ap_wps_er_add_enrollee(dev, apdev):
1019     """WPS ER configuring AP and adding a new enrollee using PIN"""
1020     try:
1021         _test_ap_wps_er_add_enrollee(dev, apdev)
1022     finally:
1023         dev[0].request("WPS_ER_STOP")
1024
1025 def _test_ap_wps_er_add_enrollee(dev, apdev):
1026     ssid = "wps-er-add-enrollee"
1027     ap_pin = "12345670"
1028     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1029     hostapd.add_ap(apdev[0],
1030                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
1031                      "device_name": "Wireless AP", "manufacturer": "Company",
1032                      "model_name": "WAP", "model_number": "123",
1033                      "serial_number": "12345", "device_type": "6-0050F204-1",
1034                      "os_version": "01020300",
1035                      'friendly_name': "WPS AP - <>&'\" - TEST",
1036                      "config_methods": "label push_button",
1037                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1038     logger.info("WPS configuration step")
1039     new_passphrase = "1234567890"
1040     dev[0].dump_monitor()
1041     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1042     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
1043                    new_passphrase)
1044     status = dev[0].get_status()
1045     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1046         raise Exception("Not fully connected")
1047     if status['ssid'] != ssid:
1048         raise Exception("Unexpected SSID")
1049     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
1050         raise Exception("Unexpected encryption configuration")
1051     if status['key_mgmt'] != 'WPA2-PSK':
1052         raise Exception("Unexpected key_mgmt")
1053
1054     logger.info("Start ER")
1055     dev[0].request("WPS_ER_START ifname=lo")
1056     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1057     if ev is None:
1058         raise Exception("AP discovery timed out")
1059     if ap_uuid not in ev:
1060         raise Exception("Expected AP UUID not found")
1061     if "|WPS AP - &lt;&gt;&amp;&apos;&quot; - TEST|Company|" not in ev:
1062         raise Exception("Expected friendly name not found")
1063
1064     logger.info("Learn AP configuration through UPnP")
1065     dev[0].dump_monitor()
1066     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1067     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1068     if ev is None:
1069         raise Exception("AP learn timed out")
1070     if ap_uuid not in ev:
1071         raise Exception("Expected AP UUID not in settings")
1072     if "ssid=" + ssid not in ev:
1073         raise Exception("Expected SSID not in settings")
1074     if "key=" + new_passphrase not in ev:
1075         raise Exception("Expected passphrase not in settings")
1076     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1077     if ev is None:
1078         raise Exception("WPS-FAIL after AP learn timed out")
1079     time.sleep(0.1)
1080
1081     logger.info("Add Enrollee using ER")
1082     pin = dev[1].wps_read_pin()
1083     dev[0].dump_monitor()
1084     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1085     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1086     dev[1].dump_monitor()
1087     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1088     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1089     if ev is None:
1090         raise Exception("Enrollee did not report success")
1091     dev[1].wait_connected(timeout=15)
1092     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1093     if ev is None:
1094         raise Exception("WPS ER did not report success")
1095     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1096
1097     logger.info("Add a specific Enrollee using ER")
1098     pin = dev[2].wps_read_pin()
1099     addr2 = dev[2].p2p_interface_addr()
1100     dev[0].dump_monitor()
1101     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1102     dev[2].dump_monitor()
1103     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1104     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1105     if ev is None:
1106         raise Exception("Enrollee not seen")
1107     if addr2 not in ev:
1108         raise Exception("Unexpected Enrollee MAC address")
1109     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
1110     dev[2].wait_connected(timeout=30)
1111     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1112     if ev is None:
1113         raise Exception("WPS ER did not report success")
1114
1115     logger.info("Verify registrar selection behavior")
1116     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1117     dev[1].request("DISCONNECT")
1118     dev[1].wait_disconnected(timeout=10)
1119     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1120     dev[1].scan(freq="2412")
1121     bss = dev[1].get_bss(apdev[0]['bssid'])
1122     if "[WPS-AUTH]" not in bss['flags']:
1123         # It is possible for scan to miss an update especially when running
1124         # tests under load with multiple VMs, so allow another attempt.
1125         dev[1].scan(freq="2412")
1126         bss = dev[1].get_bss(apdev[0]['bssid'])
1127         if "[WPS-AUTH]" not in bss['flags']:
1128             raise Exception("WPS-AUTH flag missing")
1129
1130     logger.info("Stop ER")
1131     dev[0].dump_monitor()
1132     dev[0].request("WPS_ER_STOP")
1133     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
1134     if ev is None:
1135         raise Exception("WPS ER unsubscription timed out")
1136     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
1137     # a bit before verifying that the scan results have changed.
1138     time.sleep(0.2)
1139
1140     for i in range(0, 10):
1141         dev[1].request("BSS_FLUSH 0")
1142         dev[1].scan(freq="2412", only_new=True)
1143         bss = dev[1].get_bss(apdev[0]['bssid'])
1144         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
1145             break
1146         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
1147         time.sleep(0.1)
1148     if "[WPS-AUTH]" in bss['flags']:
1149         raise Exception("WPS-AUTH flag not removed")
1150
1151 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1152     """WPS ER adding a new enrollee identified by UUID"""
1153     try:
1154         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
1155     finally:
1156         dev[0].request("WPS_ER_STOP")
1157
1158 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1159     ssid = "wps-er-add-enrollee"
1160     ap_pin = "12345670"
1161     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1162     hostapd.add_ap(apdev[0],
1163                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1164                      "wpa_passphrase": "12345678", "wpa": "2",
1165                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1166                      "device_name": "Wireless AP", "manufacturer": "Company",
1167                      "model_name": "WAP", "model_number": "123",
1168                      "serial_number": "12345", "device_type": "6-0050F204-1",
1169                      "os_version": "01020300",
1170                      "config_methods": "label push_button",
1171                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1172     logger.info("WPS configuration step")
1173     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1174     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1175
1176     logger.info("Start ER")
1177     dev[0].request("WPS_ER_START ifname=lo")
1178     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1179     if ev is None:
1180         raise Exception("AP discovery timed out")
1181     if ap_uuid not in ev:
1182         raise Exception("Expected AP UUID not found")
1183
1184     logger.info("Learn AP configuration through UPnP")
1185     dev[0].dump_monitor()
1186     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1187     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1188     if ev is None:
1189         raise Exception("AP learn timed out")
1190     if ap_uuid not in ev:
1191         raise Exception("Expected AP UUID not in settings")
1192     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1193     if ev is None:
1194         raise Exception("WPS-FAIL after AP learn timed out")
1195     time.sleep(0.1)
1196
1197     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1198     addr1 = dev[1].p2p_interface_addr()
1199     dev[0].dump_monitor()
1200     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1201     dev[1].dump_monitor()
1202     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1203     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1204     if ev is None:
1205         raise Exception("Enrollee not seen")
1206     if addr1 not in ev:
1207         raise Exception("Unexpected Enrollee MAC address")
1208     uuid = ev.split(' ')[1]
1209     dev[0].request("WPS_ER_PBC " + uuid)
1210     dev[1].wait_connected(timeout=30)
1211     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1212     if ev is None:
1213         raise Exception("WPS ER did not report success")
1214
1215     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1216     pin = dev[2].wps_read_pin()
1217     addr2 = dev[2].p2p_interface_addr()
1218     dev[0].dump_monitor()
1219     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1220     dev[2].dump_monitor()
1221     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1222     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1223     if ev is None:
1224         raise Exception("Enrollee not seen")
1225     if addr2 not in ev:
1226         raise Exception("Unexpected Enrollee MAC address")
1227     uuid = ev.split(' ')[1]
1228     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1229     dev[2].wait_connected(timeout=30)
1230     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1231     if ev is None:
1232         raise Exception("WPS ER did not report success")
1233
1234     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-REMOVE"], timeout=15)
1235     if ev is None:
1236         raise Exception("No Enrollee STA entry timeout seen")
1237
1238     logger.info("Stop ER")
1239     dev[0].dump_monitor()
1240     dev[0].request("WPS_ER_STOP")
1241
1242 def test_ap_wps_er_multi_add_enrollee(dev, apdev):
1243     """Multiple WPS ERs adding a new enrollee using PIN"""
1244     try:
1245         _test_ap_wps_er_multi_add_enrollee(dev, apdev)
1246     finally:
1247         for i in range(2):
1248             dev[i].request("WPS_ER_STOP")
1249
1250 def _test_ap_wps_er_multi_add_enrollee(dev, apdev):
1251     ssid = "wps-er-add-enrollee"
1252     ap_pin = "12345670"
1253     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1254     hostapd.add_ap(apdev[0],
1255                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1256                      "wpa_passphrase": "12345678", "wpa": "2",
1257                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1258                      "device_name": "Wireless AP", "manufacturer": "Company",
1259                      "model_name": "WAP", "model_number": "123",
1260                      "serial_number": "12345", "device_type": "6-0050F204-1",
1261                      "os_version": "01020300",
1262                      'friendly_name': "WPS AP",
1263                      "config_methods": "label push_button",
1264                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1265
1266     for i in range(2):
1267         dev[i].scan_for_bss(apdev[0]['bssid'], freq=2412)
1268         dev[i].wps_reg(apdev[0]['bssid'], ap_pin)
1269     for i in range(2):
1270         dev[i].request("WPS_ER_START ifname=lo")
1271     for i in range(2):
1272         ev = dev[i].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1273         if ev is None:
1274             raise Exception("AP discovery timed out")
1275         dev[i].dump_monitor()
1276     for i in range(2):
1277         dev[i].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1278     for i in range(2):
1279         ev = dev[i].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1280         if ev is None:
1281             raise Exception("AP learn timed out")
1282         ev = dev[i].wait_event(["WPS-FAIL"], timeout=15)
1283         if ev is None:
1284             raise Exception("WPS-FAIL after AP learn timed out")
1285
1286     time.sleep(0.1)
1287
1288     pin = dev[2].wps_read_pin()
1289     addr = dev[2].own_addr()
1290     dev[0].dump_monitor()
1291     dev[0].request("WPS_ER_PIN any " + pin + " " + addr)
1292     dev[1].dump_monitor()
1293     dev[1].request("WPS_ER_PIN any " + pin + " " + addr)
1294
1295     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1296     dev[2].dump_monitor()
1297     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1298     ev = dev[2].wait_event(["WPS-SUCCESS"], timeout=30)
1299     if ev is None:
1300         raise Exception("Enrollee did not report success")
1301     dev[2].wait_connected(timeout=15)
1302
1303 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1304     """WPS ER connected to AP and adding a new enrollee using PBC"""
1305     try:
1306         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1307     finally:
1308         dev[0].request("WPS_ER_STOP")
1309
1310 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1311     ssid = "wps-er-add-enrollee-pbc"
1312     ap_pin = "12345670"
1313     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1314     hostapd.add_ap(apdev[0],
1315                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1316                      "wpa_passphrase": "12345678", "wpa": "2",
1317                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1318                      "device_name": "Wireless AP", "manufacturer": "Company",
1319                      "model_name": "WAP", "model_number": "123",
1320                      "serial_number": "12345", "device_type": "6-0050F204-1",
1321                      "os_version": "01020300",
1322                      "config_methods": "label push_button",
1323                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1324     logger.info("Learn AP configuration")
1325     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1326     dev[0].dump_monitor()
1327     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1328     status = dev[0].get_status()
1329     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1330         raise Exception("Not fully connected")
1331
1332     logger.info("Start ER")
1333     dev[0].request("WPS_ER_START ifname=lo")
1334     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1335     if ev is None:
1336         raise Exception("AP discovery timed out")
1337     if ap_uuid not in ev:
1338         raise Exception("Expected AP UUID not found")
1339
1340     enrollee = dev[1].p2p_interface_addr()
1341
1342     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1343         raise Exception("Unknown UUID not reported")
1344
1345     logger.info("Add Enrollee using ER and PBC")
1346     dev[0].dump_monitor()
1347     dev[1].dump_monitor()
1348     dev[1].request("WPS_PBC")
1349
1350     for i in range(0, 2):
1351         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1352         if ev is None:
1353             raise Exception("Enrollee discovery timed out")
1354         if enrollee in ev:
1355             break
1356         if i == 1:
1357             raise Exception("Expected Enrollee not found")
1358     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1359         raise Exception("Unknown UUID not reported")
1360     logger.info("Use learned network configuration on ER")
1361     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1362     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1363         raise Exception("WPS_ER_PBC failed")
1364
1365     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1366     if ev is None:
1367         raise Exception("Enrollee did not report success")
1368     dev[1].wait_connected(timeout=15)
1369     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1370     if ev is None:
1371         raise Exception("WPS ER did not report success")
1372     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1373
1374 def test_ap_wps_er_pbc_overlap(dev, apdev):
1375     """WPS ER connected to AP and PBC session overlap"""
1376     try:
1377         _test_ap_wps_er_pbc_overlap(dev, apdev)
1378     finally:
1379         dev[0].request("WPS_ER_STOP")
1380
1381 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1382     ssid = "wps-er-add-enrollee-pbc"
1383     ap_pin = "12345670"
1384     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1385     hostapd.add_ap(apdev[0],
1386                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1387                      "wpa_passphrase": "12345678", "wpa": "2",
1388                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1389                      "device_name": "Wireless AP", "manufacturer": "Company",
1390                      "model_name": "WAP", "model_number": "123",
1391                      "serial_number": "12345", "device_type": "6-0050F204-1",
1392                      "os_version": "01020300",
1393                      "config_methods": "label push_button",
1394                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1395     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1396     dev[0].dump_monitor()
1397     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1398
1399     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1400     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1401     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1402     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1403
1404     dev[0].dump_monitor()
1405     dev[0].request("WPS_ER_START ifname=lo")
1406
1407     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1408     if ev is None:
1409         raise Exception("AP discovery timed out")
1410     if ap_uuid not in ev:
1411         raise Exception("Expected AP UUID not found")
1412
1413     # verify BSSID selection of the AP instead of UUID
1414     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1415         raise Exception("Could not select AP based on BSSID")
1416
1417     dev[0].dump_monitor()
1418     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1419     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1420     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1421     if ev is None:
1422         raise Exception("PBC scan failed")
1423     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1424     if ev is None:
1425         raise Exception("PBC scan failed")
1426     found1 = False
1427     found2 = False
1428     addr1 = dev[1].own_addr()
1429     addr2 = dev[2].own_addr()
1430     for i in range(3):
1431         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1432         if ev is None:
1433             raise Exception("Enrollee discovery timed out")
1434         if addr1 in ev:
1435             found1 = True
1436             if found2:
1437                 break
1438         if addr2 in ev:
1439             found2 = True
1440             if found1:
1441                 break
1442     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1443         raise Exception("PBC overlap not reported")
1444     dev[1].request("WPS_CANCEL")
1445     dev[2].request("WPS_CANCEL")
1446     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1447         raise Exception("Invalid WPS_ER_PBC accepted")
1448
1449 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1450     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1451     try:
1452         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1453     finally:
1454         dev[0].request("WPS_ER_STOP")
1455
1456 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1457     ssid = "wps-er-add-enrollee-pbc"
1458     ap_pin = "12345670"
1459     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1460     hostapd.add_ap(apdev[0],
1461                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1462                      "wpa_passphrase": "12345678", "wpa": "2",
1463                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1464                      "device_name": "Wireless AP", "manufacturer": "Company",
1465                      "model_name": "WAP", "model_number": "123",
1466                      "serial_number": "12345", "device_type": "6-0050F204-1",
1467                      "os_version": "01020300",
1468                      "config_methods": "label push_button",
1469                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1470     logger.info("Learn AP configuration")
1471     dev[0].request("SET wps_version_number 0x10")
1472     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1473     dev[0].dump_monitor()
1474     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1475     status = dev[0].get_status()
1476     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1477         raise Exception("Not fully connected")
1478
1479     logger.info("Start ER")
1480     dev[0].request("WPS_ER_START ifname=lo")
1481     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1482     if ev is None:
1483         raise Exception("AP discovery timed out")
1484     if ap_uuid not in ev:
1485         raise Exception("Expected AP UUID not found")
1486
1487     logger.info("Use learned network configuration on ER")
1488     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1489
1490     logger.info("Add Enrollee using ER and PIN")
1491     enrollee = dev[1].p2p_interface_addr()
1492     pin = dev[1].wps_read_pin()
1493     dev[0].dump_monitor()
1494     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1495     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1496     dev[1].dump_monitor()
1497     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1498     dev[1].wait_connected(timeout=30)
1499     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1500     if ev is None:
1501         raise Exception("WPS ER did not report success")
1502
1503 @remote_compatible
1504 def test_ap_wps_er_config_ap(dev, apdev):
1505     """WPS ER configuring AP over UPnP"""
1506     try:
1507         _test_ap_wps_er_config_ap(dev, apdev)
1508     finally:
1509         dev[0].request("WPS_ER_STOP")
1510
1511 def _test_ap_wps_er_config_ap(dev, apdev):
1512     ssid = "wps-er-ap-config"
1513     ap_pin = "12345670"
1514     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1515     hostapd.add_ap(apdev[0],
1516                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1517                      "wpa_passphrase": "12345678", "wpa": "2",
1518                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1519                      "device_name": "Wireless AP", "manufacturer": "Company",
1520                      "model_name": "WAP", "model_number": "123",
1521                      "serial_number": "12345", "device_type": "6-0050F204-1",
1522                      "os_version": "01020300",
1523                      "config_methods": "label push_button",
1524                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1525
1526     logger.info("Connect ER to the AP")
1527     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1528
1529     logger.info("WPS configuration step")
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     new_passphrase = "1234567890"
1537     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1538                    ssid.encode("hex") + " WPA2PSK CCMP " +
1539                    new_passphrase.encode("hex"))
1540     ev = dev[0].wait_event(["WPS-SUCCESS"])
1541     if ev is None:
1542         raise Exception("WPS ER configuration operation timed out")
1543     dev[0].wait_disconnected(timeout=10)
1544     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1545
1546     logger.info("WPS ER restart")
1547     dev[0].request("WPS_ER_START")
1548     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1549     if ev is None:
1550         raise Exception("AP discovery timed out on ER restart")
1551     if ap_uuid not in ev:
1552         raise Exception("Expected AP UUID not found on ER restart")
1553     if "OK" not in dev[0].request("WPS_ER_STOP"):
1554         raise Exception("WPS_ER_STOP failed")
1555     if "OK" not in dev[0].request("WPS_ER_STOP"):
1556         raise Exception("WPS_ER_STOP failed")
1557
1558 @remote_compatible
1559 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1560     """WPS ER caching AP settings"""
1561     try:
1562         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1563     finally:
1564         dev[0].request("WPS_ER_STOP")
1565
1566 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1567     ssid = "wps-er-add-enrollee"
1568     ap_pin = "12345670"
1569     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1570     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1571                "wpa_passphrase": "12345678", "wpa": "2",
1572                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1573                "device_name": "Wireless AP", "manufacturer": "Company",
1574                "model_name": "WAP", "model_number": "123",
1575                "serial_number": "12345", "device_type": "6-0050F204-1",
1576                "os_version": "01020300",
1577                "config_methods": "label push_button",
1578                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1579     hapd = hostapd.add_ap(apdev[0], params)
1580     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1581     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1582     id = int(dev[0].list_networks()[0]['id'])
1583     dev[0].set_network(id, "scan_freq", "2412")
1584
1585     dev[0].request("WPS_ER_START ifname=lo")
1586     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1587     if ev is None:
1588         raise Exception("AP discovery timed out")
1589     if ap_uuid not in ev:
1590         raise Exception("Expected AP UUID not found")
1591
1592     dev[0].dump_monitor()
1593     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1594     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1595     if ev is None:
1596         raise Exception("AP learn timed out")
1597     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1598     if ev is None:
1599         raise Exception("WPS-FAIL after AP learn timed out")
1600     time.sleep(0.1)
1601
1602     hapd.disable()
1603
1604     for i in range(2):
1605         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1606                                  "CTRL-EVENT-DISCONNECTED" ],
1607                                timeout=15)
1608         if ev is None:
1609             raise Exception("AP removal or disconnection timed out")
1610
1611     hapd = hostapd.add_ap(apdev[0], params)
1612     for i in range(2):
1613         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1614                                timeout=15)
1615         if ev is None:
1616             raise Exception("AP discovery or connection timed out")
1617
1618     pin = dev[1].wps_read_pin()
1619     dev[0].dump_monitor()
1620     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1621
1622     time.sleep(0.2)
1623
1624     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1625     dev[1].dump_monitor()
1626     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1627     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1628     if ev is None:
1629         raise Exception("Enrollee did not report success")
1630     dev[1].wait_connected(timeout=15)
1631     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1632     if ev is None:
1633         raise Exception("WPS ER did not report success")
1634
1635     dev[0].dump_monitor()
1636     dev[0].request("WPS_ER_STOP")
1637
1638 def test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1639     """WPS ER caching AP settings (OOM)"""
1640     try:
1641         _test_ap_wps_er_cache_ap_settings_oom(dev, apdev)
1642     finally:
1643         dev[0].request("WPS_ER_STOP")
1644
1645 def _test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1646     ssid = "wps-er-add-enrollee"
1647     ap_pin = "12345670"
1648     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1649     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1650                "wpa_passphrase": "12345678", "wpa": "2",
1651                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1652                "device_name": "Wireless AP", "manufacturer": "Company",
1653                "model_name": "WAP", "model_number": "123",
1654                "serial_number": "12345", "device_type": "6-0050F204-1",
1655                "os_version": "01020300",
1656                "config_methods": "label push_button",
1657                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1658     hapd = hostapd.add_ap(apdev[0], params)
1659     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1660     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1661     id = int(dev[0].list_networks()[0]['id'])
1662     dev[0].set_network(id, "scan_freq", "2412")
1663
1664     dev[0].request("WPS_ER_START ifname=lo")
1665     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1666     if ev is None:
1667         raise Exception("AP discovery timed out")
1668     if ap_uuid not in ev:
1669         raise Exception("Expected AP UUID not found")
1670
1671     dev[0].dump_monitor()
1672     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1673     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1674     if ev is None:
1675         raise Exception("AP learn timed out")
1676     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1677     if ev is None:
1678         raise Exception("WPS-FAIL after AP learn timed out")
1679     time.sleep(0.1)
1680
1681     with alloc_fail(dev[0], 1, "=wps_er_ap_use_cached_settings"):
1682         hapd.disable()
1683
1684         for i in range(2):
1685             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1686                                      "CTRL-EVENT-DISCONNECTED" ],
1687                                    timeout=15)
1688             if ev is None:
1689                 raise Exception("AP removal or disconnection timed out")
1690
1691         hapd = hostapd.add_ap(apdev[0], params)
1692         for i in range(2):
1693             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1694                                    timeout=15)
1695             if ev is None:
1696                 raise Exception("AP discovery or connection timed out")
1697
1698     dev[0].request("WPS_ER_STOP")
1699
1700 def test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1701     """WPS ER caching AP settings (OOM 2)"""
1702     try:
1703         _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev)
1704     finally:
1705         dev[0].request("WPS_ER_STOP")
1706
1707 def _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1708     ssid = "wps-er-add-enrollee"
1709     ap_pin = "12345670"
1710     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1711     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1712                "wpa_passphrase": "12345678", "wpa": "2",
1713                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1714                "device_name": "Wireless AP", "manufacturer": "Company",
1715                "model_name": "WAP", "model_number": "123",
1716                "serial_number": "12345", "device_type": "6-0050F204-1",
1717                "os_version": "01020300",
1718                "config_methods": "label push_button",
1719                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1720     hapd = hostapd.add_ap(apdev[0], params)
1721     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1722     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1723     id = int(dev[0].list_networks()[0]['id'])
1724     dev[0].set_network(id, "scan_freq", "2412")
1725
1726     dev[0].request("WPS_ER_START ifname=lo")
1727     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1728     if ev is None:
1729         raise Exception("AP discovery timed out")
1730     if ap_uuid not in ev:
1731         raise Exception("Expected AP UUID not found")
1732
1733     dev[0].dump_monitor()
1734     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1735     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1736     if ev is None:
1737         raise Exception("AP learn timed out")
1738     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1739     if ev is None:
1740         raise Exception("WPS-FAIL after AP learn timed out")
1741     time.sleep(0.1)
1742
1743     with alloc_fail(dev[0], 1, "=wps_er_ap_cache_settings"):
1744         hapd.disable()
1745
1746         for i in range(2):
1747             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1748                                      "CTRL-EVENT-DISCONNECTED" ],
1749                                    timeout=15)
1750             if ev is None:
1751                 raise Exception("AP removal or disconnection timed out")
1752
1753         hapd = hostapd.add_ap(apdev[0], params)
1754         for i in range(2):
1755             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1756                                    timeout=15)
1757             if ev is None:
1758                 raise Exception("AP discovery or connection timed out")
1759
1760     dev[0].request("WPS_ER_STOP")
1761
1762 def test_ap_wps_er_subscribe_oom(dev, apdev):
1763     """WPS ER subscribe OOM"""
1764     try:
1765         _test_ap_wps_er_subscribe_oom(dev, apdev)
1766     finally:
1767         dev[0].request("WPS_ER_STOP")
1768
1769 def _test_ap_wps_er_subscribe_oom(dev, apdev):
1770     ssid = "wps-er-add-enrollee"
1771     ap_pin = "12345670"
1772     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1773     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1774                "wpa_passphrase": "12345678", "wpa": "2",
1775                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1776                "device_name": "Wireless AP", "manufacturer": "Company",
1777                "model_name": "WAP", "model_number": "123",
1778                "serial_number": "12345", "device_type": "6-0050F204-1",
1779                "os_version": "01020300",
1780                "config_methods": "label push_button",
1781                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1782     hapd = hostapd.add_ap(apdev[0], params)
1783     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1784     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1785     id = int(dev[0].list_networks()[0]['id'])
1786     dev[0].set_network(id, "scan_freq", "2412")
1787
1788     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_subscribe"):
1789         dev[0].request("WPS_ER_START ifname=lo")
1790         for i in range(50):
1791             res = dev[0].request("GET_ALLOC_FAIL")
1792             if res.startswith("0:"):
1793                 break
1794             time.sleep(0.1)
1795         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=0)
1796         if ev:
1797             raise Exception("Unexpected AP discovery during OOM")
1798
1799     dev[0].request("WPS_ER_STOP")
1800
1801 def test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1802     """WPS ER SetSelectedRegistrar OOM"""
1803     try:
1804         _test_ap_wps_er_set_sel_reg_oom(dev, apdev)
1805     finally:
1806         dev[0].request("WPS_ER_STOP")
1807
1808 def _test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1809     ssid = "wps-er-add-enrollee"
1810     ap_pin = "12345670"
1811     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1812     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1813                "wpa_passphrase": "12345678", "wpa": "2",
1814                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1815                "device_name": "Wireless AP", "manufacturer": "Company",
1816                "model_name": "WAP", "model_number": "123",
1817                "serial_number": "12345", "device_type": "6-0050F204-1",
1818                "os_version": "01020300",
1819                "config_methods": "label push_button",
1820                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1821     hapd = hostapd.add_ap(apdev[0], params)
1822     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1823     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1824
1825     dev[0].request("WPS_ER_START ifname=lo")
1826     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1827     if ev is None:
1828         raise Exception("AP not discovered")
1829
1830     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1831     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1832     if ev is None:
1833         raise Exception("AP learn timed out")
1834     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1835     if ev is None:
1836         raise Exception("WPS-FAIL timed out")
1837     time.sleep(0.1)
1838
1839     for func in [ "http_client_url_parse;wps_er_send_set_sel_reg",
1840                   "wps_er_soap_hdr;wps_er_send_set_sel_reg",
1841                   "http_client_addr;wps_er_send_set_sel_reg",
1842                   "wpabuf_alloc;wps_er_set_sel_reg" ]:
1843         with alloc_fail(dev[0], 1, func):
1844             if "OK" not in dev[0].request("WPS_ER_PBC " + ap_uuid):
1845                 raise Exception("WPS_ER_PBC failed")
1846             ev = dev[0].wait_event(["WPS-PBC-ACTIVE"], timeout=3)
1847             if ev is None:
1848                 raise Exception("WPS-PBC-ACTIVE not seen")
1849
1850     dev[0].request("WPS_ER_STOP")
1851
1852 @remote_compatible
1853 def test_ap_wps_er_learn_oom(dev, apdev):
1854     """WPS ER learn OOM"""
1855     try:
1856         _test_ap_wps_er_learn_oom(dev, apdev)
1857     finally:
1858         dev[0].request("WPS_ER_STOP")
1859
1860 def _test_ap_wps_er_learn_oom(dev, apdev):
1861     ssid = "wps-er-add-enrollee"
1862     ap_pin = "12345670"
1863     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1864     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1865                "wpa_passphrase": "12345678", "wpa": "2",
1866                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1867                "device_name": "Wireless AP", "manufacturer": "Company",
1868                "model_name": "WAP", "model_number": "123",
1869                "serial_number": "12345", "device_type": "6-0050F204-1",
1870                "os_version": "01020300",
1871                "config_methods": "label push_button",
1872                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1873     hapd = hostapd.add_ap(apdev[0], params)
1874     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1875     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1876
1877     dev[0].request("WPS_ER_START ifname=lo")
1878     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1879     if ev is None:
1880         raise Exception("AP not discovered")
1881
1882     for func in [ "wps_er_http_put_message_cb",
1883                   "xml_get_base64_item;wps_er_http_put_message_cb",
1884                   "http_client_url_parse;wps_er_ap_put_message",
1885                   "wps_er_soap_hdr;wps_er_ap_put_message",
1886                   "http_client_addr;wps_er_ap_put_message" ]:
1887         with alloc_fail(dev[0], 1, func):
1888             dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1889             ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=1)
1890             if ev is not None:
1891                 raise Exception("AP learn succeeded during OOM")
1892
1893     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1894     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=10)
1895     if ev is None:
1896         raise Exception("AP learn did not succeed")
1897
1898     if "FAIL" not in dev[0].request("WPS_ER_LEARN 00000000-9e5c-4e73-bd82-f89cbcd10d7e " + ap_pin):
1899         raise Exception("WPS_ER_LEARN for unknown AP accepted")
1900
1901     dev[0].request("WPS_ER_STOP")
1902
1903 def test_ap_wps_fragmentation(dev, apdev):
1904     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1905     ssid = "test-wps-fragmentation"
1906     appin = "12345670"
1907     hapd = hostapd.add_ap(apdev[0],
1908                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1909                             "wpa_passphrase": "12345678", "wpa": "3",
1910                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1911                             "wpa_pairwise": "TKIP", "ap_pin": appin,
1912                             "fragment_size": "50" })
1913     logger.info("WPS provisioning step (PBC)")
1914     hapd.request("WPS_PBC")
1915     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1916     dev[0].dump_monitor()
1917     dev[0].request("SET wps_fragment_size 50")
1918     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1919     dev[0].wait_connected(timeout=30)
1920     status = dev[0].get_status()
1921     if status['wpa_state'] != 'COMPLETED':
1922         raise Exception("Not fully connected")
1923     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1924         raise Exception("Unexpected encryption configuration")
1925     if status['key_mgmt'] != 'WPA2-PSK':
1926         raise Exception("Unexpected key_mgmt")
1927
1928     logger.info("WPS provisioning step (PIN)")
1929     pin = dev[1].wps_read_pin()
1930     hapd.request("WPS_PIN any " + pin)
1931     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1932     dev[1].request("SET wps_fragment_size 50")
1933     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1934     dev[1].wait_connected(timeout=30)
1935     status = dev[1].get_status()
1936     if status['wpa_state'] != 'COMPLETED':
1937         raise Exception("Not fully connected")
1938     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1939         raise Exception("Unexpected encryption configuration")
1940     if status['key_mgmt'] != 'WPA2-PSK':
1941         raise Exception("Unexpected key_mgmt")
1942
1943     logger.info("WPS connection as registrar")
1944     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1945     dev[2].request("SET wps_fragment_size 50")
1946     dev[2].wps_reg(apdev[0]['bssid'], appin)
1947     status = dev[2].get_status()
1948     if status['wpa_state'] != 'COMPLETED':
1949         raise Exception("Not fully connected")
1950     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1951         raise Exception("Unexpected encryption configuration")
1952     if status['key_mgmt'] != 'WPA2-PSK':
1953         raise Exception("Unexpected key_mgmt")
1954
1955 @remote_compatible
1956 def test_ap_wps_new_version_sta(dev, apdev):
1957     """WPS compatibility with new version number on the station"""
1958     ssid = "test-wps-ver"
1959     hapd = hostapd.add_ap(apdev[0],
1960                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1961                             "wpa_passphrase": "12345678", "wpa": "2",
1962                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1963     logger.info("WPS provisioning step")
1964     hapd.request("WPS_PBC")
1965     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1966     dev[0].dump_monitor()
1967     dev[0].request("SET wps_version_number 0x43")
1968     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1969     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1970     dev[0].wait_connected(timeout=30)
1971
1972 @remote_compatible
1973 def test_ap_wps_new_version_ap(dev, apdev):
1974     """WPS compatibility with new version number on the AP"""
1975     ssid = "test-wps-ver"
1976     hapd = hostapd.add_ap(apdev[0],
1977                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1978                             "wpa_passphrase": "12345678", "wpa": "2",
1979                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1980     logger.info("WPS provisioning step")
1981     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1982         raise Exception("Failed to enable test functionality")
1983     hapd.request("WPS_PBC")
1984     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1985     dev[0].dump_monitor()
1986     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1987     dev[0].wait_connected(timeout=30)
1988     hapd.request("SET wps_version_number 0x20")
1989
1990 @remote_compatible
1991 def test_ap_wps_check_pin(dev, apdev):
1992     """Verify PIN checking through control interface"""
1993     hapd = hostapd.add_ap(apdev[0],
1994                           { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1995                             "wpa_passphrase": "12345678", "wpa": "2",
1996                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1997     for t in [ ("12345670", "12345670"),
1998                ("12345678", "FAIL-CHECKSUM"),
1999                ("12345", "FAIL"),
2000                ("123456789", "FAIL"),
2001                ("1234-5670", "12345670"),
2002                ("1234 5670", "12345670"),
2003                ("1-2.3:4 5670", "12345670") ]:
2004         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
2005         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
2006         if res != res2:
2007             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
2008         if res != t[1]:
2009             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
2010
2011     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
2012         raise Exception("Unexpected WPS_CHECK_PIN success")
2013     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
2014         raise Exception("Unexpected WPS_CHECK_PIN success")
2015
2016     for i in range(0, 10):
2017         pin = dev[0].request("WPS_PIN get")
2018         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
2019         if pin != rpin:
2020             raise Exception("Random PIN validation failed for " + pin)
2021
2022 def test_ap_wps_wep_config(dev, apdev):
2023     """WPS 2.0 AP rejecting WEP configuration"""
2024     ssid = "test-wps-config"
2025     appin = "12345670"
2026     hapd = hostapd.add_ap(apdev[0],
2027                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2028                             "ap_pin": appin})
2029     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2030     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
2031                    "hello", no_wait=True)
2032     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
2033     if ev is None:
2034         raise Exception("WPS-FAIL timed out")
2035     if "reason=2" not in ev:
2036         raise Exception("Unexpected reason code in WPS-FAIL")
2037     status = hapd.request("WPS_GET_STATUS")
2038     if "Last WPS result: Failed" not in status:
2039         raise Exception("WPS failure result not shown correctly")
2040     if "Failure Reason: WEP Prohibited" not in status:
2041         raise Exception("Failure reason not reported correctly")
2042     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
2043         raise Exception("Peer address not shown correctly")
2044
2045 def test_ap_wps_wep_enroll(dev, apdev):
2046     """WPS 2.0 STA rejecting WEP configuration"""
2047     ssid = "test-wps-wep"
2048     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2049                "skip_cred_build": "1", "extra_cred": "wps-wep-cred" }
2050     hapd = hostapd.add_ap(apdev[0], params)
2051     hapd.request("WPS_PBC")
2052     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2053     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2054     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
2055     if ev is None:
2056         raise Exception("WPS-FAIL event timed out")
2057     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
2058         raise Exception("Unexpected WPS-FAIL event: " + ev)
2059
2060 @remote_compatible
2061 def test_ap_wps_ie_fragmentation(dev, apdev):
2062     """WPS AP using fragmented WPS IE"""
2063     ssid = "test-wps-ie-fragmentation"
2064     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2065                "wpa_passphrase": "12345678", "wpa": "2",
2066                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2067                "device_name": "1234567890abcdef1234567890abcdef",
2068                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
2069                "model_name": "1234567890abcdef1234567890abcdef",
2070                "model_number": "1234567890abcdef1234567890abcdef",
2071                "serial_number": "1234567890abcdef1234567890abcdef" }
2072     hapd = hostapd.add_ap(apdev[0], params)
2073     hapd.request("WPS_PBC")
2074     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2075     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2076     dev[0].wait_connected(timeout=30)
2077     bss = dev[0].get_bss(apdev[0]['bssid'])
2078     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
2079         logger.info("Device Name not received correctly")
2080         logger.info(bss)
2081         # This can fail if Probe Response frame is missed and Beacon frame was
2082         # used to fill in the BSS entry. This can happen, e.g., during heavy
2083         # load every now and then and is not really an error, so try to
2084         # workaround by runnign another scan.
2085         dev[0].scan(freq="2412", only_new=True)
2086         bss = dev[0].get_bss(apdev[0]['bssid'])
2087         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
2088             logger.info(bss)
2089             raise Exception("Device Name not received correctly")
2090     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
2091         raise Exception("Unexpected number of WPS IEs")
2092
2093 def get_psk(pskfile):
2094     psks = {}
2095     with open(pskfile, "r") as f:
2096         lines = f.read().splitlines()
2097         for l in lines:
2098             if l == "# WPA PSKs":
2099                 continue
2100             (addr,psk) = l.split(' ')
2101             psks[addr] = psk
2102     return psks
2103
2104 def test_ap_wps_per_station_psk(dev, apdev):
2105     """WPS PBC provisioning with per-station PSK"""
2106     addr0 = dev[0].own_addr()
2107     addr1 = dev[1].own_addr()
2108     addr2 = dev[2].own_addr()
2109     ssid = "wps"
2110     appin = "12345670"
2111     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2112     try:
2113         os.remove(pskfile)
2114     except:
2115         pass
2116
2117     hapd = None
2118     try:
2119         with open(pskfile, "w") as f:
2120             f.write("# WPA PSKs\n")
2121
2122         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2123                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2124                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2125                    "wpa_psk_file": pskfile }
2126         hapd = hostapd.add_ap(apdev[0], params)
2127
2128         logger.info("First enrollee")
2129         hapd.request("WPS_PBC")
2130         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2131         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2132         dev[0].wait_connected(timeout=30)
2133
2134         logger.info("Second enrollee")
2135         hapd.request("WPS_PBC")
2136         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2137         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2138         dev[1].wait_connected(timeout=30)
2139
2140         logger.info("External registrar")
2141         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2142         dev[2].wps_reg(apdev[0]['bssid'], appin)
2143
2144         logger.info("Verifying PSK results")
2145         psks = get_psk(pskfile)
2146         if addr0 not in psks:
2147             raise Exception("No PSK recorded for sta0")
2148         if addr1 not in psks:
2149             raise Exception("No PSK recorded for sta1")
2150         if addr2 not in psks:
2151             raise Exception("No PSK recorded for sta2")
2152         if psks[addr0] == psks[addr1]:
2153             raise Exception("Same PSK recorded for sta0 and sta1")
2154         if psks[addr0] == psks[addr2]:
2155             raise Exception("Same PSK recorded for sta0 and sta2")
2156         if psks[addr1] == psks[addr2]:
2157             raise Exception("Same PSK recorded for sta1 and sta2")
2158
2159         dev[0].request("REMOVE_NETWORK all")
2160         logger.info("Second external registrar")
2161         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2162         dev[0].wps_reg(apdev[0]['bssid'], appin)
2163         psks2 = get_psk(pskfile)
2164         if addr0 not in psks2:
2165             raise Exception("No PSK recorded for sta0(reg)")
2166         if psks[addr0] == psks2[addr0]:
2167             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
2168     finally:
2169         os.remove(pskfile)
2170         if hapd:
2171             dev[0].request("DISCONNECT")
2172             dev[1].request("DISCONNECT")
2173             dev[2].request("DISCONNECT")
2174             hapd.disable()
2175             dev[0].flush_scan_cache()
2176             dev[1].flush_scan_cache()
2177             dev[2].flush_scan_cache()
2178
2179 def test_ap_wps_per_station_psk_failure(dev, apdev):
2180     """WPS PBC provisioning with per-station PSK (file not writable)"""
2181     addr0 = dev[0].p2p_dev_addr()
2182     addr1 = dev[1].p2p_dev_addr()
2183     addr2 = dev[2].p2p_dev_addr()
2184     ssid = "wps"
2185     appin = "12345670"
2186     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2187     try:
2188         os.remove(pskfile)
2189     except:
2190         pass
2191
2192     try:
2193         with open(pskfile, "w") as f:
2194             f.write("# WPA PSKs\n")
2195
2196         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2197                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2198                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2199                    "wpa_psk_file": pskfile }
2200         hapd = hostapd.add_ap(apdev[0], params)
2201         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2202             raise Exception("Failed to set wpa_psk_file")
2203
2204         logger.info("First enrollee")
2205         hapd.request("WPS_PBC")
2206         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2207         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2208         dev[0].wait_connected(timeout=30)
2209
2210         logger.info("Second enrollee")
2211         hapd.request("WPS_PBC")
2212         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2213         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2214         dev[1].wait_connected(timeout=30)
2215
2216         logger.info("External registrar")
2217         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2218         dev[2].wps_reg(apdev[0]['bssid'], appin)
2219
2220         logger.info("Verifying PSK results")
2221         psks = get_psk(pskfile)
2222         if len(psks) > 0:
2223             raise Exception("PSK recorded unexpectedly")
2224     finally:
2225         os.remove(pskfile)
2226
2227 def test_ap_wps_pin_request_file(dev, apdev):
2228     """WPS PIN provisioning with configured AP"""
2229     ssid = "wps"
2230     pinfile = "/tmp/ap_wps_pin_request_file.log"
2231     if os.path.exists(pinfile):
2232         os.remove(pinfile)
2233     hapd = hostapd.add_ap(apdev[0],
2234                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2235                             "wps_pin_requests": pinfile,
2236                             "wpa_passphrase": "12345678", "wpa": "2",
2237                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2238     uuid = dev[0].get_status_field("uuid")
2239     pin = dev[0].wps_read_pin()
2240     try:
2241         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2242         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2243         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2244         if ev is None:
2245             raise Exception("PIN needed event not shown")
2246         if uuid not in ev:
2247             raise Exception("UUID mismatch")
2248         dev[0].request("WPS_CANCEL")
2249         success = False
2250         with open(pinfile, "r") as f:
2251             lines = f.readlines()
2252             for l in lines:
2253                 if uuid in l:
2254                     success = True
2255                     break
2256         if not success:
2257             raise Exception("PIN request entry not in the log file")
2258     finally:
2259         try:
2260             os.remove(pinfile)
2261         except:
2262             pass
2263
2264 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2265     """WPS auto-setup with configuration file"""
2266     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2267     ifname = apdev[0]['ifname']
2268     try:
2269         with open(conffile, "w") as f:
2270             f.write("driver=nl80211\n")
2271             f.write("hw_mode=g\n")
2272             f.write("channel=1\n")
2273             f.write("ieee80211n=1\n")
2274             f.write("interface=%s\n" % ifname)
2275             f.write("ctrl_interface=/var/run/hostapd\n")
2276             f.write("ssid=wps\n")
2277             f.write("eap_server=1\n")
2278             f.write("wps_state=1\n")
2279         hapd = hostapd.add_bss(apdev[0], ifname, conffile)
2280         hapd.request("WPS_PBC")
2281         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2282         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2283         dev[0].wait_connected(timeout=30)
2284         with open(conffile, "r") as f:
2285             lines = f.read().splitlines()
2286             vals = dict()
2287             for l in lines:
2288                 try:
2289                     [name,value] = l.split('=', 1)
2290                     vals[name] = value
2291                 except ValueError, e:
2292                     if "# WPS configuration" in l:
2293                         pass
2294                     else:
2295                         raise Exception("Unexpected configuration line: " + l)
2296         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2297             raise Exception("Incorrect configuration: " + str(vals))
2298     finally:
2299         try:
2300             os.remove(conffile)
2301         except:
2302             pass
2303
2304 def test_ap_wps_pbc_timeout(dev, apdev, params):
2305     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2306     if not params['long']:
2307         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2308     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2309     hapd = add_ssdp_ap(apdev[0], ap_uuid)
2310
2311     location = ssdp_get_location(ap_uuid)
2312     urls = upnp_get_urls(location)
2313     eventurl = urlparse.urlparse(urls['event_sub_url'])
2314     ctrlurl = urlparse.urlparse(urls['control_url'])
2315
2316     url = urlparse.urlparse(location)
2317     conn = httplib.HTTPConnection(url.netloc)
2318
2319     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2320         def handle(self):
2321             data = self.rfile.readline().strip()
2322             logger.debug(data)
2323             self.wfile.write(gen_wps_event())
2324
2325     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2326     server.timeout = 1
2327
2328     headers = { "callback": '<http://127.0.0.1:12345/event>',
2329                 "NT": "upnp:event",
2330                 "timeout": "Second-1234" }
2331     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2332     resp = conn.getresponse()
2333     if resp.status != 200:
2334         raise Exception("Unexpected HTTP response: %d" % resp.status)
2335     sid = resp.getheader("sid")
2336     logger.debug("Subscription SID " + sid)
2337
2338     msg = '''<?xml version="1.0"?>
2339 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2340 <s:Body>
2341 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2342 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2343 VFi5hrLk
2344 </NewMessage>
2345 </u:SetSelectedRegistrar>
2346 </s:Body>
2347 </s:Envelope>'''
2348     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2349     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2350     conn.request("POST", ctrlurl.path, msg, headers)
2351     resp = conn.getresponse()
2352     if resp.status != 200:
2353         raise Exception("Unexpected HTTP response: %d" % resp.status)
2354
2355     server.handle_request()
2356
2357     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2358     if "OK" not in dev[0].request("WPS_PBC"):
2359         raise Exception("WPS_PBC failed")
2360
2361     start = os.times()[4]
2362
2363     server.handle_request()
2364     dev[1].request("BSS_FLUSH 0")
2365     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2366                         only_new=True)
2367     bss = dev[1].get_bss(apdev[0]['bssid'])
2368     logger.debug("BSS: " + str(bss))
2369     if '[WPS-AUTH]' not in bss['flags']:
2370         raise Exception("WPS not indicated authorized")
2371
2372     server.handle_request()
2373
2374     wps_timeout_seen = False
2375
2376     while True:
2377         hapd.dump_monitor()
2378         dev[1].dump_monitor()
2379         if not wps_timeout_seen:
2380             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2381             if ev is not None:
2382                 logger.info("PBC timeout seen")
2383                 wps_timeout_seen = True
2384         else:
2385             dev[0].dump_monitor()
2386         now = os.times()[4]
2387         if now - start > 130:
2388             raise Exception("Selected registration information not removed")
2389         dev[1].request("BSS_FLUSH 0")
2390         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2391                             only_new=True)
2392         bss = dev[1].get_bss(apdev[0]['bssid'])
2393         logger.debug("BSS: " + str(bss))
2394         if '[WPS-AUTH]' not in bss['flags']:
2395             break
2396         server.handle_request()
2397
2398     server.server_close()
2399
2400     if wps_timeout_seen:
2401         return
2402
2403     now = os.times()[4]
2404     if now < start + 150:
2405         dur = start + 150 - now
2406     else:
2407         dur = 1
2408     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2409     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2410     if ev is None:
2411         raise Exception("WPS-TIMEOUT not reported")
2412
2413 def add_ssdp_ap(ap, ap_uuid):
2414     ssid = "wps-ssdp"
2415     ap_pin = "12345670"
2416     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2417                "wpa_passphrase": "12345678", "wpa": "2",
2418                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2419                "device_name": "Wireless AP", "manufacturer": "Company",
2420                "model_name": "WAP", "model_number": "123",
2421                "serial_number": "12345", "device_type": "6-0050F204-1",
2422                "os_version": "01020300",
2423                "config_methods": "label push_button",
2424                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2425                "friendly_name": "WPS Access Point",
2426                "manufacturer_url": "http://www.example.com/",
2427                "model_description": "Wireless Access Point",
2428                "model_url": "http://www.example.com/model/",
2429                "upc": "123456789012" }
2430     return hostapd.add_ap(ap, params)
2431
2432 def ssdp_send(msg, no_recv=False):
2433     socket.setdefaulttimeout(1)
2434     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2435     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2436     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2437     sock.bind(("127.0.0.1", 0))
2438     sock.sendto(msg, ("239.255.255.250", 1900))
2439     if no_recv:
2440         return None
2441     return sock.recv(1000)
2442
2443 def ssdp_send_msearch(st, no_recv=False):
2444     msg = '\r\n'.join([
2445             'M-SEARCH * HTTP/1.1',
2446             'HOST: 239.255.255.250:1900',
2447             'MX: 1',
2448             'MAN: "ssdp:discover"',
2449             'ST: ' + st,
2450             '', ''])
2451     return ssdp_send(msg, no_recv=no_recv)
2452
2453 def test_ap_wps_ssdp_msearch(dev, apdev):
2454     """WPS AP and SSDP M-SEARCH messages"""
2455     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2456     add_ssdp_ap(apdev[0], ap_uuid)
2457
2458     msg = '\r\n'.join([
2459             'M-SEARCH * HTTP/1.1',
2460             'Host: 239.255.255.250:1900',
2461             'Mx: 1',
2462             'Man: "ssdp:discover"',
2463             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2464             '', ''])
2465     ssdp_send(msg)
2466
2467     msg = '\r\n'.join([
2468             'M-SEARCH * HTTP/1.1',
2469             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2470             'mx: \t1\t\t   ',
2471             'man: \t \t "ssdp:discover"   ',
2472             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2473             '', ''])
2474     ssdp_send(msg)
2475
2476     ssdp_send_msearch("ssdp:all")
2477     ssdp_send_msearch("upnp:rootdevice")
2478     ssdp_send_msearch("uuid:" + ap_uuid)
2479     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2480     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1")
2481
2482     msg = '\r\n'.join([
2483             'M-SEARCH * HTTP/1.1',
2484             'HOST:\t239.255.255.250:1900',
2485             'MAN: "ssdp:discover"',
2486             'MX: 130',
2487             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2488             '', ''])
2489     ssdp_send(msg, no_recv=True)
2490
2491 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2492     """WPS AP and invalid SSDP M-SEARCH messages"""
2493     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2494     add_ssdp_ap(apdev[0], ap_uuid)
2495
2496     socket.setdefaulttimeout(1)
2497     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2498     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2499     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2500     sock.bind(("127.0.0.1", 0))
2501
2502     logger.debug("Missing MX")
2503     msg = '\r\n'.join([
2504             'M-SEARCH * HTTP/1.1',
2505             'HOST: 239.255.255.250:1900',
2506             'MAN: "ssdp:discover"',
2507             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2508             '', ''])
2509     sock.sendto(msg, ("239.255.255.250", 1900))
2510
2511     logger.debug("Negative MX")
2512     msg = '\r\n'.join([
2513             'M-SEARCH * HTTP/1.1',
2514             'HOST: 239.255.255.250:1900',
2515             'MX: -1',
2516             'MAN: "ssdp:discover"',
2517             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2518             '', ''])
2519     sock.sendto(msg, ("239.255.255.250", 1900))
2520
2521     logger.debug("Invalid MX")
2522     msg = '\r\n'.join([
2523             'M-SEARCH * HTTP/1.1',
2524             'HOST: 239.255.255.250:1900',
2525             'MX; 1',
2526             'MAN: "ssdp:discover"',
2527             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2528             '', ''])
2529     sock.sendto(msg, ("239.255.255.250", 1900))
2530
2531     logger.debug("Missing MAN")
2532     msg = '\r\n'.join([
2533             'M-SEARCH * HTTP/1.1',
2534             'HOST: 239.255.255.250:1900',
2535             'MX: 1',
2536             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2537             '', ''])
2538     sock.sendto(msg, ("239.255.255.250", 1900))
2539
2540     logger.debug("Invalid MAN")
2541     msg = '\r\n'.join([
2542             'M-SEARCH * HTTP/1.1',
2543             'HOST: 239.255.255.250:1900',
2544             'MX: 1',
2545             'MAN: foo',
2546             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2547             '', ''])
2548     sock.sendto(msg, ("239.255.255.250", 1900))
2549     msg = '\r\n'.join([
2550             'M-SEARCH * HTTP/1.1',
2551             'HOST: 239.255.255.250:1900',
2552             'MX: 1',
2553             'MAN; "ssdp:discover"',
2554             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2555             '', ''])
2556     sock.sendto(msg, ("239.255.255.250", 1900))
2557
2558     logger.debug("Missing HOST")
2559     msg = '\r\n'.join([
2560             'M-SEARCH * HTTP/1.1',
2561             'MAN: "ssdp:discover"',
2562             'MX: 1',
2563             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2564             '', ''])
2565     sock.sendto(msg, ("239.255.255.250", 1900))
2566
2567     logger.debug("Missing ST")
2568     msg = '\r\n'.join([
2569             'M-SEARCH * HTTP/1.1',
2570             'HOST: 239.255.255.250:1900',
2571             'MAN: "ssdp:discover"',
2572             'MX: 1',
2573             '', ''])
2574     sock.sendto(msg, ("239.255.255.250", 1900))
2575
2576     logger.debug("Mismatching ST")
2577     msg = '\r\n'.join([
2578             'M-SEARCH * HTTP/1.1',
2579             'HOST: 239.255.255.250:1900',
2580             'MAN: "ssdp:discover"',
2581             'MX: 1',
2582             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2583             '', ''])
2584     sock.sendto(msg, ("239.255.255.250", 1900))
2585     msg = '\r\n'.join([
2586             'M-SEARCH * HTTP/1.1',
2587             'HOST: 239.255.255.250:1900',
2588             'MAN: "ssdp:discover"',
2589             'MX: 1',
2590             'ST: foo:bar',
2591             '', ''])
2592     sock.sendto(msg, ("239.255.255.250", 1900))
2593     msg = '\r\n'.join([
2594             'M-SEARCH * HTTP/1.1',
2595             'HOST: 239.255.255.250:1900',
2596             'MAN: "ssdp:discover"',
2597             'MX: 1',
2598             'ST: foobar',
2599             '', ''])
2600     sock.sendto(msg, ("239.255.255.250", 1900))
2601
2602     logger.debug("Invalid ST")
2603     msg = '\r\n'.join([
2604             'M-SEARCH * HTTP/1.1',
2605             'HOST: 239.255.255.250:1900',
2606             'MAN: "ssdp:discover"',
2607             'MX: 1',
2608             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2609             '', ''])
2610     sock.sendto(msg, ("239.255.255.250", 1900))
2611
2612     logger.debug("Invalid M-SEARCH")
2613     msg = '\r\n'.join([
2614             'M+SEARCH * HTTP/1.1',
2615             'HOST: 239.255.255.250:1900',
2616             'MAN: "ssdp:discover"',
2617             'MX: 1',
2618             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2619             '', ''])
2620     sock.sendto(msg, ("239.255.255.250", 1900))
2621     msg = '\r\n'.join([
2622             'M-SEARCH-* HTTP/1.1',
2623             'HOST: 239.255.255.250:1900',
2624             'MAN: "ssdp:discover"',
2625             'MX: 1',
2626             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2627             '', ''])
2628     sock.sendto(msg, ("239.255.255.250", 1900))
2629
2630     logger.debug("Invalid message format")
2631     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2632     msg = '\r'.join([
2633             'M-SEARCH * HTTP/1.1',
2634             'HOST: 239.255.255.250:1900',
2635             'MAN: "ssdp:discover"',
2636             'MX: 1',
2637             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2638             '', ''])
2639     sock.sendto(msg, ("239.255.255.250", 1900))
2640
2641     try:
2642         r = sock.recv(1000)
2643         raise Exception("Unexpected M-SEARCH response: " + r)
2644     except socket.timeout:
2645         pass
2646
2647     logger.debug("Valid M-SEARCH")
2648     msg = '\r\n'.join([
2649             'M-SEARCH * HTTP/1.1',
2650             'HOST: 239.255.255.250:1900',
2651             'MAN: "ssdp:discover"',
2652             'MX: 1',
2653             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2654             '', ''])
2655     sock.sendto(msg, ("239.255.255.250", 1900))
2656
2657     try:
2658         r = sock.recv(1000)
2659         pass
2660     except socket.timeout:
2661         raise Exception("No SSDP response")
2662
2663 def test_ap_wps_ssdp_burst(dev, apdev):
2664     """WPS AP and SSDP burst"""
2665     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2666     add_ssdp_ap(apdev[0], ap_uuid)
2667
2668     msg = '\r\n'.join([
2669             'M-SEARCH * HTTP/1.1',
2670             'HOST: 239.255.255.250:1900',
2671             'MAN: "ssdp:discover"',
2672             'MX: 1',
2673             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2674             '', ''])
2675     socket.setdefaulttimeout(1)
2676     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2677     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2678     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2679     sock.bind(("127.0.0.1", 0))
2680     for i in range(0, 25):
2681         sock.sendto(msg, ("239.255.255.250", 1900))
2682     resp = 0
2683     while True:
2684         try:
2685             r = sock.recv(1000)
2686             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2687                 raise Exception("Unexpected message: " + r)
2688             resp += 1
2689         except socket.timeout:
2690             break
2691     if resp < 20:
2692         raise Exception("Too few SSDP responses")
2693
2694     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2695     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2696     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2697     sock.bind(("127.0.0.1", 0))
2698     for i in range(0, 25):
2699         sock.sendto(msg, ("239.255.255.250", 1900))
2700     while True:
2701         try:
2702             r = sock.recv(1000)
2703             if ap_uuid in r:
2704                 break
2705         except socket.timeout:
2706             raise Exception("No SSDP response")
2707
2708 def ssdp_get_location(uuid):
2709     res = ssdp_send_msearch("uuid:" + uuid)
2710     location = None
2711     for l in res.splitlines():
2712         if l.lower().startswith("location:"):
2713             location = l.split(':', 1)[1].strip()
2714             break
2715     if location is None:
2716         raise Exception("No UPnP location found")
2717     return location
2718
2719 def upnp_get_urls(location):
2720     conn = urllib.urlopen(location, proxies={})
2721     tree = ET.parse(conn)
2722     root = tree.getroot()
2723     urn = '{urn:schemas-upnp-org:device-1-0}'
2724     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2725     res = {}
2726     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2727     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2728     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2729     return res
2730
2731 def upnp_soap_action(conn, path, action, include_soap_action=True,
2732                      soap_action_override=None, newmsg=None, neweventtype=None,
2733                      neweventmac=None):
2734     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2735     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2736     ET.register_namespace('soapenv', soapns)
2737     ET.register_namespace('wfa', wpsns)
2738     attrib = {}
2739     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2740     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2741     body = ET.SubElement(root, "{%s}Body" % soapns)
2742     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2743     if newmsg:
2744         msg = ET.SubElement(act, "NewMessage")
2745         msg.text = base64.b64encode(newmsg)
2746     if neweventtype:
2747         msg = ET.SubElement(act, "NewWLANEventType")
2748         msg.text = neweventtype
2749     if neweventmac:
2750         msg = ET.SubElement(act, "NewWLANEventMAC")
2751         msg.text = neweventmac
2752     tree = ET.ElementTree(root)
2753     soap = StringIO.StringIO()
2754     tree.write(soap, xml_declaration=True, encoding='utf-8')
2755
2756     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2757     if include_soap_action:
2758         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2759     elif soap_action_override:
2760         headers["SOAPAction"] = soap_action_override
2761     conn.request("POST", path, soap.getvalue(), headers)
2762     return conn.getresponse()
2763
2764 def test_ap_wps_upnp(dev, apdev):
2765     """WPS AP and UPnP operations"""
2766     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2767     add_ssdp_ap(apdev[0], ap_uuid)
2768
2769     location = ssdp_get_location(ap_uuid)
2770     urls = upnp_get_urls(location)
2771
2772     conn = urllib.urlopen(urls['scpd_url'], proxies={})
2773     scpd = conn.read()
2774
2775     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"),
2776                           proxies={})
2777     if conn.getcode() != 404:
2778         raise Exception("Unexpected HTTP response to GET unknown URL")
2779
2780     url = urlparse.urlparse(location)
2781     conn = httplib.HTTPConnection(url.netloc)
2782     #conn.set_debuglevel(1)
2783     headers = { "Content-type": 'text/xml; charset="utf-8"',
2784                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2785     conn.request("POST", "hello", "\r\n\r\n", headers)
2786     resp = conn.getresponse()
2787     if resp.status != 404:
2788         raise Exception("Unexpected HTTP response: %d" % resp.status)
2789
2790     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2791     resp = conn.getresponse()
2792     if resp.status != 501:
2793         raise Exception("Unexpected HTTP response: %d" % resp.status)
2794
2795     headers = { "Content-type": 'text/xml; charset="utf-8"',
2796                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2797     ctrlurl = urlparse.urlparse(urls['control_url'])
2798     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2799     resp = conn.getresponse()
2800     if resp.status != 401:
2801         raise Exception("Unexpected HTTP response: %d" % resp.status)
2802
2803     logger.debug("GetDeviceInfo without SOAPAction header")
2804     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2805                             include_soap_action=False)
2806     if resp.status != 401:
2807         raise Exception("Unexpected HTTP response: %d" % resp.status)
2808
2809     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2810     for act in [ "foo",
2811                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2812                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2813                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2814         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2815                                 include_soap_action=False,
2816                                 soap_action_override=act)
2817         if resp.status != 401:
2818             raise Exception("Unexpected HTTP response: %d" % resp.status)
2819
2820     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2821     if resp.status != 200:
2822         raise Exception("Unexpected HTTP response: %d" % resp.status)
2823     dev = resp.read()
2824     if "NewDeviceInfo" not in dev:
2825         raise Exception("Unexpected GetDeviceInfo response")
2826
2827     logger.debug("PutMessage without required parameters")
2828     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2829     if resp.status != 600:
2830         raise Exception("Unexpected HTTP response: %d" % resp.status)
2831
2832     logger.debug("PutWLANResponse without required parameters")
2833     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2834     if resp.status != 600:
2835         raise Exception("Unexpected HTTP response: %d" % resp.status)
2836
2837     logger.debug("SetSelectedRegistrar from unregistered ER")
2838     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2839     if resp.status != 501:
2840         raise Exception("Unexpected HTTP response: %d" % resp.status)
2841
2842     logger.debug("Unknown action")
2843     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2844     if resp.status != 401:
2845         raise Exception("Unexpected HTTP response: %d" % resp.status)
2846
2847 def test_ap_wps_upnp_subscribe(dev, apdev):
2848     """WPS AP and UPnP event subscription"""
2849     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2850     hapd = add_ssdp_ap(apdev[0], ap_uuid)
2851
2852     location = ssdp_get_location(ap_uuid)
2853     urls = upnp_get_urls(location)
2854     eventurl = urlparse.urlparse(urls['event_sub_url'])
2855
2856     url = urlparse.urlparse(location)
2857     conn = httplib.HTTPConnection(url.netloc)
2858     #conn.set_debuglevel(1)
2859     headers = { "callback": '<http://127.0.0.1:12345/event>',
2860                 "timeout": "Second-1234" }
2861     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2862     resp = conn.getresponse()
2863     if resp.status != 412:
2864         raise Exception("Unexpected HTTP response: %d" % resp.status)
2865
2866     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2867     resp = conn.getresponse()
2868     if resp.status != 412:
2869         raise Exception("Unexpected HTTP response: %d" % resp.status)
2870
2871     headers = { "NT": "upnp:event",
2872                 "timeout": "Second-1234" }
2873     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2874     resp = conn.getresponse()
2875     if resp.status != 412:
2876         raise Exception("Unexpected HTTP response: %d" % resp.status)
2877
2878     headers = { "callback": '<http://127.0.0.1:12345/event>',
2879                 "NT": "upnp:foobar",
2880                 "timeout": "Second-1234" }
2881     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2882     resp = conn.getresponse()
2883     if resp.status != 400:
2884         raise Exception("Unexpected HTTP response: %d" % resp.status)
2885
2886     logger.debug("Valid subscription")
2887     headers = { "callback": '<http://127.0.0.1:12345/event>',
2888                 "NT": "upnp:event",
2889                 "timeout": "Second-1234" }
2890     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2891     resp = conn.getresponse()
2892     if resp.status != 200:
2893         raise Exception("Unexpected HTTP response: %d" % resp.status)
2894     sid = resp.getheader("sid")
2895     logger.debug("Subscription SID " + sid)
2896
2897     logger.debug("Invalid re-subscription")
2898     headers = { "NT": "upnp:event",
2899                 "sid": "123456734567854",
2900                 "timeout": "Second-1234" }
2901     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2902     resp = conn.getresponse()
2903     if resp.status != 400:
2904         raise Exception("Unexpected HTTP response: %d" % resp.status)
2905
2906     logger.debug("Invalid re-subscription")
2907     headers = { "NT": "upnp:event",
2908                 "sid": "uuid:123456734567854",
2909                 "timeout": "Second-1234" }
2910     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2911     resp = conn.getresponse()
2912     if resp.status != 400:
2913         raise Exception("Unexpected HTTP response: %d" % resp.status)
2914
2915     logger.debug("Invalid re-subscription")
2916     headers = { "callback": '<http://127.0.0.1:12345/event>',
2917                 "NT": "upnp:event",
2918                 "sid": sid,
2919                 "timeout": "Second-1234" }
2920     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2921     resp = conn.getresponse()
2922     if resp.status != 400:
2923         raise Exception("Unexpected HTTP response: %d" % resp.status)
2924
2925     logger.debug("SID mismatch in re-subscription")
2926     headers = { "NT": "upnp:event",
2927                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2928                 "timeout": "Second-1234" }
2929     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2930     resp = conn.getresponse()
2931     if resp.status != 412:
2932         raise Exception("Unexpected HTTP response: %d" % resp.status)
2933
2934     logger.debug("Valid re-subscription")
2935     headers = { "NT": "upnp:event",
2936                 "sid": sid,
2937                 "timeout": "Second-1234" }
2938     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2939     resp = conn.getresponse()
2940     if resp.status != 200:
2941         raise Exception("Unexpected HTTP response: %d" % resp.status)
2942     sid2 = resp.getheader("sid")
2943     logger.debug("Subscription SID " + sid2)
2944
2945     if sid != sid2:
2946         raise Exception("Unexpected SID change")
2947
2948     logger.debug("Valid re-subscription")
2949     headers = { "NT": "upnp:event",
2950                 "sid": "uuid: \t \t" + sid.split(':')[1],
2951                 "timeout": "Second-1234" }
2952     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2953     resp = conn.getresponse()
2954     if resp.status != 200:
2955         raise Exception("Unexpected HTTP response: %d" % resp.status)
2956
2957     logger.debug("Invalid unsubscription")
2958     headers = { "sid": sid }
2959     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2960     resp = conn.getresponse()
2961     if resp.status != 412:
2962         raise Exception("Unexpected HTTP response: %d" % resp.status)
2963     headers = { "foo": "bar" }
2964     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2965     resp = conn.getresponse()
2966     if resp.status != 412:
2967         raise Exception("Unexpected HTTP response: %d" % resp.status)
2968
2969     logger.debug("Valid unsubscription")
2970     headers = { "sid": sid }
2971     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2972     resp = conn.getresponse()
2973     if resp.status != 200:
2974         raise Exception("Unexpected HTTP response: %d" % resp.status)
2975
2976     logger.debug("Unsubscription for not existing SID")
2977     headers = { "sid": sid }
2978     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2979     resp = conn.getresponse()
2980     if resp.status != 412:
2981         raise Exception("Unexpected HTTP response: %d" % resp.status)
2982
2983     logger.debug("Invalid unsubscription")
2984     headers = { "sid": " \t \tfoo" }
2985     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2986     resp = conn.getresponse()
2987     if resp.status != 400:
2988         raise Exception("Unexpected HTTP response: %d" % resp.status)
2989
2990     logger.debug("Invalid unsubscription")
2991     headers = { "sid": "uuid:\t \tfoo" }
2992     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2993     resp = conn.getresponse()
2994     if resp.status != 400:
2995         raise Exception("Unexpected HTTP response: %d" % resp.status)
2996
2997     logger.debug("Invalid unsubscription")
2998     headers = { "NT": "upnp:event",
2999                 "sid": sid }
3000     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3001     resp = conn.getresponse()
3002     if resp.status != 400:
3003         raise Exception("Unexpected HTTP response: %d" % resp.status)
3004     headers = { "callback": '<http://127.0.0.1:12345/event>',
3005                 "sid": sid }
3006     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3007     resp = conn.getresponse()
3008     if resp.status != 400:
3009         raise Exception("Unexpected HTTP response: %d" % resp.status)
3010
3011     logger.debug("Valid subscription with multiple callbacks")
3012     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>',
3013                 "NT": "upnp:event",
3014                 "timeout": "Second-1234" }
3015     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3016     resp = conn.getresponse()
3017     if resp.status != 200:
3018         raise Exception("Unexpected HTTP response: %d" % resp.status)
3019     sid = resp.getheader("sid")
3020     logger.debug("Subscription SID " + sid)
3021
3022     # Force subscription to be deleted due to errors
3023     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3024     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3025     with alloc_fail(hapd, 1, "event_build_message"):
3026         for i in range(10):
3027             dev[1].dump_monitor()
3028             dev[2].dump_monitor()
3029             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3030             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3031             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3032             dev[1].request("WPS_CANCEL")
3033             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3034             dev[2].request("WPS_CANCEL")
3035             if i % 4 == 1:
3036                 time.sleep(1)
3037             else:
3038                 time.sleep(0.1)
3039     time.sleep(0.2)
3040
3041     headers = { "sid": sid }
3042     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
3043     resp = conn.getresponse()
3044     if resp.status != 200 and resp.status != 412:
3045         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
3046
3047     headers = { "callback": '<http://127.0.0.1:12345/event>',
3048                 "NT": "upnp:event",
3049                 "timeout": "Second-1234" }
3050     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
3051         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3052         resp = conn.getresponse()
3053         if resp.status != 200:
3054             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
3055         sid = resp.getheader("sid")
3056         logger.debug("Subscription SID " + sid)
3057
3058     headers = { "sid": sid }
3059     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3060     resp = conn.getresponse()
3061     if resp.status != 200:
3062         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
3063
3064     headers = { "callback": '<http://127.0.0.1:12345/event>',
3065                 "NT": "upnp:event",
3066                 "timeout": "Second-1234" }
3067     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3068     resp = conn.getresponse()
3069     if resp.status != 200:
3070         raise Exception("Unexpected HTTP response: %d" % resp.status)
3071     sid = resp.getheader("sid")
3072     logger.debug("Subscription SID " + sid)
3073
3074     with alloc_fail(hapd, 1, "=event_add"):
3075         for i in range(2):
3076             dev[1].dump_monitor()
3077             dev[2].dump_monitor()
3078             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3079             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3080             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3081             dev[1].request("WPS_CANCEL")
3082             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3083             dev[2].request("WPS_CANCEL")
3084             if i == 0:
3085                 time.sleep(1)
3086             else:
3087                 time.sleep(0.1)
3088
3089     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3090     resp = conn.getresponse()
3091     if resp.status != 200:
3092         raise Exception("Unexpected HTTP response: %d" % resp.status)
3093
3094     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
3095         dev[1].dump_monitor()
3096         dev[2].dump_monitor()
3097         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3098         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3099         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3100         dev[1].request("WPS_CANCEL")
3101         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3102         dev[2].request("WPS_CANCEL")
3103         time.sleep(0.1)
3104
3105     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
3106         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3107         resp = conn.getresponse()
3108         if resp.status != 500:
3109             raise Exception("Unexpected HTTP response: %d" % resp.status)
3110
3111     with alloc_fail(hapd, 1, "=subscription_start"):
3112         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3113         resp = conn.getresponse()
3114         if resp.status != 500:
3115             raise Exception("Unexpected HTTP response: %d" % resp.status)
3116
3117     headers = { "callback": '',
3118                 "NT": "upnp:event",
3119                 "timeout": "Second-1234" }
3120     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3121     resp = conn.getresponse()
3122     if resp.status != 500:
3123         raise Exception("Unexpected HTTP response: %d" % resp.status)
3124
3125     headers = { "callback": ' <',
3126                 "NT": "upnp:event",
3127                 "timeout": "Second-1234" }
3128     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3129     resp = conn.getresponse()
3130     if resp.status != 500:
3131         raise Exception("Unexpected HTTP response: %d" % resp.status)
3132
3133     headers = { "callback": '<http://127.0.0.1:12345/event>',
3134                 "NT": "upnp:event",
3135                 "timeout": "Second-1234" }
3136     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
3137         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3138         resp = conn.getresponse()
3139         if resp.status != 500:
3140             raise Exception("Unexpected HTTP response: %d" % resp.status)
3141
3142     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
3143         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3144         resp = conn.getresponse()
3145         if resp.status != 500:
3146             raise Exception("Unexpected HTTP response: %d" % resp.status)
3147
3148     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
3149         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3150         resp = conn.getresponse()
3151         if resp.status != 500:
3152             raise Exception("Unexpected HTTP response: %d" % resp.status)
3153
3154     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
3155         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3156         resp = conn.getresponse()
3157         if resp.status != 500:
3158             raise Exception("Unexpected HTTP response: %d" % resp.status)
3159
3160     for i in range(6):
3161         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
3162                     "NT": "upnp:event",
3163                     "timeout": "Second-1234" }
3164         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3165         resp = conn.getresponse()
3166         if resp.status != 200:
3167             raise Exception("Unexpected HTTP response: %d" % resp.status)
3168
3169     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
3170         dev[1].dump_monitor()
3171         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3172         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3173         dev[1].request("WPS_CANCEL")
3174         time.sleep(0.1)
3175
3176     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
3177         dev[1].dump_monitor()
3178         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3179         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3180         dev[1].request("WPS_CANCEL")
3181         time.sleep(0.1)
3182
3183     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
3184         dev[1].dump_monitor()
3185         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3186         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3187         dev[1].request("WPS_CANCEL")
3188         time.sleep(0.1)
3189
3190     hapd.disable()
3191     with alloc_fail(hapd, 1, "get_netif_info"):
3192         if "FAIL" not in hapd.request("ENABLE"):
3193             raise Exception("ENABLE succeeded during OOM")
3194
3195 def test_ap_wps_upnp_subscribe_events(dev, apdev):
3196     """WPS AP and UPnP event subscription and many events"""
3197     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3198     hapd = add_ssdp_ap(apdev[0], ap_uuid)
3199
3200     location = ssdp_get_location(ap_uuid)
3201     urls = upnp_get_urls(location)
3202     eventurl = urlparse.urlparse(urls['event_sub_url'])
3203
3204     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
3205         def handle(self):
3206             data = self.rfile.readline().strip()
3207             logger.debug(data)
3208             self.wfile.write(gen_wps_event())
3209
3210     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
3211     server.timeout = 1
3212
3213     url = urlparse.urlparse(location)
3214     conn = httplib.HTTPConnection(url.netloc)
3215
3216     headers = { "callback": '<http://127.0.0.1:12345/event>',
3217                 "NT": "upnp:event",
3218                 "timeout": "Second-1234" }
3219     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3220     resp = conn.getresponse()
3221     if resp.status != 200:
3222         raise Exception("Unexpected HTTP response: %d" % resp.status)
3223     sid = resp.getheader("sid")
3224     logger.debug("Subscription SID " + sid)
3225
3226     # Fetch the first event message
3227     server.handle_request()
3228
3229     # Force subscription event queue to reach the maximum length by generating
3230     # new proxied events without the ER fetching any of the pending events.
3231     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3232     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3233     for i in range(16):
3234         dev[1].dump_monitor()
3235         dev[2].dump_monitor()
3236         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3237         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3238         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3239         dev[1].request("WPS_CANCEL")
3240         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3241         dev[2].request("WPS_CANCEL")
3242         if i % 4 == 1:
3243             time.sleep(1)
3244         else:
3245             time.sleep(0.1)
3246
3247     hapd.request("WPS_PIN any 12345670")
3248     dev[1].dump_monitor()
3249     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3250     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3251     if ev is None:
3252         raise Exception("WPS success not reported")
3253
3254     # Close the WPS ER HTTP server without fetching all the pending events.
3255     # This tests hostapd code path that clears subscription and the remaining
3256     # event queue when the interface is deinitialized.
3257     server.handle_request()
3258     server.server_close()
3259
3260     dev[1].wait_connected()
3261
3262 def test_ap_wps_upnp_http_proto(dev, apdev):
3263     """WPS AP and UPnP/HTTP protocol testing"""
3264     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3265     add_ssdp_ap(apdev[0], ap_uuid)
3266
3267     location = ssdp_get_location(ap_uuid)
3268
3269     url = urlparse.urlparse(location)
3270     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3271     #conn.set_debuglevel(1)
3272
3273     conn.request("HEAD", "hello")
3274     resp = conn.getresponse()
3275     if resp.status != 501:
3276         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3277     conn.close()
3278
3279     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3280         try:
3281             conn.request(cmd, "hello")
3282             resp = conn.getresponse()
3283         except Exception, e:
3284             pass
3285         conn.close()
3286
3287     headers = { "Content-Length": 'abc' }
3288     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3289     try:
3290         resp = conn.getresponse()
3291     except Exception, e:
3292         pass
3293     conn.close()
3294
3295     headers = { "Content-Length": '-10' }
3296     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3297     try:
3298         resp = conn.getresponse()
3299     except Exception, e:
3300         pass
3301     conn.close()
3302
3303     headers = { "Content-Length": '10000000000000' }
3304     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3305     try:
3306         resp = conn.getresponse()
3307     except Exception, e:
3308         pass
3309     conn.close()
3310
3311     headers = { "Transfer-Encoding": 'abc' }
3312     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3313     resp = conn.getresponse()
3314     if resp.status != 501:
3315         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3316     conn.close()
3317
3318     headers = { "Transfer-Encoding": 'chunked' }
3319     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3320     resp = conn.getresponse()
3321     if resp.status != 501:
3322         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3323     conn.close()
3324
3325     # Too long a header
3326     conn.request("HEAD", 5000 * 'A')
3327     try:
3328         resp = conn.getresponse()
3329     except Exception, e:
3330         pass
3331     conn.close()
3332
3333     # Long URL but within header length limits
3334     conn.request("HEAD", 3000 * 'A')
3335     resp = conn.getresponse()
3336     if resp.status != 501:
3337         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3338     conn.close()
3339
3340     headers = { "Content-Length": '20' }
3341     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3342     try:
3343         resp = conn.getresponse()
3344     except Exception, e:
3345         pass
3346     conn.close()
3347
3348     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3349     resp = conn.getresponse()
3350     if resp.status != 404:
3351         raise Exception("Unexpected HTTP response: %d" % resp.status)
3352     conn.close()
3353
3354     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3355     try:
3356         resp = conn.getresponse()
3357     except Exception, e:
3358         pass
3359     conn.close()
3360
3361 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3362     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3363     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3364     add_ssdp_ap(apdev[0], ap_uuid)
3365
3366     location = ssdp_get_location(ap_uuid)
3367
3368     url = urlparse.urlparse(location)
3369     conn = httplib.HTTPConnection(url.netloc)
3370     #conn.set_debuglevel(1)
3371
3372     headers = { "Transfer-Encoding": 'chunked' }
3373     conn.request("POST", "hello",
3374                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3375                  headers)
3376     resp = conn.getresponse()
3377     if resp.status != 404:
3378         raise Exception("Unexpected HTTP response: %d" % resp.status)
3379     conn.close()
3380
3381     conn.putrequest("POST", "hello")
3382     conn.putheader('Transfer-Encoding', 'chunked')
3383     conn.endheaders()
3384     conn.send("a\r\nabcdefghij\r\n")
3385     time.sleep(0.1)
3386     conn.send("2\r\nkl\r\n")
3387     conn.send("0\r\n\r\n")
3388     resp = conn.getresponse()
3389     if resp.status != 404:
3390         raise Exception("Unexpected HTTP response: %d" % resp.status)
3391     conn.close()
3392
3393     conn.putrequest("POST", "hello")
3394     conn.putheader('Transfer-Encoding', 'chunked')
3395     conn.endheaders()
3396     completed = False
3397     try:
3398         for i in range(20000):
3399             conn.send("1\r\nZ\r\n")
3400         conn.send("0\r\n\r\n")
3401         resp = conn.getresponse()
3402         completed = True
3403     except Exception, e:
3404         pass
3405     conn.close()
3406     if completed:
3407         raise Exception("Too long chunked request did not result in connection reset")
3408
3409     headers = { "Transfer-Encoding": 'chunked' }
3410     conn.request("POST", "hello", "80000000\r\na", headers)
3411     try:
3412         resp = conn.getresponse()
3413     except Exception, e:
3414         pass
3415     conn.close()
3416
3417     conn.request("POST", "hello", "10000000\r\na", headers)
3418     try:
3419         resp = conn.getresponse()
3420     except Exception, e:
3421         pass
3422     conn.close()
3423
3424 @remote_compatible
3425 def test_ap_wps_disabled(dev, apdev):
3426     """WPS operations while WPS is disabled"""
3427     ssid = "test-wps-disabled"
3428     hapd = hostapd.add_ap(apdev[0], { "ssid": ssid })
3429     if "FAIL" not in hapd.request("WPS_PBC"):
3430         raise Exception("WPS_PBC succeeded unexpectedly")
3431     if "FAIL" not in hapd.request("WPS_CANCEL"):
3432         raise Exception("WPS_CANCEL succeeded unexpectedly")
3433
3434 def test_ap_wps_mixed_cred(dev, apdev):
3435     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3436     ssid = "test-wps-wep"
3437     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3438                "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" }
3439     hapd = hostapd.add_ap(apdev[0], params)
3440     hapd.request("WPS_PBC")
3441     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3442     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3443     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3444     if ev is None:
3445         raise Exception("WPS-SUCCESS event timed out")
3446     nets = dev[0].list_networks()
3447     if len(nets) != 1:
3448         raise Exception("Unexpected number of network blocks")
3449     id = nets[0]['id']
3450     proto = dev[0].get_network(id, "proto")
3451     if proto != "WPA RSN":
3452         raise Exception("Unexpected merged proto field value: " + proto)
3453     pairwise = dev[0].get_network(id, "pairwise")
3454     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3455         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3456
3457 @remote_compatible
3458 def test_ap_wps_while_connected(dev, apdev):
3459     """WPS PBC provisioning while connected to another AP"""
3460     ssid = "test-wps-conf"
3461     hapd = hostapd.add_ap(apdev[0],
3462                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3463                             "wpa_passphrase": "12345678", "wpa": "2",
3464                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3465
3466     hostapd.add_ap(apdev[1], { "ssid": "open" })
3467     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3468
3469     logger.info("WPS provisioning step")
3470     hapd.request("WPS_PBC")
3471     dev[0].dump_monitor()
3472     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3473     dev[0].wait_connected(timeout=30)
3474     status = dev[0].get_status()
3475     if status['bssid'] != apdev[0]['bssid']:
3476         raise Exception("Unexpected BSSID")
3477
3478 @remote_compatible
3479 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3480     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3481     ssid = "test-wps-conf"
3482     hapd = hostapd.add_ap(apdev[0],
3483                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3484                             "wpa_passphrase": "12345678", "wpa": "2",
3485                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3486
3487     hostapd.add_ap(apdev[1], { "ssid": "open" })
3488
3489     try:
3490         dev[0].request("STA_AUTOCONNECT 0")
3491         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3492
3493         logger.info("WPS provisioning step")
3494         hapd.request("WPS_PBC")
3495         dev[0].dump_monitor()
3496         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3497         dev[0].wait_connected(timeout=30)
3498         status = dev[0].get_status()
3499         if status['bssid'] != apdev[0]['bssid']:
3500             raise Exception("Unexpected BSSID")
3501     finally:
3502         dev[0].request("STA_AUTOCONNECT 1")
3503
3504 @remote_compatible
3505 def test_ap_wps_from_event(dev, apdev):
3506     """WPS PBC event on AP to enable PBC"""
3507     ssid = "test-wps-conf"
3508     hapd = hostapd.add_ap(apdev[0],
3509                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3510                             "wpa_passphrase": "12345678", "wpa": "2",
3511                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3512     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3513     dev[0].dump_monitor()
3514     hapd.dump_monitor()
3515     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3516
3517     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3518     if ev is None:
3519         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3520     vals = ev.split(' ')
3521     if vals[1] != dev[0].p2p_interface_addr():
3522         raise Exception("Unexpected enrollee address: " + vals[1])
3523     if vals[5] != '4':
3524         raise Exception("Unexpected Device Password Id: " + vals[5])
3525     hapd.request("WPS_PBC")
3526     dev[0].wait_connected(timeout=30)
3527
3528 def test_ap_wps_ap_scan_2(dev, apdev):
3529     """AP_SCAN 2 for WPS"""
3530     ssid = "test-wps-conf"
3531     hapd = hostapd.add_ap(apdev[0],
3532                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3533                             "wpa_passphrase": "12345678", "wpa": "2",
3534                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3535     hapd.request("WPS_PBC")
3536
3537     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3538     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3539     wpas.dump_monitor()
3540
3541     if "OK" not in wpas.request("AP_SCAN 2"):
3542         raise Exception("Failed to set AP_SCAN 2")
3543
3544     wpas.flush_scan_cache()
3545     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3546     wpas.dump_monitor()
3547     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3548     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3549     if ev is None:
3550         raise Exception("WPS-SUCCESS event timed out")
3551     wpas.wait_connected(timeout=30)
3552     wpas.dump_monitor()
3553     wpas.request("DISCONNECT")
3554     wpas.request("BSS_FLUSH 0")
3555     wpas.dump_monitor()
3556     wpas.request("REASSOCIATE")
3557     wpas.wait_connected(timeout=30)
3558     wpas.dump_monitor()
3559
3560 @remote_compatible
3561 def test_ap_wps_eapol_workaround(dev, apdev):
3562     """EAPOL workaround code path for 802.1X header length mismatch"""
3563     ssid = "test-wps"
3564     hapd = hostapd.add_ap(apdev[0],
3565                           { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3566     bssid = apdev[0]['bssid']
3567     hapd.request("SET ext_eapol_frame_io 1")
3568     dev[0].request("SET ext_eapol_frame_io 1")
3569     hapd.request("WPS_PBC")
3570     dev[0].request("WPS_PBC")
3571
3572     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3573     if ev is None:
3574         raise Exception("Timeout on EAPOL-TX from hostapd")
3575
3576     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3577     if "OK" not in res:
3578         raise Exception("EAPOL_RX to wpa_supplicant failed")
3579
3580 def test_ap_wps_iteration(dev, apdev):
3581     """WPS PIN and iterate through APs without selected registrar"""
3582     ssid = "test-wps-conf"
3583     hapd = hostapd.add_ap(apdev[0],
3584                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3585                             "wpa_passphrase": "12345678", "wpa": "2",
3586                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3587
3588     ssid2 = "test-wps-conf2"
3589     hapd2 = hostapd.add_ap(apdev[1],
3590                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3591                              "wpa_passphrase": "12345678", "wpa": "2",
3592                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3593
3594     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3595     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3596     dev[0].dump_monitor()
3597     pin = dev[0].request("WPS_PIN any")
3598
3599     # Wait for iteration through all WPS APs to happen before enabling any
3600     # Registrar.
3601     for i in range(2):
3602         ev = dev[0].wait_event(["Associated with"], timeout=30)
3603         if ev is None:
3604             raise Exception("No association seen")
3605         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3606         if ev is None:
3607             raise Exception("No M2D from AP")
3608         dev[0].wait_disconnected()
3609
3610     # Verify that each AP requested PIN
3611     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3612     if ev is None:
3613         raise Exception("No WPS-PIN-NEEDED event from AP")
3614     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3615     if ev is None:
3616         raise Exception("No WPS-PIN-NEEDED event from AP2")
3617
3618     # Provide PIN to one of the APs and verify that connection gets formed
3619     hapd.request("WPS_PIN any " + pin)
3620     dev[0].wait_connected(timeout=30)
3621
3622 def test_ap_wps_iteration_error(dev, apdev):
3623     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3624     ssid = "test-wps-conf-pin"
3625     hapd = hostapd.add_ap(apdev[0],
3626                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3627                             "wpa_passphrase": "12345678", "wpa": "2",
3628                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3629                             "wps_independent": "1" })
3630     hapd.request("SET ext_eapol_frame_io 1")
3631     bssid = apdev[0]['bssid']
3632     pin = dev[0].wps_read_pin()
3633     dev[0].request("WPS_PIN any " + pin)
3634
3635     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3636     if ev is None:
3637         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3638     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3639
3640     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3641     if ev is None:
3642         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3643     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3644     if ev is None:
3645         raise Exception("No CTRL-EVENT-EAP-STARTED")
3646
3647     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3648     # a case with an incorrectly behaving WPS AP.
3649
3650     # Start the real target AP and activate registrar on it.
3651     hapd2 = hostapd.add_ap(apdev[1],
3652                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3653                             "wpa_passphrase": "12345678", "wpa": "2",
3654                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3655                             "wps_independent": "1" })
3656     hapd2.request("WPS_PIN any " + pin)
3657
3658     dev[0].wait_disconnected(timeout=15)
3659     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3660     if ev is None:
3661         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3662     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3663     if ev is None:
3664         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3665     dev[0].wait_connected(timeout=15)
3666
3667 @remote_compatible
3668 def test_ap_wps_priority(dev, apdev):
3669     """WPS PIN provisioning with configured AP and wps_priority"""
3670     ssid = "test-wps-conf-pin"
3671     hapd = hostapd.add_ap(apdev[0],
3672                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3673                             "wpa_passphrase": "12345678", "wpa": "2",
3674                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3675     logger.info("WPS provisioning step")
3676     pin = dev[0].wps_read_pin()
3677     hapd.request("WPS_PIN any " + pin)
3678     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3679     dev[0].dump_monitor()
3680     try:
3681         dev[0].request("SET wps_priority 6")
3682         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3683         dev[0].wait_connected(timeout=30)
3684         netw = dev[0].list_networks()
3685         prio = dev[0].get_network(netw[0]['id'], 'priority')
3686         if prio != '6':
3687             raise Exception("Unexpected network priority: " + prio)
3688     finally:
3689         dev[0].request("SET wps_priority 0")
3690
3691 @remote_compatible
3692 def test_ap_wps_and_non_wps(dev, apdev):
3693     """WPS and non-WPS AP in single hostapd process"""
3694     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3695     hapd = hostapd.add_ap(apdev[0], params)
3696
3697     params = { "ssid": "no wps" }
3698     hapd2 = hostapd.add_ap(apdev[1], params)
3699
3700     appin = hapd.request("WPS_AP_PIN random")
3701     if "FAIL" in appin:
3702         raise Exception("Could not generate random AP PIN")
3703     if appin not in hapd.request("WPS_AP_PIN get"):
3704         raise Exception("Could not fetch current AP PIN")
3705
3706     if "FAIL" in hapd.request("WPS_PBC"):
3707         raise Exception("WPS_PBC failed")
3708     if "FAIL" in hapd.request("WPS_CANCEL"):
3709         raise Exception("WPS_CANCEL failed")
3710
3711 def test_ap_wps_init_oom(dev, apdev):
3712     """Initial AP configuration and OOM during PSK generation"""
3713     ssid = "test-wps"
3714     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3715     hapd = hostapd.add_ap(apdev[0], params)
3716
3717     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3718         pin = dev[0].wps_read_pin()
3719         hapd.request("WPS_PIN any " + pin)
3720         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3721         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3722         dev[0].wait_disconnected()
3723
3724     hapd.request("WPS_PIN any " + pin)
3725     dev[0].wait_connected(timeout=30)
3726
3727 @remote_compatible
3728 def test_ap_wps_er_oom(dev, apdev):
3729     """WPS ER OOM in XML processing"""
3730     try:
3731         _test_ap_wps_er_oom(dev, apdev)
3732     finally:
3733         dev[0].request("WPS_ER_STOP")
3734         dev[1].request("WPS_CANCEL")
3735         dev[0].request("DISCONNECT")
3736
3737 def _test_ap_wps_er_oom(dev, apdev):
3738     ssid = "wps-er-ap-config"
3739     ap_pin = "12345670"
3740     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3741     hostapd.add_ap(apdev[0],
3742                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3743                      "wpa_passphrase": "12345678", "wpa": "2",
3744                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3745                      "device_name": "Wireless AP", "manufacturer": "Company",
3746                      "model_name": "WAP", "model_number": "123",
3747                      "serial_number": "12345", "device_type": "6-0050F204-1",
3748                      "os_version": "01020300",
3749                      "config_methods": "label push_button",
3750                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3751
3752     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3753
3754     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3755         dev[0].request("WPS_ER_START ifname=lo")
3756         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3757         if ev is not None:
3758             raise Exception("Unexpected AP discovery")
3759
3760     dev[0].request("WPS_ER_STOP")
3761     dev[0].request("WPS_ER_START ifname=lo")
3762     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3763     if ev is None:
3764         raise Exception("AP discovery timed out")
3765
3766     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3767     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3768         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3769         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3770         if ev is None:
3771             raise Exception("PBC scan failed")
3772         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3773         if ev is None:
3774             raise Exception("Enrollee discovery timed out")
3775
3776 @remote_compatible
3777 def test_ap_wps_er_init_oom(dev, apdev):
3778     """WPS ER and OOM during init"""
3779     try:
3780         _test_ap_wps_er_init_oom(dev, apdev)
3781     finally:
3782         dev[0].request("WPS_ER_STOP")
3783
3784 def _test_ap_wps_er_init_oom(dev, apdev):
3785     with alloc_fail(dev[0], 1, "wps_er_init"):
3786         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3787             raise Exception("WPS_ER_START succeeded during OOM")
3788     with alloc_fail(dev[0], 1, "http_server_init"):
3789         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3790             raise Exception("WPS_ER_START succeeded during OOM")
3791     with alloc_fail(dev[0], 2, "http_server_init"):
3792         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3793             raise Exception("WPS_ER_START succeeded during OOM")
3794     with alloc_fail(dev[0], 1, "eloop_sock_table_add_sock;?eloop_register_sock;wps_er_ssdp_init"):
3795         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3796             raise Exception("WPS_ER_START succeeded during OOM")
3797     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3798         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3799             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3800
3801 @remote_compatible
3802 def test_ap_wps_er_init_fail(dev, apdev):
3803     """WPS ER init failure"""
3804     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3805         dev[0].request("WPS_ER_STOP")
3806         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3807
3808 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3809     """WPS events and wpa_cli action script"""
3810     logdir = os.path.abspath(test_params['logdir'])
3811     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3812     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3813     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3814
3815     with open(actionfile, 'w') as f:
3816         f.write('#!/bin/sh\n')
3817         f.write('echo $* >> %s\n' % logfile)
3818         # Kill the process and wait some time before returning to allow all the
3819         # pending events to be processed with some of this happening after the
3820         # eloop SIGALRM signal has been scheduled.
3821         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3822
3823     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3824              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3825
3826     ssid = "test-wps-conf"
3827     hapd = hostapd.add_ap(apdev[0],
3828                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3829                             "wpa_passphrase": "12345678", "wpa": "2",
3830                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3831
3832     prg = os.path.join(test_params['logdir'],
3833                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3834     if not os.path.exists(prg):
3835         prg = '../../wpa_supplicant/wpa_cli'
3836     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3837     subprocess.call(arg)
3838
3839     arg = [ 'ps', 'ax' ]
3840     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3841     out = cmd.communicate()[0]
3842     cmd.wait()
3843     logger.debug("Processes:\n" + out)
3844     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3845         raise Exception("Did not see wpa_cli running")
3846
3847     hapd.request("WPS_PIN any 12345670")
3848     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3849     dev[0].dump_monitor()
3850     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3851     dev[0].wait_connected(timeout=30)
3852
3853     for i in range(30):
3854         if not os.path.exists(pidfile):
3855             break
3856         time.sleep(0.1)
3857
3858     if not os.path.exists(logfile):
3859         raise Exception("wpa_cli action results file not found")
3860     with open(logfile, 'r') as f:
3861         res = f.read()
3862     if "WPS-SUCCESS" not in res:
3863         raise Exception("WPS-SUCCESS event not seen in action file")
3864
3865     arg = [ 'ps', 'ax' ]
3866     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3867     out = cmd.communicate()[0]
3868     cmd.wait()
3869     logger.debug("Remaining processes:\n" + out)
3870     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3871         raise Exception("wpa_cli still running")
3872
3873     if os.path.exists(pidfile):
3874         raise Exception("PID file not removed")
3875
3876 def test_ap_wps_er_ssdp_proto(dev, apdev):
3877     """WPS ER SSDP protocol testing"""
3878     try:
3879         _test_ap_wps_er_ssdp_proto(dev, apdev)
3880     finally:
3881         dev[0].request("WPS_ER_STOP")
3882
3883 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3884     socket.setdefaulttimeout(1)
3885     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3886     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3887     sock.bind(("239.255.255.250", 1900))
3888     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3889         raise Exception("Invalid filter accepted")
3890     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3891         raise Exception("WPS_ER_START with filter failed")
3892     (msg,addr) = sock.recvfrom(1000)
3893     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3894     if "M-SEARCH" not in msg:
3895         raise Exception("Not an M-SEARCH")
3896     sock.sendto("FOO", addr)
3897     time.sleep(0.1)
3898     dev[0].request("WPS_ER_STOP")
3899
3900     dev[0].request("WPS_ER_START ifname=lo")
3901     (msg,addr) = sock.recvfrom(1000)
3902     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3903     if "M-SEARCH" not in msg:
3904         raise Exception("Not an M-SEARCH")
3905     sock.sendto("FOO", addr)
3906     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3907     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3908     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3909     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3910     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3911     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3912     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3913     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3914     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3915     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3916     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3917     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)
3918     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3919     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3920         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)
3921         time.sleep(0.1)
3922     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3923         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)
3924         time.sleep(0.1)
3925
3926     # Add an AP with bogus URL
3927     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)
3928     # Update timeout on AP without updating URL
3929     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)
3930     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3931     if ev is None:
3932         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3933
3934     # Add an AP with a valid URL (but no server listing to it)
3935     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)
3936     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3937     if ev is None:
3938         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3939
3940     sock.close()
3941
3942 wps_event_url = None
3943
3944 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3945                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3946     payload = '''<?xml version="1.0"?>
3947 <root xmlns="urn:schemas-upnp-org:device-1-0">
3948 <specVersion>
3949 <major>1</major>
3950 <minor>0</minor>
3951 </specVersion>
3952 <device>
3953 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3954 <friendlyName>WPS Access Point</friendlyName>
3955 <manufacturer>Company</manufacturer>
3956 <modelName>WAP</modelName>
3957 <modelNumber>123</modelNumber>
3958 <serialNumber>12345</serialNumber>
3959 '''
3960     if udn:
3961         payload += '<UDN>' + udn + '</UDN>'
3962     payload += '''<serviceList>
3963 <service>
3964 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3965 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3966 <SCPDURL>wps_scpd.xml</SCPDURL>
3967 '''
3968     if controlURL:
3969         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3970     if eventSubURL:
3971         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3972     payload += '''</service>
3973 </serviceList>
3974 </device>
3975 </root>
3976 '''
3977     hdr = 'HTTP/1.1 200 OK\r\n' + \
3978           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3979           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3980           'Connection: close\r\n' + \
3981           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3982           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3983     return hdr + payload
3984
3985 def gen_wps_control(payload_override=None):
3986     payload = '''<?xml version="1.0"?>
3987 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3988 <s:Body>
3989 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3990 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3991 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3992 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3993 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3994 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3995 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3996 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3997 AAYANyoAASA=
3998 </NewDeviceInfo>
3999 </u:GetDeviceInfoResponse>
4000 </s:Body>
4001 </s:Envelope>
4002 '''
4003     if payload_override:
4004         payload = payload_override
4005     hdr = 'HTTP/1.1 200 OK\r\n' + \
4006           'Content-Type: text/xml; charset="utf-8"\r\n' + \
4007           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4008           'Connection: close\r\n' + \
4009           'Content-Length: ' + str(len(payload)) + '\r\n' + \
4010           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4011     return hdr + payload
4012
4013 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
4014     payload = ""
4015     hdr = 'HTTP/1.1 200 OK\r\n' + \
4016           'Content-Type: text/xml; charset="utf-8"\r\n' + \
4017           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4018           'Connection: close\r\n' + \
4019           'Content-Length: ' + str(len(payload)) + '\r\n'
4020     if sid:
4021         hdr += 'SID: ' + sid + '\r\n'
4022     hdr += 'Timeout: Second-1801\r\n' + \
4023           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4024     return hdr + payload
4025
4026 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
4027     def handle(self):
4028         data = self.rfile.readline().strip()
4029         logger.info("HTTP server received: " + data)
4030         while True:
4031             hdr = self.rfile.readline().strip()
4032             if len(hdr) == 0:
4033                 break
4034             logger.info("HTTP header: " + hdr)
4035             if "CALLBACK:" in hdr:
4036                 global wps_event_url
4037                 wps_event_url = hdr.split(' ')[1].strip('<>')
4038
4039         if "GET /foo.xml" in data:
4040             self.handle_upnp_info()
4041         elif "POST /wps_control" in data:
4042             self.handle_wps_control()
4043         elif "SUBSCRIBE /wps_event" in data:
4044             self.handle_wps_event()
4045         else:
4046             self.handle_others(data)
4047
4048     def handle_upnp_info(self):
4049         self.wfile.write(gen_upnp_info())
4050
4051     def handle_wps_control(self):
4052         self.wfile.write(gen_wps_control())
4053
4054     def handle_wps_event(self):
4055         self.wfile.write(gen_wps_event())
4056
4057     def handle_others(self, data):
4058         logger.info("Ignore HTTP request: " + data)
4059
4060 class MyTCPServer(SocketServer.TCPServer):
4061     def __init__(self, addr, handler):
4062         self.allow_reuse_address = True
4063         SocketServer.TCPServer.__init__(self, addr, handler)
4064
4065 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
4066                  location_url=None):
4067     socket.setdefaulttimeout(1)
4068     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4069     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4070     sock.bind(("239.255.255.250", 1900))
4071     dev.request("WPS_ER_START ifname=lo")
4072     for i in range(100):
4073         (msg,addr) = sock.recvfrom(1000)
4074         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4075         if "M-SEARCH" in msg:
4076             break
4077         if not wait_m_search:
4078             raise Exception("Not an M-SEARCH")
4079         if i == 99:
4080             raise Exception("No M-SEARCH seen")
4081
4082     # Add an AP with a valid URL and server listing to it
4083     server = MyTCPServer(("127.0.0.1", 12345), http_server)
4084     if not location_url:
4085         location_url = 'http://127.0.0.1:12345/foo.xml'
4086     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)
4087     server.timeout = 1
4088     return server,sock
4089
4090 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
4091     sock.close()
4092     server.server_close()
4093
4094     if on_alloc_fail:
4095         done = False
4096         for i in range(50):
4097             res = dev.request("GET_ALLOC_FAIL")
4098             if res.startswith("0:"):
4099                 done = True
4100                 break
4101             time.sleep(0.1)
4102         if not done:
4103             raise Exception("No allocation failure reported")
4104     else:
4105         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
4106         if ev is None:
4107             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
4108     dev.request("WPS_ER_STOP")
4109
4110 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
4111     try:
4112         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4113         server,sock = wps_er_start(dev, handler, location_url=location_url)
4114         global wps_event_url
4115         wps_event_url = None
4116         server.handle_request()
4117         server.handle_request()
4118         server.handle_request()
4119         server.server_close()
4120         if no_event_url:
4121             if wps_event_url:
4122                 raise Exception("Received event URL unexpectedly")
4123             return
4124         if wps_event_url is None:
4125             raise Exception("Did not get event URL")
4126         logger.info("Event URL: " + wps_event_url)
4127     finally:
4128             dev.request("WPS_ER_STOP")
4129
4130 def send_wlanevent(url, uuid, data, no_response=False):
4131     conn = httplib.HTTPConnection(url.netloc)
4132     payload = '''<?xml version="1.0" encoding="utf-8"?>
4133 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4134 <e:property><STAStatus>1</STAStatus></e:property>
4135 <e:property><APStatus>1</APStatus></e:property>
4136 <e:property><WLANEvent>'''
4137     payload += base64.b64encode(data)
4138     payload += '</WLANEvent></e:property></e:propertyset>'
4139     headers = { "Content-type": 'text/xml; charset="utf-8"',
4140                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4141                 "HOST": url.netloc,
4142                 "NT": "upnp:event",
4143                 "SID": "uuid:" + uuid,
4144                 "SEQ": "0",
4145                 "Content-Length": str(len(payload)) }
4146     conn.request("NOTIFY", url.path, payload, headers)
4147     if no_response:
4148         try:
4149             conn.getresponse()
4150         except Exception, e:
4151             pass
4152         return
4153     resp = conn.getresponse()
4154     if resp.status != 200:
4155         raise Exception("Unexpected HTTP response: %d" % resp.status)
4156
4157 def test_ap_wps_er_http_proto(dev, apdev):
4158     """WPS ER HTTP protocol testing"""
4159     try:
4160         _test_ap_wps_er_http_proto(dev, apdev)
4161     finally:
4162         dev[0].request("WPS_ER_STOP")
4163
4164 def _test_ap_wps_er_http_proto(dev, apdev):
4165     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4166     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
4167     global wps_event_url
4168     wps_event_url = None
4169     server.handle_request()
4170     server.handle_request()
4171     server.handle_request()
4172     server.server_close()
4173     if wps_event_url is None:
4174         raise Exception("Did not get event URL")
4175     logger.info("Event URL: " + wps_event_url)
4176
4177     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
4178     if ev is None:
4179         raise Exception("No WPS-ER-AP-ADD event")
4180     if uuid not in ev:
4181         raise Exception("UUID mismatch")
4182
4183     sock.close()
4184
4185     logger.info("Valid Probe Request notification")
4186     url = urlparse.urlparse(wps_event_url)
4187     conn = httplib.HTTPConnection(url.netloc)
4188     payload = '''<?xml version="1.0" encoding="utf-8"?>
4189 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4190 <e:property><STAStatus>1</STAStatus></e:property>
4191 <e:property><APStatus>1</APStatus></e:property>
4192 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
4193 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
4194 RGV2aWNlIEEQSQAGADcqAAEg
4195 </WLANEvent></e:property>
4196 </e:propertyset>
4197 '''
4198     headers = { "Content-type": 'text/xml; charset="utf-8"',
4199                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4200                 "HOST": url.netloc,
4201                 "NT": "upnp:event",
4202                 "SID": "uuid:" + uuid,
4203                 "SEQ": "0",
4204                 "Content-Length": str(len(payload)) }
4205     conn.request("NOTIFY", url.path, payload, headers)
4206     resp = conn.getresponse()
4207     if resp.status != 200:
4208         raise Exception("Unexpected HTTP response: %d" % resp.status)
4209
4210     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
4211     if ev is None:
4212         raise Exception("No WPS-ER-ENROLLEE-ADD event")
4213     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
4214         raise Exception("No Enrollee UUID match")
4215
4216     logger.info("Incorrect event URL AP id")
4217     conn = httplib.HTTPConnection(url.netloc)
4218     conn.request("NOTIFY", url.path + '123', payload, headers)
4219     resp = conn.getresponse()
4220     if resp.status != 404:
4221         raise Exception("Unexpected HTTP response: %d" % resp.status)
4222
4223     logger.info("Missing AP id")
4224     conn = httplib.HTTPConnection(url.netloc)
4225     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4226                  payload, headers)
4227     time.sleep(0.1)
4228
4229     logger.info("Incorrect event URL event id")
4230     conn = httplib.HTTPConnection(url.netloc)
4231     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4232     time.sleep(0.1)
4233
4234     logger.info("Incorrect event URL prefix")
4235     conn = httplib.HTTPConnection(url.netloc)
4236     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4237     resp = conn.getresponse()
4238     if resp.status != 404:
4239         raise Exception("Unexpected HTTP response: %d" % resp.status)
4240
4241     logger.info("Unsupported request")
4242     conn = httplib.HTTPConnection(url.netloc)
4243     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4244     resp = conn.getresponse()
4245     if resp.status != 501:
4246         raise Exception("Unexpected HTTP response: %d" % resp.status)
4247
4248     logger.info("Unsupported request and OOM")
4249     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4250         conn = httplib.HTTPConnection(url.netloc)
4251         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4252         time.sleep(0.5)
4253
4254     logger.info("Too short WLANEvent")
4255     data = '\x00'
4256     send_wlanevent(url, uuid, data)
4257
4258     logger.info("Invalid WLANEventMAC")
4259     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4260     send_wlanevent(url, uuid, data)
4261
4262     logger.info("Unknown WLANEventType")
4263     data = '\xff02:00:00:00:00:00'
4264     send_wlanevent(url, uuid, data)
4265
4266     logger.info("Probe Request notification without any attributes")
4267     data = '\x0102:00:00:00:00:00'
4268     send_wlanevent(url, uuid, data)
4269
4270     logger.info("Probe Request notification with invalid attribute")
4271     data = '\x0102:00:00:00:00:00\xff'
4272     send_wlanevent(url, uuid, data)
4273
4274     logger.info("EAP message without any attributes")
4275     data = '\x0202:00:00:00:00:00'
4276     send_wlanevent(url, uuid, data)
4277
4278     logger.info("EAP message with invalid attribute")
4279     data = '\x0202:00:00:00:00:00\xff'
4280     send_wlanevent(url, uuid, data)
4281
4282     logger.info("EAP message from new STA and not M1")
4283     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4284     send_wlanevent(url, uuid, data)
4285
4286     logger.info("EAP message: M1")
4287     data = '\x0202:00:00:00:00:00'
4288     data += '\x10\x22\x00\x01\x04'
4289     data += '\x10\x47\x00\x10' + 16*'\x00'
4290     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4291     data += '\x10\x1a\x00\x10' + 16*'\x00'
4292     data += '\x10\x32\x00\xc0' + 192*'\x00'
4293     data += '\x10\x04\x00\x02\x00\x00'
4294     data += '\x10\x10\x00\x02\x00\x00'
4295     data += '\x10\x0d\x00\x01\x00'
4296     data += '\x10\x08\x00\x02\x00\x00'
4297     data += '\x10\x44\x00\x01\x00'
4298     data += '\x10\x21\x00\x00'
4299     data += '\x10\x23\x00\x00'
4300     data += '\x10\x24\x00\x00'
4301     data += '\x10\x42\x00\x00'
4302     data += '\x10\x54\x00\x08' + 8*'\x00'
4303     data += '\x10\x11\x00\x00'
4304     data += '\x10\x3c\x00\x01\x00'
4305     data += '\x10\x02\x00\x02\x00\x00'
4306     data += '\x10\x12\x00\x02\x00\x00'
4307     data += '\x10\x09\x00\x02\x00\x00'
4308     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4309     m1 = data
4310     send_wlanevent(url, uuid, data)
4311
4312     logger.info("EAP message: WSC_ACK")
4313     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4314     send_wlanevent(url, uuid, data)
4315
4316     logger.info("EAP message: M1")
4317     send_wlanevent(url, uuid, m1)
4318
4319     logger.info("EAP message: WSC_NACK")
4320     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4321     send_wlanevent(url, uuid, data)
4322
4323     logger.info("EAP message: M1 - Too long attribute values")
4324     data = '\x0202:00:00:00:00:00'
4325     data += '\x10\x11\x00\x21' + 33*'\x00'
4326     data += '\x10\x45\x00\x21' + 33*'\x00'
4327     data += '\x10\x42\x00\x21' + 33*'\x00'
4328     data += '\x10\x24\x00\x21' + 33*'\x00'
4329     data += '\x10\x23\x00\x21' + 33*'\x00'
4330     data += '\x10\x21\x00\x41' + 65*'\x00'
4331     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4332     send_wlanevent(url, uuid, data)
4333
4334     logger.info("EAP message: M1 missing UUID-E")
4335     data = '\x0202:00:00:00:00:00'
4336     data += '\x10\x22\x00\x01\x04'
4337     send_wlanevent(url, uuid, data)
4338
4339     logger.info("EAP message: M1 missing MAC Address")
4340     data += '\x10\x47\x00\x10' + 16*'\x00'
4341     send_wlanevent(url, uuid, data)
4342
4343     logger.info("EAP message: M1 missing Enrollee Nonce")
4344     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4345     send_wlanevent(url, uuid, data)
4346
4347     logger.info("EAP message: M1 missing Public Key")
4348     data += '\x10\x1a\x00\x10' + 16*'\x00'
4349     send_wlanevent(url, uuid, data)
4350
4351     logger.info("EAP message: M1 missing Authentication Type flags")
4352     data += '\x10\x32\x00\xc0' + 192*'\x00'
4353     send_wlanevent(url, uuid, data)
4354
4355     logger.info("EAP message: M1 missing Encryption Type Flags")
4356     data += '\x10\x04\x00\x02\x00\x00'
4357     send_wlanevent(url, uuid, data)
4358
4359     logger.info("EAP message: M1 missing Connection Type flags")
4360     data += '\x10\x10\x00\x02\x00\x00'
4361     send_wlanevent(url, uuid, data)
4362
4363     logger.info("EAP message: M1 missing Config Methods")
4364     data += '\x10\x0d\x00\x01\x00'
4365     send_wlanevent(url, uuid, data)
4366
4367     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4368     data += '\x10\x08\x00\x02\x00\x00'
4369     send_wlanevent(url, uuid, data)
4370
4371     logger.info("EAP message: M1 missing Manufacturer")
4372     data += '\x10\x44\x00\x01\x00'
4373     send_wlanevent(url, uuid, data)
4374
4375     logger.info("EAP message: M1 missing Model Name")
4376     data += '\x10\x21\x00\x00'
4377     send_wlanevent(url, uuid, data)
4378
4379     logger.info("EAP message: M1 missing Model Number")
4380     data += '\x10\x23\x00\x00'
4381     send_wlanevent(url, uuid, data)
4382
4383     logger.info("EAP message: M1 missing Serial Number")
4384     data += '\x10\x24\x00\x00'
4385     send_wlanevent(url, uuid, data)
4386
4387     logger.info("EAP message: M1 missing Primary Device Type")
4388     data += '\x10\x42\x00\x00'
4389     send_wlanevent(url, uuid, data)
4390
4391     logger.info("EAP message: M1 missing Device Name")
4392     data += '\x10\x54\x00\x08' + 8*'\x00'
4393     send_wlanevent(url, uuid, data)
4394
4395     logger.info("EAP message: M1 missing RF Bands")
4396     data += '\x10\x11\x00\x00'
4397     send_wlanevent(url, uuid, data)
4398
4399     logger.info("EAP message: M1 missing Association State")
4400     data += '\x10\x3c\x00\x01\x00'
4401     send_wlanevent(url, uuid, data)
4402
4403     logger.info("EAP message: M1 missing Device Password ID")
4404     data += '\x10\x02\x00\x02\x00\x00'
4405     send_wlanevent(url, uuid, data)
4406
4407     logger.info("EAP message: M1 missing Configuration Error")
4408     data += '\x10\x12\x00\x02\x00\x00'
4409     send_wlanevent(url, uuid, data)
4410
4411     logger.info("EAP message: M1 missing OS Version")
4412     data += '\x10\x09\x00\x02\x00\x00'
4413     send_wlanevent(url, uuid, data)
4414
4415     logger.info("Check max concurrent requests")
4416     addr = (url.hostname, url.port)
4417     socks = {}
4418     for i in range(20):
4419         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4420                                  socket.IPPROTO_TCP)
4421         socks[i].settimeout(10)
4422         socks[i].connect(addr)
4423     for i in range(20):
4424         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4425     count = 0
4426     for i in range(20):
4427         try:
4428             res = socks[i].recv(100)
4429             if "HTTP/1" in res:
4430                 count += 1
4431         except:
4432             pass
4433         socks[i].close()
4434     logger.info("%d concurrent HTTP GET operations returned response" % count)
4435     if count < 10:
4436         raise Exception("Too few concurrent HTTP connections accepted")
4437
4438     logger.info("OOM in HTTP server")
4439     for func in [ "http_request_init", "httpread_create",
4440                   "eloop_register_timeout;httpread_create",
4441                   "eloop_sock_table_add_sock;?eloop_register_sock;httpread_create",
4442                   "httpread_hdr_analyze" ]:
4443         with alloc_fail(dev[0], 1, func):
4444             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4445                                  socket.IPPROTO_TCP)
4446             sock.connect(addr)
4447             sock.send("GET / HTTP/1.1\r\n\r\n")
4448             try:
4449                 sock.recv(100)
4450             except:
4451                 pass
4452             sock.close()
4453
4454     logger.info("Invalid HTTP header")
4455     for req in [ " GET / HTTP/1.1\r\n\r\n",
4456                  "HTTP/1.1 200 OK\r\n\r\n",
4457                  "HTTP/\r\n\r\n",
4458                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4459                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4460                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4461                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4462                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4463                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4464                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4465                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4466         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4467                              socket.IPPROTO_TCP)
4468         sock.settimeout(0.1)
4469         sock.connect(addr)
4470         sock.send(req)
4471         try:
4472             sock.recv(100)
4473         except:
4474             pass
4475         sock.close()
4476
4477     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4478         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4479                              socket.IPPROTO_TCP)
4480         sock.connect(addr)
4481         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4482         try:
4483             sock.recv(100)
4484         except:
4485             pass
4486         sock.close()
4487
4488     conn = httplib.HTTPConnection(url.netloc)
4489     payload = '<foo'
4490     headers = { "Content-type": 'text/xml; charset="utf-8"',
4491                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4492                 "HOST": url.netloc,
4493                 "NT": "upnp:event",
4494                 "SID": "uuid:" + uuid,
4495                 "SEQ": "0",
4496                 "Content-Length": str(len(payload)) }
4497     conn.request("NOTIFY", url.path, payload, headers)
4498     resp = conn.getresponse()
4499     if resp.status != 200:
4500         raise Exception("Unexpected HTTP response: %d" % resp.status)
4501
4502     conn = httplib.HTTPConnection(url.netloc)
4503     payload = '<WLANEvent foo></WLANEvent>'
4504     headers = { "Content-type": 'text/xml; charset="utf-8"',
4505                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4506                 "HOST": url.netloc,
4507                 "NT": "upnp:event",
4508                 "SID": "uuid:" + uuid,
4509                 "SEQ": "0",
4510                 "Content-Length": str(len(payload)) }
4511     conn.request("NOTIFY", url.path, payload, headers)
4512     resp = conn.getresponse()
4513     if resp.status != 200:
4514         raise Exception("Unexpected HTTP response: %d" % resp.status)
4515
4516     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4517         send_wlanevent(url, uuid, '')
4518
4519     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4520         send_wlanevent(url, uuid, 'foo')
4521
4522     for func in [ "wps_init",
4523                   "wps_process_manufacturer",
4524                   "wps_process_model_name",
4525                   "wps_process_model_number",
4526                   "wps_process_serial_number",
4527                   "wps_process_dev_name" ]:
4528         with alloc_fail(dev[0], 1, func):
4529             send_wlanevent(url, uuid, m1)
4530
4531     with alloc_fail(dev[0], 1, "wps_er_http_resp_ok"):
4532         send_wlanevent(url, uuid, m1, no_response=True)
4533
4534     with alloc_fail(dev[0], 1, "wps_er_http_resp_not_found"):
4535         url2 = urlparse.urlparse(wps_event_url.replace('/event/', '/notfound/'))
4536         send_wlanevent(url2, uuid, m1, no_response=True)
4537
4538     logger.info("EAP message: M1")
4539     data = '\x0202:11:22:00:00:00'
4540     data += '\x10\x22\x00\x01\x04'
4541     data += '\x10\x47\x00\x10' + 16*'\x00'
4542     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4543     data += '\x10\x1a\x00\x10' + 16*'\x00'
4544     data += '\x10\x32\x00\xc0' + 192*'\x00'
4545     data += '\x10\x04\x00\x02\x00\x00'
4546     data += '\x10\x10\x00\x02\x00\x00'
4547     data += '\x10\x0d\x00\x01\x00'
4548     data += '\x10\x08\x00\x02\x00\x00'
4549     data += '\x10\x44\x00\x01\x00'
4550     data += '\x10\x21\x00\x00'
4551     data += '\x10\x23\x00\x00'
4552     data += '\x10\x24\x00\x00'
4553     data += '\x10\x42\x00\x00'
4554     data += '\x10\x54\x00\x08' + 8*'\x00'
4555     data += '\x10\x11\x00\x00'
4556     data += '\x10\x3c\x00\x01\x00'
4557     data += '\x10\x02\x00\x02\x00\x00'
4558     data += '\x10\x12\x00\x02\x00\x00'
4559     data += '\x10\x09\x00\x02\x00\x00'
4560     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4561     dev[0].dump_monitor()
4562     with alloc_fail(dev[0], 1, "wps_er_add_sta_data"):
4563         send_wlanevent(url, uuid, data)
4564         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=0.1)
4565         if ev is not None:
4566             raise Exception("Unexpected enrollee add event")
4567     send_wlanevent(url, uuid, data)
4568     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=2)
4569     if ev is None:
4570         raise Exception("Enrollee add event not seen")
4571
4572     with alloc_fail(dev[0], 1, "base64_encode;wps_er_soap_hdr"):
4573         send_wlanevent(url, uuid, data)
4574
4575     with alloc_fail(dev[0], 1, "wpabuf_alloc;wps_er_soap_hdr"):
4576         send_wlanevent(url, uuid, data)
4577
4578     with alloc_fail(dev[0], 1, "http_client_url_parse;wps_er_sta_send_msg"):
4579         send_wlanevent(url, uuid, data)
4580
4581     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_sta_send_msg"):
4582         send_wlanevent(url, uuid, data)
4583
4584 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4585     """WPS ER HTTP protocol testing - no eventSubURL"""
4586     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4587         def handle_upnp_info(self):
4588             self.wfile.write(gen_upnp_info(eventSubURL=None))
4589     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4590                           no_event_url=True)
4591
4592 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4593     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4594     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4595         def handle_upnp_info(self):
4596             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4597     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4598                           no_event_url=True)
4599
4600 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4601     """WPS ER HTTP protocol testing - subscribe OOM"""
4602     try:
4603         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4604     finally:
4605         dev[0].request("WPS_ER_STOP")
4606
4607 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4608     tests = [ (1, "http_client_url_parse"),
4609               (1, "wpabuf_alloc;wps_er_subscribe"),
4610               (1, "http_client_addr"),
4611               (1, "eloop_sock_table_add_sock;?eloop_register_sock;http_client_addr"),
4612               (1, "eloop_register_timeout;http_client_addr") ]
4613     for count,func in tests:
4614         with alloc_fail(dev[0], count, func):
4615             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4616             server.handle_request()
4617             server.handle_request()
4618             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4619
4620 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4621     """WPS ER HTTP protocol testing - no SID"""
4622     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4623         def handle_wps_event(self):
4624             self.wfile.write(gen_wps_event(sid=None))
4625     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4626
4627 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4628     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4629     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4630         def handle_wps_event(self):
4631             self.wfile.write(gen_wps_event(sid='FOO'))
4632     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4633
4634 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4635     """WPS ER HTTP protocol testing - invalid SID UUID"""
4636     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4637         def handle_wps_event(self):
4638             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4639     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4640
4641 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4642     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4643     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4644         def handle_wps_event(self):
4645             payload = ""
4646             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4647                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4648                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4649                   'Connection: close\r\n' + \
4650                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4651                   'Timeout: Second-1801\r\n' + \
4652                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4653             self.wfile.write(hdr + payload)
4654     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4655
4656 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4657     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4658     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4659         def handle_wps_event(self):
4660             payload = ""
4661             hdr = 'HTTP/1.1 FOO\r\n' + \
4662                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4663                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4664                   'Connection: close\r\n' + \
4665                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4666                   'Timeout: Second-1801\r\n' + \
4667                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4668             self.wfile.write(hdr + payload)
4669     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4670
4671 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4672     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4673     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4674         def handle_wps_control(self):
4675             payload = '''<?xml version="1.0"?>
4676 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4677 <s:Body>
4678 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4679 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4680 </u:GetDeviceInfoResponse>
4681 </s:Body>
4682 </s:Envelope>
4683 '''
4684             self.wfile.write(gen_wps_control(payload_override=payload))
4685     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4686
4687 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4688     """WPS ER HTTP protocol testing - No device in UPnP info"""
4689     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4690         def handle_upnp_info(self):
4691             payload = '''<?xml version="1.0"?>
4692 <root xmlns="urn:schemas-upnp-org:device-1-0">
4693 <specVersion>
4694 <major>1</major>
4695 <minor>0</minor>
4696 </specVersion>
4697 </root>
4698 '''
4699             hdr = 'HTTP/1.1 200 OK\r\n' + \
4700                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4701                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4702                   'Connection: close\r\n' + \
4703                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4704                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4705             self.wfile.write(hdr + payload)
4706     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4707
4708 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4709     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4710     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4711         def handle_upnp_info(self):
4712             payload = '''<?xml version="1.0"?>
4713 <root xmlns="urn:schemas-upnp-org:device-1-0">
4714 <specVersion>
4715 <major>1</major>
4716 <minor>0</minor>
4717 </specVersion>
4718 <device>
4719 </device>
4720 </root>
4721 '''
4722             hdr = 'HTTP/1.1 200 OK\r\n' + \
4723                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4724                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4725                   'Connection: close\r\n' + \
4726                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4727                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4728             self.wfile.write(hdr + payload)
4729     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4730
4731 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4732     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4733     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4734         def handle_upnp_info(self):
4735             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4736     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4737
4738 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4739     """WPS ER HTTP protocol testing - no controlURL"""
4740     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4741         def handle_upnp_info(self):
4742             self.wfile.write(gen_upnp_info(controlURL=None))
4743     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4744                           no_event_url=True)
4745
4746 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4747     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4748     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4749         def handle_upnp_info(self):
4750             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4751     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4752                           no_event_url=True)
4753
4754 def test_ap_wps_http_timeout(dev, apdev):
4755     """WPS AP/ER and HTTP timeout"""
4756     try:
4757         _test_ap_wps_http_timeout(dev, apdev)
4758     finally:
4759         dev[0].request("WPS_ER_STOP")
4760
4761 def _test_ap_wps_http_timeout(dev, apdev):
4762     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4763     add_ssdp_ap(apdev[0], ap_uuid)
4764
4765     location = ssdp_get_location(ap_uuid)
4766     url = urlparse.urlparse(location)
4767     addr = (url.hostname, url.port)
4768     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4769     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4770                          socket.IPPROTO_TCP)
4771     sock.connect(addr)
4772     sock.send("G")
4773
4774     class DummyServer(SocketServer.StreamRequestHandler):
4775         def handle(self):
4776             logger.debug("DummyServer - start 31 sec wait")
4777             time.sleep(31)
4778             logger.debug("DummyServer - wait done")
4779
4780     logger.debug("Start WPS ER")
4781     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4782                                 wait_m_search=True)
4783
4784     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4785     # This will wait for 31 seconds..
4786     server.handle_request()
4787
4788     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4789     try:
4790         sock.send("ET / HTTP/1.1\r\n\r\n")
4791         res = sock.recv(100)
4792         sock.close()
4793     except:
4794         pass
4795
4796 def test_ap_wps_er_url_parse(dev, apdev):
4797     """WPS ER and URL parsing special cases"""
4798     try:
4799         _test_ap_wps_er_url_parse(dev, apdev)
4800     finally:
4801         dev[0].request("WPS_ER_STOP")
4802
4803 def _test_ap_wps_er_url_parse(dev, apdev):
4804     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4805     sock.settimeout(1)
4806     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4807     sock.bind(("239.255.255.250", 1900))
4808     dev[0].request("WPS_ER_START ifname=lo")
4809     (msg,addr) = sock.recvfrom(1000)
4810     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4811     if "M-SEARCH" not in msg:
4812         raise Exception("Not an M-SEARCH")
4813     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)
4814     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4815     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)
4816     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4817     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)
4818     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4819
4820     sock.close()
4821
4822 def test_ap_wps_er_link_update(dev, apdev):
4823     """WPS ER and link update special cases"""
4824     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4825         def handle_upnp_info(self):
4826             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4827     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4828
4829     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4830         def handle_others(self, data):
4831             if "GET / " in data:
4832                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4833     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4834                           location_url='http://127.0.0.1:12345')
4835
4836 def test_ap_wps_er_http_client(dev, apdev):
4837     """WPS ER and HTTP client special cases"""
4838     with alloc_fail(dev[0], 1, "http_link_update"):
4839         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4840
4841     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4842         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4843
4844     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4845         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4846
4847     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4848         def handle_upnp_info(self):
4849             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4850     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4851                           no_event_url=True)
4852
4853 def test_ap_wps_init_oom(dev, apdev):
4854     """wps_init OOM cases"""
4855     ssid = "test-wps"
4856     appin = "12345670"
4857     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4858                "ap_pin": appin }
4859     hapd = hostapd.add_ap(apdev[0], params)
4860     pin = dev[0].wps_read_pin()
4861
4862     with alloc_fail(hapd, 1, "wps_init"):
4863         hapd.request("WPS_PIN any " + pin)
4864         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4865         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4866         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4867         if ev is None:
4868             raise Exception("No EAP failure reported")
4869         dev[0].request("WPS_CANCEL")
4870
4871     with alloc_fail(dev[0], 2, "wps_init"):
4872         hapd.request("WPS_PIN any " + pin)
4873         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4874         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4875         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4876         if ev is None:
4877             raise Exception("No EAP failure reported")
4878         dev[0].request("WPS_CANCEL")
4879
4880     with alloc_fail(dev[0], 2, "wps_init"):
4881         hapd.request("WPS_PBC")
4882         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4883         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4884         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4885         if ev is None:
4886             raise Exception("No EAP failure reported")
4887         dev[0].request("WPS_CANCEL")
4888
4889     dev[0].dump_monitor()
4890     new_ssid = "wps-new-ssid"
4891     new_passphrase = "1234567890"
4892     with alloc_fail(dev[0], 3, "wps_init"):
4893         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4894                        new_passphrase, no_wait=True)
4895         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4896         if ev is None:
4897             raise Exception("No EAP failure reported")
4898
4899     dev[0].flush_scan_cache()
4900
4901 @remote_compatible
4902 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4903     """WPS and invalid IE in Association Request frame"""
4904     ssid = "test-wps"
4905     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4906     hapd = hostapd.add_ap(apdev[0], params)
4907     pin = "12345670"
4908     hapd.request("WPS_PIN any " + pin)
4909     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4910     try:
4911         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4912         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4913         for i in range(5):
4914             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4915             if ev and "vendor=14122" in ev:
4916                 break
4917         if ev is None or "vendor=14122" not in ev:
4918             raise Exception("EAP-WSC not started")
4919         dev[0].request("WPS_CANCEL")
4920     finally:
4921         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4922
4923 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4924     """WPS PBC/PIN mismatch"""
4925     ssid = "test-wps"
4926     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4927     hapd = hostapd.add_ap(apdev[0], params)
4928     hapd.request("SET wps_version_number 0x10")
4929     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4930     hapd.request("WPS_PBC")
4931     pin = dev[0].wps_read_pin()
4932     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4933     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4934     if ev is None:
4935         raise Exception("Scan did not complete")
4936     dev[0].request("WPS_CANCEL")
4937
4938     hapd.request("WPS_CANCEL")
4939     dev[0].flush_scan_cache()
4940
4941 @remote_compatible
4942 def test_ap_wps_ie_invalid(dev, apdev):
4943     """WPS PIN attempt with AP that has invalid WSC IE"""
4944     ssid = "test-wps"
4945     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4946                "vendor_elements": "dd050050f20410" }
4947     hapd = hostapd.add_ap(apdev[0], params)
4948     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4949     hostapd.add_ap(apdev[1], params)
4950     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4951     pin = dev[0].wps_read_pin()
4952     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4953     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4954     if ev is None:
4955         raise Exception("Scan did not complete")
4956     dev[0].request("WPS_CANCEL")
4957
4958 @remote_compatible
4959 def test_ap_wps_scan_prio_order(dev, apdev):
4960     """WPS scan priority ordering"""
4961     ssid = "test-wps"
4962     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4963     hapd = hostapd.add_ap(apdev[0], params)
4964     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4965     hostapd.add_ap(apdev[1], params)
4966     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4967     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4968     pin = dev[0].wps_read_pin()
4969     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4970     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4971     if ev is None:
4972         raise Exception("Scan did not complete")
4973     dev[0].request("WPS_CANCEL")
4974
4975 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4976     """WPS ProbeReq IE OOM"""
4977     ssid = "test-wps"
4978     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4979     hapd = hostapd.add_ap(apdev[0], params)
4980     pin = dev[0].wps_read_pin()
4981     hapd.request("WPS_PIN any " + pin)
4982     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4983     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4984         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4985         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4986         if ev is None:
4987             raise Exception("Association not seen")
4988     dev[0].request("WPS_CANCEL")
4989     dev[0].wait_disconnected()
4990
4991     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4992         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4993         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4994         if ev is None:
4995             raise Exception("Association not seen")
4996     dev[0].request("WPS_CANCEL")
4997     hapd.disable()
4998     dev[0].request("REMOVE_NETWORK all")
4999     dev[0].wait_disconnected()
5000     time.sleep(0.2)
5001     dev[0].flush_scan_cache()
5002
5003 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
5004     """WPS AssocReq IE OOM"""
5005     ssid = "test-wps"
5006     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
5007     hapd = hostapd.add_ap(apdev[0], params)
5008     pin = dev[0].wps_read_pin()
5009     hapd.request("WPS_PIN any " + pin)
5010     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5011     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
5012         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
5013         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
5014         if ev is None:
5015             raise Exception("Association not seen")
5016     dev[0].request("WPS_CANCEL")
5017
5018 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
5019     """WPS AssocResp IE OOM"""
5020     ssid = "test-wps"
5021     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
5022     hapd = hostapd.add_ap(apdev[0], params)
5023     pin = dev[0].wps_read_pin()
5024     hapd.request("WPS_PIN any " + pin)
5025     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5026     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
5027         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
5028         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
5029         if ev is None:
5030             raise Exception("Association not seen")
5031     dev[0].request("WPS_CANCEL")
5032
5033 @remote_compatible
5034 def test_ap_wps_bss_info_errors(dev, apdev):
5035     """WPS BSS info errors"""
5036     params = { "ssid": "1",
5037                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
5038     hostapd.add_ap(apdev[0], params)
5039     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
5040     hostapd.add_ap(apdev[1], params)
5041     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5042     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
5043     bss = dev[0].get_bss(apdev[0]['bssid'])
5044     logger.info("BSS: " + str(bss))
5045     if "wps_state" in bss:
5046         raise Exception("Unexpected wps_state in BSS info")
5047     if 'wps_device_name' not in bss:
5048         raise Exception("No wps_device_name in BSS info")
5049     if bss['wps_device_name'] != '_':
5050         raise Exception("Unexpected wps_device_name value")
5051     bss = dev[0].get_bss(apdev[1]['bssid'])
5052     logger.info("BSS: " + str(bss))
5053
5054     with alloc_fail(dev[0], 1, "=wps_attr_text"):
5055         bss = dev[0].get_bss(apdev[0]['bssid'])
5056         logger.info("BSS(OOM): " + str(bss))
5057
5058 def wps_run_pbc_fail_ap(apdev, dev, hapd):
5059     hapd.request("WPS_PBC")
5060     dev.scan_for_bss(apdev['bssid'], freq="2412")
5061     dev.request("WPS_PBC " + apdev['bssid'])
5062     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5063     if ev is None:
5064         raise Exception("No EAP failure reported")
5065     dev.request("WPS_CANCEL")
5066     dev.wait_disconnected()
5067     for i in range(5):
5068         try:
5069             dev.flush_scan_cache()
5070             break
5071         except Exception, e:
5072             if str(e).startswith("Failed to trigger scan"):
5073                 # Try again
5074                 time.sleep(1)
5075             else:
5076                 raise
5077
5078 def wps_run_pbc_fail(apdev, dev):
5079     hapd = wps_start_ap(apdev)
5080     wps_run_pbc_fail_ap(apdev, dev, hapd)
5081
5082 @remote_compatible
5083 def test_ap_wps_pk_oom(dev, apdev):
5084     """WPS and public key OOM"""
5085     with alloc_fail(dev[0], 1, "wps_build_public_key"):
5086         wps_run_pbc_fail(apdev[0], dev[0])
5087
5088 @remote_compatible
5089 def test_ap_wps_pk_oom_ap(dev, apdev):
5090     """WPS and public key OOM on AP"""
5091     hapd = wps_start_ap(apdev[0])
5092     with alloc_fail(hapd, 1, "wps_build_public_key"):
5093         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5094
5095 @remote_compatible
5096 def test_ap_wps_encr_oom_ap(dev, apdev):
5097     """WPS and encrypted settings decryption OOM on AP"""
5098     hapd = wps_start_ap(apdev[0])
5099     pin = dev[0].wps_read_pin()
5100     hapd.request("WPS_PIN any " + pin)
5101     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5102     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
5103         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
5104         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
5105         if ev is None:
5106             raise Exception("No WPS-FAIL reported")
5107         dev[0].request("WPS_CANCEL")
5108     dev[0].wait_disconnected()
5109
5110 @remote_compatible
5111 def test_ap_wps_encr_no_random_ap(dev, apdev):
5112     """WPS and no random data available for encryption on AP"""
5113     hapd = wps_start_ap(apdev[0])
5114     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
5115         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5116
5117 @remote_compatible
5118 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
5119     """WPS and no random data available for e-hash on STA"""
5120     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
5121         wps_run_pbc_fail(apdev[0], dev[0])
5122
5123 @remote_compatible
5124 def test_ap_wps_m1_no_random(dev, apdev):
5125     """WPS and no random for M1 on STA"""
5126     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
5127         wps_run_pbc_fail(apdev[0], dev[0])
5128
5129 @remote_compatible
5130 def test_ap_wps_m1_oom(dev, apdev):
5131     """WPS and OOM for M1 on STA"""
5132     with alloc_fail(dev[0], 1, "wps_build_m1"):
5133         wps_run_pbc_fail(apdev[0], dev[0])
5134
5135 @remote_compatible
5136 def test_ap_wps_m3_oom(dev, apdev):
5137     """WPS and OOM for M3 on STA"""
5138     with alloc_fail(dev[0], 1, "wps_build_m3"):
5139         wps_run_pbc_fail(apdev[0], dev[0])
5140
5141 @remote_compatible
5142 def test_ap_wps_m5_oom(dev, apdev):
5143     """WPS and OOM for M5 on STA"""
5144     hapd = wps_start_ap(apdev[0])
5145     hapd.request("WPS_PBC")
5146     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5147     for i in range(1, 3):
5148         with alloc_fail(dev[0], i, "wps_build_m5"):
5149             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5150             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5151             if ev is None:
5152                 raise Exception("No EAP failure reported")
5153             dev[0].request("WPS_CANCEL")
5154             dev[0].wait_disconnected()
5155     dev[0].flush_scan_cache()
5156
5157 @remote_compatible
5158 def test_ap_wps_m5_no_random(dev, apdev):
5159     """WPS and no random for M5 on STA"""
5160     with fail_test(dev[0], 1,
5161                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
5162         wps_run_pbc_fail(apdev[0], dev[0])
5163
5164 @remote_compatible
5165 def test_ap_wps_m7_oom(dev, apdev):
5166     """WPS and OOM for M7 on STA"""
5167     hapd = wps_start_ap(apdev[0])
5168     hapd.request("WPS_PBC")
5169     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5170     for i in range(1, 3):
5171         with alloc_fail(dev[0], i, "wps_build_m7"):
5172             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5173             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5174             if ev is None:
5175                 raise Exception("No EAP failure reported")
5176             dev[0].request("WPS_CANCEL")
5177             dev[0].wait_disconnected()
5178     dev[0].flush_scan_cache()
5179
5180 @remote_compatible
5181 def test_ap_wps_m7_no_random(dev, apdev):
5182     """WPS and no random for M7 on STA"""
5183     with fail_test(dev[0], 1,
5184                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
5185         wps_run_pbc_fail(apdev[0], dev[0])
5186
5187 @remote_compatible
5188 def test_ap_wps_wsc_done_oom(dev, apdev):
5189     """WPS and OOM for WSC_Done on STA"""
5190     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
5191         wps_run_pbc_fail(apdev[0], dev[0])
5192
5193 def test_ap_wps_random_psk_fail(dev, apdev):
5194     """WPS and no random for PSK on AP"""
5195     ssid = "test-wps"
5196     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
5197     appin = "12345670"
5198     try:
5199         os.remove(pskfile)
5200     except:
5201         pass
5202
5203     try:
5204         with open(pskfile, "w") as f:
5205             f.write("# WPA PSKs\n")
5206
5207         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5208                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
5209                    "rsn_pairwise": "CCMP", "ap_pin": appin,
5210                    "wpa_psk_file": pskfile }
5211         hapd = hostapd.add_ap(apdev[0], params)
5212
5213         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5214         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
5215             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
5216             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5217             if ev is None:
5218                 raise Exception("No EAP failure reported")
5219             dev[0].request("WPS_CANCEL")
5220         dev[0].wait_disconnected()
5221
5222         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
5223             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5224
5225         with alloc_fail(hapd, 1, "wps_build_cred"):
5226             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5227
5228         with alloc_fail(hapd, 2, "wps_build_cred"):
5229             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5230     finally:
5231         os.remove(pskfile)
5232
5233 def wps_ext_eap_identity_req(dev, hapd, bssid):
5234     logger.debug("EAP-Identity/Request")
5235     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5236     if ev is None:
5237         raise Exception("Timeout on EAPOL-TX from hostapd")
5238     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
5239     if "OK" not in res:
5240         raise Exception("EAPOL_RX to wpa_supplicant failed")
5241
5242 def wps_ext_eap_identity_resp(hapd, dev, addr):
5243     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5244     if ev is None:
5245         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
5246     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
5247     if "OK" not in res:
5248         raise Exception("EAPOL_RX to hostapd failed")
5249
5250 def wps_ext_eap_wsc(dst, src, src_addr, msg):
5251     logger.debug(msg)
5252     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5253     if ev is None:
5254         raise Exception("Timeout on EAPOL-TX")
5255     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
5256     if "OK" not in res:
5257         raise Exception("EAPOL_RX failed")
5258
5259 def wps_start_ext(apdev, dev, pbc=False, pin=None):
5260     addr = dev.own_addr()
5261     bssid = apdev['bssid']
5262     ssid = "test-wps-conf"
5263     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5264                "wpa_passphrase": "12345678", "wpa": "2",
5265                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5266     hapd = hostapd.add_ap(apdev, params)
5267
5268     if pbc:
5269         hapd.request("WPS_PBC")
5270     else:
5271         if pin is None:
5272             pin = dev.wps_read_pin()
5273         hapd.request("WPS_PIN any " + pin)
5274     dev.scan_for_bss(bssid, freq="2412")
5275     hapd.request("SET ext_eapol_frame_io 1")
5276     dev.request("SET ext_eapol_frame_io 1")
5277
5278     if pbc:
5279         dev.request("WPS_PBC " + bssid)
5280     else:
5281         dev.request("WPS_PIN " + bssid + " " + pin)
5282     return addr,bssid,hapd
5283
5284 def wps_auth_corrupt(dst, src, addr):
5285     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5286     if ev is None:
5287         raise Exception("Timeout on EAPOL-TX")
5288     src.request("SET ext_eapol_frame_io 0")
5289     dst.request("SET ext_eapol_frame_io 0")
5290     msg = ev.split(' ')[2]
5291     if msg[-24:-16] != '10050008':
5292         raise Exception("Could not find Authenticator attribute")
5293     # Corrupt Authenticator value
5294     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5295     res = dst.request("EAPOL_RX " + addr + " " + msg)
5296     if "OK" not in res:
5297         raise Exception("EAPOL_RX failed")
5298
5299 def wps_fail_finish(hapd, dev, fail_str):
5300     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5301     if ev is None:
5302         raise Exception("WPS-FAIL not indicated")
5303     if fail_str not in ev:
5304         raise Exception("Unexpected WPS-FAIL value: " + ev)
5305     dev.request("WPS_CANCEL")
5306     dev.wait_disconnected()
5307
5308 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5309     wps_auth_corrupt(dev, hapd, bssid)
5310     wps_fail_finish(hapd, dev, fail_str)
5311
5312 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5313     wps_auth_corrupt(hapd, dev, addr)
5314     wps_fail_finish(hapd, dev, fail_str)
5315
5316 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5317     """WPS and Authenticator attribute mismatch in M2"""
5318     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5319     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5320     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5321     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5322     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5323     logger.debug("M2")
5324     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5325
5326 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5327     """WPS and Authenticator attribute mismatch in M3"""
5328     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
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     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5334     logger.debug("M3")
5335     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5336
5337 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5338     """WPS and Authenticator attribute mismatch in M4"""
5339     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5340     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5341     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5342     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5343     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5344     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5345     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5346     logger.debug("M4")
5347     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5348
5349 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5350     """WPS and Authenticator attribute mismatch in M5"""
5351     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5352     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5353     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5354     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5355     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5356     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5357     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5358     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5359     logger.debug("M5")
5360     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5361
5362 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5363     """WPS and Authenticator attribute mismatch in M6"""
5364     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5365     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5366     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5367     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5368     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5369     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5370     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5371     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5372     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5373     logger.debug("M6")
5374     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5375
5376 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5377     """WPS and Authenticator attribute mismatch in M7"""
5378     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5379     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5380     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5381     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5382     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5383     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5384     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5385     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5386     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5387     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5388     logger.debug("M7")
5389     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5390
5391 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5392     """WPS and Authenticator attribute mismatch in M8"""
5393     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5394     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5395     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5396     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5397     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5398     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5399     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5400     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5401     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5402     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5403     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5404     logger.debug("M8")
5405     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5406
5407 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5408     """WPS and Authenticator attribute missing from M2"""
5409     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5410     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5411     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5412     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5413     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5414     logger.debug("M2")
5415     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5416     if ev is None:
5417         raise Exception("Timeout on EAPOL-TX")
5418     hapd.request("SET ext_eapol_frame_io 0")
5419     dev[0].request("SET ext_eapol_frame_io 0")
5420     msg = ev.split(' ')[2]
5421     if msg[-24:-16] != '10050008':
5422         raise Exception("Could not find Authenticator attribute")
5423     # Remove Authenticator value
5424     msg = msg[:-24]
5425     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5426     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5427     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5428     if "OK" not in res:
5429         raise Exception("EAPOL_RX failed")
5430     wps_fail_finish(hapd, dev[0], "msg=5")
5431
5432 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5433     """WPS and M2 with different Device Password ID (P2P)"""
5434     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5435     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5436     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5437     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5438     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5439     logger.debug("M2")
5440     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5441     if ev is None:
5442         raise Exception("Timeout on EAPOL-TX")
5443     hapd.request("SET ext_eapol_frame_io 0")
5444     dev[0].request("SET ext_eapol_frame_io 0")
5445     msg = ev.split(' ')[2]
5446     if msg[722:730] != '10120002':
5447         raise Exception("Could not find Device Password ID attribute")
5448     # Replace Device Password ID value. This will fail Authenticator check, but
5449     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5450     # log.
5451     msg = msg[0:730] + "0005" + msg[734:]
5452     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5453     if "OK" not in res:
5454         raise Exception("EAPOL_RX failed")
5455     wps_fail_finish(hapd, dev[0], "msg=5")
5456
5457 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5458     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5459     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5460     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5461     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5462     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5463     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5464     logger.debug("M2")
5465     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5466     if ev is None:
5467         raise Exception("Timeout on EAPOL-TX")
5468     hapd.request("SET ext_eapol_frame_io 0")
5469     dev[0].request("SET ext_eapol_frame_io 0")
5470     msg = ev.split(' ')[2]
5471     if msg[722:730] != '10120002':
5472         raise Exception("Could not find Device Password ID attribute")
5473     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5474     msg = msg[0:730] + "0004" + msg[734:]
5475     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5476     if "OK" not in res:
5477         raise Exception("EAPOL_RX failed")
5478     wps_fail_finish(hapd, dev[0], "msg=5")
5479
5480 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5481     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5482     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5483     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5484     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5485     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5486     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5487     logger.debug("M2")
5488     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5489     if ev is None:
5490         raise Exception("Timeout on EAPOL-TX")
5491     hapd.request("SET ext_eapol_frame_io 0")
5492     dev[0].request("SET ext_eapol_frame_io 0")
5493     msg = ev.split(' ')[2]
5494     if msg[722:730] != '10120002':
5495         raise Exception("Could not find Device Password ID attribute")
5496     # Replace Device Password ID value. This will fail Authenticator check, but
5497     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5498     # log.
5499     msg = msg[0:730] + "0000" + msg[734:]
5500     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5501     if "OK" not in res:
5502         raise Exception("EAPOL_RX failed")
5503     wps_fail_finish(hapd, dev[0], "msg=5")
5504     dev[0].flush_scan_cache()
5505
5506 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5507     """WPS and M2 without Device Password ID"""
5508     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5509     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5510     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5511     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5512     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5513     logger.debug("M2")
5514     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5515     if ev is None:
5516         raise Exception("Timeout on EAPOL-TX")
5517     hapd.request("SET ext_eapol_frame_io 0")
5518     dev[0].request("SET ext_eapol_frame_io 0")
5519     msg = ev.split(' ')[2]
5520     if msg[722:730] != '10120002':
5521         raise Exception("Could not find Device Password ID attribute")
5522     # Remove Device Password ID value. This will fail Authenticator check, but
5523     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5524     # log.
5525     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5526     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5527     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5528     if "OK" not in res:
5529         raise Exception("EAPOL_RX failed")
5530     wps_fail_finish(hapd, dev[0], "msg=5")
5531
5532 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5533     """WPS and M2 without Registrar Nonce"""
5534     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5535     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5536     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5537     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5538     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5539     logger.debug("M2")
5540     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5541     if ev is None:
5542         raise Exception("Timeout on EAPOL-TX")
5543     hapd.request("SET ext_eapol_frame_io 0")
5544     dev[0].request("SET ext_eapol_frame_io 0")
5545     msg = ev.split(' ')[2]
5546     if msg[96:104] != '10390010':
5547         raise Exception("Could not find Registrar Nonce attribute")
5548     # Remove Registrar Nonce. This will fail Authenticator check, but
5549     # allows the code path in wps_process_registrar_nonce() to be checked from
5550     # the debug log.
5551     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5552     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5553     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5554     if "OK" not in res:
5555         raise Exception("EAPOL_RX failed")
5556     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5557     if ev is None:
5558         raise Exception("Disconnect event not seen")
5559     dev[0].request("WPS_CANCEL")
5560     dev[0].flush_scan_cache()
5561
5562 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5563     """WPS and M2 without Enrollee Nonce"""
5564     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5565     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5566     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5567     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5568     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5569     logger.debug("M2")
5570     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5571     if ev is None:
5572         raise Exception("Timeout on EAPOL-TX")
5573     hapd.request("SET ext_eapol_frame_io 0")
5574     dev[0].request("SET ext_eapol_frame_io 0")
5575     msg = ev.split(' ')[2]
5576     if msg[56:64] != '101a0010':
5577         raise Exception("Could not find enrollee Nonce attribute")
5578     # Remove Enrollee Nonce. This will fail Authenticator check, but
5579     # allows the code path in wps_process_enrollee_nonce() to be checked from
5580     # the debug log.
5581     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5582     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5583     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5584     if "OK" not in res:
5585         raise Exception("EAPOL_RX failed")
5586     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5587     if ev is None:
5588         raise Exception("Disconnect event not seen")
5589     dev[0].request("WPS_CANCEL")
5590     dev[0].flush_scan_cache()
5591
5592 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5593     """WPS and M2 without UUID-R"""
5594     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5595     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5596     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5597     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5598     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5599     logger.debug("M2")
5600     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5601     if ev is None:
5602         raise Exception("Timeout on EAPOL-TX")
5603     hapd.request("SET ext_eapol_frame_io 0")
5604     dev[0].request("SET ext_eapol_frame_io 0")
5605     msg = ev.split(' ')[2]
5606     if msg[136:144] != '10480010':
5607         raise Exception("Could not find enrollee Nonce attribute")
5608     # Remove UUID-R. This will fail Authenticator check, but allows the code
5609     # path in wps_process_uuid_r() to be checked from the debug log.
5610     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5611     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5612     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5613     if "OK" not in res:
5614         raise Exception("EAPOL_RX failed")
5615     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5616     if ev is None:
5617         raise Exception("Disconnect event not seen")
5618     dev[0].request("WPS_CANCEL")
5619     dev[0].flush_scan_cache()
5620
5621 def test_ap_wps_m2_invalid(dev, apdev):
5622     """WPS and M2 parsing failure"""
5623     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5624     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5625     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5626     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5627     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5628     logger.debug("M2")
5629     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5630     if ev is None:
5631         raise Exception("Timeout on EAPOL-TX")
5632     hapd.request("SET ext_eapol_frame_io 0")
5633     dev[0].request("SET ext_eapol_frame_io 0")
5634     msg = ev.split(' ')[2]
5635     if msg[136:144] != '10480010':
5636         raise Exception("Could not find enrollee Nonce attribute")
5637     # Remove UUID-R. This will fail Authenticator check, but allows the code
5638     # path in wps_process_uuid_r() to be checked from the debug log.
5639     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5640     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5641     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5642     if "OK" not in res:
5643         raise Exception("EAPOL_RX failed")
5644     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5645     if ev is None:
5646         raise Exception("Disconnect event not seen")
5647     dev[0].request("WPS_CANCEL")
5648     dev[0].flush_scan_cache()
5649
5650 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5651     """WPS and M2 without Message Type"""
5652     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5653     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5654     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5655     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5656     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5657     logger.debug("M2")
5658     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5659     if ev is None:
5660         raise Exception("Timeout on EAPOL-TX")
5661     hapd.request("SET ext_eapol_frame_io 0")
5662     dev[0].request("SET ext_eapol_frame_io 0")
5663     msg = ev.split(' ')[2]
5664     if msg[46:54] != '10220001':
5665         raise Exception("Could not find Message Type attribute")
5666     # Remove Message Type. This will fail Authenticator check, but allows the
5667     # code path in wps_process_wsc_msg() to be checked from the debug log.
5668     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5669     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5670     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5671     if "OK" not in res:
5672         raise Exception("EAPOL_RX failed")
5673     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5674     if ev is None:
5675         raise Exception("Disconnect event not seen")
5676     dev[0].request("WPS_CANCEL")
5677     dev[0].flush_scan_cache()
5678
5679 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5680     """WPS and M2 but unknown Message Type"""
5681     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5682     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5683     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5684     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5685     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5686     logger.debug("M2")
5687     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5688     if ev is None:
5689         raise Exception("Timeout on EAPOL-TX")
5690     hapd.request("SET ext_eapol_frame_io 0")
5691     dev[0].request("SET ext_eapol_frame_io 0")
5692     msg = ev.split(' ')[2]
5693     if msg[46:54] != '10220001':
5694         raise Exception("Could not find Message Type attribute")
5695     # Replace Message Type value. This will be rejected.
5696     msg = msg[0:54] + "00" + msg[56:]
5697     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5698     if "OK" not in res:
5699         raise Exception("EAPOL_RX failed")
5700     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5701     if ev is None:
5702         raise Exception("Disconnect event not seen")
5703     dev[0].request("WPS_CANCEL")
5704     dev[0].flush_scan_cache()
5705
5706 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5707     """WPS and M2 but unknown opcode"""
5708     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5709     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5710     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5711     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5712     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5713     logger.debug("M2")
5714     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5715     if ev is None:
5716         raise Exception("Timeout on EAPOL-TX")
5717     hapd.request("SET ext_eapol_frame_io 0")
5718     dev[0].request("SET ext_eapol_frame_io 0")
5719     msg = ev.split(' ')[2]
5720     # Replace opcode. This will be discarded in EAP-WSC processing.
5721     msg = msg[0:32] + "00" + msg[34:]
5722     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5723     if "OK" not in res:
5724         raise Exception("EAPOL_RX failed")
5725     dev[0].request("WPS_CANCEL")
5726     dev[0].wait_disconnected()
5727     dev[0].flush_scan_cache()
5728
5729 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5730     """WPS and M2 but unknown opcode (WSC_Start)"""
5731     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5732     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5733     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5734     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5735     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5736     logger.debug("M2")
5737     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5738     if ev is None:
5739         raise Exception("Timeout on EAPOL-TX")
5740     hapd.request("SET ext_eapol_frame_io 0")
5741     dev[0].request("SET ext_eapol_frame_io 0")
5742     msg = ev.split(' ')[2]
5743     # Replace opcode. This will be discarded in EAP-WSC processing.
5744     msg = msg[0:32] + "01" + msg[34:]
5745     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5746     if "OK" not in res:
5747         raise Exception("EAPOL_RX failed")
5748     dev[0].request("WPS_CANCEL")
5749     dev[0].wait_disconnected()
5750     dev[0].flush_scan_cache()
5751
5752 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5753     """WPS and M2 but unknown opcode (WSC_Done)"""
5754     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5755     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5756     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5757     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5758     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5759     logger.debug("M2")
5760     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5761     if ev is None:
5762         raise Exception("Timeout on EAPOL-TX")
5763     hapd.request("SET ext_eapol_frame_io 0")
5764     dev[0].request("SET ext_eapol_frame_io 0")
5765     msg = ev.split(' ')[2]
5766     # Replace opcode. This will be discarded in WPS Enrollee processing.
5767     msg = msg[0:32] + "05" + msg[34:]
5768     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5769     if "OK" not in res:
5770         raise Exception("EAPOL_RX failed")
5771     dev[0].request("WPS_CANCEL")
5772     dev[0].wait_disconnected()
5773     dev[0].flush_scan_cache()
5774
5775 def wps_m2_but_other(dev, apdev, title, msgtype):
5776     addr,bssid,hapd = wps_start_ext(apdev, dev)
5777     wps_ext_eap_identity_req(dev, hapd, bssid)
5778     wps_ext_eap_identity_resp(hapd, dev, addr)
5779     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5780     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5781     logger.debug(title)
5782     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5783     if ev is None:
5784         raise Exception("Timeout on EAPOL-TX")
5785     hapd.request("SET ext_eapol_frame_io 0")
5786     dev.request("SET ext_eapol_frame_io 0")
5787     msg = ev.split(' ')[2]
5788     if msg[46:54] != '10220001':
5789         raise Exception("Could not find Message Type attribute")
5790     # Replace Message Type value. This will be rejected.
5791     msg = msg[0:54] + msgtype + msg[56:]
5792     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5793     if "OK" not in res:
5794         raise Exception("EAPOL_RX failed")
5795     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5796     if ev is None:
5797         raise Exception("WPS-FAIL event not seen")
5798     dev.request("WPS_CANCEL")
5799     dev.wait_disconnected()
5800
5801 def wps_m4_but_other(dev, apdev, title, msgtype):
5802     addr,bssid,hapd = wps_start_ext(apdev, dev)
5803     wps_ext_eap_identity_req(dev, hapd, bssid)
5804     wps_ext_eap_identity_resp(hapd, dev, addr)
5805     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5806     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5807     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5808     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5809     logger.debug(title)
5810     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5811     if ev is None:
5812         raise Exception("Timeout on EAPOL-TX")
5813     hapd.request("SET ext_eapol_frame_io 0")
5814     dev.request("SET ext_eapol_frame_io 0")
5815     msg = ev.split(' ')[2]
5816     if msg[46:54] != '10220001':
5817         raise Exception("Could not find Message Type attribute")
5818     # Replace Message Type value. This will be rejected.
5819     msg = msg[0:54] + msgtype + msg[56:]
5820     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5821     if "OK" not in res:
5822         raise Exception("EAPOL_RX failed")
5823     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5824     if ev is None:
5825         raise Exception("WPS-FAIL event not seen")
5826     dev.request("WPS_CANCEL")
5827     dev.wait_disconnected()
5828
5829 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5830     """WPS and M2 but Message Type M4"""
5831     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5832
5833 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5834     """WPS and M2 but Message Type M6"""
5835     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5836
5837 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5838     """WPS and M2 but Message Type M8"""
5839     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5840
5841 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5842     """WPS and M4 but Message Type M2"""
5843     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5844
5845 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5846     """WPS and M4 but Message Type M2D"""
5847     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5848
5849 @remote_compatible
5850 def test_ap_wps_config_methods(dev, apdev):
5851     """WPS configuration method parsing"""
5852     ssid = "test-wps-conf"
5853     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5854                "wpa_passphrase": "12345678", "wpa": "2",
5855                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5856                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5857     hapd = hostapd.add_ap(apdev[0], params)
5858     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5859                "wpa_passphrase": "12345678", "wpa": "2",
5860                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5861                "config_methods": "display push_button" }
5862     hapd2 = hostapd.add_ap(apdev[1], params)
5863
5864 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5865     """WPS UPnP SetSelectedRegistrar protocol testing"""
5866     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5867     hapd = add_ssdp_ap(apdev[0], ap_uuid)
5868
5869     location = ssdp_get_location(ap_uuid)
5870     urls = upnp_get_urls(location)
5871     eventurl = urlparse.urlparse(urls['event_sub_url'])
5872     ctrlurl = urlparse.urlparse(urls['control_url'])
5873     url = urlparse.urlparse(location)
5874     conn = httplib.HTTPConnection(url.netloc)
5875
5876     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5877         def handle(self):
5878             data = self.rfile.readline().strip()
5879             logger.debug(data)
5880             self.wfile.write(gen_wps_event())
5881
5882     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5883     server.timeout = 1
5884
5885     headers = { "callback": '<http://127.0.0.1:12345/event>',
5886                 "NT": "upnp:event",
5887                 "timeout": "Second-1234" }
5888     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5889     resp = conn.getresponse()
5890     if resp.status != 200:
5891         raise Exception("Unexpected HTTP response: %d" % resp.status)
5892     sid = resp.getheader("sid")
5893     logger.debug("Subscription SID " + sid)
5894     server.handle_request()
5895
5896     tests = [ (500, "10"),
5897               (200, "104a000110" + "1041000101" + "101200020000" +
5898                "105300023148" +
5899                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5900                "10480010362db47ba53a519188fb5458b986b2e4"),
5901               (200, "104a000110" + "1041000100" + "101200020000" +
5902                "105300020000"),
5903               (200, "104a000110" + "1041000100"),
5904               (200, "104a000110") ]
5905     for status,test in tests:
5906         tlvs = binascii.unhexlify(test)
5907         newmsg = base64.b64encode(tlvs)
5908         msg = '<?xml version="1.0"?>\n'
5909         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5910         msg += '<s:Body>'
5911         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5912         msg += '<NewMessage>'
5913         msg += newmsg
5914         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5915         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5916         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5917         conn.request("POST", ctrlurl.path, msg, headers)
5918         resp = conn.getresponse()
5919         if resp.status != status:
5920             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5921
5922 def test_ap_wps_adv_oom(dev, apdev):
5923     """WPS AP and advertisement OOM"""
5924     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5925     hapd = add_ssdp_ap(apdev[0], ap_uuid)
5926
5927     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5928         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5929                           no_recv=True)
5930         time.sleep(0.2)
5931
5932     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5933         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5934                           no_recv=True)
5935         time.sleep(0.2)
5936
5937     with alloc_fail(hapd, 1,
5938                     "next_advertisement;advertisement_state_machine_stop"):
5939         hapd.disable()
5940
5941     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5942         if "FAIL" not in hapd.request("ENABLE"):
5943             raise Exception("ENABLE succeeded during OOM")
5944
5945 def test_wps_config_methods(dev):
5946     """WPS config method update"""
5947     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5948     wpas.interface_add("wlan5")
5949     if "OK" not in wpas.request("SET config_methods display label"):
5950         raise Exception("Failed to set config_methods")
5951     if wpas.request("GET config_methods").strip() != "display label":
5952         raise Exception("config_methods were not updated")
5953     if "OK" not in wpas.request("SET config_methods "):
5954         raise Exception("Failed to clear config_methods")
5955     if wpas.request("GET config_methods").strip() != "":
5956         raise Exception("config_methods were not cleared")
5957
5958 WPS_VENDOR_ID_WFA = 14122
5959 WPS_VENDOR_TYPE = 1
5960
5961 # EAP-WSC Op-Code values
5962 WSC_Start = 0x01
5963 WSC_ACK = 0x02
5964 WSC_NACK = 0x03
5965 WSC_MSG = 0x04
5966 WSC_Done = 0x05
5967 WSC_FRAG_ACK = 0x06
5968
5969 ATTR_AP_CHANNEL = 0x1001
5970 ATTR_ASSOC_STATE = 0x1002
5971 ATTR_AUTH_TYPE = 0x1003
5972 ATTR_AUTH_TYPE_FLAGS = 0x1004
5973 ATTR_AUTHENTICATOR = 0x1005
5974 ATTR_CONFIG_METHODS = 0x1008
5975 ATTR_CONFIG_ERROR = 0x1009
5976 ATTR_CONFIRM_URL4 = 0x100a
5977 ATTR_CONFIRM_URL6 = 0x100b
5978 ATTR_CONN_TYPE = 0x100c
5979 ATTR_CONN_TYPE_FLAGS = 0x100d
5980 ATTR_CRED = 0x100e
5981 ATTR_ENCR_TYPE = 0x100f
5982 ATTR_ENCR_TYPE_FLAGS = 0x1010
5983 ATTR_DEV_NAME = 0x1011
5984 ATTR_DEV_PASSWORD_ID = 0x1012
5985 ATTR_E_HASH1 = 0x1014
5986 ATTR_E_HASH2 = 0x1015
5987 ATTR_E_SNONCE1 = 0x1016
5988 ATTR_E_SNONCE2 = 0x1017
5989 ATTR_ENCR_SETTINGS = 0x1018
5990 ATTR_ENROLLEE_NONCE = 0x101a
5991 ATTR_FEATURE_ID = 0x101b
5992 ATTR_IDENTITY = 0x101c
5993 ATTR_IDENTITY_PROOF = 0x101d
5994 ATTR_KEY_WRAP_AUTH = 0x101e
5995 ATTR_KEY_ID = 0x101f
5996 ATTR_MAC_ADDR = 0x1020
5997 ATTR_MANUFACTURER = 0x1021
5998 ATTR_MSG_TYPE = 0x1022
5999 ATTR_MODEL_NAME = 0x1023
6000 ATTR_MODEL_NUMBER = 0x1024
6001 ATTR_NETWORK_INDEX = 0x1026
6002 ATTR_NETWORK_KEY = 0x1027
6003 ATTR_NETWORK_KEY_INDEX = 0x1028
6004 ATTR_NEW_DEVICE_NAME = 0x1029
6005 ATTR_NEW_PASSWORD = 0x102a
6006 ATTR_OOB_DEVICE_PASSWORD = 0x102c
6007 ATTR_OS_VERSION = 0x102d
6008 ATTR_POWER_LEVEL = 0x102f
6009 ATTR_PSK_CURRENT = 0x1030
6010 ATTR_PSK_MAX = 0x1031
6011 ATTR_PUBLIC_KEY = 0x1032
6012 ATTR_RADIO_ENABLE = 0x1033
6013 ATTR_REBOOT = 0x1034
6014 ATTR_REGISTRAR_CURRENT = 0x1035
6015 ATTR_REGISTRAR_ESTABLISHED = 0x1036
6016 ATTR_REGISTRAR_LIST = 0x1037
6017 ATTR_REGISTRAR_MAX = 0x1038
6018 ATTR_REGISTRAR_NONCE = 0x1039
6019 ATTR_REQUEST_TYPE = 0x103a
6020 ATTR_RESPONSE_TYPE = 0x103b
6021 ATTR_RF_BANDS = 0x103c
6022 ATTR_R_HASH1 = 0x103d
6023 ATTR_R_HASH2 = 0x103e
6024 ATTR_R_SNONCE1 = 0x103f
6025 ATTR_R_SNONCE2 = 0x1040
6026 ATTR_SELECTED_REGISTRAR = 0x1041
6027 ATTR_SERIAL_NUMBER = 0x1042
6028 ATTR_WPS_STATE = 0x1044
6029 ATTR_SSID = 0x1045
6030 ATTR_TOTAL_NETWORKS = 0x1046
6031 ATTR_UUID_E = 0x1047
6032 ATTR_UUID_R = 0x1048
6033 ATTR_VENDOR_EXT = 0x1049
6034 ATTR_VERSION = 0x104a
6035 ATTR_X509_CERT_REQ = 0x104b
6036 ATTR_X509_CERT = 0x104c
6037 ATTR_EAP_IDENTITY = 0x104d
6038 ATTR_MSG_COUNTER = 0x104e
6039 ATTR_PUBKEY_HASH = 0x104f
6040 ATTR_REKEY_KEY = 0x1050
6041 ATTR_KEY_LIFETIME = 0x1051
6042 ATTR_PERMITTED_CFG_METHODS = 0x1052
6043 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
6044 ATTR_PRIMARY_DEV_TYPE = 0x1054
6045 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
6046 ATTR_PORTABLE_DEV = 0x1056
6047 ATTR_AP_SETUP_LOCKED = 0x1057
6048 ATTR_APPLICATION_EXT = 0x1058
6049 ATTR_EAP_TYPE = 0x1059
6050 ATTR_IV = 0x1060
6051 ATTR_KEY_PROVIDED_AUTO = 0x1061
6052 ATTR_802_1X_ENABLED = 0x1062
6053 ATTR_APPSESSIONKEY = 0x1063
6054 ATTR_WEPTRANSMITKEY = 0x1064
6055 ATTR_REQUESTED_DEV_TYPE = 0x106a
6056
6057 # Message Type
6058 WPS_Beacon = 0x01
6059 WPS_ProbeRequest = 0x02
6060 WPS_ProbeResponse = 0x03
6061 WPS_M1 = 0x04
6062 WPS_M2 = 0x05
6063 WPS_M2D = 0x06
6064 WPS_M3 = 0x07
6065 WPS_M4 = 0x08
6066 WPS_M5 = 0x09
6067 WPS_M6 = 0x0a
6068 WPS_M7 = 0x0b
6069 WPS_M8 = 0x0c
6070 WPS_WSC_ACK = 0x0d
6071 WPS_WSC_NACK = 0x0e
6072 WPS_WSC_DONE = 0x0f
6073
6074 def get_wsc_msg(dev):
6075     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
6076     if ev is None:
6077         raise Exception("Timeout on EAPOL-TX")
6078     data = binascii.unhexlify(ev.split(' ')[2])
6079     msg = {}
6080
6081     # Parse EAPOL header
6082     if len(data) < 4:
6083         raise Exception("No room for EAPOL header")
6084     version,type,length = struct.unpack('>BBH', data[0:4])
6085     msg['eapol_version'] = version
6086     msg['eapol_type'] = type
6087     msg['eapol_length'] = length
6088     data = data[4:]
6089     if length != len(data):
6090         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
6091     if type != 0:
6092         raise Exception("Unexpected EAPOL header type: %d" % type)
6093
6094     # Parse EAP header
6095     if len(data) < 4:
6096         raise Exception("No room for EAP header")
6097     code,identifier,length = struct.unpack('>BBH', data[0:4])
6098     msg['eap_code'] = code
6099     msg['eap_identifier'] = identifier
6100     msg['eap_length'] = length
6101     data = data[4:]
6102     if msg['eapol_length'] != msg['eap_length']:
6103         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
6104
6105     # Parse EAP expanded header
6106     if len(data) < 1:
6107         raise Exception("No EAP type included")
6108     msg['eap_type'], = struct.unpack('B', data[0])
6109     data = data[1:]
6110
6111     if msg['eap_type'] == 254:
6112         if len(data) < 3 + 4:
6113             raise Exception("Truncated EAP expanded header")
6114         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
6115         data = data[7:]
6116     else:
6117         raise Exception("Unexpected EAP type")
6118
6119     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
6120         raise Exception("Unexpected Vendor-Id")
6121     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
6122         raise Exception("Unexpected Vendor-Type")
6123
6124     # Parse EAP-WSC header
6125     if len(data) < 2:
6126         raise Exception("Truncated EAP-WSC header")
6127     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
6128     data = data[2:]
6129
6130     # Parse WSC attributes
6131     msg['raw_attrs'] = data
6132     attrs = {}
6133     while len(data) > 0:
6134         if len(data) < 4:
6135             raise Exception("Truncated attribute header")
6136         attr,length = struct.unpack('>HH', data[0:4])
6137         data = data[4:]
6138         if length > len(data):
6139             raise Exception("Truncated attribute 0x%04x" % attr)
6140         attrs[attr] = data[0:length]
6141         data = data[length:]
6142     msg['wsc_attrs'] = attrs
6143
6144     if ATTR_MSG_TYPE in attrs:
6145         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
6146
6147     return msg
6148
6149 def recv_wsc_msg(dev, opcode, msg_type):
6150     msg = get_wsc_msg(dev)
6151     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
6152         raise Exception("Unexpected Op-Code/MsgType")
6153     return msg, msg['wsc_attrs'], msg['raw_attrs']
6154
6155 def build_wsc_attr(attr, payload):
6156     return struct.pack('>HH', attr, len(payload)) + payload
6157
6158 def build_attr_msg_type(msg_type):
6159     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
6160
6161 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
6162     length = 4 + 8 + 2 + len(payload)
6163     # EAPOL header
6164     msg = struct.pack('>BBH', 2, 0, length)
6165     # EAP header
6166     msg += struct.pack('>BBH', eap_code, eap_id, length)
6167     # EAP expanded header for EAP-WSC
6168     msg += struct.pack('B', 254)
6169     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
6170     msg += struct.pack('>L', WPS_VENDOR_TYPE)
6171     # EAP-WSC header
6172     msg += struct.pack('BB', opcode, 0)
6173     # WSC attributes
6174     msg += payload
6175     return msg
6176
6177 def build_eap_success(eap_id):
6178     length = 4
6179     # EAPOL header
6180     msg = struct.pack('>BBH', 2, 0, length)
6181     # EAP header
6182     msg += struct.pack('>BBH', 3, eap_id, length)
6183     return msg
6184
6185 def build_eap_failure(eap_id):
6186     length = 4
6187     # EAPOL header
6188     msg = struct.pack('>BBH', 2, 0, length)
6189     # EAP header
6190     msg += struct.pack('>BBH', 4, eap_id, length)
6191     return msg
6192
6193 def send_wsc_msg(dev, src, msg):
6194     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
6195     if "OK" not in res:
6196         raise Exception("EAPOL_RX failed")
6197
6198 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
6199 group_5_generator = 2
6200
6201 def wsc_kdf(key, label, bits):
6202     result = ''
6203     i = 1
6204     while len(result) * 8 < bits:
6205         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
6206         m = hmac.new(key, data, hashlib.sha256)
6207         result += m.digest()
6208         i += 1
6209     return result[0:bits / 8]
6210
6211 def wsc_keys(kdk):
6212     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
6213     authkey = keys[0:32]
6214     keywrapkey = keys[32:48]
6215     emsk = keys[48:80]
6216     return authkey,keywrapkey,emsk
6217
6218 def wsc_dev_pw_half_psk(authkey, dev_pw):
6219     m = hmac.new(authkey, dev_pw, hashlib.sha256)
6220     return m.digest()[0:16]
6221
6222 def wsc_dev_pw_psk(authkey, dev_pw):
6223     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
6224     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
6225     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
6226     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
6227     return psk1,psk2
6228
6229 def build_attr_authenticator(authkey, prev_msg, curr_msg):
6230     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
6231     auth = m.digest()[0:8]
6232     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
6233
6234 def build_attr_encr_settings(authkey, keywrapkey, data):
6235     m = hmac.new(authkey, data, hashlib.sha256)
6236     kwa = m.digest()[0:8]
6237     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6238     iv = 16*'\x99'
6239     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6240     pad_len = 16 - len(data) % 16
6241     ps = pad_len * struct.pack('B', pad_len)
6242     data += ps
6243     wrapped = aes.encrypt(data)
6244     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6245
6246 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
6247     if len(data) < 32 or len(data) % 16 != 0:
6248         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
6249     iv = data[0:16]
6250     encr = data[16:]
6251     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6252     decrypted = aes.decrypt(encr)
6253     pad_len, = struct.unpack('B', decrypted[-1])
6254     if pad_len > len(decrypted):
6255         raise Exception("Invalid padding in Encrypted Settings")
6256     for i in range(-pad_len, -1):
6257         if decrypted[i] != decrypted[-1]:
6258             raise Exception("Invalid PS value in Encrypted Settings")
6259     
6260     decrypted = decrypted[0:len(decrypted) - pad_len]
6261     if len(decrypted) < 12:
6262         raise Exception("Truncated Encrypted Settings plaintext")
6263     kwa = decrypted[-12:]
6264     attr,length = struct.unpack(">HH", kwa[0:4])
6265     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6266         raise Exception("Invalid KWA header")
6267     kwa = kwa[4:]
6268     decrypted = decrypted[0:len(decrypted) - 12]
6269
6270     m = hmac.new(authkey, decrypted, hashlib.sha256)
6271     calc_kwa = m.digest()[0:8]
6272     if kwa != calc_kwa:
6273         raise Exception("KWA mismatch")
6274
6275     return decrypted
6276
6277 def zeropad_str(val, pad_len):
6278     while len(val) < pad_len * 2:
6279         val = '0' + val
6280     return val
6281
6282 def wsc_dh_init():
6283     # For now, use a hardcoded private key. In theory, this is supposed to be
6284     # randomly selected.
6285     own_private = 0x123456789
6286     own_public = pow(group_5_generator, own_private, group_5_prime)
6287     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6288     return own_private, pk
6289
6290 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6291     peer_public = long(binascii.hexlify(peer_pk), 16)
6292     if peer_public < 2 or peer_public >= group_5_prime:
6293         raise Exception("Invalid peer public key")
6294     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6295         raise Exception("Unexpected Legendre symbol for peer public key")
6296
6297     shared_secret = pow(peer_public, own_private, group_5_prime)
6298     ss = zeropad_str(format(shared_secret, "02x"), 192)
6299     logger.debug("DH shared secret: " + ss)
6300
6301     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6302     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6303
6304     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6305     kdk = m.digest()
6306     logger.debug("KDK: " + binascii.hexlify(kdk))
6307     authkey,keywrapkey,emsk = wsc_keys(kdk)
6308     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6309     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6310     logger.debug("EMSK: " + binascii.hexlify(emsk))
6311     return authkey,keywrapkey
6312
6313 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6314     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6315     logger.debug("PSK1: " + binascii.hexlify(psk1))
6316     logger.debug("PSK2: " + binascii.hexlify(psk2))
6317
6318     # Note: Secret values are supposed to be random, but hardcoded values are
6319     # fine for testing.
6320     s1 = 16*'\x77'
6321     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6322     hash1 = m.digest()
6323     logger.debug("Hash1: " + binascii.hexlify(hash1))
6324
6325     s2 = 16*'\x88'
6326     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6327     hash2 = m.digest()
6328     logger.debug("Hash2: " + binascii.hexlify(hash2))
6329     return s1,s2,hash1,hash2
6330
6331 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6332              manufacturer='', model_name='', config_methods='\x00\x00'):
6333     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6334     attrs += build_attr_msg_type(WPS_M1)
6335     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6336     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6337     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6338     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6339     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6340     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6341     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6342     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6343     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6344     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6345     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6346     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6347     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6348     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6349     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6350     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6351     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6352     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6353     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6354     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6355     m1 = build_eap_wsc(2, eap_id, attrs)
6356     return m1, attrs
6357
6358 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6359              dev_pw_id='\x00\x00', eap_code=1):
6360     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6361     attrs += build_attr_msg_type(WPS_M2)
6362     if e_nonce:
6363         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6364     if r_nonce:
6365         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6366     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6367     if r_pk:
6368         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6369     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6370     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6371     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6372     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6373     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6374     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6375     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6376     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6377     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6378     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6379     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6380     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6381     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6382     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6383     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6384     attrs += build_attr_authenticator(authkey, m1, attrs)
6385     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6386     return m2, attrs
6387
6388 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6389     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6390     attrs += build_attr_msg_type(WPS_M2D)
6391     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6392     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6393     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6394     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6395     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6396     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6397     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6398     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6399     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6400     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6401     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6402     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6403     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6404     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6405     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6406     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6407     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6408     if dev_pw_id:
6409         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6410     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6411     return m2d, attrs
6412
6413 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6414     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6415     if msg_type is not None:
6416         attrs += build_attr_msg_type(msg_type)
6417     if e_nonce:
6418         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6419     if r_nonce:
6420         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6421     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6422     return msg, attrs
6423
6424 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6425                msg_type=WPS_WSC_NACK, eap_code=1):
6426     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6427     if msg_type is not None:
6428         attrs += build_attr_msg_type(msg_type)
6429     if e_nonce:
6430         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6431     if r_nonce:
6432         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6433     if config_error:
6434         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6435     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6436     return msg, attrs
6437
6438 def test_wps_ext(dev, apdev):
6439     """WPS against external implementation"""
6440     pin = "12345670"
6441     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6442     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6443     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6444
6445     logger.debug("Receive WSC/Start from AP")
6446     msg = get_wsc_msg(hapd)
6447     if msg['wsc_opcode'] != WSC_Start:
6448         raise Exception("Unexpected Op-Code for WSC/Start")
6449     wsc_start_id = msg['eap_identifier']
6450
6451     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6452     uuid_e = 16*'\x11'
6453     e_nonce = 16*'\x22'
6454     own_private, e_pk = wsc_dh_init()
6455
6456     logger.debug("Send M1 to AP")
6457     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6458                                 e_nonce, e_pk)
6459     send_wsc_msg(hapd, addr, m1)
6460
6461     logger.debug("Receive M2 from AP")
6462     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6463
6464     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6465                                     mac_addr, e_nonce,
6466                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6467     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6468                                                 m2_attrs[ATTR_PUBLIC_KEY])
6469
6470     logger.debug("Send M3 to AP")
6471     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6472     attrs += build_attr_msg_type(WPS_M3)
6473     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6474                             m2_attrs[ATTR_REGISTRAR_NONCE])
6475     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6476     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6477     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6478     raw_m3_attrs = attrs
6479     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6480     send_wsc_msg(hapd, addr, m3)
6481
6482     logger.debug("Receive M4 from AP")
6483     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6484
6485     logger.debug("Send M5 to AP")
6486     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6487     attrs += build_attr_msg_type(WPS_M5)
6488     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6489                             m2_attrs[ATTR_REGISTRAR_NONCE])
6490     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6491     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6492     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6493     raw_m5_attrs = attrs
6494     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6495     send_wsc_msg(hapd, addr, m5)
6496
6497     logger.debug("Receive M6 from AP")
6498     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6499
6500     logger.debug("Send M7 to AP")
6501     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6502     attrs += build_attr_msg_type(WPS_M7)
6503     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6504                             m2_attrs[ATTR_REGISTRAR_NONCE])
6505     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6506     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6507     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6508     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6509     raw_m7_attrs = attrs
6510     send_wsc_msg(hapd, addr, m7)
6511
6512     logger.debug("Receive M8 from AP")
6513     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6514     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6515                                          m8_attrs[ATTR_ENCR_SETTINGS])
6516     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6517
6518     logger.debug("Prepare WSC_Done")
6519     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6520     attrs += build_attr_msg_type(WPS_WSC_DONE)
6521     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6522     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6523                             m2_attrs[ATTR_REGISTRAR_NONCE])
6524     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6525     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6526     # AP disconnects.
6527
6528     uuid_r = 16*'\x33'
6529     r_nonce = 16*'\x44'
6530
6531     eap_id = wsc_start_id
6532     logger.debug("Send WSC/Start to STA")
6533     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6534     send_wsc_msg(dev[0], bssid, wsc_start)
6535     eap_id = (eap_id + 1) % 256
6536
6537     logger.debug("Receive M1 from STA")
6538     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6539
6540     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6541                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6542                                     r_nonce)
6543     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6544                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6545
6546     logger.debug("Send M2 to STA")
6547     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6548                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6549                                 r_nonce, uuid_r, e_pk)
6550     send_wsc_msg(dev[0], bssid, m2)
6551     eap_id = (eap_id + 1) % 256
6552
6553     logger.debug("Receive M3 from STA")
6554     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6555
6556     logger.debug("Send M4 to STA")
6557     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6558     attrs += build_attr_msg_type(WPS_M4)
6559     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6560     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6561     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6562     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6563     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6564     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6565     raw_m4_attrs = attrs
6566     m4 = build_eap_wsc(1, eap_id, attrs)
6567     send_wsc_msg(dev[0], bssid, m4)
6568     eap_id = (eap_id + 1) % 256
6569
6570     logger.debug("Receive M5 from STA")
6571     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6572
6573     logger.debug("Send M6 to STA")
6574     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6575     attrs += build_attr_msg_type(WPS_M6)
6576     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6577                             m1_attrs[ATTR_ENROLLEE_NONCE])
6578     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6579     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6580     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6581     raw_m6_attrs = attrs
6582     m6 = build_eap_wsc(1, eap_id, attrs)
6583     send_wsc_msg(dev[0], bssid, m6)
6584     eap_id = (eap_id + 1) % 256
6585
6586     logger.debug("Receive M7 from STA")
6587     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6588
6589     logger.debug("Send M8 to STA")
6590     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6591     attrs += build_attr_msg_type(WPS_M8)
6592     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6593                             m1_attrs[ATTR_ENROLLEE_NONCE])
6594     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6595     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6596     raw_m8_attrs = attrs
6597     m8 = build_eap_wsc(1, eap_id, attrs)
6598     send_wsc_msg(dev[0], bssid, m8)
6599     eap_id = (eap_id + 1) % 256
6600
6601     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6602     if ev is None:
6603         raise Exception("wpa_supplicant did not report credential")
6604
6605     logger.debug("Receive WSC_Done from STA")
6606     msg = get_wsc_msg(dev[0])
6607     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6608         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6609
6610     logger.debug("Send WSC_Done to AP")
6611     hapd.request("SET ext_eapol_frame_io 0")
6612     dev[0].request("SET ext_eapol_frame_io 0")
6613     send_wsc_msg(hapd, addr, wsc_done)
6614
6615     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6616     if ev is None:
6617         raise Exception("hostapd did not report WPS success")
6618
6619     dev[0].wait_connected()
6620
6621 def wps_start_kwa(dev, apdev):
6622     pin = "12345670"
6623     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6624     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6625     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6626     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6627
6628     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6629     uuid_r = 16*'\x33'
6630     r_nonce = 16*'\x44'
6631     own_private, e_pk = wsc_dh_init()
6632
6633     logger.debug("Receive M1 from STA")
6634     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6635     eap_id = (msg['eap_identifier'] + 1) % 256
6636
6637     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6638                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6639                                     r_nonce)
6640     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6641                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6642
6643     logger.debug("Send M2 to STA")
6644     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6645                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6646                                 r_nonce, uuid_r, e_pk)
6647     send_wsc_msg(dev[0], bssid, m2)
6648     eap_id = (eap_id + 1) % 256
6649
6650     logger.debug("Receive M3 from STA")
6651     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6652
6653     logger.debug("Send M4 to STA")
6654     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6655     attrs += build_attr_msg_type(WPS_M4)
6656     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6657     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6658     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6659
6660     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6661
6662 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6663     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6664     m4 = build_eap_wsc(1, eap_id, attrs)
6665     send_wsc_msg(dev[0], bssid, m4)
6666     eap_id = (eap_id + 1) % 256
6667
6668     logger.debug("Receive M5 from STA")
6669     msg = get_wsc_msg(dev[0])
6670     if msg['wsc_opcode'] != WSC_NACK:
6671         raise Exception("Unexpected message - expected WSC_Nack")
6672
6673     dev[0].request("WPS_CANCEL")
6674     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6675     dev[0].wait_disconnected()
6676
6677 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6678     """WPS and KWA error: No KWA attribute"""
6679     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6680     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6681     # Encrypted Settings without KWA
6682     iv = 16*'\x99'
6683     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6684     pad_len = 16 - len(data) % 16
6685     ps = pad_len * struct.pack('B', pad_len)
6686     data += ps
6687     wrapped = aes.encrypt(data)
6688     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6689     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6690
6691 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6692     """WPS and KWA error: Data after KWA"""
6693     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6694     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6695     # Encrypted Settings and data after KWA
6696     m = hmac.new(authkey, data, hashlib.sha256)
6697     kwa = m.digest()[0:8]
6698     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6699     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6700     iv = 16*'\x99'
6701     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6702     pad_len = 16 - len(data) % 16
6703     ps = pad_len * struct.pack('B', pad_len)
6704     data += ps
6705     wrapped = aes.encrypt(data)
6706     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6707     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6708
6709 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6710     """WPS and KWA error: KWA mismatch"""
6711     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6712     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6713     # Encrypted Settings and KWA with incorrect value
6714     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6715     iv = 16*'\x99'
6716     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6717     pad_len = 16 - len(data) % 16
6718     ps = pad_len * struct.pack('B', pad_len)
6719     data += ps
6720     wrapped = aes.encrypt(data)
6721     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6722     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6723
6724 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6725     pin = "12345670"
6726     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6727     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6728     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6729     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6730
6731     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6732     uuid_r = 16*'\x33'
6733     r_nonce = 16*'\x44'
6734     own_private, e_pk = wsc_dh_init()
6735
6736     logger.debug("Receive M1 from STA")
6737     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6738     eap_id = (msg['eap_identifier'] + 1) % 256
6739
6740     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6741                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6742                                     r_nonce)
6743     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6744                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6745
6746     logger.debug("Send M2 to STA")
6747     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6748                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6749                                 r_nonce, uuid_r, e_pk)
6750     send_wsc_msg(dev[0], bssid, m2)
6751     eap_id = (eap_id + 1) % 256
6752
6753     logger.debug("Receive M3 from STA")
6754     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6755
6756     logger.debug("Send M4 to STA")
6757     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6758     attrs += build_attr_msg_type(WPS_M4)
6759     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6760     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6761     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6762     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6763     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6764     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6765     raw_m4_attrs = attrs
6766     m4 = build_eap_wsc(1, eap_id, attrs)
6767     send_wsc_msg(dev[0], bssid, m4)
6768     eap_id = (eap_id + 1) % 256
6769
6770     logger.debug("Receive M5 from STA")
6771     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6772
6773     logger.debug("Send M6 to STA")
6774     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6775     attrs += build_attr_msg_type(WPS_M6)
6776     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6777                             m1_attrs[ATTR_ENROLLEE_NONCE])
6778     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6779     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6780     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6781     raw_m6_attrs = attrs
6782     m6 = build_eap_wsc(1, eap_id, attrs)
6783     send_wsc_msg(dev[0], bssid, m6)
6784     eap_id = (eap_id + 1) % 256
6785
6786     logger.debug("Receive M7 from STA")
6787     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6788
6789     logger.debug("Send M8 to STA")
6790     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6791     attrs += build_attr_msg_type(WPS_M8)
6792     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6793                             m1_attrs[ATTR_ENROLLEE_NONCE])
6794     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6795     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6796     raw_m8_attrs = attrs
6797     m8 = build_eap_wsc(1, eap_id, attrs)
6798     send_wsc_msg(dev[0], bssid, m8)
6799     eap_id = (eap_id + 1) % 256
6800
6801     if no_connect:
6802         logger.debug("Receive WSC_Done from STA")
6803         msg = get_wsc_msg(dev[0])
6804         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6805             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6806
6807         hapd.request("SET ext_eapol_frame_io 0")
6808         dev[0].request("SET ext_eapol_frame_io 0")
6809
6810         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6811
6812         dev[0].wait_disconnected()
6813         dev[0].request("REMOVE_NETWORK all")
6814     elif connect:
6815         logger.debug("Receive WSC_Done from STA")
6816         msg = get_wsc_msg(dev[0])
6817         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6818             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6819
6820         hapd.request("SET ext_eapol_frame_io 0")
6821         dev[0].request("SET ext_eapol_frame_io 0")
6822
6823         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6824
6825         dev[0].wait_connected()
6826     else:
6827         # Verify STA NACK's the credential
6828         msg = get_wsc_msg(dev[0])
6829         if msg['wsc_opcode'] != WSC_NACK:
6830             raise Exception("Unexpected message - expected WSC_Nack")
6831         dev[0].request("WPS_CANCEL")
6832         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6833         dev[0].wait_disconnected()
6834
6835 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6836                encr_type='\x00\x08', nw_key="12345678",
6837                mac_addr='\x00\x00\x00\x00\x00\x00'):
6838     attrs = ''
6839     if nw_idx is not None:
6840         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6841     if ssid is not None:
6842         attrs += build_wsc_attr(ATTR_SSID, ssid)
6843     if auth_type is not None:
6844         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6845     if encr_type is not None:
6846         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6847     if nw_key is not None:
6848         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6849     if mac_addr is not None:
6850         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6851     return build_wsc_attr(ATTR_CRED, attrs)
6852
6853 def test_wps_ext_cred_proto_success(dev, apdev):
6854     """WPS and Credential: success"""
6855     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6856     m8_cred = build_cred(mac_addr=mac_addr)
6857     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6858
6859 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6860     """WPS and Credential: MAC Address mismatch"""
6861     m8_cred = build_cred()
6862     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6863
6864 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6865     """WPS and Credential: zeropadded attributes"""
6866     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6867     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6868                          nw_key="12345678\x00")
6869     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6870
6871 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6872     """WPS and Credential: SSID missing"""
6873     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6874     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6875     wps_run_cred_proto(dev, apdev, m8_cred)
6876
6877 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6878     """WPS and Credential: Zero-length SSID"""
6879     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6880     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6881     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6882
6883 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6884     """WPS and Credential: Auth Type missing"""
6885     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6886     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6887     wps_run_cred_proto(dev, apdev, m8_cred)
6888
6889 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6890     """WPS and Credential: Encr Type missing"""
6891     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6892     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6893     wps_run_cred_proto(dev, apdev, m8_cred)
6894
6895 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6896     """WPS and Credential: Network Key missing"""
6897     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6898     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6899     wps_run_cred_proto(dev, apdev, m8_cred)
6900
6901 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6902     """WPS and Credential: Network Key missing (open)"""
6903     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6904     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6905                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6906     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6907
6908 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6909     """WPS and Credential: MAC Address missing"""
6910     m8_cred = build_cred(mac_addr=None)
6911     wps_run_cred_proto(dev, apdev, m8_cred)
6912
6913 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6914     """WPS and Credential: Invalid Encr Type"""
6915     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6916     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6917     wps_run_cred_proto(dev, apdev, m8_cred)
6918
6919 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6920     """WPS and Credential: Missing Credential"""
6921     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6922     m8_cred = ''
6923     wps_run_cred_proto(dev, apdev, m8_cred)
6924
6925 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6926     """WPS and no Public Key in M2"""
6927     pin = "12345670"
6928     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6929     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6930     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6931     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6932
6933     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6934     uuid_r = 16*'\x33'
6935     r_nonce = 16*'\x44'
6936     own_private, e_pk = wsc_dh_init()
6937
6938     logger.debug("Receive M1 from STA")
6939     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6940     eap_id = (msg['eap_identifier'] + 1) % 256
6941
6942     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6943                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6944                                     r_nonce)
6945     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6946                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6947
6948     logger.debug("Send M2 to STA")
6949     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6950                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6951                                 r_nonce, uuid_r, None)
6952     send_wsc_msg(dev[0], bssid, m2)
6953     eap_id = (eap_id + 1) % 256
6954
6955     # Verify STA NACK's the credential
6956     msg = get_wsc_msg(dev[0])
6957     if msg['wsc_opcode'] != WSC_NACK:
6958         raise Exception("Unexpected message - expected WSC_Nack")
6959     dev[0].request("WPS_CANCEL")
6960     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6961     dev[0].wait_disconnected()
6962
6963 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6964     """WPS and invalid Public Key in M2"""
6965     pin = "12345670"
6966     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6967     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6968     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6969     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6970
6971     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6972     uuid_r = 16*'\x33'
6973     r_nonce = 16*'\x44'
6974     own_private, e_pk = wsc_dh_init()
6975
6976     logger.debug("Receive M1 from STA")
6977     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6978     eap_id = (msg['eap_identifier'] + 1) % 256
6979
6980     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6981                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6982                                     r_nonce)
6983     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6984                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6985
6986     logger.debug("Send M2 to STA")
6987     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6988                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6989                                 r_nonce, uuid_r, 192*'\xff')
6990     send_wsc_msg(dev[0], bssid, m2)
6991     eap_id = (eap_id + 1) % 256
6992
6993     # Verify STA NACK's the credential
6994     msg = get_wsc_msg(dev[0])
6995     if msg['wsc_opcode'] != WSC_NACK:
6996         raise Exception("Unexpected message - expected WSC_Nack")
6997     dev[0].request("WPS_CANCEL")
6998     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6999     dev[0].wait_disconnected()
7000
7001 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
7002     """WPS and Public Key OOM in M2"""
7003     pin = "12345670"
7004     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7005     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7006     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7007     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7008
7009     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7010     uuid_r = 16*'\x33'
7011     r_nonce = 16*'\x44'
7012     own_private, e_pk = wsc_dh_init()
7013
7014     logger.debug("Receive M1 from STA")
7015     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7016     eap_id = (msg['eap_identifier'] + 1) % 256
7017
7018     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7019                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7020                                     r_nonce)
7021     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7022                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7023
7024     logger.debug("Send M2 to STA")
7025     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7026                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7027                                 r_nonce, uuid_r, e_pk)
7028     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
7029         send_wsc_msg(dev[0], bssid, m2)
7030         eap_id = (eap_id + 1) % 256
7031
7032         # Verify STA NACK's the credential
7033         msg = get_wsc_msg(dev[0])
7034         if msg['wsc_opcode'] != WSC_NACK:
7035             raise Exception("Unexpected message - expected WSC_Nack")
7036         dev[0].request("WPS_CANCEL")
7037         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7038         dev[0].wait_disconnected()
7039
7040 def test_wps_ext_proto_nack_m3(dev, apdev):
7041     """WPS and NACK M3"""
7042     pin = "12345670"
7043     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7044     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7045     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7046     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7047
7048     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7049     uuid_r = 16*'\x33'
7050     r_nonce = 16*'\x44'
7051     own_private, e_pk = wsc_dh_init()
7052
7053     logger.debug("Receive M1 from STA")
7054     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7055     eap_id = (msg['eap_identifier'] + 1) % 256
7056
7057     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7058                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7059                                     r_nonce)
7060     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7061                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7062
7063     logger.debug("Send M2 to STA")
7064     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7065                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7066                                 r_nonce, uuid_r, e_pk)
7067     send_wsc_msg(dev[0], bssid, m2)
7068     eap_id = (eap_id + 1) % 256
7069
7070     logger.debug("Receive M3 from STA")
7071     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7072
7073     logger.debug("Send NACK to STA")
7074     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
7075                             r_nonce, config_error='\x01\x23')
7076     send_wsc_msg(dev[0], bssid, msg)
7077     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
7078     if ev is None:
7079         raise Exception("Failure not reported")
7080     if "msg=7 config_error=291" not in ev:
7081         raise Exception("Unexpected failure reason: " + ev)
7082
7083 def test_wps_ext_proto_nack_m5(dev, apdev):
7084     """WPS and NACK M5"""
7085     pin = "12345670"
7086     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7087     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7088     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7089     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7090
7091     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7092     uuid_r = 16*'\x33'
7093     r_nonce = 16*'\x44'
7094     own_private, e_pk = wsc_dh_init()
7095
7096     logger.debug("Receive M1 from STA")
7097     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7098     eap_id = (msg['eap_identifier'] + 1) % 256
7099
7100     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7101                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7102                                     r_nonce)
7103     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7104                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7105
7106     logger.debug("Send M2 to STA")
7107     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7108                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7109                                 r_nonce, uuid_r, e_pk)
7110     send_wsc_msg(dev[0], bssid, m2)
7111     eap_id = (eap_id + 1) % 256
7112
7113     logger.debug("Receive M3 from STA")
7114     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7115
7116     logger.debug("Send M4 to STA")
7117     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7118     attrs += build_attr_msg_type(WPS_M4)
7119     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7120     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7121     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7122     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7123     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7124     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7125     raw_m4_attrs = attrs
7126     m4 = build_eap_wsc(1, eap_id, attrs)
7127     send_wsc_msg(dev[0], bssid, m4)
7128     eap_id = (eap_id + 1) % 256
7129
7130     logger.debug("Receive M5 from STA")
7131     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7132
7133     logger.debug("Send NACK to STA")
7134     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
7135                             r_nonce, config_error='\x01\x24')
7136     send_wsc_msg(dev[0], bssid, msg)
7137     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
7138     if ev is None:
7139         raise Exception("Failure not reported")
7140     if "msg=9 config_error=292" not in ev:
7141         raise Exception("Unexpected failure reason: " + ev)
7142
7143 def wps_nack_m3(dev, apdev):
7144     pin = "00000000"
7145     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
7146     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7147     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7148     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7149
7150     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7151     uuid_r = 16*'\x33'
7152     r_nonce = 16*'\x44'
7153     own_private, e_pk = wsc_dh_init()
7154
7155     logger.debug("Receive M1 from STA")
7156     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7157     eap_id = (msg['eap_identifier'] + 1) % 256
7158
7159     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7160                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7161                                     r_nonce)
7162     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7163                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7164
7165     logger.debug("Send M2 to STA")
7166     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7167                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7168                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
7169     send_wsc_msg(dev[0], bssid, m2)
7170     eap_id = (eap_id + 1) % 256
7171
7172     logger.debug("Receive M3 from STA")
7173     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7174     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
7175
7176 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
7177     """WPS and NACK M3 missing Config Error"""
7178     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7179     logger.debug("Send NACK to STA")
7180     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
7181     send_wsc_msg(dev[0], bssid, msg)
7182     dev[0].request("WPS_CANCEL")
7183     dev[0].wait_disconnected()
7184     dev[0].flush_scan_cache()
7185
7186 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
7187     """WPS and NACK M3 missing E-Nonce"""
7188     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7189     logger.debug("Send NACK to STA")
7190     msg, attrs = build_nack(eap_id, None, r_nonce)
7191     send_wsc_msg(dev[0], bssid, msg)
7192     dev[0].request("WPS_CANCEL")
7193     dev[0].wait_disconnected()
7194     dev[0].flush_scan_cache()
7195
7196 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
7197     """WPS and NACK M3 E-Nonce mismatch"""
7198     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7199     logger.debug("Send NACK to STA")
7200     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
7201     send_wsc_msg(dev[0], bssid, msg)
7202     dev[0].request("WPS_CANCEL")
7203     dev[0].wait_disconnected()
7204     dev[0].flush_scan_cache()
7205
7206 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
7207     """WPS and NACK M3 missing R-Nonce"""
7208     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7209     logger.debug("Send NACK to STA")
7210     msg, attrs = build_nack(eap_id, e_nonce, None)
7211     send_wsc_msg(dev[0], bssid, msg)
7212     dev[0].request("WPS_CANCEL")
7213     dev[0].wait_disconnected()
7214     dev[0].flush_scan_cache()
7215
7216 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
7217     """WPS and NACK M3 R-Nonce mismatch"""
7218     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7219     logger.debug("Send NACK to STA")
7220     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
7221     send_wsc_msg(dev[0], bssid, msg)
7222     dev[0].request("WPS_CANCEL")
7223     dev[0].wait_disconnected()
7224     dev[0].flush_scan_cache()
7225
7226 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
7227     """WPS and NACK M3 no Message Type"""
7228     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7229     logger.debug("Send NACK to STA")
7230     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
7231     send_wsc_msg(dev[0], bssid, msg)
7232     dev[0].request("WPS_CANCEL")
7233     dev[0].wait_disconnected()
7234     dev[0].flush_scan_cache()
7235
7236 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
7237     """WPS and NACK M3 invalid Message Type"""
7238     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7239     logger.debug("Send NACK to STA")
7240     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
7241     send_wsc_msg(dev[0], bssid, msg)
7242     dev[0].request("WPS_CANCEL")
7243     dev[0].wait_disconnected()
7244     dev[0].flush_scan_cache()
7245
7246 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
7247     """WPS and NACK M3 invalid attribute"""
7248     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7249     logger.debug("Send NACK to STA")
7250     attrs = '\x10\x10\x00'
7251     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
7252     send_wsc_msg(dev[0], bssid, msg)
7253     dev[0].request("WPS_CANCEL")
7254     dev[0].wait_disconnected()
7255     dev[0].flush_scan_cache()
7256
7257 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
7258     """WPS and ACK M3 missing E-Nonce"""
7259     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7260     logger.debug("Send NACK to STA")
7261     msg, attrs = build_ack(eap_id, None, r_nonce)
7262     send_wsc_msg(dev[0], bssid, msg)
7263     dev[0].request("WPS_CANCEL")
7264     dev[0].wait_disconnected()
7265     dev[0].flush_scan_cache()
7266
7267 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7268     """WPS and ACK M3 E-Nonce mismatch"""
7269     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7270     logger.debug("Send NACK to STA")
7271     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7272     send_wsc_msg(dev[0], bssid, msg)
7273     dev[0].request("WPS_CANCEL")
7274     dev[0].wait_disconnected()
7275     dev[0].flush_scan_cache()
7276
7277 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7278     """WPS and ACK M3 missing R-Nonce"""
7279     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7280     logger.debug("Send NACK to STA")
7281     msg, attrs = build_ack(eap_id, e_nonce, None)
7282     send_wsc_msg(dev[0], bssid, msg)
7283     dev[0].request("WPS_CANCEL")
7284     dev[0].wait_disconnected()
7285     dev[0].flush_scan_cache()
7286
7287 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7288     """WPS and ACK M3 R-Nonce mismatch"""
7289     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7290     logger.debug("Send NACK to STA")
7291     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7292     send_wsc_msg(dev[0], bssid, msg)
7293     dev[0].request("WPS_CANCEL")
7294     dev[0].wait_disconnected()
7295     dev[0].flush_scan_cache()
7296
7297 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7298     """WPS and ACK M3 no Message Type"""
7299     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7300     logger.debug("Send NACK to STA")
7301     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7302     send_wsc_msg(dev[0], bssid, msg)
7303     dev[0].request("WPS_CANCEL")
7304     dev[0].wait_disconnected()
7305     dev[0].flush_scan_cache()
7306
7307 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7308     """WPS and ACK M3 invalid Message Type"""
7309     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7310     logger.debug("Send NACK to STA")
7311     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7312     send_wsc_msg(dev[0], bssid, msg)
7313     dev[0].request("WPS_CANCEL")
7314     dev[0].wait_disconnected()
7315     dev[0].flush_scan_cache()
7316
7317 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7318     """WPS and ACK M3 invalid attribute"""
7319     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7320     logger.debug("Send ACK to STA")
7321     attrs = '\x10\x10\x00'
7322     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7323     send_wsc_msg(dev[0], bssid, msg)
7324     dev[0].request("WPS_CANCEL")
7325     dev[0].wait_disconnected()
7326     dev[0].flush_scan_cache()
7327
7328 def test_wps_ext_proto_ack_m3(dev, apdev):
7329     """WPS and ACK M3"""
7330     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7331     logger.debug("Send ACK to STA")
7332     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7333     send_wsc_msg(dev[0], bssid, msg)
7334     dev[0].request("WPS_CANCEL")
7335     dev[0].wait_disconnected()
7336     dev[0].flush_scan_cache()
7337
7338 def wps_to_m3_helper(dev, apdev):
7339     pin = "12345670"
7340     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7341     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7342     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7343     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7344
7345     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7346     uuid_r = 16*'\x33'
7347     r_nonce = 16*'\x44'
7348     own_private, e_pk = wsc_dh_init()
7349
7350     logger.debug("Receive M1 from STA")
7351     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7352     eap_id = (msg['eap_identifier'] + 1) % 256
7353
7354     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7355                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7356                                     r_nonce)
7357     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7358                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7359
7360     logger.debug("Send M2 to STA")
7361     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7362                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7363                                 r_nonce, uuid_r, e_pk)
7364     send_wsc_msg(dev[0], bssid, m2)
7365     eap_id = (eap_id + 1) % 256
7366
7367     logger.debug("Receive M3 from STA")
7368     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7369     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7370
7371 def wps_to_m3(dev, apdev):
7372     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)
7373     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7374
7375 def wps_to_m5(dev, apdev):
7376     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)
7377
7378     logger.debug("Send M4 to STA")
7379     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7380     attrs += build_attr_msg_type(WPS_M4)
7381     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7382     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7383     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7384     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7385     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7386     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7387     raw_m4_attrs = attrs
7388     m4 = build_eap_wsc(1, eap_id, attrs)
7389     send_wsc_msg(dev[0], bssid, m4)
7390     eap_id = (eap_id + 1) % 256
7391
7392     logger.debug("Receive M5 from STA")
7393     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7394
7395     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7396
7397 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7398     """WPS and no R-Hash1 in M4"""
7399     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7400
7401     logger.debug("Send M4 to STA")
7402     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7403     attrs += build_attr_msg_type(WPS_M4)
7404     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7405     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7406     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7407     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7408     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7409     attrs += build_attr_authenticator(authkey, m3, attrs)
7410     m4 = build_eap_wsc(1, eap_id, attrs)
7411     send_wsc_msg(dev[0], bssid, m4)
7412     eap_id = (eap_id + 1) % 256
7413
7414     logger.debug("Receive M5 (NACK) from STA")
7415     msg = get_wsc_msg(dev[0])
7416     if msg['wsc_opcode'] != WSC_NACK:
7417         raise Exception("Unexpected message - expected WSC_Nack")
7418
7419     dev[0].request("WPS_CANCEL")
7420     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7421     dev[0].wait_disconnected()
7422
7423 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7424     """WPS and no R-Hash2 in M4"""
7425     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7426
7427     logger.debug("Send M4 to STA")
7428     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7429     attrs += build_attr_msg_type(WPS_M4)
7430     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7431     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7432     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7433     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7434     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7435     attrs += build_attr_authenticator(authkey, m3, attrs)
7436     m4 = build_eap_wsc(1, eap_id, attrs)
7437     send_wsc_msg(dev[0], bssid, m4)
7438     eap_id = (eap_id + 1) % 256
7439
7440     logger.debug("Receive M5 (NACK) from STA")
7441     msg = get_wsc_msg(dev[0])
7442     if msg['wsc_opcode'] != WSC_NACK:
7443         raise Exception("Unexpected message - expected WSC_Nack")
7444
7445     dev[0].request("WPS_CANCEL")
7446     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7447     dev[0].wait_disconnected()
7448
7449 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7450     """WPS and no R-SNonce1 in M4"""
7451     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7452
7453     logger.debug("Send M4 to STA")
7454     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7455     attrs += build_attr_msg_type(WPS_M4)
7456     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7457     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7458     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7459     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7460     data = ''
7461     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7462     attrs += build_attr_authenticator(authkey, m3, attrs)
7463     m4 = build_eap_wsc(1, eap_id, attrs)
7464     send_wsc_msg(dev[0], bssid, m4)
7465     eap_id = (eap_id + 1) % 256
7466
7467     logger.debug("Receive M5 (NACK) from STA")
7468     msg = get_wsc_msg(dev[0])
7469     if msg['wsc_opcode'] != WSC_NACK:
7470         raise Exception("Unexpected message - expected WSC_Nack")
7471
7472     dev[0].request("WPS_CANCEL")
7473     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7474     dev[0].wait_disconnected()
7475
7476 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7477     """WPS and invalid pad string in M4"""
7478     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7479
7480     logger.debug("Send M4 to STA")
7481     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7482     attrs += build_attr_msg_type(WPS_M4)
7483     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7484     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7485     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7486     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7487
7488     m = hmac.new(authkey, data, hashlib.sha256)
7489     kwa = m.digest()[0:8]
7490     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7491     iv = 16*'\x99'
7492     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7493     pad_len = 16 - len(data) % 16
7494     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7495     data += ps
7496     wrapped = aes.encrypt(data)
7497     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7498
7499     attrs += build_attr_authenticator(authkey, m3, attrs)
7500     m4 = build_eap_wsc(1, eap_id, attrs)
7501     send_wsc_msg(dev[0], bssid, m4)
7502     eap_id = (eap_id + 1) % 256
7503
7504     logger.debug("Receive M5 (NACK) from STA")
7505     msg = get_wsc_msg(dev[0])
7506     if msg['wsc_opcode'] != WSC_NACK:
7507         raise Exception("Unexpected message - expected WSC_Nack")
7508
7509     dev[0].request("WPS_CANCEL")
7510     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7511     dev[0].wait_disconnected()
7512
7513 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7514     """WPS and invalid pad value in M4"""
7515     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7516
7517     logger.debug("Send M4 to STA")
7518     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7519     attrs += build_attr_msg_type(WPS_M4)
7520     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7521     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7522     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7523     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7524
7525     m = hmac.new(authkey, data, hashlib.sha256)
7526     kwa = m.digest()[0:8]
7527     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7528     iv = 16*'\x99'
7529     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7530     pad_len = 16 - len(data) % 16
7531     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7532     data += ps
7533     wrapped = aes.encrypt(data)
7534     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7535
7536     attrs += build_attr_authenticator(authkey, m3, attrs)
7537     m4 = build_eap_wsc(1, eap_id, attrs)
7538     send_wsc_msg(dev[0], bssid, m4)
7539     eap_id = (eap_id + 1) % 256
7540
7541     logger.debug("Receive M5 (NACK) from STA")
7542     msg = get_wsc_msg(dev[0])
7543     if msg['wsc_opcode'] != WSC_NACK:
7544         raise Exception("Unexpected message - expected WSC_Nack")
7545
7546     dev[0].request("WPS_CANCEL")
7547     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7548     dev[0].wait_disconnected()
7549
7550 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7551     """WPS and no Encr Settings in M4"""
7552     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7553
7554     logger.debug("Send M4 to STA")
7555     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7556     attrs += build_attr_msg_type(WPS_M4)
7557     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7558     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7559     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7560     attrs += build_attr_authenticator(authkey, m3, attrs)
7561     m4 = build_eap_wsc(1, eap_id, attrs)
7562     send_wsc_msg(dev[0], bssid, m4)
7563     eap_id = (eap_id + 1) % 256
7564
7565     logger.debug("Receive M5 (NACK) from STA")
7566     msg = get_wsc_msg(dev[0])
7567     if msg['wsc_opcode'] != WSC_NACK:
7568         raise Exception("Unexpected message - expected WSC_Nack")
7569
7570     dev[0].request("WPS_CANCEL")
7571     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7572     dev[0].wait_disconnected()
7573
7574 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7575     """WPS and no R-SNonce2 in M6"""
7576     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7577
7578     logger.debug("Send M6 to STA")
7579     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7580     attrs += build_attr_msg_type(WPS_M6)
7581     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7582     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7583     data = ''
7584     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7585     attrs += build_attr_authenticator(authkey, m5, attrs)
7586     m6 = build_eap_wsc(1, eap_id, attrs)
7587     send_wsc_msg(dev[0], bssid, m6)
7588     eap_id = (eap_id + 1) % 256
7589
7590     logger.debug("Receive M7 (NACK) from STA")
7591     msg = get_wsc_msg(dev[0])
7592     if msg['wsc_opcode'] != WSC_NACK:
7593         raise Exception("Unexpected message - expected WSC_Nack")
7594
7595     dev[0].request("WPS_CANCEL")
7596     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7597     dev[0].wait_disconnected()
7598
7599 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7600     """WPS and no Encr Settings in M6"""
7601     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7602
7603     logger.debug("Send M6 to STA")
7604     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7605     attrs += build_attr_msg_type(WPS_M6)
7606     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7607     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7608     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7609     attrs += build_attr_authenticator(authkey, m5, attrs)
7610     m6 = build_eap_wsc(1, eap_id, attrs)
7611     send_wsc_msg(dev[0], bssid, m6)
7612     eap_id = (eap_id + 1) % 256
7613
7614     logger.debug("Receive M7 (NACK) from STA")
7615     msg = get_wsc_msg(dev[0])
7616     if msg['wsc_opcode'] != WSC_NACK:
7617         raise Exception("Unexpected message - expected WSC_Nack")
7618
7619     dev[0].request("WPS_CANCEL")
7620     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7621     dev[0].wait_disconnected()
7622
7623 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7624     """WPS and no Encr Settings in M6"""
7625     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7626
7627     logger.debug("Send M6 to STA")
7628     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7629     attrs += build_attr_msg_type(WPS_M6)
7630     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7631     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7632     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7633     attrs += build_attr_authenticator(authkey, m5, attrs)
7634     raw_m6_attrs = attrs
7635     m6 = build_eap_wsc(1, eap_id, attrs)
7636     send_wsc_msg(dev[0], bssid, m6)
7637     eap_id = (eap_id + 1) % 256
7638
7639     logger.debug("Receive M7 from STA")
7640     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7641
7642     logger.debug("Send M8 to STA")
7643     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7644     attrs += build_attr_msg_type(WPS_M8)
7645     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7646     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7647     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7648     raw_m8_attrs = attrs
7649     m8 = build_eap_wsc(1, eap_id, attrs)
7650     send_wsc_msg(dev[0], bssid, m8)
7651
7652     logger.debug("Receive WSC_Done (NACK) from STA")
7653     msg = get_wsc_msg(dev[0])
7654     if msg['wsc_opcode'] != WSC_NACK:
7655         raise Exception("Unexpected message - expected WSC_Nack")
7656
7657     dev[0].request("WPS_CANCEL")
7658     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7659     dev[0].wait_disconnected()
7660
7661 def wps_start_ext_reg(apdev, dev):
7662     addr = dev.own_addr()
7663     bssid = apdev['bssid']
7664     ssid = "test-wps-conf"
7665     appin = "12345670"
7666     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7667                "wpa_passphrase": "12345678", "wpa": "2",
7668                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7669                "ap_pin": appin }
7670     hapd = hostapd.add_ap(apdev, params)
7671
7672     dev.scan_for_bss(bssid, freq="2412")
7673     hapd.request("SET ext_eapol_frame_io 1")
7674     dev.request("SET ext_eapol_frame_io 1")
7675
7676     dev.request("WPS_REG " + bssid + " " + appin)
7677
7678     return addr,bssid,hapd
7679
7680 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7681     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7682     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7683     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7684
7685     logger.debug("Receive M1 from AP")
7686     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7687     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7688     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7689     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7690
7691     appin = '12345670'
7692     uuid_r = 16*'\x33'
7693     r_nonce = 16*'\x44'
7694     own_private, r_pk = wsc_dh_init()
7695     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7696                                     r_nonce)
7697     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7698
7699     logger.debug("Send M2 to AP")
7700     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7701                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7702     send_wsc_msg(hapd, addr, m2)
7703
7704     logger.debug("Receive M3 from AP")
7705     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7706
7707     logger.debug("Send M4 to AP")
7708     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7709     attrs += build_attr_msg_type(WPS_M4)
7710     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7711     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7712     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7713     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7714     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7715     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7716     raw_m4_attrs = attrs
7717     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7718     send_wsc_msg(hapd, addr, m4)
7719
7720     logger.debug("Receive M5 from AP")
7721     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7722
7723     logger.debug("Send M6 to STA")
7724     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7725     attrs += build_attr_msg_type(WPS_M6)
7726     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7727     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7728     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7729     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7730     raw_m6_attrs = attrs
7731     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7732     send_wsc_msg(hapd, addr, m6)
7733
7734     logger.debug("Receive M7 from AP")
7735     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7736
7737     logger.debug("Send M8 to STA")
7738     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7739     attrs += build_attr_msg_type(WPS_M8)
7740     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7741     if ap_settings:
7742         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7743     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7744     raw_m8_attrs = attrs
7745     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7746     send_wsc_msg(hapd, addr, m8)
7747
7748     if success:
7749         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7750         if ev is None:
7751             raise Exception("New AP settings not reported")
7752         logger.debug("Receive WSC_Done from AP")
7753         msg = get_wsc_msg(hapd)
7754         if msg['wsc_opcode'] != WSC_Done:
7755             raise Exception("Unexpected message - expected WSC_Done")
7756
7757         logger.debug("Send WSC_ACK to AP")
7758         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7759                               eap_code=2)
7760         send_wsc_msg(hapd, addr, ack)
7761         dev[0].wait_disconnected()
7762     else:
7763         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7764         if ev is None:
7765             raise Exception("WPS failure not reported")
7766         logger.debug("Receive WSC_NACK from AP")
7767         msg = get_wsc_msg(hapd)
7768         if msg['wsc_opcode'] != WSC_NACK:
7769             raise Exception("Unexpected message - expected WSC_NACK")
7770
7771         logger.debug("Send WSC_NACK to AP")
7772         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7773                                 eap_code=2)
7774         send_wsc_msg(hapd, addr, nack)
7775         dev[0].wait_disconnected()
7776
7777 def test_wps_ext_ap_settings_success(dev, apdev):
7778     """WPS and AP Settings: success"""
7779     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7780     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7781     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7782     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7783     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7784     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7785     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7786
7787 @remote_compatible
7788 def test_wps_ext_ap_settings_missing(dev, apdev):
7789     """WPS and AP Settings: missing"""
7790     wps_run_ap_settings_proto(dev, apdev, None, False)
7791
7792 @remote_compatible
7793 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7794     """WPS and AP Settings: MAC Address mismatch"""
7795     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7796     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7797     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7798     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7799     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7800     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7801     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7802
7803 @remote_compatible
7804 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7805     """WPS and AP Settings: missing MAC Address"""
7806     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7807     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7808     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7809     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7810     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7811     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7812
7813 @remote_compatible
7814 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7815     """WPS and AP Settings: reject Encr Type"""
7816     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7817     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7818     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7819     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7820     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7821     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7822     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7823
7824 @remote_compatible
7825 def test_wps_ext_ap_settings_m2d(dev, apdev):
7826     """WPS and AP Settings: M2D"""
7827     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7828     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7829     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7830
7831     logger.debug("Receive M1 from AP")
7832     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7833     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7834
7835     r_nonce = 16*'\x44'
7836     uuid_r = 16*'\x33'
7837
7838     logger.debug("Send M2D to AP")
7839     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7840                                    e_nonce, r_nonce, uuid_r,
7841                                    dev_pw_id='\x00\x00', eap_code=2)
7842     send_wsc_msg(hapd, addr, m2d)
7843
7844     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7845     if ev is None:
7846         raise Exception("M2D not reported")
7847
7848     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7849
7850 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7851     logger.debug("Receive WSC_NACK from AP")
7852     msg = get_wsc_msg(hapd)
7853     if msg['wsc_opcode'] != WSC_NACK:
7854         raise Exception("Unexpected message - expected WSC_NACK")
7855
7856     logger.debug("Send WSC_NACK to AP")
7857     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7858                             eap_code=2)
7859     send_wsc_msg(hapd, dev.own_addr(), nack)
7860     dev.wait_disconnected()
7861
7862 @remote_compatible
7863 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7864     """WPS proto: M3 missing E-Hash1"""
7865     pin = "12345670"
7866     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7867     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7868     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7869
7870     logger.debug("Receive WSC/Start from AP")
7871     msg = get_wsc_msg(hapd)
7872     if msg['wsc_opcode'] != WSC_Start:
7873         raise Exception("Unexpected Op-Code for WSC/Start")
7874
7875     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7876     uuid_e = 16*'\x11'
7877     e_nonce = 16*'\x22'
7878     own_private, e_pk = wsc_dh_init()
7879
7880     logger.debug("Send M1 to AP")
7881     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7882                                 e_nonce, e_pk)
7883     send_wsc_msg(hapd, addr, m1)
7884
7885     logger.debug("Receive M2 from AP")
7886     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7887     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7888     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7889
7890     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7891                                     r_nonce)
7892     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7893
7894     logger.debug("Send M3 to AP")
7895     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7896     attrs += build_attr_msg_type(WPS_M3)
7897     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7898     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7899     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7900     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7901     raw_m3_attrs = attrs
7902     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7903     send_wsc_msg(hapd, addr, m3)
7904
7905     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7906
7907 @remote_compatible
7908 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7909     """WPS proto: M3 missing E-Hash2"""
7910     pin = "12345670"
7911     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7912     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7913     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7914
7915     logger.debug("Receive WSC/Start from AP")
7916     msg = get_wsc_msg(hapd)
7917     if msg['wsc_opcode'] != WSC_Start:
7918         raise Exception("Unexpected Op-Code for WSC/Start")
7919
7920     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7921     uuid_e = 16*'\x11'
7922     e_nonce = 16*'\x22'
7923     own_private, e_pk = wsc_dh_init()
7924
7925     logger.debug("Send M1 to AP")
7926     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7927                                 e_nonce, e_pk)
7928     send_wsc_msg(hapd, addr, m1)
7929
7930     logger.debug("Receive M2 from AP")
7931     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7932     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7933     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7934
7935     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7936                                     r_nonce)
7937     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7938
7939     logger.debug("Send M3 to AP")
7940     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7941     attrs += build_attr_msg_type(WPS_M3)
7942     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7943     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7944     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7945     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7946     raw_m3_attrs = attrs
7947     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7948     send_wsc_msg(hapd, addr, m3)
7949
7950     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7951
7952 @remote_compatible
7953 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7954     """WPS proto: M5 missing E-SNonce1"""
7955     pin = "12345670"
7956     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7957     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7958     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7959
7960     logger.debug("Receive WSC/Start from AP")
7961     msg = get_wsc_msg(hapd)
7962     if msg['wsc_opcode'] != WSC_Start:
7963         raise Exception("Unexpected Op-Code for WSC/Start")
7964
7965     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7966     uuid_e = 16*'\x11'
7967     e_nonce = 16*'\x22'
7968     own_private, e_pk = wsc_dh_init()
7969
7970     logger.debug("Send M1 to AP")
7971     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7972                                 e_nonce, e_pk)
7973     send_wsc_msg(hapd, addr, m1)
7974
7975     logger.debug("Receive M2 from AP")
7976     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7977     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7978     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7979
7980     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7981                                     r_nonce)
7982     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7983
7984     logger.debug("Send M3 to AP")
7985     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7986     attrs += build_attr_msg_type(WPS_M3)
7987     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7988     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7989     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7990     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7991     raw_m3_attrs = attrs
7992     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7993     send_wsc_msg(hapd, addr, m3)
7994
7995     logger.debug("Receive M4 from AP")
7996     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7997
7998     logger.debug("Send M5 to AP")
7999     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8000     attrs += build_attr_msg_type(WPS_M5)
8001     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8002     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8003     data = ''
8004     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8005     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8006     raw_m5_attrs = attrs
8007     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8008     send_wsc_msg(hapd, addr, m5)
8009
8010     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8011
8012 @remote_compatible
8013 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
8014     """WPS proto: M5 E-SNonce1 mismatch"""
8015     pin = "12345670"
8016     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8017     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8018     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8019
8020     logger.debug("Receive WSC/Start from AP")
8021     msg = get_wsc_msg(hapd)
8022     if msg['wsc_opcode'] != WSC_Start:
8023         raise Exception("Unexpected Op-Code for WSC/Start")
8024
8025     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8026     uuid_e = 16*'\x11'
8027     e_nonce = 16*'\x22'
8028     own_private, e_pk = wsc_dh_init()
8029
8030     logger.debug("Send M1 to AP")
8031     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8032                                 e_nonce, e_pk)
8033     send_wsc_msg(hapd, addr, m1)
8034
8035     logger.debug("Receive M2 from AP")
8036     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8037     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8038     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8039
8040     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8041                                     r_nonce)
8042     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8043
8044     logger.debug("Send M3 to AP")
8045     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8046     attrs += build_attr_msg_type(WPS_M3)
8047     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8048     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8049     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8050     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8051     raw_m3_attrs = attrs
8052     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8053     send_wsc_msg(hapd, addr, m3)
8054
8055     logger.debug("Receive M4 from AP")
8056     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8057
8058     logger.debug("Send M5 to AP")
8059     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8060     attrs += build_attr_msg_type(WPS_M5)
8061     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8062     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
8063     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8064     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8065     raw_m5_attrs = attrs
8066     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8067     send_wsc_msg(hapd, addr, m5)
8068
8069     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8070
8071 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
8072     """WPS proto: M7 missing E-SNonce2"""
8073     pin = "12345670"
8074     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8075     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8076     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8077
8078     logger.debug("Receive WSC/Start from AP")
8079     msg = get_wsc_msg(hapd)
8080     if msg['wsc_opcode'] != WSC_Start:
8081         raise Exception("Unexpected Op-Code for WSC/Start")
8082
8083     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8084     uuid_e = 16*'\x11'
8085     e_nonce = 16*'\x22'
8086     own_private, e_pk = wsc_dh_init()
8087
8088     logger.debug("Send M1 to AP")
8089     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8090                                 e_nonce, e_pk)
8091     send_wsc_msg(hapd, addr, m1)
8092
8093     logger.debug("Receive M2 from AP")
8094     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8095     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8096     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8097
8098     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8099                                     r_nonce)
8100     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8101
8102     logger.debug("Send M3 to AP")
8103     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8104     attrs += build_attr_msg_type(WPS_M3)
8105     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8106     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8107     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8108     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8109     raw_m3_attrs = attrs
8110     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8111     send_wsc_msg(hapd, addr, m3)
8112
8113     logger.debug("Receive M4 from AP")
8114     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8115
8116     logger.debug("Send M5 to AP")
8117     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8118     attrs += build_attr_msg_type(WPS_M5)
8119     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8120     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8121     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8122     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8123     raw_m5_attrs = attrs
8124     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8125     send_wsc_msg(hapd, addr, m5)
8126
8127     logger.debug("Receive M6 from AP")
8128     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8129
8130     logger.debug("Send M7 to AP")
8131     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8132     attrs += build_attr_msg_type(WPS_M7)
8133     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8134     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8135     data = ''
8136     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8137     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8138     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8139     raw_m7_attrs = attrs
8140     send_wsc_msg(hapd, addr, m7)
8141
8142     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8143
8144 @remote_compatible
8145 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
8146     """WPS proto: M7 E-SNonce2 mismatch"""
8147     pin = "12345670"
8148     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8149     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8150     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8151
8152     logger.debug("Receive WSC/Start from AP")
8153     msg = get_wsc_msg(hapd)
8154     if msg['wsc_opcode'] != WSC_Start:
8155         raise Exception("Unexpected Op-Code for WSC/Start")
8156
8157     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8158     uuid_e = 16*'\x11'
8159     e_nonce = 16*'\x22'
8160     own_private, e_pk = wsc_dh_init()
8161
8162     logger.debug("Send M1 to AP")
8163     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8164                                 e_nonce, e_pk)
8165     send_wsc_msg(hapd, addr, m1)
8166
8167     logger.debug("Receive M2 from AP")
8168     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8169     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8170     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8171
8172     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8173                                     r_nonce)
8174     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8175
8176     logger.debug("Send M3 to AP")
8177     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8178     attrs += build_attr_msg_type(WPS_M3)
8179     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8180     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8181     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8182     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8183     raw_m3_attrs = attrs
8184     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8185     send_wsc_msg(hapd, addr, m3)
8186
8187     logger.debug("Receive M4 from AP")
8188     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8189
8190     logger.debug("Send M5 to AP")
8191     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8192     attrs += build_attr_msg_type(WPS_M5)
8193     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8194     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8195     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8196     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8197     raw_m5_attrs = attrs
8198     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8199     send_wsc_msg(hapd, addr, m5)
8200
8201     logger.debug("Receive M6 from AP")
8202     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8203
8204     logger.debug("Send M7 to AP")
8205     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8206     attrs += build_attr_msg_type(WPS_M7)
8207     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8208     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
8209     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8210     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8211     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8212     raw_m7_attrs = attrs
8213     send_wsc_msg(hapd, addr, m7)
8214
8215     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8216
8217 @remote_compatible
8218 def test_wps_ext_m1_pubkey_oom(dev, apdev):
8219     """WPS proto: M1 PubKey OOM"""
8220     pin = "12345670"
8221     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8222     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8223     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8224
8225     logger.debug("Receive WSC/Start from AP")
8226     msg = get_wsc_msg(hapd)
8227     if msg['wsc_opcode'] != WSC_Start:
8228         raise Exception("Unexpected Op-Code for WSC/Start")
8229
8230     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8231     uuid_e = 16*'\x11'
8232     e_nonce = 16*'\x22'
8233     own_private, e_pk = wsc_dh_init()
8234
8235     logger.debug("Send M1 to AP")
8236     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
8237         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8238                                     e_nonce, e_pk)
8239         send_wsc_msg(hapd, addr, m1)
8240         wps_wait_eap_failure(hapd, dev[0])
8241
8242 def wps_wait_eap_failure(hapd, dev):
8243     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8244     if ev is None:
8245         raise Exception("EAP-Failure not reported")
8246     dev.wait_disconnected()
8247
8248 @remote_compatible
8249 def test_wps_ext_m3_m1(dev, apdev):
8250     """WPS proto: M3 replaced with M1"""
8251     pin = "12345670"
8252     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8253     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8254     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8255
8256     logger.debug("Receive WSC/Start from AP")
8257     msg = get_wsc_msg(hapd)
8258     if msg['wsc_opcode'] != WSC_Start:
8259         raise Exception("Unexpected Op-Code for WSC/Start")
8260
8261     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8262     uuid_e = 16*'\x11'
8263     e_nonce = 16*'\x22'
8264     own_private, e_pk = wsc_dh_init()
8265
8266     logger.debug("Send M1 to AP")
8267     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8268                                 e_nonce, e_pk)
8269     send_wsc_msg(hapd, addr, m1)
8270
8271     logger.debug("Receive M2 from AP")
8272     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8273     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8274     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8275
8276     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8277                                     r_nonce)
8278     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8279
8280     logger.debug("Send M3(M1) to AP")
8281     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8282     attrs += build_attr_msg_type(WPS_M1)
8283     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8284     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8285     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8286     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8287     raw_m3_attrs = attrs
8288     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8289     send_wsc_msg(hapd, addr, m3)
8290
8291     wps_wait_eap_failure(hapd, dev[0])
8292
8293 @remote_compatible
8294 def test_wps_ext_m5_m3(dev, apdev):
8295     """WPS proto: M5 replaced with M3"""
8296     pin = "12345670"
8297     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8298     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8299     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8300
8301     logger.debug("Receive WSC/Start from AP")
8302     msg = get_wsc_msg(hapd)
8303     if msg['wsc_opcode'] != WSC_Start:
8304         raise Exception("Unexpected Op-Code for WSC/Start")
8305
8306     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8307     uuid_e = 16*'\x11'
8308     e_nonce = 16*'\x22'
8309     own_private, e_pk = wsc_dh_init()
8310
8311     logger.debug("Send M1 to AP")
8312     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8313                                 e_nonce, e_pk)
8314     send_wsc_msg(hapd, addr, m1)
8315
8316     logger.debug("Receive M2 from AP")
8317     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8318     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8319     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8320
8321     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8322                                     r_nonce)
8323     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8324
8325     logger.debug("Send M3 to AP")
8326     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8327     attrs += build_attr_msg_type(WPS_M3)
8328     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8329     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8330     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8331     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8332     raw_m3_attrs = attrs
8333     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8334     send_wsc_msg(hapd, addr, m3)
8335
8336     logger.debug("Receive M4 from AP")
8337     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8338
8339     logger.debug("Send M5(M3) to AP")
8340     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8341     attrs += build_attr_msg_type(WPS_M3)
8342     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8343     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8344     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8345     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8346     raw_m5_attrs = attrs
8347     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8348     send_wsc_msg(hapd, addr, m5)
8349
8350     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8351
8352 @remote_compatible
8353 def test_wps_ext_m3_m2(dev, apdev):
8354     """WPS proto: M3 replaced with M2"""
8355     pin = "12345670"
8356     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8357     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8358     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8359
8360     logger.debug("Receive WSC/Start from AP")
8361     msg = get_wsc_msg(hapd)
8362     if msg['wsc_opcode'] != WSC_Start:
8363         raise Exception("Unexpected Op-Code for WSC/Start")
8364
8365     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8366     uuid_e = 16*'\x11'
8367     e_nonce = 16*'\x22'
8368     own_private, e_pk = wsc_dh_init()
8369
8370     logger.debug("Send M1 to AP")
8371     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8372                                 e_nonce, e_pk)
8373     send_wsc_msg(hapd, addr, m1)
8374
8375     logger.debug("Receive M2 from AP")
8376     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8377     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8378     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8379
8380     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8381                                     r_nonce)
8382     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8383
8384     logger.debug("Send M3(M2) to AP")
8385     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8386     attrs += build_attr_msg_type(WPS_M2)
8387     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8388     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8389     raw_m3_attrs = attrs
8390     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8391     send_wsc_msg(hapd, addr, m3)
8392
8393     wps_wait_eap_failure(hapd, dev[0])
8394
8395 @remote_compatible
8396 def test_wps_ext_m3_m5(dev, apdev):
8397     """WPS proto: M3 replaced with M5"""
8398     pin = "12345670"
8399     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8400     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8401     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8402
8403     logger.debug("Receive WSC/Start from AP")
8404     msg = get_wsc_msg(hapd)
8405     if msg['wsc_opcode'] != WSC_Start:
8406         raise Exception("Unexpected Op-Code for WSC/Start")
8407
8408     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8409     uuid_e = 16*'\x11'
8410     e_nonce = 16*'\x22'
8411     own_private, e_pk = wsc_dh_init()
8412
8413     logger.debug("Send M1 to AP")
8414     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8415                                 e_nonce, e_pk)
8416     send_wsc_msg(hapd, addr, m1)
8417
8418     logger.debug("Receive M2 from AP")
8419     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8420     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8421     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8422
8423     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8424                                     r_nonce)
8425     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8426
8427     logger.debug("Send M3(M5) to AP")
8428     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8429     attrs += build_attr_msg_type(WPS_M5)
8430     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8431     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8432     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8433     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8434     raw_m3_attrs = attrs
8435     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8436     send_wsc_msg(hapd, addr, m3)
8437
8438     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8439
8440 @remote_compatible
8441 def test_wps_ext_m3_m7(dev, apdev):
8442     """WPS proto: M3 replaced with M7"""
8443     pin = "12345670"
8444     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8445     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8446     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8447
8448     logger.debug("Receive WSC/Start from AP")
8449     msg = get_wsc_msg(hapd)
8450     if msg['wsc_opcode'] != WSC_Start:
8451         raise Exception("Unexpected Op-Code for WSC/Start")
8452
8453     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8454     uuid_e = 16*'\x11'
8455     e_nonce = 16*'\x22'
8456     own_private, e_pk = wsc_dh_init()
8457
8458     logger.debug("Send M1 to AP")
8459     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8460                                 e_nonce, e_pk)
8461     send_wsc_msg(hapd, addr, m1)
8462
8463     logger.debug("Receive M2 from AP")
8464     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8465     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8466     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8467
8468     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8469                                     r_nonce)
8470     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8471
8472     logger.debug("Send M3(M7) to AP")
8473     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8474     attrs += build_attr_msg_type(WPS_M7)
8475     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8476     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8477     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8478     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8479     raw_m3_attrs = attrs
8480     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8481     send_wsc_msg(hapd, addr, m3)
8482
8483     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8484
8485 @remote_compatible
8486 def test_wps_ext_m3_done(dev, apdev):
8487     """WPS proto: M3 replaced with WSC_Done"""
8488     pin = "12345670"
8489     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8490     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8491     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8492
8493     logger.debug("Receive WSC/Start from AP")
8494     msg = get_wsc_msg(hapd)
8495     if msg['wsc_opcode'] != WSC_Start:
8496         raise Exception("Unexpected Op-Code for WSC/Start")
8497
8498     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8499     uuid_e = 16*'\x11'
8500     e_nonce = 16*'\x22'
8501     own_private, e_pk = wsc_dh_init()
8502
8503     logger.debug("Send M1 to AP")
8504     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8505                                 e_nonce, e_pk)
8506     send_wsc_msg(hapd, addr, m1)
8507
8508     logger.debug("Receive M2 from AP")
8509     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8510     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8511     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8512
8513     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8514                                     r_nonce)
8515     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8516
8517     logger.debug("Send M3(WSC_Done) to AP")
8518     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8519     attrs += build_attr_msg_type(WPS_WSC_DONE)
8520     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8521     raw_m3_attrs = attrs
8522     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8523     send_wsc_msg(hapd, addr, m3)
8524
8525     wps_wait_eap_failure(hapd, dev[0])
8526
8527 @remote_compatible
8528 def test_wps_ext_m2_nack_invalid(dev, apdev):
8529     """WPS proto: M2 followed by invalid NACK"""
8530     pin = "12345670"
8531     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8532     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8533     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8534
8535     logger.debug("Receive WSC/Start from AP")
8536     msg = get_wsc_msg(hapd)
8537     if msg['wsc_opcode'] != WSC_Start:
8538         raise Exception("Unexpected Op-Code for WSC/Start")
8539
8540     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8541     uuid_e = 16*'\x11'
8542     e_nonce = 16*'\x22'
8543     own_private, e_pk = wsc_dh_init()
8544
8545     logger.debug("Send M1 to AP")
8546     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8547                                 e_nonce, e_pk)
8548     send_wsc_msg(hapd, addr, m1)
8549
8550     logger.debug("Receive M2 from AP")
8551     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8552     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8553     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8554
8555     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8556                                     r_nonce)
8557     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8558
8559     logger.debug("Send WSC_NACK to AP")
8560     attrs = '\x10\x00\x00'
8561     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8562     send_wsc_msg(hapd, addr, nack)
8563
8564     wps_wait_eap_failure(hapd, dev[0])
8565
8566 @remote_compatible
8567 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8568     """WPS proto: M2 followed by NACK without Msg Type"""
8569     pin = "12345670"
8570     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8571     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8572     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8573
8574     logger.debug("Receive WSC/Start from AP")
8575     msg = get_wsc_msg(hapd)
8576     if msg['wsc_opcode'] != WSC_Start:
8577         raise Exception("Unexpected Op-Code for WSC/Start")
8578
8579     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8580     uuid_e = 16*'\x11'
8581     e_nonce = 16*'\x22'
8582     own_private, e_pk = wsc_dh_init()
8583
8584     logger.debug("Send M1 to AP")
8585     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8586                                 e_nonce, e_pk)
8587     send_wsc_msg(hapd, addr, m1)
8588
8589     logger.debug("Receive M2 from AP")
8590     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8591     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8592     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8593
8594     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8595                                     r_nonce)
8596     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8597
8598     logger.debug("Send WSC_NACK to AP")
8599     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8600                             msg_type=None, eap_code=2)
8601     send_wsc_msg(hapd, addr, nack)
8602
8603     wps_wait_eap_failure(hapd, dev[0])
8604
8605 @remote_compatible
8606 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8607     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8608     pin = "12345670"
8609     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8610     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8611     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8612
8613     logger.debug("Receive WSC/Start from AP")
8614     msg = get_wsc_msg(hapd)
8615     if msg['wsc_opcode'] != WSC_Start:
8616         raise Exception("Unexpected Op-Code for WSC/Start")
8617
8618     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8619     uuid_e = 16*'\x11'
8620     e_nonce = 16*'\x22'
8621     own_private, e_pk = wsc_dh_init()
8622
8623     logger.debug("Send M1 to AP")
8624     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8625                                 e_nonce, e_pk)
8626     send_wsc_msg(hapd, addr, m1)
8627
8628     logger.debug("Receive M2 from AP")
8629     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8630     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8631     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8632
8633     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8634                                     r_nonce)
8635     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8636
8637     logger.debug("Send WSC_NACK to AP")
8638     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8639                             msg_type=WPS_WSC_ACK, eap_code=2)
8640     send_wsc_msg(hapd, addr, nack)
8641
8642     wps_wait_eap_failure(hapd, dev[0])
8643
8644 @remote_compatible
8645 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8646     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8647     pin = "12345670"
8648     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8649     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8650     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8651
8652     logger.debug("Receive WSC/Start from AP")
8653     msg = get_wsc_msg(hapd)
8654     if msg['wsc_opcode'] != WSC_Start:
8655         raise Exception("Unexpected Op-Code for WSC/Start")
8656
8657     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8658     uuid_e = 16*'\x11'
8659     e_nonce = 16*'\x22'
8660     own_private, e_pk = wsc_dh_init()
8661
8662     logger.debug("Send M1 to AP")
8663     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8664                                 e_nonce, e_pk)
8665     send_wsc_msg(hapd, addr, m1)
8666
8667     logger.debug("Receive M2 from AP")
8668     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8669     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8670     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8671
8672     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8673                                     r_nonce)
8674     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8675
8676     logger.debug("Send WSC_NACK to AP")
8677     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8678                             eap_code=2)
8679     send_wsc_msg(hapd, addr, nack)
8680
8681     wps_wait_eap_failure(hapd, dev[0])
8682
8683 @remote_compatible
8684 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8685     """WPS proto: M2 followed by NACK without Config Error"""
8686     pin = "12345670"
8687     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8688     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8689     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8690
8691     logger.debug("Receive WSC/Start from AP")
8692     msg = get_wsc_msg(hapd)
8693     if msg['wsc_opcode'] != WSC_Start:
8694         raise Exception("Unexpected Op-Code for WSC/Start")
8695
8696     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8697     uuid_e = 16*'\x11'
8698     e_nonce = 16*'\x22'
8699     own_private, e_pk = wsc_dh_init()
8700
8701     logger.debug("Send M1 to AP")
8702     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8703                                 e_nonce, e_pk)
8704     send_wsc_msg(hapd, addr, m1)
8705
8706     logger.debug("Receive M2 from AP")
8707     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8708     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8709     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8710
8711     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8712                                     r_nonce)
8713     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8714
8715     logger.debug("Send WSC_NACK to AP")
8716     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8717                             config_error=None, eap_code=2)
8718     send_wsc_msg(hapd, addr, nack)
8719
8720     wps_wait_eap_failure(hapd, dev[0])
8721
8722 @remote_compatible
8723 def test_wps_ext_m2_ack_invalid(dev, apdev):
8724     """WPS proto: M2 followed by invalid ACK"""
8725     pin = "12345670"
8726     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8727     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8728     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8729
8730     logger.debug("Receive WSC/Start from AP")
8731     msg = get_wsc_msg(hapd)
8732     if msg['wsc_opcode'] != WSC_Start:
8733         raise Exception("Unexpected Op-Code for WSC/Start")
8734
8735     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8736     uuid_e = 16*'\x11'
8737     e_nonce = 16*'\x22'
8738     own_private, e_pk = wsc_dh_init()
8739
8740     logger.debug("Send M1 to AP")
8741     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8742                                 e_nonce, e_pk)
8743     send_wsc_msg(hapd, addr, m1)
8744
8745     logger.debug("Receive M2 from AP")
8746     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8747     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8748     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8749
8750     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8751                                     r_nonce)
8752     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8753
8754     logger.debug("Send WSC_ACK to AP")
8755     attrs = '\x10\x00\x00'
8756     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8757     send_wsc_msg(hapd, addr, ack)
8758
8759     wps_wait_eap_failure(hapd, dev[0])
8760
8761 @remote_compatible
8762 def test_wps_ext_m2_ack(dev, apdev):
8763     """WPS proto: M2 followed by ACK"""
8764     pin = "12345670"
8765     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8766     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8767     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8768
8769     logger.debug("Receive WSC/Start from AP")
8770     msg = get_wsc_msg(hapd)
8771     if msg['wsc_opcode'] != WSC_Start:
8772         raise Exception("Unexpected Op-Code for WSC/Start")
8773
8774     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8775     uuid_e = 16*'\x11'
8776     e_nonce = 16*'\x22'
8777     own_private, e_pk = wsc_dh_init()
8778
8779     logger.debug("Send M1 to AP")
8780     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8781                                 e_nonce, e_pk)
8782     send_wsc_msg(hapd, addr, m1)
8783
8784     logger.debug("Receive M2 from AP")
8785     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8786     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8787     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8788
8789     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8790                                     r_nonce)
8791     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8792
8793     logger.debug("Send WSC_ACK to AP")
8794     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8795     send_wsc_msg(hapd, addr, ack)
8796
8797     wps_wait_eap_failure(hapd, dev[0])
8798
8799 @remote_compatible
8800 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8801     """WPS proto: M2 followed by ACK missing Msg Type"""
8802     pin = "12345670"
8803     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8804     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8805     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8806
8807     logger.debug("Receive WSC/Start from AP")
8808     msg = get_wsc_msg(hapd)
8809     if msg['wsc_opcode'] != WSC_Start:
8810         raise Exception("Unexpected Op-Code for WSC/Start")
8811
8812     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8813     uuid_e = 16*'\x11'
8814     e_nonce = 16*'\x22'
8815     own_private, e_pk = wsc_dh_init()
8816
8817     logger.debug("Send M1 to AP")
8818     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8819                                 e_nonce, e_pk)
8820     send_wsc_msg(hapd, addr, m1)
8821
8822     logger.debug("Receive M2 from AP")
8823     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8824     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8825     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8826
8827     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8828                                     r_nonce)
8829     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8830
8831     logger.debug("Send WSC_ACK to AP")
8832     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8833                           msg_type=None, eap_code=2)
8834     send_wsc_msg(hapd, addr, ack)
8835
8836     wps_wait_eap_failure(hapd, dev[0])
8837
8838 @remote_compatible
8839 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8840     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8841     pin = "12345670"
8842     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8843     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8844     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8845
8846     logger.debug("Receive WSC/Start from AP")
8847     msg = get_wsc_msg(hapd)
8848     if msg['wsc_opcode'] != WSC_Start:
8849         raise Exception("Unexpected Op-Code for WSC/Start")
8850
8851     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8852     uuid_e = 16*'\x11'
8853     e_nonce = 16*'\x22'
8854     own_private, e_pk = wsc_dh_init()
8855
8856     logger.debug("Send M1 to AP")
8857     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8858                                 e_nonce, e_pk)
8859     send_wsc_msg(hapd, addr, m1)
8860
8861     logger.debug("Receive M2 from AP")
8862     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8863     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8864     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8865
8866     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8867                                     r_nonce)
8868     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8869
8870     logger.debug("Send WSC_ACK to AP")
8871     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8872                           msg_type=WPS_WSC_NACK, eap_code=2)
8873     send_wsc_msg(hapd, addr, ack)
8874
8875     wps_wait_eap_failure(hapd, dev[0])
8876
8877 @remote_compatible
8878 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8879     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8880     pin = "12345670"
8881     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8882     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8883     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8884
8885     logger.debug("Receive WSC/Start from AP")
8886     msg = get_wsc_msg(hapd)
8887     if msg['wsc_opcode'] != WSC_Start:
8888         raise Exception("Unexpected Op-Code for WSC/Start")
8889
8890     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8891     uuid_e = 16*'\x11'
8892     e_nonce = 16*'\x22'
8893     own_private, e_pk = wsc_dh_init()
8894
8895     logger.debug("Send M1 to AP")
8896     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8897                                 e_nonce, e_pk)
8898     send_wsc_msg(hapd, addr, m1)
8899
8900     logger.debug("Receive M2 from AP")
8901     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8902     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8903     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8904
8905     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8906                                     r_nonce)
8907     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8908
8909     logger.debug("Send WSC_ACK to AP")
8910     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8911                           eap_code=2)
8912     send_wsc_msg(hapd, addr, ack)
8913
8914     wps_wait_eap_failure(hapd, dev[0])
8915
8916 @remote_compatible
8917 def test_wps_ext_m1_invalid(dev, apdev):
8918     """WPS proto: M1 failing parsing"""
8919     pin = "12345670"
8920     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8921     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8922     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8923
8924     logger.debug("Receive WSC/Start from AP")
8925     msg = get_wsc_msg(hapd)
8926     if msg['wsc_opcode'] != WSC_Start:
8927         raise Exception("Unexpected Op-Code for WSC/Start")
8928
8929     logger.debug("Send M1 to AP")
8930     attrs = '\x10\x00\x00'
8931     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8932     send_wsc_msg(hapd, addr, m1)
8933
8934     wps_wait_eap_failure(hapd, dev[0])
8935
8936 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8937     """WPS proto: M1 missing Msg Type"""
8938     pin = "12345670"
8939     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8940     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8941     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8942
8943     logger.debug("Receive WSC/Start from AP")
8944     msg = get_wsc_msg(hapd)
8945     if msg['wsc_opcode'] != WSC_Start:
8946         raise Exception("Unexpected Op-Code for WSC/Start")
8947
8948     logger.debug("Send M1 to AP")
8949     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8950     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8951     send_wsc_msg(hapd, addr, m1)
8952
8953     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8954
8955 def wps_ext_wsc_done(dev, apdev):
8956     pin = "12345670"
8957     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8958     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8959     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8960
8961     logger.debug("Receive WSC/Start from AP")
8962     msg = get_wsc_msg(hapd)
8963     if msg['wsc_opcode'] != WSC_Start:
8964         raise Exception("Unexpected Op-Code for WSC/Start")
8965
8966     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8967     uuid_e = 16*'\x11'
8968     e_nonce = 16*'\x22'
8969     own_private, e_pk = wsc_dh_init()
8970
8971     logger.debug("Send M1 to AP")
8972     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8973                                 e_nonce, e_pk)
8974     send_wsc_msg(hapd, addr, m1)
8975
8976     logger.debug("Receive M2 from AP")
8977     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8978     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8979     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8980
8981     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8982                                     r_nonce)
8983     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8984
8985     logger.debug("Send M3 to AP")
8986     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8987     attrs += build_attr_msg_type(WPS_M3)
8988     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8989     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8990     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8991     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8992     raw_m3_attrs = attrs
8993     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8994     send_wsc_msg(hapd, addr, m3)
8995
8996     logger.debug("Receive M4 from AP")
8997     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8998
8999     logger.debug("Send M5 to AP")
9000     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9001     attrs += build_attr_msg_type(WPS_M5)
9002     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9003     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
9004     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9005     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
9006     raw_m5_attrs = attrs
9007     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9008     send_wsc_msg(hapd, addr, m5)
9009
9010     logger.debug("Receive M6 from AP")
9011     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
9012
9013     logger.debug("Send M7 to AP")
9014     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9015     attrs += build_attr_msg_type(WPS_M7)
9016     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9017     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
9018     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9019     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
9020     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9021     raw_m7_attrs = attrs
9022     send_wsc_msg(hapd, addr, m7)
9023
9024     logger.debug("Receive M8 from AP")
9025     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
9026     return hapd, msg, e_nonce, r_nonce
9027
9028 @remote_compatible
9029 def test_wps_ext_wsc_done_invalid(dev, apdev):
9030     """WPS proto: invalid WSC_Done"""
9031     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9032
9033     logger.debug("Send WSC_Done to AP")
9034     attrs = '\x10\x00\x00'
9035     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9036     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9037
9038     wps_wait_eap_failure(hapd, dev[0])
9039
9040 @remote_compatible
9041 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
9042     """WPS proto: invalid WSC_Done"""
9043     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9044
9045     logger.debug("Send WSC_Done to AP")
9046     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9047     #attrs += build_attr_msg_type(WPS_WSC_DONE)
9048     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9049     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9050     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9051     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9052
9053     wps_wait_eap_failure(hapd, dev[0])
9054
9055 @remote_compatible
9056 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
9057     """WPS proto: WSC_Done with wrong Msg Type"""
9058     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9059
9060     logger.debug("Send WSC_Done to AP")
9061     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9062     attrs += build_attr_msg_type(WPS_WSC_ACK)
9063     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9064     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9065     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9066     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9067
9068     wps_wait_eap_failure(hapd, dev[0])
9069
9070 @remote_compatible
9071 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
9072     """WPS proto: WSC_Done without e_nonce"""
9073     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9074
9075     logger.debug("Send WSC_Done to AP")
9076     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9077     attrs += build_attr_msg_type(WPS_WSC_DONE)
9078     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9079     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9080     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9081     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9082
9083     wps_wait_eap_failure(hapd, dev[0])
9084
9085 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
9086     """WPS proto: WSC_Done without r_nonce"""
9087     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
9088
9089     logger.debug("Send WSC_Done to AP")
9090     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9091     attrs += build_attr_msg_type(WPS_WSC_DONE)
9092     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
9093     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9094     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
9095     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
9096
9097     wps_wait_eap_failure(hapd, dev[0])
9098
9099 @remote_compatible
9100 def test_wps_ext_m7_no_encr_settings(dev, apdev):
9101     """WPS proto: M7 without Encr Settings"""
9102     pin = "12345670"
9103     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
9104     wps_ext_eap_identity_req(dev[0], hapd, bssid)
9105     wps_ext_eap_identity_resp(hapd, dev[0], addr)
9106
9107     logger.debug("Receive WSC/Start from AP")
9108     msg = get_wsc_msg(hapd)
9109     if msg['wsc_opcode'] != WSC_Start:
9110         raise Exception("Unexpected Op-Code for WSC/Start")
9111
9112     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
9113     uuid_e = 16*'\x11'
9114     e_nonce = 16*'\x22'
9115     own_private, e_pk = wsc_dh_init()
9116
9117     logger.debug("Send M1 to AP")
9118     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
9119                                 e_nonce, e_pk)
9120     send_wsc_msg(hapd, addr, m1)
9121
9122     logger.debug("Receive M2 from AP")
9123     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
9124     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
9125     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
9126
9127     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
9128                                     r_nonce)
9129     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
9130
9131     logger.debug("Send M3 to AP")
9132     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9133     attrs += build_attr_msg_type(WPS_M3)
9134     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9135     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
9136     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
9137     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
9138     raw_m3_attrs = attrs
9139     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9140     send_wsc_msg(hapd, addr, m3)
9141
9142     logger.debug("Receive M4 from AP")
9143     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
9144
9145     logger.debug("Send M5 to AP")
9146     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9147     attrs += build_attr_msg_type(WPS_M5)
9148     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9149     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
9150     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9151     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
9152     raw_m5_attrs = attrs
9153     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9154     send_wsc_msg(hapd, addr, m5)
9155
9156     logger.debug("Receive M6 from AP")
9157     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
9158
9159     logger.debug("Send M7 to AP")
9160     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
9161     attrs += build_attr_msg_type(WPS_M7)
9162     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
9163     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
9164     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
9165     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
9166     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
9167     raw_m7_attrs = attrs
9168     send_wsc_msg(hapd, addr, m7)
9169
9170     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
9171
9172 @remote_compatible
9173 def test_wps_ext_m1_workaround(dev, apdev):
9174     """WPS proto: M1 Manufacturer/Model workaround"""
9175     pin = "12345670"
9176     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
9177     wps_ext_eap_identity_req(dev[0], hapd, bssid)
9178     wps_ext_eap_identity_resp(hapd, dev[0], addr)
9179
9180     logger.debug("Receive WSC/Start from AP")
9181     msg = get_wsc_msg(hapd)
9182     if msg['wsc_opcode'] != WSC_Start:
9183         raise Exception("Unexpected Op-Code for WSC/Start")
9184
9185     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
9186     uuid_e = 16*'\x11'
9187     e_nonce = 16*'\x22'
9188     own_private, e_pk = wsc_dh_init()
9189
9190     logger.debug("Send M1 to AP")
9191     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
9192                                 e_nonce, e_pk, manufacturer='Apple TEST',
9193                                 model_name='AirPort', config_methods='\xff\xff')
9194     send_wsc_msg(hapd, addr, m1)
9195
9196     logger.debug("Receive M2 from AP")
9197     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
9198
9199 @remote_compatible
9200 def test_ap_wps_disable_enable(dev, apdev):
9201     """WPS and DISABLE/ENABLE AP"""
9202     hapd = wps_start_ap(apdev[0])
9203     hapd.disable()
9204     hapd.enable()
9205     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
9206
9207 def test_ap_wps_upnp_web_oom(dev, apdev, params):
9208     """hostapd WPS UPnP web OOM"""
9209     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
9210     hapd = add_ssdp_ap(apdev[0], ap_uuid)
9211
9212     location = ssdp_get_location(ap_uuid)
9213     url = urlparse.urlparse(location)
9214     urls = upnp_get_urls(location)
9215     eventurl = urlparse.urlparse(urls['event_sub_url'])
9216     ctrlurl = urlparse.urlparse(urls['control_url'])
9217
9218     conn = httplib.HTTPConnection(url.netloc)
9219     with alloc_fail(hapd, 1, "web_connection_parse_get"):
9220         conn.request("GET", "/wps_device.xml")
9221         try:
9222             resp = conn.getresponse()
9223         except:
9224             pass
9225
9226     conn = httplib.HTTPConnection(url.netloc)
9227     conn.request("GET", "/unknown")
9228     resp = conn.getresponse()
9229     if resp.status != 404:
9230         raise Exception("Unexpected HTTP result for unknown URL: %d" + resp.status)
9231
9232     with alloc_fail(hapd, 1, "web_connection_parse_get"):
9233         conn.request("GET", "/unknown")
9234         try:
9235             resp = conn.getresponse()
9236             print resp.status
9237         except:
9238             pass
9239
9240     conn = httplib.HTTPConnection(url.netloc)
9241     conn.request("GET", "/wps_device.xml")
9242     resp = conn.getresponse()
9243     if resp.status != 200:
9244         raise Exception("GET /wps_device.xml failed")
9245
9246     conn = httplib.HTTPConnection(url.netloc)
9247     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9248     if resp.status != 200:
9249         raise Exception("GetDeviceInfo failed")
9250
9251     with alloc_fail(hapd, 1, "web_process_get_device_info"):
9252         conn = httplib.HTTPConnection(url.netloc)
9253         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9254         if resp.status != 500:
9255             raise Exception("Internal error not reported from GetDeviceInfo OOM")
9256
9257     with alloc_fail(hapd, 1, "wps_build_m1;web_process_get_device_info"):
9258         conn = httplib.HTTPConnection(url.netloc)
9259         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9260         if resp.status != 500:
9261             raise Exception("Internal error not reported from GetDeviceInfo OOM")
9262
9263     with alloc_fail(hapd, 1, "wpabuf_alloc;web_connection_send_reply"):
9264         conn = httplib.HTTPConnection(url.netloc)
9265         try:
9266             resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9267         except:
9268             pass
9269
9270     conn = httplib.HTTPConnection(url.netloc)
9271     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
9272     if resp.status != 200:
9273         raise Exception("GetDeviceInfo failed")
9274
9275     # No NewWLANEventType in PutWLANResponse NewMessage
9276     conn = httplib.HTTPConnection(url.netloc)
9277     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse", newmsg="foo")
9278     if resp.status != 600:
9279         raise Exception("Unexpected HTTP response: %d" % resp.status)
9280
9281     # No NewWLANEventMAC in PutWLANResponse NewMessage
9282     conn = httplib.HTTPConnection(url.netloc)
9283     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9284                             newmsg="foo", neweventtype="1")
9285     if resp.status != 600:
9286         raise Exception("Unexpected HTTP response: %d" % resp.status)
9287
9288     # Invalid NewWLANEventMAC in PutWLANResponse NewMessage
9289     conn = httplib.HTTPConnection(url.netloc)
9290     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9291                             newmsg="foo", neweventtype="1",
9292                             neweventmac="foo")
9293     if resp.status != 600:
9294         raise Exception("Unexpected HTTP response: %d" % resp.status)
9295
9296     # Workaround for NewWLANEventMAC in PutWLANResponse NewMessage
9297     # Ignored unexpected PutWLANResponse WLANEventType 1
9298     conn = httplib.HTTPConnection(url.netloc)
9299     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9300                             newmsg="foo", neweventtype="1",
9301                             neweventmac="00.11.22.33.44.55")
9302     if resp.status != 500:
9303         raise Exception("Unexpected HTTP response: %d" % resp.status)
9304
9305     # PutWLANResponse NewMessage with invalid EAP message
9306     conn = httplib.HTTPConnection(url.netloc)
9307     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse",
9308                             newmsg="foo", neweventtype="2",
9309                             neweventmac="00:11:22:33:44:55")
9310     if resp.status != 200:
9311         raise Exception("Unexpected HTTP response: %d" % resp.status)
9312
9313     with alloc_fail(hapd, 1, "web_connection_parse_subscribe"):
9314         conn = httplib.HTTPConnection(url.netloc)
9315         headers = { "callback": '<http://127.0.0.1:12345/event>',
9316                     "NT": "upnp:event",
9317                     "timeout": "Second-1234" }
9318         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
9319         try:
9320             resp = conn.getresponse()
9321         except:
9322             pass
9323
9324     with alloc_fail(hapd, 1, "dup_binstr;web_connection_parse_subscribe"):
9325         conn = httplib.HTTPConnection(url.netloc)
9326         headers = { "callback": '<http://127.0.0.1:12345/event>',
9327                     "NT": "upnp:event",
9328                     "timeout": "Second-1234" }
9329         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
9330         resp = conn.getresponse()
9331         if resp.status != 500:
9332             raise Exception("Unexpected HTTP response: %d" % resp.status)
9333
9334     with alloc_fail(hapd, 1, "wpabuf_alloc;web_connection_parse_unsubscribe"):
9335         conn = httplib.HTTPConnection(url.netloc)
9336         headers = { "callback": '<http://127.0.0.1:12345/event>',
9337                     "NT": "upnp:event",
9338                     "timeout": "Second-1234" }
9339         conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
9340         try:
9341             resp = conn.getresponse()
9342         except:
9343             pass
9344
9345     with alloc_fail(hapd, 1, "web_connection_unimplemented"):
9346         conn = httplib.HTTPConnection(url.netloc)
9347         conn.request("HEAD", "/wps_device.xml")
9348         try:
9349             resp = conn.getresponse()
9350         except:
9351             pass
9352
9353 def test_ap_wps_frag_ack_oom(dev, apdev):
9354     """WPS and fragment ack OOM"""
9355     dev[0].request("SET wps_fragment_size 50")
9356     hapd = wps_start_ap(apdev[0])
9357     with alloc_fail(hapd, 1, "eap_wsc_build_frag_ack"):
9358         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
9359
9360 def wait_scan_stopped(dev):
9361     dev.request("ABORT_SCAN")
9362     for i in range(50):
9363         res = dev.get_driver_status_field("scan_state")
9364         if "SCAN_STARTED" not in res and "SCAN_REQUESTED" not in res:
9365             break
9366         logger.debug("Waiting for scan to complete")
9367         time.sleep(0.1)
9368
9369 @remote_compatible
9370 def test_ap_wps_eap_wsc_errors(dev, apdev):
9371     """WPS and EAP-WSC error cases"""
9372     ssid = "test-wps-conf-pin"
9373     appin = "12345670"
9374     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
9375                "wpa_passphrase": "12345678", "wpa": "2",
9376                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
9377                "fragment_size": "300", "ap_pin": appin }
9378     hapd = hostapd.add_ap(apdev[0], params)
9379     bssid = apdev[0]['bssid']
9380
9381     pin = dev[0].wps_read_pin()
9382     hapd.request("WPS_PIN any " + pin)
9383     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
9384     dev[0].dump_monitor()
9385
9386     dev[0].wps_reg(bssid, appin + " new_ssid=a", "new ssid", "WPA2PSK", "CCMP",
9387                    "new passphrase", no_wait=True)
9388     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9389     if ev is None:
9390         raise Exception("WPS-FAIL not reported")
9391     dev[0].request("WPS_CANCEL")
9392     dev[0].wait_disconnected()
9393     wait_scan_stopped(dev[0])
9394     dev[0].dump_monitor()
9395
9396     dev[0].wps_reg(bssid, appin, "new ssid", "FOO", "CCMP",
9397                    "new passphrase", no_wait=True)
9398     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9399     if ev is None:
9400         raise Exception("WPS-FAIL not reported")
9401     dev[0].request("WPS_CANCEL")
9402     dev[0].wait_disconnected()
9403     wait_scan_stopped(dev[0])
9404     dev[0].dump_monitor()
9405
9406     dev[0].wps_reg(bssid, appin, "new ssid", "WPA2PSK", "FOO",
9407                    "new passphrase", no_wait=True)
9408     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9409     if ev is None:
9410         raise Exception("WPS-FAIL not reported")
9411     dev[0].request("WPS_CANCEL")
9412     dev[0].wait_disconnected()
9413     wait_scan_stopped(dev[0])
9414     dev[0].dump_monitor()
9415
9416     dev[0].wps_reg(bssid, appin + "new_key=a", "new ssid", "WPA2PSK", "CCMP",
9417                    "new passphrase", no_wait=True)
9418     ev = dev[0].wait_event(["WPS-FAIL"], timeout=10)
9419     if ev is None:
9420         raise Exception("WPS-FAIL not reported")
9421     dev[0].request("WPS_CANCEL")
9422     dev[0].wait_disconnected()
9423     wait_scan_stopped(dev[0])
9424     dev[0].dump_monitor()
9425
9426     tests = [ "eap_wsc_init",
9427               "eap_msg_alloc;eap_wsc_build_msg",
9428               "wpabuf_alloc;eap_wsc_process_fragment" ]
9429     for func in tests:
9430         with alloc_fail(dev[0], 1, func):
9431             dev[0].request("WPS_PIN %s %s" % (bssid, pin))
9432             wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
9433             dev[0].request("WPS_CANCEL")
9434             dev[0].wait_disconnected()
9435             wait_scan_stopped(dev[0])
9436             dev[0].dump_monitor()
9437
9438     with alloc_fail(dev[0], 1, "eap_msg_alloc;eap_sm_build_expanded_nak"):
9439         dev[0].wps_reg(bssid, appin + " new_ssid=a", "new ssid", "WPA2PSK",
9440                        "CCMP", "new passphrase", no_wait=True)
9441         wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
9442         dev[0].request("WPS_CANCEL")
9443         dev[0].wait_disconnected()
9444         wait_scan_stopped(dev[0])
9445         dev[0].dump_monitor()
9446
9447 def test_ap_wps_eap_wsc(dev, apdev):
9448     """WPS and EAP-WSC in network profile"""
9449     params = int_eap_server_params()
9450     params["wps_state"] = "2"
9451     hapd = hostapd.add_ap(apdev[0], params)
9452     bssid = apdev[0]['bssid']
9453
9454     logger.info("Unexpected identity")
9455     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9456                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-unexpected",
9457                    wait_connect=False)
9458     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9459     if ev is None:
9460         raise Exception("No EAP-Failure seen")
9461     dev[0].request("REMOVE_NETWORK all")
9462     dev[0].wait_disconnected()
9463
9464     logger.info("No phase1 parameter")
9465     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9466                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9467                    wait_connect=False)
9468     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9469     if ev is None:
9470         raise Exception("Timeout on EAP method start")
9471     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9472     if ev is None:
9473         raise Exception("No EAP-Failure seen")
9474     dev[0].request("REMOVE_NETWORK all")
9475     dev[0].wait_disconnected()
9476
9477     logger.info("No PIN/PBC in phase1")
9478     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9479                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9480                    phase1="foo", wait_connect=False)
9481     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9482     if ev is None:
9483         raise Exception("Timeout on EAP method start")
9484     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9485     if ev is None:
9486         raise Exception("No EAP-Failure seen")
9487     dev[0].request("REMOVE_NETWORK all")
9488     dev[0].wait_disconnected()
9489
9490     logger.info("Invalid pkhash in phase1")
9491     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9492                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9493                    phase1="foo pkhash=q pbc=1", wait_connect=False)
9494     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9495     if ev is None:
9496         raise Exception("Timeout on EAP method start")
9497     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9498     if ev is None:
9499         raise Exception("No EAP-Failure seen")
9500     dev[0].request("REMOVE_NETWORK all")
9501     dev[0].wait_disconnected()
9502
9503     logger.info("Zero fragment_size")
9504     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9505                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9506                    fragment_size="0", phase1="pin=12345670", wait_connect=False)
9507     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9508     if ev is None:
9509         raise Exception("Timeout on EAP method start")
9510     ev = dev[0].wait_event(["WPS-M2D"], timeout=5)
9511     if ev is None:
9512         raise Exception("No M2D seen")
9513     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9514     if ev is None:
9515         raise Exception("No EAP-Failure seen")
9516     dev[0].request("REMOVE_NETWORK all")
9517     dev[0].wait_disconnected()
9518
9519     logger.info("Missing new_auth")
9520     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9521                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9522                    phase1="pin=12345670 new_ssid=aa", wait_connect=False)
9523     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9524     if ev is None:
9525         raise Exception("Timeout on EAP method start")
9526     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9527     if ev is None:
9528         raise Exception("No EAP-Failure seen")
9529     dev[0].request("REMOVE_NETWORK all")
9530     dev[0].wait_disconnected()
9531
9532     logger.info("Missing new_encr")
9533     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9534                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9535                    phase1="pin=12345670 new_auth=WPA2PSK new_ssid=aa", wait_connect=False)
9536     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9537     if ev is None:
9538         raise Exception("Timeout on EAP method start")
9539     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9540     if ev is None:
9541         raise Exception("No EAP-Failure seen")
9542     dev[0].request("REMOVE_NETWORK all")
9543     dev[0].wait_disconnected()
9544
9545     logger.info("Missing new_key")
9546     dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP", scan_freq="2412",
9547                    eap="WSC", identity="WFA-SimpleConfig-Enrollee-1-0",
9548                    phase1="pin=12345670 new_auth=WPA2PSK new_ssid=aa new_encr=CCMP",
9549                    wait_connect=False)
9550     ev = dev[0].wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=5)
9551     if ev is None:
9552         raise Exception("Timeout on EAP method start")
9553     ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
9554     if ev is None:
9555         raise Exception("No EAP-Failure seen")
9556     dev[0].request("REMOVE_NETWORK all")
9557     dev[0].wait_disconnected()
9558
9559 def test_ap_wps_and_bss_limit(dev, apdev):
9560     """WPS and wpa_supplicant BSS entry limit"""
9561     try:
9562         _test_ap_wps_and_bss_limit(dev, apdev)
9563     finally:
9564         dev[0].request("SET bss_max_count 200")
9565         pass
9566
9567 def _test_ap_wps_and_bss_limit(dev, apdev):
9568     params = { "ssid": "test-wps", "eap_server": "1", "wps_state": "2",
9569                "wpa_passphrase": "12345678", "wpa": "2",
9570                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
9571     hapd = hostapd.add_ap(apdev[0], params)
9572
9573     params = { "ssid": "test-wps-2", "eap_server": "1", "wps_state": "2",
9574                "wpa_passphrase": "1234567890", "wpa": "2",
9575                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
9576     hapd2 = hostapd.add_ap(apdev[1], params)
9577
9578     id = dev[1].add_network()
9579     dev[1].set_network(id, "mode", "2")
9580     dev[1].set_network_quoted(id, "ssid", "wpas-ap-no-wps")
9581     dev[1].set_network_quoted(id, "psk", "12345678")
9582     dev[1].set_network(id, "frequency", "2462")
9583     dev[1].set_network(id, "scan_freq", "2462")
9584     dev[1].set_network(id, "wps_disabled", "1")
9585     dev[1].select_network(id)
9586
9587     id = dev[2].add_network()
9588     dev[2].set_network(id, "mode", "2")
9589     dev[2].set_network_quoted(id, "ssid", "wpas-ap")
9590     dev[2].set_network_quoted(id, "psk", "12345678")
9591     dev[2].set_network(id, "frequency", "2437")
9592     dev[2].set_network(id, "scan_freq", "2437")
9593     dev[2].select_network(id)
9594
9595     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
9596     wpas.interface_add("wlan5")
9597     id = wpas.add_network()
9598     wpas.set_network(id, "mode", "2")
9599     wpas.set_network_quoted(id, "ssid", "wpas-ap")
9600     wpas.set_network_quoted(id, "psk", "12345678")
9601     wpas.set_network(id, "frequency", "2437")
9602     wpas.set_network(id, "scan_freq", "2437")
9603     wpas.select_network(id)
9604
9605     dev[1].wait_connected()
9606     dev[2].wait_connected()
9607     wpas.wait_connected()
9608     wpas.request("WPS_PIN any 12345670")
9609
9610     hapd.request("WPS_PBC")
9611     hapd2.request("WPS_PBC")
9612
9613     dev[0].request("SET bss_max_count 1")
9614
9615     id = dev[0].add_network()
9616     dev[0].set_network_quoted(id, "ssid", "testing")
9617
9618     id = dev[0].add_network()
9619     dev[0].set_network_quoted(id, "ssid", "testing")
9620     dev[0].set_network(id, "key_mgmt", "WPS")
9621
9622     dev[0].request("WPS_PBC")
9623     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
9624     dev[0].request("WPS_CANCEL")
9625
9626     id = dev[0].add_network()
9627     dev[0].set_network_quoted(id, "ssid", "testing")
9628     dev[0].set_network(id, "key_mgmt", "WPS")
9629
9630     dev[0].scan(freq="2412")