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