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