LCOV - code coverage report
Current view: top level - wpa_supplicant - wpas_glue.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 355 441 80.5 %
Date: 2014-03-02 Functions: 43 43 100.0 %
Branches: 99 188 52.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * WPA Supplicant - Glue code to setup EAPOL and RSN modules
       3                 :            :  * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
       4                 :            :  *
       5                 :            :  * This software may be distributed under the terms of the BSD license.
       6                 :            :  * See README for more details.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "includes.h"
      10                 :            : 
      11                 :            : #include "common.h"
      12                 :            : #include "eapol_supp/eapol_supp_sm.h"
      13                 :            : #include "rsn_supp/wpa.h"
      14                 :            : #include "eloop.h"
      15                 :            : #include "config.h"
      16                 :            : #include "l2_packet/l2_packet.h"
      17                 :            : #include "common/wpa_common.h"
      18                 :            : #include "wpa_supplicant_i.h"
      19                 :            : #include "driver_i.h"
      20                 :            : #include "rsn_supp/pmksa_cache.h"
      21                 :            : #include "sme.h"
      22                 :            : #include "common/ieee802_11_defs.h"
      23                 :            : #include "common/wpa_ctrl.h"
      24                 :            : #include "wpas_glue.h"
      25                 :            : #include "wps_supplicant.h"
      26                 :            : #include "bss.h"
      27                 :            : #include "scan.h"
      28                 :            : #include "notify.h"
      29                 :            : 
      30                 :            : 
      31                 :            : #ifndef CONFIG_NO_CONFIG_BLOBS
      32                 :            : #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
      33                 :          4 : static void wpa_supplicant_set_config_blob(void *ctx,
      34                 :            :                                            struct wpa_config_blob *blob)
      35                 :            : {
      36                 :          4 :         struct wpa_supplicant *wpa_s = ctx;
      37                 :          4 :         wpa_config_set_blob(wpa_s->conf, blob);
      38         [ -  + ]:          4 :         if (wpa_s->conf->update_config) {
      39                 :          0 :                 int ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
      40         [ #  # ]:          0 :                 if (ret) {
      41                 :          0 :                         wpa_printf(MSG_DEBUG, "Failed to update config after "
      42                 :            :                                    "blob set");
      43                 :            :                 }
      44                 :            :         }
      45                 :          4 : }
      46                 :            : 
      47                 :            : 
      48                 :            : static const struct wpa_config_blob *
      49                 :          7 : wpa_supplicant_get_config_blob(void *ctx, const char *name)
      50                 :            : {
      51                 :          7 :         struct wpa_supplicant *wpa_s = ctx;
      52                 :          7 :         return wpa_config_get_blob(wpa_s->conf, name);
      53                 :            : }
      54                 :            : #endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */
      55                 :            : #endif /* CONFIG_NO_CONFIG_BLOBS */
      56                 :            : 
      57                 :            : 
      58                 :            : #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
      59                 :       2797 : static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
      60                 :            :                             const void *data, u16 data_len,
      61                 :            :                             size_t *msg_len, void **data_pos)
      62                 :            : {
      63                 :            :         struct ieee802_1x_hdr *hdr;
      64                 :            : 
      65                 :       2797 :         *msg_len = sizeof(*hdr) + data_len;
      66                 :       2797 :         hdr = os_malloc(*msg_len);
      67         [ -  + ]:       2797 :         if (hdr == NULL)
      68                 :          0 :                 return NULL;
      69                 :            : 
      70                 :       2797 :         hdr->version = wpa_s->conf->eapol_version;
      71                 :       2797 :         hdr->type = type;
      72                 :       2797 :         hdr->length = host_to_be16(data_len);
      73                 :            : 
      74         [ +  + ]:       2797 :         if (data)
      75                 :       1950 :                 os_memcpy(hdr + 1, data, data_len);
      76                 :            :         else
      77                 :        847 :                 os_memset(hdr + 1, 0, data_len);
      78                 :            : 
      79         [ +  + ]:       2797 :         if (data_pos)
      80                 :        847 :                 *data_pos = hdr + 1;
      81                 :            : 
      82                 :       2797 :         return (u8 *) hdr;
      83                 :            : }
      84                 :            : 
      85                 :            : 
      86                 :            : /**
      87                 :            :  * wpa_ether_send - Send Ethernet frame
      88                 :            :  * @wpa_s: Pointer to wpa_supplicant data
      89                 :            :  * @dest: Destination MAC address
      90                 :            :  * @proto: Ethertype in host byte order
      91                 :            :  * @buf: Frame payload starting from IEEE 802.1X header
      92                 :            :  * @len: Frame payload length
      93                 :            :  * Returns: >=0 on success, <0 on failure
      94                 :            :  */
      95                 :       2794 : static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
      96                 :            :                           u16 proto, const u8 *buf, size_t len)
      97                 :            : {
      98         [ +  - ]:       2794 :         if (wpa_s->l2) {
      99                 :       2794 :                 return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
     100                 :            :         }
     101                 :            : 
     102                 :       2794 :         return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len);
     103                 :            : }
     104                 :            : #endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
     105                 :            : 
     106                 :            : 
     107                 :            : #ifdef IEEE8021X_EAPOL
     108                 :            : 
     109                 :            : /**
     110                 :            :  * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
     111                 :            :  * @ctx: Pointer to wpa_supplicant data (wpa_s)
     112                 :            :  * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
     113                 :            :  * @buf: EAPOL payload (after IEEE 802.1X header)
     114                 :            :  * @len: EAPOL payload length
     115                 :            :  * Returns: >=0 on success, <0 on failure
     116                 :            :  *
     117                 :            :  * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
     118                 :            :  * to the current Authenticator.
     119                 :            :  */
     120                 :       1947 : static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
     121                 :            :                                      size_t len)
     122                 :            : {
     123                 :       1947 :         struct wpa_supplicant *wpa_s = ctx;
     124                 :            :         u8 *msg, *dst, bssid[ETH_ALEN];
     125                 :            :         size_t msglen;
     126                 :            :         int res;
     127                 :            : 
     128                 :            :         /* TODO: could add l2_packet_sendmsg that allows fragments to avoid
     129                 :            :          * extra copy here */
     130                 :            : 
     131 [ +  - ][ -  + ]:       1947 :         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
     132                 :       1947 :             wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
     133                 :            :                 /* Current SSID is not using IEEE 802.1X/EAP, so drop possible
     134                 :            :                  * EAPOL frames (mainly, EAPOL-Start) from EAPOL state
     135                 :            :                  * machines. */
     136                 :          0 :                 wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X "
     137                 :            :                            "mode (type=%d len=%lu)", type,
     138                 :            :                            (unsigned long) len);
     139                 :          0 :                 return -1;
     140                 :            :         }
     141                 :            : 
     142 [ -  + ][ #  # ]:       1947 :         if (pmksa_cache_get_current(wpa_s->wpa) &&
     143                 :            :             type == IEEE802_1X_TYPE_EAPOL_START) {
     144                 :            :                 /* Trying to use PMKSA caching - do not send EAPOL-Start frames
     145                 :            :                  * since they will trigger full EAPOL authentication. */
     146                 :          0 :                 wpa_printf(MSG_DEBUG, "RSN: PMKSA caching - do not send "
     147                 :            :                            "EAPOL-Start");
     148                 :          0 :                 return -1;
     149                 :            :         }
     150                 :            : 
     151         [ -  + ]:       1947 :         if (is_zero_ether_addr(wpa_s->bssid)) {
     152                 :          0 :                 wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
     153                 :            :                            "EAPOL frame");
     154   [ #  #  #  # ]:          0 :                 if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
     155                 :          0 :                     !is_zero_ether_addr(bssid)) {
     156                 :          0 :                         dst = bssid;
     157                 :          0 :                         wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
     158                 :            :                                    " from the driver as the EAPOL destination",
     159                 :          0 :                                    MAC2STR(dst));
     160                 :            :                 } else {
     161                 :          0 :                         dst = wpa_s->last_eapol_src;
     162                 :          0 :                         wpa_printf(MSG_DEBUG, "Using the source address of the"
     163                 :            :                                    " last received EAPOL frame " MACSTR " as "
     164                 :            :                                    "the EAPOL destination",
     165                 :          0 :                                    MAC2STR(dst));
     166                 :            :                 }
     167                 :            :         } else {
     168                 :            :                 /* BSSID was already set (from (Re)Assoc event, so use it as
     169                 :            :                  * the EAPOL destination. */
     170                 :       1947 :                 dst = wpa_s->bssid;
     171                 :            :         }
     172                 :            : 
     173                 :       1947 :         msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL);
     174         [ -  + ]:       1947 :         if (msg == NULL)
     175                 :          0 :                 return -1;
     176                 :            : 
     177                 :       1947 :         wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst));
     178                 :       1947 :         wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
     179                 :       1947 :         res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
     180                 :       1947 :         os_free(msg);
     181                 :       1947 :         return res;
     182                 :            : }
     183                 :            : 
     184                 :            : 
     185                 :            : /**
     186                 :            :  * wpa_eapol_set_wep_key - set WEP key for the driver
     187                 :            :  * @ctx: Pointer to wpa_supplicant data (wpa_s)
     188                 :            :  * @unicast: 1 = individual unicast key, 0 = broadcast key
     189                 :            :  * @keyidx: WEP key index (0..3)
     190                 :            :  * @key: Pointer to key data
     191                 :            :  * @keylen: Key length in bytes
     192                 :            :  * Returns: 0 on success or < 0 on error.
     193                 :            :  */
     194                 :          4 : static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
     195                 :            :                                  const u8 *key, size_t keylen)
     196                 :            : {
     197                 :          4 :         struct wpa_supplicant *wpa_s = ctx;
     198         [ +  - ]:          4 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
     199         [ +  + ]:          4 :                 int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
     200                 :            :                         WPA_CIPHER_WEP104;
     201         [ +  + ]:          4 :                 if (unicast)
     202                 :          2 :                         wpa_s->pairwise_cipher = cipher;
     203                 :            :                 else
     204                 :          2 :                         wpa_s->group_cipher = cipher;
     205                 :            :         }
     206         [ +  + ]:          4 :         return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
     207                 :            :                                unicast ? wpa_s->bssid : NULL,
     208                 :            :                                keyidx, unicast, NULL, 0, key, keylen);
     209                 :            : }
     210                 :            : 
     211                 :            : 
     212                 :          9 : static void wpa_supplicant_aborted_cached(void *ctx)
     213                 :            : {
     214                 :          9 :         struct wpa_supplicant *wpa_s = ctx;
     215                 :          9 :         wpa_sm_aborted_cached(wpa_s->wpa);
     216                 :          9 : }
     217                 :            : 
     218                 :            : 
     219                 :        590 : static const char * result_str(enum eapol_supp_result result)
     220                 :            : {
     221   [ +  +  +  - ]:        590 :         switch (result) {
     222                 :            :         case EAPOL_SUPP_RESULT_FAILURE:
     223                 :        167 :                 return "FAILURE";
     224                 :            :         case EAPOL_SUPP_RESULT_SUCCESS:
     225                 :        422 :                 return "SUCCESS";
     226                 :            :         case EAPOL_SUPP_RESULT_EXPECTED_FAILURE:
     227                 :          1 :                 return "EXPECTED_FAILURE";
     228                 :            :         }
     229                 :        590 :         return "?";
     230                 :            : }
     231                 :            : 
     232                 :            : 
     233                 :        590 : static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol,
     234                 :            :                                     enum eapol_supp_result result,
     235                 :            :                                     void *ctx)
     236                 :            : {
     237                 :        590 :         struct wpa_supplicant *wpa_s = ctx;
     238                 :            :         int res, pmk_len;
     239                 :            :         u8 pmk[PMK_LEN];
     240                 :            : 
     241                 :        590 :         wpa_printf(MSG_DEBUG, "EAPOL authentication completed - result=%s",
     242                 :            :                    result_str(result));
     243                 :            : 
     244         [ +  + ]:        590 :         if (wpas_wps_eapol_cb(wpa_s) > 0)
     245                 :        142 :                 return;
     246                 :            : 
     247                 :        448 :         wpa_s->eap_expected_failure = result ==
     248                 :            :                 EAPOL_SUPP_RESULT_EXPECTED_FAILURE;
     249                 :            : 
     250         [ +  + ]:        448 :         if (result != EAPOL_SUPP_RESULT_SUCCESS) {
     251                 :            :                 /*
     252                 :            :                  * Make sure we do not get stuck here waiting for long EAPOL
     253                 :            :                  * timeout if the AP does not disconnect in case of
     254                 :            :                  * authentication failure.
     255                 :            :                  */
     256                 :         26 :                 wpa_supplicant_req_auth_timeout(wpa_s, 2, 0);
     257                 :            :         }
     258                 :            : 
     259 [ +  + ][ +  - ]:        448 :         if (result != EAPOL_SUPP_RESULT_SUCCESS ||
     260                 :        422 :             !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
     261                 :        448 :                 return;
     262                 :            : 
     263         [ #  # ]:          0 :         if (!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt))
     264                 :          0 :                 return;
     265                 :            : 
     266                 :          0 :         wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
     267                 :            :                    "handshake");
     268                 :            : 
     269                 :          0 :         pmk_len = PMK_LEN;
     270         [ #  # ]:          0 :         if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
     271                 :            : #ifdef CONFIG_IEEE80211R
     272                 :            :                 u8 buf[2 * PMK_LEN];
     273                 :          0 :                 wpa_printf(MSG_DEBUG, "RSN: Use FT XXKey as PMK for "
     274                 :            :                            "driver-based 4-way hs and FT");
     275                 :          0 :                 res = eapol_sm_get_key(eapol, buf, 2 * PMK_LEN);
     276         [ #  # ]:          0 :                 if (res == 0) {
     277                 :          0 :                         os_memcpy(pmk, buf + PMK_LEN, PMK_LEN);
     278                 :          0 :                         os_memset(buf, 0, sizeof(buf));
     279                 :            :                 }
     280                 :            : #else /* CONFIG_IEEE80211R */
     281                 :            :                 res = -1;
     282                 :            : #endif /* CONFIG_IEEE80211R */
     283                 :            :         } else {
     284                 :          0 :                 res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
     285         [ #  # ]:          0 :                 if (res) {
     286                 :            :                         /*
     287                 :            :                          * EAP-LEAP is an exception from other EAP methods: it
     288                 :            :                          * uses only 16-byte PMK.
     289                 :            :                          */
     290                 :          0 :                         res = eapol_sm_get_key(eapol, pmk, 16);
     291                 :          0 :                         pmk_len = 16;
     292                 :            :                 }
     293                 :            :         }
     294                 :            : 
     295         [ #  # ]:          0 :         if (res) {
     296                 :          0 :                 wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
     297                 :            :                            "machines");
     298                 :          0 :                 return;
     299                 :            :         }
     300                 :            : 
     301                 :          0 :         wpa_hexdump_key(MSG_DEBUG, "RSN: Configure PMK for driver-based 4-way "
     302                 :            :                         "handshake", pmk, pmk_len);
     303                 :            : 
     304         [ #  # ]:          0 :         if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
     305                 :            :                             pmk_len)) {
     306                 :          0 :                 wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
     307                 :            :         }
     308                 :            : 
     309                 :          0 :         wpa_supplicant_cancel_scan(wpa_s);
     310                 :          0 :         wpa_supplicant_cancel_auth_timeout(wpa_s);
     311                 :        590 :         wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
     312                 :            : 
     313                 :            : }
     314                 :            : 
     315                 :            : 
     316                 :          4 : static void wpa_supplicant_notify_eapol_done(void *ctx)
     317                 :            : {
     318                 :          4 :         struct wpa_supplicant *wpa_s = ctx;
     319                 :          4 :         wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
     320         [ -  + ]:          4 :         if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
     321                 :          0 :                 wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
     322                 :            :         } else {
     323                 :          4 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
     324                 :          4 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
     325                 :            :         }
     326                 :          4 : }
     327                 :            : 
     328                 :            : #endif /* IEEE8021X_EAPOL */
     329                 :            : 
     330                 :            : 
     331                 :            : #ifndef CONFIG_NO_WPA
     332                 :            : 
     333                 :          1 : static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
     334                 :            : {
     335                 :          1 :         int ret = 0;
     336                 :          1 :         struct wpa_bss *curr = NULL, *bss;
     337                 :          1 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
     338                 :            :         const u8 *ie;
     339                 :            : 
     340         [ +  - ]:          1 :         dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
     341         [ -  + ]:          1 :                 if (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) != 0)
     342                 :          0 :                         continue;
     343 [ +  - ][ +  - ]:          1 :                 if (ssid == NULL ||
     344         [ -  + ]:          1 :                     ((bss->ssid_len == ssid->ssid_len &&
     345         [ #  # ]:          0 :                       os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) == 0) ||
     346                 :          0 :                      ssid->ssid_len == 0)) {
     347                 :          1 :                         curr = bss;
     348                 :          1 :                         break;
     349                 :            :                 }
     350                 :            :         }
     351                 :            : 
     352         [ +  - ]:          1 :         if (curr) {
     353                 :          1 :                 ie = wpa_bss_get_vendor_ie(curr, WPA_IE_VENDOR_TYPE);
     354 [ -  + ][ -  + ]:          1 :                 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
     355                 :          0 :                         ret = -1;
     356                 :            : 
     357                 :          1 :                 ie = wpa_bss_get_ie(curr, WLAN_EID_RSN);
     358 [ -  + ][ -  + ]:          1 :                 if (wpa_sm_set_ap_rsn_ie(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0))
     359                 :          0 :                         ret = -1;
     360                 :            :         } else {
     361                 :          0 :                 ret = -1;
     362                 :            :         }
     363                 :            : 
     364                 :          1 :         return ret;
     365                 :            : }
     366                 :            : 
     367                 :            : 
     368                 :          1 : static int wpa_supplicant_get_beacon_ie(void *ctx)
     369                 :            : {
     370                 :          1 :         struct wpa_supplicant *wpa_s = ctx;
     371         [ +  - ]:          1 :         if (wpa_get_beacon_ie(wpa_s) == 0) {
     372                 :          1 :                 return 0;
     373                 :            :         }
     374                 :            : 
     375                 :            :         /* No WPA/RSN IE found in the cached scan results. Try to get updated
     376                 :            :          * scan results from the driver. */
     377         [ #  # ]:          0 :         if (wpa_supplicant_update_scan_results(wpa_s) < 0)
     378                 :          0 :                 return -1;
     379                 :            : 
     380                 :          1 :         return wpa_get_beacon_ie(wpa_s);
     381                 :            : }
     382                 :            : 
     383                 :            : 
     384                 :        850 : static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
     385                 :            :                              const void *data, u16 data_len,
     386                 :            :                              size_t *msg_len, void **data_pos)
     387                 :            : {
     388                 :        850 :         return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
     389                 :            : }
     390                 :            : 
     391                 :            : 
     392                 :        847 : static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
     393                 :            :                            const u8 *buf, size_t len)
     394                 :            : {
     395                 :        847 :         return wpa_ether_send(wpa_s, dest, proto, buf, len);
     396                 :            : }
     397                 :            : 
     398                 :            : 
     399                 :        419 : static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
     400                 :            : {
     401                 :        419 :         wpa_supplicant_cancel_auth_timeout(wpa_s);
     402                 :        419 : }
     403                 :            : 
     404                 :            : 
     405                 :       1662 : static void _wpa_supplicant_set_state(void *wpa_s, enum wpa_states state)
     406                 :            : {
     407                 :       1662 :         wpa_supplicant_set_state(wpa_s, state);
     408                 :       1662 : }
     409                 :            : 
     410                 :            : 
     411                 :            : /**
     412                 :            :  * wpa_supplicant_get_state - Get the connection state
     413                 :            :  * @wpa_s: Pointer to wpa_supplicant data
     414                 :            :  * Returns: The current connection state (WPA_*)
     415                 :            :  */
     416                 :       1248 : static enum wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
     417                 :            : {
     418                 :       1248 :         return wpa_s->wpa_state;
     419                 :            : }
     420                 :            : 
     421                 :            : 
     422                 :       1248 : static enum wpa_states _wpa_supplicant_get_state(void *wpa_s)
     423                 :            : {
     424                 :       1248 :         return wpa_supplicant_get_state(wpa_s);
     425                 :            : }
     426                 :            : 
     427                 :            : 
     428                 :         27 : static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
     429                 :            : {
     430                 :         27 :         wpa_supplicant_deauthenticate(wpa_s, reason_code);
     431                 :            :         /* Schedule a scan to make sure we continue looking for networks */
     432                 :         27 :         wpa_supplicant_req_scan(wpa_s, 5, 0);
     433                 :         27 : }
     434                 :            : 
     435                 :            : 
     436                 :        430 : static void * wpa_supplicant_get_network_ctx(void *wpa_s)
     437                 :            : {
     438                 :        430 :         return wpa_supplicant_get_ssid(wpa_s);
     439                 :            : }
     440                 :            : 
     441                 :            : 
     442                 :          1 : static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
     443                 :            : {
     444                 :          1 :         struct wpa_supplicant *wpa_s = ctx;
     445                 :          1 :         return wpa_drv_get_bssid(wpa_s, bssid);
     446                 :            : }
     447                 :            : 
     448                 :            : 
     449                 :        941 : static int wpa_supplicant_set_key(void *_wpa_s, enum wpa_alg alg,
     450                 :            :                                   const u8 *addr, int key_idx, int set_tx,
     451                 :            :                                   const u8 *seq, size_t seq_len,
     452                 :            :                                   const u8 *key, size_t key_len)
     453                 :            : {
     454                 :        941 :         struct wpa_supplicant *wpa_s = _wpa_s;
     455 [ +  + ][ +  + ]:        941 :         if (alg == WPA_ALG_TKIP && key_idx == 0 && key_len == 32) {
                 [ +  - ]
     456                 :            :                 /* Clear the MIC error counter when setting a new PTK. */
     457                 :          9 :                 wpa_s->mic_errors_seen = 0;
     458                 :            :         }
     459                 :            : #ifdef CONFIG_TESTING_GET_GTK
     460                 :            :         if (key_idx > 0 && addr && is_broadcast_ether_addr(addr) &&
     461                 :            :             alg != WPA_ALG_NONE && key_len <= sizeof(wpa_s->last_gtk)) {
     462                 :            :                 os_memcpy(wpa_s->last_gtk, key, key_len);
     463                 :            :                 wpa_s->last_gtk_len = key_len;
     464                 :            :         }
     465                 :            : #endif /* CONFIG_TESTING_GET_GTK */
     466                 :        941 :         return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
     467                 :            :                                key, key_len);
     468                 :            : }
     469                 :            : 
     470                 :            : 
     471                 :        812 : static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
     472                 :            :                                              int protection_type,
     473                 :            :                                              int key_type)
     474                 :            : {
     475                 :        812 :         return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
     476                 :            :                                           key_type);
     477                 :            : }
     478                 :            : 
     479                 :            : 
     480                 :        172 : static int wpa_supplicant_add_pmkid(void *wpa_s,
     481                 :            :                                     const u8 *bssid, const u8 *pmkid)
     482                 :            : {
     483                 :        172 :         return wpa_drv_add_pmkid(wpa_s, bssid, pmkid);
     484                 :            : }
     485                 :            : 
     486                 :            : 
     487                 :        172 : static int wpa_supplicant_remove_pmkid(void *wpa_s,
     488                 :            :                                        const u8 *bssid, const u8 *pmkid)
     489                 :            : {
     490                 :        172 :         return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid);
     491                 :            : }
     492                 :            : 
     493                 :            : 
     494                 :            : #ifdef CONFIG_IEEE80211R
     495                 :         76 : static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
     496                 :            :                                         const u8 *ies, size_t ies_len)
     497                 :            : {
     498                 :         76 :         struct wpa_supplicant *wpa_s = ctx;
     499         [ +  - ]:         76 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
     500                 :         76 :                 return sme_update_ft_ies(wpa_s, md, ies, ies_len);
     501                 :         76 :         return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
     502                 :            : }
     503                 :            : 
     504                 :            : 
     505                 :          6 : static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
     506                 :            :                                          const u8 *target_ap,
     507                 :            :                                          const u8 *ies, size_t ies_len)
     508                 :            : {
     509                 :          6 :         struct wpa_supplicant *wpa_s = ctx;
     510                 :          6 :         return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len);
     511                 :            : }
     512                 :            : 
     513                 :            : 
     514                 :         16 : static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap)
     515                 :            : {
     516                 :         16 :         struct wpa_supplicant *wpa_s = ctx;
     517                 :            :         struct wpa_driver_auth_params params;
     518                 :            :         struct wpa_bss *bss;
     519                 :            : 
     520                 :         16 :         bss = wpa_bss_get_bssid(wpa_s, target_ap);
     521         [ -  + ]:         16 :         if (bss == NULL)
     522                 :          0 :                 return -1;
     523                 :            : 
     524                 :         16 :         os_memset(&params, 0, sizeof(params));
     525                 :         16 :         params.bssid = target_ap;
     526                 :         16 :         params.freq = bss->freq;
     527                 :         16 :         params.ssid = bss->ssid;
     528                 :         16 :         params.ssid_len = bss->ssid_len;
     529                 :         16 :         params.auth_alg = WPA_AUTH_ALG_FT;
     530                 :         16 :         params.local_state_change = 1;
     531                 :         16 :         return wpa_drv_authenticate(wpa_s, &params);
     532                 :            : }
     533                 :            : #endif /* CONFIG_IEEE80211R */
     534                 :            : 
     535                 :            : 
     536                 :            : #ifdef CONFIG_TDLS
     537                 :            : 
     538                 :         39 : static int wpa_supplicant_tdls_get_capa(void *ctx, int *tdls_supported,
     539                 :            :                                         int *tdls_ext_setup)
     540                 :            : {
     541                 :         39 :         struct wpa_supplicant *wpa_s = ctx;
     542                 :            : 
     543                 :         39 :         *tdls_supported = 0;
     544                 :         39 :         *tdls_ext_setup = 0;
     545                 :            : 
     546         [ -  + ]:         39 :         if (!wpa_s->drv_capa_known)
     547                 :          0 :                 return -1;
     548                 :            : 
     549         [ +  - ]:         39 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)
     550                 :         39 :                 *tdls_supported = 1;
     551                 :            : 
     552         [ +  - ]:         39 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP)
     553                 :         39 :                 *tdls_ext_setup = 1;
     554                 :            : 
     555                 :         39 :         return 0;
     556                 :            : }
     557                 :            : 
     558                 :            : 
     559                 :        106 : static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
     560                 :            :                                          u8 action_code, u8 dialog_token,
     561                 :            :                                          u16 status_code, const u8 *buf,
     562                 :            :                                          size_t len)
     563                 :            : {
     564                 :        106 :         struct wpa_supplicant *wpa_s = ctx;
     565                 :        106 :         return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
     566                 :            :                                       status_code, buf, len);
     567                 :            : }
     568                 :            : 
     569                 :            : 
     570                 :         98 : static int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer)
     571                 :            : {
     572                 :         98 :         struct wpa_supplicant *wpa_s = ctx;
     573                 :         98 :         return wpa_drv_tdls_oper(wpa_s, oper, peer);
     574                 :            : }
     575                 :            : 
     576                 :            : 
     577                 :         81 : static int wpa_supplicant_tdls_peer_addset(
     578                 :            :         void *ctx, const u8 *peer, int add, u16 aid, u16 capability,
     579                 :            :         const u8 *supp_rates, size_t supp_rates_len,
     580                 :            :         const struct ieee80211_ht_capabilities *ht_capab,
     581                 :            :         const struct ieee80211_vht_capabilities *vht_capab,
     582                 :            :         u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len,
     583                 :            :         const u8 *supp_channels, size_t supp_channels_len,
     584                 :            :         const u8 *supp_oper_classes, size_t supp_oper_classes_len)
     585                 :            : {
     586                 :         81 :         struct wpa_supplicant *wpa_s = ctx;
     587                 :            :         struct hostapd_sta_add_params params;
     588                 :            : 
     589                 :         81 :         os_memset(&params, 0, sizeof(params));
     590                 :            : 
     591                 :         81 :         params.addr = peer;
     592                 :         81 :         params.aid = aid;
     593                 :         81 :         params.capability = capability;
     594                 :         81 :         params.flags = WPA_STA_TDLS_PEER | WPA_STA_AUTHORIZED;
     595                 :            : 
     596                 :            :         /*
     597                 :            :          * TDLS Setup frames do not contain WMM IEs, hence need to depend on
     598                 :            :          * qosinfo to check if the peer is WMM capable.
     599                 :            :          */
     600         [ -  + ]:         81 :         if (qosinfo)
     601                 :          0 :                 params.flags |= WPA_STA_WMM;
     602                 :            : 
     603                 :         81 :         params.ht_capabilities = ht_capab;
     604                 :         81 :         params.vht_capabilities = vht_capab;
     605                 :         81 :         params.qosinfo = qosinfo;
     606                 :         81 :         params.listen_interval = 0;
     607                 :         81 :         params.supp_rates = supp_rates;
     608                 :         81 :         params.supp_rates_len = supp_rates_len;
     609                 :         81 :         params.set = !add;
     610                 :         81 :         params.ext_capab = ext_capab;
     611                 :         81 :         params.ext_capab_len = ext_capab_len;
     612                 :         81 :         params.supp_channels = supp_channels;
     613                 :         81 :         params.supp_channels_len = supp_channels_len;
     614                 :         81 :         params.supp_oper_classes = supp_oper_classes;
     615                 :         81 :         params.supp_oper_classes_len = supp_oper_classes_len;
     616                 :            : 
     617                 :         81 :         return wpa_drv_sta_add(wpa_s, &params);
     618                 :            : }
     619                 :            : 
     620                 :            : #endif /* CONFIG_TDLS */
     621                 :            : 
     622                 :            : #endif /* CONFIG_NO_WPA */
     623                 :            : 
     624                 :            : 
     625                 :         12 : enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
     626                 :            : {
     627         [ +  + ]:         12 :         if (os_strcmp(field, "IDENTITY") == 0)
     628                 :          1 :                 return WPA_CTRL_REQ_EAP_IDENTITY;
     629         [ +  + ]:         11 :         else if (os_strcmp(field, "PASSWORD") == 0)
     630                 :          5 :                 return WPA_CTRL_REQ_EAP_PASSWORD;
     631         [ -  + ]:          6 :         else if (os_strcmp(field, "NEW_PASSWORD") == 0)
     632                 :          0 :                 return WPA_CTRL_REQ_EAP_NEW_PASSWORD;
     633         [ -  + ]:          6 :         else if (os_strcmp(field, "PIN") == 0)
     634                 :          0 :                 return WPA_CTRL_REQ_EAP_PIN;
     635         [ +  + ]:          6 :         else if (os_strcmp(field, "OTP") == 0)
     636                 :          1 :                 return WPA_CTRL_REQ_EAP_OTP;
     637         [ +  + ]:          5 :         else if (os_strcmp(field, "PASSPHRASE") == 0)
     638                 :          1 :                 return WPA_CTRL_REQ_EAP_PASSPHRASE;
     639         [ +  - ]:          4 :         else if (os_strcmp(field, "SIM") == 0)
     640                 :          4 :                 return WPA_CTRL_REQ_SIM;
     641                 :         12 :         return WPA_CTRL_REQ_UNKNOWN;
     642                 :            : }
     643                 :            : 
     644                 :            : 
     645                 :         13 : const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
     646                 :            :                                                const char *default_txt,
     647                 :            :                                                const char **txt)
     648                 :            : {
     649                 :         13 :         const char *ret = NULL;
     650                 :            : 
     651                 :         13 :         *txt = default_txt;
     652                 :            : 
     653   [ +  +  -  -  :         13 :         switch (field) {
             +  +  +  - ]
     654                 :            :         case WPA_CTRL_REQ_EAP_IDENTITY:
     655                 :          1 :                 *txt = "Identity";
     656                 :          1 :                 ret = "IDENTITY";
     657                 :          1 :                 break;
     658                 :            :         case WPA_CTRL_REQ_EAP_PASSWORD:
     659                 :          6 :                 *txt = "Password";
     660                 :          6 :                 ret = "PASSWORD";
     661                 :          6 :                 break;
     662                 :            :         case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
     663                 :          0 :                 *txt = "New Password";
     664                 :          0 :                 ret = "NEW_PASSWORD";
     665                 :          0 :                 break;
     666                 :            :         case WPA_CTRL_REQ_EAP_PIN:
     667                 :          0 :                 *txt = "PIN";
     668                 :          0 :                 ret = "PIN";
     669                 :          0 :                 break;
     670                 :            :         case WPA_CTRL_REQ_EAP_OTP:
     671                 :          1 :                 ret = "OTP";
     672                 :          1 :                 break;
     673                 :            :         case WPA_CTRL_REQ_EAP_PASSPHRASE:
     674                 :          1 :                 *txt = "Private key passphrase";
     675                 :          1 :                 ret = "PASSPHRASE";
     676                 :          1 :                 break;
     677                 :            :         case WPA_CTRL_REQ_SIM:
     678                 :          4 :                 ret = "SIM";
     679                 :          4 :                 break;
     680                 :            :         default:
     681                 :          0 :                 break;
     682                 :            :         }
     683                 :            : 
     684                 :            :         /* txt needs to be something */
     685         [ -  + ]:         13 :         if (*txt == NULL) {
     686                 :          0 :                 wpa_printf(MSG_WARNING, "No message for request %d", field);
     687                 :          0 :                 ret = NULL;
     688                 :            :         }
     689                 :            : 
     690                 :         13 :         return ret;
     691                 :            : }
     692                 :            : 
     693                 :            : #ifdef IEEE8021X_EAPOL
     694                 :            : #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
     695                 :         13 : static void wpa_supplicant_eap_param_needed(void *ctx,
     696                 :            :                                             enum wpa_ctrl_req_type field,
     697                 :            :                                             const char *default_txt)
     698                 :            : {
     699                 :         13 :         struct wpa_supplicant *wpa_s = ctx;
     700                 :         13 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
     701                 :         13 :         const char *field_name, *txt = NULL;
     702                 :            :         char *buf;
     703                 :            :         size_t buflen;
     704                 :            :         int len;
     705                 :            : 
     706         [ -  + ]:         13 :         if (ssid == NULL)
     707                 :          0 :                 return;
     708                 :            : 
     709                 :         13 :         wpas_notify_network_request(wpa_s, ssid, field, default_txt);
     710                 :            : 
     711                 :         13 :         field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,
     712                 :            :                                                        &txt);
     713         [ -  + ]:         13 :         if (field_name == NULL) {
     714                 :          0 :                 wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed",
     715                 :            :                            field);
     716                 :          0 :                 return;
     717                 :            :         }
     718                 :            : 
     719                 :         13 :         wpas_notify_eap_status(wpa_s, "eap parameter needed", field_name);
     720                 :            : 
     721                 :         13 :         buflen = 100 + os_strlen(txt) + ssid->ssid_len;
     722                 :         13 :         buf = os_malloc(buflen);
     723         [ -  + ]:         13 :         if (buf == NULL)
     724                 :          0 :                 return;
     725                 :         13 :         len = os_snprintf(buf, buflen,
     726                 :            :                           WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
     727                 :            :                           field_name, ssid->id, txt);
     728 [ +  - ][ -  + ]:         13 :         if (len < 0 || (size_t) len >= buflen) {
     729                 :          0 :                 os_free(buf);
     730                 :          0 :                 return;
     731                 :            :         }
     732 [ +  - ][ +  - ]:         13 :         if (ssid->ssid && buflen > len + ssid->ssid_len) {
     733                 :         13 :                 os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
     734                 :         13 :                 len += ssid->ssid_len;
     735                 :         13 :                 buf[len] = '\0';
     736                 :            :         }
     737                 :         13 :         buf[buflen - 1] = '\0';
     738                 :         13 :         wpa_msg(wpa_s, MSG_INFO, "%s", buf);
     739                 :         13 :         os_free(buf);
     740                 :            : }
     741                 :            : #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
     742                 :            : #define wpa_supplicant_eap_param_needed NULL
     743                 :            : #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
     744                 :            : 
     745                 :            : 
     746                 :       1402 : static void wpa_supplicant_port_cb(void *ctx, int authorized)
     747                 :            : {
     748                 :       1402 :         struct wpa_supplicant *wpa_s = ctx;
     749                 :            : #ifdef CONFIG_AP
     750         [ -  + ]:       1402 :         if (wpa_s->ap_iface) {
     751         [ #  # ]:          0 :                 wpa_printf(MSG_DEBUG, "AP mode active - skip EAPOL Supplicant "
     752                 :            :                            "port status: %s",
     753                 :            :                            authorized ? "Authorized" : "Unauthorized");
     754                 :       1402 :                 return;
     755                 :            :         }
     756                 :            : #endif /* CONFIG_AP */
     757         [ +  + ]:       1402 :         wpa_printf(MSG_DEBUG, "EAPOL: Supplicant port status: %s",
     758                 :            :                    authorized ? "Authorized" : "Unauthorized");
     759                 :       1402 :         wpa_drv_set_supp_port(wpa_s, authorized);
     760                 :            : }
     761                 :            : 
     762                 :            : 
     763                 :        307 : static void wpa_supplicant_cert_cb(void *ctx, int depth, const char *subject,
     764                 :            :                                    const char *cert_hash,
     765                 :            :                                    const struct wpabuf *cert)
     766                 :            : {
     767                 :        307 :         struct wpa_supplicant *wpa_s = ctx;
     768                 :            : 
     769                 :        307 :         wpas_notify_certification(wpa_s, depth, subject, cert_hash, cert);
     770                 :        307 : }
     771                 :            : 
     772                 :            : 
     773                 :       1412 : static void wpa_supplicant_status_cb(void *ctx, const char *status,
     774                 :            :                                      const char *parameter)
     775                 :            : {
     776                 :       1412 :         struct wpa_supplicant *wpa_s = ctx;
     777                 :            : 
     778                 :       1412 :         wpas_notify_eap_status(wpa_s, status, parameter);
     779                 :       1412 : }
     780                 :            : 
     781                 :            : 
     782                 :         12 : static void wpa_supplicant_set_anon_id(void *ctx, const u8 *id, size_t len)
     783                 :            : {
     784                 :         12 :         struct wpa_supplicant *wpa_s = ctx;
     785                 :            :         char *str;
     786                 :            :         int res;
     787                 :            : 
     788                 :         12 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity",
     789                 :            :                           id, len);
     790                 :            : 
     791         [ -  + ]:         12 :         if (wpa_s->current_ssid == NULL)
     792                 :          0 :                 return;
     793                 :            : 
     794         [ -  + ]:         12 :         if (id == NULL) {
     795         [ #  # ]:          0 :                 if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
     796                 :            :                                    "NULL", 0) < 0)
     797                 :          0 :                         return;
     798                 :            :         } else {
     799                 :         12 :                 str = os_malloc(len * 2 + 1);
     800         [ -  + ]:         12 :                 if (str == NULL)
     801                 :          0 :                         return;
     802                 :         12 :                 wpa_snprintf_hex(str, len * 2 + 1, id, len);
     803                 :         12 :                 res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
     804                 :            :                                      str, 0);
     805                 :         12 :                 os_free(str);
     806         [ -  + ]:         12 :                 if (res < 0)
     807                 :          0 :                         return;
     808                 :            :         }
     809                 :            : 
     810         [ -  + ]:         12 :         if (wpa_s->conf->update_config) {
     811                 :          0 :                 res = wpa_config_write(wpa_s->confname, wpa_s->conf);
     812         [ #  # ]:          0 :                 if (res) {
     813                 :         12 :                         wpa_printf(MSG_DEBUG, "Failed to update config after "
     814                 :            :                                    "anonymous_id update");
     815                 :            :                 }
     816                 :            :         }
     817                 :            : }
     818                 :            : #endif /* IEEE8021X_EAPOL */
     819                 :            : 
     820                 :            : 
     821                 :         39 : int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
     822                 :            : {
     823                 :            : #ifdef IEEE8021X_EAPOL
     824                 :            :         struct eapol_ctx *ctx;
     825                 :         39 :         ctx = os_zalloc(sizeof(*ctx));
     826         [ -  + ]:         39 :         if (ctx == NULL) {
     827                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
     828                 :          0 :                 return -1;
     829                 :            :         }
     830                 :            : 
     831                 :         39 :         ctx->ctx = wpa_s;
     832                 :         39 :         ctx->msg_ctx = wpa_s;
     833                 :         39 :         ctx->eapol_send_ctx = wpa_s;
     834                 :         39 :         ctx->preauth = 0;
     835                 :         39 :         ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
     836                 :         39 :         ctx->eapol_send = wpa_supplicant_eapol_send;
     837                 :         39 :         ctx->set_wep_key = wpa_eapol_set_wep_key;
     838                 :            : #ifndef CONFIG_NO_CONFIG_BLOBS
     839                 :         39 :         ctx->set_config_blob = wpa_supplicant_set_config_blob;
     840                 :         39 :         ctx->get_config_blob = wpa_supplicant_get_config_blob;
     841                 :            : #endif /* CONFIG_NO_CONFIG_BLOBS */
     842                 :         39 :         ctx->aborted_cached = wpa_supplicant_aborted_cached;
     843                 :         39 :         ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
     844                 :         39 :         ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
     845                 :         39 :         ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
     846                 :         39 :         ctx->wps = wpa_s->wps;
     847                 :         39 :         ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
     848                 :         39 :         ctx->port_cb = wpa_supplicant_port_cb;
     849                 :         39 :         ctx->cb = wpa_supplicant_eapol_cb;
     850                 :         39 :         ctx->cert_cb = wpa_supplicant_cert_cb;
     851                 :         39 :         ctx->status_cb = wpa_supplicant_status_cb;
     852                 :         39 :         ctx->set_anon_id = wpa_supplicant_set_anon_id;
     853                 :         39 :         ctx->cb_ctx = wpa_s;
     854                 :         39 :         wpa_s->eapol = eapol_sm_init(ctx);
     855         [ -  + ]:         39 :         if (wpa_s->eapol == NULL) {
     856                 :          0 :                 os_free(ctx);
     857                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
     858                 :            :                            "machines.");
     859                 :          0 :                 return -1;
     860                 :            :         }
     861                 :            : #endif /* IEEE8021X_EAPOL */
     862                 :            : 
     863                 :         39 :         return 0;
     864                 :            : }
     865                 :            : 
     866                 :            : 
     867                 :            : #ifndef CONFIG_NO_WPA
     868                 :        403 : static void wpa_supplicant_set_rekey_offload(void *ctx, const u8 *kek,
     869                 :            :                                              const u8 *kck,
     870                 :            :                                              const u8 *replay_ctr)
     871                 :            : {
     872                 :        403 :         struct wpa_supplicant *wpa_s = ctx;
     873                 :            : 
     874                 :        403 :         wpa_drv_set_rekey_info(wpa_s, kek, kck, replay_ctr);
     875                 :        403 : }
     876                 :            : #endif /* CONFIG_NO_WPA */
     877                 :            : 
     878                 :            : 
     879                 :         39 : int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
     880                 :            : {
     881                 :            : #ifndef CONFIG_NO_WPA
     882                 :            :         struct wpa_sm_ctx *ctx;
     883                 :         39 :         ctx = os_zalloc(sizeof(*ctx));
     884         [ -  + ]:         39 :         if (ctx == NULL) {
     885                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
     886                 :          0 :                 return -1;
     887                 :            :         }
     888                 :            : 
     889                 :         39 :         ctx->ctx = wpa_s;
     890                 :         39 :         ctx->msg_ctx = wpa_s;
     891                 :         39 :         ctx->set_state = _wpa_supplicant_set_state;
     892                 :         39 :         ctx->get_state = _wpa_supplicant_get_state;
     893                 :         39 :         ctx->deauthenticate = _wpa_supplicant_deauthenticate;
     894                 :         39 :         ctx->set_key = wpa_supplicant_set_key;
     895                 :         39 :         ctx->get_network_ctx = wpa_supplicant_get_network_ctx;
     896                 :         39 :         ctx->get_bssid = wpa_supplicant_get_bssid;
     897                 :         39 :         ctx->ether_send = _wpa_ether_send;
     898                 :         39 :         ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
     899                 :         39 :         ctx->alloc_eapol = _wpa_alloc_eapol;
     900                 :         39 :         ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
     901                 :         39 :         ctx->add_pmkid = wpa_supplicant_add_pmkid;
     902                 :         39 :         ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
     903                 :            : #ifndef CONFIG_NO_CONFIG_BLOBS
     904                 :         39 :         ctx->set_config_blob = wpa_supplicant_set_config_blob;
     905                 :         39 :         ctx->get_config_blob = wpa_supplicant_get_config_blob;
     906                 :            : #endif /* CONFIG_NO_CONFIG_BLOBS */
     907                 :         39 :         ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
     908                 :            : #ifdef CONFIG_IEEE80211R
     909                 :         39 :         ctx->update_ft_ies = wpa_supplicant_update_ft_ies;
     910                 :         39 :         ctx->send_ft_action = wpa_supplicant_send_ft_action;
     911                 :         39 :         ctx->mark_authenticated = wpa_supplicant_mark_authenticated;
     912                 :            : #endif /* CONFIG_IEEE80211R */
     913                 :            : #ifdef CONFIG_TDLS
     914                 :         39 :         ctx->tdls_get_capa = wpa_supplicant_tdls_get_capa;
     915                 :         39 :         ctx->send_tdls_mgmt = wpa_supplicant_send_tdls_mgmt;
     916                 :         39 :         ctx->tdls_oper = wpa_supplicant_tdls_oper;
     917                 :         39 :         ctx->tdls_peer_addset = wpa_supplicant_tdls_peer_addset;
     918                 :            : #endif /* CONFIG_TDLS */
     919                 :         39 :         ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
     920                 :            : 
     921                 :         39 :         wpa_s->wpa = wpa_sm_init(ctx);
     922         [ -  + ]:         39 :         if (wpa_s->wpa == NULL) {
     923                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
     924                 :            :                            "machine");
     925                 :          0 :                 return -1;
     926                 :            :         }
     927                 :            : #endif /* CONFIG_NO_WPA */
     928                 :            : 
     929                 :         39 :         return 0;
     930                 :            : }
     931                 :            : 
     932                 :            : 
     933                 :        701 : void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
     934                 :            :                                         struct wpa_ssid *ssid)
     935                 :            : {
     936                 :            :         struct rsn_supp_config conf;
     937         [ +  - ]:        701 :         if (ssid) {
     938                 :        701 :                 os_memset(&conf, 0, sizeof(conf));
     939                 :        701 :                 conf.network_ctx = ssid;
     940                 :        701 :                 conf.peerkey_enabled = ssid->peerkey;
     941                 :        701 :                 conf.allowed_pairwise_cipher = ssid->pairwise_cipher;
     942                 :            : #ifdef IEEE8021X_EAPOL
     943                 :       1402 :                 conf.proactive_key_caching = ssid->proactive_key_caching < 0 ?
     944         [ +  + ]:        701 :                         wpa_s->conf->okc : ssid->proactive_key_caching;
     945                 :        701 :                 conf.eap_workaround = ssid->eap_workaround;
     946                 :        701 :                 conf.eap_conf_ctx = &ssid->eap;
     947                 :            : #endif /* IEEE8021X_EAPOL */
     948                 :        701 :                 conf.ssid = ssid->ssid;
     949                 :        701 :                 conf.ssid_len = ssid->ssid_len;
     950                 :        701 :                 conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey;
     951                 :            : #ifdef CONFIG_P2P
     952 [ +  + ][ +  - ]:        701 :                 if (ssid->p2p_group && wpa_s->current_bss &&
                 [ +  + ]
     953                 :        170 :                     !wpa_s->p2p_disable_ip_addr_req) {
     954                 :            :                         struct wpabuf *p2p;
     955                 :        168 :                         p2p = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
     956                 :            :                                                           P2P_IE_VENDOR_TYPE);
     957         [ +  - ]:        168 :                         if (p2p) {
     958                 :            :                                 u8 group_capab;
     959                 :        168 :                                 group_capab = p2p_get_group_capab(p2p);
     960         [ +  - ]:        168 :                                 if (group_capab &
     961                 :            :                                     P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION)
     962                 :        168 :                                         conf.p2p = 1;
     963                 :        168 :                                 wpabuf_free(p2p);
     964                 :            :                         }
     965                 :            :                 }
     966                 :            : #endif /* CONFIG_P2P */
     967                 :            :         }
     968         [ +  - ]:        701 :         wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
     969                 :        701 : }

Generated by: LCOV version 1.9