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 1401264779 Lines: 1718 2251 76.3 %
Date: 2014-05-28 Functions: 94 102 92.2 %

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

Generated by: LCOV version 1.10