LCOV - code coverage report
Current view: top level - wpa_supplicant - wpa_supplicant.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1422976643 Lines: 2136 2602 82.1 %
Date: 2015-02-03 Functions: 107 111 96.4 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant
       3             :  * Copyright (c) 2003-2015, 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             :  * This file implements functions for registering and unregistering
       9             :  * %wpa_supplicant interfaces. In addition, this file contains number of
      10             :  * functions for managing network connections.
      11             :  */
      12             : 
      13             : #include "includes.h"
      14             : 
      15             : #include "common.h"
      16             : #include "crypto/random.h"
      17             : #include "crypto/sha1.h"
      18             : #include "eapol_supp/eapol_supp_sm.h"
      19             : #include "eap_peer/eap.h"
      20             : #include "eap_peer/eap_proxy.h"
      21             : #include "eap_server/eap_methods.h"
      22             : #include "rsn_supp/wpa.h"
      23             : #include "eloop.h"
      24             : #include "config.h"
      25             : #include "utils/ext_password.h"
      26             : #include "l2_packet/l2_packet.h"
      27             : #include "wpa_supplicant_i.h"
      28             : #include "driver_i.h"
      29             : #include "ctrl_iface.h"
      30             : #include "pcsc_funcs.h"
      31             : #include "common/version.h"
      32             : #include "rsn_supp/preauth.h"
      33             : #include "rsn_supp/pmksa_cache.h"
      34             : #include "common/wpa_ctrl.h"
      35             : #include "common/ieee802_11_defs.h"
      36             : #include "common/hw_features_common.h"
      37             : #include "p2p/p2p.h"
      38             : #include "blacklist.h"
      39             : #include "wpas_glue.h"
      40             : #include "wps_supplicant.h"
      41             : #include "ibss_rsn.h"
      42             : #include "sme.h"
      43             : #include "gas_query.h"
      44             : #include "ap.h"
      45             : #include "p2p_supplicant.h"
      46             : #include "wifi_display.h"
      47             : #include "notify.h"
      48             : #include "bgscan.h"
      49             : #include "autoscan.h"
      50             : #include "bss.h"
      51             : #include "scan.h"
      52             : #include "offchannel.h"
      53             : #include "hs20_supplicant.h"
      54             : #include "wnm_sta.h"
      55             : #include "wpas_kay.h"
      56             : #include "mesh.h"
      57             : 
      58             : const char *wpa_supplicant_version =
      59             : "wpa_supplicant v" VERSION_STR "\n"
      60             : "Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> and contributors";
      61             : 
      62             : const char *wpa_supplicant_license =
      63             : "This software may be distributed under the terms of the BSD license.\n"
      64             : "See README for more details.\n"
      65             : #ifdef EAP_TLS_OPENSSL
      66             : "\nThis product includes software developed by the OpenSSL Project\n"
      67             : "for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
      68             : #endif /* EAP_TLS_OPENSSL */
      69             : ;
      70             : 
      71             : #ifndef CONFIG_NO_STDOUT_DEBUG
      72             : /* Long text divided into parts in order to fit in C89 strings size limits. */
      73             : const char *wpa_supplicant_full_license1 =
      74             : "";
      75             : const char *wpa_supplicant_full_license2 =
      76             : "This software may be distributed under the terms of the BSD license.\n"
      77             : "\n"
      78             : "Redistribution and use in source and binary forms, with or without\n"
      79             : "modification, are permitted provided that the following conditions are\n"
      80             : "met:\n"
      81             : "\n";
      82             : const char *wpa_supplicant_full_license3 =
      83             : "1. Redistributions of source code must retain the above copyright\n"
      84             : "   notice, this list of conditions and the following disclaimer.\n"
      85             : "\n"
      86             : "2. Redistributions in binary form must reproduce the above copyright\n"
      87             : "   notice, this list of conditions and the following disclaimer in the\n"
      88             : "   documentation and/or other materials provided with the distribution.\n"
      89             : "\n";
      90             : const char *wpa_supplicant_full_license4 =
      91             : "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
      92             : "   names of its contributors may be used to endorse or promote products\n"
      93             : "   derived from this software without specific prior written permission.\n"
      94             : "\n"
      95             : "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
      96             : "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
      97             : "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
      98             : "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
      99             : const char *wpa_supplicant_full_license5 =
     100             : "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
     101             : "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
     102             : "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
     103             : "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
     104             : "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
     105             : "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
     106             : "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
     107             : "\n";
     108             : #endif /* CONFIG_NO_STDOUT_DEBUG */
     109             : 
     110             : /* Configure default/group WEP keys for static WEP */
     111         353 : int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
     112             : {
     113         353 :         int i, set = 0;
     114             : 
     115        1765 :         for (i = 0; i < NUM_WEP_KEYS; i++) {
     116        1412 :                 if (ssid->wep_key_len[i] == 0)
     117        1381 :                         continue;
     118             : 
     119          31 :                 set = 1;
     120          62 :                 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
     121          31 :                                 i, i == ssid->wep_tx_keyidx, NULL, 0,
     122          31 :                                 ssid->wep_key[i], ssid->wep_key_len[i]);
     123             :         }
     124             : 
     125         353 :         return set;
     126             : }
     127             : 
     128             : 
     129          15 : int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
     130             :                                     struct wpa_ssid *ssid)
     131             : {
     132             :         u8 key[32];
     133             :         size_t keylen;
     134             :         enum wpa_alg alg;
     135          15 :         u8 seq[6] = { 0 };
     136             :         int ret;
     137             : 
     138             :         /* IBSS/WPA-None uses only one key (Group) for both receiving and
     139             :          * sending unicast and multicast packets. */
     140             : 
     141          15 :         if (ssid->mode != WPAS_MODE_IBSS) {
     142           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
     143           0 :                         "IBSS/ad-hoc) for WPA-None", ssid->mode);
     144           0 :                 return -1;
     145             :         }
     146             : 
     147          15 :         if (!ssid->psk_set) {
     148           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
     149             :                         "WPA-None");
     150           0 :                 return -1;
     151             :         }
     152             : 
     153          15 :         switch (wpa_s->group_cipher) {
     154             :         case WPA_CIPHER_CCMP:
     155           0 :                 os_memcpy(key, ssid->psk, 16);
     156           0 :                 keylen = 16;
     157           0 :                 alg = WPA_ALG_CCMP;
     158           0 :                 break;
     159             :         case WPA_CIPHER_GCMP:
     160           0 :                 os_memcpy(key, ssid->psk, 16);
     161           0 :                 keylen = 16;
     162           0 :                 alg = WPA_ALG_GCMP;
     163           0 :                 break;
     164             :         case WPA_CIPHER_TKIP:
     165             :                 /* WPA-None uses the same Michael MIC key for both TX and RX */
     166          15 :                 os_memcpy(key, ssid->psk, 16 + 8);
     167          15 :                 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
     168          15 :                 keylen = 32;
     169          15 :                 alg = WPA_ALG_TKIP;
     170          15 :                 break;
     171             :         default:
     172           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
     173             :                         "WPA-None", wpa_s->group_cipher);
     174           0 :                 return -1;
     175             :         }
     176             : 
     177             :         /* TODO: should actually remember the previously used seq#, both for TX
     178             :          * and RX from each STA.. */
     179             : 
     180          15 :         ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
     181          15 :         os_memset(key, 0, sizeof(key));
     182          15 :         return ret;
     183             : }
     184             : 
     185             : 
     186           2 : static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
     187             : {
     188           2 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     189           2 :         const u8 *bssid = wpa_s->bssid;
     190           2 :         if (is_zero_ether_addr(bssid))
     191           0 :                 bssid = wpa_s->pending_bssid;
     192          12 :         wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
     193          12 :                 MAC2STR(bssid));
     194           2 :         wpa_blacklist_add(wpa_s, bssid);
     195           2 :         wpa_sm_notify_disassoc(wpa_s->wpa);
     196           2 :         wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
     197           2 :         wpa_s->reassociate = 1;
     198             : 
     199             :         /*
     200             :          * If we timed out, the AP or the local radio may be busy.
     201             :          * So, wait a second until scanning again.
     202             :          */
     203           2 :         wpa_supplicant_req_scan(wpa_s, 1, 0);
     204           2 : }
     205             : 
     206             : 
     207             : /**
     208             :  * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
     209             :  * @wpa_s: Pointer to wpa_supplicant data
     210             :  * @sec: Number of seconds after which to time out authentication
     211             :  * @usec: Number of microseconds after which to time out authentication
     212             :  *
     213             :  * This function is used to schedule a timeout for the current authentication
     214             :  * attempt.
     215             :  */
     216        4105 : void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
     217             :                                      int sec, int usec)
     218             : {
     219        4105 :         if (wpa_s->conf->ap_scan == 0 &&
     220           0 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
     221        4105 :                 return;
     222             : 
     223        4105 :         wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
     224             :                 "%d usec", sec, usec);
     225        4105 :         eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
     226        4105 :         eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
     227             : }
     228             : 
     229             : 
     230             : /**
     231             :  * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
     232             :  * @wpa_s: Pointer to wpa_supplicant data
     233             :  *
     234             :  * This function is used to cancel authentication timeout scheduled with
     235             :  * wpa_supplicant_req_auth_timeout() and it is called when authentication has
     236             :  * been completed.
     237             :  */
     238        2291 : void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
     239             : {
     240        2291 :         wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
     241        2291 :         eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
     242        2291 :         wpa_blacklist_del(wpa_s, wpa_s->bssid);
     243        2291 : }
     244             : 
     245             : 
     246             : /**
     247             :  * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
     248             :  * @wpa_s: Pointer to wpa_supplicant data
     249             :  *
     250             :  * This function is used to configure EAPOL state machine based on the selected
     251             :  * authentication mode.
     252             :  */
     253        2472 : void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
     254             : {
     255             : #ifdef IEEE8021X_EAPOL
     256             :         struct eapol_config eapol_conf;
     257        2472 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
     258             : 
     259             : #ifdef CONFIG_IBSS_RSN
     260        2489 :         if (ssid->mode == WPAS_MODE_IBSS &&
     261          26 :             wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
     262           9 :             wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
     263             :                 /*
     264             :                  * RSN IBSS authentication is per-STA and we can disable the
     265             :                  * per-BSSID EAPOL authentication.
     266             :                  */
     267           4 :                 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
     268           4 :                 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
     269           4 :                 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
     270        2476 :                 return;
     271             :         }
     272             : #endif /* CONFIG_IBSS_RSN */
     273             : 
     274        2468 :         eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
     275        2468 :         eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
     276             : 
     277        4574 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
     278        2106 :             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
     279         367 :                 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
     280             :         else
     281        2101 :                 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
     282             : 
     283        2468 :         os_memset(&eapol_conf, 0, sizeof(eapol_conf));
     284        2468 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
     285          10 :                 eapol_conf.accept_802_1x_keys = 1;
     286          10 :                 eapol_conf.required_keys = 0;
     287          10 :                 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
     288           2 :                         eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
     289             :                 }
     290          10 :                 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
     291           2 :                         eapol_conf.required_keys |=
     292             :                                 EAPOL_REQUIRE_KEY_BROADCAST;
     293             :                 }
     294             : 
     295          10 :                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
     296           0 :                         eapol_conf.required_keys = 0;
     297             :         }
     298        2468 :         eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
     299        2468 :         eapol_conf.workaround = ssid->eap_workaround;
     300        2468 :         eapol_conf.eap_disabled =
     301        3953 :                 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
     302        3943 :                 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
     303        1475 :                 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
     304        2468 :         eapol_conf.external_sim = wpa_s->conf->external_sim;
     305             : 
     306             : #ifdef CONFIG_WPS
     307        2468 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
     308         281 :                 eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
     309         281 :                 if (wpa_s->current_bss) {
     310             :                         struct wpabuf *ie;
     311         281 :                         ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
     312             :                                                          WPS_IE_VENDOR_TYPE);
     313         281 :                         if (ie) {
     314         281 :                                 if (wps_is_20(ie))
     315         280 :                                         eapol_conf.wps |=
     316             :                                                 EAPOL_PEER_IS_WPS20_AP;
     317         281 :                                 wpabuf_free(ie);
     318             :                         }
     319             :                 }
     320             :         }
     321             : #endif /* CONFIG_WPS */
     322             : 
     323        2468 :         eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
     324             : 
     325        2468 :         ieee802_1x_alloc_kay_sm(wpa_s, ssid);
     326             : #endif /* IEEE8021X_EAPOL */
     327             : }
     328             : 
     329             : 
     330             : /**
     331             :  * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
     332             :  * @wpa_s: Pointer to wpa_supplicant data
     333             :  * @ssid: Configuration data for the network
     334             :  *
     335             :  * This function is used to configure WPA state machine and related parameters
     336             :  * to a mode where WPA is not enabled. This is called as part of the
     337             :  * authentication configuration when the selected network does not use WPA.
     338             :  */
     339         652 : void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
     340             :                                        struct wpa_ssid *ssid)
     341             : {
     342             :         int i;
     343             : 
     344         652 :         if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
     345         281 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
     346         371 :         else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
     347          10 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
     348             :         else
     349         361 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
     350         652 :         wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
     351         652 :         wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
     352         652 :         wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
     353         652 :         wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
     354         652 :         wpa_s->group_cipher = WPA_CIPHER_NONE;
     355         652 :         wpa_s->mgmt_group_cipher = 0;
     356             : 
     357        3144 :         for (i = 0; i < NUM_WEP_KEYS; i++) {
     358        2521 :                 if (ssid->wep_key_len[i] > 5) {
     359          15 :                         wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
     360          15 :                         wpa_s->group_cipher = WPA_CIPHER_WEP104;
     361          15 :                         break;
     362        2506 :                 } else if (ssid->wep_key_len[i] > 0) {
     363          14 :                         wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
     364          14 :                         wpa_s->group_cipher = WPA_CIPHER_WEP40;
     365          14 :                         break;
     366             :                 }
     367             :         }
     368             : 
     369         652 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
     370         652 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
     371         652 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
     372         652 :                          wpa_s->pairwise_cipher);
     373         652 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
     374             : #ifdef CONFIG_IEEE80211W
     375         652 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
     376         652 :                          wpa_s->mgmt_group_cipher);
     377             : #endif /* CONFIG_IEEE80211W */
     378             : 
     379         652 :         pmksa_cache_clear_current(wpa_s->wpa);
     380         652 : }
     381             : 
     382             : 
     383        7202 : void free_hw_features(struct wpa_supplicant *wpa_s)
     384             : {
     385             :         int i;
     386        7202 :         if (wpa_s->hw.modes == NULL)
     387        7266 :                 return;
     388             : 
     389       28552 :         for (i = 0; i < wpa_s->hw.num_modes; i++) {
     390       21414 :                 os_free(wpa_s->hw.modes[i].channels);
     391       21414 :                 os_free(wpa_s->hw.modes[i].rates);
     392             :         }
     393             : 
     394        7138 :         os_free(wpa_s->hw.modes);
     395        7138 :         wpa_s->hw.modes = NULL;
     396             : }
     397             : 
     398             : 
     399         212 : static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
     400             : {
     401             :         int i;
     402             : 
     403         212 :         bgscan_deinit(wpa_s);
     404         212 :         autoscan_deinit(wpa_s);
     405             :         scard_deinit(wpa_s->scard);
     406         212 :         wpa_s->scard = NULL;
     407         212 :         wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
     408         212 :         eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
     409         212 :         l2_packet_deinit(wpa_s->l2);
     410         212 :         wpa_s->l2 = NULL;
     411         212 :         if (wpa_s->l2_br) {
     412           2 :                 l2_packet_deinit(wpa_s->l2_br);
     413           2 :                 wpa_s->l2_br = NULL;
     414             :         }
     415             : #ifdef CONFIG_TESTING_OPTIONS
     416         212 :         l2_packet_deinit(wpa_s->l2_test);
     417         212 :         wpa_s->l2_test = NULL;
     418             : #endif /* CONFIG_TESTING_OPTIONS */
     419             : 
     420         212 :         if (wpa_s->conf != NULL) {
     421             :                 struct wpa_ssid *ssid;
     422         325 :                 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
     423         122 :                         wpas_notify_network_removed(wpa_s, ssid);
     424             :         }
     425             : 
     426         212 :         os_free(wpa_s->confname);
     427         212 :         wpa_s->confname = NULL;
     428             : 
     429         212 :         os_free(wpa_s->confanother);
     430         212 :         wpa_s->confanother = NULL;
     431             : 
     432         212 :         wpa_sm_set_eapol(wpa_s->wpa, NULL);
     433         212 :         eapol_sm_deinit(wpa_s->eapol);
     434         212 :         wpa_s->eapol = NULL;
     435             : 
     436         212 :         rsn_preauth_deinit(wpa_s->wpa);
     437             : 
     438             : #ifdef CONFIG_TDLS
     439         212 :         wpa_tdls_deinit(wpa_s->wpa);
     440             : #endif /* CONFIG_TDLS */
     441             : 
     442         212 :         wmm_ac_clear_saved_tspecs(wpa_s);
     443         212 :         pmksa_candidate_free(wpa_s->wpa);
     444         212 :         wpa_sm_deinit(wpa_s->wpa);
     445         212 :         wpa_s->wpa = NULL;
     446         212 :         wpa_blacklist_clear(wpa_s);
     447             : 
     448         212 :         wpa_bss_deinit(wpa_s);
     449             : 
     450         212 :         wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
     451         212 :         wpa_supplicant_cancel_scan(wpa_s);
     452         212 :         wpa_supplicant_cancel_auth_timeout(wpa_s);
     453         212 :         eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
     454             : #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
     455             :         eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
     456             :                              wpa_s, NULL);
     457             : #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
     458             : 
     459         212 :         wpas_wps_deinit(wpa_s);
     460             : 
     461         212 :         wpabuf_free(wpa_s->pending_eapol_rx);
     462         212 :         wpa_s->pending_eapol_rx = NULL;
     463             : 
     464             : #ifdef CONFIG_IBSS_RSN
     465         212 :         ibss_rsn_deinit(wpa_s->ibss_rsn);
     466         212 :         wpa_s->ibss_rsn = NULL;
     467             : #endif /* CONFIG_IBSS_RSN */
     468             : 
     469         212 :         sme_deinit(wpa_s);
     470             : 
     471             : #ifdef CONFIG_AP
     472         212 :         wpa_supplicant_ap_deinit(wpa_s);
     473             : #endif /* CONFIG_AP */
     474             : 
     475         212 :         wpas_p2p_deinit(wpa_s);
     476             : 
     477             : #ifdef CONFIG_OFFCHANNEL
     478         212 :         offchannel_deinit(wpa_s);
     479             : #endif /* CONFIG_OFFCHANNEL */
     480             : 
     481         212 :         wpa_supplicant_cancel_sched_scan(wpa_s);
     482             : 
     483         212 :         os_free(wpa_s->next_scan_freqs);
     484         212 :         wpa_s->next_scan_freqs = NULL;
     485             : 
     486         212 :         os_free(wpa_s->manual_scan_freqs);
     487         212 :         wpa_s->manual_scan_freqs = NULL;
     488             : 
     489         212 :         os_free(wpa_s->manual_sched_scan_freqs);
     490         212 :         wpa_s->manual_sched_scan_freqs = NULL;
     491             : 
     492         212 :         wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
     493             : 
     494         212 :         gas_query_deinit(wpa_s->gas);
     495         212 :         wpa_s->gas = NULL;
     496             : 
     497         212 :         free_hw_features(wpa_s);
     498             : 
     499         212 :         ieee802_1x_dealloc_kay_sm(wpa_s);
     500             : 
     501         212 :         os_free(wpa_s->bssid_filter);
     502         212 :         wpa_s->bssid_filter = NULL;
     503             : 
     504         212 :         os_free(wpa_s->disallow_aps_bssid);
     505         212 :         wpa_s->disallow_aps_bssid = NULL;
     506         212 :         os_free(wpa_s->disallow_aps_ssid);
     507         212 :         wpa_s->disallow_aps_ssid = NULL;
     508             : 
     509         212 :         wnm_bss_keep_alive_deinit(wpa_s);
     510             : #ifdef CONFIG_WNM
     511         212 :         wnm_deallocate_memory(wpa_s);
     512             : #endif /* CONFIG_WNM */
     513             : 
     514         212 :         ext_password_deinit(wpa_s->ext_pw);
     515         212 :         wpa_s->ext_pw = NULL;
     516             : 
     517         212 :         wpabuf_free(wpa_s->last_gas_resp);
     518         212 :         wpa_s->last_gas_resp = NULL;
     519         212 :         wpabuf_free(wpa_s->prev_gas_resp);
     520         212 :         wpa_s->prev_gas_resp = NULL;
     521             : 
     522         212 :         os_free(wpa_s->last_scan_res);
     523         212 :         wpa_s->last_scan_res = NULL;
     524             : 
     525             : #ifdef CONFIG_HS20
     526         212 :         hs20_deinit(wpa_s);
     527             : #endif /* CONFIG_HS20 */
     528             : 
     529        3180 :         for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
     530        2968 :                 wpabuf_free(wpa_s->vendor_elem[i]);
     531        2968 :                 wpa_s->vendor_elem[i] = NULL;
     532             :         }
     533             : 
     534         212 :         wmm_ac_notify_disassoc(wpa_s);
     535         212 : }
     536             : 
     537             : 
     538             : /**
     539             :  * wpa_clear_keys - Clear keys configured for the driver
     540             :  * @wpa_s: Pointer to wpa_supplicant data
     541             :  * @addr: Previously used BSSID or %NULL if not available
     542             :  *
     543             :  * This function clears the encryption keys that has been previously configured
     544             :  * for the driver.
     545             :  */
     546        9126 : void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
     547             : {
     548             :         int i, max;
     549             : 
     550             : #ifdef CONFIG_IEEE80211W
     551        9126 :         max = 6;
     552             : #else /* CONFIG_IEEE80211W */
     553             :         max = 4;
     554             : #endif /* CONFIG_IEEE80211W */
     555             : 
     556             :         /* MLME-DELETEKEYS.request */
     557       63882 :         for (i = 0; i < max; i++) {
     558       54756 :                 if (wpa_s->keys_cleared & BIT(i))
     559       50691 :                         continue;
     560        4065 :                 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
     561             :                                 NULL, 0);
     562             :         }
     563       10488 :         if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
     564        1362 :             !is_zero_ether_addr(addr)) {
     565        1342 :                 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
     566             :                                 0);
     567             :                 /* MLME-SETPROTECTION.request(None) */
     568        1342 :                 wpa_drv_mlme_setprotection(
     569             :                         wpa_s, addr,
     570             :                         MLME_SETPROTECTION_PROTECT_TYPE_NONE,
     571             :                         MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
     572             :         }
     573        9126 :         wpa_s->keys_cleared = (u32) -1;
     574        9126 : }
     575             : 
     576             : 
     577             : /**
     578             :  * wpa_supplicant_state_txt - Get the connection state name as a text string
     579             :  * @state: State (wpa_state; WPA_*)
     580             :  * Returns: The state name as a printable text string
     581             :  */
     582       98128 : const char * wpa_supplicant_state_txt(enum wpa_states state)
     583             : {
     584       98128 :         switch (state) {
     585             :         case WPA_DISCONNECTED:
     586       19816 :                 return "DISCONNECTED";
     587             :         case WPA_INACTIVE:
     588        4638 :                 return "INACTIVE";
     589             :         case WPA_INTERFACE_DISABLED:
     590         100 :                 return "INTERFACE_DISABLED";
     591             :         case WPA_SCANNING:
     592        9160 :                 return "SCANNING";
     593             :         case WPA_AUTHENTICATING:
     594       11897 :                 return "AUTHENTICATING";
     595             :         case WPA_ASSOCIATING:
     596       12416 :                 return "ASSOCIATING";
     597             :         case WPA_ASSOCIATED:
     598       11811 :                 return "ASSOCIATED";
     599             :         case WPA_4WAY_HANDSHAKE:
     600        8910 :                 return "4WAY_HANDSHAKE";
     601             :         case WPA_GROUP_HANDSHAKE:
     602        4600 :                 return "GROUP_HANDSHAKE";
     603             :         case WPA_COMPLETED:
     604       14780 :                 return "COMPLETED";
     605             :         default:
     606           0 :                 return "UNKNOWN";
     607             :         }
     608             : }
     609             : 
     610             : 
     611             : #ifdef CONFIG_BGSCAN
     612             : 
     613        2311 : static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
     614             : {
     615             :         const char *name;
     616             : 
     617        2311 :         if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
     618          13 :                 name = wpa_s->current_ssid->bgscan;
     619             :         else
     620        2298 :                 name = wpa_s->conf->bgscan;
     621        2311 :         if (name == NULL || name[0] == '\0')
     622        2298 :                 return;
     623          13 :         if (wpas_driver_bss_selection(wpa_s))
     624           0 :                 return;
     625          13 :         if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
     626           0 :                 return;
     627             : #ifdef CONFIG_P2P
     628          13 :         if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
     629           0 :                 return;
     630             : #endif /* CONFIG_P2P */
     631             : 
     632          13 :         bgscan_deinit(wpa_s);
     633          13 :         if (wpa_s->current_ssid) {
     634          13 :                 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
     635           4 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
     636             :                                 "bgscan");
     637             :                         /*
     638             :                          * Live without bgscan; it is only used as a roaming
     639             :                          * optimization, so the initial connection is not
     640             :                          * affected.
     641             :                          */
     642             :                 } else {
     643             :                         struct wpa_scan_results *scan_res;
     644           9 :                         wpa_s->bgscan_ssid = wpa_s->current_ssid;
     645           9 :                         scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
     646             :                                                                    0);
     647           9 :                         if (scan_res) {
     648           9 :                                 bgscan_notify_scan(wpa_s, scan_res);
     649           9 :                                 wpa_scan_results_free(scan_res);
     650             :                         }
     651             :                 }
     652             :         } else
     653           0 :                 wpa_s->bgscan_ssid = NULL;
     654             : }
     655             : 
     656             : 
     657       13022 : static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
     658             : {
     659       13022 :         if (wpa_s->bgscan_ssid != NULL) {
     660           9 :                 bgscan_deinit(wpa_s);
     661           9 :                 wpa_s->bgscan_ssid = NULL;
     662             :         }
     663       13022 : }
     664             : 
     665             : #endif /* CONFIG_BGSCAN */
     666             : 
     667             : 
     668        6402 : static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
     669             : {
     670        6402 :         if (autoscan_init(wpa_s, 0))
     671           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
     672        6402 : }
     673             : 
     674             : 
     675        2417 : static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
     676             : {
     677        2417 :         autoscan_deinit(wpa_s);
     678        2417 : }
     679             : 
     680             : 
     681         126 : void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
     682             : {
     683         179 :         if (wpa_s->wpa_state == WPA_DISCONNECTED ||
     684          53 :             wpa_s->wpa_state == WPA_SCANNING) {
     685          77 :                 autoscan_deinit(wpa_s);
     686          77 :                 wpa_supplicant_start_autoscan(wpa_s);
     687             :         }
     688         126 : }
     689             : 
     690             : 
     691             : /**
     692             :  * wpa_supplicant_set_state - Set current connection state
     693             :  * @wpa_s: Pointer to wpa_supplicant data
     694             :  * @state: The new connection state
     695             :  *
     696             :  * This function is called whenever the connection state changes, e.g.,
     697             :  * association is completed for WPA/WPA2 4-Way Handshake is started.
     698             :  */
     699       21706 : void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
     700             :                               enum wpa_states state)
     701             : {
     702       21706 :         enum wpa_states old_state = wpa_s->wpa_state;
     703             : 
     704       21706 :         wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
     705             :                 wpa_supplicant_state_txt(wpa_s->wpa_state),
     706             :                 wpa_supplicant_state_txt(state));
     707             : 
     708       21706 :         if (state == WPA_INTERFACE_DISABLED) {
     709             :                 /* Assure normal scan when interface is restored */
     710          37 :                 wpa_s->normal_scans = 0;
     711             :         }
     712             : 
     713       21706 :         if (state == WPA_COMPLETED) {
     714        2311 :                 wpas_connect_work_done(wpa_s);
     715             :                 /* Reinitialize normal_scan counter */
     716        2311 :                 wpa_s->normal_scans = 0;
     717             :         }
     718             : 
     719       21706 :         if (state != WPA_SCANNING)
     720       19949 :                 wpa_supplicant_notify_scanning(wpa_s, 0);
     721             : 
     722       23722 :         if (state == WPA_COMPLETED && wpa_s->new_connection) {
     723        2016 :                 struct wpa_ssid *ssid = wpa_s->current_ssid;
     724             : #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
     725       14113 :                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
     726             :                         MACSTR " completed [id=%d id_str=%s]",
     727       12096 :                         MAC2STR(wpa_s->bssid),
     728             :                         ssid ? ssid->id : -1,
     729        2016 :                         ssid && ssid->id_str ? ssid->id_str : "");
     730             : #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
     731        2016 :                 wpas_clear_temp_disabled(wpa_s, ssid, 1);
     732        2016 :                 wpa_s->extra_blacklist_count = 0;
     733        2016 :                 wpa_s->new_connection = 0;
     734        2016 :                 wpa_drv_set_operstate(wpa_s, 1);
     735             : #ifndef IEEE8021X_EAPOL
     736             :                 wpa_drv_set_supp_port(wpa_s, 1);
     737             : #endif /* IEEE8021X_EAPOL */
     738        2016 :                 wpa_s->after_wps = 0;
     739        2016 :                 wpa_s->known_wps_freq = 0;
     740        2016 :                 wpas_p2p_completed(wpa_s);
     741             : 
     742        2016 :                 sme_sched_obss_scan(wpa_s, 1);
     743       19690 :         } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
     744             :                    state == WPA_ASSOCIATED) {
     745       10309 :                 wpa_s->new_connection = 1;
     746       10309 :                 wpa_drv_set_operstate(wpa_s, 0);
     747             : #ifndef IEEE8021X_EAPOL
     748             :                 wpa_drv_set_supp_port(wpa_s, 0);
     749             : #endif /* IEEE8021X_EAPOL */
     750       10309 :                 sme_sched_obss_scan(wpa_s, 0);
     751             :         }
     752       21706 :         wpa_s->wpa_state = state;
     753             : 
     754             : #ifdef CONFIG_BGSCAN
     755       21706 :         if (state == WPA_COMPLETED)
     756        2311 :                 wpa_supplicant_start_bgscan(wpa_s);
     757       19395 :         else if (state < WPA_ASSOCIATED)
     758       13022 :                 wpa_supplicant_stop_bgscan(wpa_s);
     759             : #endif /* CONFIG_BGSCAN */
     760             : 
     761       21706 :         if (state == WPA_AUTHENTICATING)
     762        2417 :                 wpa_supplicant_stop_autoscan(wpa_s);
     763             : 
     764       21706 :         if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
     765        6325 :                 wpa_supplicant_start_autoscan(wpa_s);
     766             : 
     767       21706 :         if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
     768        2712 :                 wmm_ac_notify_disassoc(wpa_s);
     769             : 
     770       21706 :         if (wpa_s->wpa_state != old_state) {
     771       17630 :                 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
     772             : 
     773             :                 /*
     774             :                  * Notify the P2P Device interface about a state change in one
     775             :                  * of the interfaces.
     776             :                  */
     777       17630 :                 wpas_p2p_indicate_state_change(wpa_s);
     778             : 
     779       17630 :                 if (wpa_s->wpa_state == WPA_COMPLETED ||
     780             :                     old_state == WPA_COMPLETED)
     781        4180 :                         wpas_notify_auth_changed(wpa_s);
     782             :         }
     783       21706 : }
     784             : 
     785             : 
     786          20 : void wpa_supplicant_terminate_proc(struct wpa_global *global)
     787             : {
     788          20 :         int pending = 0;
     789             : #ifdef CONFIG_WPS
     790          20 :         struct wpa_supplicant *wpa_s = global->ifaces;
     791          55 :         while (wpa_s) {
     792          15 :                 struct wpa_supplicant *next = wpa_s->next;
     793          15 :                 if (wpas_wps_terminate_pending(wpa_s) == 1)
     794           0 :                         pending = 1;
     795             : #ifdef CONFIG_P2P
     796          30 :                 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
     797          15 :                     (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
     798           0 :                         wpas_p2p_disconnect(wpa_s);
     799             : #endif /* CONFIG_P2P */
     800          15 :                 wpa_s = next;
     801             :         }
     802             : #endif /* CONFIG_WPS */
     803          20 :         if (pending)
     804          20 :                 return;
     805          20 :         eloop_terminate();
     806             : }
     807             : 
     808             : 
     809          20 : static void wpa_supplicant_terminate(int sig, void *signal_ctx)
     810             : {
     811          20 :         struct wpa_global *global = signal_ctx;
     812          20 :         wpa_supplicant_terminate_proc(global);
     813          20 : }
     814             : 
     815             : 
     816         357 : void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
     817             : {
     818         357 :         enum wpa_states old_state = wpa_s->wpa_state;
     819             : 
     820         357 :         wpa_s->pairwise_cipher = 0;
     821         357 :         wpa_s->group_cipher = 0;
     822         357 :         wpa_s->mgmt_group_cipher = 0;
     823         357 :         wpa_s->key_mgmt = 0;
     824         357 :         if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
     825         356 :                 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
     826             : 
     827         357 :         if (wpa_s->wpa_state != old_state)
     828         189 :                 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
     829         357 : }
     830             : 
     831             : 
     832             : /**
     833             :  * wpa_supplicant_reload_configuration - Reload configuration data
     834             :  * @wpa_s: Pointer to wpa_supplicant data
     835             :  * Returns: 0 on success or -1 if configuration parsing failed
     836             :  *
     837             :  * This function can be used to request that the configuration data is reloaded
     838             :  * (e.g., after configuration file change). This function is reloading
     839             :  * configuration only for one interface, so this may need to be called multiple
     840             :  * times if %wpa_supplicant is controlling multiple interfaces and all
     841             :  * interfaces need reconfiguration.
     842             :  */
     843           1 : int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
     844             : {
     845             :         struct wpa_config *conf;
     846             :         int reconf_ctrl;
     847             :         int old_ap_scan;
     848             : 
     849           1 :         if (wpa_s->confname == NULL)
     850           0 :                 return -1;
     851           1 :         conf = wpa_config_read(wpa_s->confname, NULL);
     852           1 :         if (conf == NULL) {
     853           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
     854             :                         "file '%s' - exiting", wpa_s->confname);
     855           0 :                 return -1;
     856             :         }
     857           1 :         wpa_config_read(wpa_s->confanother, conf);
     858             : 
     859           1 :         conf->changed_parameters = (unsigned int) -1;
     860             : 
     861           2 :         reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
     862           2 :                 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
     863           1 :                     os_strcmp(conf->ctrl_interface,
     864             :                               wpa_s->conf->ctrl_interface) != 0);
     865             : 
     866           1 :         if (reconf_ctrl && wpa_s->ctrl_iface) {
     867           0 :                 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
     868           0 :                 wpa_s->ctrl_iface = NULL;
     869             :         }
     870             : 
     871           1 :         eapol_sm_invalidate_cached_session(wpa_s->eapol);
     872           1 :         if (wpa_s->current_ssid) {
     873           0 :                 wpa_supplicant_deauthenticate(wpa_s,
     874             :                                               WLAN_REASON_DEAUTH_LEAVING);
     875             :         }
     876             : 
     877             :         /*
     878             :          * TODO: should notify EAPOL SM about changes in opensc_engine_path,
     879             :          * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
     880             :          */
     881           1 :         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
     882             :                 /*
     883             :                  * Clear forced success to clear EAP state for next
     884             :                  * authentication.
     885             :                  */
     886           0 :                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
     887             :         }
     888           1 :         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
     889           1 :         wpa_sm_set_config(wpa_s->wpa, NULL);
     890           1 :         wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
     891           1 :         wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
     892           1 :         rsn_preauth_deinit(wpa_s->wpa);
     893             : 
     894           1 :         old_ap_scan = wpa_s->conf->ap_scan;
     895           1 :         wpa_config_free(wpa_s->conf);
     896           1 :         wpa_s->conf = conf;
     897           1 :         if (old_ap_scan != wpa_s->conf->ap_scan)
     898           0 :                 wpas_notify_ap_scan_changed(wpa_s);
     899             : 
     900           1 :         if (reconf_ctrl)
     901           0 :                 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
     902             : 
     903           1 :         wpa_supplicant_update_config(wpa_s);
     904             : 
     905           1 :         wpa_supplicant_clear_status(wpa_s);
     906           1 :         if (wpa_supplicant_enabled_networks(wpa_s)) {
     907           0 :                 wpa_s->reassociate = 1;
     908           0 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
     909             :         }
     910           1 :         wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
     911           1 :         return 0;
     912             : }
     913             : 
     914             : 
     915           0 : static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
     916             : {
     917           0 :         struct wpa_global *global = signal_ctx;
     918             :         struct wpa_supplicant *wpa_s;
     919           0 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
     920           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
     921             :                         sig);
     922           0 :                 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
     923           0 :                         wpa_supplicant_terminate_proc(global);
     924             :                 }
     925             :         }
     926           0 : }
     927             : 
     928             : 
     929          18 : static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
     930             :                                          struct wpa_ssid *ssid,
     931             :                                          struct wpa_ie_data *ie)
     932             : {
     933          18 :         int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
     934          18 :         if (ret) {
     935          12 :                 if (ret == -2) {
     936           0 :                         wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
     937             :                                 "from association info");
     938             :                 }
     939          12 :                 return -1;
     940             :         }
     941             : 
     942           6 :         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
     943             :                 "cipher suites");
     944           6 :         if (!(ie->group_cipher & ssid->group_cipher)) {
     945           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
     946             :                         "cipher 0x%x (mask 0x%x) - reject",
     947             :                         ie->group_cipher, ssid->group_cipher);
     948           0 :                 return -1;
     949             :         }
     950           6 :         if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
     951           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
     952             :                         "cipher 0x%x (mask 0x%x) - reject",
     953             :                         ie->pairwise_cipher, ssid->pairwise_cipher);
     954           0 :                 return -1;
     955             :         }
     956           6 :         if (!(ie->key_mgmt & ssid->key_mgmt)) {
     957           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
     958             :                         "management 0x%x (mask 0x%x) - reject",
     959             :                         ie->key_mgmt, ssid->key_mgmt);
     960           0 :                 return -1;
     961             :         }
     962             : 
     963             : #ifdef CONFIG_IEEE80211W
     964          12 :         if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
     965           6 :             wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
     966           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
     967             :                         "that does not support management frame protection - "
     968             :                         "reject");
     969           0 :                 return -1;
     970             :         }
     971             : #endif /* CONFIG_IEEE80211W */
     972             : 
     973           6 :         return 0;
     974             : }
     975             : 
     976             : 
     977             : /**
     978             :  * wpa_supplicant_set_suites - Set authentication and encryption parameters
     979             :  * @wpa_s: Pointer to wpa_supplicant data
     980             :  * @bss: Scan results for the selected BSS, or %NULL if not available
     981             :  * @ssid: Configuration data for the selected network
     982             :  * @wpa_ie: Buffer for the WPA/RSN IE
     983             :  * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
     984             :  * used buffer length in case the functions returns success.
     985             :  * Returns: 0 on success or -1 on failure
     986             :  *
     987             :  * This function is used to configure authentication and encryption parameters
     988             :  * based on the network configuration and scan result for the selected BSS (if
     989             :  * available).
     990             :  */
     991        1827 : int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
     992             :                               struct wpa_bss *bss, struct wpa_ssid *ssid,
     993             :                               u8 *wpa_ie, size_t *wpa_ie_len)
     994             : {
     995             :         struct wpa_ie_data ie;
     996             :         int sel, proto;
     997             :         const u8 *bss_wpa, *bss_rsn, *bss_osen;
     998             : 
     999        1827 :         if (bss) {
    1000        1809 :                 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
    1001        1809 :                 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    1002        1809 :                 bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
    1003             :         } else
    1004          18 :                 bss_wpa = bss_rsn = bss_osen = NULL;
    1005             : 
    1006        3617 :         if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
    1007        3580 :             wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
    1008        3580 :             (ie.group_cipher & ssid->group_cipher) &&
    1009        3580 :             (ie.pairwise_cipher & ssid->pairwise_cipher) &&
    1010        1790 :             (ie.key_mgmt & ssid->key_mgmt)) {
    1011        1790 :                 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
    1012        1790 :                 proto = WPA_PROTO_RSN;
    1013          56 :         } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
    1014          38 :                    wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
    1015          38 :                    (ie.group_cipher & ssid->group_cipher) &&
    1016          38 :                    (ie.pairwise_cipher & ssid->pairwise_cipher) &&
    1017          19 :                    (ie.key_mgmt & ssid->key_mgmt)) {
    1018          19 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
    1019          19 :                 proto = WPA_PROTO_WPA;
    1020             : #ifdef CONFIG_HS20
    1021          18 :         } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
    1022           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
    1023             :                 /* TODO: parse OSEN element */
    1024           0 :                 os_memset(&ie, 0, sizeof(ie));
    1025           0 :                 ie.group_cipher = WPA_CIPHER_CCMP;
    1026           0 :                 ie.pairwise_cipher = WPA_CIPHER_CCMP;
    1027           0 :                 ie.key_mgmt = WPA_KEY_MGMT_OSEN;
    1028           0 :                 proto = WPA_PROTO_OSEN;
    1029             : #endif /* CONFIG_HS20 */
    1030          18 :         } else if (bss) {
    1031           0 :                 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
    1032           0 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1033             :                         "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
    1034             :                         ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
    1035             :                         ssid->key_mgmt);
    1036           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
    1037             :                         MAC2STR(bss->bssid),
    1038             :                         wpa_ssid_txt(bss->ssid, bss->ssid_len),
    1039             :                         bss_wpa ? " WPA" : "",
    1040             :                         bss_rsn ? " RSN" : "",
    1041             :                         bss_osen ? " OSEN" : "");
    1042           0 :                 if (bss_rsn) {
    1043           0 :                         wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
    1044           0 :                         if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
    1045           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
    1046             :                                         "Could not parse RSN element");
    1047             :                         } else {
    1048           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
    1049             :                                         "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
    1050             :                                         ie.pairwise_cipher, ie.group_cipher,
    1051             :                                         ie.key_mgmt);
    1052             :                         }
    1053             :                 }
    1054           0 :                 if (bss_wpa) {
    1055           0 :                         wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
    1056           0 :                         if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
    1057           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
    1058             :                                         "Could not parse WPA element");
    1059             :                         } else {
    1060           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
    1061             :                                         "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
    1062             :                                         ie.pairwise_cipher, ie.group_cipher,
    1063             :                                         ie.key_mgmt);
    1064             :                         }
    1065             :                 }
    1066           0 :                 return -1;
    1067             :         } else {
    1068          18 :                 if (ssid->proto & WPA_PROTO_OSEN)
    1069           2 :                         proto = WPA_PROTO_OSEN;
    1070          16 :                 else if (ssid->proto & WPA_PROTO_RSN)
    1071          11 :                         proto = WPA_PROTO_RSN;
    1072             :                 else
    1073           5 :                         proto = WPA_PROTO_WPA;
    1074          18 :                 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
    1075          12 :                         os_memset(&ie, 0, sizeof(ie));
    1076          12 :                         ie.group_cipher = ssid->group_cipher;
    1077          12 :                         ie.pairwise_cipher = ssid->pairwise_cipher;
    1078          12 :                         ie.key_mgmt = ssid->key_mgmt;
    1079             : #ifdef CONFIG_IEEE80211W
    1080          12 :                         ie.mgmt_group_cipher =
    1081          12 :                                 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
    1082          12 :                                 WPA_CIPHER_AES_128_CMAC : 0;
    1083             : #endif /* CONFIG_IEEE80211W */
    1084          12 :                         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
    1085             :                                 "based on configuration");
    1086             :                 } else
    1087           6 :                         proto = ie.proto;
    1088             :         }
    1089             : 
    1090        1827 :         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
    1091             :                 "pairwise %d key_mgmt %d proto %d",
    1092             :                 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
    1093             : #ifdef CONFIG_IEEE80211W
    1094        1827 :         if (ssid->ieee80211w) {
    1095        1827 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
    1096             :                         ie.mgmt_group_cipher);
    1097             :         }
    1098             : #endif /* CONFIG_IEEE80211W */
    1099             : 
    1100        1827 :         wpa_s->wpa_proto = proto;
    1101        1827 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
    1102        1827 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
    1103        1827 :                          !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
    1104             : 
    1105        1827 :         if (bss || !wpa_s->ap_ies_from_associnfo) {
    1106        1877 :                 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
    1107        1877 :                                          bss_wpa ? 2 + bss_wpa[1] : 0) ||
    1108        3622 :                     wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
    1109        1795 :                                          bss_rsn ? 2 + bss_rsn[1] : 0))
    1110           1 :                         return -1;
    1111             :         }
    1112             : 
    1113        1826 :         sel = ie.group_cipher & ssid->group_cipher;
    1114        1826 :         wpa_s->group_cipher = wpa_pick_group_cipher(sel);
    1115        1826 :         if (wpa_s->group_cipher < 0) {
    1116           0 :                 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
    1117             :                         "cipher");
    1118           0 :                 return -1;
    1119             :         }
    1120        1826 :         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
    1121             :                 wpa_cipher_txt(wpa_s->group_cipher));
    1122             : 
    1123        1826 :         sel = ie.pairwise_cipher & ssid->pairwise_cipher;
    1124        1826 :         wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
    1125        1826 :         if (wpa_s->pairwise_cipher < 0) {
    1126           0 :                 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
    1127             :                         "cipher");
    1128           0 :                 return -1;
    1129             :         }
    1130        1826 :         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
    1131             :                 wpa_cipher_txt(wpa_s->pairwise_cipher));
    1132             : 
    1133        1826 :         sel = ie.key_mgmt & ssid->key_mgmt;
    1134             : #ifdef CONFIG_SAE
    1135        1826 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
    1136           9 :                 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
    1137             : #endif /* CONFIG_SAE */
    1138             :         if (0) {
    1139             : #ifdef CONFIG_SUITEB192
    1140        1826 :         } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
    1141           2 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
    1142           2 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1143             :                         "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
    1144             : #endif /* CONFIG_SUITEB192 */
    1145             : #ifdef CONFIG_SUITEB
    1146        1824 :         } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
    1147           2 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
    1148           2 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1149             :                         "WPA: using KEY_MGMT 802.1X with Suite B");
    1150             : #endif /* CONFIG_SUITEB */
    1151             : #ifdef CONFIG_IEEE80211R
    1152        1822 :         } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
    1153           8 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
    1154           8 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
    1155        1814 :         } else if (sel & WPA_KEY_MGMT_FT_PSK) {
    1156         124 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
    1157         124 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
    1158             : #endif /* CONFIG_IEEE80211R */
    1159             : #ifdef CONFIG_SAE
    1160        1690 :         } else if (sel & WPA_KEY_MGMT_SAE) {
    1161          62 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
    1162          62 :                 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
    1163        1628 :         } else if (sel & WPA_KEY_MGMT_FT_SAE) {
    1164           8 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
    1165           8 :                 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
    1166             : #endif /* CONFIG_SAE */
    1167             : #ifdef CONFIG_IEEE80211W
    1168        1620 :         } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
    1169           4 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
    1170           4 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1171             :                         "WPA: using KEY_MGMT 802.1X with SHA256");
    1172        1616 :         } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
    1173          25 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
    1174          25 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1175             :                         "WPA: using KEY_MGMT PSK with SHA256");
    1176             : #endif /* CONFIG_IEEE80211W */
    1177        1591 :         } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
    1178         965 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
    1179         965 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
    1180         626 :         } else if (sel & WPA_KEY_MGMT_PSK) {
    1181         619 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
    1182         619 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
    1183           7 :         } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
    1184           5 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
    1185           5 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
    1186             : #ifdef CONFIG_HS20
    1187           2 :         } else if (sel & WPA_KEY_MGMT_OSEN) {
    1188           2 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
    1189           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
    1190             : #endif /* CONFIG_HS20 */
    1191             :         } else {
    1192           0 :                 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
    1193             :                         "authenticated key management type");
    1194           0 :                 return -1;
    1195             :         }
    1196             : 
    1197        1826 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
    1198        1826 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
    1199        1826 :                          wpa_s->pairwise_cipher);
    1200        1826 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
    1201             : 
    1202             : #ifdef CONFIG_IEEE80211W
    1203        1826 :         sel = ie.mgmt_group_cipher;
    1204        2167 :         if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
    1205         341 :             !(ie.capabilities & WPA_CAPABILITY_MFPC))
    1206        1778 :                 sel = 0;
    1207        1826 :         if (sel & WPA_CIPHER_AES_128_CMAC) {
    1208          39 :                 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
    1209          39 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
    1210             :                         "AES-128-CMAC");
    1211        1787 :         } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
    1212           3 :                 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
    1213           3 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
    1214             :                         "BIP-GMAC-128");
    1215        1784 :         } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
    1216           4 :                 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
    1217           4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
    1218             :                         "BIP-GMAC-256");
    1219        1780 :         } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
    1220           2 :                 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
    1221           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
    1222             :                         "BIP-CMAC-256");
    1223             :         } else {
    1224        1778 :                 wpa_s->mgmt_group_cipher = 0;
    1225        1778 :                 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
    1226             :         }
    1227        1826 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
    1228        1826 :                          wpa_s->mgmt_group_cipher);
    1229        1826 :         wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
    1230        1826 :                          wpas_get_ssid_pmf(wpa_s, ssid));
    1231             : #endif /* CONFIG_IEEE80211W */
    1232             : 
    1233        1826 :         if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
    1234           0 :                 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
    1235           0 :                 return -1;
    1236             :         }
    1237             : 
    1238        1826 :         if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
    1239         838 :                 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
    1240             : #ifndef CONFIG_NO_PBKDF2
    1241         840 :                 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
    1242           2 :                     ssid->passphrase) {
    1243             :                         u8 psk[PMK_LEN];
    1244           1 :                         pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
    1245             :                                     4096, psk, PMK_LEN);
    1246           1 :                         wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
    1247             :                                         psk, PMK_LEN);
    1248           1 :                         wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
    1249           1 :                         os_memset(psk, 0, sizeof(psk));
    1250             :                 }
    1251             : #endif /* CONFIG_NO_PBKDF2 */
    1252             : #ifdef CONFIG_EXT_PASSWORD
    1253         838 :                 if (ssid->ext_psk) {
    1254           4 :                         struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
    1255           4 :                                                              ssid->ext_psk);
    1256             :                         char pw_str[64 + 1];
    1257             :                         u8 psk[PMK_LEN];
    1258             : 
    1259           4 :                         if (pw == NULL) {
    1260           1 :                                 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
    1261             :                                         "found from external storage");
    1262           4 :                                 return -1;
    1263             :                         }
    1264             : 
    1265           3 :                         if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
    1266           1 :                                 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
    1267             :                                         "PSK length %d in external storage",
    1268           1 :                                         (int) wpabuf_len(pw));
    1269           1 :                                 ext_password_free(pw);
    1270           1 :                                 return -1;
    1271             :                         }
    1272             : 
    1273           2 :                         os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
    1274           2 :                         pw_str[wpabuf_len(pw)] = '\0';
    1275             : 
    1276             : #ifndef CONFIG_NO_PBKDF2
    1277           2 :                         if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
    1278             :                         {
    1279           1 :                                 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
    1280             :                                             4096, psk, PMK_LEN);
    1281           1 :                                 os_memset(pw_str, 0, sizeof(pw_str));
    1282           1 :                                 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
    1283             :                                                 "external passphrase)",
    1284             :                                                 psk, PMK_LEN);
    1285           1 :                                 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
    1286           1 :                                 os_memset(psk, 0, sizeof(psk));
    1287             :                         } else
    1288             : #endif /* CONFIG_NO_PBKDF2 */
    1289           1 :                         if (wpabuf_len(pw) == 2 * PMK_LEN) {
    1290           1 :                                 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
    1291           1 :                                         wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
    1292             :                                                 "Invalid PSK hex string");
    1293           1 :                                         os_memset(pw_str, 0, sizeof(pw_str));
    1294           1 :                                         ext_password_free(pw);
    1295           1 :                                         return -1;
    1296             :                                 }
    1297           0 :                                 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
    1298           0 :                                 os_memset(psk, 0, sizeof(psk));
    1299             :                         } else {
    1300           0 :                                 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
    1301             :                                         "PSK available");
    1302           0 :                                 os_memset(pw_str, 0, sizeof(pw_str));
    1303           0 :                                 ext_password_free(pw);
    1304           0 :                                 return -1;
    1305             :                         }
    1306             : 
    1307           1 :                         os_memset(pw_str, 0, sizeof(pw_str));
    1308           1 :                         ext_password_free(pw);
    1309             :                 }
    1310             : #endif /* CONFIG_EXT_PASSWORD */
    1311             :         } else
    1312         988 :                 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
    1313             : 
    1314        1823 :         return 0;
    1315             : }
    1316             : 
    1317             : 
    1318       19658 : static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
    1319             : {
    1320       19658 :         *pos = 0x00;
    1321             : 
    1322       19658 :         switch (idx) {
    1323             :         case 0: /* Bits 0-7 */
    1324        2461 :                 break;
    1325             :         case 1: /* Bits 8-15 */
    1326        2461 :                 break;
    1327             :         case 2: /* Bits 16-23 */
    1328             : #ifdef CONFIG_WNM
    1329        2461 :                 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
    1330        2461 :                 *pos |= 0x08; /* Bit 19 - BSS Transition */
    1331             : #endif /* CONFIG_WNM */
    1332        2461 :                 break;
    1333             :         case 3: /* Bits 24-31 */
    1334             : #ifdef CONFIG_WNM
    1335        2461 :                 *pos |= 0x02; /* Bit 25 - SSID List */
    1336             : #endif /* CONFIG_WNM */
    1337             : #ifdef CONFIG_INTERWORKING
    1338        2461 :                 if (wpa_s->conf->interworking)
    1339         674 :                         *pos |= 0x80; /* Bit 31 - Interworking */
    1340             : #endif /* CONFIG_INTERWORKING */
    1341        2461 :                 break;
    1342             :         case 4: /* Bits 32-39 */
    1343             : #ifdef CONFIG_INTERWORKING
    1344        2461 :                 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
    1345        2446 :                         *pos |= 0x01; /* Bit 32 - QoS Map */
    1346             : #endif /* CONFIG_INTERWORKING */
    1347        2461 :                 break;
    1348             :         case 5: /* Bits 40-47 */
    1349             : #ifdef CONFIG_HS20
    1350        2461 :                 if (wpa_s->conf->hs20)
    1351         674 :                         *pos |= 0x40; /* Bit 46 - WNM-Notification */
    1352             : #endif /* CONFIG_HS20 */
    1353        2461 :                 break;
    1354             :         case 6: /* Bits 48-55 */
    1355        2446 :                 break;
    1356             :         }
    1357       19658 : }
    1358             : 
    1359             : 
    1360        2461 : int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
    1361             : {
    1362        2461 :         u8 *pos = buf;
    1363        2461 :         u8 len = 6, i;
    1364             : 
    1365        2461 :         if (len < wpa_s->extended_capa_len)
    1366        2446 :                 len = wpa_s->extended_capa_len;
    1367        2461 :         if (buflen < (size_t) len + 2) {
    1368           0 :                 wpa_printf(MSG_INFO,
    1369             :                            "Not enough room for building extended capabilities element");
    1370           0 :                 return -1;
    1371             :         }
    1372             : 
    1373        2461 :         *pos++ = WLAN_EID_EXT_CAPAB;
    1374        2461 :         *pos++ = len;
    1375       22119 :         for (i = 0; i < len; i++, pos++) {
    1376       19658 :                 wpas_ext_capab_byte(wpa_s, pos, i);
    1377             : 
    1378       19658 :                 if (i < wpa_s->extended_capa_len) {
    1379       19568 :                         *pos &= ~wpa_s->extended_capa_mask[i];
    1380       19568 :                         *pos |= wpa_s->extended_capa[i];
    1381             :                 }
    1382             :         }
    1383             : 
    1384        4952 :         while (len > 0 && buf[1 + len] == 0) {
    1385          30 :                 len--;
    1386          30 :                 buf[1] = len;
    1387             :         }
    1388        2461 :         if (len == 0)
    1389           0 :                 return 0;
    1390             : 
    1391        2461 :         return 2 + len;
    1392             : }
    1393             : 
    1394             : 
    1395        2410 : static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
    1396             :                           struct wpa_bss *test_bss)
    1397             : {
    1398             :         struct wpa_bss *bss;
    1399             : 
    1400        2969 :         dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
    1401        2969 :                 if (bss == test_bss)
    1402        2410 :                         return 1;
    1403             :         }
    1404             : 
    1405           0 :         return 0;
    1406             : }
    1407             : 
    1408             : 
    1409        2431 : static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
    1410             :                            struct wpa_ssid *test_ssid)
    1411             : {
    1412             :         struct wpa_ssid *ssid;
    1413             : 
    1414        2809 :         for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
    1415        2809 :                 if (ssid == test_ssid)
    1416        2431 :                         return 1;
    1417             :         }
    1418             : 
    1419           0 :         return 0;
    1420             : }
    1421             : 
    1422             : 
    1423        2431 : int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
    1424             :                         struct wpa_ssid *test_ssid)
    1425             : {
    1426        2431 :         if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
    1427           0 :                 return 0;
    1428             : 
    1429        2431 :         return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
    1430             : }
    1431             : 
    1432             : 
    1433        2435 : void wpas_connect_work_free(struct wpa_connect_work *cwork)
    1434             : {
    1435        2435 :         if (cwork == NULL)
    1436        2435 :                 return;
    1437        2435 :         os_free(cwork);
    1438             : }
    1439             : 
    1440             : 
    1441        6893 : void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
    1442             : {
    1443             :         struct wpa_connect_work *cwork;
    1444        6893 :         struct wpa_radio_work *work = wpa_s->connect_work;
    1445             : 
    1446        6893 :         if (!work)
    1447       11353 :                 return;
    1448             : 
    1449        2433 :         wpa_s->connect_work = NULL;
    1450        2433 :         cwork = work->ctx;
    1451        2433 :         work->ctx = NULL;
    1452        2433 :         wpas_connect_work_free(cwork);
    1453        2433 :         radio_work_done(work);
    1454             : }
    1455             : 
    1456             : 
    1457          13 : int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
    1458             : {
    1459             :         struct os_reltime now;
    1460             :         u8 addr[ETH_ALEN];
    1461             : 
    1462          13 :         os_get_reltime(&now);
    1463          21 :         if (wpa_s->last_mac_addr_style == style &&
    1464          16 :             wpa_s->last_mac_addr_change.sec != 0 &&
    1465           8 :             !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
    1466           8 :                                 wpa_s->conf->rand_addr_lifetime)) {
    1467           4 :                 wpa_msg(wpa_s, MSG_DEBUG,
    1468             :                         "Previously selected random MAC address has not yet expired");
    1469           4 :                 return 0;
    1470             :         }
    1471             : 
    1472           9 :         switch (style) {
    1473             :         case 1:
    1474           5 :                 if (random_mac_addr(addr) < 0)
    1475           0 :                         return -1;
    1476           5 :                 break;
    1477             :         case 2:
    1478           4 :                 os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
    1479           4 :                 if (random_mac_addr_keep_oui(addr) < 0)
    1480           0 :                         return -1;
    1481           4 :                 break;
    1482             :         default:
    1483           0 :                 return -1;
    1484             :         }
    1485             : 
    1486           9 :         if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
    1487           0 :                 wpa_msg(wpa_s, MSG_INFO,
    1488             :                         "Failed to set random MAC address");
    1489           0 :                 return -1;
    1490             :         }
    1491             : 
    1492           9 :         os_get_reltime(&wpa_s->last_mac_addr_change);
    1493           9 :         wpa_s->mac_addr_changed = 1;
    1494           9 :         wpa_s->last_mac_addr_style = style;
    1495             : 
    1496           9 :         if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
    1497           0 :                 wpa_msg(wpa_s, MSG_INFO,
    1498             :                         "Could not update MAC address information");
    1499           0 :                 return -1;
    1500             :         }
    1501             : 
    1502          54 :         wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
    1503          54 :                 MAC2STR(addr));
    1504             : 
    1505           9 :         return 0;
    1506             : }
    1507             : 
    1508             : 
    1509        2172 : int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
    1510             : {
    1511        4243 :         if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
    1512        2071 :             !wpa_s->conf->preassoc_mac_addr)
    1513        2164 :                 return 0;
    1514             : 
    1515           8 :         return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
    1516             : }
    1517             : 
    1518             : 
    1519             : static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
    1520             : 
    1521             : /**
    1522             :  * wpa_supplicant_associate - Request association
    1523             :  * @wpa_s: Pointer to wpa_supplicant data
    1524             :  * @bss: Scan results for the selected BSS, or %NULL if not available
    1525             :  * @ssid: Configuration data for the selected network
    1526             :  *
    1527             :  * This function is used to request %wpa_supplicant to associate with a BSS.
    1528             :  */
    1529        2704 : void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
    1530             :                               struct wpa_bss *bss, struct wpa_ssid *ssid)
    1531             : {
    1532             :         struct wpa_connect_work *cwork;
    1533             :         int rand_style;
    1534             : 
    1535        2704 :         if (ssid->mac_addr == -1)
    1536        2698 :                 rand_style = wpa_s->conf->mac_addr;
    1537             :         else
    1538           6 :                 rand_style = ssid->mac_addr;
    1539             : 
    1540        2704 :         wmm_ac_clear_saved_tspecs(wpa_s);
    1541        2704 :         wpa_s->reassoc_same_bss = 0;
    1542             : 
    1543        2704 :         if (wpa_s->last_ssid == ssid) {
    1544         854 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
    1545         854 :                 if (wpa_s->current_bss && wpa_s->current_bss == bss) {
    1546          63 :                         wmm_ac_save_tspecs(wpa_s);
    1547          63 :                         wpa_s->reassoc_same_bss = 1;
    1548             :                 }
    1549        1850 :         } else if (rand_style > 0) {
    1550           5 :                 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
    1551           0 :                         return;
    1552           5 :                 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
    1553        1845 :         } else if (wpa_s->mac_addr_changed) {
    1554           2 :                 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
    1555           0 :                         wpa_msg(wpa_s, MSG_INFO,
    1556             :                                 "Could not restore permanent MAC address");
    1557           0 :                         return;
    1558             :                 }
    1559           2 :                 wpa_s->mac_addr_changed = 0;
    1560           2 :                 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
    1561           0 :                         wpa_msg(wpa_s, MSG_INFO,
    1562             :                                 "Could not update MAC address information");
    1563           0 :                         return;
    1564             :                 }
    1565           2 :                 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
    1566             :         }
    1567        2704 :         wpa_s->last_ssid = ssid;
    1568             : 
    1569             : #ifdef CONFIG_IBSS_RSN
    1570        2704 :         ibss_rsn_deinit(wpa_s->ibss_rsn);
    1571        2704 :         wpa_s->ibss_rsn = NULL;
    1572             : #endif /* CONFIG_IBSS_RSN */
    1573             : 
    1574        5270 :         if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
    1575        2566 :             ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
    1576             : #ifdef CONFIG_AP
    1577         238 :                 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
    1578           0 :                         wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
    1579             :                                 "mode");
    1580           0 :                         return;
    1581             :                 }
    1582         238 :                 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
    1583           2 :                         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
    1584           2 :                         if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
    1585           0 :                                 wpas_p2p_ap_setup_failed(wpa_s);
    1586           2 :                         return;
    1587             :                 }
    1588         236 :                 wpa_s->current_bss = bss;
    1589             : #else /* CONFIG_AP */
    1590             :                 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
    1591             :                         "the build");
    1592             : #endif /* CONFIG_AP */
    1593         236 :                 return;
    1594             :         }
    1595             : 
    1596        2466 :         if (ssid->mode == WPAS_MODE_MESH) {
    1597             : #ifdef CONFIG_MESH
    1598          29 :                 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
    1599           0 :                         wpa_msg(wpa_s, MSG_INFO,
    1600             :                                 "Driver does not support mesh mode");
    1601           0 :                         return;
    1602             :                 }
    1603          29 :                 if (bss)
    1604           0 :                         ssid->frequency = bss->freq;
    1605          29 :                 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
    1606           1 :                         wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
    1607           1 :                         return;
    1608             :                 }
    1609          28 :                 wpa_s->current_bss = bss;
    1610          56 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_STARTED
    1611             :                              "ssid=\"%s\" id=%d",
    1612          28 :                              wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
    1613             :                              ssid->id);
    1614             : #else /* CONFIG_MESH */
    1615             :                 wpa_msg(wpa_s, MSG_ERROR,
    1616             :                         "mesh mode support not included in the build");
    1617             : #endif /* CONFIG_MESH */
    1618          28 :                 return;
    1619             :         }
    1620             : 
    1621             : #ifdef CONFIG_TDLS
    1622        2437 :         if (bss)
    1623        2414 :                 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
    1624             :                                 bss->ie_len);
    1625             : #endif /* CONFIG_TDLS */
    1626             : 
    1627        4829 :         if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
    1628        2392 :             ssid->mode == IEEE80211_MODE_INFRA) {
    1629        2378 :                 sme_authenticate(wpa_s, bss, ssid);
    1630        2378 :                 return;
    1631             :         }
    1632             : 
    1633          59 :         if (wpa_s->connect_work) {
    1634           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
    1635           0 :                 return;
    1636             :         }
    1637             : 
    1638          59 :         if (radio_work_pending(wpa_s, "connect")) {
    1639           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
    1640           0 :                 return;
    1641             :         }
    1642             : 
    1643          59 :         cwork = os_zalloc(sizeof(*cwork));
    1644          59 :         if (cwork == NULL)
    1645           0 :                 return;
    1646             : 
    1647          59 :         cwork->bss = bss;
    1648          59 :         cwork->ssid = ssid;
    1649             : 
    1650          59 :         if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
    1651             :                            wpas_start_assoc_cb, cwork) < 0) {
    1652           0 :                 os_free(cwork);
    1653             :         }
    1654             : }
    1655             : 
    1656             : 
    1657          43 : void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
    1658             :                           const struct wpa_ssid *ssid,
    1659             :                           struct hostapd_freq_params *freq)
    1660             : {
    1661             :         enum hostapd_hw_mode hw_mode;
    1662          43 :         struct hostapd_hw_modes *mode = NULL;
    1663          43 :         int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
    1664             :                            184, 192 };
    1665          43 :         struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
    1666             :         u8 channel;
    1667          43 :         int i, chan_idx, ht40 = -1, res;
    1668             :         unsigned int j;
    1669             : 
    1670          43 :         freq->freq = ssid->frequency;
    1671             : 
    1672             :         /* For IBSS check HT_IBSS flag */
    1673          57 :         if (ssid->mode == WPAS_MODE_IBSS &&
    1674          14 :             !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
    1675          41 :                 return;
    1676             : 
    1677          43 :         hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
    1678          45 :         for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
    1679          45 :                 if (wpa_s->hw.modes[i].mode == hw_mode) {
    1680          43 :                         mode = &wpa_s->hw.modes[i];
    1681          43 :                         break;
    1682             :                 }
    1683             :         }
    1684             : 
    1685          43 :         if (!mode)
    1686           0 :                 return;
    1687             : 
    1688          43 :         freq->ht_enabled = ht_supported(mode);
    1689          43 :         if (!freq->ht_enabled)
    1690           0 :                 return;
    1691             : 
    1692             :         /* Setup higher BW only for 5 GHz */
    1693          43 :         if (mode->mode != HOSTAPD_MODE_IEEE80211A)
    1694          41 :                 return;
    1695             : 
    1696           2 :         for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
    1697           2 :                 pri_chan = &mode->channels[chan_idx];
    1698           2 :                 if (pri_chan->chan == channel)
    1699           2 :                         break;
    1700           0 :                 pri_chan = NULL;
    1701             :         }
    1702           2 :         if (!pri_chan)
    1703           0 :                 return;
    1704             : 
    1705             :         /* Check primary channel flags */
    1706           2 :         if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
    1707           0 :                 return;
    1708             : 
    1709             :         /* Check/setup HT40+/HT40- */
    1710           2 :         for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
    1711           2 :                 if (ht40plus[j] == channel) {
    1712           2 :                         ht40 = 1;
    1713           2 :                         break;
    1714             :                 }
    1715             :         }
    1716             : 
    1717             :         /* Find secondary channel */
    1718           4 :         for (i = 0; i < mode->num_channels; i++) {
    1719           4 :                 sec_chan = &mode->channels[i];
    1720           4 :                 if (sec_chan->chan == channel + ht40 * 4)
    1721           2 :                         break;
    1722           2 :                 sec_chan = NULL;
    1723             :         }
    1724           2 :         if (!sec_chan)
    1725           0 :                 return;
    1726             : 
    1727             :         /* Check secondary channel flags */
    1728           2 :         if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
    1729           0 :                 return;
    1730             : 
    1731           2 :         freq->channel = pri_chan->chan;
    1732             : 
    1733           2 :         switch (ht40) {
    1734             :         case -1:
    1735           0 :                 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
    1736           0 :                         return;
    1737           0 :                 freq->sec_channel_offset = -1;
    1738           0 :                 break;
    1739             :         case 1:
    1740           2 :                 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
    1741           0 :                         return;
    1742           2 :                 freq->sec_channel_offset = 1;
    1743           2 :                 break;
    1744             :         default:
    1745           0 :                 break;
    1746             :         }
    1747             : 
    1748           2 :         if (freq->sec_channel_offset) {
    1749             :                 struct wpa_scan_results *scan_res;
    1750             : 
    1751           2 :                 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
    1752           2 :                 if (scan_res == NULL) {
    1753             :                         /* Back to HT20 */
    1754           0 :                         freq->sec_channel_offset = 0;
    1755           0 :                         return;
    1756             :                 }
    1757             : 
    1758           2 :                 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
    1759           2 :                                      sec_chan->chan);
    1760           2 :                 switch (res) {
    1761             :                 case 0:
    1762             :                         /* Back to HT20 */
    1763           0 :                         freq->sec_channel_offset = 0;
    1764           0 :                         break;
    1765             :                 case 1:
    1766             :                         /* Configuration allowed */
    1767           2 :                         break;
    1768             :                 case 2:
    1769             :                         /* Switch pri/sec channels */
    1770           0 :                         freq->freq = hw_get_freq(mode, sec_chan->chan);
    1771           0 :                         freq->sec_channel_offset = -freq->sec_channel_offset;
    1772           0 :                         freq->channel = sec_chan->chan;
    1773           0 :                         break;
    1774             :                 default:
    1775           0 :                         freq->sec_channel_offset = 0;
    1776           0 :                         break;
    1777             :                 }
    1778             : 
    1779           2 :                 wpa_scan_results_free(scan_res);
    1780             :         }
    1781             : 
    1782           2 :         wpa_printf(MSG_DEBUG,
    1783             :                    "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
    1784             :                    freq->channel, freq->sec_channel_offset);
    1785             : }
    1786             : 
    1787             : 
    1788          59 : static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
    1789             : {
    1790          59 :         struct wpa_connect_work *cwork = work->ctx;
    1791          59 :         struct wpa_bss *bss = cwork->bss;
    1792          59 :         struct wpa_ssid *ssid = cwork->ssid;
    1793          59 :         struct wpa_supplicant *wpa_s = work->wpa_s;
    1794             :         u8 wpa_ie[200];
    1795             :         size_t wpa_ie_len;
    1796             :         int use_crypt, ret, i, bssid_changed;
    1797          59 :         int algs = WPA_AUTH_ALG_OPEN;
    1798             :         unsigned int cipher_pairwise, cipher_group;
    1799             :         struct wpa_driver_associate_params params;
    1800          59 :         int wep_keys_set = 0;
    1801          59 :         int assoc_failed = 0;
    1802             :         struct wpa_ssid *old_ssid;
    1803             : #ifdef CONFIG_HT_OVERRIDES
    1804             :         struct ieee80211_ht_capabilities htcaps;
    1805             :         struct ieee80211_ht_capabilities htcaps_mask;
    1806             : #endif /* CONFIG_HT_OVERRIDES */
    1807             : #ifdef CONFIG_VHT_OVERRIDES
    1808             :        struct ieee80211_vht_capabilities vhtcaps;
    1809             :        struct ieee80211_vht_capabilities vhtcaps_mask;
    1810             : #endif /* CONFIG_VHT_OVERRIDES */
    1811             : 
    1812          59 :         if (deinit) {
    1813           0 :                 if (work->started) {
    1814           0 :                         wpa_s->connect_work = NULL;
    1815             : 
    1816             :                         /* cancel possible auth. timeout */
    1817           0 :                         eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
    1818             :                                              NULL);
    1819             :                 }
    1820           0 :                 wpas_connect_work_free(cwork);
    1821           0 :                 return;
    1822             :         }
    1823             : 
    1824          59 :         wpa_s->connect_work = work;
    1825             : 
    1826          59 :         if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid)) {
    1827           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
    1828           1 :                 wpas_connect_work_done(wpa_s);
    1829           1 :                 return;
    1830             :         }
    1831             : 
    1832          58 :         os_memset(&params, 0, sizeof(params));
    1833          58 :         wpa_s->reassociate = 0;
    1834          58 :         wpa_s->eap_expected_failure = 0;
    1835          95 :         if (bss &&
    1836          75 :             (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
    1837             : #ifdef CONFIG_IEEE80211R
    1838          36 :                 const u8 *ie, *md = NULL;
    1839             : #endif /* CONFIG_IEEE80211R */
    1840         288 :                 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
    1841         216 :                         " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
    1842          36 :                         wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
    1843          36 :                 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
    1844          36 :                 os_memset(wpa_s->bssid, 0, ETH_ALEN);
    1845          36 :                 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
    1846          36 :                 if (bssid_changed)
    1847           4 :                         wpas_notify_bssid_changed(wpa_s);
    1848             : #ifdef CONFIG_IEEE80211R
    1849          36 :                 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
    1850          36 :                 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
    1851           0 :                         md = ie + 2;
    1852          36 :                 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
    1853          36 :                 if (md) {
    1854             :                         /* Prepare for the next transition */
    1855           0 :                         wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
    1856             :                 }
    1857             : #endif /* CONFIG_IEEE80211R */
    1858             : #ifdef CONFIG_WPS
    1859          23 :         } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
    1860           2 :                    wpa_s->conf->ap_scan == 2 &&
    1861           1 :                    (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
    1862             :                 /* Use ap_scan==1 style network selection to find the network
    1863             :                  */
    1864           1 :                 wpas_connect_work_done(wpa_s);
    1865           1 :                 wpa_s->scan_req = MANUAL_SCAN_REQ;
    1866           1 :                 wpa_s->reassociate = 1;
    1867           1 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    1868           1 :                 return;
    1869             : #endif /* CONFIG_WPS */
    1870             :         } else {
    1871          42 :                 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
    1872          21 :                         wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
    1873          21 :                 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
    1874             :         }
    1875          57 :         wpa_supplicant_cancel_sched_scan(wpa_s);
    1876          57 :         wpa_supplicant_cancel_scan(wpa_s);
    1877             : 
    1878             :         /* Starting new association, so clear the possibly used WPA IE from the
    1879             :          * previous association. */
    1880          57 :         wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
    1881             : 
    1882             : #ifdef IEEE8021X_EAPOL
    1883          57 :         if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    1884           0 :                 if (ssid->leap) {
    1885           0 :                         if (ssid->non_leap == 0)
    1886           0 :                                 algs = WPA_AUTH_ALG_LEAP;
    1887             :                         else
    1888           0 :                                 algs |= WPA_AUTH_ALG_LEAP;
    1889             :                 }
    1890             :         }
    1891             : #endif /* IEEE8021X_EAPOL */
    1892          57 :         wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
    1893          57 :         if (ssid->auth_alg) {
    1894           7 :                 algs = ssid->auth_alg;
    1895           7 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
    1896             :                         "0x%x", algs);
    1897             :         }
    1898             : 
    1899          93 :         if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
    1900          52 :                     wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
    1901          30 :             wpa_key_mgmt_wpa(ssid->key_mgmt)) {
    1902             :                 int try_opportunistic;
    1903          28 :                 try_opportunistic = (ssid->proactive_key_caching < 0 ?
    1904          11 :                                      wpa_s->conf->okc :
    1905          28 :                                      ssid->proactive_key_caching) &&
    1906           3 :                         (ssid->proto & WPA_PROTO_RSN);
    1907          14 :                 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
    1908             :                                             ssid, try_opportunistic) == 0)
    1909           3 :                         eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
    1910          14 :                 wpa_ie_len = sizeof(wpa_ie);
    1911          14 :                 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
    1912             :                                               wpa_ie, &wpa_ie_len)) {
    1913           0 :                         wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
    1914             :                                 "key management and encryption suites");
    1915           0 :                         wpas_connect_work_done(wpa_s);
    1916           0 :                         return;
    1917             :                 }
    1918          43 :         } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
    1919           0 :                    wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
    1920             :                 /*
    1921             :                  * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
    1922             :                  * use non-WPA since the scan results did not indicate that the
    1923             :                  * AP is using WPA or WPA2.
    1924             :                  */
    1925           0 :                 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
    1926           0 :                 wpa_ie_len = 0;
    1927           0 :                 wpa_s->wpa_proto = 0;
    1928          43 :         } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
    1929          11 :                 wpa_ie_len = sizeof(wpa_ie);
    1930          11 :                 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
    1931             :                                               wpa_ie, &wpa_ie_len)) {
    1932           0 :                         wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
    1933             :                                 "key management and encryption suites (no "
    1934             :                                 "scan results)");
    1935           0 :                         wpas_connect_work_done(wpa_s);
    1936           0 :                         return;
    1937             :                 }
    1938             : #ifdef CONFIG_WPS
    1939          32 :         } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
    1940             :                 struct wpabuf *wps_ie;
    1941           2 :                 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
    1942           2 :                 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
    1943           2 :                         wpa_ie_len = wpabuf_len(wps_ie);
    1944           2 :                         os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
    1945             :                 } else
    1946           0 :                         wpa_ie_len = 0;
    1947           2 :                 wpabuf_free(wps_ie);
    1948           2 :                 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
    1949           2 :                 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
    1950           2 :                         params.wps = WPS_MODE_PRIVACY;
    1951             :                 else
    1952           0 :                         params.wps = WPS_MODE_OPEN;
    1953           2 :                 wpa_s->wpa_proto = 0;
    1954             : #endif /* CONFIG_WPS */
    1955             :         } else {
    1956          30 :                 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
    1957          30 :                 wpa_ie_len = 0;
    1958          30 :                 wpa_s->wpa_proto = 0;
    1959             :         }
    1960             : 
    1961             : #ifdef CONFIG_P2P
    1962          57 :         if (wpa_s->global->p2p) {
    1963             :                 u8 *pos;
    1964             :                 size_t len;
    1965             :                 int res;
    1966          42 :                 pos = wpa_ie + wpa_ie_len;
    1967          42 :                 len = sizeof(wpa_ie) - wpa_ie_len;
    1968          42 :                 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
    1969             :                                             ssid->p2p_group);
    1970          42 :                 if (res >= 0)
    1971          22 :                         wpa_ie_len += res;
    1972             :         }
    1973             : 
    1974          57 :         wpa_s->cross_connect_disallowed = 0;
    1975          57 :         if (bss) {
    1976             :                 struct wpabuf *p2p;
    1977          37 :                 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
    1978          37 :                 if (p2p) {
    1979           4 :                         wpa_s->cross_connect_disallowed =
    1980           4 :                                 p2p_get_cross_connect_disallowed(p2p);
    1981           4 :                         wpabuf_free(p2p);
    1982           4 :                         wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
    1983             :                                 "connection",
    1984             :                                 wpa_s->cross_connect_disallowed ?
    1985             :                                 "disallows" : "allows");
    1986             :                 }
    1987             :         }
    1988             : 
    1989          57 :         os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
    1990             : #endif /* CONFIG_P2P */
    1991             : 
    1992             : #ifdef CONFIG_HS20
    1993          57 :         if (is_hs20_network(wpa_s, ssid, bss)) {
    1994             :                 struct wpabuf *hs20;
    1995           1 :                 hs20 = wpabuf_alloc(20);
    1996           1 :                 if (hs20) {
    1997           1 :                         int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
    1998             :                         size_t len;
    1999             : 
    2000           1 :                         wpas_hs20_add_indication(hs20, pps_mo_id);
    2001           1 :                         len = sizeof(wpa_ie) - wpa_ie_len;
    2002           1 :                         if (wpabuf_len(hs20) <= len) {
    2003           1 :                                 os_memcpy(wpa_ie + wpa_ie_len,
    2004             :                                           wpabuf_head(hs20), wpabuf_len(hs20));
    2005           1 :                                 wpa_ie_len += wpabuf_len(hs20);
    2006             :                         }
    2007           1 :                         wpabuf_free(hs20);
    2008             :                 }
    2009             :         }
    2010             : #endif /* CONFIG_HS20 */
    2011             : 
    2012             :         /*
    2013             :          * Workaround: Add Extended Capabilities element only if the AP
    2014             :          * included this element in Beacon/Probe Response frames. Some older
    2015             :          * APs seem to have interoperability issues if this element is
    2016             :          * included, so while the standard may require us to include the
    2017             :          * element in all cases, it is justifiable to skip it to avoid
    2018             :          * interoperability issues.
    2019             :          */
    2020          57 :         if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
    2021             :                 u8 ext_capab[18];
    2022             :                 int ext_capab_len;
    2023          57 :                 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
    2024             :                                                      sizeof(ext_capab));
    2025          57 :                 if (ext_capab_len > 0) {
    2026          57 :                         u8 *pos = wpa_ie;
    2027          57 :                         if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
    2028          18 :                                 pos += 2 + pos[1];
    2029          57 :                         os_memmove(pos + ext_capab_len, pos,
    2030             :                                    wpa_ie_len - (pos - wpa_ie));
    2031          57 :                         wpa_ie_len += ext_capab_len;
    2032          57 :                         os_memcpy(pos, ext_capab, ext_capab_len);
    2033             :                 }
    2034             :         }
    2035             : 
    2036          57 :         if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
    2037           0 :                 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
    2038             :                 size_t len;
    2039             : 
    2040           0 :                 len = sizeof(wpa_ie) - wpa_ie_len;
    2041           0 :                 if (wpabuf_len(buf) <= len) {
    2042           0 :                         os_memcpy(wpa_ie + wpa_ie_len,
    2043             :                                   wpabuf_head(buf), wpabuf_len(buf));
    2044           0 :                         wpa_ie_len += wpabuf_len(buf);
    2045             :                 }
    2046             :         }
    2047             : 
    2048          57 :         wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
    2049          57 :         use_crypt = 1;
    2050          57 :         cipher_pairwise = wpa_s->pairwise_cipher;
    2051          57 :         cipher_group = wpa_s->group_cipher;
    2052          84 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
    2053          27 :             wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    2054          30 :                 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
    2055          30 :                         use_crypt = 0;
    2056          30 :                 if (wpa_set_wep_keys(wpa_s, ssid)) {
    2057           8 :                         use_crypt = 1;
    2058           8 :                         wep_keys_set = 1;
    2059             :                 }
    2060             :         }
    2061          57 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
    2062           2 :                 use_crypt = 0;
    2063             : 
    2064             : #ifdef IEEE8021X_EAPOL
    2065          57 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    2066           0 :                 if ((ssid->eapol_flags &
    2067             :                      (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
    2068           0 :                       EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
    2069             :                     !wep_keys_set) {
    2070           0 :                         use_crypt = 0;
    2071             :                 } else {
    2072             :                         /* Assume that dynamic WEP-104 keys will be used and
    2073             :                          * set cipher suites in order for drivers to expect
    2074             :                          * encryption. */
    2075           0 :                         cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
    2076             :                 }
    2077             :         }
    2078             : #endif /* IEEE8021X_EAPOL */
    2079             : 
    2080          57 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
    2081             :                 /* Set the key before (and later after) association */
    2082           5 :                 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
    2083             :         }
    2084             : 
    2085          57 :         wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
    2086          57 :         if (bss) {
    2087          37 :                 params.ssid = bss->ssid;
    2088          37 :                 params.ssid_len = bss->ssid_len;
    2089          37 :                 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
    2090         252 :                         wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
    2091             :                                    MACSTR " freq=%u MHz based on scan results "
    2092             :                                    "(bssid_set=%d)",
    2093         216 :                                    MAC2STR(bss->bssid), bss->freq,
    2094             :                                    ssid->bssid_set);
    2095          36 :                         params.bssid = bss->bssid;
    2096          36 :                         params.freq.freq = bss->freq;
    2097             :                 }
    2098          37 :                 params.bssid_hint = bss->bssid;
    2099          37 :                 params.freq_hint = bss->freq;
    2100             :         } else {
    2101          20 :                 params.ssid = ssid->ssid;
    2102          20 :                 params.ssid_len = ssid->ssid_len;
    2103             :         }
    2104             : 
    2105          60 :         if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
    2106           3 :             wpa_s->conf->ap_scan == 2) {
    2107           3 :                 params.bssid = ssid->bssid;
    2108           3 :                 params.fixed_bssid = 1;
    2109             :         }
    2110             : 
    2111             :         /* Initial frequency for IBSS/mesh */
    2112          71 :         if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
    2113          28 :             ssid->frequency > 0 && params.freq.freq == 0)
    2114          14 :                 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
    2115             : 
    2116          57 :         if (ssid->mode == WPAS_MODE_IBSS) {
    2117          14 :                 if (ssid->beacon_int)
    2118           5 :                         params.beacon_int = ssid->beacon_int;
    2119             :                 else
    2120           9 :                         params.beacon_int = wpa_s->conf->beacon_int;
    2121             :         }
    2122             : 
    2123          57 :         params.wpa_ie = wpa_ie;
    2124          57 :         params.wpa_ie_len = wpa_ie_len;
    2125          57 :         params.pairwise_suite = cipher_pairwise;
    2126          57 :         params.group_suite = cipher_group;
    2127          57 :         params.key_mgmt_suite = wpa_s->key_mgmt;
    2128          57 :         params.wpa_proto = wpa_s->wpa_proto;
    2129          57 :         params.auth_alg = algs;
    2130          57 :         params.mode = ssid->mode;
    2131          57 :         params.bg_scan_period = ssid->bg_scan_period;
    2132         285 :         for (i = 0; i < NUM_WEP_KEYS; i++) {
    2133         228 :                 if (ssid->wep_key_len[i])
    2134           8 :                         params.wep_key[i] = ssid->wep_key[i];
    2135         228 :                 params.wep_key_len[i] = ssid->wep_key_len[i];
    2136             :         }
    2137          57 :         params.wep_tx_keyidx = ssid->wep_tx_keyidx;
    2138             : 
    2139          57 :         if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
    2140           0 :             (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    2141           0 :              params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
    2142           0 :                 params.passphrase = ssid->passphrase;
    2143           0 :                 if (ssid->psk_set)
    2144           0 :                         params.psk = ssid->psk;
    2145             :         }
    2146             : 
    2147          57 :         if (wpa_s->conf->key_mgmt_offload) {
    2148         106 :                 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
    2149          98 :                     params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
    2150          98 :                     params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
    2151          49 :                     params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
    2152           8 :                         params.req_key_mgmt_offload =
    2153           8 :                                 ssid->proactive_key_caching < 0 ?
    2154           8 :                                 wpa_s->conf->okc : ssid->proactive_key_caching;
    2155             :                 else
    2156          49 :                         params.req_key_mgmt_offload = 1;
    2157             : 
    2158         104 :                 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
    2159          93 :                      params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
    2160          57 :                      params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
    2161          11 :                     ssid->psk_set)
    2162          11 :                         params.psk = ssid->psk;
    2163             :         }
    2164             : 
    2165          57 :         params.drop_unencrypted = use_crypt;
    2166             : 
    2167             : #ifdef CONFIG_IEEE80211W
    2168          57 :         params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
    2169          57 :         if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
    2170           1 :                 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    2171             :                 struct wpa_ie_data ie;
    2172           2 :                 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
    2173           1 :                     ie.capabilities &
    2174             :                     (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
    2175           1 :                         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
    2176             :                                 "MFP: require MFP");
    2177           1 :                         params.mgmt_frame_protection =
    2178             :                                 MGMT_FRAME_PROTECTION_REQUIRED;
    2179             :                 }
    2180             :         }
    2181             : #endif /* CONFIG_IEEE80211W */
    2182             : 
    2183          57 :         params.p2p = ssid->p2p_group;
    2184             : 
    2185          57 :         if (wpa_s->parent->set_sta_uapsd)
    2186           0 :                 params.uapsd = wpa_s->parent->sta_uapsd;
    2187             :         else
    2188          57 :                 params.uapsd = -1;
    2189             : 
    2190             : #ifdef CONFIG_HT_OVERRIDES
    2191          57 :         os_memset(&htcaps, 0, sizeof(htcaps));
    2192          57 :         os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
    2193          57 :         params.htcaps = (u8 *) &htcaps;
    2194          57 :         params.htcaps_mask = (u8 *) &htcaps_mask;
    2195          57 :         wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
    2196             : #endif /* CONFIG_HT_OVERRIDES */
    2197             : #ifdef CONFIG_VHT_OVERRIDES
    2198          57 :         os_memset(&vhtcaps, 0, sizeof(vhtcaps));
    2199          57 :         os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
    2200          57 :         params.vhtcaps = &vhtcaps;
    2201          57 :         params.vhtcaps_mask = &vhtcaps_mask;
    2202          57 :         wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
    2203             : #endif /* CONFIG_VHT_OVERRIDES */
    2204             : 
    2205             : #ifdef CONFIG_P2P
    2206             :         /*
    2207             :          * If multi-channel concurrency is not supported, check for any
    2208             :          * frequency conflict. In case of any frequency conflict, remove the
    2209             :          * least prioritized connection.
    2210             :          */
    2211          57 :         if (wpa_s->num_multichan_concurrent < 2) {
    2212             :                 int freq, num;
    2213          57 :                 num = get_shared_radio_freqs(wpa_s, &freq, 1);
    2214          57 :                 if (num > 0 && freq > 0 && freq != params.freq.freq) {
    2215           0 :                         wpa_printf(MSG_DEBUG,
    2216             :                                    "Assoc conflicting freq found (%d != %d)",
    2217             :                                    freq, params.freq.freq);
    2218           0 :                         if (wpas_p2p_handle_frequency_conflicts(
    2219             :                                     wpa_s, params.freq.freq, ssid) < 0) {
    2220           0 :                                 wpas_connect_work_done(wpa_s);
    2221           0 :                                 return;
    2222             :                         }
    2223             :                 }
    2224             :         }
    2225             : #endif /* CONFIG_P2P */
    2226             : 
    2227          57 :         ret = wpa_drv_associate(wpa_s, &params);
    2228          57 :         if (ret < 0) {
    2229          15 :                 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
    2230             :                         "failed");
    2231          15 :                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
    2232             :                         /*
    2233             :                          * The driver is known to mean what is saying, so we
    2234             :                          * can stop right here; the association will not
    2235             :                          * succeed.
    2236             :                          */
    2237           0 :                         wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
    2238           0 :                         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
    2239           0 :                         os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
    2240           0 :                         return;
    2241             :                 }
    2242             :                 /* try to continue anyway; new association will be tried again
    2243             :                  * after timeout */
    2244          15 :                 assoc_failed = 1;
    2245             :         }
    2246             : 
    2247          57 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
    2248             :                 /* Set the key after the association just in case association
    2249             :                  * cleared the previously configured key. */
    2250           5 :                 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
    2251             :                 /* No need to timeout authentication since there is no key
    2252             :                  * management. */
    2253           5 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
    2254           5 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
    2255             : #ifdef CONFIG_IBSS_RSN
    2256          61 :         } else if (ssid->mode == WPAS_MODE_IBSS &&
    2257          13 :                    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
    2258           4 :                    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
    2259             :                 /*
    2260             :                  * RSN IBSS authentication is per-STA and we can disable the
    2261             :                  * per-BSSID authentication.
    2262             :                  */
    2263           4 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
    2264             : #endif /* CONFIG_IBSS_RSN */
    2265             :         } else {
    2266             :                 /* Timeout for IEEE 802.11 authentication and association */
    2267          48 :                 int timeout = 60;
    2268             : 
    2269          48 :                 if (assoc_failed) {
    2270             :                         /* give IBSS a bit more time */
    2271          15 :                         timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
    2272          33 :                 } else if (wpa_s->conf->ap_scan == 1) {
    2273             :                         /* give IBSS a bit more time */
    2274          22 :                         timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
    2275             :                 }
    2276          48 :                 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
    2277             :         }
    2278             : 
    2279          65 :         if (wep_keys_set &&
    2280           8 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
    2281             :                 /* Set static WEP keys again */
    2282           0 :                 wpa_set_wep_keys(wpa_s, ssid);
    2283             :         }
    2284             : 
    2285          57 :         if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
    2286             :                 /*
    2287             :                  * Do not allow EAP session resumption between different
    2288             :                  * network configurations.
    2289             :                  */
    2290           0 :                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
    2291             :         }
    2292          57 :         old_ssid = wpa_s->current_ssid;
    2293          57 :         wpa_s->current_ssid = ssid;
    2294          57 :         wpa_s->current_bss = bss;
    2295          57 :         wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
    2296          57 :         wpa_supplicant_initiate_eapol(wpa_s);
    2297          57 :         if (old_ssid != wpa_s->current_ssid)
    2298          17 :                 wpas_notify_network_changed(wpa_s);
    2299             : }
    2300             : 
    2301             : 
    2302        2343 : static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
    2303             :                                             const u8 *addr)
    2304             : {
    2305             :         struct wpa_ssid *old_ssid;
    2306             : 
    2307        2343 :         wpas_connect_work_done(wpa_s);
    2308        2343 :         wpa_clear_keys(wpa_s, addr);
    2309        2343 :         old_ssid = wpa_s->current_ssid;
    2310        2343 :         wpa_supplicant_mark_disassoc(wpa_s);
    2311        2343 :         wpa_sm_set_config(wpa_s->wpa, NULL);
    2312        2343 :         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
    2313        2343 :         if (old_ssid != wpa_s->current_ssid)
    2314         121 :                 wpas_notify_network_changed(wpa_s);
    2315        2343 :         eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
    2316        2343 : }
    2317             : 
    2318             : 
    2319             : /**
    2320             :  * wpa_supplicant_deauthenticate - Deauthenticate the current connection
    2321             :  * @wpa_s: Pointer to wpa_supplicant data
    2322             :  * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
    2323             :  *
    2324             :  * This function is used to request %wpa_supplicant to deauthenticate from the
    2325             :  * current AP.
    2326             :  */
    2327        2343 : void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
    2328             :                                    int reason_code)
    2329             : {
    2330        2343 :         u8 *addr = NULL;
    2331             :         union wpa_event_data event;
    2332        2343 :         int zero_addr = 0;
    2333             : 
    2334        2343 :         wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
    2335             :                 " pending_bssid=" MACSTR " reason=%d state=%s",
    2336             :                 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
    2337             :                 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
    2338             : 
    2339        2343 :         if (!is_zero_ether_addr(wpa_s->bssid))
    2340        2074 :                 addr = wpa_s->bssid;
    2341         287 :         else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
    2342          31 :                  (wpa_s->wpa_state == WPA_AUTHENTICATING ||
    2343          13 :                   wpa_s->wpa_state == WPA_ASSOCIATING))
    2344           7 :                 addr = wpa_s->pending_bssid;
    2345         262 :         else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
    2346             :                 /*
    2347             :                  * When using driver-based BSS selection, we may not know the
    2348             :                  * BSSID with which we are currently trying to associate. We
    2349             :                  * need to notify the driver of this disconnection even in such
    2350             :                  * a case, so use the all zeros address here.
    2351             :                  */
    2352           0 :                 addr = wpa_s->bssid;
    2353           0 :                 zero_addr = 1;
    2354             :         }
    2355             : 
    2356             : #ifdef CONFIG_TDLS
    2357        2343 :         wpa_tdls_teardown_peers(wpa_s->wpa);
    2358             : #endif /* CONFIG_TDLS */
    2359             : 
    2360             : #ifdef CONFIG_MESH
    2361        2343 :         if (wpa_s->ifmsh) {
    2362          28 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
    2363          28 :                              wpa_s->ifname);
    2364          28 :                 wpa_supplicant_leave_mesh(wpa_s);
    2365             :         }
    2366             : #endif /* CONFIG_MESH */
    2367             : 
    2368        2343 :         if (addr) {
    2369        2081 :                 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
    2370        2081 :                 os_memset(&event, 0, sizeof(event));
    2371        2081 :                 event.deauth_info.reason_code = (u16) reason_code;
    2372        2081 :                 event.deauth_info.locally_generated = 1;
    2373        2081 :                 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
    2374        2081 :                 if (zero_addr)
    2375           0 :                         addr = NULL;
    2376             :         }
    2377             : 
    2378        2343 :         wpa_supplicant_clear_connection(wpa_s, addr);
    2379        2343 : }
    2380             : 
    2381           7 : static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
    2382             :                                               struct wpa_ssid *ssid)
    2383             : {
    2384           7 :         if (!ssid || !ssid->disabled || ssid->disabled == 2)
    2385           7 :                 return;
    2386             : 
    2387           7 :         ssid->disabled = 0;
    2388           7 :         wpas_clear_temp_disabled(wpa_s, ssid, 1);
    2389           7 :         wpas_notify_network_enabled_changed(wpa_s, ssid);
    2390             : 
    2391             :         /*
    2392             :          * Try to reassociate since there is no current configuration and a new
    2393             :          * network was made available.
    2394             :          */
    2395           7 :         if (!wpa_s->current_ssid && !wpa_s->disconnected)
    2396           7 :                 wpa_s->reassociate = 1;
    2397             : }
    2398             : 
    2399             : 
    2400             : /**
    2401             :  * wpa_supplicant_enable_network - Mark a configured network as enabled
    2402             :  * @wpa_s: wpa_supplicant structure for a network interface
    2403             :  * @ssid: wpa_ssid structure for a configured network or %NULL
    2404             :  *
    2405             :  * Enables the specified network or all networks if no network specified.
    2406             :  */
    2407           7 : void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
    2408             :                                    struct wpa_ssid *ssid)
    2409             : {
    2410           7 :         if (ssid == NULL) {
    2411           2 :                 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
    2412           1 :                         wpa_supplicant_enable_one_network(wpa_s, ssid);
    2413             :         } else
    2414           6 :                 wpa_supplicant_enable_one_network(wpa_s, ssid);
    2415             : 
    2416           7 :         if (wpa_s->reassociate && !wpa_s->disconnected) {
    2417           7 :                 if (wpa_s->sched_scanning) {
    2418           0 :                         wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
    2419             :                                    "new network to scan filters");
    2420           0 :                         wpa_supplicant_cancel_sched_scan(wpa_s);
    2421             :                 }
    2422             : 
    2423           7 :                 if (wpa_supplicant_fast_associate(wpa_s) != 1)
    2424           5 :                         wpa_supplicant_req_scan(wpa_s, 0, 0);
    2425             :         }
    2426           7 : }
    2427             : 
    2428             : 
    2429             : /**
    2430             :  * wpa_supplicant_disable_network - Mark a configured network as disabled
    2431             :  * @wpa_s: wpa_supplicant structure for a network interface
    2432             :  * @ssid: wpa_ssid structure for a configured network or %NULL
    2433             :  *
    2434             :  * Disables the specified network or all networks if no network specified.
    2435             :  */
    2436           9 : void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
    2437             :                                     struct wpa_ssid *ssid)
    2438             : {
    2439             :         struct wpa_ssid *other_ssid;
    2440             :         int was_disabled;
    2441             : 
    2442           9 :         if (ssid == NULL) {
    2443           2 :                 if (wpa_s->sched_scanning)
    2444           0 :                         wpa_supplicant_cancel_sched_scan(wpa_s);
    2445             : 
    2446           6 :                 for (other_ssid = wpa_s->conf->ssid; other_ssid;
    2447           2 :                      other_ssid = other_ssid->next) {
    2448           2 :                         was_disabled = other_ssid->disabled;
    2449           2 :                         if (was_disabled == 2)
    2450           0 :                                 continue; /* do not change persistent P2P group
    2451             :                                            * data */
    2452             : 
    2453           2 :                         other_ssid->disabled = 1;
    2454             : 
    2455           2 :                         if (was_disabled != other_ssid->disabled)
    2456           2 :                                 wpas_notify_network_enabled_changed(
    2457             :                                         wpa_s, other_ssid);
    2458             :                 }
    2459           2 :                 if (wpa_s->current_ssid)
    2460           1 :                         wpa_supplicant_deauthenticate(
    2461             :                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    2462           7 :         } else if (ssid->disabled != 2) {
    2463           7 :                 if (ssid == wpa_s->current_ssid)
    2464           2 :                         wpa_supplicant_deauthenticate(
    2465             :                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    2466             : 
    2467           7 :                 was_disabled = ssid->disabled;
    2468             : 
    2469           7 :                 ssid->disabled = 1;
    2470             : 
    2471           7 :                 if (was_disabled != ssid->disabled) {
    2472           3 :                         wpas_notify_network_enabled_changed(wpa_s, ssid);
    2473           3 :                         if (wpa_s->sched_scanning) {
    2474           0 :                                 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
    2475             :                                            "to remove network from filters");
    2476           0 :                                 wpa_supplicant_cancel_sched_scan(wpa_s);
    2477           0 :                                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    2478             :                         }
    2479             :                 }
    2480             :         }
    2481           9 : }
    2482             : 
    2483             : 
    2484             : /**
    2485             :  * wpa_supplicant_select_network - Attempt association with a network
    2486             :  * @wpa_s: wpa_supplicant structure for a network interface
    2487             :  * @ssid: wpa_ssid structure for a configured network or %NULL for any network
    2488             :  */
    2489        1528 : void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
    2490             :                                    struct wpa_ssid *ssid)
    2491             : {
    2492             : 
    2493             :         struct wpa_ssid *other_ssid;
    2494        1528 :         int disconnected = 0;
    2495             : 
    2496        1528 :         if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
    2497           3 :                 wpa_supplicant_deauthenticate(
    2498             :                         wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    2499           3 :                 disconnected = 1;
    2500             :         }
    2501             : 
    2502        1528 :         if (ssid)
    2503        1526 :                 wpas_clear_temp_disabled(wpa_s, ssid, 1);
    2504             : 
    2505             :         /*
    2506             :          * Mark all other networks disabled or mark all networks enabled if no
    2507             :          * network specified.
    2508             :          */
    2509        4867 :         for (other_ssid = wpa_s->conf->ssid; other_ssid;
    2510        1811 :              other_ssid = other_ssid->next) {
    2511        1811 :                 int was_disabled = other_ssid->disabled;
    2512        1811 :                 if (was_disabled == 2)
    2513          32 :                         continue; /* do not change persistent P2P group data */
    2514             : 
    2515        1779 :                 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
    2516        1779 :                 if (was_disabled && !other_ssid->disabled)
    2517        1388 :                         wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
    2518             : 
    2519        1779 :                 if (was_disabled != other_ssid->disabled)
    2520        1438 :                         wpas_notify_network_enabled_changed(wpa_s, other_ssid);
    2521             :         }
    2522             : 
    2523        1528 :         if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
    2524             :                 /* We are already associated with the selected network */
    2525           0 :                 wpa_printf(MSG_DEBUG, "Already associated with the "
    2526             :                            "selected network - do nothing");
    2527        1528 :                 return;
    2528             :         }
    2529             : 
    2530        1528 :         if (ssid) {
    2531        1526 :                 wpa_s->current_ssid = ssid;
    2532        1526 :                 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
    2533        1526 :                 wpa_s->connect_without_scan =
    2534        1526 :                         (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
    2535             :         } else {
    2536           2 :                 wpa_s->connect_without_scan = NULL;
    2537             :         }
    2538             : 
    2539        1528 :         wpa_s->disconnected = 0;
    2540        1528 :         wpa_s->reassociate = 1;
    2541             : 
    2542        3027 :         if (wpa_s->connect_without_scan ||
    2543        1499 :             wpa_supplicant_fast_associate(wpa_s) != 1)
    2544         753 :                 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
    2545             : 
    2546        1528 :         if (ssid)
    2547        1526 :                 wpas_notify_network_selected(wpa_s, ssid);
    2548             : }
    2549             : 
    2550             : 
    2551             : /**
    2552             :  * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
    2553             :  * @wpa_s: wpa_supplicant structure for a network interface
    2554             :  * @pkcs11_engine_path: PKCS #11 engine path or NULL
    2555             :  * @pkcs11_module_path: PKCS #11 module path or NULL
    2556             :  * Returns: 0 on success; -1 on failure
    2557             :  *
    2558             :  * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
    2559             :  * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
    2560             :  * module path fails the paths will be reset to the default value (NULL).
    2561             :  */
    2562           4 : int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
    2563             :                                            const char *pkcs11_engine_path,
    2564             :                                            const char *pkcs11_module_path)
    2565             : {
    2566           4 :         char *pkcs11_engine_path_copy = NULL;
    2567           4 :         char *pkcs11_module_path_copy = NULL;
    2568             : 
    2569           4 :         if (pkcs11_engine_path != NULL) {
    2570           2 :                 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
    2571           2 :                 if (pkcs11_engine_path_copy == NULL)
    2572           0 :                         return -1;
    2573             :         }
    2574           4 :         if (pkcs11_module_path != NULL) {
    2575           2 :                 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
    2576           2 :                 if (pkcs11_module_path_copy == NULL) {
    2577           0 :                         os_free(pkcs11_engine_path_copy);
    2578           0 :                         return -1;
    2579             :                 }
    2580             :         }
    2581             : 
    2582           4 :         os_free(wpa_s->conf->pkcs11_engine_path);
    2583           4 :         os_free(wpa_s->conf->pkcs11_module_path);
    2584           4 :         wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
    2585           4 :         wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
    2586             : 
    2587           4 :         wpa_sm_set_eapol(wpa_s->wpa, NULL);
    2588           4 :         eapol_sm_deinit(wpa_s->eapol);
    2589           4 :         wpa_s->eapol = NULL;
    2590           4 :         if (wpa_supplicant_init_eapol(wpa_s)) {
    2591             :                 /* Error -> Reset paths to the default value (NULL) once. */
    2592           0 :                 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
    2593           0 :                         wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
    2594             :                                                                NULL);
    2595             : 
    2596           0 :                 return -1;
    2597             :         }
    2598           4 :         wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
    2599             : 
    2600           4 :         return 0;
    2601             : }
    2602             : 
    2603             : 
    2604             : /**
    2605             :  * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
    2606             :  * @wpa_s: wpa_supplicant structure for a network interface
    2607             :  * @ap_scan: AP scan mode
    2608             :  * Returns: 0 if succeed or -1 if ap_scan has an invalid value
    2609             :  *
    2610             :  */
    2611          20 : int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
    2612             : {
    2613             : 
    2614             :         int old_ap_scan;
    2615             : 
    2616          20 :         if (ap_scan < 0 || ap_scan > 2)
    2617           4 :                 return -1;
    2618             : 
    2619             : #ifdef ANDROID
    2620             :         if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
    2621             :             wpa_s->wpa_state >= WPA_ASSOCIATING &&
    2622             :             wpa_s->wpa_state < WPA_COMPLETED) {
    2623             :                 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
    2624             :                            "associating", wpa_s->conf->ap_scan, ap_scan);
    2625             :                 return 0;
    2626             :         }
    2627             : #endif /* ANDROID */
    2628             : 
    2629          16 :         old_ap_scan = wpa_s->conf->ap_scan;
    2630          16 :         wpa_s->conf->ap_scan = ap_scan;
    2631             : 
    2632          16 :         if (old_ap_scan != wpa_s->conf->ap_scan)
    2633          14 :                 wpas_notify_ap_scan_changed(wpa_s);
    2634             : 
    2635          16 :         return 0;
    2636             : }
    2637             : 
    2638             : 
    2639             : /**
    2640             :  * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
    2641             :  * @wpa_s: wpa_supplicant structure for a network interface
    2642             :  * @expire_age: Expiration age in seconds
    2643             :  * Returns: 0 if succeed or -1 if expire_age has an invalid value
    2644             :  *
    2645             :  */
    2646           6 : int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
    2647             :                                           unsigned int bss_expire_age)
    2648             : {
    2649           6 :         if (bss_expire_age < 10) {
    2650           2 :                 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
    2651             :                         bss_expire_age);
    2652           2 :                 return -1;
    2653             :         }
    2654           4 :         wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
    2655             :                 bss_expire_age);
    2656           4 :         wpa_s->conf->bss_expiration_age = bss_expire_age;
    2657             : 
    2658           4 :         return 0;
    2659             : }
    2660             : 
    2661             : 
    2662             : /**
    2663             :  * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
    2664             :  * @wpa_s: wpa_supplicant structure for a network interface
    2665             :  * @expire_count: number of scans after which an unseen BSS is reclaimed
    2666             :  * Returns: 0 if succeed or -1 if expire_count has an invalid value
    2667             :  *
    2668             :  */
    2669           5 : int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
    2670             :                                             unsigned int bss_expire_count)
    2671             : {
    2672           5 :         if (bss_expire_count < 1) {
    2673           2 :                 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
    2674             :                         bss_expire_count);
    2675           2 :                 return -1;
    2676             :         }
    2677           3 :         wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
    2678             :                 bss_expire_count);
    2679           3 :         wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
    2680             : 
    2681           3 :         return 0;
    2682             : }
    2683             : 
    2684             : 
    2685             : /**
    2686             :  * wpa_supplicant_set_scan_interval - Set scan interval
    2687             :  * @wpa_s: wpa_supplicant structure for a network interface
    2688             :  * @scan_interval: scan interval in seconds
    2689             :  * Returns: 0 if succeed or -1 if scan_interval has an invalid value
    2690             :  *
    2691             :  */
    2692          21 : int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
    2693             :                                      int scan_interval)
    2694             : {
    2695          21 :         if (scan_interval < 0) {
    2696           2 :                 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
    2697             :                         scan_interval);
    2698           2 :                 return -1;
    2699             :         }
    2700          19 :         wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
    2701             :                 scan_interval);
    2702          19 :         wpa_supplicant_update_scan_int(wpa_s, scan_interval);
    2703             : 
    2704          19 :         return 0;
    2705             : }
    2706             : 
    2707             : 
    2708             : /**
    2709             :  * wpa_supplicant_set_debug_params - Set global debug params
    2710             :  * @global: wpa_global structure
    2711             :  * @debug_level: debug level
    2712             :  * @debug_timestamp: determines if show timestamp in debug data
    2713             :  * @debug_show_keys: determines if show keys in debug data
    2714             :  * Returns: 0 if succeed or -1 if debug_level has wrong value
    2715             :  */
    2716           8 : int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
    2717             :                                     int debug_timestamp, int debug_show_keys)
    2718             : {
    2719             : 
    2720             :         int old_level, old_timestamp, old_show_keys;
    2721             : 
    2722             :         /* check for allowed debuglevels */
    2723           8 :         if (debug_level != MSG_EXCESSIVE &&
    2724           2 :             debug_level != MSG_MSGDUMP &&
    2725           1 :             debug_level != MSG_DEBUG &&
    2726           1 :             debug_level != MSG_INFO &&
    2727           1 :             debug_level != MSG_WARNING &&
    2728             :             debug_level != MSG_ERROR)
    2729           1 :                 return -1;
    2730             : 
    2731           7 :         old_level = wpa_debug_level;
    2732           7 :         old_timestamp = wpa_debug_timestamp;
    2733           7 :         old_show_keys = wpa_debug_show_keys;
    2734             : 
    2735           7 :         wpa_debug_level = debug_level;
    2736           7 :         wpa_debug_timestamp = debug_timestamp ? 1 : 0;
    2737           7 :         wpa_debug_show_keys = debug_show_keys ? 1 : 0;
    2738             : 
    2739           7 :         if (wpa_debug_level != old_level)
    2740           2 :                 wpas_notify_debug_level_changed(global);
    2741           7 :         if (wpa_debug_timestamp != old_timestamp)
    2742           2 :                 wpas_notify_debug_timestamp_changed(global);
    2743           7 :         if (wpa_debug_show_keys != old_show_keys)
    2744           2 :                 wpas_notify_debug_show_keys_changed(global);
    2745             : 
    2746           7 :         return 0;
    2747             : }
    2748             : 
    2749             : 
    2750             : /**
    2751             :  * wpa_supplicant_get_ssid - Get a pointer to the current network structure
    2752             :  * @wpa_s: Pointer to wpa_supplicant data
    2753             :  * Returns: A pointer to the current network structure or %NULL on failure
    2754             :  */
    2755        1339 : struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
    2756             : {
    2757             :         struct wpa_ssid *entry;
    2758             :         u8 ssid[MAX_SSID_LEN];
    2759             :         int res;
    2760             :         size_t ssid_len;
    2761             :         u8 bssid[ETH_ALEN];
    2762             :         int wired;
    2763             : 
    2764        1339 :         res = wpa_drv_get_ssid(wpa_s, ssid);
    2765        1339 :         if (res < 0) {
    2766           1 :                 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
    2767             :                         "driver");
    2768           1 :                 return NULL;
    2769             :         }
    2770        1338 :         ssid_len = res;
    2771             : 
    2772        1338 :         if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
    2773           0 :                 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
    2774             :                         "driver");
    2775           0 :                 return NULL;
    2776             :         }
    2777             : 
    2778        1340 :         wired = wpa_s->conf->ap_scan == 0 &&
    2779           2 :                 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
    2780             : 
    2781        1338 :         entry = wpa_s->conf->ssid;
    2782        2880 :         while (entry) {
    2783        2879 :                 if (!wpas_network_disabled(wpa_s, entry) &&
    2784        2672 :                     ((ssid_len == entry->ssid_len &&
    2785        2672 :                       os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
    2786        1499 :                     (!entry->bssid_set ||
    2787         168 :                      os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
    2788        1331 :                         return entry;
    2789             : #ifdef CONFIG_WPS
    2790         217 :                 if (!wpas_network_disabled(wpa_s, entry) &&
    2791          11 :                     (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
    2792           2 :                     (entry->ssid == NULL || entry->ssid_len == 0) &&
    2793           2 :                     (!entry->bssid_set ||
    2794           1 :                      os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
    2795           1 :                         return entry;
    2796             : #endif /* CONFIG_WPS */
    2797             : 
    2798         209 :                 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
    2799           5 :                     entry->ssid_len == 0 &&
    2800           2 :                     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
    2801           2 :                         return entry;
    2802             : 
    2803         204 :                 entry = entry->next;
    2804             :         }
    2805             : 
    2806           4 :         return NULL;
    2807             : }
    2808             : 
    2809             : 
    2810         203 : static int select_driver(struct wpa_supplicant *wpa_s, int i)
    2811             : {
    2812         203 :         struct wpa_global *global = wpa_s->global;
    2813             : 
    2814         203 :         if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
    2815          20 :                 global->drv_priv[i] = wpa_drivers[i]->global_init();
    2816          20 :                 if (global->drv_priv[i] == NULL) {
    2817           0 :                         wpa_printf(MSG_ERROR, "Failed to initialize driver "
    2818           0 :                                    "'%s'", wpa_drivers[i]->name);
    2819           0 :                         return -1;
    2820             :                 }
    2821             :         }
    2822             : 
    2823         203 :         wpa_s->driver = wpa_drivers[i];
    2824         203 :         wpa_s->global_drv_priv = global->drv_priv[i];
    2825             : 
    2826         203 :         return 0;
    2827             : }
    2828             : 
    2829             : 
    2830         203 : static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
    2831             :                                      const char *name)
    2832             : {
    2833             :         int i;
    2834             :         size_t len;
    2835         203 :         const char *pos, *driver = name;
    2836             : 
    2837         203 :         if (wpa_s == NULL)
    2838           0 :                 return -1;
    2839             : 
    2840         203 :         if (wpa_drivers[0] == NULL) {
    2841           0 :                 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
    2842             :                         "wpa_supplicant");
    2843           0 :                 return -1;
    2844             :         }
    2845             : 
    2846         203 :         if (name == NULL) {
    2847             :                 /* default to first driver in the list */
    2848           3 :                 return select_driver(wpa_s, 0);
    2849             :         }
    2850             : 
    2851             :         do {
    2852         200 :                 pos = os_strchr(driver, ',');
    2853         200 :                 if (pos)
    2854           0 :                         len = pos - driver;
    2855             :                 else
    2856         200 :                         len = os_strlen(driver);
    2857             : 
    2858         286 :                 for (i = 0; wpa_drivers[i]; i++) {
    2859         524 :                         if (os_strlen(wpa_drivers[i]->name) == len &&
    2860         238 :                             os_strncmp(driver, wpa_drivers[i]->name, len) ==
    2861             :                             0) {
    2862             :                                 /* First driver that succeeds wins */
    2863         200 :                                 if (select_driver(wpa_s, i) == 0)
    2864         200 :                                         return 0;
    2865             :                         }
    2866             :                 }
    2867             : 
    2868           0 :                 driver = pos + 1;
    2869           0 :         } while (pos);
    2870             : 
    2871           0 :         wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
    2872           0 :         return -1;
    2873             : }
    2874             : 
    2875             : 
    2876             : /**
    2877             :  * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
    2878             :  * @ctx: Context pointer (wpa_s); this is the ctx variable registered
    2879             :  *      with struct wpa_driver_ops::init()
    2880             :  * @src_addr: Source address of the EAPOL frame
    2881             :  * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
    2882             :  * @len: Length of the EAPOL data
    2883             :  *
    2884             :  * This function is called for each received EAPOL frame. Most driver
    2885             :  * interfaces rely on more generic OS mechanism for receiving frames through
    2886             :  * l2_packet, but if such a mechanism is not available, the driver wrapper may
    2887             :  * take care of received EAPOL frames and deliver them to the core supplicant
    2888             :  * code by calling this function.
    2889             :  */
    2890       10661 : void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
    2891             :                              const u8 *buf, size_t len)
    2892             : {
    2893       10661 :         struct wpa_supplicant *wpa_s = ctx;
    2894             : 
    2895       10661 :         wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
    2896       10661 :         wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
    2897             : 
    2898             : #ifdef CONFIG_PEERKEY
    2899       13871 :         if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
    2900        3228 :             wpa_s->current_ssid->peerkey &&
    2901          36 :             !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
    2902          18 :             wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
    2903           4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
    2904           4 :                 return;
    2905             :         }
    2906             : #endif /* CONFIG_PEERKEY */
    2907             : 
    2908       21310 :         if (wpa_s->wpa_state < WPA_ASSOCIATED ||
    2909       17978 :             (wpa_s->last_eapol_matches_bssid &&
    2910             : #ifdef CONFIG_AP
    2911       14601 :              !wpa_s->ap_iface &&
    2912             : #endif /* CONFIG_AP */
    2913        7276 :              os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
    2914             :                 /*
    2915             :                  * There is possible race condition between receiving the
    2916             :                  * association event and the EAPOL frame since they are coming
    2917             :                  * through different paths from the driver. In order to avoid
    2918             :                  * issues in trying to process the EAPOL frame before receiving
    2919             :                  * association information, lets queue it for processing until
    2920             :                  * the association event is received. This may also be needed in
    2921             :                  * driver-based roaming case, so also use src_addr != BSSID as a
    2922             :                  * trigger if we have previously confirmed that the
    2923             :                  * Authenticator uses BSSID as the src_addr (which is not the
    2924             :                  * case with wired IEEE 802.1X).
    2925             :                  */
    2926           4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
    2927             :                         "of received EAPOL frame (state=%s bssid=" MACSTR ")",
    2928             :                         wpa_supplicant_state_txt(wpa_s->wpa_state),
    2929             :                         MAC2STR(wpa_s->bssid));
    2930           4 :                 wpabuf_free(wpa_s->pending_eapol_rx);
    2931           4 :                 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
    2932           4 :                 if (wpa_s->pending_eapol_rx) {
    2933           4 :                         os_get_reltime(&wpa_s->pending_eapol_rx_time);
    2934           4 :                         os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
    2935             :                                   ETH_ALEN);
    2936             :                 }
    2937           4 :                 return;
    2938             :         }
    2939             : 
    2940       10653 :         wpa_s->last_eapol_matches_bssid =
    2941       10653 :                 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
    2942             : 
    2943             : #ifdef CONFIG_AP
    2944       10653 :         if (wpa_s->ap_iface) {
    2945        1423 :                 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
    2946        1423 :                 return;
    2947             :         }
    2948             : #endif /* CONFIG_AP */
    2949             : 
    2950        9230 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
    2951           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
    2952             :                         "no key management is configured");
    2953           0 :                 return;
    2954             :         }
    2955             : 
    2956       11144 :         if (wpa_s->eapol_received == 0 &&
    2957        1914 :             (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
    2958           0 :              !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
    2959        1914 :              wpa_s->wpa_state != WPA_COMPLETED) &&
    2960        3828 :             (wpa_s->current_ssid == NULL ||
    2961        1914 :              wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
    2962             :                 /* Timeout for completing IEEE 802.1X and WPA authentication */
    2963        3169 :                 wpa_supplicant_req_auth_timeout(
    2964             :                         wpa_s,
    2965        2851 :                         (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
    2966        1872 :                          wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
    2967         931 :                          wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
    2968             :                         70 : 10, 0);
    2969             :         }
    2970        9230 :         wpa_s->eapol_received++;
    2971             : 
    2972        9230 :         if (wpa_s->countermeasures) {
    2973           0 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
    2974             :                         "EAPOL packet");
    2975           0 :                 return;
    2976             :         }
    2977             : 
    2978             : #ifdef CONFIG_IBSS_RSN
    2979       18459 :         if (wpa_s->current_ssid &&
    2980        9229 :             wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
    2981          44 :                 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
    2982          44 :                 return;
    2983             :         }
    2984             : #endif /* CONFIG_IBSS_RSN */
    2985             : 
    2986             :         /* Source address of the incoming EAPOL frame could be compared to the
    2987             :          * current BSSID. However, it is possible that a centralized
    2988             :          * Authenticator could be using another MAC address than the BSSID of
    2989             :          * an AP, so just allow any address to be used for now. The replies are
    2990             :          * still sent to the current BSSID (if available), though. */
    2991             : 
    2992        9186 :         os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
    2993       17014 :         if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
    2994        7828 :             eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
    2995        6558 :                 return;
    2996        2628 :         wpa_drv_poll(wpa_s);
    2997        2628 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
    2998        2628 :                 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
    2999           0 :         else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
    3000             :                 /*
    3001             :                  * Set portValid = TRUE here since we are going to skip 4-way
    3002             :                  * handshake processing which would normally set portValid. We
    3003             :                  * need this to allow the EAPOL state machines to be completed
    3004             :                  * without going through EAPOL-Key handshake.
    3005             :                  */
    3006           0 :                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
    3007             :         }
    3008             : }
    3009             : 
    3010             : 
    3011         217 : int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
    3012             : {
    3013         222 :         if ((!wpa_s->p2p_mgmt ||
    3014         217 :              !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
    3015         212 :             !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
    3016         212 :                 l2_packet_deinit(wpa_s->l2);
    3017         212 :                 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
    3018             :                                            wpa_drv_get_mac_addr(wpa_s),
    3019             :                                            ETH_P_EAPOL,
    3020             :                                            wpa_supplicant_rx_eapol, wpa_s, 0);
    3021         423 :                 if (wpa_s->l2 == NULL)
    3022           1 :                         return -1;
    3023             :         } else {
    3024           5 :                 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
    3025           5 :                 if (addr)
    3026           5 :                         os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
    3027             :         }
    3028             : 
    3029         216 :         if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
    3030           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
    3031           0 :                 return -1;
    3032             :         }
    3033             : 
    3034         216 :         wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
    3035             : 
    3036         216 :         return 0;
    3037             : }
    3038             : 
    3039             : 
    3040           4 : static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
    3041             :                                            const u8 *buf, size_t len)
    3042             : {
    3043           4 :         struct wpa_supplicant *wpa_s = ctx;
    3044             :         const struct l2_ethhdr *eth;
    3045             : 
    3046           4 :         if (len < sizeof(*eth))
    3047           0 :                 return;
    3048           4 :         eth = (const struct l2_ethhdr *) buf;
    3049             : 
    3050           6 :         if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
    3051           2 :             !(eth->h_dest[0] & 0x01)) {
    3052           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
    3053             :                         " (bridge - not for this interface - ignore)",
    3054             :                         MAC2STR(src_addr), MAC2STR(eth->h_dest));
    3055           2 :                 return;
    3056             :         }
    3057             : 
    3058           2 :         wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
    3059             :                 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
    3060           2 :         wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
    3061             :                                 len - sizeof(*eth));
    3062             : }
    3063             : 
    3064             : 
    3065             : /**
    3066             :  * wpa_supplicant_driver_init - Initialize driver interface parameters
    3067             :  * @wpa_s: Pointer to wpa_supplicant data
    3068             :  * Returns: 0 on success, -1 on failure
    3069             :  *
    3070             :  * This function is called to initialize driver interface parameters.
    3071             :  * wpa_drv_init() must have been called before this function to initialize the
    3072             :  * driver interface.
    3073             :  */
    3074         195 : int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
    3075             : {
    3076             :         static int interface_count = 0;
    3077             : 
    3078         195 :         if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
    3079           1 :                 return -1;
    3080             : 
    3081         194 :         wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
    3082             :                 MAC2STR(wpa_s->own_addr));
    3083         194 :         os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
    3084         194 :         wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
    3085             : 
    3086         194 :         if (wpa_s->bridge_ifname[0]) {
    3087           3 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
    3088             :                         "interface '%s'", wpa_s->bridge_ifname);
    3089           3 :                 wpa_s->l2_br = l2_packet_init_bridge(
    3090           3 :                         wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
    3091             :                         ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
    3092           3 :                 if (wpa_s->l2_br == NULL) {
    3093           1 :                         wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
    3094             :                                 "connection for the bridge interface '%s'",
    3095           1 :                                 wpa_s->bridge_ifname);
    3096           1 :                         return -1;
    3097             :                 }
    3098             :         }
    3099             : 
    3100         193 :         wpa_clear_keys(wpa_s, NULL);
    3101             : 
    3102             :         /* Make sure that TKIP countermeasures are not left enabled (could
    3103             :          * happen if wpa_supplicant is killed during countermeasures. */
    3104         193 :         wpa_drv_set_countermeasures(wpa_s, 0);
    3105             : 
    3106         193 :         wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
    3107         193 :         wpa_drv_flush_pmkid(wpa_s);
    3108             : 
    3109         193 :         wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
    3110         193 :         wpa_s->prev_scan_wildcard = 0;
    3111             : 
    3112         193 :         if (wpa_supplicant_enabled_networks(wpa_s)) {
    3113           0 :                 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    3114           0 :                         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
    3115           0 :                         interface_count = 0;
    3116             :                 }
    3117             : #ifndef ANDROID
    3118           0 :                 if (!wpa_s->p2p_mgmt &&
    3119           0 :                     wpa_supplicant_delayed_sched_scan(wpa_s,
    3120             :                                                       interface_count % 3,
    3121             :                                                       100000))
    3122           0 :                         wpa_supplicant_req_scan(wpa_s, interface_count % 3,
    3123             :                                                 100000);
    3124             : #endif /* ANDROID */
    3125           0 :                 interface_count++;
    3126             :         } else
    3127         193 :                 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
    3128             : 
    3129         193 :         return 0;
    3130             : }
    3131             : 
    3132             : 
    3133           0 : static int wpa_supplicant_daemon(const char *pid_file)
    3134             : {
    3135           0 :         wpa_printf(MSG_DEBUG, "Daemonize..");
    3136           0 :         return os_daemonize(pid_file);
    3137             : }
    3138             : 
    3139             : 
    3140         213 : static struct wpa_supplicant * wpa_supplicant_alloc(void)
    3141             : {
    3142             :         struct wpa_supplicant *wpa_s;
    3143             : 
    3144         213 :         wpa_s = os_zalloc(sizeof(*wpa_s));
    3145         213 :         if (wpa_s == NULL)
    3146           1 :                 return NULL;
    3147         212 :         wpa_s->scan_req = INITIAL_SCAN_REQ;
    3148         212 :         wpa_s->scan_interval = 5;
    3149         212 :         wpa_s->new_connection = 1;
    3150         212 :         wpa_s->parent = wpa_s;
    3151         212 :         wpa_s->sched_scanning = 0;
    3152             : 
    3153         212 :         return wpa_s;
    3154             : }
    3155             : 
    3156             : 
    3157             : #ifdef CONFIG_HT_OVERRIDES
    3158             : 
    3159        2486 : static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
    3160             :                              struct ieee80211_ht_capabilities *htcaps,
    3161             :                              struct ieee80211_ht_capabilities *htcaps_mask,
    3162             :                              const char *ht_mcs)
    3163             : {
    3164             :         /* parse ht_mcs into hex array */
    3165             :         int i;
    3166        2486 :         const char *tmp = ht_mcs;
    3167        2486 :         char *end = NULL;
    3168             : 
    3169             :         /* If ht_mcs is null, do not set anything */
    3170        2486 :         if (!ht_mcs)
    3171        2485 :                 return 0;
    3172             : 
    3173             :         /* This is what we are setting in the kernel */
    3174           1 :         os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
    3175             : 
    3176           1 :         wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
    3177             : 
    3178          11 :         for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
    3179          10 :                 errno = 0;
    3180          10 :                 long v = strtol(tmp, &end, 16);
    3181          10 :                 if (errno == 0) {
    3182          10 :                         wpa_msg(wpa_s, MSG_DEBUG,
    3183             :                                 "htcap value[%i]: %ld end: %p  tmp: %p",
    3184             :                                 i, v, end, tmp);
    3185          10 :                         if (end == tmp)
    3186           0 :                                 break;
    3187             : 
    3188          10 :                         htcaps->supported_mcs_set[i] = v;
    3189          10 :                         tmp = end;
    3190             :                 } else {
    3191           0 :                         wpa_msg(wpa_s, MSG_ERROR,
    3192             :                                 "Failed to parse ht-mcs: %s, error: %s\n",
    3193           0 :                                 ht_mcs, strerror(errno));
    3194           0 :                         return -1;
    3195             :                 }
    3196             :         }
    3197             : 
    3198             :         /*
    3199             :          * If we were able to parse any values, then set mask for the MCS set.
    3200             :          */
    3201           1 :         if (i) {
    3202           1 :                 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
    3203             :                           IEEE80211_HT_MCS_MASK_LEN - 1);
    3204             :                 /* skip the 3 reserved bits */
    3205           1 :                 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
    3206             :                         0x1f;
    3207             :         }
    3208             : 
    3209           1 :         return 0;
    3210             : }
    3211             : 
    3212             : 
    3213        2486 : static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
    3214             :                                  struct ieee80211_ht_capabilities *htcaps,
    3215             :                                  struct ieee80211_ht_capabilities *htcaps_mask,
    3216             :                                  int disabled)
    3217             : {
    3218             :         le16 msk;
    3219             : 
    3220        2486 :         wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
    3221             : 
    3222        2486 :         if (disabled == -1)
    3223        2485 :                 return 0;
    3224             : 
    3225           1 :         msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
    3226           1 :         htcaps_mask->ht_capabilities_info |= msk;
    3227           1 :         if (disabled)
    3228           1 :                 htcaps->ht_capabilities_info &= msk;
    3229             :         else
    3230           0 :                 htcaps->ht_capabilities_info |= msk;
    3231             : 
    3232           1 :         return 0;
    3233             : }
    3234             : 
    3235             : 
    3236        2486 : static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
    3237             :                                 struct ieee80211_ht_capabilities *htcaps,
    3238             :                                 struct ieee80211_ht_capabilities *htcaps_mask,
    3239             :                                 int factor)
    3240             : {
    3241        2486 :         wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
    3242             : 
    3243        2486 :         if (factor == -1)
    3244        2485 :                 return 0;
    3245             : 
    3246           1 :         if (factor < 0 || factor > 3) {
    3247           0 :                 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
    3248             :                         "Must be 0-3 or -1", factor);
    3249           0 :                 return -EINVAL;
    3250             :         }
    3251             : 
    3252           1 :         htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
    3253           1 :         htcaps->a_mpdu_params &= ~0x3;
    3254           1 :         htcaps->a_mpdu_params |= factor & 0x3;
    3255             : 
    3256           1 :         return 0;
    3257             : }
    3258             : 
    3259             : 
    3260        2486 : static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
    3261             :                                  struct ieee80211_ht_capabilities *htcaps,
    3262             :                                  struct ieee80211_ht_capabilities *htcaps_mask,
    3263             :                                  int density)
    3264             : {
    3265        2486 :         wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
    3266             : 
    3267        2486 :         if (density == -1)
    3268        2485 :                 return 0;
    3269             : 
    3270           1 :         if (density < 0 || density > 7) {
    3271           0 :                 wpa_msg(wpa_s, MSG_ERROR,
    3272             :                         "ampdu_density: %d out of range. Must be 0-7 or -1.",
    3273             :                         density);
    3274           0 :                 return -EINVAL;
    3275             :         }
    3276             : 
    3277           1 :         htcaps_mask->a_mpdu_params |= 0x1C;
    3278           1 :         htcaps->a_mpdu_params &= ~(0x1C);
    3279           1 :         htcaps->a_mpdu_params |= (density << 2) & 0x1C;
    3280             : 
    3281           1 :         return 0;
    3282             : }
    3283             : 
    3284             : 
    3285        2486 : static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
    3286             :                                 struct ieee80211_ht_capabilities *htcaps,
    3287             :                                 struct ieee80211_ht_capabilities *htcaps_mask,
    3288             :                                 int disabled)
    3289             : {
    3290             :         /* Masking these out disables HT40 */
    3291        2486 :         le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
    3292             :                                 HT_CAP_INFO_SHORT_GI40MHZ);
    3293             : 
    3294        2486 :         wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
    3295             : 
    3296        2486 :         if (disabled)
    3297           1 :                 htcaps->ht_capabilities_info &= ~msk;
    3298             :         else
    3299        2485 :                 htcaps->ht_capabilities_info |= msk;
    3300             : 
    3301        2486 :         htcaps_mask->ht_capabilities_info |= msk;
    3302             : 
    3303        2486 :         return 0;
    3304             : }
    3305             : 
    3306             : 
    3307        2486 : static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
    3308             :                                struct ieee80211_ht_capabilities *htcaps,
    3309             :                                struct ieee80211_ht_capabilities *htcaps_mask,
    3310             :                                int disabled)
    3311             : {
    3312             :         /* Masking these out disables SGI */
    3313        2486 :         le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
    3314             :                                 HT_CAP_INFO_SHORT_GI40MHZ);
    3315             : 
    3316        2486 :         wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
    3317             : 
    3318        2486 :         if (disabled)
    3319           1 :                 htcaps->ht_capabilities_info &= ~msk;
    3320             :         else
    3321        2485 :                 htcaps->ht_capabilities_info |= msk;
    3322             : 
    3323        2486 :         htcaps_mask->ht_capabilities_info |= msk;
    3324             : 
    3325        2486 :         return 0;
    3326             : }
    3327             : 
    3328             : 
    3329        2486 : static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
    3330             :                                struct ieee80211_ht_capabilities *htcaps,
    3331             :                                struct ieee80211_ht_capabilities *htcaps_mask,
    3332             :                                int disabled)
    3333             : {
    3334             :         /* Masking these out disables LDPC */
    3335        2486 :         le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
    3336             : 
    3337        2486 :         wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
    3338             : 
    3339        2486 :         if (disabled)
    3340           1 :                 htcaps->ht_capabilities_info &= ~msk;
    3341             :         else
    3342        2485 :                 htcaps->ht_capabilities_info |= msk;
    3343             : 
    3344        2486 :         htcaps_mask->ht_capabilities_info |= msk;
    3345             : 
    3346        2486 :         return 0;
    3347             : }
    3348             : 
    3349             : 
    3350        2486 : void wpa_supplicant_apply_ht_overrides(
    3351             :         struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
    3352             :         struct wpa_driver_associate_params *params)
    3353             : {
    3354             :         struct ieee80211_ht_capabilities *htcaps;
    3355             :         struct ieee80211_ht_capabilities *htcaps_mask;
    3356             : 
    3357        2486 :         if (!ssid)
    3358           0 :                 return;
    3359             : 
    3360        2486 :         params->disable_ht = ssid->disable_ht;
    3361        2486 :         if (!params->htcaps || !params->htcaps_mask)
    3362           0 :                 return;
    3363             : 
    3364        2486 :         htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
    3365        2486 :         htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
    3366        2486 :         wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
    3367        2486 :         wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
    3368             :                               ssid->disable_max_amsdu);
    3369        2486 :         wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
    3370        2486 :         wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
    3371        2486 :         wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
    3372        2486 :         wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
    3373        2486 :         wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
    3374             : 
    3375        2486 :         if (ssid->ht40_intolerant) {
    3376           1 :                 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
    3377           1 :                 htcaps->ht_capabilities_info |= bit;
    3378           1 :                 htcaps_mask->ht_capabilities_info |= bit;
    3379             :         }
    3380             : }
    3381             : 
    3382             : #endif /* CONFIG_HT_OVERRIDES */
    3383             : 
    3384             : 
    3385             : #ifdef CONFIG_VHT_OVERRIDES
    3386        2486 : void wpa_supplicant_apply_vht_overrides(
    3387             :         struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
    3388             :         struct wpa_driver_associate_params *params)
    3389             : {
    3390             :         struct ieee80211_vht_capabilities *vhtcaps;
    3391             :         struct ieee80211_vht_capabilities *vhtcaps_mask;
    3392             : 
    3393        2486 :         if (!ssid)
    3394           0 :                 return;
    3395             : 
    3396        2486 :         params->disable_vht = ssid->disable_vht;
    3397             : 
    3398        2486 :         vhtcaps = (void *) params->vhtcaps;
    3399        2486 :         vhtcaps_mask = (void *) params->vhtcaps_mask;
    3400             : 
    3401        2486 :         if (!vhtcaps || !vhtcaps_mask)
    3402           0 :                 return;
    3403             : 
    3404        2486 :         vhtcaps->vht_capabilities_info = ssid->vht_capa;
    3405        2486 :         vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
    3406             : 
    3407             : #ifdef CONFIG_HT_OVERRIDES
    3408             :         /* if max ampdu is <= 3, we have to make the HT cap the same */
    3409        2486 :         if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
    3410             :                 int max_ampdu;
    3411             : 
    3412           0 :                 max_ampdu = (ssid->vht_capa &
    3413           0 :                              VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
    3414             :                         VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
    3415             : 
    3416           0 :                 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
    3417           0 :                 wpa_set_ampdu_factor(wpa_s,
    3418           0 :                                      (void *) params->htcaps,
    3419           0 :                                      (void *) params->htcaps_mask,
    3420             :                                      max_ampdu);
    3421             :         }
    3422             : #endif /* CONFIG_HT_OVERRIDES */
    3423             : 
    3424             : #define OVERRIDE_MCS(i)                                                 \
    3425             :         if (ssid->vht_tx_mcs_nss_ ##i >= 0) {                             \
    3426             :                 vhtcaps_mask->vht_supported_mcs_set.tx_map |=                \
    3427             :                         3 << 2 * (i - 1);                         \
    3428             :                 vhtcaps->vht_supported_mcs_set.tx_map |=             \
    3429             :                         ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1);      \
    3430             :         }                                                               \
    3431             :         if (ssid->vht_rx_mcs_nss_ ##i >= 0) {                             \
    3432             :                 vhtcaps_mask->vht_supported_mcs_set.rx_map |=                \
    3433             :                         3 << 2 * (i - 1);                         \
    3434             :                 vhtcaps->vht_supported_mcs_set.rx_map |=             \
    3435             :                         ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1);      \
    3436             :         }
    3437             : 
    3438        2486 :         OVERRIDE_MCS(1);
    3439        2486 :         OVERRIDE_MCS(2);
    3440        2486 :         OVERRIDE_MCS(3);
    3441        2486 :         OVERRIDE_MCS(4);
    3442        2486 :         OVERRIDE_MCS(5);
    3443        2486 :         OVERRIDE_MCS(6);
    3444        2486 :         OVERRIDE_MCS(7);
    3445        2486 :         OVERRIDE_MCS(8);
    3446             : }
    3447             : #endif /* CONFIG_VHT_OVERRIDES */
    3448             : 
    3449             : 
    3450         184 : static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
    3451             : {
    3452             : #ifdef PCSC_FUNCS
    3453             :         size_t len;
    3454             : 
    3455             :         if (!wpa_s->conf->pcsc_reader)
    3456             :                 return 0;
    3457             : 
    3458             :         wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
    3459             :         if (!wpa_s->scard)
    3460             :                 return 1;
    3461             : 
    3462             :         if (wpa_s->conf->pcsc_pin &&
    3463             :             scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
    3464             :                 scard_deinit(wpa_s->scard);
    3465             :                 wpa_s->scard = NULL;
    3466             :                 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
    3467             :                 return -1;
    3468             :         }
    3469             : 
    3470             :         len = sizeof(wpa_s->imsi) - 1;
    3471             :         if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
    3472             :                 scard_deinit(wpa_s->scard);
    3473             :                 wpa_s->scard = NULL;
    3474             :                 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
    3475             :                 return -1;
    3476             :         }
    3477             :         wpa_s->imsi[len] = '\0';
    3478             : 
    3479             :         wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
    3480             : 
    3481             :         wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
    3482             :                    wpa_s->imsi, wpa_s->mnc_len);
    3483             : 
    3484             :         wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
    3485             :         eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
    3486             : #endif /* PCSC_FUNCS */
    3487             : 
    3488         184 :         return 0;
    3489             : }
    3490             : 
    3491             : 
    3492         192 : int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
    3493             : {
    3494             :         char *val, *pos;
    3495             : 
    3496         192 :         ext_password_deinit(wpa_s->ext_pw);
    3497         192 :         wpa_s->ext_pw = NULL;
    3498         192 :         eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
    3499             : 
    3500         192 :         if (!wpa_s->conf->ext_password_backend)
    3501         185 :                 return 0;
    3502             : 
    3503           7 :         val = os_strdup(wpa_s->conf->ext_password_backend);
    3504           7 :         if (val == NULL)
    3505           0 :                 return -1;
    3506           7 :         pos = os_strchr(val, ':');
    3507           7 :         if (pos)
    3508           7 :                 *pos++ = '\0';
    3509             : 
    3510           7 :         wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
    3511             : 
    3512           7 :         wpa_s->ext_pw = ext_password_init(val, pos);
    3513           7 :         os_free(val);
    3514           7 :         if (wpa_s->ext_pw == NULL) {
    3515           0 :                 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
    3516           0 :                 return -1;
    3517             :         }
    3518           7 :         eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
    3519             : 
    3520           7 :         return 0;
    3521             : }
    3522             : 
    3523             : 
    3524         161 : static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
    3525             :                                     const struct wpa_driver_capa *capa)
    3526             : {
    3527             :         struct wowlan_triggers *triggers;
    3528         161 :         int ret = 0;
    3529             : 
    3530         161 :         if (!wpa_s->conf->wowlan_triggers)
    3531         161 :                 return 0;
    3532             : 
    3533           0 :         triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
    3534           0 :         if (triggers) {
    3535           0 :                 ret = wpa_drv_wowlan(wpa_s, triggers);
    3536           0 :                 os_free(triggers);
    3537             :         }
    3538           0 :         return ret;
    3539             : }
    3540             : 
    3541             : 
    3542         199 : static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
    3543             :                                               const char *rn)
    3544             : {
    3545         199 :         struct wpa_supplicant *iface = wpa_s->global->ifaces;
    3546             :         struct wpa_radio *radio;
    3547             : 
    3548         398 :         while (rn && iface) {
    3549          71 :                 radio = iface->radio;
    3550          71 :                 if (radio && os_strcmp(rn, radio->name) == 0) {
    3551          71 :                         wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
    3552          71 :                                    wpa_s->ifname, rn);
    3553          71 :                         dl_list_add(&radio->ifaces, &wpa_s->radio_list);
    3554          71 :                         return radio;
    3555             :                 }
    3556             : 
    3557           0 :                 iface = iface->next;
    3558             :         }
    3559             : 
    3560         256 :         wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
    3561         128 :                    wpa_s->ifname, rn ? rn : "N/A");
    3562         128 :         radio = os_zalloc(sizeof(*radio));
    3563         128 :         if (radio == NULL)
    3564           1 :                 return NULL;
    3565             : 
    3566         127 :         if (rn)
    3567          91 :                 os_strlcpy(radio->name, rn, sizeof(radio->name));
    3568         127 :         dl_list_init(&radio->ifaces);
    3569         127 :         dl_list_init(&radio->work);
    3570         127 :         dl_list_add(&radio->ifaces, &wpa_s->radio_list);
    3571             : 
    3572         127 :         return radio;
    3573             : }
    3574             : 
    3575             : 
    3576        7475 : static void radio_work_free(struct wpa_radio_work *work)
    3577             : {
    3578        7475 :         if (work->wpa_s->scan_work == work) {
    3579             :                 /* This should not really happen. */
    3580           0 :                 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
    3581             :                         work->type, work, work->started);
    3582           0 :                 work->wpa_s->scan_work = NULL;
    3583             :         }
    3584             : 
    3585             : #ifdef CONFIG_P2P
    3586        7475 :         if (work->wpa_s->p2p_scan_work == work) {
    3587             :                 /* This should not really happen. */
    3588           0 :                 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
    3589             :                         work->type, work, work->started);
    3590           0 :                 work->wpa_s->p2p_scan_work = NULL;
    3591             :         }
    3592             : #endif /* CONFIG_P2P */
    3593             : 
    3594        7475 :         dl_list_del(&work->list);
    3595        7475 :         os_free(work);
    3596        7475 : }
    3597             : 
    3598             : 
    3599        7479 : static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
    3600             : {
    3601        7479 :         struct wpa_radio *radio = eloop_ctx;
    3602             :         struct wpa_radio_work *work;
    3603             :         struct os_reltime now, diff;
    3604             :         struct wpa_supplicant *wpa_s;
    3605             : 
    3606        7479 :         work = dl_list_first(&radio->work, struct wpa_radio_work, list);
    3607        7479 :         if (work == NULL)
    3608          19 :                 return;
    3609             : 
    3610        7475 :         if (work->started)
    3611          10 :                 return; /* already started and still in progress */
    3612             : 
    3613        7465 :         wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
    3614             :                               radio_list);
    3615        7465 :         if (wpa_s && wpa_s->radio->external_scan_running) {
    3616           1 :                 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
    3617           1 :                 return;
    3618             :         }
    3619             : 
    3620        7464 :         os_get_reltime(&now);
    3621        7464 :         os_reltime_sub(&now, &work->time, &diff);
    3622        7464 :         wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting radio work '%s'@%p after %ld.%06ld second wait",
    3623             :                 work->type, work, diff.sec, diff.usec);
    3624        7464 :         work->started = 1;
    3625        7464 :         work->time = now;
    3626        7464 :         work->cb(work, 0);
    3627             : }
    3628             : 
    3629             : 
    3630             : /*
    3631             :  * This function removes both started and pending radio works running on
    3632             :  * the provided interface's radio.
    3633             :  * Prior to the removal of the radio work, its callback (cb) is called with
    3634             :  * deinit set to be 1. Each work's callback is responsible for clearing its
    3635             :  * internal data and restoring to a correct state.
    3636             :  * @wpa_s: wpa_supplicant data
    3637             :  * @type: type of works to be removed
    3638             :  * @remove_all: 1 to remove all the works on this radio, 0 to remove only
    3639             :  * this interface's works.
    3640             :  */
    3641        4120 : void radio_remove_works(struct wpa_supplicant *wpa_s,
    3642             :                         const char *type, int remove_all)
    3643             : {
    3644             :         struct wpa_radio_work *work, *tmp;
    3645        4120 :         struct wpa_radio *radio = wpa_s->radio;
    3646             : 
    3647        4172 :         dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
    3648             :                               list) {
    3649          52 :                 if (type && os_strcmp(type, work->type) != 0)
    3650           5 :                         continue;
    3651             : 
    3652             :                 /* skip other ifaces' works */
    3653          47 :                 if (!remove_all && work->wpa_s != wpa_s)
    3654           2 :                         continue;
    3655             : 
    3656          45 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
    3657             :                         work->type, work, work->started ? " (started)" : "");
    3658          45 :                 work->cb(work, 1);
    3659          45 :                 radio_work_free(work);
    3660             :         }
    3661             : 
    3662             :         /* in case we removed the started work */
    3663        4120 :         radio_work_check_next(wpa_s);
    3664        4120 : }
    3665             : 
    3666             : 
    3667         212 : static void radio_remove_interface(struct wpa_supplicant *wpa_s)
    3668             : {
    3669         212 :         struct wpa_radio *radio = wpa_s->radio;
    3670             : 
    3671         212 :         if (!radio)
    3672          14 :                 return;
    3673             : 
    3674         198 :         wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
    3675         198 :                    wpa_s->ifname, radio->name);
    3676         198 :         dl_list_del(&wpa_s->radio_list);
    3677         198 :         radio_remove_works(wpa_s, NULL, 0);
    3678         198 :         wpa_s->radio = NULL;
    3679         198 :         if (!dl_list_empty(&radio->ifaces))
    3680          71 :                 return; /* Interfaces remain for this radio */
    3681             : 
    3682         127 :         wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
    3683         127 :         eloop_cancel_timeout(radio_start_next_work, radio, NULL);
    3684         127 :         os_free(radio);
    3685             : }
    3686             : 
    3687             : 
    3688       21593 : void radio_work_check_next(struct wpa_supplicant *wpa_s)
    3689             : {
    3690       21593 :         struct wpa_radio *radio = wpa_s->radio;
    3691             : 
    3692       21593 :         if (dl_list_empty(&radio->work))
    3693       12277 :                 return;
    3694        9316 :         if (wpa_s->ext_work_in_progress) {
    3695           6 :                 wpa_printf(MSG_DEBUG,
    3696             :                            "External radio work in progress - delay start of pending item");
    3697           6 :                 return;
    3698             :         }
    3699        9310 :         eloop_cancel_timeout(radio_start_next_work, radio, NULL);
    3700        9310 :         eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
    3701             : }
    3702             : 
    3703             : 
    3704             : /**
    3705             :  * radio_add_work - Add a radio work item
    3706             :  * @wpa_s: Pointer to wpa_supplicant data
    3707             :  * @freq: Frequency of the offchannel operation in MHz or 0
    3708             :  * @type: Unique identifier for each type of work
    3709             :  * @next: Force as the next work to be executed
    3710             :  * @cb: Callback function for indicating when radio is available
    3711             :  * @ctx: Context pointer for the work (work->ctx in cb())
    3712             :  * Returns: 0 on success, -1 on failure
    3713             :  *
    3714             :  * This function is used to request time for an operation that requires
    3715             :  * exclusive radio control. Once the radio is available, the registered callback
    3716             :  * function will be called. radio_work_done() must be called once the exclusive
    3717             :  * radio operation has been completed, so that the radio is freed for other
    3718             :  * operations. The special case of deinit=1 is used to free the context data
    3719             :  * during interface removal. That does not allow the callback function to start
    3720             :  * the radio operation, i.e., it must free any resources allocated for the radio
    3721             :  * work and return.
    3722             :  *
    3723             :  * The @freq parameter can be used to indicate a single channel on which the
    3724             :  * offchannel operation will occur. This may allow multiple radio work
    3725             :  * operations to be performed in parallel if they apply for the same channel.
    3726             :  * Setting this to 0 indicates that the work item may use multiple channels or
    3727             :  * requires exclusive control of the radio.
    3728             :  */
    3729        7475 : int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
    3730             :                    const char *type, int next,
    3731             :                    void (*cb)(struct wpa_radio_work *work, int deinit),
    3732             :                    void *ctx)
    3733             : {
    3734             :         struct wpa_radio_work *work;
    3735             :         int was_empty;
    3736             : 
    3737        7475 :         work = os_zalloc(sizeof(*work));
    3738        7475 :         if (work == NULL)
    3739           0 :                 return -1;
    3740        7475 :         wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
    3741        7475 :         os_get_reltime(&work->time);
    3742        7475 :         work->freq = freq;
    3743        7475 :         work->type = type;
    3744        7475 :         work->wpa_s = wpa_s;
    3745        7475 :         work->cb = cb;
    3746        7475 :         work->ctx = ctx;
    3747             : 
    3748        7475 :         was_empty = dl_list_empty(&wpa_s->radio->work);
    3749        7475 :         if (next)
    3750        2435 :                 dl_list_add(&wpa_s->radio->work, &work->list);
    3751             :         else
    3752        5040 :                 dl_list_add_tail(&wpa_s->radio->work, &work->list);
    3753        7475 :         if (was_empty) {
    3754        7289 :                 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
    3755        7289 :                 radio_work_check_next(wpa_s);
    3756             :         }
    3757             : 
    3758        7475 :         return 0;
    3759             : }
    3760             : 
    3761             : 
    3762             : /**
    3763             :  * radio_work_done - Indicate that a radio work item has been completed
    3764             :  * @work: Completed work
    3765             :  *
    3766             :  * This function is called once the callback function registered with
    3767             :  * radio_add_work() has completed its work.
    3768             :  */
    3769        7430 : void radio_work_done(struct wpa_radio_work *work)
    3770             : {
    3771        7430 :         struct wpa_supplicant *wpa_s = work->wpa_s;
    3772             :         struct os_reltime now, diff;
    3773        7430 :         unsigned int started = work->started;
    3774             : 
    3775        7430 :         os_get_reltime(&now);
    3776        7430 :         os_reltime_sub(&now, &work->time, &diff);
    3777        7430 :         wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
    3778             :                 work->type, work, started ? "done" : "canceled",
    3779             :                 diff.sec, diff.usec);
    3780        7430 :         radio_work_free(work);
    3781        7430 :         if (started)
    3782        7429 :                 radio_work_check_next(wpa_s);
    3783        7430 : }
    3784             : 
    3785             : 
    3786             : struct wpa_radio_work *
    3787        6712 : radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
    3788             : {
    3789             :         struct wpa_radio_work *work;
    3790        6712 :         struct wpa_radio *radio = wpa_s->radio;
    3791             : 
    3792        7126 :         dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
    3793         428 :                 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
    3794          14 :                         return work;
    3795             :         }
    3796             : 
    3797        6698 :         return NULL;
    3798             : }
    3799             : 
    3800             : 
    3801         203 : static int wpas_init_driver(struct wpa_supplicant *wpa_s,
    3802             :                             struct wpa_interface *iface)
    3803             : {
    3804             :         const char *ifname, *driver, *rn;
    3805             : 
    3806         203 :         driver = iface->driver;
    3807             : next_driver:
    3808         203 :         if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
    3809           0 :                 return -1;
    3810             : 
    3811         203 :         wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
    3812         203 :         if (wpa_s->drv_priv == NULL) {
    3813             :                 const char *pos;
    3814           4 :                 pos = driver ? os_strchr(driver, ',') : NULL;
    3815           4 :                 if (pos) {
    3816           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
    3817             :                                 "driver interface - try next driver wrapper");
    3818           0 :                         driver = pos + 1;
    3819           0 :                         goto next_driver;
    3820             :                 }
    3821           4 :                 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
    3822             :                         "interface");
    3823           4 :                 return -1;
    3824             :         }
    3825         199 :         if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
    3826           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
    3827           0 :                         "driver_param '%s'", wpa_s->conf->driver_param);
    3828           0 :                 return -1;
    3829             :         }
    3830             : 
    3831         199 :         ifname = wpa_drv_get_ifname(wpa_s);
    3832         199 :         if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
    3833           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
    3834             :                         "interface name with '%s'", ifname);
    3835           0 :                 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
    3836             :         }
    3837             : 
    3838         199 :         rn = wpa_driver_get_radio_name(wpa_s);
    3839         199 :         if (rn && rn[0] == '\0')
    3840           0 :                 rn = NULL;
    3841             : 
    3842         199 :         wpa_s->radio = radio_add_interface(wpa_s, rn);
    3843         199 :         if (wpa_s->radio == NULL)
    3844           1 :                 return -1;
    3845             : 
    3846         198 :         return 0;
    3847             : }
    3848             : 
    3849             : 
    3850         212 : static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
    3851             :                                      struct wpa_interface *iface)
    3852             : {
    3853             :         struct wpa_driver_capa capa;
    3854             :         int capa_res;
    3855             : 
    3856         848 :         wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
    3857             :                    "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
    3858         212 :                    iface->confname ? iface->confname : "N/A",
    3859         212 :                    iface->driver ? iface->driver : "default",
    3860         212 :                    iface->ctrl_interface ? iface->ctrl_interface : "N/A",
    3861         212 :                    iface->bridge_ifname ? iface->bridge_ifname : "N/A");
    3862             : 
    3863         212 :         if (iface->confname) {
    3864             : #ifdef CONFIG_BACKEND_FILE
    3865          25 :                 wpa_s->confname = os_rel2abs_path(iface->confname);
    3866          25 :                 if (wpa_s->confname == NULL) {
    3867           0 :                         wpa_printf(MSG_ERROR, "Failed to get absolute path "
    3868             :                                    "for configuration file '%s'.",
    3869             :                                    iface->confname);
    3870           0 :                         return -1;
    3871             :                 }
    3872          25 :                 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
    3873             :                            iface->confname, wpa_s->confname);
    3874             : #else /* CONFIG_BACKEND_FILE */
    3875             :                 wpa_s->confname = os_strdup(iface->confname);
    3876             : #endif /* CONFIG_BACKEND_FILE */
    3877          25 :                 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
    3878          25 :                 if (wpa_s->conf == NULL) {
    3879           8 :                         wpa_printf(MSG_ERROR, "Failed to read or parse "
    3880             :                                    "configuration '%s'.", wpa_s->confname);
    3881           8 :                         return -1;
    3882             :                 }
    3883          17 :                 wpa_s->confanother = os_rel2abs_path(iface->confanother);
    3884          17 :                 wpa_config_read(wpa_s->confanother, wpa_s->conf);
    3885             : 
    3886             :                 /*
    3887             :                  * Override ctrl_interface and driver_param if set on command
    3888             :                  * line.
    3889             :                  */
    3890          17 :                 if (iface->ctrl_interface) {
    3891           2 :                         os_free(wpa_s->conf->ctrl_interface);
    3892           4 :                         wpa_s->conf->ctrl_interface =
    3893           2 :                                 os_strdup(iface->ctrl_interface);
    3894             :                 }
    3895             : 
    3896          17 :                 if (iface->driver_param) {
    3897           0 :                         os_free(wpa_s->conf->driver_param);
    3898           0 :                         wpa_s->conf->driver_param =
    3899           0 :                                 os_strdup(iface->driver_param);
    3900             :                 }
    3901             : 
    3902          17 :                 if (iface->p2p_mgmt && !iface->ctrl_interface) {
    3903           0 :                         os_free(wpa_s->conf->ctrl_interface);
    3904           0 :                         wpa_s->conf->ctrl_interface = NULL;
    3905             :                 }
    3906             :         } else
    3907         187 :                 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
    3908             :                                                      iface->driver_param);
    3909             : 
    3910         204 :         if (wpa_s->conf == NULL) {
    3911           1 :                 wpa_printf(MSG_ERROR, "\nNo configuration found.");
    3912           1 :                 return -1;
    3913             :         }
    3914             : 
    3915         203 :         if (iface->ifname == NULL) {
    3916           0 :                 wpa_printf(MSG_ERROR, "\nInterface name is required.");
    3917           0 :                 return -1;
    3918             :         }
    3919         203 :         if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
    3920           0 :                 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
    3921             :                            iface->ifname);
    3922           0 :                 return -1;
    3923             :         }
    3924         203 :         os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
    3925             : 
    3926         203 :         if (iface->bridge_ifname) {
    3927           3 :                 if (os_strlen(iface->bridge_ifname) >=
    3928             :                     sizeof(wpa_s->bridge_ifname)) {
    3929           0 :                         wpa_printf(MSG_ERROR, "\nToo long bridge interface "
    3930             :                                    "name '%s'.", iface->bridge_ifname);
    3931           0 :                         return -1;
    3932             :                 }
    3933           3 :                 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
    3934             :                            sizeof(wpa_s->bridge_ifname));
    3935             :         }
    3936             : 
    3937             :         /* RSNA Supplicant Key Management - INITIALIZE */
    3938         203 :         eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
    3939         203 :         eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
    3940             : 
    3941             :         /* Initialize driver interface and register driver event handler before
    3942             :          * L2 receive handler so that association events are processed before
    3943             :          * EAPOL-Key packets if both become available for the same select()
    3944             :          * call. */
    3945         203 :         if (wpas_init_driver(wpa_s, iface) < 0)
    3946           5 :                 return -1;
    3947             : 
    3948         198 :         if (wpa_supplicant_init_wpa(wpa_s) < 0)
    3949           3 :                 return -1;
    3950             : 
    3951         195 :         wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
    3952         195 :                           wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
    3953             :                           NULL);
    3954         195 :         wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
    3955             : 
    3956         195 :         if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
    3957           0 :             wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
    3958           0 :                              wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
    3959           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
    3960             :                         "dot11RSNAConfigPMKLifetime");
    3961           0 :                 return -1;
    3962             :         }
    3963             : 
    3964         195 :         if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
    3965           0 :             wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
    3966           0 :                              wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
    3967           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
    3968             :                         "dot11RSNAConfigPMKReauthThreshold");
    3969           0 :                 return -1;
    3970             :         }
    3971             : 
    3972         195 :         if (wpa_s->conf->dot11RSNAConfigSATimeout &&
    3973           0 :             wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
    3974           0 :                              wpa_s->conf->dot11RSNAConfigSATimeout)) {
    3975           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
    3976             :                         "dot11RSNAConfigSATimeout");
    3977           0 :                 return -1;
    3978             :         }
    3979             : 
    3980         195 :         wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
    3981             :                                                       &wpa_s->hw.num_modes,
    3982             :                                                       &wpa_s->hw.flags);
    3983             : 
    3984         195 :         capa_res = wpa_drv_get_capa(wpa_s, &capa);
    3985         195 :         if (capa_res == 0) {
    3986         162 :                 wpa_s->drv_capa_known = 1;
    3987         162 :                 wpa_s->drv_flags = capa.flags;
    3988         162 :                 wpa_s->drv_enc = capa.enc;
    3989         162 :                 wpa_s->drv_smps_modes = capa.smps_modes;
    3990         162 :                 wpa_s->drv_rrm_flags = capa.rrm_flags;
    3991         162 :                 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
    3992         162 :                 wpa_s->max_scan_ssids = capa.max_scan_ssids;
    3993         162 :                 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
    3994         162 :                 wpa_s->sched_scan_supported = capa.sched_scan_supported;
    3995         162 :                 wpa_s->max_match_sets = capa.max_match_sets;
    3996         162 :                 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
    3997         162 :                 wpa_s->max_stations = capa.max_stations;
    3998         162 :                 wpa_s->extended_capa = capa.extended_capa;
    3999         162 :                 wpa_s->extended_capa_mask = capa.extended_capa_mask;
    4000         162 :                 wpa_s->extended_capa_len = capa.extended_capa_len;
    4001         162 :                 wpa_s->num_multichan_concurrent =
    4002         162 :                         capa.num_multichan_concurrent;
    4003         162 :                 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
    4004             : 
    4005         162 :                 if (capa.mac_addr_rand_scan_supported)
    4006         152 :                         wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
    4007         162 :                 if (wpa_s->sched_scan_supported &&
    4008             :                     capa.mac_addr_rand_sched_scan_supported)
    4009           0 :                         wpa_s->mac_addr_rand_supported |=
    4010             :                                 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
    4011             :         }
    4012         195 :         if (wpa_s->max_remain_on_chan == 0)
    4013          43 :                 wpa_s->max_remain_on_chan = 1000;
    4014             : 
    4015             :         /*
    4016             :          * Only take p2p_mgmt parameters when P2P Device is supported.
    4017             :          * Doing it here as it determines whether l2_packet_init() will be done
    4018             :          * during wpa_supplicant_driver_init().
    4019             :          */
    4020         195 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
    4021          14 :                 wpa_s->p2p_mgmt = iface->p2p_mgmt;
    4022             :         else
    4023         181 :                 iface->p2p_mgmt = 1;
    4024             : 
    4025         195 :         if (wpa_s->num_multichan_concurrent == 0)
    4026         181 :                 wpa_s->num_multichan_concurrent = 1;
    4027             : 
    4028         195 :         if (wpa_supplicant_driver_init(wpa_s) < 0)
    4029           2 :                 return -1;
    4030             : 
    4031             : #ifdef CONFIG_TDLS
    4032         377 :         if ((!iface->p2p_mgmt ||
    4033         184 :              !(wpa_s->drv_flags &
    4034         188 :                WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
    4035         188 :             wpa_tdls_init(wpa_s->wpa))
    4036           1 :                 return -1;
    4037             : #endif /* CONFIG_TDLS */
    4038             : 
    4039         192 :         if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
    4040           0 :             wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
    4041           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
    4042           0 :                 return -1;
    4043             :         }
    4044             : 
    4045         192 :         if (wpas_wps_init(wpa_s))
    4046           2 :                 return -1;
    4047             : 
    4048         190 :         if (wpa_supplicant_init_eapol(wpa_s) < 0)
    4049           4 :                 return -1;
    4050         186 :         wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
    4051             : 
    4052         186 :         wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
    4053         186 :         if (wpa_s->ctrl_iface == NULL) {
    4054           1 :                 wpa_printf(MSG_ERROR,
    4055             :                            "Failed to initialize control interface '%s'.\n"
    4056             :                            "You may have another wpa_supplicant process "
    4057             :                            "already running or the file was\n"
    4058             :                            "left by an unclean termination of wpa_supplicant "
    4059             :                            "in which case you will need\n"
    4060             :                            "to manually remove this file before starting "
    4061             :                            "wpa_supplicant again.\n",
    4062           1 :                            wpa_s->conf->ctrl_interface);
    4063           1 :                 return -1;
    4064             :         }
    4065             : 
    4066         185 :         wpa_s->gas = gas_query_init(wpa_s);
    4067         185 :         if (wpa_s->gas == NULL) {
    4068           1 :                 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
    4069           1 :                 return -1;
    4070             :         }
    4071             : 
    4072         184 :         if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
    4073           0 :                 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
    4074           0 :                 return -1;
    4075             :         }
    4076             : 
    4077         184 :         if (wpa_bss_init(wpa_s) < 0)
    4078           0 :                 return -1;
    4079             : 
    4080             :         /*
    4081             :          * Set Wake-on-WLAN triggers, if configured.
    4082             :          * Note: We don't restore/remove the triggers on shutdown (it doesn't
    4083             :          * have effect anyway when the interface is down).
    4084             :          */
    4085         184 :         if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
    4086           0 :                 return -1;
    4087             : 
    4088             : #ifdef CONFIG_EAP_PROXY
    4089             : {
    4090             :         size_t len;
    4091             :         wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
    4092             :                                                      &len);
    4093             :         if (wpa_s->mnc_len > 0) {
    4094             :                 wpa_s->imsi[len] = '\0';
    4095             :                 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
    4096             :                            wpa_s->imsi, wpa_s->mnc_len);
    4097             :         } else {
    4098             :                 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
    4099             :         }
    4100             : }
    4101             : #endif /* CONFIG_EAP_PROXY */
    4102             : 
    4103         184 :         if (pcsc_reader_init(wpa_s) < 0)
    4104           0 :                 return -1;
    4105             : 
    4106         184 :         if (wpas_init_ext_pw(wpa_s) < 0)
    4107           0 :                 return -1;
    4108             : 
    4109         184 :         wpas_rrm_reset(wpa_s);
    4110             : 
    4111         184 :         return 0;
    4112             : }
    4113             : 
    4114             : 
    4115         212 : static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
    4116             :                                         int notify, int terminate)
    4117             : {
    4118         212 :         struct wpa_global *global = wpa_s->global;
    4119             :         struct wpa_supplicant *iface, *prev;
    4120             : 
    4121         212 :         if (wpa_s == wpa_s->parent)
    4122         141 :                 wpas_p2p_group_remove(wpa_s, "*");
    4123             : 
    4124         212 :         iface = global->ifaces;
    4125         546 :         while (iface) {
    4126         122 :                 if (iface == wpa_s || iface->parent != wpa_s) {
    4127         117 :                         iface = iface->next;
    4128         117 :                         continue;
    4129             :                 }
    4130           5 :                 wpa_printf(MSG_DEBUG,
    4131             :                            "Remove remaining child interface %s from parent %s",
    4132           5 :                            iface->ifname, wpa_s->ifname);
    4133           5 :                 prev = iface;
    4134           5 :                 iface = iface->next;
    4135           5 :                 wpa_supplicant_remove_iface(global, prev, terminate);
    4136             :         }
    4137             : 
    4138         212 :         wpa_s->disconnected = 1;
    4139         212 :         if (wpa_s->drv_priv) {
    4140         199 :                 wpa_supplicant_deauthenticate(wpa_s,
    4141             :                                               WLAN_REASON_DEAUTH_LEAVING);
    4142             : 
    4143         199 :                 wpa_drv_set_countermeasures(wpa_s, 0);
    4144         199 :                 wpa_clear_keys(wpa_s, NULL);
    4145             :         }
    4146             : 
    4147         212 :         wpa_supplicant_cleanup(wpa_s);
    4148         212 :         wpas_p2p_deinit_iface(wpa_s);
    4149             : 
    4150         212 :         wpas_ctrl_radio_work_flush(wpa_s);
    4151         212 :         radio_remove_interface(wpa_s);
    4152             : 
    4153         212 :         if (wpa_s->drv_priv)
    4154         199 :                 wpa_drv_deinit(wpa_s);
    4155             : 
    4156         212 :         if (notify)
    4157         184 :                 wpas_notify_iface_removed(wpa_s);
    4158             : 
    4159         212 :         if (terminate)
    4160          15 :                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
    4161             : 
    4162         212 :         if (wpa_s->ctrl_iface) {
    4163         185 :                 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
    4164         185 :                 wpa_s->ctrl_iface = NULL;
    4165             :         }
    4166             : 
    4167             : #ifdef CONFIG_MESH
    4168         212 :         if (wpa_s->ifmsh) {
    4169           0 :                 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
    4170           0 :                 wpa_s->ifmsh = NULL;
    4171             :         }
    4172             : #endif /* CONFIG_MESH */
    4173             : 
    4174         212 :         if (wpa_s->conf != NULL) {
    4175         203 :                 wpa_config_free(wpa_s->conf);
    4176         203 :                 wpa_s->conf = NULL;
    4177             :         }
    4178             : 
    4179         212 :         os_free(wpa_s);
    4180         212 : }
    4181             : 
    4182             : 
    4183             : /**
    4184             :  * wpa_supplicant_add_iface - Add a new network interface
    4185             :  * @global: Pointer to global data from wpa_supplicant_init()
    4186             :  * @iface: Interface configuration options
    4187             :  * Returns: Pointer to the created interface or %NULL on failure
    4188             :  *
    4189             :  * This function is used to add new network interfaces for %wpa_supplicant.
    4190             :  * This can be called before wpa_supplicant_run() to add interfaces before the
    4191             :  * main event loop has been started. In addition, new interfaces can be added
    4192             :  * dynamically while %wpa_supplicant is already running. This could happen,
    4193             :  * e.g., when a hotplug network adapter is inserted.
    4194             :  */
    4195         213 : struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
    4196             :                                                  struct wpa_interface *iface)
    4197             : {
    4198             :         struct wpa_supplicant *wpa_s;
    4199             :         struct wpa_interface t_iface;
    4200             :         struct wpa_ssid *ssid;
    4201             : 
    4202         213 :         if (global == NULL || iface == NULL)
    4203           0 :                 return NULL;
    4204             : 
    4205         213 :         wpa_s = wpa_supplicant_alloc();
    4206         213 :         if (wpa_s == NULL)
    4207           1 :                 return NULL;
    4208             : 
    4209         212 :         wpa_s->global = global;
    4210             : 
    4211         212 :         t_iface = *iface;
    4212         212 :         if (global->params.override_driver) {
    4213           0 :                 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
    4214             :                            "('%s' -> '%s')",
    4215             :                            iface->driver, global->params.override_driver);
    4216           0 :                 t_iface.driver = global->params.override_driver;
    4217             :         }
    4218         212 :         if (global->params.override_ctrl_interface) {
    4219           0 :                 wpa_printf(MSG_DEBUG, "Override interface parameter: "
    4220             :                            "ctrl_interface ('%s' -> '%s')",
    4221             :                            iface->ctrl_interface,
    4222             :                            global->params.override_ctrl_interface);
    4223           0 :                 t_iface.ctrl_interface =
    4224           0 :                         global->params.override_ctrl_interface;
    4225             :         }
    4226         212 :         if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
    4227          28 :                 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
    4228             :                            iface->ifname);
    4229          28 :                 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
    4230          28 :                 return NULL;
    4231             :         }
    4232             : 
    4233         184 :         if (iface->p2p_mgmt == 0) {
    4234             :                 /* Notify the control interfaces about new iface */
    4235         179 :                 if (wpas_notify_iface_added(wpa_s)) {
    4236           3 :                         wpa_supplicant_deinit_iface(wpa_s, 1, 0);
    4237           3 :                         return NULL;
    4238             :                 }
    4239             : 
    4240         177 :                 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
    4241           1 :                         wpas_notify_network_added(wpa_s, ssid);
    4242             :         }
    4243             : 
    4244         181 :         wpa_s->next = global->ifaces;
    4245         181 :         global->ifaces = wpa_s;
    4246             : 
    4247         181 :         wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
    4248         181 :         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
    4249             : 
    4250             : #ifdef CONFIG_P2P
    4251         196 :         if (wpa_s->global->p2p == NULL &&
    4252          20 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
    4253           5 :             wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) < 0) {
    4254           0 :                 wpa_printf(MSG_INFO,
    4255             :                            "P2P: Failed to enable P2P Device interface");
    4256             :                 /* Try to continue without. P2P will be disabled. */
    4257             :         }
    4258             : #endif /* CONFIG_P2P */
    4259             : 
    4260         181 :         return wpa_s;
    4261             : }
    4262             : 
    4263             : 
    4264             : /**
    4265             :  * wpa_supplicant_remove_iface - Remove a network interface
    4266             :  * @global: Pointer to global data from wpa_supplicant_init()
    4267             :  * @wpa_s: Pointer to the network interface to be removed
    4268             :  * Returns: 0 if interface was removed, -1 if interface was not found
    4269             :  *
    4270             :  * This function can be used to dynamically remove network interfaces from
    4271             :  * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
    4272             :  * addition, this function is used to remove all remaining interfaces when
    4273             :  * %wpa_supplicant is terminated.
    4274             :  */
    4275         181 : int wpa_supplicant_remove_iface(struct wpa_global *global,
    4276             :                                 struct wpa_supplicant *wpa_s,
    4277             :                                 int terminate)
    4278             : {
    4279             :         struct wpa_supplicant *prev;
    4280             : #ifdef CONFIG_MESH
    4281         181 :         unsigned int mesh_if_created = wpa_s->mesh_if_created;
    4282         181 :         char *ifname = NULL;
    4283             : #endif /* CONFIG_MESH */
    4284             : 
    4285             :         /* Remove interface from the global list of interfaces */
    4286         181 :         prev = global->ifaces;
    4287         181 :         if (prev == wpa_s) {
    4288         174 :                 global->ifaces = wpa_s->next;
    4289             :         } else {
    4290          15 :                 while (prev && prev->next != wpa_s)
    4291           1 :                         prev = prev->next;
    4292           7 :                 if (prev == NULL)
    4293           0 :                         return -1;
    4294           7 :                 prev->next = wpa_s->next;
    4295             :         }
    4296             : 
    4297         181 :         wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
    4298             : 
    4299             : #ifdef CONFIG_MESH
    4300         181 :         if (mesh_if_created) {
    4301           4 :                 ifname = os_strdup(wpa_s->ifname);
    4302           4 :                 if (ifname == NULL) {
    4303           0 :                         wpa_dbg(wpa_s, MSG_ERROR,
    4304             :                                 "mesh: Failed to malloc ifname");
    4305           0 :                         return -1;
    4306             :                 }
    4307             :         }
    4308             : #endif /* CONFIG_MESH */
    4309             : 
    4310         181 :         if (global->p2p_group_formation == wpa_s)
    4311           4 :                 global->p2p_group_formation = NULL;
    4312         181 :         if (global->p2p_invite_group == wpa_s)
    4313           3 :                 global->p2p_invite_group = NULL;
    4314         181 :         wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
    4315             : 
    4316             : #ifdef CONFIG_MESH
    4317         181 :         if (mesh_if_created) {
    4318           4 :                 wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
    4319           4 :                 os_free(ifname);
    4320             :         }
    4321             : #endif /* CONFIG_MESH */
    4322             : 
    4323         181 :         return 0;
    4324             : }
    4325             : 
    4326             : 
    4327             : /**
    4328             :  * wpa_supplicant_get_eap_mode - Get the current EAP mode
    4329             :  * @wpa_s: Pointer to the network interface
    4330             :  * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
    4331             :  */
    4332        1118 : const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
    4333             : {
    4334             :         const char *eapol_method;
    4335             : 
    4336        1134 :         if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
    4337          16 :             wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
    4338           0 :                 return "NO-EAP";
    4339             :         }
    4340             : 
    4341        1118 :         eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
    4342        1118 :         if (eapol_method == NULL)
    4343           0 :                 return "UNKNOWN-EAP";
    4344             : 
    4345        1118 :         return eapol_method;
    4346             : }
    4347             : 
    4348             : 
    4349             : /**
    4350             :  * wpa_supplicant_get_iface - Get a new network interface
    4351             :  * @global: Pointer to global data from wpa_supplicant_init()
    4352             :  * @ifname: Interface name
    4353             :  * Returns: Pointer to the interface or %NULL if not found
    4354             :  */
    4355         283 : struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
    4356             :                                                  const char *ifname)
    4357             : {
    4358             :         struct wpa_supplicant *wpa_s;
    4359             : 
    4360         344 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    4361         214 :                 if (os_strcmp(wpa_s->ifname, ifname) == 0)
    4362         153 :                         return wpa_s;
    4363             :         }
    4364         130 :         return NULL;
    4365             : }
    4366             : 
    4367             : 
    4368             : #ifndef CONFIG_NO_WPA_MSG
    4369      380680 : static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
    4370             : {
    4371      380680 :         struct wpa_supplicant *wpa_s = ctx;
    4372      380680 :         if (wpa_s == NULL)
    4373         171 :                 return NULL;
    4374      380509 :         return wpa_s->ifname;
    4375             : }
    4376             : #endif /* CONFIG_NO_WPA_MSG */
    4377             : 
    4378             : 
    4379             : /**
    4380             :  * wpa_supplicant_init - Initialize %wpa_supplicant
    4381             :  * @params: Parameters for %wpa_supplicant
    4382             :  * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
    4383             :  *
    4384             :  * This function is used to initialize %wpa_supplicant. After successful
    4385             :  * initialization, the returned data pointer can be used to add and remove
    4386             :  * network interfaces, and eventually, to deinitialize %wpa_supplicant.
    4387             :  */
    4388          30 : struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
    4389             : {
    4390             :         struct wpa_global *global;
    4391             :         int ret, i;
    4392             : 
    4393          30 :         if (params == NULL)
    4394           0 :                 return NULL;
    4395             : 
    4396             : #ifdef CONFIG_DRIVER_NDIS
    4397             :         {
    4398             :                 void driver_ndis_init_ops(void);
    4399             :                 driver_ndis_init_ops();
    4400             :         }
    4401             : #endif /* CONFIG_DRIVER_NDIS */
    4402             : 
    4403             : #ifndef CONFIG_NO_WPA_MSG
    4404          30 :         wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
    4405             : #endif /* CONFIG_NO_WPA_MSG */
    4406             : 
    4407          30 :         if (params->wpa_debug_file_path)
    4408          20 :                 wpa_debug_open_file(params->wpa_debug_file_path);
    4409             :         else
    4410          10 :                 wpa_debug_setup_stdout();
    4411          30 :         if (params->wpa_debug_syslog)
    4412           0 :                 wpa_debug_open_syslog();
    4413          30 :         if (params->wpa_debug_tracing) {
    4414           0 :                 ret = wpa_debug_open_linux_tracing();
    4415           0 :                 if (ret) {
    4416           0 :                         wpa_printf(MSG_ERROR,
    4417             :                                    "Failed to enable trace logging");
    4418           0 :                         return NULL;
    4419             :                 }
    4420             :         }
    4421             : 
    4422          30 :         ret = eap_register_methods();
    4423          30 :         if (ret) {
    4424           0 :                 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
    4425           0 :                 if (ret == -2)
    4426           0 :                         wpa_printf(MSG_ERROR, "Two or more EAP methods used "
    4427             :                                    "the same EAP type.");
    4428           0 :                 return NULL;
    4429             :         }
    4430             : 
    4431          30 :         global = os_zalloc(sizeof(*global));
    4432          30 :         if (global == NULL)
    4433           0 :                 return NULL;
    4434          30 :         dl_list_init(&global->p2p_srv_bonjour);
    4435          30 :         dl_list_init(&global->p2p_srv_upnp);
    4436          30 :         global->params.daemonize = params->daemonize;
    4437          30 :         global->params.wait_for_monitor = params->wait_for_monitor;
    4438          30 :         global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
    4439          30 :         if (params->pid_file)
    4440           0 :                 global->params.pid_file = os_strdup(params->pid_file);
    4441          30 :         if (params->ctrl_interface)
    4442          20 :                 global->params.ctrl_interface =
    4443          20 :                         os_strdup(params->ctrl_interface);
    4444          30 :         if (params->ctrl_interface_group)
    4445          20 :                 global->params.ctrl_interface_group =
    4446          20 :                         os_strdup(params->ctrl_interface_group);
    4447          30 :         if (params->override_driver)
    4448           0 :                 global->params.override_driver =
    4449           0 :                         os_strdup(params->override_driver);
    4450          30 :         if (params->override_ctrl_interface)
    4451           0 :                 global->params.override_ctrl_interface =
    4452           0 :                         os_strdup(params->override_ctrl_interface);
    4453          30 :         wpa_debug_level = global->params.wpa_debug_level =
    4454          30 :                 params->wpa_debug_level;
    4455          30 :         wpa_debug_show_keys = global->params.wpa_debug_show_keys =
    4456          30 :                 params->wpa_debug_show_keys;
    4457          30 :         wpa_debug_timestamp = global->params.wpa_debug_timestamp =
    4458          30 :                 params->wpa_debug_timestamp;
    4459             : 
    4460          30 :         wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
    4461             : 
    4462          30 :         if (eloop_init()) {
    4463           0 :                 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
    4464           0 :                 wpa_supplicant_deinit(global);
    4465           0 :                 return NULL;
    4466             :         }
    4467             : 
    4468             :         random_init(params->entropy_file);
    4469             : 
    4470          30 :         global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
    4471          30 :         if (global->ctrl_iface == NULL) {
    4472           0 :                 wpa_supplicant_deinit(global);
    4473           0 :                 return NULL;
    4474             :         }
    4475             : 
    4476          30 :         if (wpas_notify_supplicant_initialized(global)) {
    4477           0 :                 wpa_supplicant_deinit(global);
    4478           0 :                 return NULL;
    4479             :         }
    4480             : 
    4481         120 :         for (i = 0; wpa_drivers[i]; i++)
    4482          90 :                 global->drv_count++;
    4483          30 :         if (global->drv_count == 0) {
    4484           0 :                 wpa_printf(MSG_ERROR, "No drivers enabled");
    4485           0 :                 wpa_supplicant_deinit(global);
    4486           0 :                 return NULL;
    4487             :         }
    4488          30 :         global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
    4489          30 :         if (global->drv_priv == NULL) {
    4490           0 :                 wpa_supplicant_deinit(global);
    4491           0 :                 return NULL;
    4492             :         }
    4493             : 
    4494             : #ifdef CONFIG_WIFI_DISPLAY
    4495          30 :         if (wifi_display_init(global) < 0) {
    4496           0 :                 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
    4497           0 :                 wpa_supplicant_deinit(global);
    4498           0 :                 return NULL;
    4499             :         }
    4500             : #endif /* CONFIG_WIFI_DISPLAY */
    4501             : 
    4502          30 :         return global;
    4503             : }
    4504             : 
    4505             : 
    4506             : /**
    4507             :  * wpa_supplicant_run - Run the %wpa_supplicant main event loop
    4508             :  * @global: Pointer to global data from wpa_supplicant_init()
    4509             :  * Returns: 0 after successful event loop run, -1 on failure
    4510             :  *
    4511             :  * This function starts the main event loop and continues running as long as
    4512             :  * there are any remaining events. In most cases, this function is running as
    4513             :  * long as the %wpa_supplicant process in still in use.
    4514             :  */
    4515          20 : int wpa_supplicant_run(struct wpa_global *global)
    4516             : {
    4517             :         struct wpa_supplicant *wpa_s;
    4518             : 
    4519          20 :         if (global->params.daemonize &&
    4520           0 :             wpa_supplicant_daemon(global->params.pid_file))
    4521           0 :                 return -1;
    4522             : 
    4523          20 :         if (global->params.wait_for_monitor) {
    4524           0 :                 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
    4525           0 :                         if (wpa_s->ctrl_iface)
    4526           0 :                                 wpa_supplicant_ctrl_iface_wait(
    4527             :                                         wpa_s->ctrl_iface);
    4528             :         }
    4529             : 
    4530          20 :         eloop_register_signal_terminate(wpa_supplicant_terminate, global);
    4531          20 :         eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
    4532             : 
    4533          20 :         eloop_run();
    4534             : 
    4535          20 :         return 0;
    4536             : }
    4537             : 
    4538             : 
    4539             : /**
    4540             :  * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
    4541             :  * @global: Pointer to global data from wpa_supplicant_init()
    4542             :  *
    4543             :  * This function is called to deinitialize %wpa_supplicant and to free all
    4544             :  * allocated resources. Remaining network interfaces will also be removed.
    4545             :  */
    4546          30 : void wpa_supplicant_deinit(struct wpa_global *global)
    4547             : {
    4548             :         int i;
    4549             : 
    4550          30 :         if (global == NULL)
    4551          30 :                 return;
    4552             : 
    4553             : #ifdef CONFIG_WIFI_DISPLAY
    4554          30 :         wifi_display_deinit(global);
    4555             : #endif /* CONFIG_WIFI_DISPLAY */
    4556             : 
    4557          75 :         while (global->ifaces)
    4558          15 :                 wpa_supplicant_remove_iface(global, global->ifaces, 1);
    4559             : 
    4560          30 :         if (global->ctrl_iface)
    4561          30 :                 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
    4562             : 
    4563          30 :         wpas_notify_supplicant_deinitialized(global);
    4564             : 
    4565          30 :         eap_peer_unregister_methods();
    4566             : #ifdef CONFIG_AP
    4567          30 :         eap_server_unregister_methods();
    4568             : #endif /* CONFIG_AP */
    4569             : 
    4570         120 :         for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
    4571          90 :                 if (!global->drv_priv[i])
    4572          70 :                         continue;
    4573          20 :                 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
    4574             :         }
    4575          30 :         os_free(global->drv_priv);
    4576             : 
    4577             :         random_deinit();
    4578             : 
    4579          30 :         eloop_destroy();
    4580             : 
    4581          30 :         if (global->params.pid_file) {
    4582           0 :                 os_daemonize_terminate(global->params.pid_file);
    4583           0 :                 os_free(global->params.pid_file);
    4584             :         }
    4585          30 :         os_free(global->params.ctrl_interface);
    4586          30 :         os_free(global->params.ctrl_interface_group);
    4587          30 :         os_free(global->params.override_driver);
    4588          30 :         os_free(global->params.override_ctrl_interface);
    4589             : 
    4590          30 :         os_free(global->p2p_disallow_freq.range);
    4591          30 :         os_free(global->p2p_go_avoid_freq.range);
    4592          30 :         os_free(global->add_psk);
    4593             : 
    4594          30 :         os_free(global);
    4595          30 :         wpa_debug_close_syslog();
    4596          30 :         wpa_debug_close_file();
    4597          30 :         wpa_debug_close_linux_tracing();
    4598             : }
    4599             : 
    4600             : 
    4601       19510 : void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
    4602             : {
    4603       19514 :         if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
    4604           7 :             wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
    4605             :                 char country[3];
    4606           3 :                 country[0] = wpa_s->conf->country[0];
    4607           3 :                 country[1] = wpa_s->conf->country[1];
    4608           3 :                 country[2] = '\0';
    4609           3 :                 if (wpa_drv_set_country(wpa_s, country) < 0) {
    4610           0 :                         wpa_printf(MSG_ERROR, "Failed to set country code "
    4611             :                                    "'%s'", country);
    4612             :                 }
    4613             :         }
    4614             : 
    4615       19510 :         if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
    4616           8 :                 wpas_init_ext_pw(wpa_s);
    4617             : 
    4618             : #ifdef CONFIG_WPS
    4619       19510 :         wpas_wps_update_config(wpa_s);
    4620             : #endif /* CONFIG_WPS */
    4621       19510 :         wpas_p2p_update_config(wpa_s);
    4622       19510 :         wpa_s->conf->changed_parameters = 0;
    4623       19510 : }
    4624             : 
    4625             : 
    4626          71 : void add_freq(int *freqs, int *num_freqs, int freq)
    4627             : {
    4628             :         int i;
    4629             : 
    4630          74 :         for (i = 0; i < *num_freqs; i++) {
    4631           3 :                 if (freqs[i] == freq)
    4632          71 :                         return;
    4633             :         }
    4634             : 
    4635          71 :         freqs[*num_freqs] = freq;
    4636          71 :         (*num_freqs)++;
    4637             : }
    4638             : 
    4639             : 
    4640        1692 : static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
    4641             : {
    4642             :         struct wpa_bss *bss, *cbss;
    4643        1692 :         const int max_freqs = 10;
    4644             :         int *freqs;
    4645        1692 :         int num_freqs = 0;
    4646             : 
    4647        1692 :         freqs = os_calloc(max_freqs + 1, sizeof(int));
    4648        1692 :         if (freqs == NULL)
    4649           0 :                 return NULL;
    4650             : 
    4651        1692 :         cbss = wpa_s->current_bss;
    4652             : 
    4653        3728 :         dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
    4654        2036 :                 if (bss == cbss)
    4655        1692 :                         continue;
    4656         574 :                 if (bss->ssid_len == cbss->ssid_len &&
    4657         300 :                     os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
    4658          70 :                     wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
    4659          64 :                         add_freq(freqs, &num_freqs, bss->freq);
    4660          64 :                         if (num_freqs == max_freqs)
    4661           0 :                                 break;
    4662             :                 }
    4663             :         }
    4664             : 
    4665        1692 :         if (num_freqs == 0) {
    4666        1628 :                 os_free(freqs);
    4667        1628 :                 freqs = NULL;
    4668             :         }
    4669             : 
    4670        1692 :         return freqs;
    4671             : }
    4672             : 
    4673             : 
    4674        2229 : void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
    4675             : {
    4676             :         int timeout;
    4677             :         int count;
    4678        2229 :         int *freqs = NULL;
    4679             : 
    4680        2229 :         wpas_connect_work_done(wpa_s);
    4681             : 
    4682             :         /*
    4683             :          * Remove possible authentication timeout since the connection failed.
    4684             :          */
    4685        2229 :         eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
    4686             : 
    4687        2229 :         if (wpa_s->disconnected) {
    4688             :                 /*
    4689             :                  * There is no point in blacklisting the AP if this event is
    4690             :                  * generated based on local request to disconnect.
    4691             :                  */
    4692         513 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
    4693             :                         "indication since interface has been put into "
    4694             :                         "disconnected state");
    4695        2742 :                 return;
    4696             :         }
    4697             : 
    4698             :         /*
    4699             :          * Add the failed BSSID into the blacklist and speed up next scan
    4700             :          * attempt if there could be other APs that could accept association.
    4701             :          * The current blacklist count indicates how many times we have tried
    4702             :          * connecting to this AP and multiple attempts mean that other APs are
    4703             :          * either not available or has already been tried, so that we can start
    4704             :          * increasing the delay here to avoid constant scanning.
    4705             :          */
    4706        1716 :         count = wpa_blacklist_add(wpa_s, bssid);
    4707        1716 :         if (count == 1 && wpa_s->current_bss) {
    4708             :                 /*
    4709             :                  * This BSS was not in the blacklist before. If there is
    4710             :                  * another BSS available for the same ESS, we should try that
    4711             :                  * next. Otherwise, we may as well try this one once more
    4712             :                  * before allowing other, likely worse, ESSes to be considered.
    4713             :                  */
    4714        1692 :                 freqs = get_bss_freqs_in_ess(wpa_s);
    4715        1692 :                 if (freqs) {
    4716          64 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
    4717             :                                 "has been seen; try it next");
    4718          64 :                         wpa_blacklist_add(wpa_s, bssid);
    4719             :                         /*
    4720             :                          * On the next scan, go through only the known channels
    4721             :                          * used in this ESS based on previous scans to speed up
    4722             :                          * common load balancing use case.
    4723             :                          */
    4724          64 :                         os_free(wpa_s->next_scan_freqs);
    4725          64 :                         wpa_s->next_scan_freqs = freqs;
    4726             :                 }
    4727             :         }
    4728             : 
    4729             :         /*
    4730             :          * Add previous failure count in case the temporary blacklist was
    4731             :          * cleared due to no other BSSes being available.
    4732             :          */
    4733        1716 :         count += wpa_s->extra_blacklist_count;
    4734             : 
    4735        1716 :         if (count > 3 && wpa_s->current_ssid) {
    4736         235 :                 wpa_printf(MSG_DEBUG, "Continuous association failures - "
    4737             :                            "consider temporary network disabling");
    4738         235 :                 wpas_auth_failed(wpa_s, "CONN_FAILED");
    4739             :         }
    4740             : 
    4741        1716 :         switch (count) {
    4742             :         case 1:
    4743        1342 :                 timeout = 100;
    4744        1342 :                 break;
    4745             :         case 2:
    4746         100 :                 timeout = 500;
    4747         100 :                 break;
    4748             :         case 3:
    4749          39 :                 timeout = 1000;
    4750          39 :                 break;
    4751             :         case 4:
    4752          25 :                 timeout = 5000;
    4753          25 :                 break;
    4754             :         default:
    4755         210 :                 timeout = 10000;
    4756         210 :                 break;
    4757             :         }
    4758             : 
    4759        1716 :         wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
    4760             :                 "ms", count, timeout);
    4761             : 
    4762             :         /*
    4763             :          * TODO: if more than one possible AP is available in scan results,
    4764             :          * could try the other ones before requesting a new scan.
    4765             :          */
    4766        1716 :         wpa_supplicant_req_scan(wpa_s, timeout / 1000,
    4767        1716 :                                 1000 * (timeout % 1000));
    4768             : }
    4769             : 
    4770             : 
    4771        1605 : int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
    4772             : {
    4773        3205 :         return wpa_s->conf->ap_scan == 2 ||
    4774        1600 :                 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
    4775             : }
    4776             : 
    4777             : 
    4778             : #if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
    4779          46 : int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
    4780             :                                               struct wpa_ssid *ssid,
    4781             :                                               const char *field,
    4782             :                                               const char *value)
    4783             : {
    4784             : #ifdef IEEE8021X_EAPOL
    4785          46 :         struct eap_peer_config *eap = &ssid->eap;
    4786             : 
    4787          46 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
    4788          46 :         wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
    4789             :                               (const u8 *) value, os_strlen(value));
    4790             : 
    4791          46 :         switch (wpa_supplicant_ctrl_req_from_string(field)) {
    4792             :         case WPA_CTRL_REQ_EAP_IDENTITY:
    4793           3 :                 os_free(eap->identity);
    4794           3 :                 eap->identity = (u8 *) os_strdup(value);
    4795           3 :                 eap->identity_len = os_strlen(value);
    4796           3 :                 eap->pending_req_identity = 0;
    4797           3 :                 if (ssid == wpa_s->current_ssid)
    4798           1 :                         wpa_s->reassociate = 1;
    4799           3 :                 break;
    4800             :         case WPA_CTRL_REQ_EAP_PASSWORD:
    4801           8 :                 bin_clear_free(eap->password, eap->password_len);
    4802           8 :                 eap->password = (u8 *) os_strdup(value);
    4803           8 :                 eap->password_len = os_strlen(value);
    4804           8 :                 eap->pending_req_password = 0;
    4805           8 :                 if (ssid == wpa_s->current_ssid)
    4806           6 :                         wpa_s->reassociate = 1;
    4807           8 :                 break;
    4808             :         case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
    4809           2 :                 bin_clear_free(eap->new_password, eap->new_password_len);
    4810           2 :                 eap->new_password = (u8 *) os_strdup(value);
    4811           2 :                 eap->new_password_len = os_strlen(value);
    4812           2 :                 eap->pending_req_new_password = 0;
    4813           2 :                 if (ssid == wpa_s->current_ssid)
    4814           0 :                         wpa_s->reassociate = 1;
    4815           2 :                 break;
    4816             :         case WPA_CTRL_REQ_EAP_PIN:
    4817           2 :                 str_clear_free(eap->pin);
    4818           2 :                 eap->pin = os_strdup(value);
    4819           2 :                 eap->pending_req_pin = 0;
    4820           2 :                 if (ssid == wpa_s->current_ssid)
    4821           0 :                         wpa_s->reassociate = 1;
    4822           2 :                 break;
    4823             :         case WPA_CTRL_REQ_EAP_OTP:
    4824           4 :                 bin_clear_free(eap->otp, eap->otp_len);
    4825           4 :                 eap->otp = (u8 *) os_strdup(value);
    4826           4 :                 eap->otp_len = os_strlen(value);
    4827           4 :                 os_free(eap->pending_req_otp);
    4828           4 :                 eap->pending_req_otp = NULL;
    4829           4 :                 eap->pending_req_otp_len = 0;
    4830           4 :                 break;
    4831             :         case WPA_CTRL_REQ_EAP_PASSPHRASE:
    4832           3 :                 str_clear_free(eap->private_key_passwd);
    4833           3 :                 eap->private_key_passwd = os_strdup(value);
    4834           3 :                 eap->pending_req_passphrase = 0;
    4835           3 :                 if (ssid == wpa_s->current_ssid)
    4836           1 :                         wpa_s->reassociate = 1;
    4837           3 :                 break;
    4838             :         case WPA_CTRL_REQ_SIM:
    4839          23 :                 str_clear_free(eap->external_sim_resp);
    4840          23 :                 eap->external_sim_resp = os_strdup(value);
    4841          23 :                 break;
    4842             :         default:
    4843           1 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
    4844           1 :                 return -1;
    4845             :         }
    4846             : 
    4847          45 :         return 0;
    4848             : #else /* IEEE8021X_EAPOL */
    4849             :         wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
    4850             :         return -1;
    4851             : #endif /* IEEE8021X_EAPOL */
    4852             : }
    4853             : #endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
    4854             : 
    4855             : 
    4856       13130 : int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
    4857             : {
    4858             :         int i;
    4859             :         unsigned int drv_enc;
    4860             : 
    4861       13130 :         if (ssid == NULL)
    4862           0 :                 return 1;
    4863             : 
    4864       13130 :         if (ssid->disabled)
    4865        2822 :                 return 1;
    4866             : 
    4867       10308 :         if (wpa_s && wpa_s->drv_capa_known)
    4868       10308 :                 drv_enc = wpa_s->drv_enc;
    4869             :         else
    4870           0 :                 drv_enc = (unsigned int) -1;
    4871             : 
    4872       51540 :         for (i = 0; i < NUM_WEP_KEYS; i++) {
    4873       41232 :                 size_t len = ssid->wep_key_len[i];
    4874       41232 :                 if (len == 0)
    4875       41105 :                         continue;
    4876         127 :                 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
    4877          56 :                         continue;
    4878          71 :                 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
    4879          71 :                         continue;
    4880           0 :                 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
    4881           0 :                         continue;
    4882           0 :                 return 1; /* invalid WEP key */
    4883             :         }
    4884             : 
    4885       10337 :         if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
    4886          36 :             (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk)
    4887           0 :                 return 1;
    4888             : 
    4889       10308 :         return 0;
    4890             : }
    4891             : 
    4892             : 
    4893        7882 : int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
    4894             : {
    4895             : #ifdef CONFIG_IEEE80211W
    4896        7882 :         if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
    4897        6674 :                 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
    4898          12 :                     !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
    4899             :                         /*
    4900             :                          * Driver does not support BIP -- ignore pmf=1 default
    4901             :                          * since the connection with PMF would fail and the
    4902             :                          * configuration does not require PMF to be enabled.
    4903             :                          */
    4904           0 :                         return NO_MGMT_FRAME_PROTECTION;
    4905             :                 }
    4906             : 
    4907        6662 :                 return wpa_s->conf->pmf;
    4908             :         }
    4909             : 
    4910        1220 :         return ssid->ieee80211w;
    4911             : #else /* CONFIG_IEEE80211W */
    4912             :         return NO_MGMT_FRAME_PROTECTION;
    4913             : #endif /* CONFIG_IEEE80211W */
    4914             : }
    4915             : 
    4916             : 
    4917          42 : int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
    4918             : {
    4919          42 :         if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
    4920           0 :                 return 1;
    4921          42 :         if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
    4922           0 :                 return 0;
    4923          42 :         return -1;
    4924             : }
    4925             : 
    4926             : 
    4927         479 : void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
    4928             : {
    4929         479 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    4930             :         int dur;
    4931             :         struct os_reltime now;
    4932             : 
    4933         479 :         if (ssid == NULL) {
    4934          14 :                 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
    4935             :                            "SSID block");
    4936          14 :                 return;
    4937             :         }
    4938             : 
    4939         465 :         if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
    4940           8 :                 return;
    4941             : 
    4942         457 :         ssid->auth_failures++;
    4943             : 
    4944             : #ifdef CONFIG_P2P
    4945         460 :         if (ssid->p2p_group &&
    4946           6 :             (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
    4947             :                 /*
    4948             :                  * Skip the wait time since there is a short timeout on the
    4949             :                  * connection to a P2P group.
    4950             :                  */
    4951           3 :                 return;
    4952             :         }
    4953             : #endif /* CONFIG_P2P */
    4954             : 
    4955         454 :         if (ssid->auth_failures > 50)
    4956           0 :                 dur = 300;
    4957         454 :         else if (ssid->auth_failures > 10)
    4958           0 :                 dur = 120;
    4959         454 :         else if (ssid->auth_failures > 5)
    4960           0 :                 dur = 90;
    4961         454 :         else if (ssid->auth_failures > 3)
    4962           0 :                 dur = 60;
    4963         454 :         else if (ssid->auth_failures > 2)
    4964           0 :                 dur = 30;
    4965         454 :         else if (ssid->auth_failures > 1)
    4966         121 :                 dur = 20;
    4967             :         else
    4968         333 :                 dur = 10;
    4969             : 
    4970         575 :         if (ssid->auth_failures > 1 &&
    4971         121 :             wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
    4972         121 :                 dur += os_random() % (ssid->auth_failures * 10);
    4973             : 
    4974         454 :         os_get_reltime(&now);
    4975         454 :         if (now.sec + dur <= ssid->disabled_until.sec)
    4976           0 :                 return;
    4977             : 
    4978         454 :         ssid->disabled_until.sec = now.sec + dur;
    4979             : 
    4980         908 :         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
    4981             :                 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
    4982         454 :                 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
    4983             :                 ssid->auth_failures, dur, reason);
    4984             : }
    4985             : 
    4986             : 
    4987        5162 : void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
    4988             :                               struct wpa_ssid *ssid, int clear_failures)
    4989             : {
    4990        5162 :         if (ssid == NULL)
    4991        5162 :                 return;
    4992             : 
    4993        5162 :         if (ssid->disabled_until.sec) {
    4994          38 :                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
    4995             :                         "id=%d ssid=\"%s\"",
    4996          19 :                         ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
    4997             :         }
    4998        5162 :         ssid->disabled_until.sec = 0;
    4999        5162 :         ssid->disabled_until.usec = 0;
    5000        5162 :         if (clear_failures)
    5001        3774 :                 ssid->auth_failures = 0;
    5002             : }
    5003             : 
    5004             : 
    5005        4039 : int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
    5006             : {
    5007             :         size_t i;
    5008             : 
    5009        4039 :         if (wpa_s->disallow_aps_bssid == NULL)
    5010        4030 :                 return 0;
    5011             : 
    5012          12 :         for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
    5013          10 :                 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
    5014             :                               bssid, ETH_ALEN) == 0)
    5015           7 :                         return 1;
    5016             :         }
    5017             : 
    5018           2 :         return 0;
    5019             : }
    5020             : 
    5021             : 
    5022        4032 : int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
    5023             :                     size_t ssid_len)
    5024             : {
    5025             :         size_t i;
    5026             : 
    5027        4032 :         if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
    5028        4026 :                 return 0;
    5029             : 
    5030           6 :         for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
    5031           6 :                 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
    5032          12 :                 if (ssid_len == s->ssid_len &&
    5033           6 :                     os_memcmp(ssid, s->ssid, ssid_len) == 0)
    5034           6 :                         return 1;
    5035             :         }
    5036             : 
    5037           0 :         return 0;
    5038             : }
    5039             : 
    5040             : 
    5041             : /**
    5042             :  * wpas_request_connection - Request a new connection
    5043             :  * @wpa_s: Pointer to the network interface
    5044             :  *
    5045             :  * This function is used to request a new connection to be found. It will mark
    5046             :  * the interface to allow reassociation and request a new scan to find a
    5047             :  * suitable network to connect to.
    5048             :  */
    5049         119 : void wpas_request_connection(struct wpa_supplicant *wpa_s)
    5050             : {
    5051         119 :         wpa_s->normal_scans = 0;
    5052         119 :         wpa_s->scan_req = NORMAL_SCAN_REQ;
    5053         119 :         wpa_supplicant_reinit_autoscan(wpa_s);
    5054         119 :         wpa_s->extra_blacklist_count = 0;
    5055         119 :         wpa_s->disconnected = 0;
    5056         119 :         wpa_s->reassociate = 1;
    5057             : 
    5058         119 :         if (wpa_supplicant_fast_associate(wpa_s) != 1)
    5059          10 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    5060             :         else
    5061         109 :                 wpa_s->reattach = 0;
    5062         119 : }
    5063             : 
    5064             : 
    5065        3828 : void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
    5066             :                     struct wpa_used_freq_data *freqs_data,
    5067             :                     unsigned int len)
    5068             : {
    5069             :         unsigned int i;
    5070             : 
    5071        3828 :         wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
    5072             :                 len, title);
    5073        4153 :         for (i = 0; i < len; i++) {
    5074         325 :                 struct wpa_used_freq_data *cur = &freqs_data[i];
    5075         325 :                 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
    5076             :                         i, cur->freq, cur->flags);
    5077             :         }
    5078        3828 : }
    5079             : 
    5080             : 
    5081             : /*
    5082             :  * Find the operating frequencies of any of the virtual interfaces that
    5083             :  * are using the same radio as the current interface, and in addition, get
    5084             :  * information about the interface types that are using the frequency.
    5085             :  */
    5086        3388 : int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
    5087             :                                 struct wpa_used_freq_data *freqs_data,
    5088             :                                 unsigned int len)
    5089             : {
    5090             :         struct wpa_supplicant *ifs;
    5091             :         u8 bssid[ETH_ALEN];
    5092             :         int freq;
    5093        3388 :         unsigned int idx = 0, i;
    5094             : 
    5095        3388 :         wpa_dbg(wpa_s, MSG_DEBUG,
    5096             :                 "Determining shared radio frequencies (max len %u)", len);
    5097        3388 :         os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
    5098             : 
    5099        6837 :         dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
    5100             :                          radio_list) {
    5101        3450 :                 if (idx == len)
    5102           1 :                         break;
    5103             : 
    5104        3449 :                 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
    5105        3165 :                         continue;
    5106             : 
    5107         568 :                 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
    5108         284 :                     ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
    5109          16 :                         freq = ifs->current_ssid->frequency;
    5110         268 :                 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
    5111         268 :                         freq = ifs->assoc_freq;
    5112             :                 else
    5113           0 :                         continue;
    5114             : 
    5115             :                 /* Hold only distinct freqs */
    5116         284 :                 for (i = 0; i < idx; i++)
    5117           0 :                         if (freqs_data[i].freq == freq)
    5118           0 :                                 break;
    5119             : 
    5120         284 :                 if (i == idx)
    5121         284 :                         freqs_data[idx++].freq = freq;
    5122             : 
    5123         284 :                 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
    5124         268 :                         freqs_data[i].flags = ifs->current_ssid->p2p_group ?
    5125             :                                 WPA_FREQ_USED_BY_P2P_CLIENT :
    5126             :                                 WPA_FREQ_USED_BY_INFRA_STATION;
    5127             :                 }
    5128             :         }
    5129             : 
    5130        3388 :         dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
    5131        3388 :         return idx;
    5132             : }
    5133             : 
    5134             : 
    5135             : /*
    5136             :  * Find the operating frequencies of any of the virtual interfaces that
    5137             :  * are using the same radio as the current interface.
    5138             :  */
    5139        2946 : int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
    5140             :                            int *freq_array, unsigned int len)
    5141             : {
    5142             :         struct wpa_used_freq_data *freqs_data;
    5143             :         int num, i;
    5144             : 
    5145        2946 :         os_memset(freq_array, 0, sizeof(int) * len);
    5146             : 
    5147        2946 :         freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
    5148        2946 :         if (!freqs_data)
    5149           1 :                 return -1;
    5150             : 
    5151        2945 :         num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
    5152        3181 :         for (i = 0; i < num; i++)
    5153         236 :                 freq_array[i] = freqs_data[i].freq;
    5154             : 
    5155        2945 :         os_free(freqs_data);
    5156             : 
    5157        2945 :         return num;
    5158             : }
    5159             : 
    5160             : 
    5161           2 : static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
    5162             : {
    5163           2 :         struct rrm_data *rrm = data;
    5164             : 
    5165           2 :         if (!rrm->notify_neighbor_rep) {
    5166           0 :                 wpa_printf(MSG_ERROR,
    5167             :                            "RRM: Unexpected neighbor report timeout");
    5168           2 :                 return;
    5169             :         }
    5170             : 
    5171           2 :         wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
    5172           2 :         rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
    5173             : 
    5174           2 :         rrm->notify_neighbor_rep = NULL;
    5175           2 :         rrm->neighbor_rep_cb_ctx = NULL;
    5176             : }
    5177             : 
    5178             : 
    5179             : /*
    5180             :  * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
    5181             :  * @wpa_s: Pointer to wpa_supplicant
    5182             :  */
    5183        4888 : void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
    5184             : {
    5185        4888 :         wpa_s->rrm.rrm_used = 0;
    5186             : 
    5187        4888 :         eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
    5188             :                              NULL);
    5189        4888 :         if (wpa_s->rrm.notify_neighbor_rep)
    5190           0 :                 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
    5191        4888 :         wpa_s->rrm.next_neighbor_rep_token = 1;
    5192        4888 : }
    5193             : 
    5194             : 
    5195             : /*
    5196             :  * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
    5197             :  * @wpa_s: Pointer to wpa_supplicant
    5198             :  * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
    5199             :  * @report_len: Length of neighbor report buffer
    5200             :  */
    5201           0 : void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
    5202             :                                    const u8 *report, size_t report_len)
    5203             : {
    5204             :         struct wpabuf *neighbor_rep;
    5205             : 
    5206           0 :         wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
    5207           0 :         if (report_len < 1)
    5208           0 :                 return;
    5209             : 
    5210           0 :         if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
    5211           0 :                 wpa_printf(MSG_DEBUG,
    5212             :                            "RRM: Discarding neighbor report with token %d (expected %d)",
    5213           0 :                            report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
    5214           0 :                 return;
    5215             :         }
    5216             : 
    5217           0 :         eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
    5218             :                              NULL);
    5219             : 
    5220           0 :         if (!wpa_s->rrm.notify_neighbor_rep) {
    5221           0 :                 wpa_printf(MSG_ERROR, "RRM: Unexpected neighbor report");
    5222           0 :                 return;
    5223             :         }
    5224             : 
    5225             :         /* skipping the first byte, which is only an id (dialog token) */
    5226           0 :         neighbor_rep = wpabuf_alloc(report_len - 1);
    5227           0 :         if (neighbor_rep == NULL)
    5228           0 :                 return;
    5229           0 :         wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
    5230           0 :         wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
    5231           0 :                    report[0]);
    5232           0 :         wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
    5233             :                                        neighbor_rep);
    5234           0 :         wpa_s->rrm.notify_neighbor_rep = NULL;
    5235           0 :         wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
    5236             : }
    5237             : 
    5238             : 
    5239             : #if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
    5240             : /* Workaround different, undefined for Windows, error codes used here */
    5241             : #define ENOTCONN -1
    5242             : #define EOPNOTSUPP -1
    5243             : #define ECANCELED -1
    5244             : #endif
    5245             : 
    5246             : /**
    5247             :  * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
    5248             :  * @wpa_s: Pointer to wpa_supplicant
    5249             :  * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
    5250             :  *        is sent in the request.
    5251             :  * @cb: Callback function to be called once the requested report arrives, or
    5252             :  *      timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
    5253             :  *      In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
    5254             :  *      the requester's responsibility to free it.
    5255             :  *      In the latter case NULL will be sent in 'neighbor_rep'.
    5256             :  * @cb_ctx: Context value to send the callback function
    5257             :  * Returns: 0 in case of success, negative error code otherwise
    5258             :  *
    5259             :  * In case there is a previous request which has not been answered yet, the
    5260             :  * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
    5261             :  * Request must contain a callback function.
    5262             :  */
    5263           4 : int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
    5264             :                                        const struct wpa_ssid *ssid,
    5265             :                                        void (*cb)(void *ctx,
    5266             :                                                   struct wpabuf *neighbor_rep),
    5267             :                                        void *cb_ctx)
    5268             : {
    5269             :         struct wpabuf *buf;
    5270             :         const u8 *rrm_ie;
    5271             : 
    5272           4 :         if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
    5273           0 :                 wpa_printf(MSG_DEBUG, "RRM: No connection, no RRM.");
    5274           0 :                 return -ENOTCONN;
    5275             :         }
    5276             : 
    5277           4 :         if (!wpa_s->rrm.rrm_used) {
    5278           2 :                 wpa_printf(MSG_DEBUG, "RRM: No RRM in current connection.");
    5279           2 :                 return -EOPNOTSUPP;
    5280             :         }
    5281             : 
    5282           2 :         rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
    5283             :                                 WLAN_EID_RRM_ENABLED_CAPABILITIES);
    5284           4 :         if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
    5285           2 :             !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
    5286           0 :                 wpa_printf(MSG_DEBUG,
    5287             :                            "RRM: No network support for Neighbor Report.");
    5288           0 :                 return -EOPNOTSUPP;
    5289             :         }
    5290             : 
    5291           2 :         if (!cb) {
    5292           0 :                 wpa_printf(MSG_DEBUG,
    5293             :                            "RRM: Neighbor Report request must provide a callback.");
    5294           0 :                 return -EINVAL;
    5295             :         }
    5296             : 
    5297             :         /* Refuse if there's a live request */
    5298           2 :         if (wpa_s->rrm.notify_neighbor_rep) {
    5299           0 :                 wpa_printf(MSG_DEBUG,
    5300             :                            "RRM: Currently handling previous Neighbor Report.");
    5301           0 :                 return -EBUSY;
    5302             :         }
    5303             : 
    5304             :         /* 3 = action category + action code + dialog token */
    5305           2 :         buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0));
    5306           2 :         if (buf == NULL) {
    5307           0 :                 wpa_printf(MSG_DEBUG,
    5308             :                            "RRM: Failed to allocate Neighbor Report Request");
    5309           0 :                 return -ENOMEM;
    5310             :         }
    5311             : 
    5312           3 :         wpa_printf(MSG_DEBUG, "RRM: Neighbor report request (for %s), token=%d",
    5313           1 :                    (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
    5314           2 :                    wpa_s->rrm.next_neighbor_rep_token);
    5315             : 
    5316           2 :         wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
    5317           2 :         wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
    5318           2 :         wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
    5319           2 :         if (ssid) {
    5320           1 :                 wpabuf_put_u8(buf, WLAN_EID_SSID);
    5321           1 :                 wpabuf_put_u8(buf, ssid->ssid_len);
    5322           1 :                 wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
    5323             :         }
    5324             : 
    5325           2 :         wpa_s->rrm.next_neighbor_rep_token++;
    5326             : 
    5327           4 :         if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
    5328           2 :                                 wpa_s->own_addr, wpa_s->bssid,
    5329           2 :                                 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
    5330           0 :                 wpa_printf(MSG_DEBUG,
    5331             :                            "RRM: Failed to send Neighbor Report Request");
    5332           0 :                 wpabuf_free(buf);
    5333           0 :                 return -ECANCELED;
    5334             :         }
    5335             : 
    5336           2 :         wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
    5337           2 :         wpa_s->rrm.notify_neighbor_rep = cb;
    5338           2 :         eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
    5339             :                                wpas_rrm_neighbor_rep_timeout_handler,
    5340           2 :                                &wpa_s->rrm, NULL);
    5341             : 
    5342           2 :         wpabuf_free(buf);
    5343           2 :         return 0;
    5344             : }
    5345             : 
    5346             : 
    5347           0 : void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
    5348             :                                               const u8 *src,
    5349             :                                               const u8 *frame, size_t len,
    5350             :                                               int rssi)
    5351             : {
    5352             :         struct wpabuf *buf;
    5353             :         const struct rrm_link_measurement_request *req;
    5354             :         struct rrm_link_measurement_report report;
    5355             : 
    5356           0 :         if (wpa_s->wpa_state != WPA_COMPLETED) {
    5357           0 :                 wpa_printf(MSG_INFO,
    5358             :                            "RRM: Ignoring link measurement request. Not associated");
    5359           0 :                 return;
    5360             :         }
    5361             : 
    5362           0 :         if (!wpa_s->rrm.rrm_used) {
    5363           0 :                 wpa_printf(MSG_INFO,
    5364             :                            "RRM: Ignoring link measurement request. Not RRM network");
    5365           0 :                 return;
    5366             :         }
    5367             : 
    5368           0 :         if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
    5369           0 :                 wpa_printf(MSG_INFO,
    5370             :                            "RRM: Measurement report failed. TX power insertion not supported");
    5371           0 :                 return;
    5372             :         }
    5373             : 
    5374           0 :         req = (const struct rrm_link_measurement_request *) frame;
    5375           0 :         if (len < sizeof(*req)) {
    5376           0 :                 wpa_printf(MSG_INFO,
    5377             :                            "RRM: Link measurement report failed. Request too short");
    5378           0 :                 return;
    5379             :         }
    5380             : 
    5381           0 :         os_memset(&report, 0, sizeof(report));
    5382           0 :         report.tpc.eid = WLAN_EID_TPC_REPORT;
    5383           0 :         report.tpc.len = 2;
    5384           0 :         report.rsni = 255; /* 255 indicates that RSNI is not available */
    5385           0 :         report.dialog_token = req->dialog_token;
    5386             : 
    5387             :         /*
    5388             :          * It's possible to estimate RCPI based on RSSI in dBm. This
    5389             :          * calculation will not reflect the correct value for high rates,
    5390             :          * but it's good enough for Action frames which are transmitted
    5391             :          * with up to 24 Mbps rates.
    5392             :          */
    5393           0 :         if (!rssi)
    5394           0 :                 report.rcpi = 255; /* not available */
    5395           0 :         else if (rssi < -110)
    5396           0 :                 report.rcpi = 0;
    5397           0 :         else if (rssi > 0)
    5398           0 :                 report.rcpi = 220;
    5399             :         else
    5400           0 :                 report.rcpi = (rssi + 110) * 2;
    5401             : 
    5402             :         /* action_category + action_code */
    5403           0 :         buf = wpabuf_alloc(2 + sizeof(report));
    5404           0 :         if (buf == NULL) {
    5405           0 :                 wpa_printf(MSG_ERROR,
    5406             :                            "RRM: Link measurement report failed. Buffer allocation failed");
    5407           0 :                 return;
    5408             :         }
    5409             : 
    5410           0 :         wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
    5411           0 :         wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
    5412           0 :         wpabuf_put_data(buf, &report, sizeof(report));
    5413           0 :         wpa_hexdump(MSG_DEBUG, "RRM: Link measurement report:",
    5414             :                     wpabuf_head(buf), wpabuf_len(buf));
    5415             : 
    5416           0 :         if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
    5417           0 :                                 wpa_s->own_addr, wpa_s->bssid,
    5418           0 :                                 wpabuf_head(buf), wpabuf_len(buf), 0)) {
    5419           0 :                 wpa_printf(MSG_ERROR,
    5420             :                            "RRM: Link measurement report failed. Send action failed");
    5421             :         }
    5422           0 :         wpabuf_free(buf);
    5423             : }

Generated by: LCOV version 1.10