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