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 1443382998 Lines: 2348 2825 83.1 %
Date: 2015-09-27 Functions: 120 123 97.6 %

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

Generated by: LCOV version 1.10