tests: WPS ER OOM in XML processing
[mech_eap.git] / tests / hwsim / test_ap_wps.py
1 # WPS tests
2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import os
8 import time
9 import subprocess
10 import logging
11 logger = logging.getLogger()
12 import re
13 import socket
14 import httplib
15 import urlparse
16 import urllib
17 import xml.etree.ElementTree as ET
18 import StringIO
19
20 import hwsim_utils
21 import hostapd
22 from wpasupplicant import WpaSupplicant
23 from utils import HwsimSkip, alloc_fail
24
25 def test_ap_wps_init(dev, apdev):
26     """Initial AP configuration with first WPS Enrollee"""
27     ssid = "test-wps"
28     hostapd.add_ap(apdev[0]['ifname'],
29                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
30     hapd = hostapd.Hostapd(apdev[0]['ifname'])
31     logger.info("WPS provisioning step")
32     hapd.request("WPS_PBC")
33     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
34         raise Exception("PBC status not shown correctly")
35
36     id = dev[0].add_network()
37     dev[0].set_network_quoted(id, "ssid", "home")
38     dev[0].set_network_quoted(id, "psk", "12345678")
39     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
40
41     id = dev[0].add_network()
42     dev[0].set_network_quoted(id, "ssid", "home2")
43     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
44     dev[0].set_network(id, "key_mgmt", "NONE")
45     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
46
47     dev[0].request("WPS_PBC")
48     dev[0].wait_connected(timeout=30)
49     status = dev[0].get_status()
50     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
51         raise Exception("Not fully connected")
52     if status['ssid'] != ssid:
53         raise Exception("Unexpected SSID")
54     if status['pairwise_cipher'] != 'CCMP':
55         raise Exception("Unexpected encryption configuration")
56     if status['key_mgmt'] != 'WPA2-PSK':
57         raise Exception("Unexpected key_mgmt")
58
59     status = hapd.request("WPS_GET_STATUS")
60     if "PBC Status: Disabled" not in status:
61         raise Exception("PBC status not shown correctly")
62     if "Last WPS result: Success" not in status:
63         raise Exception("Last WPS result not shown correctly")
64     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
65         raise Exception("Peer address not shown correctly")
66     conf = hapd.request("GET_CONFIG")
67     if "wps_state=configured" not in conf:
68         raise Exception("AP not in WPS configured state")
69     if "wpa=3" not in conf:
70         raise Exception("AP not in WPA+WPA2 configuration")
71     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
72         raise Exception("Unexpected rsn_pairwise_cipher")
73     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
74         raise Exception("Unexpected wpa_pairwise_cipher")
75     if "group_cipher=TKIP" not in conf:
76         raise Exception("Unexpected group_cipher")
77
78     if len(dev[0].list_networks()) != 3:
79         raise Exception("Unexpected number of network blocks")
80
81 def test_ap_wps_init_2ap_pbc(dev, apdev):
82     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
83     ssid = "test-wps"
84     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
85     hostapd.add_ap(apdev[0]['ifname'], params)
86     hostapd.add_ap(apdev[1]['ifname'], params)
87     hapd = hostapd.Hostapd(apdev[0]['ifname'])
88     logger.info("WPS provisioning step")
89     hapd.request("WPS_PBC")
90     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
91     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
92     bss = dev[0].get_bss(apdev[0]['bssid'])
93     if "[WPS-PBC]" not in bss['flags']:
94         raise Exception("WPS-PBC flag missing from AP1")
95     bss = dev[0].get_bss(apdev[1]['bssid'])
96     if "[WPS-PBC]" not in bss['flags']:
97         raise Exception("WPS-PBC flag missing from AP2")
98     dev[0].dump_monitor()
99     dev[0].request("SET wps_cred_processing 2")
100     dev[0].request("WPS_PBC")
101     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
102     dev[0].request("SET wps_cred_processing 0")
103     if ev is None:
104         raise Exception("WPS cred event not seen")
105     if "100e" not in ev:
106         raise Exception("WPS attributes not included in the cred event")
107     dev[0].wait_connected(timeout=30)
108
109     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
110     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
111     bss = dev[1].get_bss(apdev[0]['bssid'])
112     if "[WPS-PBC]" in bss['flags']:
113         raise Exception("WPS-PBC flag not cleared from AP1")
114     bss = dev[1].get_bss(apdev[1]['bssid'])
115     if "[WPS-PBC]" in bss['flags']:
116         raise Exception("WPS-PBC flag not cleared from AP2")
117
118 def test_ap_wps_init_2ap_pin(dev, apdev):
119     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
120     ssid = "test-wps"
121     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
122     hostapd.add_ap(apdev[0]['ifname'], params)
123     hostapd.add_ap(apdev[1]['ifname'], params)
124     hapd = hostapd.Hostapd(apdev[0]['ifname'])
125     logger.info("WPS provisioning step")
126     pin = dev[0].wps_read_pin()
127     hapd.request("WPS_PIN any " + pin)
128     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
129     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
130     bss = dev[0].get_bss(apdev[0]['bssid'])
131     if "[WPS-AUTH]" not in bss['flags']:
132         raise Exception("WPS-AUTH flag missing from AP1")
133     bss = dev[0].get_bss(apdev[1]['bssid'])
134     if "[WPS-AUTH]" not in bss['flags']:
135         raise Exception("WPS-AUTH flag missing from AP2")
136     dev[0].dump_monitor()
137     dev[0].request("WPS_PIN any " + pin)
138     dev[0].wait_connected(timeout=30)
139
140     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
141     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
142     bss = dev[1].get_bss(apdev[0]['bssid'])
143     if "[WPS-AUTH]" in bss['flags']:
144         raise Exception("WPS-AUTH flag not cleared from AP1")
145     bss = dev[1].get_bss(apdev[1]['bssid'])
146     if "[WPS-AUTH]" in bss['flags']:
147         raise Exception("WPS-AUTH flag not cleared from AP2")
148
149 def test_ap_wps_init_through_wps_config(dev, apdev):
150     """Initial AP configuration using wps_config command"""
151     ssid = "test-wps-init-config"
152     hostapd.add_ap(apdev[0]['ifname'],
153                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
154     hapd = hostapd.Hostapd(apdev[0]['ifname'])
155     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
156         raise Exception("WPS_CONFIG command failed")
157     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
158     if ev is None:
159         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
160     # It takes some time for the AP to update Beacon and Probe Response frames,
161     # so wait here before requesting the scan to be started to avoid adding
162     # extra five second wait to the test due to fetching obsolete scan results.
163     hapd.ping()
164     time.sleep(0.2)
165     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
166                    pairwise="CCMP", group="CCMP")
167
168 def test_ap_wps_conf(dev, apdev):
169     """WPS PBC provisioning with configured AP"""
170     ssid = "test-wps-conf"
171     hostapd.add_ap(apdev[0]['ifname'],
172                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
173                      "wpa_passphrase": "12345678", "wpa": "2",
174                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
175     hapd = hostapd.Hostapd(apdev[0]['ifname'])
176     logger.info("WPS provisioning step")
177     hapd.request("WPS_PBC")
178     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
179     dev[0].dump_monitor()
180     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
181     dev[0].wait_connected(timeout=30)
182     status = dev[0].get_status()
183     if status['wpa_state'] != 'COMPLETED':
184         raise Exception("Not fully connected")
185     if status['bssid'] != apdev[0]['bssid']:
186         raise Exception("Unexpected BSSID")
187     if status['ssid'] != ssid:
188         raise Exception("Unexpected SSID")
189     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
190         raise Exception("Unexpected encryption configuration")
191     if status['key_mgmt'] != 'WPA2-PSK':
192         raise Exception("Unexpected key_mgmt")
193
194     sta = hapd.get_sta(dev[0].p2p_interface_addr())
195     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
196         raise Exception("Device name not available in STA command")
197
198 def test_ap_wps_conf_5ghz(dev, apdev):
199     """WPS PBC provisioning with configured AP on 5 GHz band"""
200     try:
201         hapd = None
202         ssid = "test-wps-conf"
203         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
204                    "wpa_passphrase": "12345678", "wpa": "2",
205                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
206                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
207         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
208         logger.info("WPS provisioning step")
209         hapd.request("WPS_PBC")
210         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
211         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
212         dev[0].wait_connected(timeout=30)
213
214         sta = hapd.get_sta(dev[0].p2p_interface_addr())
215         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
216             raise Exception("Device name not available in STA command")
217     finally:
218         dev[0].request("DISCONNECT")
219         if hapd:
220             hapd.request("DISABLE")
221         subprocess.call(['iw', 'reg', 'set', '00'])
222         dev[0].flush_scan_cache()
223
224 def test_ap_wps_conf_chan14(dev, apdev):
225     """WPS PBC provisioning with configured AP on channel 14"""
226     try:
227         hapd = None
228         ssid = "test-wps-conf"
229         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
230                    "wpa_passphrase": "12345678", "wpa": "2",
231                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
232                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
233         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
234         logger.info("WPS provisioning step")
235         hapd.request("WPS_PBC")
236         dev[0].request("WPS_PBC")
237         dev[0].wait_connected(timeout=30)
238
239         sta = hapd.get_sta(dev[0].p2p_interface_addr())
240         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
241             raise Exception("Device name not available in STA command")
242     finally:
243         dev[0].request("DISCONNECT")
244         if hapd:
245             hapd.request("DISABLE")
246         subprocess.call(['iw', 'reg', 'set', '00'])
247         dev[0].flush_scan_cache()
248
249 def test_ap_wps_twice(dev, apdev):
250     """WPS provisioning with twice to change passphrase"""
251     ssid = "test-wps-twice"
252     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
253                "wpa_passphrase": "12345678", "wpa": "2",
254                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
255     hostapd.add_ap(apdev[0]['ifname'], params)
256     hapd = hostapd.Hostapd(apdev[0]['ifname'])
257     logger.info("WPS provisioning step")
258     hapd.request("WPS_PBC")
259     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
260     dev[0].dump_monitor()
261     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
262     dev[0].wait_connected(timeout=30)
263     dev[0].request("DISCONNECT")
264
265     logger.info("Restart AP with different passphrase and re-run WPS")
266     hapd_global = hostapd.HostapdGlobal()
267     hapd_global.remove(apdev[0]['ifname'])
268     params['wpa_passphrase'] = 'another passphrase'
269     hostapd.add_ap(apdev[0]['ifname'], params)
270     hapd = hostapd.Hostapd(apdev[0]['ifname'])
271     logger.info("WPS provisioning step")
272     hapd.request("WPS_PBC")
273     dev[0].dump_monitor()
274     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
275     dev[0].wait_connected(timeout=30)
276     networks = dev[0].list_networks()
277     if len(networks) > 1:
278         raise Exception("Unexpected duplicated network block present")
279
280 def test_ap_wps_incorrect_pin(dev, apdev):
281     """WPS PIN provisioning with incorrect PIN"""
282     ssid = "test-wps-incorrect-pin"
283     hostapd.add_ap(apdev[0]['ifname'],
284                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
285                      "wpa_passphrase": "12345678", "wpa": "2",
286                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
287     hapd = hostapd.Hostapd(apdev[0]['ifname'])
288
289     logger.info("WPS provisioning attempt 1")
290     hapd.request("WPS_PIN any 12345670")
291     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
292     dev[0].dump_monitor()
293     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
294     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
295     if ev is None:
296         raise Exception("WPS operation timed out")
297     if "config_error=18" not in ev:
298         raise Exception("Incorrect config_error reported")
299     if "msg=8" not in ev:
300         raise Exception("PIN error detected on incorrect message")
301     dev[0].wait_disconnected(timeout=10)
302     dev[0].request("WPS_CANCEL")
303     # if a scan was in progress, wait for it to complete before trying WPS again
304     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
305
306     status = hapd.request("WPS_GET_STATUS")
307     if "Last WPS result: Failed" not in status:
308         raise Exception("WPS failure result not shown correctly")
309
310     logger.info("WPS provisioning attempt 2")
311     hapd.request("WPS_PIN any 12345670")
312     dev[0].dump_monitor()
313     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
314     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
315     if ev is None:
316         raise Exception("WPS operation timed out")
317     if "config_error=18" not in ev:
318         raise Exception("Incorrect config_error reported")
319     if "msg=10" not in ev:
320         raise Exception("PIN error detected on incorrect message")
321     dev[0].wait_disconnected(timeout=10)
322
323 def test_ap_wps_conf_pin(dev, apdev):
324     """WPS PIN provisioning with configured AP"""
325     ssid = "test-wps-conf-pin"
326     hostapd.add_ap(apdev[0]['ifname'],
327                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
328                      "wpa_passphrase": "12345678", "wpa": "2",
329                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
330     hapd = hostapd.Hostapd(apdev[0]['ifname'])
331     logger.info("WPS provisioning step")
332     pin = dev[0].wps_read_pin()
333     hapd.request("WPS_PIN any " + pin)
334     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
335     dev[0].dump_monitor()
336     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
337     dev[0].wait_connected(timeout=30)
338     status = dev[0].get_status()
339     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
340         raise Exception("Not fully connected")
341     if status['ssid'] != ssid:
342         raise Exception("Unexpected SSID")
343     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
344         raise Exception("Unexpected encryption configuration")
345     if status['key_mgmt'] != 'WPA2-PSK':
346         raise Exception("Unexpected key_mgmt")
347
348     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
349     bss = dev[1].get_bss(apdev[0]['bssid'])
350     if "[WPS-AUTH]" in bss['flags']:
351         raise Exception("WPS-AUTH flag not cleared")
352     logger.info("Try to connect from another station using the same PIN")
353     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
354     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
355     if ev is None:
356         raise Exception("Operation timed out")
357     if "WPS-M2D" not in ev:
358         raise Exception("Unexpected WPS operation started")
359     hapd.request("WPS_PIN any " + pin)
360     dev[1].wait_connected(timeout=30)
361
362 def test_ap_wps_conf_pin_v1(dev, apdev):
363     """WPS PIN provisioning with configured WPS v1.0 AP"""
364     ssid = "test-wps-conf-pin-v1"
365     hostapd.add_ap(apdev[0]['ifname'],
366                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
367                      "wpa_passphrase": "12345678", "wpa": "2",
368                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
369     hapd = hostapd.Hostapd(apdev[0]['ifname'])
370     logger.info("WPS provisioning step")
371     pin = dev[0].wps_read_pin()
372     hapd.request("SET wps_version_number 0x10")
373     hapd.request("WPS_PIN any " + pin)
374     found = False
375     for i in range(0, 10):
376         dev[0].scan(freq="2412")
377         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
378             found = True
379             break
380     if not found:
381         hapd.request("SET wps_version_number 0x20")
382         raise Exception("WPS-PIN flag not seen in scan results")
383     dev[0].dump_monitor()
384     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
385     dev[0].wait_connected(timeout=30)
386     hapd.request("SET wps_version_number 0x20")
387
388 def test_ap_wps_conf_pin_2sta(dev, apdev):
389     """Two stations trying to use WPS PIN at the same time"""
390     ssid = "test-wps-conf-pin2"
391     hostapd.add_ap(apdev[0]['ifname'],
392                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
393                      "wpa_passphrase": "12345678", "wpa": "2",
394                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
395     hapd = hostapd.Hostapd(apdev[0]['ifname'])
396     logger.info("WPS provisioning step")
397     pin = "12345670"
398     pin2 = "55554444"
399     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
400     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
401     dev[0].dump_monitor()
402     dev[1].dump_monitor()
403     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
404     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
405     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
406     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
407     dev[0].wait_connected(timeout=30)
408     dev[1].wait_connected(timeout=30)
409
410 def test_ap_wps_conf_pin_timeout(dev, apdev):
411     """WPS PIN provisioning with configured AP timing out PIN"""
412     ssid = "test-wps-conf-pin"
413     hostapd.add_ap(apdev[0]['ifname'],
414                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
415                      "wpa_passphrase": "12345678", "wpa": "2",
416                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
417     hapd = hostapd.Hostapd(apdev[0]['ifname'])
418     addr = dev[0].p2p_interface_addr()
419     pin = dev[0].wps_read_pin()
420     if "FAIL" not in hapd.request("WPS_PIN "):
421         raise Exception("Unexpected success on invalid WPS_PIN")
422     hapd.request("WPS_PIN any " + pin + " 1")
423     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
424     time.sleep(1.1)
425     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
426     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
427     if ev is None:
428         raise Exception("WPS-PIN-NEEDED event timed out")
429     ev = dev[0].wait_event(["WPS-M2D"])
430     if ev is None:
431         raise Exception("M2D not reported")
432     dev[0].request("WPS_CANCEL")
433
434     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
435     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
436     dev[0].wait_connected(timeout=30)
437
438 def test_ap_wps_reg_connect(dev, apdev):
439     """WPS registrar using AP PIN to connect"""
440     ssid = "test-wps-reg-ap-pin"
441     appin = "12345670"
442     hostapd.add_ap(apdev[0]['ifname'],
443                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
444                      "wpa_passphrase": "12345678", "wpa": "2",
445                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
446                      "ap_pin": appin})
447     logger.info("WPS provisioning step")
448     dev[0].dump_monitor()
449     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
450     dev[0].wps_reg(apdev[0]['bssid'], appin)
451     status = dev[0].get_status()
452     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
453         raise Exception("Not fully connected")
454     if status['ssid'] != ssid:
455         raise Exception("Unexpected SSID")
456     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
457         raise Exception("Unexpected encryption configuration")
458     if status['key_mgmt'] != 'WPA2-PSK':
459         raise Exception("Unexpected key_mgmt")
460
461 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
462     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
463     ssid = "test-wps-reg-ap-pin"
464     appin = "12345670"
465     hostapd.add_ap(apdev[0]['ifname'],
466                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
467                      "wpa_passphrase": "12345678", "wpa": "3",
468                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
469                      "wpa_pairwise": "TKIP", "ap_pin": appin})
470     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
471     dev[0].wps_reg(apdev[0]['bssid'], appin)
472     status = dev[0].get_status()
473     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
474         raise Exception("Not fully connected")
475     if status['ssid'] != ssid:
476         raise Exception("Unexpected SSID")
477     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
478         raise Exception("Unexpected encryption configuration")
479     if status['key_mgmt'] != 'WPA2-PSK':
480         raise Exception("Unexpected key_mgmt")
481
482 def check_wps_reg_failure(dev, ap, appin):
483     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
484     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
485     if ev is None:
486         raise Exception("WPS operation timed out")
487     if "WPS-SUCCESS" in ev:
488         raise Exception("WPS operation succeeded unexpectedly")
489     if "config_error=15" not in ev:
490         raise Exception("WPS setup locked state was not reported correctly")
491
492 def test_ap_wps_random_ap_pin(dev, apdev):
493     """WPS registrar using random AP PIN"""
494     ssid = "test-wps-reg-random-ap-pin"
495     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
496     hostapd.add_ap(apdev[0]['ifname'],
497                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
498                      "wpa_passphrase": "12345678", "wpa": "2",
499                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
500                      "device_name": "Wireless AP", "manufacturer": "Company",
501                      "model_name": "WAP", "model_number": "123",
502                      "serial_number": "12345", "device_type": "6-0050F204-1",
503                      "os_version": "01020300",
504                      "config_methods": "label push_button",
505                      "uuid": ap_uuid, "upnp_iface": "lo" })
506     hapd = hostapd.Hostapd(apdev[0]['ifname'])
507     appin = hapd.request("WPS_AP_PIN random")
508     if "FAIL" in appin:
509         raise Exception("Could not generate random AP PIN")
510     if appin not in hapd.request("WPS_AP_PIN get"):
511         raise Exception("Could not fetch current AP PIN")
512     logger.info("WPS provisioning step")
513     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
514     dev[0].wps_reg(apdev[0]['bssid'], appin)
515
516     hapd.request("WPS_AP_PIN disable")
517     logger.info("WPS provisioning step with AP PIN disabled")
518     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
519     check_wps_reg_failure(dev[1], apdev[0], appin)
520
521     logger.info("WPS provisioning step with AP PIN reset")
522     appin = "12345670"
523     hapd.request("WPS_AP_PIN set " + appin)
524     dev[1].wps_reg(apdev[0]['bssid'], appin)
525     dev[0].request("REMOVE_NETWORK all")
526     dev[1].request("REMOVE_NETWORK all")
527     dev[0].wait_disconnected(timeout=10)
528     dev[1].wait_disconnected(timeout=10)
529
530     logger.info("WPS provisioning step after AP PIN timeout")
531     hapd.request("WPS_AP_PIN disable")
532     appin = hapd.request("WPS_AP_PIN random 1")
533     time.sleep(1.1)
534     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
535         raise Exception("AP PIN unexpectedly still enabled")
536     check_wps_reg_failure(dev[0], apdev[0], appin)
537
538     logger.info("WPS provisioning step after AP PIN timeout(2)")
539     hapd.request("WPS_AP_PIN disable")
540     appin = "12345670"
541     hapd.request("WPS_AP_PIN set " + appin + " 1")
542     time.sleep(1.1)
543     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
544         raise Exception("AP PIN unexpectedly still enabled")
545     check_wps_reg_failure(dev[1], apdev[0], appin)
546
547 def test_ap_wps_reg_config(dev, apdev):
548     """WPS registrar configuring an AP using AP PIN"""
549     ssid = "test-wps-init-ap-pin"
550     appin = "12345670"
551     hostapd.add_ap(apdev[0]['ifname'],
552                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
553                      "ap_pin": appin})
554     logger.info("WPS configuration step")
555     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
556     dev[0].dump_monitor()
557     new_ssid = "wps-new-ssid"
558     new_passphrase = "1234567890"
559     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
560                    new_passphrase)
561     status = dev[0].get_status()
562     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
563         raise Exception("Not fully connected")
564     if status['ssid'] != new_ssid:
565         raise Exception("Unexpected SSID")
566     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
567         raise Exception("Unexpected encryption configuration")
568     if status['key_mgmt'] != 'WPA2-PSK':
569         raise Exception("Unexpected key_mgmt")
570
571     logger.info("Re-configure back to open")
572     dev[0].request("REMOVE_NETWORK all")
573     dev[0].flush_scan_cache()
574     dev[0].dump_monitor()
575     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
576     status = dev[0].get_status()
577     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
578         raise Exception("Not fully connected")
579     if status['ssid'] != "wps-open":
580         raise Exception("Unexpected SSID")
581     if status['key_mgmt'] != 'NONE':
582         raise Exception("Unexpected key_mgmt")
583
584 def test_ap_wps_reg_config_ext_processing(dev, apdev):
585     """WPS registrar configuring an AP with external config processing"""
586     ssid = "test-wps-init-ap-pin"
587     appin = "12345670"
588     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
589                "wps_cred_processing": "1", "ap_pin": appin}
590     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
591     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
592     new_ssid = "wps-new-ssid"
593     new_passphrase = "1234567890"
594     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
595                    new_passphrase, no_wait=True)
596     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
597     if ev is None:
598         raise Exception("WPS registrar operation timed out")
599     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
600     if ev is None:
601         raise Exception("WPS configuration timed out")
602     if "1026" not in ev:
603         raise Exception("AP Settings missing from event")
604     hapd.request("SET wps_cred_processing 0")
605     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
606         raise Exception("WPS_CONFIG command failed")
607     dev[0].wait_connected(timeout=15)
608
609 def test_ap_wps_reg_config_tkip(dev, apdev):
610     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
611     ssid = "test-wps-init-ap"
612     appin = "12345670"
613     hostapd.add_ap(apdev[0]['ifname'],
614                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
615                      "ap_pin": appin})
616     logger.info("WPS configuration step")
617     dev[0].request("SET wps_version_number 0x10")
618     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
619     dev[0].dump_monitor()
620     new_ssid = "wps-new-ssid-with-tkip"
621     new_passphrase = "1234567890"
622     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
623                    new_passphrase)
624     logger.info("Re-connect to verify WPA2 mixed mode")
625     dev[0].request("DISCONNECT")
626     id = 0
627     dev[0].set_network(id, "pairwise", "CCMP")
628     dev[0].set_network(id, "proto", "RSN")
629     dev[0].connect_network(id)
630     status = dev[0].get_status()
631     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
632         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
633     if status['ssid'] != new_ssid:
634         raise Exception("Unexpected SSID")
635     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
636         raise Exception("Unexpected encryption configuration")
637     if status['key_mgmt'] != 'WPA2-PSK':
638         raise Exception("Unexpected key_mgmt")
639
640 def test_ap_wps_setup_locked(dev, apdev):
641     """WPS registrar locking up AP setup on AP PIN failures"""
642     ssid = "test-wps-incorrect-ap-pin"
643     appin = "12345670"
644     hostapd.add_ap(apdev[0]['ifname'],
645                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
646                      "wpa_passphrase": "12345678", "wpa": "2",
647                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
648                      "ap_pin": appin})
649     new_ssid = "wps-new-ssid-test"
650     new_passphrase = "1234567890"
651
652     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
653     ap_setup_locked=False
654     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
655         dev[0].dump_monitor()
656         logger.info("Try incorrect AP PIN - attempt " + pin)
657         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
658                        "CCMP", new_passphrase, no_wait=True)
659         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
660         if ev is None:
661             raise Exception("Timeout on receiving WPS operation failure event")
662         if "CTRL-EVENT-CONNECTED" in ev:
663             raise Exception("Unexpected connection")
664         if "config_error=15" in ev:
665             logger.info("AP Setup Locked")
666             ap_setup_locked=True
667         elif "config_error=18" not in ev:
668             raise Exception("config_error=18 not reported")
669         dev[0].wait_disconnected(timeout=10)
670         time.sleep(0.1)
671     if not ap_setup_locked:
672         raise Exception("AP setup was not locked")
673
674     hapd = hostapd.Hostapd(apdev[0]['ifname'])
675     status = hapd.request("WPS_GET_STATUS")
676     if "Last WPS result: Failed" not in status:
677         raise Exception("WPS failure result not shown correctly")
678     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
679         raise Exception("Peer address not shown correctly")
680
681     time.sleep(0.5)
682     dev[0].dump_monitor()
683     logger.info("WPS provisioning step")
684     pin = dev[0].wps_read_pin()
685     hapd = hostapd.Hostapd(apdev[0]['ifname'])
686     hapd.request("WPS_PIN any " + pin)
687     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
688     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
689     if ev is None:
690         raise Exception("WPS success was not reported")
691     dev[0].wait_connected(timeout=30)
692
693     appin = hapd.request("WPS_AP_PIN random")
694     if "FAIL" in appin:
695         raise Exception("Could not generate random AP PIN")
696     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
697     if ev is None:
698         raise Exception("Failed to unlock AP PIN")
699
700 def test_ap_wps_setup_locked_timeout(dev, apdev):
701     """WPS re-enabling AP PIN after timeout"""
702     ssid = "test-wps-incorrect-ap-pin"
703     appin = "12345670"
704     hostapd.add_ap(apdev[0]['ifname'],
705                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
706                      "wpa_passphrase": "12345678", "wpa": "2",
707                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
708                      "ap_pin": appin})
709     new_ssid = "wps-new-ssid-test"
710     new_passphrase = "1234567890"
711
712     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
713     ap_setup_locked=False
714     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
715         dev[0].dump_monitor()
716         logger.info("Try incorrect AP PIN - attempt " + pin)
717         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
718                        "CCMP", new_passphrase, no_wait=True)
719         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
720         if ev is None:
721             raise Exception("Timeout on receiving WPS operation failure event")
722         if "CTRL-EVENT-CONNECTED" in ev:
723             raise Exception("Unexpected connection")
724         if "config_error=15" in ev:
725             logger.info("AP Setup Locked")
726             ap_setup_locked=True
727             break
728         elif "config_error=18" not in ev:
729             raise Exception("config_error=18 not reported")
730         dev[0].wait_disconnected(timeout=10)
731         time.sleep(0.1)
732     if not ap_setup_locked:
733         raise Exception("AP setup was not locked")
734     hapd = hostapd.Hostapd(apdev[0]['ifname'])
735     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
736     if ev is None:
737         raise Exception("AP PIN did not get unlocked on 60 second timeout")
738
739 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
740     """WPS PBC session overlap with two active APs"""
741     hostapd.add_ap(apdev[0]['ifname'],
742                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
743                      "wpa_passphrase": "12345678", "wpa": "2",
744                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
745                      "wps_independent": "1"})
746     hostapd.add_ap(apdev[1]['ifname'],
747                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
748                      "wpa_passphrase": "123456789", "wpa": "2",
749                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
750                      "wps_independent": "1"})
751     hapd = hostapd.Hostapd(apdev[0]['ifname'])
752     hapd.request("WPS_PBC")
753     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
754     hapd2.request("WPS_PBC")
755     logger.info("WPS provisioning step")
756     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
757     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
758     dev[0].request("WPS_PBC")
759     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
760     if ev is None:
761         raise Exception("PBC session overlap not detected")
762     hapd.request("DISABLE")
763     hapd2.request("DISABLE")
764     dev[0].flush_scan_cache()
765
766 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
767     """WPS PBC session overlap with two active STAs"""
768     ssid = "test-wps-pbc-overlap"
769     hostapd.add_ap(apdev[0]['ifname'],
770                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
771                      "wpa_passphrase": "12345678", "wpa": "2",
772                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
773     hapd = hostapd.Hostapd(apdev[0]['ifname'])
774     logger.info("WPS provisioning step")
775     hapd.request("WPS_PBC")
776     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
777     dev[0].dump_monitor()
778     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
779     dev[1].dump_monitor()
780     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
781     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
782     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
783     if ev is None:
784         raise Exception("PBC session overlap not detected (dev0)")
785     if "config_error=12" not in ev:
786         raise Exception("PBC session overlap not correctly reported (dev0)")
787     dev[0].request("WPS_CANCEL")
788     dev[0].request("DISCONNECT")
789     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
790     if ev is None:
791         raise Exception("PBC session overlap not detected (dev1)")
792     if "config_error=12" not in ev:
793         raise Exception("PBC session overlap not correctly reported (dev1)")
794     dev[1].request("WPS_CANCEL")
795     dev[1].request("DISCONNECT")
796     hapd.request("WPS_CANCEL")
797     ret = hapd.request("WPS_PBC")
798     if "FAIL" not in ret:
799         raise Exception("PBC mode allowed to be started while PBC overlap still active")
800     hapd.request("DISABLE")
801     dev[0].flush_scan_cache()
802     dev[1].flush_scan_cache()
803
804 def test_ap_wps_cancel(dev, apdev):
805     """WPS AP cancelling enabled config method"""
806     ssid = "test-wps-ap-cancel"
807     hostapd.add_ap(apdev[0]['ifname'],
808                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
809                      "wpa_passphrase": "12345678", "wpa": "2",
810                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
811     bssid = apdev[0]['bssid']
812     hapd = hostapd.Hostapd(apdev[0]['ifname'])
813
814     logger.info("Verify PBC enable/cancel")
815     hapd.request("WPS_PBC")
816     dev[0].scan(freq="2412")
817     dev[0].scan(freq="2412")
818     bss = dev[0].get_bss(apdev[0]['bssid'])
819     if "[WPS-PBC]" not in bss['flags']:
820         raise Exception("WPS-PBC flag missing")
821     if "FAIL" in hapd.request("WPS_CANCEL"):
822         raise Exception("WPS_CANCEL failed")
823     dev[0].scan(freq="2412")
824     dev[0].scan(freq="2412")
825     bss = dev[0].get_bss(apdev[0]['bssid'])
826     if "[WPS-PBC]" in bss['flags']:
827         raise Exception("WPS-PBC flag not cleared")
828
829     logger.info("Verify PIN enable/cancel")
830     hapd.request("WPS_PIN any 12345670")
831     dev[0].scan(freq="2412")
832     dev[0].scan(freq="2412")
833     bss = dev[0].get_bss(apdev[0]['bssid'])
834     if "[WPS-AUTH]" not in bss['flags']:
835         raise Exception("WPS-AUTH flag missing")
836     if "FAIL" in hapd.request("WPS_CANCEL"):
837         raise Exception("WPS_CANCEL failed")
838     dev[0].scan(freq="2412")
839     dev[0].scan(freq="2412")
840     bss = dev[0].get_bss(apdev[0]['bssid'])
841     if "[WPS-AUTH]" in bss['flags']:
842         raise Exception("WPS-AUTH flag not cleared")
843
844 def test_ap_wps_er_add_enrollee(dev, apdev):
845     """WPS ER configuring AP and adding a new enrollee using PIN"""
846     try:
847         _test_ap_wps_er_add_enrollee(dev, apdev)
848     finally:
849         dev[0].request("WPS_ER_STOP")
850
851 def _test_ap_wps_er_add_enrollee(dev, apdev):
852     ssid = "wps-er-add-enrollee"
853     ap_pin = "12345670"
854     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
855     hostapd.add_ap(apdev[0]['ifname'],
856                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
857                      "device_name": "Wireless AP", "manufacturer": "Company",
858                      "model_name": "WAP", "model_number": "123",
859                      "serial_number": "12345", "device_type": "6-0050F204-1",
860                      "os_version": "01020300",
861                      "config_methods": "label push_button",
862                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
863     logger.info("WPS configuration step")
864     new_passphrase = "1234567890"
865     dev[0].dump_monitor()
866     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
867     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
868                    new_passphrase)
869     status = dev[0].get_status()
870     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
871         raise Exception("Not fully connected")
872     if status['ssid'] != ssid:
873         raise Exception("Unexpected SSID")
874     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
875         raise Exception("Unexpected encryption configuration")
876     if status['key_mgmt'] != 'WPA2-PSK':
877         raise Exception("Unexpected key_mgmt")
878
879     logger.info("Start ER")
880     dev[0].request("WPS_ER_START ifname=lo")
881     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
882     if ev is None:
883         raise Exception("AP discovery timed out")
884     if ap_uuid not in ev:
885         raise Exception("Expected AP UUID not found")
886
887     logger.info("Learn AP configuration through UPnP")
888     dev[0].dump_monitor()
889     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
890     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
891     if ev is None:
892         raise Exception("AP learn timed out")
893     if ap_uuid not in ev:
894         raise Exception("Expected AP UUID not in settings")
895     if "ssid=" + ssid not in ev:
896         raise Exception("Expected SSID not in settings")
897     if "key=" + new_passphrase not in ev:
898         raise Exception("Expected passphrase not in settings")
899     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
900     if ev is None:
901         raise Exception("WPS-FAIL after AP learn timed out")
902     time.sleep(0.1)
903
904     logger.info("Add Enrollee using ER")
905     pin = dev[1].wps_read_pin()
906     dev[0].dump_monitor()
907     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
908     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
909     dev[1].dump_monitor()
910     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
911     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
912     if ev is None:
913         raise Exception("Enrollee did not report success")
914     dev[1].wait_connected(timeout=15)
915     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
916     if ev is None:
917         raise Exception("WPS ER did not report success")
918     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
919
920     logger.info("Add a specific Enrollee using ER")
921     pin = dev[2].wps_read_pin()
922     addr2 = dev[2].p2p_interface_addr()
923     dev[0].dump_monitor()
924     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
925     dev[2].dump_monitor()
926     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
927     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
928     if ev is None:
929         raise Exception("Enrollee not seen")
930     if addr2 not in ev:
931         raise Exception("Unexpected Enrollee MAC address")
932     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
933     dev[2].wait_connected(timeout=30)
934     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
935     if ev is None:
936         raise Exception("WPS ER did not report success")
937
938     logger.info("Verify registrar selection behavior")
939     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
940     dev[1].request("DISCONNECT")
941     dev[1].wait_disconnected(timeout=10)
942     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
943     dev[1].scan(freq="2412")
944     bss = dev[1].get_bss(apdev[0]['bssid'])
945     if "[WPS-AUTH]" not in bss['flags']:
946         # It is possible for scan to miss an update especially when running
947         # tests under load with multiple VMs, so allow another attempt.
948         dev[1].scan(freq="2412")
949         bss = dev[1].get_bss(apdev[0]['bssid'])
950         if "[WPS-AUTH]" not in bss['flags']:
951             raise Exception("WPS-AUTH flag missing")
952
953     logger.info("Stop ER")
954     dev[0].dump_monitor()
955     dev[0].request("WPS_ER_STOP")
956     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
957     if ev is None:
958         raise Exception("WPS ER unsubscription timed out")
959     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
960     # a bit before verifying that the scan results have changed.
961     time.sleep(0.2)
962
963     for i in range(0, 10):
964         dev[1].request("BSS_FLUSH 0")
965         dev[1].scan(freq="2412", only_new=True)
966         bss = dev[1].get_bss(apdev[0]['bssid'])
967         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
968             break
969         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
970         time.sleep(0.1)
971     if "[WPS-AUTH]" in bss['flags']:
972         raise Exception("WPS-AUTH flag not removed")
973
974 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
975     """WPS ER connected to AP and adding a new enrollee using PBC"""
976     try:
977         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
978     finally:
979         dev[0].request("WPS_ER_STOP")
980
981 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
982     ssid = "wps-er-add-enrollee-pbc"
983     ap_pin = "12345670"
984     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
985     hostapd.add_ap(apdev[0]['ifname'],
986                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
987                      "wpa_passphrase": "12345678", "wpa": "2",
988                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
989                      "device_name": "Wireless AP", "manufacturer": "Company",
990                      "model_name": "WAP", "model_number": "123",
991                      "serial_number": "12345", "device_type": "6-0050F204-1",
992                      "os_version": "01020300",
993                      "config_methods": "label push_button",
994                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
995     logger.info("Learn AP configuration")
996     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
997     dev[0].dump_monitor()
998     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
999     status = dev[0].get_status()
1000     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1001         raise Exception("Not fully connected")
1002
1003     logger.info("Start ER")
1004     dev[0].request("WPS_ER_START ifname=lo")
1005     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1006     if ev is None:
1007         raise Exception("AP discovery timed out")
1008     if ap_uuid not in ev:
1009         raise Exception("Expected AP UUID not found")
1010
1011     enrollee = dev[1].p2p_interface_addr()
1012
1013     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1014         raise Exception("Unknown UUID not reported")
1015
1016     logger.info("Add Enrollee using ER and PBC")
1017     dev[0].dump_monitor()
1018     dev[1].dump_monitor()
1019     dev[1].request("WPS_PBC")
1020
1021     for i in range(0, 2):
1022         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1023         if ev is None:
1024             raise Exception("Enrollee discovery timed out")
1025         if enrollee in ev:
1026             break
1027         if i == 1:
1028             raise Exception("Expected Enrollee not found")
1029     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1030         raise Exception("Unknown UUID not reported")
1031     logger.info("Use learned network configuration on ER")
1032     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1033     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1034         raise Exception("WPS_ER_PBC failed")
1035
1036     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1037     if ev is None:
1038         raise Exception("Enrollee did not report success")
1039     dev[1].wait_connected(timeout=15)
1040     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1041     if ev is None:
1042         raise Exception("WPS ER did not report success")
1043     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1044
1045 def test_ap_wps_er_pbc_overlap(dev, apdev):
1046     """WPS ER connected to AP and PBC session overlap"""
1047     try:
1048         _test_ap_wps_er_pbc_overlap(dev, apdev)
1049     finally:
1050         dev[0].request("WPS_ER_STOP")
1051
1052 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1053     ssid = "wps-er-add-enrollee-pbc"
1054     ap_pin = "12345670"
1055     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1056     hostapd.add_ap(apdev[0]['ifname'],
1057                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1058                      "wpa_passphrase": "12345678", "wpa": "2",
1059                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1060                      "device_name": "Wireless AP", "manufacturer": "Company",
1061                      "model_name": "WAP", "model_number": "123",
1062                      "serial_number": "12345", "device_type": "6-0050F204-1",
1063                      "os_version": "01020300",
1064                      "config_methods": "label push_button",
1065                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1066     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1067     dev[0].dump_monitor()
1068     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1069
1070     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1071     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1072     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1073     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1074
1075     dev[0].dump_monitor()
1076     dev[0].request("WPS_ER_START ifname=lo")
1077
1078     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1079     if ev is None:
1080         raise Exception("AP discovery timed out")
1081     if ap_uuid not in ev:
1082         raise Exception("Expected AP UUID not found")
1083
1084     # verify BSSID selection of the AP instead of UUID
1085     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1086         raise Exception("Could not select AP based on BSSID")
1087
1088     dev[0].dump_monitor()
1089     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1090     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1091     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1092     if ev is None:
1093         raise Exception("PBC scan failed")
1094     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1095     if ev is None:
1096         raise Exception("PBC scan failed")
1097     found1 = False
1098     found2 = False
1099     addr1 = dev[1].own_addr()
1100     addr2 = dev[2].own_addr()
1101     for i in range(3):
1102         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1103         if ev is None:
1104             raise Exception("Enrollee discovery timed out")
1105         if addr1 in ev:
1106             found1 = True
1107             if found2:
1108                 break
1109         if addr2 in ev:
1110             found2 = True
1111             if found1:
1112                 break
1113     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1114         raise Exception("PBC overlap not reported")
1115     dev[1].request("WPS_CANCEL")
1116     dev[2].request("WPS_CANCEL")
1117     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1118         raise Exception("Invalid WPS_ER_PBC accepted")
1119
1120 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1121     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1122     try:
1123         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1124     finally:
1125         dev[0].request("WPS_ER_STOP")
1126
1127 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1128     ssid = "wps-er-add-enrollee-pbc"
1129     ap_pin = "12345670"
1130     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1131     hostapd.add_ap(apdev[0]['ifname'],
1132                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1133                      "wpa_passphrase": "12345678", "wpa": "2",
1134                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1135                      "device_name": "Wireless AP", "manufacturer": "Company",
1136                      "model_name": "WAP", "model_number": "123",
1137                      "serial_number": "12345", "device_type": "6-0050F204-1",
1138                      "os_version": "01020300",
1139                      "config_methods": "label push_button",
1140                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1141     logger.info("Learn AP configuration")
1142     dev[0].request("SET wps_version_number 0x10")
1143     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1144     dev[0].dump_monitor()
1145     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1146     status = dev[0].get_status()
1147     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1148         raise Exception("Not fully connected")
1149
1150     logger.info("Start ER")
1151     dev[0].request("WPS_ER_START ifname=lo")
1152     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1153     if ev is None:
1154         raise Exception("AP discovery timed out")
1155     if ap_uuid not in ev:
1156         raise Exception("Expected AP UUID not found")
1157
1158     logger.info("Use learned network configuration on ER")
1159     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1160
1161     logger.info("Add Enrollee using ER and PIN")
1162     enrollee = dev[1].p2p_interface_addr()
1163     pin = dev[1].wps_read_pin()
1164     dev[0].dump_monitor()
1165     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1166     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1167     dev[1].dump_monitor()
1168     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1169     dev[1].wait_connected(timeout=30)
1170     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1171     if ev is None:
1172         raise Exception("WPS ER did not report success")
1173
1174 def test_ap_wps_er_config_ap(dev, apdev):
1175     """WPS ER configuring AP over UPnP"""
1176     try:
1177         _test_ap_wps_er_config_ap(dev, apdev)
1178     finally:
1179         dev[0].request("WPS_ER_STOP")
1180
1181 def _test_ap_wps_er_config_ap(dev, apdev):
1182     ssid = "wps-er-ap-config"
1183     ap_pin = "12345670"
1184     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1185     hostapd.add_ap(apdev[0]['ifname'],
1186                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1187                      "wpa_passphrase": "12345678", "wpa": "2",
1188                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1189                      "device_name": "Wireless AP", "manufacturer": "Company",
1190                      "model_name": "WAP", "model_number": "123",
1191                      "serial_number": "12345", "device_type": "6-0050F204-1",
1192                      "os_version": "01020300",
1193                      "config_methods": "label push_button",
1194                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1195
1196     logger.info("Connect ER to the AP")
1197     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1198
1199     logger.info("WPS configuration step")
1200     dev[0].request("WPS_ER_START ifname=lo")
1201     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1202     if ev is None:
1203         raise Exception("AP discovery timed out")
1204     if ap_uuid not in ev:
1205         raise Exception("Expected AP UUID not found")
1206     new_passphrase = "1234567890"
1207     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1208                    ssid.encode("hex") + " WPA2PSK CCMP " +
1209                    new_passphrase.encode("hex"))
1210     ev = dev[0].wait_event(["WPS-SUCCESS"])
1211     if ev is None:
1212         raise Exception("WPS ER configuration operation timed out")
1213     dev[0].wait_disconnected(timeout=10)
1214     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1215
1216     logger.info("WPS ER restart")
1217     dev[0].request("WPS_ER_START")
1218     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1219     if ev is None:
1220         raise Exception("AP discovery timed out on ER restart")
1221     if ap_uuid not in ev:
1222         raise Exception("Expected AP UUID not found on ER restart")
1223     if "OK" not in dev[0].request("WPS_ER_STOP"):
1224         raise Exception("WPS_ER_STOP failed")
1225     if "OK" not in dev[0].request("WPS_ER_STOP"):
1226         raise Exception("WPS_ER_STOP failed")
1227
1228 def test_ap_wps_fragmentation(dev, apdev):
1229     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1230     ssid = "test-wps-fragmentation"
1231     appin = "12345670"
1232     hostapd.add_ap(apdev[0]['ifname'],
1233                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1234                      "wpa_passphrase": "12345678", "wpa": "3",
1235                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1236                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1237                      "fragment_size": "50" })
1238     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1239     logger.info("WPS provisioning step (PBC)")
1240     hapd.request("WPS_PBC")
1241     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1242     dev[0].dump_monitor()
1243     dev[0].request("SET wps_fragment_size 50")
1244     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1245     dev[0].wait_connected(timeout=30)
1246     status = dev[0].get_status()
1247     if status['wpa_state'] != 'COMPLETED':
1248         raise Exception("Not fully connected")
1249     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1250         raise Exception("Unexpected encryption configuration")
1251     if status['key_mgmt'] != 'WPA2-PSK':
1252         raise Exception("Unexpected key_mgmt")
1253
1254     logger.info("WPS provisioning step (PIN)")
1255     pin = dev[1].wps_read_pin()
1256     hapd.request("WPS_PIN any " + pin)
1257     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1258     dev[1].request("SET wps_fragment_size 50")
1259     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1260     dev[1].wait_connected(timeout=30)
1261     status = dev[1].get_status()
1262     if status['wpa_state'] != 'COMPLETED':
1263         raise Exception("Not fully connected")
1264     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1265         raise Exception("Unexpected encryption configuration")
1266     if status['key_mgmt'] != 'WPA2-PSK':
1267         raise Exception("Unexpected key_mgmt")
1268
1269     logger.info("WPS connection as registrar")
1270     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1271     dev[2].request("SET wps_fragment_size 50")
1272     dev[2].wps_reg(apdev[0]['bssid'], appin)
1273     status = dev[2].get_status()
1274     if status['wpa_state'] != 'COMPLETED':
1275         raise Exception("Not fully connected")
1276     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1277         raise Exception("Unexpected encryption configuration")
1278     if status['key_mgmt'] != 'WPA2-PSK':
1279         raise Exception("Unexpected key_mgmt")
1280
1281 def test_ap_wps_new_version_sta(dev, apdev):
1282     """WPS compatibility with new version number on the station"""
1283     ssid = "test-wps-ver"
1284     hostapd.add_ap(apdev[0]['ifname'],
1285                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1286                      "wpa_passphrase": "12345678", "wpa": "2",
1287                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1288     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1289     logger.info("WPS provisioning step")
1290     hapd.request("WPS_PBC")
1291     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1292     dev[0].dump_monitor()
1293     dev[0].request("SET wps_version_number 0x43")
1294     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1295     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1296     dev[0].wait_connected(timeout=30)
1297
1298 def test_ap_wps_new_version_ap(dev, apdev):
1299     """WPS compatibility with new version number on the AP"""
1300     ssid = "test-wps-ver"
1301     hostapd.add_ap(apdev[0]['ifname'],
1302                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1303                      "wpa_passphrase": "12345678", "wpa": "2",
1304                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1305     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1306     logger.info("WPS provisioning step")
1307     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1308         raise Exception("Failed to enable test functionality")
1309     hapd.request("WPS_PBC")
1310     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1311     dev[0].dump_monitor()
1312     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1313     dev[0].wait_connected(timeout=30)
1314     hapd.request("SET wps_version_number 0x20")
1315
1316 def test_ap_wps_check_pin(dev, apdev):
1317     """Verify PIN checking through control interface"""
1318     hostapd.add_ap(apdev[0]['ifname'],
1319                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1320                      "wpa_passphrase": "12345678", "wpa": "2",
1321                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1322     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1323     for t in [ ("12345670", "12345670"),
1324                ("12345678", "FAIL-CHECKSUM"),
1325                ("12345", "FAIL"),
1326                ("123456789", "FAIL"),
1327                ("1234-5670", "12345670"),
1328                ("1234 5670", "12345670"),
1329                ("1-2.3:4 5670", "12345670") ]:
1330         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1331         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1332         if res != res2:
1333             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1334         if res != t[1]:
1335             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1336
1337     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1338         raise Exception("Unexpected WPS_CHECK_PIN success")
1339     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1340         raise Exception("Unexpected WPS_CHECK_PIN success")
1341
1342     for i in range(0, 10):
1343         pin = dev[0].request("WPS_PIN get")
1344         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1345         if pin != rpin:
1346             raise Exception("Random PIN validation failed for " + pin)
1347
1348 def test_ap_wps_wep_config(dev, apdev):
1349     """WPS 2.0 AP rejecting WEP configuration"""
1350     ssid = "test-wps-config"
1351     appin = "12345670"
1352     hostapd.add_ap(apdev[0]['ifname'],
1353                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1354                      "ap_pin": appin})
1355     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1356     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1357     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1358                    "hello", no_wait=True)
1359     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1360     if ev is None:
1361         raise Exception("WPS-FAIL timed out")
1362     if "reason=2" not in ev:
1363         raise Exception("Unexpected reason code in WPS-FAIL")
1364     status = hapd.request("WPS_GET_STATUS")
1365     if "Last WPS result: Failed" not in status:
1366         raise Exception("WPS failure result not shown correctly")
1367     if "Failure Reason: WEP Prohibited" not in status:
1368         raise Exception("Failure reason not reported correctly")
1369     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1370         raise Exception("Peer address not shown correctly")
1371
1372 def test_ap_wps_wep_enroll(dev, apdev):
1373     """WPS 2.0 STA rejecting WEP configuration"""
1374     ssid = "test-wps-wep"
1375     hostapd.add_ap(apdev[0]['ifname'],
1376                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1377                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1378     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1379     hapd.request("WPS_PBC")
1380     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1381     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1382     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1383     if ev is None:
1384         raise Exception("WPS-FAIL event timed out")
1385     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1386         raise Exception("Unexpected WPS-FAIL event: " + ev)
1387
1388 def test_ap_wps_ie_fragmentation(dev, apdev):
1389     """WPS AP using fragmented WPS IE"""
1390     ssid = "test-wps-ie-fragmentation"
1391     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1392                "wpa_passphrase": "12345678", "wpa": "2",
1393                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1394                "device_name": "1234567890abcdef1234567890abcdef",
1395                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1396                "model_name": "1234567890abcdef1234567890abcdef",
1397                "model_number": "1234567890abcdef1234567890abcdef",
1398                "serial_number": "1234567890abcdef1234567890abcdef" }
1399     hostapd.add_ap(apdev[0]['ifname'], params)
1400     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1401     hapd.request("WPS_PBC")
1402     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1403     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1404     dev[0].wait_connected(timeout=30)
1405     bss = dev[0].get_bss(apdev[0]['bssid'])
1406     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1407         logger.info("Device Name not received correctly")
1408         logger.info(bss)
1409         # This can fail if Probe Response frame is missed and Beacon frame was
1410         # used to fill in the BSS entry. This can happen, e.g., during heavy
1411         # load every now and then and is not really an error, so try to
1412         # workaround by runnign another scan.
1413         dev[0].scan(freq="2412", only_new=True)
1414         bss = dev[0].get_bss(apdev[0]['bssid'])
1415         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1416             logger.info(bss)
1417             raise Exception("Device Name not received correctly")
1418     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1419         raise Exception("Unexpected number of WPS IEs")
1420
1421 def get_psk(pskfile):
1422     psks = {}
1423     with open(pskfile, "r") as f:
1424         lines = f.read().splitlines()
1425         for l in lines:
1426             if l == "# WPA PSKs":
1427                 continue
1428             (addr,psk) = l.split(' ')
1429             psks[addr] = psk
1430     return psks
1431
1432 def test_ap_wps_per_station_psk(dev, apdev):
1433     """WPS PBC provisioning with per-station PSK"""
1434     addr0 = dev[0].own_addr()
1435     addr1 = dev[1].own_addr()
1436     addr2 = dev[2].own_addr()
1437     ssid = "wps"
1438     appin = "12345670"
1439     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1440     try:
1441         os.remove(pskfile)
1442     except:
1443         pass
1444
1445     try:
1446         with open(pskfile, "w") as f:
1447             f.write("# WPA PSKs\n")
1448
1449         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1450                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1451                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1452                    "wpa_psk_file": pskfile }
1453         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1454
1455         logger.info("First enrollee")
1456         hapd.request("WPS_PBC")
1457         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1458         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1459         dev[0].wait_connected(timeout=30)
1460
1461         logger.info("Second enrollee")
1462         hapd.request("WPS_PBC")
1463         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1464         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1465         dev[1].wait_connected(timeout=30)
1466
1467         logger.info("External registrar")
1468         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1469         dev[2].wps_reg(apdev[0]['bssid'], appin)
1470
1471         logger.info("Verifying PSK results")
1472         psks = get_psk(pskfile)
1473         if addr0 not in psks:
1474             raise Exception("No PSK recorded for sta0")
1475         if addr1 not in psks:
1476             raise Exception("No PSK recorded for sta1")
1477         if addr2 not in psks:
1478             raise Exception("No PSK recorded for sta2")
1479         if psks[addr0] == psks[addr1]:
1480             raise Exception("Same PSK recorded for sta0 and sta1")
1481         if psks[addr0] == psks[addr2]:
1482             raise Exception("Same PSK recorded for sta0 and sta2")
1483         if psks[addr1] == psks[addr2]:
1484             raise Exception("Same PSK recorded for sta1 and sta2")
1485
1486         dev[0].request("REMOVE_NETWORK all")
1487         logger.info("Second external registrar")
1488         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1489         dev[0].wps_reg(apdev[0]['bssid'], appin)
1490         psks2 = get_psk(pskfile)
1491         if addr0 not in psks2:
1492             raise Exception("No PSK recorded for sta0(reg)")
1493         if psks[addr0] == psks2[addr0]:
1494             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
1495     finally:
1496         os.remove(pskfile)
1497
1498 def test_ap_wps_per_station_psk_failure(dev, apdev):
1499     """WPS PBC provisioning with per-station PSK (file not writable)"""
1500     addr0 = dev[0].p2p_dev_addr()
1501     addr1 = dev[1].p2p_dev_addr()
1502     addr2 = dev[2].p2p_dev_addr()
1503     ssid = "wps"
1504     appin = "12345670"
1505     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1506     try:
1507         os.remove(pskfile)
1508     except:
1509         pass
1510
1511     try:
1512         with open(pskfile, "w") as f:
1513             f.write("# WPA PSKs\n")
1514
1515         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1516                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1517                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1518                    "wpa_psk_file": pskfile }
1519         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1520         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
1521             raise Exception("Failed to set wpa_psk_file")
1522
1523         logger.info("First enrollee")
1524         hapd.request("WPS_PBC")
1525         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1526         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1527         dev[0].wait_connected(timeout=30)
1528
1529         logger.info("Second enrollee")
1530         hapd.request("WPS_PBC")
1531         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1532         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1533         dev[1].wait_connected(timeout=30)
1534
1535         logger.info("External registrar")
1536         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1537         dev[2].wps_reg(apdev[0]['bssid'], appin)
1538
1539         logger.info("Verifying PSK results")
1540         psks = get_psk(pskfile)
1541         if len(psks) > 0:
1542             raise Exception("PSK recorded unexpectedly")
1543     finally:
1544         os.remove(pskfile)
1545
1546 def test_ap_wps_pin_request_file(dev, apdev):
1547     """WPS PIN provisioning with configured AP"""
1548     ssid = "wps"
1549     pinfile = "/tmp/ap_wps_pin_request_file.log"
1550     if os.path.exists(pinfile):
1551         os.remove(pinfile)
1552     hostapd.add_ap(apdev[0]['ifname'],
1553                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1554                      "wps_pin_requests": pinfile,
1555                      "wpa_passphrase": "12345678", "wpa": "2",
1556                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
1557     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1558     uuid = dev[0].get_status_field("uuid")
1559     pin = dev[0].wps_read_pin()
1560     try:
1561         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1562         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1563         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
1564         if ev is None:
1565             raise Exception("PIN needed event not shown")
1566         if uuid not in ev:
1567             raise Exception("UUID mismatch")
1568         dev[0].request("WPS_CANCEL")
1569         success = False
1570         with open(pinfile, "r") as f:
1571             lines = f.readlines()
1572             for l in lines:
1573                 if uuid in l:
1574                     success = True
1575                     break
1576         if not success:
1577             raise Exception("PIN request entry not in the log file")
1578     finally:
1579         try:
1580             os.remove(pinfile)
1581         except:
1582             pass
1583
1584 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
1585     """WPS auto-setup with configuration file"""
1586     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
1587     ifname = apdev[0]['ifname']
1588     try:
1589         with open(conffile, "w") as f:
1590             f.write("driver=nl80211\n")
1591             f.write("hw_mode=g\n")
1592             f.write("channel=1\n")
1593             f.write("ieee80211n=1\n")
1594             f.write("interface=%s\n" % ifname)
1595             f.write("ctrl_interface=/var/run/hostapd\n")
1596             f.write("ssid=wps\n")
1597             f.write("eap_server=1\n")
1598             f.write("wps_state=1\n")
1599         hostapd.add_bss('phy3', ifname, conffile)
1600         hapd = hostapd.Hostapd(ifname)
1601         hapd.request("WPS_PBC")
1602         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1603         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1604         dev[0].wait_connected(timeout=30)
1605         with open(conffile, "r") as f:
1606             lines = f.read().splitlines()
1607             vals = dict()
1608             for l in lines:
1609                 try:
1610                     [name,value] = l.split('=', 1)
1611                     vals[name] = value
1612                 except ValueError, e:
1613                     if "# WPS configuration" in l:
1614                         pass
1615                     else:
1616                         raise Exception("Unexpected configuration line: " + l)
1617         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
1618             raise Exception("Incorrect configuration: " + str(vals))
1619     finally:
1620         try:
1621             os.remove(conffile)
1622         except:
1623             pass
1624
1625 def test_ap_wps_pbc_timeout(dev, apdev, params):
1626     """wpa_supplicant PBC walk time [long]"""
1627     if not params['long']:
1628         raise HwsimSkip("Skip test case with long duration due to --long not specified")
1629     ssid = "test-wps"
1630     hostapd.add_ap(apdev[0]['ifname'],
1631                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
1632     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1633     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
1634     if "OK" not in dev[0].request("WPS_PBC"):
1635         raise Exception("WPS_PBC failed")
1636     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=150)
1637     if ev is None:
1638         raise Exception("WPS-TIMEOUT not reported")
1639
1640 def add_ssdp_ap(ifname, ap_uuid):
1641     ssid = "wps-ssdp"
1642     ap_pin = "12345670"
1643     hostapd.add_ap(ifname,
1644                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1645                      "wpa_passphrase": "12345678", "wpa": "2",
1646                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1647                      "device_name": "Wireless AP", "manufacturer": "Company",
1648                      "model_name": "WAP", "model_number": "123",
1649                      "serial_number": "12345", "device_type": "6-0050F204-1",
1650                      "os_version": "01020300",
1651                      "config_methods": "label push_button",
1652                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
1653                      "friendly_name": "WPS Access Point",
1654                      "manufacturer_url": "http://www.example.com/",
1655                      "model_description": "Wireless Access Point",
1656                      "model_url": "http://www.example.com/model/",
1657                      "upc": "123456789012" })
1658
1659 def ssdp_send(msg, no_recv=False):
1660     socket.setdefaulttimeout(1)
1661     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1662     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1663     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1664     sock.bind(("127.0.0.1", 0))
1665     sock.sendto(msg, ("239.255.255.250", 1900))
1666     if no_recv:
1667         return None
1668     return sock.recv(1000)
1669
1670 def ssdp_send_msearch(st):
1671     msg = '\r\n'.join([
1672             'M-SEARCH * HTTP/1.1',
1673             'HOST: 239.255.255.250:1900',
1674             'MX: 1',
1675             'MAN: "ssdp:discover"',
1676             'ST: ' + st,
1677             '', ''])
1678     return ssdp_send(msg)
1679
1680 def test_ap_wps_ssdp_msearch(dev, apdev):
1681     """WPS AP and SSDP M-SEARCH messages"""
1682     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1683     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1684
1685     msg = '\r\n'.join([
1686             'M-SEARCH * HTTP/1.1',
1687             'Host: 239.255.255.250:1900',
1688             'Mx: 1',
1689             'Man: "ssdp:discover"',
1690             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
1691             '', ''])
1692     ssdp_send(msg)
1693
1694     msg = '\r\n'.join([
1695             'M-SEARCH * HTTP/1.1',
1696             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
1697             'mx: \t1\t\t   ',
1698             'man: \t \t "ssdp:discover"   ',
1699             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
1700             '', ''])
1701     ssdp_send(msg)
1702
1703     ssdp_send_msearch("ssdp:all")
1704     ssdp_send_msearch("upnp:rootdevice")
1705     ssdp_send_msearch("uuid:" + ap_uuid)
1706     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
1707     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
1708
1709     msg = '\r\n'.join([
1710             'M-SEARCH * HTTP/1.1',
1711             'HOST:\t239.255.255.250:1900',
1712             'MAN: "ssdp:discover"',
1713             'MX: 130',
1714             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1715             '', ''])
1716     ssdp_send(msg, no_recv=True)
1717
1718 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
1719     """WPS AP and invalid SSDP M-SEARCH messages"""
1720     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1721     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1722
1723     socket.setdefaulttimeout(1)
1724     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1725     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1726     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1727     sock.bind(("127.0.0.1", 0))
1728
1729     logger.debug("Missing MX")
1730     msg = '\r\n'.join([
1731             'M-SEARCH * HTTP/1.1',
1732             'HOST: 239.255.255.250:1900',
1733             'MAN: "ssdp:discover"',
1734             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1735             '', ''])
1736     sock.sendto(msg, ("239.255.255.250", 1900))
1737
1738     logger.debug("Negative MX")
1739     msg = '\r\n'.join([
1740             'M-SEARCH * HTTP/1.1',
1741             'HOST: 239.255.255.250:1900',
1742             'MX: -1',
1743             'MAN: "ssdp:discover"',
1744             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1745             '', ''])
1746     sock.sendto(msg, ("239.255.255.250", 1900))
1747
1748     logger.debug("Invalid MX")
1749     msg = '\r\n'.join([
1750             'M-SEARCH * HTTP/1.1',
1751             'HOST: 239.255.255.250:1900',
1752             'MX; 1',
1753             'MAN: "ssdp:discover"',
1754             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1755             '', ''])
1756     sock.sendto(msg, ("239.255.255.250", 1900))
1757
1758     logger.debug("Missing MAN")
1759     msg = '\r\n'.join([
1760             'M-SEARCH * HTTP/1.1',
1761             'HOST: 239.255.255.250:1900',
1762             'MX: 1',
1763             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1764             '', ''])
1765     sock.sendto(msg, ("239.255.255.250", 1900))
1766
1767     logger.debug("Invalid MAN")
1768     msg = '\r\n'.join([
1769             'M-SEARCH * HTTP/1.1',
1770             'HOST: 239.255.255.250:1900',
1771             'MX: 1',
1772             'MAN: foo',
1773             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1774             '', ''])
1775     sock.sendto(msg, ("239.255.255.250", 1900))
1776     msg = '\r\n'.join([
1777             'M-SEARCH * HTTP/1.1',
1778             'HOST: 239.255.255.250:1900',
1779             'MX: 1',
1780             'MAN; "ssdp:discover"',
1781             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1782             '', ''])
1783     sock.sendto(msg, ("239.255.255.250", 1900))
1784
1785     logger.debug("Missing HOST")
1786     msg = '\r\n'.join([
1787             'M-SEARCH * HTTP/1.1',
1788             'MAN: "ssdp:discover"',
1789             'MX: 1',
1790             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1791             '', ''])
1792     sock.sendto(msg, ("239.255.255.250", 1900))
1793
1794     logger.debug("Missing ST")
1795     msg = '\r\n'.join([
1796             'M-SEARCH * HTTP/1.1',
1797             'HOST: 239.255.255.250:1900',
1798             'MAN: "ssdp:discover"',
1799             'MX: 1',
1800             '', ''])
1801     sock.sendto(msg, ("239.255.255.250", 1900))
1802
1803     logger.debug("Mismatching ST")
1804     msg = '\r\n'.join([
1805             'M-SEARCH * HTTP/1.1',
1806             'HOST: 239.255.255.250:1900',
1807             'MAN: "ssdp:discover"',
1808             'MX: 1',
1809             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
1810             '', ''])
1811     sock.sendto(msg, ("239.255.255.250", 1900))
1812     msg = '\r\n'.join([
1813             'M-SEARCH * HTTP/1.1',
1814             'HOST: 239.255.255.250:1900',
1815             'MAN: "ssdp:discover"',
1816             'MX: 1',
1817             'ST: foo:bar',
1818             '', ''])
1819     sock.sendto(msg, ("239.255.255.250", 1900))
1820     msg = '\r\n'.join([
1821             'M-SEARCH * HTTP/1.1',
1822             'HOST: 239.255.255.250:1900',
1823             'MAN: "ssdp:discover"',
1824             'MX: 1',
1825             'ST: foobar',
1826             '', ''])
1827     sock.sendto(msg, ("239.255.255.250", 1900))
1828
1829     logger.debug("Invalid ST")
1830     msg = '\r\n'.join([
1831             'M-SEARCH * HTTP/1.1',
1832             'HOST: 239.255.255.250:1900',
1833             'MAN: "ssdp:discover"',
1834             'MX: 1',
1835             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
1836             '', ''])
1837     sock.sendto(msg, ("239.255.255.250", 1900))
1838
1839     logger.debug("Invalid M-SEARCH")
1840     msg = '\r\n'.join([
1841             'M+SEARCH * HTTP/1.1',
1842             'HOST: 239.255.255.250:1900',
1843             'MAN: "ssdp:discover"',
1844             'MX: 1',
1845             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1846             '', ''])
1847     sock.sendto(msg, ("239.255.255.250", 1900))
1848     msg = '\r\n'.join([
1849             'M-SEARCH-* HTTP/1.1',
1850             'HOST: 239.255.255.250:1900',
1851             'MAN: "ssdp:discover"',
1852             'MX: 1',
1853             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1854             '', ''])
1855     sock.sendto(msg, ("239.255.255.250", 1900))
1856
1857     logger.debug("Invalid message format")
1858     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
1859     msg = '\r'.join([
1860             'M-SEARCH * HTTP/1.1',
1861             'HOST: 239.255.255.250:1900',
1862             'MAN: "ssdp:discover"',
1863             'MX: 1',
1864             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1865             '', ''])
1866     sock.sendto(msg, ("239.255.255.250", 1900))
1867
1868     try:
1869         r = sock.recv(1000)
1870         raise Exception("Unexpected M-SEARCH response: " + r)
1871     except socket.timeout:
1872         pass
1873
1874     logger.debug("Valid M-SEARCH")
1875     msg = '\r\n'.join([
1876             'M-SEARCH * HTTP/1.1',
1877             'HOST: 239.255.255.250:1900',
1878             'MAN: "ssdp:discover"',
1879             'MX: 1',
1880             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1881             '', ''])
1882     sock.sendto(msg, ("239.255.255.250", 1900))
1883
1884     try:
1885         r = sock.recv(1000)
1886         pass
1887     except socket.timeout:
1888         raise Exception("No SSDP response")
1889
1890 def test_ap_wps_ssdp_burst(dev, apdev):
1891     """WPS AP and SSDP burst"""
1892     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1893     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1894
1895     msg = '\r\n'.join([
1896             'M-SEARCH * HTTP/1.1',
1897             'HOST: 239.255.255.250:1900',
1898             'MAN: "ssdp:discover"',
1899             'MX: 1',
1900             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
1901             '', ''])
1902     socket.setdefaulttimeout(1)
1903     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1904     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1905     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1906     sock.bind(("127.0.0.1", 0))
1907     for i in range(0, 25):
1908         sock.sendto(msg, ("239.255.255.250", 1900))
1909     resp = 0
1910     while True:
1911         try:
1912             r = sock.recv(1000)
1913             if not r.startswith("HTTP/1.1 200 OK\r\n"):
1914                 raise Exception("Unexpected message: " + r)
1915             resp += 1
1916         except socket.timeout:
1917             break
1918     if resp < 20:
1919         raise Exception("Too few SSDP responses")
1920
1921     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
1922     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1923     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
1924     sock.bind(("127.0.0.1", 0))
1925     for i in range(0, 25):
1926         sock.sendto(msg, ("239.255.255.250", 1900))
1927     while True:
1928         try:
1929             r = sock.recv(1000)
1930             if ap_uuid in r:
1931                 break
1932         except socket.timeout:
1933             raise Exception("No SSDP response")
1934
1935 def ssdp_get_location(uuid):
1936     res = ssdp_send_msearch("uuid:" + uuid)
1937     location = None
1938     for l in res.splitlines():
1939         if l.lower().startswith("location:"):
1940             location = l.split(':', 1)[1].strip()
1941             break
1942     if location is None:
1943         raise Exception("No UPnP location found")
1944     return location
1945
1946 def upnp_get_urls(location):
1947     conn = urllib.urlopen(location)
1948     tree = ET.parse(conn)
1949     root = tree.getroot()
1950     urn = '{urn:schemas-upnp-org:device-1-0}'
1951     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
1952     res = {}
1953     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
1954     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
1955     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
1956     return res
1957
1958 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
1959     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
1960     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
1961     ET.register_namespace('soapenv', soapns)
1962     ET.register_namespace('wfa', wpsns)
1963     attrib = {}
1964     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
1965     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
1966     body = ET.SubElement(root, "{%s}Body" % soapns)
1967     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
1968     tree = ET.ElementTree(root)
1969     soap = StringIO.StringIO()
1970     tree.write(soap, xml_declaration=True, encoding='utf-8')
1971
1972     headers = { "Content-type": 'text/xml; charset="utf-8"' }
1973     if include_soap_action:
1974         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
1975     elif soap_action_override:
1976         headers["SOAPAction"] = soap_action_override
1977     conn.request("POST", path, soap.getvalue(), headers)
1978     return conn.getresponse()
1979
1980 def test_ap_wps_upnp(dev, apdev):
1981     """WPS AP and UPnP operations"""
1982     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1983     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
1984
1985     location = ssdp_get_location(ap_uuid)
1986     urls = upnp_get_urls(location)
1987
1988     conn = urllib.urlopen(urls['scpd_url'])
1989     scpd = conn.read()
1990
1991     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
1992     if conn.getcode() != 404:
1993         raise Exception("Unexpected HTTP response to GET unknown URL")
1994
1995     url = urlparse.urlparse(location)
1996     conn = httplib.HTTPConnection(url.netloc)
1997     #conn.set_debuglevel(1)
1998     headers = { "Content-type": 'text/xml; charset="utf-8"',
1999                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2000     conn.request("POST", "hello", "\r\n\r\n", headers)
2001     resp = conn.getresponse()
2002     if resp.status != 404:
2003         raise Exception("Unexpected HTTP response: %s" % resp.status)
2004
2005     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2006     resp = conn.getresponse()
2007     if resp.status != 501:
2008         raise Exception("Unexpected HTTP response: %s" % resp.status)
2009
2010     headers = { "Content-type": 'text/xml; charset="utf-8"',
2011                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2012     ctrlurl = urlparse.urlparse(urls['control_url'])
2013     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2014     resp = conn.getresponse()
2015     if resp.status != 401:
2016         raise Exception("Unexpected HTTP response: %s" % resp.status)
2017
2018     logger.debug("GetDeviceInfo without SOAPAction header")
2019     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2020                             include_soap_action=False)
2021     if resp.status != 401:
2022         raise Exception("Unexpected HTTP response: %s" % resp.status)
2023
2024     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2025     for act in [ "foo",
2026                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2027                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2028                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2029         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2030                                 include_soap_action=False,
2031                                 soap_action_override=act)
2032         if resp.status != 401:
2033             raise Exception("Unexpected HTTP response: %s" % resp.status)
2034
2035     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2036     if resp.status != 200:
2037         raise Exception("Unexpected HTTP response: %s" % resp.status)
2038     dev = resp.read()
2039     if "NewDeviceInfo" not in dev:
2040         raise Exception("Unexpected GetDeviceInfo response")
2041
2042     logger.debug("PutMessage without required parameters")
2043     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2044     if resp.status != 600:
2045         raise Exception("Unexpected HTTP response: %s" % resp.status)
2046
2047     logger.debug("PutWLANResponse without required parameters")
2048     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2049     if resp.status != 600:
2050         raise Exception("Unexpected HTTP response: %s" % resp.status)
2051
2052     logger.debug("SetSelectedRegistrar from unregistered ER")
2053     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2054     if resp.status != 501:
2055         raise Exception("Unexpected HTTP response: %s" % resp.status)
2056
2057     logger.debug("Unknown action")
2058     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2059     if resp.status != 401:
2060         raise Exception("Unexpected HTTP response: %s" % resp.status)
2061
2062 def test_ap_wps_upnp_subscribe(dev, apdev):
2063     """WPS AP and UPnP event subscription"""
2064     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2065     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2066
2067     location = ssdp_get_location(ap_uuid)
2068     urls = upnp_get_urls(location)
2069     eventurl = urlparse.urlparse(urls['event_sub_url'])
2070
2071     url = urlparse.urlparse(location)
2072     conn = httplib.HTTPConnection(url.netloc)
2073     #conn.set_debuglevel(1)
2074     headers = { "callback": '<http://127.0.0.1:12345/event>',
2075                 "timeout": "Second-1234" }
2076     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2077     resp = conn.getresponse()
2078     if resp.status != 412:
2079         raise Exception("Unexpected HTTP response: %s" % resp.status)
2080
2081     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2082     resp = conn.getresponse()
2083     if resp.status != 412:
2084         raise Exception("Unexpected HTTP response: %s" % resp.status)
2085
2086     headers = { "NT": "upnp:event",
2087                 "timeout": "Second-1234" }
2088     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2089     resp = conn.getresponse()
2090     if resp.status != 412:
2091         raise Exception("Unexpected HTTP response: %s" % resp.status)
2092
2093     headers = { "callback": '<http://127.0.0.1:12345/event>',
2094                 "NT": "upnp:foobar",
2095                 "timeout": "Second-1234" }
2096     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2097     resp = conn.getresponse()
2098     if resp.status != 400:
2099         raise Exception("Unexpected HTTP response: %s" % resp.status)
2100
2101     logger.debug("Valid subscription")
2102     headers = { "callback": '<http://127.0.0.1:12345/event>',
2103                 "NT": "upnp:event",
2104                 "timeout": "Second-1234" }
2105     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2106     resp = conn.getresponse()
2107     if resp.status != 200:
2108         raise Exception("Unexpected HTTP response: %s" % resp.status)
2109     sid = resp.getheader("sid")
2110     logger.debug("Subscription SID " + sid)
2111
2112     logger.debug("Invalid re-subscription")
2113     headers = { "NT": "upnp:event",
2114                 "sid": "123456734567854",
2115                 "timeout": "Second-1234" }
2116     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2117     resp = conn.getresponse()
2118     if resp.status != 400:
2119         raise Exception("Unexpected HTTP response: %s" % resp.status)
2120
2121     logger.debug("Invalid re-subscription")
2122     headers = { "NT": "upnp:event",
2123                 "sid": "uuid:123456734567854",
2124                 "timeout": "Second-1234" }
2125     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2126     resp = conn.getresponse()
2127     if resp.status != 400:
2128         raise Exception("Unexpected HTTP response: %s" % resp.status)
2129
2130     logger.debug("Invalid re-subscription")
2131     headers = { "callback": '<http://127.0.0.1:12345/event>',
2132                 "NT": "upnp:event",
2133                 "sid": sid,
2134                 "timeout": "Second-1234" }
2135     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2136     resp = conn.getresponse()
2137     if resp.status != 400:
2138         raise Exception("Unexpected HTTP response: %s" % resp.status)
2139
2140     logger.debug("SID mismatch in re-subscription")
2141     headers = { "NT": "upnp:event",
2142                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2143                 "timeout": "Second-1234" }
2144     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2145     resp = conn.getresponse()
2146     if resp.status != 412:
2147         raise Exception("Unexpected HTTP response: %s" % resp.status)
2148
2149     logger.debug("Valid re-subscription")
2150     headers = { "NT": "upnp:event",
2151                 "sid": sid,
2152                 "timeout": "Second-1234" }
2153     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2154     resp = conn.getresponse()
2155     if resp.status != 200:
2156         raise Exception("Unexpected HTTP response: %s" % resp.status)
2157     sid2 = resp.getheader("sid")
2158     logger.debug("Subscription SID " + sid2)
2159
2160     if sid != sid2:
2161         raise Exception("Unexpected SID change")
2162
2163     logger.debug("Valid re-subscription")
2164     headers = { "NT": "upnp:event",
2165                 "sid": "uuid: \t \t" + sid.split(':')[1],
2166                 "timeout": "Second-1234" }
2167     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2168     resp = conn.getresponse()
2169     if resp.status != 200:
2170         raise Exception("Unexpected HTTP response: %s" % resp.status)
2171
2172     logger.debug("Invalid unsubscription")
2173     headers = { "sid": sid }
2174     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2175     resp = conn.getresponse()
2176     if resp.status != 412:
2177         raise Exception("Unexpected HTTP response: %s" % resp.status)
2178     headers = { "foo": "bar" }
2179     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2180     resp = conn.getresponse()
2181     if resp.status != 412:
2182         raise Exception("Unexpected HTTP response: %s" % resp.status)
2183
2184     logger.debug("Valid unsubscription")
2185     headers = { "sid": sid }
2186     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2187     resp = conn.getresponse()
2188     if resp.status != 200:
2189         raise Exception("Unexpected HTTP response: %s" % resp.status)
2190
2191     logger.debug("Unsubscription for not existing SID")
2192     headers = { "sid": sid }
2193     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2194     resp = conn.getresponse()
2195     if resp.status != 412:
2196         raise Exception("Unexpected HTTP response: %s" % resp.status)
2197
2198     logger.debug("Invalid unsubscription")
2199     headers = { "sid": " \t \tfoo" }
2200     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2201     resp = conn.getresponse()
2202     if resp.status != 400:
2203         raise Exception("Unexpected HTTP response: %s" % resp.status)
2204
2205     logger.debug("Invalid unsubscription")
2206     headers = { "sid": "uuid:\t \tfoo" }
2207     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2208     resp = conn.getresponse()
2209     if resp.status != 400:
2210         raise Exception("Unexpected HTTP response: %s" % resp.status)
2211
2212     logger.debug("Invalid unsubscription")
2213     headers = { "NT": "upnp:event",
2214                 "sid": sid }
2215     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2216     resp = conn.getresponse()
2217     if resp.status != 400:
2218         raise Exception("Unexpected HTTP response: %s" % resp.status)
2219     headers = { "callback": '<http://127.0.0.1:12345/event>',
2220                 "sid": sid }
2221     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2222     resp = conn.getresponse()
2223     if resp.status != 400:
2224         raise Exception("Unexpected HTTP response: %s" % resp.status)
2225
2226     logger.debug("Valid subscription with multiple callbacks")
2227     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>',
2228                 "NT": "upnp:event",
2229                 "timeout": "Second-1234" }
2230     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2231     resp = conn.getresponse()
2232     if resp.status != 200:
2233         raise Exception("Unexpected HTTP response: %s" % resp.status)
2234     sid = resp.getheader("sid")
2235     logger.debug("Subscription SID " + sid)
2236
2237 def test_ap_wps_upnp_http_proto(dev, apdev):
2238     """WPS AP and UPnP/HTTP protocol testing"""
2239     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2240     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2241
2242     location = ssdp_get_location(ap_uuid)
2243
2244     url = urlparse.urlparse(location)
2245     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
2246     #conn.set_debuglevel(1)
2247
2248     conn.request("HEAD", "hello")
2249     resp = conn.getresponse()
2250     if resp.status != 501:
2251         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2252     conn.close()
2253
2254     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
2255         try:
2256             conn.request(cmd, "hello")
2257             resp = conn.getresponse()
2258         except Exception, e:
2259             pass
2260         conn.close()
2261
2262     headers = { "Content-Length": 'abc' }
2263     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2264     try:
2265         resp = conn.getresponse()
2266     except Exception, e:
2267         pass
2268     conn.close()
2269
2270     headers = { "Content-Length": '-10' }
2271     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2272     try:
2273         resp = conn.getresponse()
2274     except Exception, e:
2275         pass
2276     conn.close()
2277
2278     headers = { "Content-Length": '10000000000000' }
2279     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
2280     try:
2281         resp = conn.getresponse()
2282     except Exception, e:
2283         pass
2284     conn.close()
2285
2286     headers = { "Transfer-Encoding": 'abc' }
2287     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2288     resp = conn.getresponse()
2289     if resp.status != 501:
2290         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2291     conn.close()
2292
2293     headers = { "Transfer-Encoding": 'chunked' }
2294     conn.request("HEAD", "hello", "\r\n\r\n", headers)
2295     resp = conn.getresponse()
2296     if resp.status != 501:
2297         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2298     conn.close()
2299
2300     # Too long a header
2301     conn.request("HEAD", 5000 * 'A')
2302     try:
2303         resp = conn.getresponse()
2304     except Exception, e:
2305         pass
2306     conn.close()
2307
2308     # Long URL but within header length limits
2309     conn.request("HEAD", 3000 * 'A')
2310     resp = conn.getresponse()
2311     if resp.status != 501:
2312         raise Exception("Unexpected response to HEAD: " + str(resp.status))
2313     conn.close()
2314
2315     headers = { "Content-Length": '20' }
2316     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
2317     try:
2318         resp = conn.getresponse()
2319     except Exception, e:
2320         pass
2321     conn.close()
2322
2323     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
2324     resp = conn.getresponse()
2325     if resp.status != 404:
2326         raise Exception("Unexpected HTTP response: %s" % resp.status)
2327     conn.close()
2328
2329     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
2330     try:
2331         resp = conn.getresponse()
2332     except Exception, e:
2333         pass
2334     conn.close()
2335
2336 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
2337     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
2338     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2339     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2340
2341     location = ssdp_get_location(ap_uuid)
2342
2343     url = urlparse.urlparse(location)
2344     conn = httplib.HTTPConnection(url.netloc)
2345     #conn.set_debuglevel(1)
2346
2347     headers = { "Transfer-Encoding": 'chunked' }
2348     conn.request("POST", "hello",
2349                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
2350                  headers)
2351     resp = conn.getresponse()
2352     if resp.status != 404:
2353         raise Exception("Unexpected HTTP response: %s" % resp.status)
2354     conn.close()
2355
2356     conn.putrequest("POST", "hello")
2357     conn.putheader('Transfer-Encoding', 'chunked')
2358     conn.endheaders()
2359     conn.send("a\r\nabcdefghij\r\n")
2360     time.sleep(0.1)
2361     conn.send("2\r\nkl\r\n")
2362     conn.send("0\r\n\r\n")
2363     resp = conn.getresponse()
2364     if resp.status != 404:
2365         raise Exception("Unexpected HTTP response: %s" % resp.status)
2366     conn.close()
2367
2368     conn.putrequest("POST", "hello")
2369     conn.putheader('Transfer-Encoding', 'chunked')
2370     conn.endheaders()
2371     completed = False
2372     try:
2373         for i in range(20000):
2374             conn.send("1\r\nZ\r\n")
2375         conn.send("0\r\n\r\n")
2376         resp = conn.getresponse()
2377         completed = True
2378     except Exception, e:
2379         pass
2380     conn.close()
2381     if completed:
2382         raise Exception("Too long chunked request did not result in connection reset")
2383
2384     headers = { "Transfer-Encoding": 'chunked' }
2385     conn.request("POST", "hello", "80000000\r\na", headers)
2386     try:
2387         resp = conn.getresponse()
2388     except Exception, e:
2389         pass
2390     conn.close()
2391
2392     conn.request("POST", "hello", "10000000\r\na", headers)
2393     try:
2394         resp = conn.getresponse()
2395     except Exception, e:
2396         pass
2397     conn.close()
2398
2399 def test_ap_wps_disabled(dev, apdev):
2400     """WPS operations while WPS is disabled"""
2401     ssid = "test-wps-disabled"
2402     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
2403     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2404     if "FAIL" not in hapd.request("WPS_PBC"):
2405         raise Exception("WPS_PBC succeeded unexpectedly")
2406     if "FAIL" not in hapd.request("WPS_CANCEL"):
2407         raise Exception("WPS_CANCEL succeeded unexpectedly")
2408
2409 def test_ap_wps_mixed_cred(dev, apdev):
2410     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
2411     ssid = "test-wps-wep"
2412     hostapd.add_ap(apdev[0]['ifname'],
2413                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2414                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
2415     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2416     hapd.request("WPS_PBC")
2417     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2418     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2419     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
2420     if ev is None:
2421         raise Exception("WPS-SUCCESS event timed out")
2422     nets = dev[0].list_networks()
2423     if len(nets) != 1:
2424         raise Exception("Unexpected number of network blocks")
2425     id = nets[0]['id']
2426     proto = dev[0].get_network(id, "proto")
2427     if proto != "WPA RSN":
2428         raise Exception("Unexpected merged proto field value: " + proto)
2429     pairwise = dev[0].get_network(id, "pairwise")
2430     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
2431         raise Exception("Unexpected merged pairwise field value: " + pairwise)
2432
2433 def test_ap_wps_while_connected(dev, apdev):
2434     """WPS PBC provisioning while connected to another AP"""
2435     ssid = "test-wps-conf"
2436     hostapd.add_ap(apdev[0]['ifname'],
2437                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2438                      "wpa_passphrase": "12345678", "wpa": "2",
2439                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2440     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2441
2442     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2443     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2444
2445     logger.info("WPS provisioning step")
2446     hapd.request("WPS_PBC")
2447     dev[0].dump_monitor()
2448     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2449     dev[0].wait_connected(timeout=30)
2450     status = dev[0].get_status()
2451     if status['bssid'] != apdev[0]['bssid']:
2452         raise Exception("Unexpected BSSID")
2453
2454 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
2455     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
2456     ssid = "test-wps-conf"
2457     hostapd.add_ap(apdev[0]['ifname'],
2458                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2459                      "wpa_passphrase": "12345678", "wpa": "2",
2460                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2461     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2462
2463     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
2464
2465     try:
2466         dev[0].request("STA_AUTOCONNECT 0")
2467         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
2468
2469         logger.info("WPS provisioning step")
2470         hapd.request("WPS_PBC")
2471         dev[0].dump_monitor()
2472         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2473         dev[0].wait_connected(timeout=30)
2474         status = dev[0].get_status()
2475         if status['bssid'] != apdev[0]['bssid']:
2476             raise Exception("Unexpected BSSID")
2477     finally:
2478         dev[0].request("STA_AUTOCONNECT 1")
2479
2480 def test_ap_wps_from_event(dev, apdev):
2481     """WPS PBC event on AP to enable PBC"""
2482     ssid = "test-wps-conf"
2483     hapd = hostapd.add_ap(apdev[0]['ifname'],
2484                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2485                             "wpa_passphrase": "12345678", "wpa": "2",
2486                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2487     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2488     dev[0].dump_monitor()
2489     hapd.dump_monitor()
2490     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2491
2492     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
2493     if ev is None:
2494         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
2495     vals = ev.split(' ')
2496     if vals[1] != dev[0].p2p_interface_addr():
2497         raise Exception("Unexpected enrollee address: " + vals[1])
2498     if vals[5] != '4':
2499         raise Exception("Unexpected Device Password Id: " + vals[5])
2500     hapd.request("WPS_PBC")
2501     dev[0].wait_connected(timeout=30)
2502
2503 def test_ap_wps_ap_scan_2(dev, apdev):
2504     """AP_SCAN 2 for WPS"""
2505     ssid = "test-wps-conf"
2506     hapd = hostapd.add_ap(apdev[0]['ifname'],
2507                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2508                             "wpa_passphrase": "12345678", "wpa": "2",
2509                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2510     hapd.request("WPS_PBC")
2511
2512     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
2513     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
2514
2515     if "OK" not in wpas.request("AP_SCAN 2"):
2516         raise Exception("Failed to set AP_SCAN 2")
2517
2518     wpas.flush_scan_cache()
2519     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
2520     wpas.request("WPS_PBC " + apdev[0]['bssid'])
2521     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
2522     if ev is None:
2523         raise Exception("WPS-SUCCESS event timed out")
2524     wpas.wait_connected(timeout=30)
2525     wpas.request("DISCONNECT")
2526     wpas.request("BSS_FLUSH 0")
2527     wpas.dump_monitor()
2528     wpas.request("REASSOCIATE")
2529     wpas.wait_connected(timeout=30)
2530
2531 def test_ap_wps_eapol_workaround(dev, apdev):
2532     """EAPOL workaround code path for 802.1X header length mismatch"""
2533     ssid = "test-wps"
2534     hostapd.add_ap(apdev[0]['ifname'],
2535                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
2536     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2537     bssid = apdev[0]['bssid']
2538     hapd.request("SET ext_eapol_frame_io 1")
2539     dev[0].request("SET ext_eapol_frame_io 1")
2540     hapd.request("WPS_PBC")
2541     dev[0].request("WPS_PBC")
2542
2543     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2544     if ev is None:
2545         raise Exception("Timeout on EAPOL-TX from hostapd")
2546
2547     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
2548     if "OK" not in res:
2549         raise Exception("EAPOL_RX to wpa_supplicant failed")
2550
2551 def test_ap_wps_iteration(dev, apdev):
2552     """WPS PIN and iterate through APs without selected registrar"""
2553     ssid = "test-wps-conf"
2554     hapd = hostapd.add_ap(apdev[0]['ifname'],
2555                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2556                             "wpa_passphrase": "12345678", "wpa": "2",
2557                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2558
2559     ssid2 = "test-wps-conf2"
2560     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
2561                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
2562                              "wpa_passphrase": "12345678", "wpa": "2",
2563                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2564
2565     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2566     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
2567     dev[0].dump_monitor()
2568     pin = dev[0].request("WPS_PIN any")
2569
2570     # Wait for iteration through all WPS APs to happen before enabling any
2571     # Registrar.
2572     for i in range(2):
2573         ev = dev[0].wait_event(["Associated with"], timeout=30)
2574         if ev is None:
2575             raise Exception("No association seen")
2576         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
2577         if ev is None:
2578             raise Exception("No M2D from AP")
2579         dev[0].wait_disconnected()
2580
2581     # Verify that each AP requested PIN
2582     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
2583     if ev is None:
2584         raise Exception("No WPS-PIN-NEEDED event from AP")
2585     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
2586     if ev is None:
2587         raise Exception("No WPS-PIN-NEEDED event from AP2")
2588
2589     # Provide PIN to one of the APs and verify that connection gets formed
2590     hapd.request("WPS_PIN any " + pin)
2591     dev[0].wait_connected(timeout=30)
2592
2593 def test_ap_wps_iteration_error(dev, apdev):
2594     """WPS AP iteration on no Selected Registrar and error case with an AP"""
2595     ssid = "test-wps-conf-pin"
2596     hapd = hostapd.add_ap(apdev[0]['ifname'],
2597                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2598                             "wpa_passphrase": "12345678", "wpa": "2",
2599                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2600                             "wps_independent": "1" })
2601     hapd.request("SET ext_eapol_frame_io 1")
2602     bssid = apdev[0]['bssid']
2603     pin = dev[0].wps_read_pin()
2604     dev[0].request("WPS_PIN any " + pin)
2605
2606     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2607     if ev is None:
2608         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
2609     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
2610
2611     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
2612     if ev is None:
2613         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
2614     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
2615     if ev is None:
2616         raise Exception("No CTRL-EVENT-EAP-STARTED")
2617
2618     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
2619     # a case with an incorrectly behaving WPS AP.
2620
2621     # Start the real target AP and activate registrar on it.
2622     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
2623                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2624                             "wpa_passphrase": "12345678", "wpa": "2",
2625                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2626                             "wps_independent": "1" })
2627     hapd2.request("WPS_PIN any " + pin)
2628
2629     dev[0].wait_disconnected(timeout=15)
2630     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
2631     if ev is None:
2632         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
2633     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
2634     if ev is None:
2635         raise Exception("No WPS-CRED-RECEIVED for the second AP")
2636     dev[0].wait_connected(timeout=15)
2637
2638 def test_ap_wps_priority(dev, apdev):
2639     """WPS PIN provisioning with configured AP and wps_priority"""
2640     ssid = "test-wps-conf-pin"
2641     hostapd.add_ap(apdev[0]['ifname'],
2642                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2643                      "wpa_passphrase": "12345678", "wpa": "2",
2644                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2645     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2646     logger.info("WPS provisioning step")
2647     pin = dev[0].wps_read_pin()
2648     hapd.request("WPS_PIN any " + pin)
2649     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2650     dev[0].dump_monitor()
2651     try:
2652         dev[0].request("SET wps_priority 6")
2653         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2654         dev[0].wait_connected(timeout=30)
2655         netw = dev[0].list_networks()
2656         prio = dev[0].get_network(netw[0]['id'], 'priority')
2657         if prio != '6':
2658             raise Exception("Unexpected network priority: " + prio)
2659     finally:
2660         dev[0].request("SET wps_priority 0")
2661
2662 def test_ap_wps_init_oom(dev, apdev):
2663     """Initial AP configuration and OOM during PSK generation"""
2664     ssid = "test-wps"
2665     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
2666     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2667
2668     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
2669         pin = dev[0].wps_read_pin()
2670         hapd.request("WPS_PIN any " + pin)
2671         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2672         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2673         dev[0].wait_disconnected()
2674
2675     hapd.request("WPS_PIN any " + pin)
2676     dev[0].wait_connected(timeout=30)
2677
2678 def test_ap_wps_er_oom(dev, apdev):
2679     """WPS ER OOM in XML processing"""
2680     try:
2681         _test_ap_wps_er_oom(dev, apdev)
2682     finally:
2683         dev[0].request("WPS_ER_STOP")
2684         dev[1].request("WPS_CANCEL")
2685         dev[0].request("DISCONNECT")
2686
2687 def _test_ap_wps_er_oom(dev, apdev):
2688     ssid = "wps-er-ap-config"
2689     ap_pin = "12345670"
2690     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2691     hostapd.add_ap(apdev[0]['ifname'],
2692                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2693                      "wpa_passphrase": "12345678", "wpa": "2",
2694                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2695                      "device_name": "Wireless AP", "manufacturer": "Company",
2696                      "model_name": "WAP", "model_number": "123",
2697                      "serial_number": "12345", "device_type": "6-0050F204-1",
2698                      "os_version": "01020300",
2699                      "config_methods": "label push_button",
2700                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
2701
2702     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
2703
2704     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
2705         dev[0].request("WPS_ER_START ifname=lo")
2706         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
2707         if ev is not None:
2708             raise Exception("Unexpected AP discovery")
2709
2710     dev[0].request("WPS_ER_STOP")
2711     dev[0].request("WPS_ER_START ifname=lo")
2712     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
2713     if ev is None:
2714         raise Exception("AP discovery timed out")
2715
2716     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2717     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
2718         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2719         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
2720         if ev is None:
2721             raise Exception("PBC scan failed")
2722         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
2723         if ev is None:
2724             raise Exception("Enrollee discovery timed out")