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