]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/wpa_supplicant/wps_supplicant.c
Merge LLVM libunwind trunk r351319, from just before upstream's
[FreeBSD/FreeBSD.git] / contrib / wpa / wpa_supplicant / wps_supplicant.c
1 /*
2  * wpa_supplicant / WPS integration
3  * Copyright (c) 2008-2014, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "eloop.h"
13 #include "uuid.h"
14 #include "crypto/random.h"
15 #include "crypto/dh_group5.h"
16 #include "common/ieee802_11_defs.h"
17 #include "common/ieee802_11_common.h"
18 #include "common/wpa_common.h"
19 #include "common/wpa_ctrl.h"
20 #include "eap_common/eap_wsc_common.h"
21 #include "eap_peer/eap.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "rsn_supp/wpa.h"
24 #include "wps/wps_attr_parse.h"
25 #include "config.h"
26 #include "wpa_supplicant_i.h"
27 #include "driver_i.h"
28 #include "notify.h"
29 #include "blacklist.h"
30 #include "bss.h"
31 #include "scan.h"
32 #include "ap.h"
33 #include "p2p/p2p.h"
34 #include "p2p_supplicant.h"
35 #include "wps_supplicant.h"
36
37
38 #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
39 #define WPS_PIN_SCAN_IGNORE_SEL_REG 3
40 #endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
41
42 /*
43  * The minimum time in seconds before trying to associate to a WPS PIN AP that
44  * does not have Selected Registrar TRUE.
45  */
46 #ifndef WPS_PIN_TIME_IGNORE_SEL_REG
47 #define WPS_PIN_TIME_IGNORE_SEL_REG 5
48 #endif /* WPS_PIN_TIME_IGNORE_SEL_REG */
49
50 static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
51 static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
52
53
54 static void wpas_wps_clear_ap_info(struct wpa_supplicant *wpa_s)
55 {
56         os_free(wpa_s->wps_ap);
57         wpa_s->wps_ap = NULL;
58         wpa_s->num_wps_ap = 0;
59         wpa_s->wps_ap_iter = 0;
60 }
61
62
63 static void wpas_wps_assoc_with_cred(void *eloop_ctx, void *timeout_ctx)
64 {
65         struct wpa_supplicant *wpa_s = eloop_ctx;
66         int use_fast_assoc = timeout_ctx != NULL;
67
68         wpa_printf(MSG_DEBUG, "WPS: Continuing association after eapol_cb");
69         if (!use_fast_assoc ||
70             wpa_supplicant_fast_associate(wpa_s) != 1)
71                 wpa_supplicant_req_scan(wpa_s, 0, 0);
72 }
73
74
75 static void wpas_wps_assoc_with_cred_cancel(struct wpa_supplicant *wpa_s)
76 {
77         eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 0);
78         eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 1);
79 }
80
81
82 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
83 {
84         if (wpas_p2p_wps_eapol_cb(wpa_s) > 0)
85                 return 1;
86
87         if (!wpa_s->wps_success &&
88             wpa_s->current_ssid &&
89             eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
90                 const u8 *bssid = wpa_s->bssid;
91                 if (is_zero_ether_addr(bssid))
92                         bssid = wpa_s->pending_bssid;
93
94                 wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR
95                            " did not succeed - continue trying to find "
96                            "suitable AP", MAC2STR(bssid));
97                 wpa_blacklist_add(wpa_s, bssid);
98
99                 wpa_supplicant_deauthenticate(wpa_s,
100                                               WLAN_REASON_DEAUTH_LEAVING);
101                 wpa_s->reassociate = 1;
102                 wpa_supplicant_req_scan(wpa_s,
103                                         wpa_s->blacklist_cleared ? 5 : 0, 0);
104                 wpa_s->blacklist_cleared = 0;
105                 return 1;
106         }
107
108         wpas_wps_clear_ap_info(wpa_s);
109         eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
110         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success)
111                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL);
112
113         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid &&
114             !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
115                 int disabled = wpa_s->current_ssid->disabled;
116                 unsigned int freq = wpa_s->assoc_freq;
117                 struct wpa_bss *bss;
118                 struct wpa_ssid *ssid = NULL;
119                 int use_fast_assoc = 0;
120
121                 wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
122                            "try to associate with the received credential "
123                            "(freq=%u)", freq);
124                 wpa_s->own_disconnect_req = 1;
125                 wpa_supplicant_deauthenticate(wpa_s,
126                                               WLAN_REASON_DEAUTH_LEAVING);
127                 if (disabled) {
128                         wpa_printf(MSG_DEBUG, "WPS: Current network is "
129                                    "disabled - wait for user to enable");
130                         return 1;
131                 }
132                 wpa_s->after_wps = 5;
133                 wpa_s->wps_freq = freq;
134                 wpa_s->normal_scans = 0;
135                 wpa_s->reassociate = 1;
136
137                 wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association "
138                            "without a new scan can be used");
139                 bss = wpa_supplicant_pick_network(wpa_s, &ssid);
140                 if (bss) {
141                         struct wpabuf *wps;
142                         struct wps_parse_attr attr;
143
144                         wps = wpa_bss_get_vendor_ie_multi(bss,
145                                                           WPS_IE_VENDOR_TYPE);
146                         if (wps && wps_parse_msg(wps, &attr) == 0 &&
147                             attr.wps_state &&
148                             *attr.wps_state == WPS_STATE_CONFIGURED)
149                                 use_fast_assoc = 1;
150                         wpabuf_free(wps);
151                 }
152
153                 /*
154                  * Complete the next step from an eloop timeout to allow pending
155                  * driver events related to the disconnection to be processed
156                  * first. This makes it less likely for disconnection event to
157                  * cause problems with the following connection.
158                  */
159                 wpa_printf(MSG_DEBUG, "WPS: Continue association from timeout");
160                 wpas_wps_assoc_with_cred_cancel(wpa_s);
161                 eloop_register_timeout(0, 10000,
162                                        wpas_wps_assoc_with_cred, wpa_s,
163                                        use_fast_assoc ? (void *) 1 :
164                                        (void *) 0);
165                 return 1;
166         }
167
168         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) {
169                 wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting "
170                            "for external credential processing");
171                 wpas_clear_wps(wpa_s);
172                 wpa_s->own_disconnect_req = 1;
173                 wpa_supplicant_deauthenticate(wpa_s,
174                                               WLAN_REASON_DEAUTH_LEAVING);
175                 return 1;
176         }
177
178         return 0;
179 }
180
181
182 static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s,
183                                          struct wpa_ssid *ssid,
184                                          const struct wps_credential *cred)
185 {
186         struct wpa_driver_capa capa;
187         struct wpa_bss *bss;
188         const u8 *ie;
189         struct wpa_ie_data adv;
190         int wpa2 = 0, ccmp = 0;
191
192         /*
193          * Many existing WPS APs do not know how to negotiate WPA2 or CCMP in
194          * case they are configured for mixed mode operation (WPA+WPA2 and
195          * TKIP+CCMP). Try to use scan results to figure out whether the AP
196          * actually supports stronger security and select that if the client
197          * has support for it, too.
198          */
199
200         if (wpa_drv_get_capa(wpa_s, &capa))
201                 return; /* Unknown what driver supports */
202
203         if (ssid->ssid == NULL)
204                 return;
205         bss = wpa_bss_get(wpa_s, cred->mac_addr, ssid->ssid, ssid->ssid_len);
206         if (!bss)
207                 bss = wpa_bss_get(wpa_s, wpa_s->bssid,
208                                   ssid->ssid, ssid->ssid_len);
209         if (bss == NULL) {
210                 wpa_printf(MSG_DEBUG, "WPS: The AP was not found from BSS "
211                            "table - use credential as-is");
212                 return;
213         }
214
215         wpa_printf(MSG_DEBUG, "WPS: AP found from BSS table");
216
217         ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
218         if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0) {
219                 wpa2 = 1;
220                 if (adv.pairwise_cipher & WPA_CIPHER_CCMP)
221                         ccmp = 1;
222         } else {
223                 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
224                 if (ie && wpa_parse_wpa_ie(ie, 2 + ie[1], &adv) == 0 &&
225                     adv.pairwise_cipher & WPA_CIPHER_CCMP)
226                         ccmp = 1;
227         }
228
229         if (ie == NULL && (ssid->proto & WPA_PROTO_WPA) &&
230             (ssid->pairwise_cipher & WPA_CIPHER_TKIP)) {
231                 /*
232                  * TODO: This could be the initial AP configuration and the
233                  * Beacon contents could change shortly. Should request a new
234                  * scan and delay addition of the network until the updated
235                  * scan results are available.
236                  */
237                 wpa_printf(MSG_DEBUG, "WPS: The AP did not yet advertise WPA "
238                            "support - use credential as-is");
239                 return;
240         }
241
242         if (ccmp && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) &&
243             (ssid->pairwise_cipher & WPA_CIPHER_TKIP) &&
244             (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
245                 wpa_printf(MSG_DEBUG, "WPS: Add CCMP into the credential "
246                            "based on scan results");
247                 if (wpa_s->conf->ap_scan == 1)
248                         ssid->pairwise_cipher |= WPA_CIPHER_CCMP;
249                 else
250                         ssid->pairwise_cipher = WPA_CIPHER_CCMP;
251         }
252
253         if (wpa2 && !(ssid->proto & WPA_PROTO_RSN) &&
254             (ssid->proto & WPA_PROTO_WPA) &&
255             (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP)) {
256                 wpa_printf(MSG_DEBUG, "WPS: Add WPA2 into the credential "
257                            "based on scan results");
258                 if (wpa_s->conf->ap_scan == 1)
259                         ssid->proto |= WPA_PROTO_RSN;
260                 else
261                         ssid->proto = WPA_PROTO_RSN;
262         }
263 }
264
265
266 static void wpas_wps_remove_dup_network(struct wpa_supplicant *wpa_s,
267                                         struct wpa_ssid *new_ssid)
268 {
269         struct wpa_ssid *ssid, *next;
270
271         for (ssid = wpa_s->conf->ssid, next = ssid ? ssid->next : NULL; ssid;
272              ssid = next, next = ssid ? ssid->next : NULL) {
273                 /*
274                  * new_ssid has already been added to the list in
275                  * wpas_wps_add_network(), so skip it.
276                  */
277                 if (ssid == new_ssid)
278                         continue;
279
280                 if (ssid->bssid_set || new_ssid->bssid_set) {
281                         if (ssid->bssid_set != new_ssid->bssid_set)
282                                 continue;
283                         if (os_memcmp(ssid->bssid, new_ssid->bssid, ETH_ALEN) !=
284                             0)
285                                 continue;
286                 }
287
288                 /* compare SSID */
289                 if (ssid->ssid_len == 0 || ssid->ssid_len != new_ssid->ssid_len)
290                         continue;
291
292                 if (ssid->ssid && new_ssid->ssid) {
293                         if (os_memcmp(ssid->ssid, new_ssid->ssid,
294                                       ssid->ssid_len) != 0)
295                                 continue;
296                 } else if (ssid->ssid || new_ssid->ssid)
297                         continue;
298
299                 /* compare security parameters */
300                 if (ssid->auth_alg != new_ssid->auth_alg ||
301                     ssid->key_mgmt != new_ssid->key_mgmt ||
302                     (ssid->group_cipher != new_ssid->group_cipher &&
303                      !(ssid->group_cipher & new_ssid->group_cipher &
304                        WPA_CIPHER_CCMP)))
305                         continue;
306
307                 /*
308                  * Some existing WPS APs will send two creds in case they are
309                  * configured for mixed mode operation (WPA+WPA2 and TKIP+CCMP).
310                  * Try to merge these two creds if they are received in the same
311                  * M8 message.
312                  */
313                 if (ssid->wps_run && ssid->wps_run == new_ssid->wps_run &&
314                     wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
315                         if (new_ssid->passphrase && ssid->passphrase &&
316                             os_strcmp(new_ssid->passphrase, ssid->passphrase) !=
317                             0) {
318                                 wpa_printf(MSG_DEBUG,
319                                            "WPS: M8 Creds with different passphrase - do not merge");
320                                 continue;
321                         }
322
323                         if (new_ssid->psk_set &&
324                             (!ssid->psk_set ||
325                              os_memcmp(new_ssid->psk, ssid->psk, 32) != 0)) {
326                                 wpa_printf(MSG_DEBUG,
327                                            "WPS: M8 Creds with different PSK - do not merge");
328                                 continue;
329                         }
330
331                         if ((new_ssid->passphrase && !ssid->passphrase) ||
332                             (!new_ssid->passphrase && ssid->passphrase)) {
333                                 wpa_printf(MSG_DEBUG,
334                                            "WPS: M8 Creds with different passphrase/PSK type - do not merge");
335                                 continue;
336                         }
337
338                         wpa_printf(MSG_DEBUG,
339                                    "WPS: Workaround - merge likely WPA/WPA2-mixed mode creds in same M8 message");
340                         new_ssid->proto |= ssid->proto;
341                         new_ssid->pairwise_cipher |= ssid->pairwise_cipher;
342                 } else {
343                         /*
344                          * proto and pairwise_cipher difference matter for
345                          * non-mixed-mode creds.
346                          */
347                         if (ssid->proto != new_ssid->proto ||
348                             ssid->pairwise_cipher != new_ssid->pairwise_cipher)
349                                 continue;
350                 }
351
352                 /* Remove the duplicated older network entry. */
353                 wpa_printf(MSG_DEBUG, "Remove duplicate network %d", ssid->id);
354                 wpas_notify_network_removed(wpa_s, ssid);
355                 if (wpa_s->current_ssid == ssid)
356                         wpa_s->current_ssid = NULL;
357                 wpa_config_remove_network(wpa_s->conf, ssid->id);
358         }
359 }
360
361
362 static int wpa_supplicant_wps_cred(void *ctx,
363                                    const struct wps_credential *cred)
364 {
365         struct wpa_supplicant *wpa_s = ctx;
366         struct wpa_ssid *ssid = wpa_s->current_ssid;
367         u16 auth_type;
368 #ifdef CONFIG_WPS_REG_DISABLE_OPEN
369         int registrar = 0;
370 #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
371
372         if ((wpa_s->conf->wps_cred_processing == 1 ||
373              wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
374                 size_t blen = cred->cred_attr_len * 2 + 1;
375                 char *buf = os_malloc(blen);
376                 if (buf) {
377                         wpa_snprintf_hex(buf, blen,
378                                          cred->cred_attr, cred->cred_attr_len);
379                         wpa_msg(wpa_s, MSG_INFO, "%s%s",
380                                 WPS_EVENT_CRED_RECEIVED, buf);
381                         os_free(buf);
382                 }
383
384                 wpas_notify_wps_credential(wpa_s, cred);
385         } else
386                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
387
388         wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
389                         cred->cred_attr, cred->cred_attr_len);
390
391         if (wpa_s->conf->wps_cred_processing == 1)
392                 return 0;
393
394         wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
395         wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
396                    cred->auth_type);
397         wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
398         wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
399         wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
400                         cred->key, cred->key_len);
401         wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
402                    MAC2STR(cred->mac_addr));
403
404         auth_type = cred->auth_type;
405         if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
406                 wpa_printf(MSG_DEBUG, "WPS: Workaround - convert mixed-mode "
407                            "auth_type into WPA2PSK");
408                 auth_type = WPS_AUTH_WPA2PSK;
409         }
410
411         if (auth_type != WPS_AUTH_OPEN &&
412             auth_type != WPS_AUTH_WPAPSK &&
413             auth_type != WPS_AUTH_WPA2PSK) {
414                 wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for "
415                            "unsupported authentication type 0x%x",
416                            auth_type);
417                 return 0;
418         }
419
420         if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) {
421                 if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) {
422                         wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with "
423                                    "invalid Network Key length %lu",
424                                    (unsigned long) cred->key_len);
425                         return -1;
426                 }
427         }
428
429         if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
430                 wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
431                            "on the received credential");
432 #ifdef CONFIG_WPS_REG_DISABLE_OPEN
433                 if (ssid->eap.identity &&
434                     ssid->eap.identity_len == WSC_ID_REGISTRAR_LEN &&
435                     os_memcmp(ssid->eap.identity, WSC_ID_REGISTRAR,
436                               WSC_ID_REGISTRAR_LEN) == 0)
437                         registrar = 1;
438 #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
439                 os_free(ssid->eap.identity);
440                 ssid->eap.identity = NULL;
441                 ssid->eap.identity_len = 0;
442                 os_free(ssid->eap.phase1);
443                 ssid->eap.phase1 = NULL;
444                 os_free(ssid->eap.eap_methods);
445                 ssid->eap.eap_methods = NULL;
446                 if (!ssid->p2p_group) {
447                         ssid->temporary = 0;
448                         ssid->bssid_set = 0;
449                 }
450                 ssid->disabled_until.sec = 0;
451                 ssid->disabled_until.usec = 0;
452                 ssid->auth_failures = 0;
453         } else {
454                 wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the "
455                            "received credential");
456                 ssid = wpa_config_add_network(wpa_s->conf);
457                 if (ssid == NULL)
458                         return -1;
459                 if (wpa_s->current_ssid) {
460                         /*
461                          * Should the GO issue multiple credentials for some
462                          * reason, each credential should be marked as a
463                          * temporary P2P group similarly to the one that gets
464                          * marked as such based on the pre-configured values
465                          * used for the WPS network block.
466                          */
467                         ssid->p2p_group = wpa_s->current_ssid->p2p_group;
468                         ssid->temporary = wpa_s->current_ssid->temporary;
469                 }
470                 wpas_notify_network_added(wpa_s, ssid);
471         }
472
473         wpa_config_set_network_defaults(ssid);
474         ssid->wps_run = wpa_s->wps_run;
475
476         os_free(ssid->ssid);
477         ssid->ssid = os_malloc(cred->ssid_len);
478         if (ssid->ssid) {
479                 os_memcpy(ssid->ssid, cred->ssid, cred->ssid_len);
480                 ssid->ssid_len = cred->ssid_len;
481         }
482
483         switch (cred->encr_type) {
484         case WPS_ENCR_NONE:
485                 break;
486         case WPS_ENCR_TKIP:
487                 ssid->pairwise_cipher = WPA_CIPHER_TKIP;
488                 break;
489         case WPS_ENCR_AES:
490                 ssid->pairwise_cipher = WPA_CIPHER_CCMP;
491                 if (wpa_s->drv_capa_known &&
492                     (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP)) {
493                         ssid->pairwise_cipher |= WPA_CIPHER_GCMP;
494                         ssid->group_cipher |= WPA_CIPHER_GCMP;
495                 }
496                 if (wpa_s->drv_capa_known &&
497                     (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_GCMP_256)) {
498                         ssid->pairwise_cipher |= WPA_CIPHER_GCMP_256;
499                         ssid->group_cipher |= WPA_CIPHER_GCMP_256;
500                 }
501                 if (wpa_s->drv_capa_known &&
502                     (wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_CCMP_256)) {
503                         ssid->pairwise_cipher |= WPA_CIPHER_CCMP_256;
504                         ssid->group_cipher |= WPA_CIPHER_CCMP_256;
505                 }
506                 break;
507         }
508
509         switch (auth_type) {
510         case WPS_AUTH_OPEN:
511                 ssid->auth_alg = WPA_AUTH_ALG_OPEN;
512                 ssid->key_mgmt = WPA_KEY_MGMT_NONE;
513                 ssid->proto = 0;
514 #ifdef CONFIG_WPS_REG_DISABLE_OPEN
515                 if (registrar) {
516                         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OPEN_NETWORK
517                                 "id=%d - Credentials for an open "
518                                 "network disabled by default - use "
519                                 "'select_network %d' to enable",
520                                 ssid->id, ssid->id);
521                         ssid->disabled = 1;
522                 }
523 #endif /* CONFIG_WPS_REG_DISABLE_OPEN */
524                 break;
525         case WPS_AUTH_WPAPSK:
526                 ssid->auth_alg = WPA_AUTH_ALG_OPEN;
527                 ssid->key_mgmt = WPA_KEY_MGMT_PSK;
528                 ssid->proto = WPA_PROTO_WPA;
529                 break;
530         case WPS_AUTH_WPA2PSK:
531                 ssid->auth_alg = WPA_AUTH_ALG_OPEN;
532                 ssid->key_mgmt = WPA_KEY_MGMT_PSK;
533                 ssid->proto = WPA_PROTO_RSN;
534                 break;
535         }
536
537         if (ssid->key_mgmt == WPA_KEY_MGMT_PSK) {
538                 if (cred->key_len == 2 * PMK_LEN) {
539                         if (hexstr2bin((const char *) cred->key, ssid->psk,
540                                        PMK_LEN)) {
541                                 wpa_printf(MSG_ERROR, "WPS: Invalid Network "
542                                            "Key");
543                                 return -1;
544                         }
545                         ssid->psk_set = 1;
546                         ssid->export_keys = 1;
547                 } else if (cred->key_len >= 8 && cred->key_len < 2 * PMK_LEN) {
548                         os_free(ssid->passphrase);
549                         ssid->passphrase = os_malloc(cred->key_len + 1);
550                         if (ssid->passphrase == NULL)
551                                 return -1;
552                         os_memcpy(ssid->passphrase, cred->key, cred->key_len);
553                         ssid->passphrase[cred->key_len] = '\0';
554                         wpa_config_update_psk(ssid);
555                         ssid->export_keys = 1;
556                 } else {
557                         wpa_printf(MSG_ERROR, "WPS: Invalid Network Key "
558                                    "length %lu",
559                                    (unsigned long) cred->key_len);
560                         return -1;
561                 }
562         }
563         ssid->priority = wpa_s->conf->wps_priority;
564
565         wpas_wps_security_workaround(wpa_s, ssid, cred);
566
567         wpas_wps_remove_dup_network(wpa_s, ssid);
568
569 #ifndef CONFIG_NO_CONFIG_WRITE
570         if (wpa_s->conf->update_config &&
571             wpa_config_write(wpa_s->confname, wpa_s->conf)) {
572                 wpa_printf(MSG_DEBUG, "WPS: Failed to update configuration");
573                 return -1;
574         }
575 #endif /* CONFIG_NO_CONFIG_WRITE */
576
577         if (ssid->priority)
578                 wpa_config_update_prio_list(wpa_s->conf);
579
580         /*
581          * Optimize the post-WPS scan based on the channel used during
582          * the provisioning in case EAP-Failure is not received.
583          */
584         wpa_s->after_wps = 5;
585         wpa_s->wps_freq = wpa_s->assoc_freq;
586
587         return 0;
588 }
589
590
591 static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
592                                          struct wps_event_m2d *m2d)
593 {
594         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D
595                 "dev_password_id=%d config_error=%d",
596                 m2d->dev_password_id, m2d->config_error);
597         wpas_notify_wps_event_m2d(wpa_s, m2d);
598 #ifdef CONFIG_P2P
599         if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s) {
600                 wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_M2D
601                         "dev_password_id=%d config_error=%d",
602                         m2d->dev_password_id, m2d->config_error);
603         }
604         if (m2d->config_error == WPS_CFG_MULTIPLE_PBC_DETECTED) {
605                 /*
606                  * Notify P2P from eloop timeout to avoid issues with the
607                  * interface getting removed while processing a message.
608                  */
609                 eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb, wpa_s,
610                                        NULL);
611         }
612 #endif /* CONFIG_P2P */
613 }
614
615
616 static void wpas_wps_clear_timeout(void *eloop_ctx, void *timeout_ctx)
617 {
618         struct wpa_supplicant *wpa_s = eloop_ctx;
619         wpa_printf(MSG_DEBUG, "WPS: Clear WPS network from timeout");
620         wpas_clear_wps(wpa_s);
621 }
622
623
624 static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
625                                           struct wps_event_fail *fail)
626 {
627         if (fail->error_indication > 0 &&
628             fail->error_indication < NUM_WPS_EI_VALUES) {
629                 wpa_msg(wpa_s, MSG_INFO,
630                         WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
631                         fail->msg, fail->config_error, fail->error_indication,
632                         wps_ei_str(fail->error_indication));
633                 if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s)
634                         wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
635                                 "msg=%d config_error=%d reason=%d (%s)",
636                                 fail->msg, fail->config_error,
637                                 fail->error_indication,
638                                 wps_ei_str(fail->error_indication));
639         } else {
640                 wpa_msg(wpa_s, MSG_INFO,
641                         WPS_EVENT_FAIL "msg=%d config_error=%d",
642                         fail->msg, fail->config_error);
643                 if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s)
644                         wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
645                                 "msg=%d config_error=%d",
646                                 fail->msg, fail->config_error);
647         }
648
649         /*
650          * Need to allow WPS processing to complete, e.g., by sending WSC_NACK.
651          */
652         wpa_printf(MSG_DEBUG, "WPS: Register timeout to clear WPS network");
653         eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
654         eloop_register_timeout(0, 100000, wpas_wps_clear_timeout, wpa_s, NULL);
655
656         wpas_notify_wps_event_fail(wpa_s, fail);
657         wpas_p2p_wps_failed(wpa_s, fail);
658 }
659
660
661 static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx);
662
663 static void wpas_wps_reenable_networks(struct wpa_supplicant *wpa_s)
664 {
665         struct wpa_ssid *ssid;
666         int changed = 0;
667
668         eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
669
670         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
671                 if (ssid->disabled_for_connect && ssid->disabled) {
672                         ssid->disabled_for_connect = 0;
673                         ssid->disabled = 0;
674                         wpas_notify_network_enabled_changed(wpa_s, ssid);
675                         changed++;
676                 }
677         }
678
679         if (changed) {
680 #ifndef CONFIG_NO_CONFIG_WRITE
681                 if (wpa_s->conf->update_config &&
682                     wpa_config_write(wpa_s->confname, wpa_s->conf)) {
683                         wpa_printf(MSG_DEBUG, "WPS: Failed to update "
684                                    "configuration");
685                 }
686 #endif /* CONFIG_NO_CONFIG_WRITE */
687         }
688 }
689
690
691 static void wpas_wps_reenable_networks_cb(void *eloop_ctx, void *timeout_ctx)
692 {
693         struct wpa_supplicant *wpa_s = eloop_ctx;
694         /* Enable the networks disabled during wpas_wps_reassoc */
695         wpas_wps_reenable_networks(wpa_s);
696 }
697
698
699 int wpas_wps_reenable_networks_pending(struct wpa_supplicant *wpa_s)
700 {
701         return eloop_is_timeout_registered(wpas_wps_reenable_networks_cb,
702                                            wpa_s, NULL);
703 }
704
705
706 static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
707 {
708         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
709         wpa_s->wps_success = 1;
710         wpas_notify_wps_event_success(wpa_s);
711         if (wpa_s->current_ssid)
712                 wpas_clear_temp_disabled(wpa_s, wpa_s->current_ssid, 1);
713         wpa_s->extra_blacklist_count = 0;
714
715         /*
716          * Enable the networks disabled during wpas_wps_reassoc after 10
717          * seconds. The 10 seconds timer is to allow the data connection to be
718          * formed before allowing other networks to be selected.
719          */
720         eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
721                                NULL);
722
723         wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0);
724 }
725
726
727 static void wpa_supplicant_wps_event_er_ap_add(struct wpa_supplicant *wpa_s,
728                                                struct wps_event_er_ap *ap)
729 {
730         char uuid_str[100];
731         char dev_type[WPS_DEV_TYPE_BUFSIZE];
732
733         uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
734         if (ap->pri_dev_type)
735                 wps_dev_type_bin2str(ap->pri_dev_type, dev_type,
736                                      sizeof(dev_type));
737         else
738                 dev_type[0] = '\0';
739
740         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_ADD "%s " MACSTR
741                 " pri_dev_type=%s wps_state=%d |%s|%s|%s|%s|%s|%s|",
742                 uuid_str, MAC2STR(ap->mac_addr), dev_type, ap->wps_state,
743                 ap->friendly_name ? ap->friendly_name : "",
744                 ap->manufacturer ? ap->manufacturer : "",
745                 ap->model_description ? ap->model_description : "",
746                 ap->model_name ? ap->model_name : "",
747                 ap->manufacturer_url ? ap->manufacturer_url : "",
748                 ap->model_url ? ap->model_url : "");
749 }
750
751
752 static void wpa_supplicant_wps_event_er_ap_remove(struct wpa_supplicant *wpa_s,
753                                                   struct wps_event_er_ap *ap)
754 {
755         char uuid_str[100];
756         uuid_bin2str(ap->uuid, uuid_str, sizeof(uuid_str));
757         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_REMOVE "%s", uuid_str);
758 }
759
760
761 static void wpa_supplicant_wps_event_er_enrollee_add(
762         struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
763 {
764         char uuid_str[100];
765         char dev_type[WPS_DEV_TYPE_BUFSIZE];
766
767         uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
768         if (enrollee->pri_dev_type)
769                 wps_dev_type_bin2str(enrollee->pri_dev_type, dev_type,
770                                      sizeof(dev_type));
771         else
772                 dev_type[0] = '\0';
773
774         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_ADD "%s " MACSTR
775                 " M1=%d config_methods=0x%x dev_passwd_id=%d pri_dev_type=%s "
776                 "|%s|%s|%s|%s|%s|",
777                 uuid_str, MAC2STR(enrollee->mac_addr), enrollee->m1_received,
778                 enrollee->config_methods, enrollee->dev_passwd_id, dev_type,
779                 enrollee->dev_name ? enrollee->dev_name : "",
780                 enrollee->manufacturer ? enrollee->manufacturer : "",
781                 enrollee->model_name ? enrollee->model_name : "",
782                 enrollee->model_number ? enrollee->model_number : "",
783                 enrollee->serial_number ? enrollee->serial_number : "");
784 }
785
786
787 static void wpa_supplicant_wps_event_er_enrollee_remove(
788         struct wpa_supplicant *wpa_s, struct wps_event_er_enrollee *enrollee)
789 {
790         char uuid_str[100];
791         uuid_bin2str(enrollee->uuid, uuid_str, sizeof(uuid_str));
792         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_ENROLLEE_REMOVE "%s " MACSTR,
793                 uuid_str, MAC2STR(enrollee->mac_addr));
794 }
795
796
797 static void wpa_supplicant_wps_event_er_ap_settings(
798         struct wpa_supplicant *wpa_s,
799         struct wps_event_er_ap_settings *ap_settings)
800 {
801         char uuid_str[100];
802         char key_str[65];
803         const struct wps_credential *cred = ap_settings->cred;
804
805         key_str[0] = '\0';
806         if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
807                 if (cred->key_len >= 8 && cred->key_len <= 64) {
808                         os_memcpy(key_str, cred->key, cred->key_len);
809                         key_str[cred->key_len] = '\0';
810                 }
811         }
812
813         uuid_bin2str(ap_settings->uuid, uuid_str, sizeof(uuid_str));
814         /* Use wpa_msg_ctrl to avoid showing the key in debug log */
815         wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_ER_AP_SETTINGS
816                      "uuid=%s ssid=%s auth_type=0x%04x encr_type=0x%04x "
817                      "key=%s",
818                      uuid_str, wpa_ssid_txt(cred->ssid, cred->ssid_len),
819                      cred->auth_type, cred->encr_type, key_str);
820 }
821
822
823 static void wpa_supplicant_wps_event_er_set_sel_reg(
824         struct wpa_supplicant *wpa_s,
825         struct wps_event_er_set_selected_registrar *ev)
826 {
827         char uuid_str[100];
828
829         uuid_bin2str(ev->uuid, uuid_str, sizeof(uuid_str));
830         switch (ev->state) {
831         case WPS_ER_SET_SEL_REG_START:
832                 wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
833                         "uuid=%s state=START sel_reg=%d dev_passwd_id=%u "
834                         "sel_reg_config_methods=0x%x",
835                         uuid_str, ev->sel_reg, ev->dev_passwd_id,
836                         ev->sel_reg_config_methods);
837                 break;
838         case WPS_ER_SET_SEL_REG_DONE:
839                 wpa_msg(wpa_s, MSG_DEBUG, WPS_EVENT_ER_SET_SEL_REG
840                         "uuid=%s state=DONE", uuid_str);
841                 break;
842         case WPS_ER_SET_SEL_REG_FAILED:
843                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ER_SET_SEL_REG
844                         "uuid=%s state=FAILED", uuid_str);
845                 break;
846         }
847 }
848
849
850 static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
851                                      union wps_event_data *data)
852 {
853         struct wpa_supplicant *wpa_s = ctx;
854         switch (event) {
855         case WPS_EV_M2D:
856                 wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
857                 break;
858         case WPS_EV_FAIL:
859                 wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
860                 break;
861         case WPS_EV_SUCCESS:
862                 wpa_supplicant_wps_event_success(wpa_s);
863                 break;
864         case WPS_EV_PWD_AUTH_FAIL:
865 #ifdef CONFIG_AP
866                 if (wpa_s->ap_iface && data->pwd_auth_fail.enrollee)
867                         wpa_supplicant_ap_pwd_auth_fail(wpa_s);
868 #endif /* CONFIG_AP */
869                 break;
870         case WPS_EV_PBC_OVERLAP:
871                 break;
872         case WPS_EV_PBC_TIMEOUT:
873                 break;
874         case WPS_EV_PBC_ACTIVE:
875                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_ACTIVE);
876                 break;
877         case WPS_EV_PBC_DISABLE:
878                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_DISABLE);
879                 break;
880         case WPS_EV_ER_AP_ADD:
881                 wpa_supplicant_wps_event_er_ap_add(wpa_s, &data->ap);
882                 break;
883         case WPS_EV_ER_AP_REMOVE:
884                 wpa_supplicant_wps_event_er_ap_remove(wpa_s, &data->ap);
885                 break;
886         case WPS_EV_ER_ENROLLEE_ADD:
887                 wpa_supplicant_wps_event_er_enrollee_add(wpa_s,
888                                                          &data->enrollee);
889                 break;
890         case WPS_EV_ER_ENROLLEE_REMOVE:
891                 wpa_supplicant_wps_event_er_enrollee_remove(wpa_s,
892                                                             &data->enrollee);
893                 break;
894         case WPS_EV_ER_AP_SETTINGS:
895                 wpa_supplicant_wps_event_er_ap_settings(wpa_s,
896                                                         &data->ap_settings);
897                 break;
898         case WPS_EV_ER_SET_SELECTED_REGISTRAR:
899                 wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
900                                                         &data->set_sel_reg);
901                 break;
902         case WPS_EV_AP_PIN_SUCCESS:
903                 break;
904         }
905 }
906
907
908 static int wpa_supplicant_wps_rf_band(void *ctx)
909 {
910         struct wpa_supplicant *wpa_s = ctx;
911
912         if (!wpa_s->current_ssid || !wpa_s->assoc_freq)
913                 return 0;
914
915         return (wpa_s->assoc_freq > 50000) ? WPS_RF_60GHZ :
916                 (wpa_s->assoc_freq > 2484) ? WPS_RF_50GHZ : WPS_RF_24GHZ;
917 }
918
919
920 enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
921 {
922         if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
923             eap_is_wps_pin_enrollee(&ssid->eap))
924                 return WPS_REQ_ENROLLEE;
925         else
926                 return WPS_REQ_REGISTRAR;
927 }
928
929
930 static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
931 {
932         int id;
933         struct wpa_ssid *ssid, *remove_ssid = NULL, *prev_current;
934
935         wpa_s->after_wps = 0;
936         wpa_s->known_wps_freq = 0;
937
938         prev_current = wpa_s->current_ssid;
939
940         /* Enable the networks disabled during wpas_wps_reassoc */
941         wpas_wps_reenable_networks(wpa_s);
942
943         eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
944         eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
945
946         /* Remove any existing WPS network from configuration */
947         ssid = wpa_s->conf->ssid;
948         while (ssid) {
949                 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
950                         if (ssid == wpa_s->current_ssid) {
951                                 wpa_s->own_disconnect_req = 1;
952                                 wpa_supplicant_deauthenticate(
953                                         wpa_s, WLAN_REASON_DEAUTH_LEAVING);
954                         }
955                         id = ssid->id;
956                         remove_ssid = ssid;
957                 } else
958                         id = -1;
959                 ssid = ssid->next;
960                 if (id >= 0) {
961                         if (prev_current == remove_ssid) {
962                                 wpa_sm_set_config(wpa_s->wpa, NULL);
963                                 eapol_sm_notify_config(wpa_s->eapol, NULL,
964                                                        NULL);
965                         }
966                         wpas_notify_network_removed(wpa_s, remove_ssid);
967                         wpa_config_remove_network(wpa_s->conf, id);
968                 }
969         }
970
971         wpas_wps_clear_ap_info(wpa_s);
972 }
973
974
975 static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx)
976 {
977         struct wpa_supplicant *wpa_s = eloop_ctx;
978         union wps_event_data data;
979
980         wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
981                 "out");
982         os_memset(&data, 0, sizeof(data));
983         data.fail.config_error = WPS_CFG_MSG_TIMEOUT;
984         data.fail.error_indication = WPS_EI_NO_ERROR;
985         /*
986          * Call wpas_notify_wps_event_fail() directly instead of through
987          * wpa_supplicant_wps_event() which would end up registering unnecessary
988          * timeouts (those are only for the case where the failure happens
989          * during an EAP-WSC exchange).
990          */
991         wpas_notify_wps_event_fail(wpa_s, &data.fail);
992         wpas_clear_wps(wpa_s);
993 }
994
995
996 static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
997                                               int registrar, const u8 *dev_addr,
998                                               const u8 *bssid)
999 {
1000         struct wpa_ssid *ssid;
1001
1002         ssid = wpa_config_add_network(wpa_s->conf);
1003         if (ssid == NULL)
1004                 return NULL;
1005         wpas_notify_network_added(wpa_s, ssid);
1006         wpa_config_set_network_defaults(ssid);
1007         ssid->temporary = 1;
1008         if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
1009             wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
1010             wpa_config_set(ssid, "identity", registrar ?
1011                            "\"" WSC_ID_REGISTRAR "\"" :
1012                            "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
1013                 wpas_notify_network_removed(wpa_s, ssid);
1014                 wpa_config_remove_network(wpa_s->conf, ssid->id);
1015                 return NULL;
1016         }
1017
1018 #ifdef CONFIG_P2P
1019         if (dev_addr)
1020                 os_memcpy(ssid->go_p2p_dev_addr, dev_addr, ETH_ALEN);
1021 #endif /* CONFIG_P2P */
1022
1023         if (bssid) {
1024 #ifndef CONFIG_P2P
1025                 struct wpa_bss *bss;
1026                 int count = 0;
1027 #endif /* CONFIG_P2P */
1028
1029                 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
1030                 ssid->bssid_set = 1;
1031
1032                 /*
1033                  * Note: With P2P, the SSID may change at the time the WPS
1034                  * provisioning is started, so better not filter the AP based
1035                  * on the current SSID in the scan results.
1036                  */
1037 #ifndef CONFIG_P2P
1038                 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1039                         if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
1040                                 continue;
1041
1042                         os_free(ssid->ssid);
1043                         ssid->ssid = os_memdup(bss->ssid, bss->ssid_len);
1044                         if (ssid->ssid == NULL)
1045                                 break;
1046                         ssid->ssid_len = bss->ssid_len;
1047                         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
1048                                           "scan results",
1049                                           ssid->ssid, ssid->ssid_len);
1050                         count++;
1051                 }
1052
1053                 if (count > 1) {
1054                         wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
1055                                    "for the AP; use wildcard");
1056                         os_free(ssid->ssid);
1057                         ssid->ssid = NULL;
1058                         ssid->ssid_len = 0;
1059                 }
1060 #endif /* CONFIG_P2P */
1061         }
1062
1063         return ssid;
1064 }
1065
1066
1067 static void wpas_wps_temp_disable(struct wpa_supplicant *wpa_s,
1068                                   struct wpa_ssid *selected)
1069 {
1070         struct wpa_ssid *ssid;
1071
1072         if (wpa_s->current_ssid) {
1073                 wpa_s->own_disconnect_req = 1;
1074                 wpa_supplicant_deauthenticate(
1075                         wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1076         }
1077
1078         /* Mark all other networks disabled and trigger reassociation */
1079         ssid = wpa_s->conf->ssid;
1080         while (ssid) {
1081                 int was_disabled = ssid->disabled;
1082                 ssid->disabled_for_connect = 0;
1083                 /*
1084                  * In case the network object corresponds to a persistent group
1085                  * then do not send out network disabled signal. In addition,
1086                  * do not change disabled status of persistent network objects
1087                  * from 2 to 1 should we connect to another network.
1088                  */
1089                 if (was_disabled != 2) {
1090                         ssid->disabled = ssid != selected;
1091                         if (was_disabled != ssid->disabled) {
1092                                 if (ssid->disabled)
1093                                         ssid->disabled_for_connect = 1;
1094                                 wpas_notify_network_enabled_changed(wpa_s,
1095                                                                     ssid);
1096                         }
1097                 }
1098                 ssid = ssid->next;
1099         }
1100 }
1101
1102
1103 static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
1104                              struct wpa_ssid *selected, const u8 *bssid,
1105                              int freq)
1106 {
1107         struct wpa_bss *bss;
1108
1109         wpa_s->wps_run++;
1110         if (wpa_s->wps_run == 0)
1111                 wpa_s->wps_run++;
1112         wpa_s->after_wps = 0;
1113         wpa_s->known_wps_freq = 0;
1114         if (freq) {
1115                 wpa_s->after_wps = 5;
1116                 wpa_s->wps_freq = freq;
1117         } else if (bssid) {
1118                 bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
1119                 if (bss && bss->freq > 0) {
1120                         wpa_s->known_wps_freq = 1;
1121                         wpa_s->wps_freq = bss->freq;
1122                 }
1123         }
1124
1125         wpas_wps_temp_disable(wpa_s, selected);
1126
1127         wpa_s->disconnected = 0;
1128         wpa_s->reassociate = 1;
1129         wpa_s->scan_runs = 0;
1130         wpa_s->normal_scans = 0;
1131         wpa_s->wps_success = 0;
1132         wpa_s->blacklist_cleared = 0;
1133
1134         wpa_supplicant_cancel_sched_scan(wpa_s);
1135         wpa_supplicant_req_scan(wpa_s, 0, 0);
1136 }
1137
1138
1139 int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
1140                        int p2p_group)
1141 {
1142         struct wpa_ssid *ssid;
1143
1144 #ifdef CONFIG_AP
1145         if (wpa_s->ap_iface) {
1146                 wpa_printf(MSG_DEBUG,
1147                            "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
1148                 return -1;
1149         }
1150 #endif /* CONFIG_AP */
1151         wpas_clear_wps(wpa_s);
1152         ssid = wpas_wps_add_network(wpa_s, 0, NULL, bssid);
1153         if (ssid == NULL)
1154                 return -1;
1155         ssid->temporary = 1;
1156         ssid->p2p_group = p2p_group;
1157         /*
1158          * When starting a regular WPS process (not P2P group formation)
1159          * the registrar/final station can be either AP or PCP
1160          * so use a "don't care" value for the pbss flag.
1161          */
1162         if (!p2p_group)
1163                 ssid->pbss = 2;
1164 #ifdef CONFIG_P2P
1165         if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
1166                 ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
1167                 if (ssid->ssid) {
1168                         ssid->ssid_len = wpa_s->go_params->ssid_len;
1169                         os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
1170                                   ssid->ssid_len);
1171                         if (wpa_s->go_params->freq > 56160) {
1172                                 /* P2P in 60 GHz uses PBSS */
1173                                 ssid->pbss = 1;
1174                         }
1175                         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
1176                                           "SSID", ssid->ssid, ssid->ssid_len);
1177                 }
1178         }
1179 #endif /* CONFIG_P2P */
1180         if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
1181                 return -1;
1182         if (wpa_s->wps_fragment_size)
1183                 ssid->eap.fragment_size = wpa_s->wps_fragment_size;
1184         wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
1185         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
1186                                wpa_s, NULL);
1187         wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
1188         return 0;
1189 }
1190
1191
1192 static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s,
1193                                  const u8 *dev_addr, const u8 *bssid,
1194                                  const char *pin, int p2p_group, u16 dev_pw_id,
1195                                  const u8 *peer_pubkey_hash,
1196                                  const u8 *ssid_val, size_t ssid_len, int freq)
1197 {
1198         struct wpa_ssid *ssid;
1199         char val[128 + 2 * WPS_OOB_PUBKEY_HASH_LEN];
1200         unsigned int rpin = 0;
1201         char hash[2 * WPS_OOB_PUBKEY_HASH_LEN + 10];
1202
1203 #ifdef CONFIG_AP
1204         if (wpa_s->ap_iface) {
1205                 wpa_printf(MSG_DEBUG,
1206                            "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
1207                 return -1;
1208         }
1209 #endif /* CONFIG_AP */
1210         wpas_clear_wps(wpa_s);
1211         if (bssid && is_zero_ether_addr(bssid))
1212                 bssid = NULL;
1213         ssid = wpas_wps_add_network(wpa_s, 0, dev_addr, bssid);
1214         if (ssid == NULL) {
1215                 wpa_printf(MSG_DEBUG, "WPS: Could not add network");
1216                 return -1;
1217         }
1218         ssid->temporary = 1;
1219         ssid->p2p_group = p2p_group;
1220         /*
1221          * When starting a regular WPS process (not P2P group formation)
1222          * the registrar/final station can be either AP or PCP
1223          * so use a "don't care" value for the pbss flag.
1224          */
1225         if (!p2p_group)
1226                 ssid->pbss = 2;
1227         if (ssid_val) {
1228                 ssid->ssid = os_malloc(ssid_len);
1229                 if (ssid->ssid) {
1230                         os_memcpy(ssid->ssid, ssid_val, ssid_len);
1231                         ssid->ssid_len = ssid_len;
1232                 }
1233         }
1234         if (peer_pubkey_hash) {
1235                 os_memcpy(hash, " pkhash=", 8);
1236                 wpa_snprintf_hex_uppercase(hash + 8, sizeof(hash) - 8,
1237                                            peer_pubkey_hash,
1238                                            WPS_OOB_PUBKEY_HASH_LEN);
1239         } else {
1240                 hash[0] = '\0';
1241         }
1242 #ifdef CONFIG_P2P
1243         if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) {
1244                 os_free(ssid->ssid);
1245                 ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1);
1246                 if (ssid->ssid) {
1247                         ssid->ssid_len = wpa_s->go_params->ssid_len;
1248                         os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
1249                                   ssid->ssid_len);
1250                         if (wpa_s->go_params->freq > 56160) {
1251                                 /* P2P in 60 GHz uses PBSS */
1252                                 ssid->pbss = 1;
1253                         }
1254                         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
1255                                           "SSID", ssid->ssid, ssid->ssid_len);
1256                 }
1257         }
1258 #endif /* CONFIG_P2P */
1259         if (pin)
1260                 os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u%s\"",
1261                             pin, dev_pw_id, hash);
1262         else if (pin == NULL && dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
1263                 os_snprintf(val, sizeof(val), "\"dev_pw_id=%u%s\"",
1264                             dev_pw_id, hash);
1265         } else {
1266                 if (wps_generate_pin(&rpin) < 0) {
1267                         wpa_printf(MSG_DEBUG, "WPS: Could not generate PIN");
1268                         return -1;
1269                 }
1270                 os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u%s\"",
1271                             rpin, dev_pw_id, hash);
1272         }
1273         if (wpa_config_set(ssid, "phase1", val, 0) < 0) {
1274                 wpa_printf(MSG_DEBUG, "WPS: Failed to set phase1 '%s'", val);
1275                 return -1;
1276         }
1277         if (wpa_s->wps_fragment_size)
1278                 ssid->eap.fragment_size = wpa_s->wps_fragment_size;
1279         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
1280                                wpa_s, NULL);
1281         wpa_s->wps_ap_iter = 1;
1282         wpas_wps_reassoc(wpa_s, ssid, bssid, freq);
1283         return rpin;
1284 }
1285
1286
1287 int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
1288                        const char *pin, int p2p_group, u16 dev_pw_id)
1289 {
1290         os_get_reltime(&wpa_s->wps_pin_start_time);
1291         return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group,
1292                                      dev_pw_id, NULL, NULL, 0, 0);
1293 }
1294
1295
1296 void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s)
1297 {
1298         union wps_event_data data;
1299
1300         os_memset(&data, 0, sizeof(data));
1301         data.fail.config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
1302         data.fail.error_indication = WPS_EI_NO_ERROR;
1303         /*
1304          * Call wpas_notify_wps_event_fail() directly instead of through
1305          * wpa_supplicant_wps_event() which would end up registering unnecessary
1306          * timeouts (those are only for the case where the failure happens
1307          * during an EAP-WSC exchange).
1308          */
1309         wpas_notify_wps_event_fail(wpa_s, &data.fail);
1310 }
1311
1312 /* Cancel the wps pbc/pin requests */
1313 int wpas_wps_cancel(struct wpa_supplicant *wpa_s)
1314 {
1315 #ifdef CONFIG_AP
1316         if (wpa_s->ap_iface) {
1317                 wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode");
1318                 return wpa_supplicant_ap_wps_cancel(wpa_s);
1319         }
1320 #endif /* CONFIG_AP */
1321
1322         if (wpa_s->wpa_state == WPA_SCANNING ||
1323             wpa_s->wpa_state == WPA_DISCONNECTED) {
1324                 wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan");
1325                 wpa_supplicant_cancel_scan(wpa_s);
1326                 wpas_clear_wps(wpa_s);
1327         } else if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
1328                 wpa_printf(MSG_DEBUG, "WPS: Cancel operation - "
1329                            "deauthenticate");
1330                 wpa_s->own_disconnect_req = 1;
1331                 wpa_supplicant_deauthenticate(wpa_s,
1332                                               WLAN_REASON_DEAUTH_LEAVING);
1333                 wpas_clear_wps(wpa_s);
1334         } else {
1335                 wpas_wps_reenable_networks(wpa_s);
1336                 wpas_wps_clear_ap_info(wpa_s);
1337                 if (eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL) >
1338                     0)
1339                         wpas_clear_wps(wpa_s);
1340         }
1341
1342         wpa_s->after_wps = 0;
1343
1344         return 0;
1345 }
1346
1347
1348 int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,
1349                        const char *pin, struct wps_new_ap_settings *settings)
1350 {
1351         struct wpa_ssid *ssid;
1352         char val[200];
1353         char *pos, *end;
1354         int res;
1355
1356 #ifdef CONFIG_AP
1357         if (wpa_s->ap_iface) {
1358                 wpa_printf(MSG_DEBUG,
1359                            "WPS: Reject request to start Registrar(as station) operation while AP mode is enabled");
1360                 return -1;
1361         }
1362 #endif /* CONFIG_AP */
1363         if (!pin)
1364                 return -1;
1365         wpas_clear_wps(wpa_s);
1366         ssid = wpas_wps_add_network(wpa_s, 1, NULL, bssid);
1367         if (ssid == NULL)
1368                 return -1;
1369         ssid->temporary = 1;
1370         pos = val;
1371         end = pos + sizeof(val);
1372         res = os_snprintf(pos, end - pos, "\"pin=%s", pin);
1373         if (os_snprintf_error(end - pos, res))
1374                 return -1;
1375         pos += res;
1376         if (settings) {
1377                 res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s "
1378                                   "new_encr=%s new_key=%s",
1379                                   settings->ssid_hex, settings->auth,
1380                                   settings->encr, settings->key_hex);
1381                 if (os_snprintf_error(end - pos, res))
1382                         return -1;
1383                 pos += res;
1384         }
1385         res = os_snprintf(pos, end - pos, "\"");
1386         if (os_snprintf_error(end - pos, res))
1387                 return -1;
1388         if (wpa_config_set(ssid, "phase1", val, 0) < 0)
1389                 return -1;
1390         if (wpa_s->wps_fragment_size)
1391                 ssid->eap.fragment_size = wpa_s->wps_fragment_size;
1392         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
1393                                wpa_s, NULL);
1394         wpas_wps_reassoc(wpa_s, ssid, bssid, 0);
1395         return 0;
1396 }
1397
1398
1399 static int wpas_wps_new_psk_cb(void *ctx, const u8 *mac_addr,
1400                                const u8 *p2p_dev_addr, const u8 *psk,
1401                                size_t psk_len)
1402 {
1403         if (is_zero_ether_addr(p2p_dev_addr)) {
1404                 wpa_printf(MSG_DEBUG,
1405                            "Received new WPA/WPA2-PSK from WPS for STA " MACSTR,
1406                            MAC2STR(mac_addr));
1407         } else {
1408                 wpa_printf(MSG_DEBUG,
1409                            "Received new WPA/WPA2-PSK from WPS for STA " MACSTR
1410                            " P2P Device Addr " MACSTR,
1411                            MAC2STR(mac_addr), MAC2STR(p2p_dev_addr));
1412         }
1413         wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
1414
1415         /* TODO */
1416
1417         return 0;
1418 }
1419
1420
1421 static void wpas_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
1422                                    const struct wps_device_data *dev)
1423 {
1424         char uuid[40], txt[400];
1425         int len;
1426         char devtype[WPS_DEV_TYPE_BUFSIZE];
1427         if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
1428                 return;
1429         wpa_printf(MSG_DEBUG, "WPS: PIN needed for UUID-E %s", uuid);
1430         len = os_snprintf(txt, sizeof(txt), "WPS-EVENT-PIN-NEEDED %s " MACSTR
1431                           " [%s|%s|%s|%s|%s|%s]",
1432                           uuid, MAC2STR(dev->mac_addr), dev->device_name,
1433                           dev->manufacturer, dev->model_name,
1434                           dev->model_number, dev->serial_number,
1435                           wps_dev_type_bin2str(dev->pri_dev_type, devtype,
1436                                                sizeof(devtype)));
1437         if (!os_snprintf_error(sizeof(txt), len))
1438                 wpa_printf(MSG_INFO, "%s", txt);
1439 }
1440
1441
1442 static void wpas_wps_set_sel_reg_cb(void *ctx, int sel_reg, u16 dev_passwd_id,
1443                                     u16 sel_reg_config_methods)
1444 {
1445 #ifdef CONFIG_WPS_ER
1446         struct wpa_supplicant *wpa_s = ctx;
1447
1448         if (wpa_s->wps_er == NULL)
1449                 return;
1450         wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar - sel_reg=%d "
1451                    "dev_password_id=%u sel_reg_config_methods=0x%x",
1452                    sel_reg, dev_passwd_id, sel_reg_config_methods);
1453         wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
1454                            sel_reg_config_methods);
1455 #endif /* CONFIG_WPS_ER */
1456 }
1457
1458
1459 static u16 wps_fix_config_methods(u16 config_methods)
1460 {
1461         if ((config_methods &
1462              (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
1463               WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
1464                 wpa_printf(MSG_INFO, "WPS: Converting display to "
1465                            "virtual_display for WPS 2.0 compliance");
1466                 config_methods |= WPS_CONFIG_VIRT_DISPLAY;
1467         }
1468         if ((config_methods &
1469              (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
1470               WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
1471                 wpa_printf(MSG_INFO, "WPS: Converting push_button to "
1472                            "virtual_push_button for WPS 2.0 compliance");
1473                 config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
1474         }
1475
1476         return config_methods;
1477 }
1478
1479
1480 static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
1481                               struct wps_context *wps)
1482 {
1483         char buf[50];
1484         const char *src;
1485
1486         if (is_nil_uuid(wpa_s->conf->uuid)) {
1487                 struct wpa_supplicant *first;
1488                 first = wpa_s->global->ifaces;
1489                 while (first && first->next)
1490                         first = first->next;
1491                 if (first && first != wpa_s) {
1492                         if (wps != wpa_s->global->ifaces->wps)
1493                                 os_memcpy(wps->uuid,
1494                                           wpa_s->global->ifaces->wps->uuid,
1495                                           WPS_UUID_LEN);
1496                         src = "from the first interface";
1497                 } else if (wpa_s->conf->auto_uuid == 1) {
1498                         uuid_random(wps->uuid);
1499                         src = "based on random data";
1500                 } else {
1501                         uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
1502                         src = "based on MAC address";
1503                 }
1504         } else {
1505                 os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
1506                 src = "based on configuration";
1507         }
1508
1509         uuid_bin2str(wps->uuid, buf, sizeof(buf));
1510         wpa_dbg(wpa_s, MSG_DEBUG, "WPS: UUID %s: %s", src, buf);
1511 }
1512
1513
1514 static void wpas_wps_set_vendor_ext_m1(struct wpa_supplicant *wpa_s,
1515                                        struct wps_context *wps)
1516 {
1517         wpabuf_free(wps->dev.vendor_ext_m1);
1518         wps->dev.vendor_ext_m1 = NULL;
1519
1520         if (wpa_s->conf->wps_vendor_ext_m1) {
1521                 wps->dev.vendor_ext_m1 =
1522                         wpabuf_dup(wpa_s->conf->wps_vendor_ext_m1);
1523                 if (!wps->dev.vendor_ext_m1) {
1524                         wpa_printf(MSG_ERROR, "WPS: Cannot "
1525                                    "allocate memory for vendor_ext_m1");
1526                 }
1527         }
1528 }
1529
1530
1531 int wpas_wps_init(struct wpa_supplicant *wpa_s)
1532 {
1533         struct wps_context *wps;
1534         struct wps_registrar_config rcfg;
1535         struct hostapd_hw_modes *modes;
1536         u16 m;
1537
1538         wps = os_zalloc(sizeof(*wps));
1539         if (wps == NULL)
1540                 return -1;
1541
1542         wps->cred_cb = wpa_supplicant_wps_cred;
1543         wps->event_cb = wpa_supplicant_wps_event;
1544         wps->rf_band_cb = wpa_supplicant_wps_rf_band;
1545         wps->cb_ctx = wpa_s;
1546
1547         wps->dev.device_name = wpa_s->conf->device_name;
1548         wps->dev.manufacturer = wpa_s->conf->manufacturer;
1549         wps->dev.model_name = wpa_s->conf->model_name;
1550         wps->dev.model_number = wpa_s->conf->model_number;
1551         wps->dev.serial_number = wpa_s->conf->serial_number;
1552         wps->config_methods =
1553                 wps_config_methods_str2bin(wpa_s->conf->config_methods);
1554         if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
1555             (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
1556                 wpa_printf(MSG_ERROR, "WPS: Both Label and Display config "
1557                            "methods are not allowed at the same time");
1558                 os_free(wps);
1559                 return -1;
1560         }
1561         wps->config_methods = wps_fix_config_methods(wps->config_methods);
1562         wps->dev.config_methods = wps->config_methods;
1563         os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
1564                   WPS_DEV_TYPE_LEN);
1565
1566         wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
1567         os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
1568                   WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
1569
1570         wpas_wps_set_vendor_ext_m1(wpa_s, wps);
1571
1572         wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
1573         modes = wpa_s->hw.modes;
1574         if (modes) {
1575                 for (m = 0; m < wpa_s->hw.num_modes; m++) {
1576                         if (modes[m].mode == HOSTAPD_MODE_IEEE80211B ||
1577                             modes[m].mode == HOSTAPD_MODE_IEEE80211G)
1578                                 wps->dev.rf_bands |= WPS_RF_24GHZ;
1579                         else if (modes[m].mode == HOSTAPD_MODE_IEEE80211A)
1580                                 wps->dev.rf_bands |= WPS_RF_50GHZ;
1581                         else if (modes[m].mode == HOSTAPD_MODE_IEEE80211AD)
1582                                 wps->dev.rf_bands |= WPS_RF_60GHZ;
1583                 }
1584         }
1585         if (wps->dev.rf_bands == 0) {
1586                 /*
1587                  * Default to claiming support for both bands if the driver
1588                  * does not provide support for fetching supported bands.
1589                  */
1590                 wps->dev.rf_bands = WPS_RF_24GHZ | WPS_RF_50GHZ;
1591         }
1592         os_memcpy(wps->dev.mac_addr, wpa_s->own_addr, ETH_ALEN);
1593         wpas_wps_set_uuid(wpa_s, wps);
1594
1595         wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
1596         wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
1597
1598         os_memset(&rcfg, 0, sizeof(rcfg));
1599         rcfg.new_psk_cb = wpas_wps_new_psk_cb;
1600         rcfg.pin_needed_cb = wpas_wps_pin_needed_cb;
1601         rcfg.set_sel_reg_cb = wpas_wps_set_sel_reg_cb;
1602         rcfg.cb_ctx = wpa_s;
1603
1604         wps->registrar = wps_registrar_init(wps, &rcfg);
1605         if (wps->registrar == NULL) {
1606                 wpa_printf(MSG_DEBUG, "Failed to initialize WPS Registrar");
1607                 os_free(wps);
1608                 return -1;
1609         }
1610
1611         wpa_s->wps = wps;
1612
1613         return 0;
1614 }
1615
1616
1617 #ifdef CONFIG_WPS_ER
1618 static void wpas_wps_nfc_clear(struct wps_context *wps)
1619 {
1620         wps->ap_nfc_dev_pw_id = 0;
1621         wpabuf_free(wps->ap_nfc_dh_pubkey);
1622         wps->ap_nfc_dh_pubkey = NULL;
1623         wpabuf_free(wps->ap_nfc_dh_privkey);
1624         wps->ap_nfc_dh_privkey = NULL;
1625         wpabuf_free(wps->ap_nfc_dev_pw);
1626         wps->ap_nfc_dev_pw = NULL;
1627 }
1628 #endif /* CONFIG_WPS_ER */
1629
1630
1631 void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
1632 {
1633         wpas_wps_assoc_with_cred_cancel(wpa_s);
1634         eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
1635         eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
1636         eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);
1637         wpas_wps_clear_ap_info(wpa_s);
1638
1639 #ifdef CONFIG_P2P
1640         eloop_cancel_timeout(wpas_p2p_pbc_overlap_cb, wpa_s, NULL);
1641 #endif /* CONFIG_P2P */
1642
1643         if (wpa_s->wps == NULL)
1644                 return;
1645
1646 #ifdef CONFIG_WPS_ER
1647         wps_er_deinit(wpa_s->wps_er, NULL, NULL);
1648         wpa_s->wps_er = NULL;
1649         wpas_wps_nfc_clear(wpa_s->wps);
1650 #endif /* CONFIG_WPS_ER */
1651
1652         wps_registrar_deinit(wpa_s->wps->registrar);
1653         wpabuf_free(wpa_s->wps->dh_pubkey);
1654         wpabuf_free(wpa_s->wps->dh_privkey);
1655         wpabuf_free(wpa_s->wps->dev.vendor_ext_m1);
1656         os_free(wpa_s->wps->network_key);
1657         os_free(wpa_s->wps);
1658         wpa_s->wps = NULL;
1659 }
1660
1661
1662 int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
1663                             struct wpa_ssid *ssid, struct wpa_bss *bss)
1664 {
1665         struct wpabuf *wps_ie;
1666
1667         if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
1668                 return -1;
1669
1670         wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1671         if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
1672                 if (!wps_ie) {
1673                         wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
1674                         return 0;
1675                 }
1676
1677                 if (!wps_is_selected_pbc_registrar(wps_ie)) {
1678                         wpa_printf(MSG_DEBUG, "   skip - WPS AP "
1679                                    "without active PBC Registrar");
1680                         wpabuf_free(wps_ie);
1681                         return 0;
1682                 }
1683
1684                 /* TODO: overlap detection */
1685                 wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
1686                            "(Active PBC)");
1687                 wpabuf_free(wps_ie);
1688                 return 1;
1689         }
1690
1691         if (eap_is_wps_pin_enrollee(&ssid->eap)) {
1692                 if (!wps_ie) {
1693                         wpa_printf(MSG_DEBUG, "   skip - non-WPS AP");
1694                         return 0;
1695                 }
1696
1697                 /*
1698                  * Start with WPS APs that advertise our address as an
1699                  * authorized MAC (v2.0) or active PIN Registrar (v1.0) and
1700                  * allow any WPS AP after couple of scans since some APs do not
1701                  * set Selected Registrar attribute properly when using
1702                  * external Registrar.
1703                  */
1704                 if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
1705                         struct os_reltime age;
1706
1707                         os_reltime_age(&wpa_s->wps_pin_start_time, &age);
1708
1709                         if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG ||
1710                             age.sec < WPS_PIN_TIME_IGNORE_SEL_REG) {
1711                                 wpa_printf(MSG_DEBUG,
1712                                            "   skip - WPS AP without active PIN Registrar (scan_runs=%d age=%d)",
1713                                            wpa_s->scan_runs, (int) age.sec);
1714                                 wpabuf_free(wps_ie);
1715                                 return 0;
1716                         }
1717                         wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
1718                 } else {
1719                         wpa_printf(MSG_DEBUG, "   selected based on WPS IE "
1720                                    "(Authorized MAC or Active PIN)");
1721                 }
1722                 wpabuf_free(wps_ie);
1723                 return 1;
1724         }
1725
1726         if (wps_ie) {
1727                 wpa_printf(MSG_DEBUG, "   selected based on WPS IE");
1728                 wpabuf_free(wps_ie);
1729                 return 1;
1730         }
1731
1732         return -1;
1733 }
1734
1735
1736 int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s,
1737                               struct wpa_ssid *ssid,
1738                               struct wpa_bss *bss)
1739 {
1740         struct wpabuf *wps_ie = NULL;
1741         int ret = 0;
1742
1743         if (eap_is_wps_pbc_enrollee(&ssid->eap)) {
1744                 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1745                 if (wps_ie && wps_is_selected_pbc_registrar(wps_ie)) {
1746                         /* allow wildcard SSID for WPS PBC */
1747                         ret = 1;
1748                 }
1749         } else if (eap_is_wps_pin_enrollee(&ssid->eap)) {
1750                 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1751                 if (wps_ie &&
1752                     (wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1) ||
1753                      wpa_s->scan_runs >= WPS_PIN_SCAN_IGNORE_SEL_REG)) {
1754                         /* allow wildcard SSID for WPS PIN */
1755                         ret = 1;
1756                 }
1757         }
1758
1759         if (!ret && ssid->bssid_set &&
1760             os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
1761                 /* allow wildcard SSID due to hardcoded BSSID match */
1762                 ret = 1;
1763         }
1764
1765 #ifdef CONFIG_WPS_STRICT
1766         if (wps_ie) {
1767                 if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
1768                                                    0, bss->bssid) < 0)
1769                         ret = 0;
1770                 if (bss->beacon_ie_len) {
1771                         struct wpabuf *bcn_wps;
1772                         bcn_wps = wpa_bss_get_vendor_ie_multi_beacon(
1773                                 bss, WPS_IE_VENDOR_TYPE);
1774                         if (bcn_wps == NULL) {
1775                                 wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
1776                                            "missing from AP Beacon");
1777                                 ret = 0;
1778                         } else {
1779                                 if (wps_validate_beacon(wps_ie) < 0)
1780                                         ret = 0;
1781                                 wpabuf_free(bcn_wps);
1782                         }
1783                 }
1784         }
1785 #endif /* CONFIG_WPS_STRICT */
1786
1787         wpabuf_free(wps_ie);
1788
1789         return ret;
1790 }
1791
1792
1793 int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s,
1794                               struct wpa_bss *selected, struct wpa_ssid *ssid)
1795 {
1796         const u8 *sel_uuid;
1797         struct wpabuf *wps_ie;
1798         int ret = 0;
1799         size_t i;
1800
1801         if (!eap_is_wps_pbc_enrollee(&ssid->eap))
1802                 return 0;
1803
1804         wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
1805                    "present in scan results; selected BSSID " MACSTR,
1806                    MAC2STR(selected->bssid));
1807
1808         /* Make sure that only one AP is in active PBC mode */
1809         wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
1810         if (wps_ie) {
1811                 sel_uuid = wps_get_uuid_e(wps_ie);
1812                 wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
1813                             sel_uuid, UUID_LEN);
1814         } else {
1815                 wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
1816                            "WPS IE?!");
1817                 sel_uuid = NULL;
1818         }
1819
1820         for (i = 0; i < wpa_s->num_wps_ap; i++) {
1821                 struct wps_ap_info *ap = &wpa_s->wps_ap[i];
1822
1823                 if (!ap->pbc_active ||
1824                     os_memcmp(selected->bssid, ap->bssid, ETH_ALEN) == 0)
1825                         continue;
1826
1827                 wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: "
1828                            MACSTR, MAC2STR(ap->bssid));
1829                 wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
1830                             ap->uuid, UUID_LEN);
1831                 if (sel_uuid == NULL ||
1832                     os_memcmp(sel_uuid, ap->uuid, UUID_LEN) != 0) {
1833                         ret = 1; /* PBC overlap */
1834                         wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: "
1835                                 MACSTR " and " MACSTR,
1836                                 MAC2STR(selected->bssid),
1837                                 MAC2STR(ap->bssid));
1838                         break;
1839                 }
1840
1841                 /* TODO: verify that this is reasonable dual-band situation */
1842         }
1843
1844         wpabuf_free(wps_ie);
1845
1846         return ret;
1847 }
1848
1849
1850 void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
1851 {
1852         struct wpa_bss *bss;
1853         unsigned int pbc = 0, auth = 0, pin = 0, wps = 0;
1854
1855         if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED)
1856                 return;
1857
1858         dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1859                 struct wpabuf *ie;
1860                 ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
1861                 if (!ie)
1862                         continue;
1863                 if (wps_is_selected_pbc_registrar(ie))
1864                         pbc++;
1865                 else if (wps_is_addr_authorized(ie, wpa_s->own_addr, 0))
1866                         auth++;
1867                 else if (wps_is_selected_pin_registrar(ie))
1868                         pin++;
1869                 else
1870                         wps++;
1871                 wpabuf_free(ie);
1872         }
1873
1874         if (pbc)
1875                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC);
1876         else if (auth)
1877                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_AUTH);
1878         else if (pin)
1879                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN);
1880         else if (wps)
1881                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE);
1882 }
1883
1884
1885 int wpas_wps_searching(struct wpa_supplicant *wpa_s)
1886 {
1887         struct wpa_ssid *ssid;
1888
1889         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1890                 if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !ssid->disabled)
1891                         return 1;
1892         }
1893
1894         return 0;
1895 }
1896
1897
1898 int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
1899                               char *end)
1900 {
1901         struct wpabuf *wps_ie;
1902         int ret;
1903
1904         wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, WPS_DEV_OUI_WFA);
1905         if (wps_ie == NULL)
1906                 return 0;
1907
1908         ret = wps_attr_text(wps_ie, buf, end);
1909         wpabuf_free(wps_ie);
1910         return ret;
1911 }
1912
1913
1914 int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter)
1915 {
1916 #ifdef CONFIG_WPS_ER
1917         if (wpa_s->wps_er) {
1918                 wps_er_refresh(wpa_s->wps_er);
1919                 return 0;
1920         }
1921         wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname, filter);
1922         if (wpa_s->wps_er == NULL)
1923                 return -1;
1924         return 0;
1925 #else /* CONFIG_WPS_ER */
1926         return 0;
1927 #endif /* CONFIG_WPS_ER */
1928 }
1929
1930
1931 void wpas_wps_er_stop(struct wpa_supplicant *wpa_s)
1932 {
1933 #ifdef CONFIG_WPS_ER
1934         wps_er_deinit(wpa_s->wps_er, NULL, NULL);
1935         wpa_s->wps_er = NULL;
1936 #endif /* CONFIG_WPS_ER */
1937 }
1938
1939
1940 #ifdef CONFIG_WPS_ER
1941 int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const u8 *addr,
1942                         const char *uuid, const char *pin)
1943 {
1944         u8 u[UUID_LEN];
1945         const u8 *use_uuid = NULL;
1946         u8 addr_buf[ETH_ALEN];
1947
1948         if (os_strcmp(uuid, "any") == 0) {
1949         } else if (uuid_str2bin(uuid, u) == 0) {
1950                 use_uuid = u;
1951         } else if (hwaddr_aton(uuid, addr_buf) == 0) {
1952                 use_uuid = wps_er_get_sta_uuid(wpa_s->wps_er, addr_buf);
1953                 if (use_uuid == NULL)
1954                         return -1;
1955         } else
1956                 return -1;
1957         return wps_registrar_add_pin(wpa_s->wps->registrar, addr,
1958                                      use_uuid,
1959                                      (const u8 *) pin, os_strlen(pin), 300);
1960 }
1961
1962
1963 int wpas_wps_er_pbc(struct wpa_supplicant *wpa_s, const char *uuid)
1964 {
1965         u8 u[UUID_LEN], *use_uuid = NULL;
1966         u8 addr[ETH_ALEN], *use_addr = NULL;
1967
1968         if (uuid_str2bin(uuid, u) == 0)
1969                 use_uuid = u;
1970         else if (hwaddr_aton(uuid, addr) == 0)
1971                 use_addr = addr;
1972         else
1973                 return -1;
1974         return wps_er_pbc(wpa_s->wps_er, use_uuid, use_addr);
1975 }
1976
1977
1978 int wpas_wps_er_learn(struct wpa_supplicant *wpa_s, const char *uuid,
1979                       const char *pin)
1980 {
1981         u8 u[UUID_LEN], *use_uuid = NULL;
1982         u8 addr[ETH_ALEN], *use_addr = NULL;
1983
1984         if (uuid_str2bin(uuid, u) == 0)
1985                 use_uuid = u;
1986         else if (hwaddr_aton(uuid, addr) == 0)
1987                 use_addr = addr;
1988         else
1989                 return -1;
1990
1991         return wps_er_learn(wpa_s->wps_er, use_uuid, use_addr, (const u8 *) pin,
1992                             os_strlen(pin));
1993 }
1994
1995
1996 static int wpas_wps_network_to_cred(struct wpa_ssid *ssid,
1997                                     struct wps_credential *cred)
1998 {
1999         os_memset(cred, 0, sizeof(*cred));
2000         if (ssid->ssid_len > SSID_MAX_LEN)
2001                 return -1;
2002         os_memcpy(cred->ssid, ssid->ssid, ssid->ssid_len);
2003         cred->ssid_len = ssid->ssid_len;
2004         if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) {
2005                 cred->auth_type = (ssid->proto & WPA_PROTO_RSN) ?
2006                         WPS_AUTH_WPA2PSK : WPS_AUTH_WPAPSK;
2007                 if (ssid->pairwise_cipher & WPA_CIPHER_CCMP)
2008                         cred->encr_type = WPS_ENCR_AES;
2009                 else
2010                         cred->encr_type = WPS_ENCR_TKIP;
2011                 if (ssid->passphrase) {
2012                         cred->key_len = os_strlen(ssid->passphrase);
2013                         if (cred->key_len >= 64)
2014                                 return -1;
2015                         os_memcpy(cred->key, ssid->passphrase, cred->key_len);
2016                 } else if (ssid->psk_set) {
2017                         cred->key_len = 32;
2018                         os_memcpy(cred->key, ssid->psk, 32);
2019                 } else
2020                         return -1;
2021         } else {
2022                 cred->auth_type = WPS_AUTH_OPEN;
2023                 cred->encr_type = WPS_ENCR_NONE;
2024         }
2025
2026         return 0;
2027 }
2028
2029
2030 int wpas_wps_er_set_config(struct wpa_supplicant *wpa_s, const char *uuid,
2031                            int id)
2032 {
2033         u8 u[UUID_LEN], *use_uuid = NULL;
2034         u8 addr[ETH_ALEN], *use_addr = NULL;
2035         struct wpa_ssid *ssid;
2036         struct wps_credential cred;
2037         int ret;
2038
2039         if (uuid_str2bin(uuid, u) == 0)
2040                 use_uuid = u;
2041         else if (hwaddr_aton(uuid, addr) == 0)
2042                 use_addr = addr;
2043         else
2044                 return -1;
2045         ssid = wpa_config_get_network(wpa_s->conf, id);
2046         if (ssid == NULL || ssid->ssid == NULL)
2047                 return -1;
2048
2049         if (wpas_wps_network_to_cred(ssid, &cred) < 0)
2050                 return -1;
2051         ret = wps_er_set_config(wpa_s->wps_er, use_uuid, use_addr, &cred);
2052         os_memset(&cred, 0, sizeof(cred));
2053         return ret;
2054 }
2055
2056
2057 int wpas_wps_er_config(struct wpa_supplicant *wpa_s, const char *uuid,
2058                        const char *pin, struct wps_new_ap_settings *settings)
2059 {
2060         u8 u[UUID_LEN], *use_uuid = NULL;
2061         u8 addr[ETH_ALEN], *use_addr = NULL;
2062         struct wps_credential cred;
2063         size_t len;
2064
2065         if (uuid_str2bin(uuid, u) == 0)
2066                 use_uuid = u;
2067         else if (hwaddr_aton(uuid, addr) == 0)
2068                 use_addr = addr;
2069         else
2070                 return -1;
2071         if (settings->ssid_hex == NULL || settings->auth == NULL ||
2072             settings->encr == NULL || settings->key_hex == NULL)
2073                 return -1;
2074
2075         os_memset(&cred, 0, sizeof(cred));
2076         len = os_strlen(settings->ssid_hex);
2077         if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
2078             hexstr2bin(settings->ssid_hex, cred.ssid, len / 2))
2079                 return -1;
2080         cred.ssid_len = len / 2;
2081
2082         len = os_strlen(settings->key_hex);
2083         if ((len & 1) || len > 2 * sizeof(cred.key) ||
2084             hexstr2bin(settings->key_hex, cred.key, len / 2))
2085                 return -1;
2086         cred.key_len = len / 2;
2087
2088         if (os_strcmp(settings->auth, "OPEN") == 0)
2089                 cred.auth_type = WPS_AUTH_OPEN;
2090         else if (os_strcmp(settings->auth, "WPAPSK") == 0)
2091                 cred.auth_type = WPS_AUTH_WPAPSK;
2092         else if (os_strcmp(settings->auth, "WPA2PSK") == 0)
2093                 cred.auth_type = WPS_AUTH_WPA2PSK;
2094         else
2095                 return -1;
2096
2097         if (os_strcmp(settings->encr, "NONE") == 0)
2098                 cred.encr_type = WPS_ENCR_NONE;
2099 #ifdef CONFIG_TESTING_OPTIONS
2100         else if (os_strcmp(settings->encr, "WEP") == 0)
2101                 cred.encr_type = WPS_ENCR_WEP;
2102 #endif /* CONFIG_TESTING_OPTIONS */
2103         else if (os_strcmp(settings->encr, "TKIP") == 0)
2104                 cred.encr_type = WPS_ENCR_TKIP;
2105         else if (os_strcmp(settings->encr, "CCMP") == 0)
2106                 cred.encr_type = WPS_ENCR_AES;
2107         else
2108                 return -1;
2109
2110         return wps_er_config(wpa_s->wps_er, use_uuid, use_addr,
2111                              (const u8 *) pin, os_strlen(pin), &cred);
2112 }
2113
2114
2115 #ifdef CONFIG_WPS_NFC
2116 struct wpabuf * wpas_wps_er_nfc_config_token(struct wpa_supplicant *wpa_s,
2117                                              int ndef, const char *uuid)
2118 {
2119         struct wpabuf *ret;
2120         u8 u[UUID_LEN], *use_uuid = NULL;
2121         u8 addr[ETH_ALEN], *use_addr = NULL;
2122
2123         if (!wpa_s->wps_er)
2124                 return NULL;
2125
2126         if (uuid_str2bin(uuid, u) == 0)
2127                 use_uuid = u;
2128         else if (hwaddr_aton(uuid, addr) == 0)
2129                 use_addr = addr;
2130         else
2131                 return NULL;
2132
2133         ret = wps_er_nfc_config_token(wpa_s->wps_er, use_uuid, use_addr);
2134         if (ndef && ret) {
2135                 struct wpabuf *tmp;
2136                 tmp = ndef_build_wifi(ret);
2137                 wpabuf_free(ret);
2138                 if (tmp == NULL)
2139                         return NULL;
2140                 ret = tmp;
2141         }
2142
2143         return ret;
2144 }
2145 #endif /* CONFIG_WPS_NFC */
2146
2147
2148 static int callbacks_pending = 0;
2149
2150 static void wpas_wps_terminate_cb(void *ctx)
2151 {
2152         wpa_printf(MSG_DEBUG, "WPS ER: Terminated");
2153         if (--callbacks_pending <= 0)
2154                 eloop_terminate();
2155 }
2156 #endif /* CONFIG_WPS_ER */
2157
2158
2159 int wpas_wps_terminate_pending(struct wpa_supplicant *wpa_s)
2160 {
2161 #ifdef CONFIG_WPS_ER
2162         if (wpa_s->wps_er) {
2163                 callbacks_pending++;
2164                 wps_er_deinit(wpa_s->wps_er, wpas_wps_terminate_cb, wpa_s);
2165                 wpa_s->wps_er = NULL;
2166                 return 1;
2167         }
2168 #endif /* CONFIG_WPS_ER */
2169         return 0;
2170 }
2171
2172
2173 void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
2174 {
2175         struct wps_context *wps = wpa_s->wps;
2176
2177         if (wps == NULL)
2178                 return;
2179
2180         if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
2181                 wps->config_methods = wps_config_methods_str2bin(
2182                         wpa_s->conf->config_methods);
2183                 if ((wps->config_methods &
2184                      (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
2185                     (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
2186                         wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
2187                                    "config methods are not allowed at the "
2188                                    "same time");
2189                         wps->config_methods &= ~WPS_CONFIG_LABEL;
2190                 }
2191         }
2192         wps->config_methods = wps_fix_config_methods(wps->config_methods);
2193         wps->dev.config_methods = wps->config_methods;
2194
2195         if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
2196                 os_memcpy(wps->dev.pri_dev_type, wpa_s->conf->device_type,
2197                           WPS_DEV_TYPE_LEN);
2198
2199         if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE) {
2200                 wps->dev.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
2201                 os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
2202                           wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
2203         }
2204
2205         if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION)
2206                 wpas_wps_set_vendor_ext_m1(wpa_s, wps);
2207
2208         if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
2209                 wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
2210
2211         if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID)
2212                 wpas_wps_set_uuid(wpa_s, wps);
2213
2214         if (wpa_s->conf->changed_parameters &
2215             (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) {
2216                 /* Update pointers to make sure they refer current values */
2217                 wps->dev.device_name = wpa_s->conf->device_name;
2218                 wps->dev.manufacturer = wpa_s->conf->manufacturer;
2219                 wps->dev.model_name = wpa_s->conf->model_name;
2220                 wps->dev.model_number = wpa_s->conf->model_number;
2221                 wps->dev.serial_number = wpa_s->conf->serial_number;
2222         }
2223 }
2224
2225
2226 #ifdef CONFIG_WPS_NFC
2227
2228 #ifdef CONFIG_WPS_ER
2229 static struct wpabuf *
2230 wpas_wps_network_config_token(struct wpa_supplicant *wpa_s, int ndef,
2231                               struct wpa_ssid *ssid)
2232 {
2233         struct wpabuf *ret;
2234         struct wps_credential cred;
2235
2236         if (wpas_wps_network_to_cred(ssid, &cred) < 0)
2237                 return NULL;
2238
2239         ret = wps_er_config_token_from_cred(wpa_s->wps, &cred);
2240
2241         if (ndef && ret) {
2242                 struct wpabuf *tmp;
2243                 tmp = ndef_build_wifi(ret);
2244                 wpabuf_free(ret);
2245                 if (tmp == NULL)
2246                         return NULL;
2247                 ret = tmp;
2248         }
2249
2250         return ret;
2251 }
2252 #endif /* CONFIG_WPS_ER */
2253
2254
2255 struct wpabuf * wpas_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
2256                                           int ndef, const char *id_str)
2257 {
2258 #ifdef CONFIG_WPS_ER
2259         if (id_str) {
2260                 int id;
2261                 char *end = NULL;
2262                 struct wpa_ssid *ssid;
2263
2264                 id = strtol(id_str, &end, 10);
2265                 if (end && *end)
2266                         return NULL;
2267
2268                 ssid = wpa_config_get_network(wpa_s->conf, id);
2269                 if (ssid == NULL)
2270                         return NULL;
2271                 return wpas_wps_network_config_token(wpa_s, ndef, ssid);
2272         }
2273 #endif /* CONFIG_WPS_ER */
2274 #ifdef CONFIG_AP
2275         if (wpa_s->ap_iface)
2276                 return wpas_ap_wps_nfc_config_token(wpa_s, ndef);
2277 #endif /* CONFIG_AP */
2278         return NULL;
2279 }
2280
2281
2282 struct wpabuf * wpas_wps_nfc_token(struct wpa_supplicant *wpa_s, int ndef)
2283 {
2284         if (wpa_s->conf->wps_nfc_pw_from_config) {
2285                 return wps_nfc_token_build(ndef,
2286                                            wpa_s->conf->wps_nfc_dev_pw_id,
2287                                            wpa_s->conf->wps_nfc_dh_pubkey,
2288                                            wpa_s->conf->wps_nfc_dev_pw);
2289         }
2290
2291         return wps_nfc_token_gen(ndef, &wpa_s->conf->wps_nfc_dev_pw_id,
2292                                  &wpa_s->conf->wps_nfc_dh_pubkey,
2293                                  &wpa_s->conf->wps_nfc_dh_privkey,
2294                                  &wpa_s->conf->wps_nfc_dev_pw);
2295 }
2296
2297
2298 int wpas_wps_start_nfc(struct wpa_supplicant *wpa_s, const u8 *go_dev_addr,
2299                        const u8 *bssid,
2300                        const struct wpabuf *dev_pw, u16 dev_pw_id,
2301                        int p2p_group, const u8 *peer_pubkey_hash,
2302                        const u8 *ssid, size_t ssid_len, int freq)
2303 {
2304         struct wps_context *wps = wpa_s->wps;
2305         char pw[32 * 2 + 1];
2306
2307         if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
2308                 dev_pw = wpa_s->conf->wps_nfc_dev_pw;
2309                 dev_pw_id = wpa_s->conf->wps_nfc_dev_pw_id;
2310         }
2311
2312         if (wpa_s->conf->wps_nfc_dh_pubkey == NULL ||
2313             wpa_s->conf->wps_nfc_dh_privkey == NULL) {
2314                 wpa_printf(MSG_DEBUG, "WPS: Missing DH params - "
2315                            "cannot start NFC-triggered connection");
2316                 return -1;
2317         }
2318
2319         if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER && dev_pw == NULL) {
2320                 wpa_printf(MSG_DEBUG, "WPS: Missing Device Password (id=%u) - "
2321                            "cannot start NFC-triggered connection", dev_pw_id);
2322                 return -1;
2323         }
2324
2325         dh5_free(wps->dh_ctx);
2326         wpabuf_free(wps->dh_pubkey);
2327         wpabuf_free(wps->dh_privkey);
2328         wps->dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
2329         wps->dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
2330         if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
2331                 wps->dh_ctx = NULL;
2332                 wpabuf_free(wps->dh_pubkey);
2333                 wps->dh_pubkey = NULL;
2334                 wpabuf_free(wps->dh_privkey);
2335                 wps->dh_privkey = NULL;
2336                 wpa_printf(MSG_DEBUG, "WPS: Failed to get DH priv/pub key");
2337                 return -1;
2338         }
2339         wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
2340         if (wps->dh_ctx == NULL) {
2341                 wpabuf_free(wps->dh_pubkey);
2342                 wps->dh_pubkey = NULL;
2343                 wpabuf_free(wps->dh_privkey);
2344                 wps->dh_privkey = NULL;
2345                 wpa_printf(MSG_DEBUG, "WPS: Failed to initialize DH context");
2346                 return -1;
2347         }
2348
2349         if (dev_pw) {
2350                 wpa_snprintf_hex_uppercase(pw, sizeof(pw),
2351                                            wpabuf_head(dev_pw),
2352                                            wpabuf_len(dev_pw));
2353         }
2354         return wpas_wps_start_dev_pw(wpa_s, go_dev_addr, bssid,
2355                                      dev_pw ? pw : NULL,
2356                                      p2p_group, dev_pw_id, peer_pubkey_hash,
2357                                      ssid, ssid_len, freq);
2358 }
2359
2360
2361 static int wpas_wps_use_cred(struct wpa_supplicant *wpa_s,
2362                              struct wps_parse_attr *attr)
2363 {
2364         /*
2365          * Disable existing networks temporarily to allow the newly learned
2366          * credential to be preferred. Enable the temporarily disabled networks
2367          * after 10 seconds.
2368          */
2369         wpas_wps_temp_disable(wpa_s, NULL);
2370         eloop_register_timeout(10, 0, wpas_wps_reenable_networks_cb, wpa_s,
2371                                NULL);
2372
2373         if (wps_oob_use_cred(wpa_s->wps, attr) < 0)
2374                 return -1;
2375
2376         if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
2377                 return 0;
2378
2379         if (attr->ap_channel) {
2380                 u16 chan = WPA_GET_BE16(attr->ap_channel);
2381                 int freq = 0;
2382
2383                 if (chan >= 1 && chan <= 13)
2384                         freq = 2407 + 5 * chan;
2385                 else if (chan == 14)
2386                         freq = 2484;
2387                 else if (chan >= 30)
2388                         freq = 5000 + 5 * chan;
2389
2390                 if (freq) {
2391                         wpa_printf(MSG_DEBUG, "WPS: Credential container indicated AP channel %u -> %u MHz",
2392                                    chan, freq);
2393                         wpa_s->after_wps = 5;
2394                         wpa_s->wps_freq = freq;
2395                 }
2396         }
2397
2398         wpa_printf(MSG_DEBUG, "WPS: Request reconnection with new network "
2399                    "based on the received credential added");
2400         wpa_s->normal_scans = 0;
2401         wpa_supplicant_reinit_autoscan(wpa_s);
2402         wpa_s->disconnected = 0;
2403         wpa_s->reassociate = 1;
2404
2405         wpa_supplicant_cancel_sched_scan(wpa_s);
2406         wpa_supplicant_req_scan(wpa_s, 0, 0);
2407
2408         return 0;
2409 }
2410
2411
2412 #ifdef CONFIG_WPS_ER
2413 static int wpas_wps_add_nfc_password_token(struct wpa_supplicant *wpa_s,
2414                                            struct wps_parse_attr *attr)
2415 {
2416         return wps_registrar_add_nfc_password_token(
2417                 wpa_s->wps->registrar, attr->oob_dev_password,
2418                 attr->oob_dev_password_len);
2419 }
2420 #endif /* CONFIG_WPS_ER */
2421
2422
2423 static int wpas_wps_nfc_tag_process(struct wpa_supplicant *wpa_s,
2424                                     const struct wpabuf *wps)
2425 {
2426         struct wps_parse_attr attr;
2427
2428         wpa_hexdump_buf(MSG_DEBUG, "WPS: Received NFC tag payload", wps);
2429
2430         if (wps_parse_msg(wps, &attr)) {
2431                 wpa_printf(MSG_DEBUG, "WPS: Ignore invalid data from NFC tag");
2432                 return -1;
2433         }
2434
2435         if (attr.num_cred)
2436                 return wpas_wps_use_cred(wpa_s, &attr);
2437
2438 #ifdef CONFIG_WPS_ER
2439         if (attr.oob_dev_password)
2440                 return wpas_wps_add_nfc_password_token(wpa_s, &attr);
2441 #endif /* CONFIG_WPS_ER */
2442
2443         wpa_printf(MSG_DEBUG, "WPS: Ignore unrecognized NFC tag");
2444         return -1;
2445 }
2446
2447
2448 int wpas_wps_nfc_tag_read(struct wpa_supplicant *wpa_s,
2449                           const struct wpabuf *data, int forced_freq)
2450 {
2451         const struct wpabuf *wps = data;
2452         struct wpabuf *tmp = NULL;
2453         int ret;
2454
2455         if (wpabuf_len(data) < 4)
2456                 return -1;
2457
2458         if (*wpabuf_head_u8(data) != 0x10) {
2459                 /* Assume this contains full NDEF record */
2460                 tmp = ndef_parse_wifi(data);
2461                 if (tmp == NULL) {
2462 #ifdef CONFIG_P2P
2463                         tmp = ndef_parse_p2p(data);
2464                         if (tmp) {
2465                                 ret = wpas_p2p_nfc_tag_process(wpa_s, tmp,
2466                                                                forced_freq);
2467                                 wpabuf_free(tmp);
2468                                 return ret;
2469                         }
2470 #endif /* CONFIG_P2P */
2471                         wpa_printf(MSG_DEBUG, "WPS: Could not parse NDEF");
2472                         return -1;
2473                 }
2474                 wps = tmp;
2475         }
2476
2477         ret = wpas_wps_nfc_tag_process(wpa_s, wps);
2478         wpabuf_free(tmp);
2479         return ret;
2480 }
2481
2482
2483 struct wpabuf * wpas_wps_nfc_handover_req(struct wpa_supplicant *wpa_s,
2484                                           int ndef)
2485 {
2486         struct wpabuf *ret;
2487
2488         if (wpa_s->conf->wps_nfc_dh_pubkey == NULL &&
2489             wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
2490                            &wpa_s->conf->wps_nfc_dh_privkey) < 0)
2491                 return NULL;
2492
2493         ret = wps_build_nfc_handover_req(wpa_s->wps,
2494                                          wpa_s->conf->wps_nfc_dh_pubkey);
2495
2496         if (ndef && ret) {
2497                 struct wpabuf *tmp;
2498                 tmp = ndef_build_wifi(ret);
2499                 wpabuf_free(ret);
2500                 if (tmp == NULL)
2501                         return NULL;
2502                 ret = tmp;
2503         }
2504
2505         return ret;
2506 }
2507
2508
2509 #ifdef CONFIG_WPS_NFC
2510
2511 static struct wpabuf *
2512 wpas_wps_er_nfc_handover_sel(struct wpa_supplicant *wpa_s, int ndef,
2513                              const char *uuid)
2514 {
2515 #ifdef CONFIG_WPS_ER
2516         struct wpabuf *ret;
2517         u8 u[UUID_LEN], *use_uuid = NULL;
2518         u8 addr[ETH_ALEN], *use_addr = NULL;
2519         struct wps_context *wps = wpa_s->wps;
2520
2521         if (wps == NULL)
2522                 return NULL;
2523
2524         if (uuid == NULL)
2525                 return NULL;
2526         if (uuid_str2bin(uuid, u) == 0)
2527                 use_uuid = u;
2528         else if (hwaddr_aton(uuid, addr) == 0)
2529                 use_addr = addr;
2530         else
2531                 return NULL;
2532
2533         if (wpa_s->conf->wps_nfc_dh_pubkey == NULL) {
2534                 if (wps_nfc_gen_dh(&wpa_s->conf->wps_nfc_dh_pubkey,
2535                                    &wpa_s->conf->wps_nfc_dh_privkey) < 0)
2536                         return NULL;
2537         }
2538
2539         wpas_wps_nfc_clear(wps);
2540         wps->ap_nfc_dev_pw_id = DEV_PW_NFC_CONNECTION_HANDOVER;
2541         wps->ap_nfc_dh_pubkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_pubkey);
2542         wps->ap_nfc_dh_privkey = wpabuf_dup(wpa_s->conf->wps_nfc_dh_privkey);
2543         if (!wps->ap_nfc_dh_pubkey || !wps->ap_nfc_dh_privkey) {
2544                 wpas_wps_nfc_clear(wps);
2545                 return NULL;
2546         }
2547
2548         ret = wps_er_nfc_handover_sel(wpa_s->wps_er, wpa_s->wps, use_uuid,
2549                                       use_addr, wpa_s->conf->wps_nfc_dh_pubkey);
2550         if (ndef && ret) {
2551                 struct wpabuf *tmp;
2552                 tmp = ndef_build_wifi(ret);
2553                 wpabuf_free(ret);
2554                 if (tmp == NULL)
2555                         return NULL;
2556                 ret = tmp;
2557         }
2558
2559         return ret;
2560 #else /* CONFIG_WPS_ER */
2561         return NULL;
2562 #endif /* CONFIG_WPS_ER */
2563 }
2564 #endif /* CONFIG_WPS_NFC */
2565
2566
2567 struct wpabuf * wpas_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
2568                                           int ndef, int cr, const char *uuid)
2569 {
2570         struct wpabuf *ret;
2571         if (!cr)
2572                 return NULL;
2573         ret = wpas_ap_wps_nfc_handover_sel(wpa_s, ndef);
2574         if (ret)
2575                 return ret;
2576         return wpas_wps_er_nfc_handover_sel(wpa_s, ndef, uuid);
2577 }
2578
2579
2580 static int wpas_wps_nfc_rx_handover_sel(struct wpa_supplicant *wpa_s,
2581                                         const struct wpabuf *data)
2582 {
2583         struct wpabuf *wps;
2584         int ret = -1;
2585         u16 wsc_len;
2586         const u8 *pos;
2587         struct wpabuf msg;
2588         struct wps_parse_attr attr;
2589         u16 dev_pw_id;
2590         const u8 *bssid = NULL;
2591         int freq = 0;
2592
2593         wps = ndef_parse_wifi(data);
2594         if (wps == NULL)
2595                 return -1;
2596         wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
2597                    "payload from NFC connection handover");
2598         wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
2599         if (wpabuf_len(wps) < 2) {
2600                 wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Select "
2601                            "Message");
2602                 goto out;
2603         }
2604         pos = wpabuf_head(wps);
2605         wsc_len = WPA_GET_BE16(pos);
2606         if (wsc_len > wpabuf_len(wps) - 2) {
2607                 wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
2608                            "in Wi-Fi Handover Select Message", wsc_len);
2609                 goto out;
2610         }
2611         pos += 2;
2612
2613         wpa_hexdump(MSG_DEBUG,
2614                     "WPS: WSC attributes in Wi-Fi Handover Select Message",
2615                     pos, wsc_len);
2616         if (wsc_len < wpabuf_len(wps) - 2) {
2617                 wpa_hexdump(MSG_DEBUG,
2618                             "WPS: Ignore extra data after WSC attributes",
2619                             pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
2620         }
2621
2622         wpabuf_set(&msg, pos, wsc_len);
2623         ret = wps_parse_msg(&msg, &attr);
2624         if (ret < 0) {
2625                 wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
2626                            "Wi-Fi Handover Select Message");
2627                 goto out;
2628         }
2629
2630         if (attr.oob_dev_password == NULL ||
2631             attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
2632                 wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
2633                            "included in Wi-Fi Handover Select Message");
2634                 ret = -1;
2635                 goto out;
2636         }
2637
2638         if (attr.ssid == NULL) {
2639                 wpa_printf(MSG_DEBUG, "WPS: No SSID included in Wi-Fi Handover "
2640                            "Select Message");
2641                 ret = -1;
2642                 goto out;
2643         }
2644
2645         wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", attr.ssid, attr.ssid_len);
2646
2647         if (attr.mac_addr) {
2648                 bssid = attr.mac_addr;
2649                 wpa_printf(MSG_DEBUG, "WPS: MAC Address (BSSID): " MACSTR,
2650                            MAC2STR(bssid));
2651         }
2652
2653         if (attr.rf_bands)
2654                 wpa_printf(MSG_DEBUG, "WPS: RF Bands: %d", *attr.rf_bands);
2655
2656         if (attr.ap_channel) {
2657                 u16 chan = WPA_GET_BE16(attr.ap_channel);
2658
2659                 wpa_printf(MSG_DEBUG, "WPS: AP Channel: %d", chan);
2660
2661                 if (chan >= 1 && chan <= 13 &&
2662                     (attr.rf_bands == NULL || *attr.rf_bands & WPS_RF_24GHZ))
2663                         freq = 2407 + 5 * chan;
2664                 else if (chan == 14 &&
2665                          (attr.rf_bands == NULL ||
2666                           *attr.rf_bands & WPS_RF_24GHZ))
2667                         freq = 2484;
2668                 else if (chan >= 30 &&
2669                          (attr.rf_bands == NULL ||
2670                           *attr.rf_bands & WPS_RF_50GHZ))
2671                         freq = 5000 + 5 * chan;
2672                 else if (chan >= 1 && chan <= 4 &&
2673                          (attr.rf_bands == NULL ||
2674                           *attr.rf_bands & WPS_RF_60GHZ))
2675                         freq = 56160 + 2160 * chan;
2676
2677                 if (freq) {
2678                         wpa_printf(MSG_DEBUG,
2679                                    "WPS: AP indicated channel %u -> %u MHz",
2680                                    chan, freq);
2681                 }
2682         }
2683
2684         wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
2685                     attr.oob_dev_password, attr.oob_dev_password_len);
2686         dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
2687                                  WPS_OOB_PUBKEY_HASH_LEN);
2688         if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
2689                 wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
2690                            "%u in Wi-Fi Handover Select Message", dev_pw_id);
2691                 ret = -1;
2692                 goto out;
2693         }
2694         wpa_hexdump(MSG_DEBUG, "WPS: AP Public Key hash",
2695                     attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
2696
2697         ret = wpas_wps_start_nfc(wpa_s, NULL, bssid, NULL, dev_pw_id, 0,
2698                                  attr.oob_dev_password,
2699                                  attr.ssid, attr.ssid_len, freq);
2700
2701 out:
2702         wpabuf_free(wps);
2703         return ret;
2704 }
2705
2706
2707 int wpas_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
2708                                  const struct wpabuf *req,
2709                                  const struct wpabuf *sel)
2710 {
2711         wpa_printf(MSG_DEBUG, "NFC: WPS connection handover reported");
2712         wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in request", req);
2713         wpa_hexdump_buf_key(MSG_DEBUG, "WPS: Carrier record in select", sel);
2714         return wpas_wps_nfc_rx_handover_sel(wpa_s, sel);
2715 }
2716
2717
2718 int wpas_er_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
2719                                     const struct wpabuf *req,
2720                                     const struct wpabuf *sel)
2721 {
2722         struct wpabuf *wps;
2723         int ret = -1;
2724         u16 wsc_len;
2725         const u8 *pos;
2726         struct wpabuf msg;
2727         struct wps_parse_attr attr;
2728         u16 dev_pw_id;
2729
2730         /*
2731          * Enrollee/station is always initiator of the NFC connection handover,
2732          * so use the request message here to find Enrollee public key hash.
2733          */
2734         wps = ndef_parse_wifi(req);
2735         if (wps == NULL)
2736                 return -1;
2737         wpa_printf(MSG_DEBUG, "WPS: Received application/vnd.wfa.wsc "
2738                    "payload from NFC connection handover");
2739         wpa_hexdump_buf(MSG_DEBUG, "WPS: NFC payload", wps);
2740         if (wpabuf_len(wps) < 2) {
2741                 wpa_printf(MSG_DEBUG, "WPS: Too short Wi-Fi Handover Request "
2742                            "Message");
2743                 goto out;
2744         }
2745         pos = wpabuf_head(wps);
2746         wsc_len = WPA_GET_BE16(pos);
2747         if (wsc_len > wpabuf_len(wps) - 2) {
2748                 wpa_printf(MSG_DEBUG, "WPS: Invalid WSC attribute length (%u) "
2749                            "in rt Wi-Fi Handover Request Message", wsc_len);
2750                 goto out;
2751         }
2752         pos += 2;
2753
2754         wpa_hexdump(MSG_DEBUG,
2755                     "WPS: WSC attributes in Wi-Fi Handover Request Message",
2756                     pos, wsc_len);
2757         if (wsc_len < wpabuf_len(wps) - 2) {
2758                 wpa_hexdump(MSG_DEBUG,
2759                             "WPS: Ignore extra data after WSC attributes",
2760                             pos + wsc_len, wpabuf_len(wps) - 2 - wsc_len);
2761         }
2762
2763         wpabuf_set(&msg, pos, wsc_len);
2764         ret = wps_parse_msg(&msg, &attr);
2765         if (ret < 0) {
2766                 wpa_printf(MSG_DEBUG, "WPS: Could not parse WSC attributes in "
2767                            "Wi-Fi Handover Request Message");
2768                 goto out;
2769         }
2770
2771         if (attr.oob_dev_password == NULL ||
2772             attr.oob_dev_password_len < WPS_OOB_PUBKEY_HASH_LEN + 2) {
2773                 wpa_printf(MSG_DEBUG, "WPS: No Out-of-Band Device Password "
2774                            "included in Wi-Fi Handover Request Message");
2775                 ret = -1;
2776                 goto out;
2777         }
2778
2779         if (attr.uuid_e == NULL) {
2780                 wpa_printf(MSG_DEBUG, "WPS: No UUID-E included in Wi-Fi "
2781                            "Handover Request Message");
2782                 ret = -1;
2783                 goto out;
2784         }
2785
2786         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", attr.uuid_e, WPS_UUID_LEN);
2787
2788         wpa_hexdump(MSG_DEBUG, "WPS: Out-of-Band Device Password",
2789                     attr.oob_dev_password, attr.oob_dev_password_len);
2790         dev_pw_id = WPA_GET_BE16(attr.oob_dev_password +
2791                                  WPS_OOB_PUBKEY_HASH_LEN);
2792         if (dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER) {
2793                 wpa_printf(MSG_DEBUG, "WPS: Unexpected OOB Device Password ID "
2794                            "%u in Wi-Fi Handover Request Message", dev_pw_id);
2795                 ret = -1;
2796                 goto out;
2797         }
2798         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Public Key hash",
2799                     attr.oob_dev_password, WPS_OOB_PUBKEY_HASH_LEN);
2800
2801         ret = wps_registrar_add_nfc_pw_token(wpa_s->wps->registrar,
2802                                              attr.oob_dev_password,
2803                                              DEV_PW_NFC_CONNECTION_HANDOVER,
2804                                              NULL, 0, 1);
2805
2806 out:
2807         wpabuf_free(wps);
2808         return ret;
2809 }
2810
2811 #endif /* CONFIG_WPS_NFC */
2812
2813
2814 static void wpas_wps_dump_ap_info(struct wpa_supplicant *wpa_s)
2815 {
2816         size_t i;
2817         struct os_reltime now;
2818
2819         if (wpa_debug_level > MSG_DEBUG)
2820                 return;
2821
2822         if (wpa_s->wps_ap == NULL)
2823                 return;
2824
2825         os_get_reltime(&now);
2826
2827         for (i = 0; i < wpa_s->num_wps_ap; i++) {
2828                 struct wps_ap_info *ap = &wpa_s->wps_ap[i];
2829                 struct wpa_blacklist *e = wpa_blacklist_get(wpa_s, ap->bssid);
2830
2831                 wpa_printf(MSG_DEBUG, "WPS: AP[%d] " MACSTR " type=%d "
2832                            "tries=%d last_attempt=%d sec ago blacklist=%d",
2833                            (int) i, MAC2STR(ap->bssid), ap->type, ap->tries,
2834                            ap->last_attempt.sec > 0 ?
2835                            (int) now.sec - (int) ap->last_attempt.sec : -1,
2836                            e ? e->count : 0);
2837         }
2838 }
2839
2840
2841 static struct wps_ap_info * wpas_wps_get_ap_info(struct wpa_supplicant *wpa_s,
2842                                                  const u8 *bssid)
2843 {
2844         size_t i;
2845
2846         if (wpa_s->wps_ap == NULL)
2847                 return NULL;
2848
2849         for (i = 0; i < wpa_s->num_wps_ap; i++) {
2850                 struct wps_ap_info *ap = &wpa_s->wps_ap[i];
2851                 if (os_memcmp(ap->bssid, bssid, ETH_ALEN) == 0)
2852                         return ap;
2853         }
2854
2855         return NULL;
2856 }
2857
2858
2859 static void wpas_wps_update_ap_info_bss(struct wpa_supplicant *wpa_s,
2860                                         struct wpa_scan_res *res)
2861 {
2862         struct wpabuf *wps;
2863         enum wps_ap_info_type type;
2864         struct wps_ap_info *ap;
2865         int r, pbc_active;
2866         const u8 *uuid;
2867
2868         if (wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE) == NULL)
2869                 return;
2870
2871         wps = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
2872         if (wps == NULL)
2873                 return;
2874
2875         r = wps_is_addr_authorized(wps, wpa_s->own_addr, 1);
2876         if (r == 2)
2877                 type = WPS_AP_SEL_REG_OUR;
2878         else if (r == 1)
2879                 type = WPS_AP_SEL_REG;
2880         else
2881                 type = WPS_AP_NOT_SEL_REG;
2882
2883         uuid = wps_get_uuid_e(wps);
2884         pbc_active = wps_is_selected_pbc_registrar(wps);
2885
2886         ap = wpas_wps_get_ap_info(wpa_s, res->bssid);
2887         if (ap) {
2888                 if (ap->type != type) {
2889                         wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR
2890                                    " changed type %d -> %d",
2891                                    MAC2STR(res->bssid), ap->type, type);
2892                         ap->type = type;
2893                         if (type != WPS_AP_NOT_SEL_REG)
2894                                 wpa_blacklist_del(wpa_s, ap->bssid);
2895                 }
2896                 ap->pbc_active = pbc_active;
2897                 if (uuid)
2898                         os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
2899                 goto out;
2900         }
2901
2902         ap = os_realloc_array(wpa_s->wps_ap, wpa_s->num_wps_ap + 1,
2903                               sizeof(struct wps_ap_info));
2904         if (ap == NULL)
2905                 goto out;
2906
2907         wpa_s->wps_ap = ap;
2908         ap = &wpa_s->wps_ap[wpa_s->num_wps_ap];
2909         wpa_s->num_wps_ap++;
2910
2911         os_memset(ap, 0, sizeof(*ap));
2912         os_memcpy(ap->bssid, res->bssid, ETH_ALEN);
2913         ap->type = type;
2914         ap->pbc_active = pbc_active;
2915         if (uuid)
2916                 os_memcpy(ap->uuid, uuid, WPS_UUID_LEN);
2917         wpa_printf(MSG_DEBUG, "WPS: AP " MACSTR " type %d added",
2918                    MAC2STR(ap->bssid), ap->type);
2919
2920 out:
2921         wpabuf_free(wps);
2922 }
2923
2924
2925 void wpas_wps_update_ap_info(struct wpa_supplicant *wpa_s,
2926                              struct wpa_scan_results *scan_res)
2927 {
2928         size_t i;
2929
2930         for (i = 0; i < scan_res->num; i++)
2931                 wpas_wps_update_ap_info_bss(wpa_s, scan_res->res[i]);
2932
2933         wpas_wps_dump_ap_info(wpa_s);
2934 }
2935
2936
2937 void wpas_wps_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *bssid)
2938 {
2939         struct wps_ap_info *ap;
2940
2941         wpa_s->after_wps = 0;
2942
2943         if (!wpa_s->wps_ap_iter)
2944                 return;
2945         ap = wpas_wps_get_ap_info(wpa_s, bssid);
2946         if (ap == NULL)
2947                 return;
2948         ap->tries++;
2949         os_get_reltime(&ap->last_attempt);
2950 }