LCOV - code coverage report
Current view: top level - wpa_supplicant - ap.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 486 614 79.2 %
Date: 2014-03-02 Functions: 40 44 90.9 %
Branches: 197 324 60.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * WPA Supplicant - Basic AP mode support routines
       3                 :            :  * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
       4                 :            :  * Copyright (c) 2009, Atheros Communications
       5                 :            :  *
       6                 :            :  * This software may be distributed under the terms of the BSD license.
       7                 :            :  * See README for more details.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include "utils/includes.h"
      11                 :            : 
      12                 :            : #include "utils/common.h"
      13                 :            : #include "utils/eloop.h"
      14                 :            : #include "utils/uuid.h"
      15                 :            : #include "common/ieee802_11_defs.h"
      16                 :            : #include "common/wpa_ctrl.h"
      17                 :            : #include "eapol_supp/eapol_supp_sm.h"
      18                 :            : #include "crypto/dh_group5.h"
      19                 :            : #include "ap/hostapd.h"
      20                 :            : #include "ap/ap_config.h"
      21                 :            : #include "ap/ap_drv_ops.h"
      22                 :            : #ifdef NEED_AP_MLME
      23                 :            : #include "ap/ieee802_11.h"
      24                 :            : #endif /* NEED_AP_MLME */
      25                 :            : #include "ap/beacon.h"
      26                 :            : #include "ap/ieee802_1x.h"
      27                 :            : #include "ap/wps_hostapd.h"
      28                 :            : #include "ap/ctrl_iface_ap.h"
      29                 :            : #include "wps/wps.h"
      30                 :            : #include "common/ieee802_11_defs.h"
      31                 :            : #include "config_ssid.h"
      32                 :            : #include "config.h"
      33                 :            : #include "wpa_supplicant_i.h"
      34                 :            : #include "driver_i.h"
      35                 :            : #include "p2p_supplicant.h"
      36                 :            : #include "ap.h"
      37                 :            : #include "ap/sta_info.h"
      38                 :            : #include "notify.h"
      39                 :            : 
      40                 :            : 
      41                 :            : #ifdef CONFIG_WPS
      42                 :            : static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
      43                 :            : #endif /* CONFIG_WPS */
      44                 :            : 
      45                 :            : 
      46                 :            : #ifdef CONFIG_IEEE80211N
      47                 :          6 : static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
      48                 :            :                              struct hostapd_config *conf,
      49                 :            :                              struct hostapd_hw_modes *mode)
      50                 :            : {
      51                 :          6 :         u8 center_chan = 0;
      52                 :          6 :         u8 channel = conf->channel;
      53                 :            : 
      54         [ +  - ]:          6 :         if (!conf->secondary_channel)
      55                 :          6 :                 goto no_vht;
      56                 :            : 
      57                 :          0 :         center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
      58         [ #  # ]:          0 :         if (!center_chan)
      59                 :          0 :                 goto no_vht;
      60                 :            : 
      61                 :            :         /* Use 80 MHz channel */
      62                 :          0 :         conf->vht_oper_chwidth = 1;
      63                 :          0 :         conf->vht_oper_centr_freq_seg0_idx = center_chan;
      64                 :          6 :         return;
      65                 :            : 
      66                 :            : no_vht:
      67                 :          6 :         conf->vht_oper_centr_freq_seg0_idx =
      68                 :          6 :                 channel + conf->secondary_channel * 2;
      69                 :            : }
      70                 :            : #endif /* CONFIG_IEEE80211N */
      71                 :            : 
      72                 :            : 
      73                 :         86 : static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
      74                 :            :                                   struct wpa_ssid *ssid,
      75                 :            :                                   struct hostapd_config *conf)
      76                 :            : {
      77                 :         86 :         struct hostapd_bss_config *bss = conf->bss[0];
      78                 :            : 
      79                 :         86 :         conf->driver = wpa_s->driver;
      80                 :            : 
      81                 :         86 :         os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
      82                 :            : 
      83                 :         86 :         conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
      84                 :            :                                                &conf->channel);
      85         [ -  + ]:         86 :         if (conf->hw_mode == NUM_HOSTAPD_MODES) {
      86                 :          0 :                 wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
      87                 :            :                            ssid->frequency);
      88                 :          0 :                 return -1;
      89                 :            :         }
      90                 :            : 
      91                 :            :         /* TODO: enable HT40 if driver supports it;
      92                 :            :          * drop to 11b if driver does not support 11g */
      93                 :            : 
      94                 :            : #ifdef CONFIG_IEEE80211N
      95                 :            :         /*
      96                 :            :          * Enable HT20 if the driver supports it, by setting conf->ieee80211n
      97                 :            :          * and a mask of allowed capabilities within conf->ht_capab.
      98                 :            :          * Using default config settings for: conf->ht_op_mode_fixed,
      99                 :            :          * conf->secondary_channel, conf->require_ht
     100                 :            :          */
     101         [ +  - ]:         86 :         if (wpa_s->hw.modes) {
     102                 :         86 :                 struct hostapd_hw_modes *mode = NULL;
     103                 :         86 :                 int i, no_ht = 0;
     104         [ +  - ]:         86 :                 for (i = 0; i < wpa_s->hw.num_modes; i++) {
     105         [ +  - ]:         86 :                         if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
     106                 :         86 :                                 mode = &wpa_s->hw.modes[i];
     107                 :         86 :                                 break;
     108                 :            :                         }
     109                 :            :                 }
     110                 :            : 
     111                 :            : #ifdef CONFIG_HT_OVERRIDES
     112                 :            :                 if (ssid->disable_ht) {
     113                 :            :                         conf->ieee80211n = 0;
     114                 :            :                         conf->ht_capab = 0;
     115                 :            :                         no_ht = 1;
     116                 :            :                 }
     117                 :            : #endif /* CONFIG_HT_OVERRIDES */
     118                 :            : 
     119 [ +  - ][ +  - ]:         86 :                 if (!no_ht && mode && mode->ht_capab) {
                 [ +  - ]
     120                 :         86 :                         conf->ieee80211n = 1;
     121                 :            : #ifdef CONFIG_P2P
     122 [ -  + ][ #  # ]:         86 :                         if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
     123                 :          0 :                             (mode->ht_capab &
     124         [ #  # ]:          0 :                              HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
     125                 :          0 :                             ssid->ht40)
     126                 :          0 :                                 conf->secondary_channel =
     127                 :          0 :                                         wpas_p2p_get_ht40_mode(wpa_s, mode,
     128                 :          0 :                                                                conf->channel);
     129         [ -  + ]:         86 :                         if (conf->secondary_channel)
     130                 :          0 :                                 conf->ht_capab |=
     131                 :            :                                         HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
     132                 :            : #endif /* CONFIG_P2P */
     133                 :            : 
     134                 :            :                         /*
     135                 :            :                          * white-list capabilities that won't cause issues
     136                 :            :                          * to connecting stations, while leaving the current
     137                 :            :                          * capabilities intact (currently disabled SMPS).
     138                 :            :                          */
     139                 :         86 :                         conf->ht_capab |= mode->ht_capab &
     140                 :            :                                 (HT_CAP_INFO_GREEN_FIELD |
     141                 :            :                                  HT_CAP_INFO_SHORT_GI20MHZ |
     142                 :            :                                  HT_CAP_INFO_SHORT_GI40MHZ |
     143                 :            :                                  HT_CAP_INFO_RX_STBC_MASK |
     144                 :            :                                  HT_CAP_INFO_MAX_AMSDU_SIZE);
     145                 :            : 
     146 [ +  - ][ +  + ]:         86 :                         if (mode->vht_capab && ssid->vht) {
     147                 :          6 :                                 conf->ieee80211ac = 1;
     148                 :          6 :                                 wpas_conf_ap_vht(wpa_s, conf, mode);
     149                 :            :                         }
     150                 :            :                 }
     151                 :            :         }
     152                 :            : #endif /* CONFIG_IEEE80211N */
     153                 :            : 
     154                 :            : #ifdef CONFIG_P2P
     155 [ +  - ][ +  + ]:         86 :         if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
     156         [ +  + ]:         51 :             (ssid->mode == WPAS_MODE_P2P_GO ||
     157                 :         51 :              ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
     158                 :            :                 /* Remove 802.11b rates from supported and basic rate sets */
     159                 :         80 :                 int *list = os_malloc(4 * sizeof(int));
     160         [ +  - ]:         80 :                 if (list) {
     161                 :         80 :                         list[0] = 60;
     162                 :         80 :                         list[1] = 120;
     163                 :         80 :                         list[2] = 240;
     164                 :         80 :                         list[3] = -1;
     165                 :            :                 }
     166                 :         80 :                 conf->basic_rates = list;
     167                 :            : 
     168                 :         80 :                 list = os_malloc(9 * sizeof(int));
     169         [ +  - ]:         80 :                 if (list) {
     170                 :         80 :                         list[0] = 60;
     171                 :         80 :                         list[1] = 90;
     172                 :         80 :                         list[2] = 120;
     173                 :         80 :                         list[3] = 180;
     174                 :         80 :                         list[4] = 240;
     175                 :         80 :                         list[5] = 360;
     176                 :         80 :                         list[6] = 480;
     177                 :         80 :                         list[7] = 540;
     178                 :         80 :                         list[8] = -1;
     179                 :            :                 }
     180                 :         80 :                 conf->supported_rates = list;
     181                 :            :         }
     182                 :            : 
     183                 :         86 :         bss->isolate = !wpa_s->conf->p2p_intra_bss;
     184                 :         86 :         bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
     185                 :            : 
     186         [ +  + ]:         86 :         if (ssid->p2p_group) {
     187                 :         80 :                 os_memcpy(bss->ip_addr_go, wpa_s->parent->conf->ip_addr_go, 4);
     188                 :         80 :                 os_memcpy(bss->ip_addr_mask, wpa_s->parent->conf->ip_addr_mask,
     189                 :            :                           4);
     190                 :         80 :                 os_memcpy(bss->ip_addr_start,
     191                 :            :                           wpa_s->parent->conf->ip_addr_start, 4);
     192                 :         80 :                 os_memcpy(bss->ip_addr_end, wpa_s->parent->conf->ip_addr_end,
     193                 :            :                           4);
     194                 :            :         }
     195                 :            : #endif /* CONFIG_P2P */
     196                 :            : 
     197         [ -  + ]:         86 :         if (ssid->ssid_len == 0) {
     198                 :          0 :                 wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
     199                 :          0 :                 return -1;
     200                 :            :         }
     201                 :         86 :         os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
     202                 :         86 :         bss->ssid.ssid_len = ssid->ssid_len;
     203                 :         86 :         bss->ssid.ssid_set = 1;
     204                 :            : 
     205                 :         86 :         bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
     206                 :            : 
     207         [ +  + ]:         86 :         if (ssid->auth_alg)
     208                 :         80 :                 bss->auth_algs = ssid->auth_alg;
     209                 :            : 
     210         [ +  + ]:         86 :         if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
     211                 :         82 :                 bss->wpa = ssid->proto;
     212                 :         86 :         bss->wpa_key_mgmt = ssid->key_mgmt;
     213                 :         86 :         bss->wpa_pairwise = ssid->pairwise_cipher;
     214         [ +  + ]:         86 :         if (ssid->psk_set) {
     215                 :         82 :                 os_free(bss->ssid.wpa_psk);
     216                 :         82 :                 bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
     217         [ -  + ]:         82 :                 if (bss->ssid.wpa_psk == NULL)
     218                 :          0 :                         return -1;
     219                 :         82 :                 os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
     220                 :         82 :                 bss->ssid.wpa_psk->group = 1;
     221         [ -  + ]:          4 :         } else if (ssid->passphrase) {
     222                 :          0 :                 bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
     223 [ +  + ][ +  - ]:          4 :         } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
                 [ +  - ]
     224         [ -  + ]:          3 :                    ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
     225                 :          1 :                 struct hostapd_wep_keys *wep = &bss->ssid.wep;
     226                 :            :                 int i;
     227         [ +  + ]:          5 :                 for (i = 0; i < NUM_WEP_KEYS; i++) {
     228         [ +  + ]:          4 :                         if (ssid->wep_key_len[i] == 0)
     229                 :          3 :                                 continue;
     230                 :          1 :                         wep->key[i] = os_malloc(ssid->wep_key_len[i]);
     231         [ -  + ]:          1 :                         if (wep->key[i] == NULL)
     232                 :          0 :                                 return -1;
     233                 :          1 :                         os_memcpy(wep->key[i], ssid->wep_key[i],
     234                 :            :                                   ssid->wep_key_len[i]);
     235                 :          1 :                         wep->len[i] = ssid->wep_key_len[i];
     236                 :            :                 }
     237                 :          1 :                 wep->idx = ssid->wep_tx_keyidx;
     238                 :          1 :                 wep->keys_set = 1;
     239                 :            :         }
     240                 :            : 
     241         [ +  + ]:         86 :         if (ssid->ap_max_inactivity)
     242                 :         80 :                 bss->ap_max_inactivity = ssid->ap_max_inactivity;
     243                 :            : 
     244         [ -  + ]:         86 :         if (ssid->dtim_period)
     245                 :          0 :                 bss->dtim_period = ssid->dtim_period;
     246         [ -  + ]:         86 :         else if (wpa_s->conf->dtim_period)
     247                 :          0 :                 bss->dtim_period = wpa_s->conf->dtim_period;
     248                 :            : 
     249         [ -  + ]:         86 :         if (ssid->beacon_int)
     250                 :          0 :                 conf->beacon_int = ssid->beacon_int;
     251         [ -  + ]:         86 :         else if (wpa_s->conf->beacon_int)
     252                 :          0 :                 conf->beacon_int = wpa_s->conf->beacon_int;
     253                 :            : 
     254 [ +  + ][ +  - ]:         86 :         if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
     255                 :         82 :                 bss->rsn_pairwise = bss->wpa_pairwise;
     256                 :         86 :         bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
     257                 :            :                                                     bss->rsn_pairwise);
     258                 :            : 
     259 [ +  + ][ -  + ]:         86 :         if (bss->wpa && bss->ieee802_1x)
     260                 :          0 :                 bss->ssid.security_policy = SECURITY_WPA;
     261         [ +  + ]:         86 :         else if (bss->wpa)
     262                 :         82 :                 bss->ssid.security_policy = SECURITY_WPA_PSK;
     263         [ -  + ]:          4 :         else if (bss->ieee802_1x) {
     264                 :          0 :                 int cipher = WPA_CIPHER_NONE;
     265                 :          0 :                 bss->ssid.security_policy = SECURITY_IEEE_802_1X;
     266                 :          0 :                 bss->ssid.wep.default_len = bss->default_wep_key_len;
     267         [ #  # ]:          0 :                 if (bss->default_wep_key_len)
     268                 :          0 :                         cipher = bss->default_wep_key_len >= 13 ?
     269         [ #  # ]:          0 :                                 WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
     270                 :          0 :                 bss->wpa_group = cipher;
     271                 :          0 :                 bss->wpa_pairwise = cipher;
     272                 :          0 :                 bss->rsn_pairwise = cipher;
     273         [ +  + ]:          4 :         } else if (bss->ssid.wep.keys_set) {
     274                 :          1 :                 int cipher = WPA_CIPHER_WEP40;
     275         [ -  + ]:          1 :                 if (bss->ssid.wep.len[0] >= 13)
     276                 :          0 :                         cipher = WPA_CIPHER_WEP104;
     277                 :          1 :                 bss->ssid.security_policy = SECURITY_STATIC_WEP;
     278                 :          1 :                 bss->wpa_group = cipher;
     279                 :          1 :                 bss->wpa_pairwise = cipher;
     280                 :          1 :                 bss->rsn_pairwise = cipher;
     281                 :            :         } else {
     282                 :          3 :                 bss->ssid.security_policy = SECURITY_PLAINTEXT;
     283                 :          3 :                 bss->wpa_group = WPA_CIPHER_NONE;
     284                 :          3 :                 bss->wpa_pairwise = WPA_CIPHER_NONE;
     285                 :          3 :                 bss->rsn_pairwise = WPA_CIPHER_NONE;
     286                 :            :         }
     287                 :            : 
     288 [ +  - ][ +  + ]:         86 :         if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
                 [ +  + ]
     289         [ +  - ]:          1 :             (bss->wpa_group == WPA_CIPHER_CCMP ||
     290         [ +  - ]:          1 :              bss->wpa_group == WPA_CIPHER_GCMP ||
     291         [ -  + ]:          1 :              bss->wpa_group == WPA_CIPHER_CCMP_256 ||
     292                 :          1 :              bss->wpa_group == WPA_CIPHER_GCMP_256)) {
     293                 :            :                 /*
     294                 :            :                  * Strong ciphers do not need frequent rekeying, so increase
     295                 :            :                  * the default GTK rekeying period to 24 hours.
     296                 :            :                  */
     297                 :         81 :                 bss->wpa_group_rekey = 86400;
     298                 :            :         }
     299                 :            : 
     300                 :            : #ifdef CONFIG_WPS
     301                 :            :         /*
     302                 :            :          * Enable WPS by default for open and WPA/WPA2-Personal network, but
     303                 :            :          * require user interaction to actually use it. Only the internal
     304                 :            :          * Registrar is supported.
     305                 :            :          */
     306 [ +  + ][ +  + ]:         86 :         if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
     307                 :          4 :             bss->ssid.security_policy != SECURITY_PLAINTEXT)
     308                 :          1 :                 goto no_wps;
     309                 :            : #ifdef CONFIG_WPS2
     310 [ +  + ][ +  - ]:         85 :         if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
     311         [ +  - ]:         82 :             (!(bss->rsn_pairwise & WPA_CIPHER_CCMP) || !(bss->wpa & 2)))
     312                 :            :                 goto no_wps; /* WPS2 does not allow WPA/TKIP-only
     313                 :            :                               * configuration */
     314                 :            : #endif /* CONFIG_WPS2 */
     315                 :         85 :         bss->eap_server = 1;
     316                 :            : 
     317         [ +  - ]:         85 :         if (!ssid->ignore_broadcast_ssid)
     318                 :         85 :                 bss->wps_state = 2;
     319                 :            : 
     320                 :         85 :         bss->ap_setup_locked = 2;
     321         [ -  + ]:         85 :         if (wpa_s->conf->config_methods)
     322                 :          0 :                 bss->config_methods = os_strdup(wpa_s->conf->config_methods);
     323                 :         85 :         os_memcpy(bss->device_type, wpa_s->conf->device_type,
     324                 :            :                   WPS_DEV_TYPE_LEN);
     325         [ +  + ]:         85 :         if (wpa_s->conf->device_name) {
     326                 :         80 :                 bss->device_name = os_strdup(wpa_s->conf->device_name);
     327                 :         80 :                 bss->friendly_name = os_strdup(wpa_s->conf->device_name);
     328                 :            :         }
     329         [ -  + ]:         85 :         if (wpa_s->conf->manufacturer)
     330                 :          0 :                 bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
     331         [ -  + ]:         85 :         if (wpa_s->conf->model_name)
     332                 :          0 :                 bss->model_name = os_strdup(wpa_s->conf->model_name);
     333         [ -  + ]:         85 :         if (wpa_s->conf->model_number)
     334                 :          0 :                 bss->model_number = os_strdup(wpa_s->conf->model_number);
     335         [ -  + ]:         85 :         if (wpa_s->conf->serial_number)
     336                 :          0 :                 bss->serial_number = os_strdup(wpa_s->conf->serial_number);
     337         [ +  - ]:         85 :         if (is_nil_uuid(wpa_s->conf->uuid))
     338                 :         85 :                 os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
     339                 :            :         else
     340                 :          0 :                 os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
     341                 :         85 :         os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
     342                 :         85 :         bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
     343                 :            : no_wps:
     344                 :            : #endif /* CONFIG_WPS */
     345                 :            : 
     346 [ -  + ][ #  # ]:         86 :         if (wpa_s->max_stations &&
     347                 :          0 :             wpa_s->max_stations < wpa_s->conf->max_num_sta)
     348                 :          0 :                 bss->max_num_sta = wpa_s->max_stations;
     349                 :            :         else
     350                 :         86 :                 bss->max_num_sta = wpa_s->conf->max_num_sta;
     351                 :            : 
     352                 :         86 :         bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
     353                 :            : 
     354         [ -  + ]:         86 :         if (wpa_s->conf->ap_vendor_elements) {
     355                 :          0 :                 bss->vendor_elements =
     356                 :          0 :                         wpabuf_dup(wpa_s->conf->ap_vendor_elements);
     357                 :            :         }
     358                 :            : 
     359                 :         86 :         return 0;
     360                 :            : }
     361                 :            : 
     362                 :            : 
     363                 :         32 : static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
     364                 :            : {
     365                 :            : #ifdef CONFIG_P2P
     366                 :         32 :         struct wpa_supplicant *wpa_s = ctx;
     367                 :            :         const struct ieee80211_mgmt *mgmt;
     368                 :            :         size_t hdr_len;
     369                 :            : 
     370                 :         32 :         mgmt = (const struct ieee80211_mgmt *) buf;
     371                 :         32 :         hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
     372         [ -  + ]:         32 :         if (hdr_len > len)
     373                 :          0 :                 return;
     374         [ -  + ]:         32 :         if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
     375                 :          0 :                 return;
     376                 :         32 :         wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
     377                 :         32 :                            mgmt->u.action.category,
     378                 :            :                            &mgmt->u.action.u.vs_public_action.action,
     379                 :            :                            len - hdr_len, freq);
     380                 :            : #endif /* CONFIG_P2P */
     381                 :            : }
     382                 :            : 
     383                 :            : 
     384                 :        102 : static void ap_wps_event_cb(void *ctx, enum wps_event event,
     385                 :            :                             union wps_event_data *data)
     386                 :            : {
     387                 :            : #ifdef CONFIG_P2P
     388                 :        102 :         struct wpa_supplicant *wpa_s = ctx;
     389                 :            : 
     390         [ +  + ]:        102 :         if (event == WPS_EV_FAIL) {
     391                 :          5 :                 struct wps_event_fail *fail = &data->fail;
     392                 :            : 
     393 [ +  - ][ -  + ]:          5 :                 if (wpa_s->parent && wpa_s->parent != wpa_s &&
                 [ #  # ]
     394                 :          0 :                     wpa_s == wpa_s->global->p2p_group_formation) {
     395                 :            :                         /*
     396                 :            :                          * src/ap/wps_hostapd.c has already sent this on the
     397                 :            :                          * main interface, so only send on the parent interface
     398                 :            :                          * here if needed.
     399                 :            :                          */
     400                 :          0 :                         wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
     401                 :            :                                 "msg=%d config_error=%d",
     402                 :          0 :                                 fail->msg, fail->config_error);
     403                 :            :                 }
     404                 :          5 :                 wpas_p2p_wps_failed(wpa_s, fail);
     405                 :            :         }
     406                 :            : #endif /* CONFIG_P2P */
     407                 :        102 : }
     408                 :            : 
     409                 :            : 
     410                 :        202 : static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
     411                 :            :                                  int authorized, const u8 *p2p_dev_addr)
     412                 :            : {
     413                 :        202 :         wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
     414                 :        202 : }
     415                 :            : 
     416                 :            : 
     417                 :            : #ifdef CONFIG_P2P
     418                 :          8 : static void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
     419                 :            :                           const u8 *psk, size_t psk_len)
     420                 :            : {
     421                 :            : 
     422                 :          8 :         struct wpa_supplicant *wpa_s = ctx;
     423 [ +  - ][ -  + ]:          8 :         if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
     424                 :          8 :                 return;
     425                 :          8 :         wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
     426                 :            : }
     427                 :            : #endif /* CONFIG_P2P */
     428                 :            : 
     429                 :            : 
     430                 :          1 : static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
     431                 :            : {
     432                 :            : #ifdef CONFIG_P2P
     433                 :          1 :         struct wpa_supplicant *wpa_s = ctx;
     434                 :            :         const struct ieee80211_mgmt *mgmt;
     435                 :            :         size_t hdr_len;
     436                 :            : 
     437                 :          1 :         mgmt = (const struct ieee80211_mgmt *) buf;
     438                 :          1 :         hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
     439         [ -  + ]:          1 :         if (hdr_len > len)
     440                 :          0 :                 return -1;
     441                 :          1 :         wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
     442                 :          1 :                            mgmt->u.action.category,
     443                 :            :                            &mgmt->u.action.u.vs_public_action.action,
     444                 :            :                            len - hdr_len, freq);
     445                 :            : #endif /* CONFIG_P2P */
     446                 :          1 :         return 0;
     447                 :            : }
     448                 :            : 
     449                 :            : 
     450                 :        176 : static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
     451                 :            :                            const u8 *bssid, const u8 *ie, size_t ie_len,
     452                 :            :                            int ssi_signal)
     453                 :            : {
     454                 :            : #ifdef CONFIG_P2P
     455                 :        176 :         struct wpa_supplicant *wpa_s = ctx;
     456                 :        176 :         return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
     457                 :            :                                      ssi_signal);
     458                 :            : #else /* CONFIG_P2P */
     459                 :            :         return 0;
     460                 :            : #endif /* CONFIG_P2P */
     461                 :            : }
     462                 :            : 
     463                 :            : 
     464                 :         81 : static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
     465                 :            :                                   const u8 *uuid_e)
     466                 :            : {
     467                 :            : #ifdef CONFIG_P2P
     468                 :         81 :         struct wpa_supplicant *wpa_s = ctx;
     469                 :         81 :         wpas_p2p_wps_success(wpa_s, mac_addr, 1);
     470                 :            : #endif /* CONFIG_P2P */
     471                 :         81 : }
     472                 :            : 
     473                 :            : 
     474                 :         86 : static void wpas_ap_configured_cb(void *ctx)
     475                 :            : {
     476                 :         86 :         struct wpa_supplicant *wpa_s = ctx;
     477                 :            : 
     478                 :         86 :         wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
     479                 :            : 
     480         [ +  + ]:         86 :         if (wpa_s->ap_configured_cb)
     481                 :         80 :                 wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
     482                 :            :                                         wpa_s->ap_configured_cb_data);
     483                 :         86 : }
     484                 :            : 
     485                 :            : 
     486                 :         88 : int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
     487                 :            :                              struct wpa_ssid *ssid)
     488                 :            : {
     489                 :            :         struct wpa_driver_associate_params params;
     490                 :            :         struct hostapd_iface *hapd_iface;
     491                 :            :         struct hostapd_config *conf;
     492                 :            :         size_t i;
     493                 :            : 
     494 [ +  + ][ -  + ]:         88 :         if (ssid->ssid == NULL || ssid->ssid_len == 0) {
     495                 :          1 :                 wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
     496                 :          1 :                 return -1;
     497                 :            :         }
     498                 :            : 
     499                 :         87 :         wpa_supplicant_ap_deinit(wpa_s);
     500                 :            : 
     501                 :         87 :         wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
     502                 :         87 :                    wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
     503                 :            : 
     504                 :         87 :         os_memset(&params, 0, sizeof(params));
     505                 :         87 :         params.ssid = ssid->ssid;
     506                 :         87 :         params.ssid_len = ssid->ssid_len;
     507         [ +  - ]:         87 :         switch (ssid->mode) {
     508                 :            :         case WPAS_MODE_AP:
     509                 :            :         case WPAS_MODE_P2P_GO:
     510                 :            :         case WPAS_MODE_P2P_GROUP_FORMATION:
     511                 :         87 :                 params.mode = IEEE80211_MODE_AP;
     512                 :         87 :                 break;
     513                 :            :         default:
     514                 :          0 :                 return -1;
     515                 :            :         }
     516         [ +  + ]:         87 :         if (ssid->frequency == 0)
     517                 :          1 :                 ssid->frequency = 2462; /* default channel 11 */
     518                 :         87 :         params.freq = ssid->frequency;
     519                 :            : 
     520                 :         87 :         params.wpa_proto = ssid->proto;
     521         [ +  + ]:         87 :         if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
     522                 :         82 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
     523                 :            :         else
     524                 :          5 :                 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
     525                 :         87 :         params.key_mgmt_suite = wpa_s->key_mgmt;
     526                 :            : 
     527                 :         87 :         wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
     528                 :            :                                                           1);
     529         [ -  + ]:         87 :         if (wpa_s->pairwise_cipher < 0) {
     530                 :          0 :                 wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
     531                 :            :                            "cipher.");
     532                 :          0 :                 return -1;
     533                 :            :         }
     534                 :         87 :         params.pairwise_suite = wpa_s->pairwise_cipher;
     535                 :         87 :         params.group_suite = params.pairwise_suite;
     536                 :            : 
     537                 :            : #ifdef CONFIG_P2P
     538 [ +  + ][ +  + ]:         87 :         if (ssid->mode == WPAS_MODE_P2P_GO ||
     539                 :         52 :             ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
     540                 :         80 :                 params.p2p = 1;
     541                 :            : #endif /* CONFIG_P2P */
     542                 :            : 
     543         [ -  + ]:         87 :         if (wpa_s->parent->set_ap_uapsd)
     544                 :          0 :                 params.uapsd = wpa_s->parent->ap_uapsd;
     545 [ +  + ][ +  - ]:         87 :         else if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
     546                 :         80 :                 params.uapsd = 1; /* mandatory for P2P GO */
     547                 :            :         else
     548                 :          7 :                 params.uapsd = -1;
     549                 :            : 
     550         [ +  + ]:         87 :         if (wpa_drv_associate(wpa_s, &params) < 0) {
     551                 :          1 :                 wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
     552                 :          1 :                 return -1;
     553                 :            :         }
     554                 :            : 
     555                 :         86 :         wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface));
     556         [ -  + ]:         86 :         if (hapd_iface == NULL)
     557                 :          0 :                 return -1;
     558                 :         86 :         hapd_iface->owner = wpa_s;
     559                 :         86 :         hapd_iface->drv_flags = wpa_s->drv_flags;
     560                 :         86 :         hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
     561                 :         86 :         hapd_iface->extended_capa = wpa_s->extended_capa;
     562                 :         86 :         hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
     563                 :         86 :         hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
     564                 :            : 
     565                 :         86 :         wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
     566         [ -  + ]:         86 :         if (conf == NULL) {
     567                 :          0 :                 wpa_supplicant_ap_deinit(wpa_s);
     568                 :          0 :                 return -1;
     569                 :            :         }
     570                 :            : 
     571                 :         86 :         os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
     572                 :            :                   wpa_s->conf->wmm_ac_params,
     573                 :            :                   sizeof(wpa_s->conf->wmm_ac_params));
     574                 :            : 
     575         [ +  + ]:         86 :         if (params.uapsd > 0) {
     576                 :         80 :                 conf->bss[0]->wmm_enabled = 1;
     577                 :         80 :                 conf->bss[0]->wmm_uapsd = 1;
     578                 :            :         }
     579                 :            : 
     580         [ -  + ]:         86 :         if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
     581                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to create AP configuration");
     582                 :          0 :                 wpa_supplicant_ap_deinit(wpa_s);
     583                 :          0 :                 return -1;
     584                 :            :         }
     585                 :            : 
     586                 :            : #ifdef CONFIG_P2P
     587         [ +  + ]:         86 :         if (ssid->mode == WPAS_MODE_P2P_GO)
     588                 :         35 :                 conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
     589         [ +  + ]:         51 :         else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
     590                 :         45 :                 conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
     591                 :            :                         P2P_GROUP_FORMATION;
     592                 :            : #endif /* CONFIG_P2P */
     593                 :            : 
     594                 :         86 :         hapd_iface->num_bss = conf->num_bss;
     595                 :         86 :         hapd_iface->bss = os_calloc(conf->num_bss,
     596                 :            :                                     sizeof(struct hostapd_data *));
     597         [ -  + ]:         86 :         if (hapd_iface->bss == NULL) {
     598                 :          0 :                 wpa_supplicant_ap_deinit(wpa_s);
     599                 :          0 :                 return -1;
     600                 :            :         }
     601                 :            : 
     602         [ +  + ]:        172 :         for (i = 0; i < conf->num_bss; i++) {
     603                 :        172 :                 hapd_iface->bss[i] =
     604                 :         86 :                         hostapd_alloc_bss_data(hapd_iface, conf,
     605                 :         86 :                                                conf->bss[i]);
     606         [ -  + ]:         86 :                 if (hapd_iface->bss[i] == NULL) {
     607                 :          0 :                         wpa_supplicant_ap_deinit(wpa_s);
     608                 :          0 :                         return -1;
     609                 :            :                 }
     610                 :            : 
     611                 :         86 :                 hapd_iface->bss[i]->msg_ctx = wpa_s;
     612                 :         86 :                 hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
     613                 :         86 :                 hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
     614                 :         86 :                 hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
     615                 :         86 :                 hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
     616                 :         86 :                 hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
     617                 :         86 :                 hostapd_register_probereq_cb(hapd_iface->bss[i],
     618                 :            :                                              ap_probe_req_rx, wpa_s);
     619                 :         86 :                 hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
     620                 :         86 :                 hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
     621                 :         86 :                 hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
     622                 :         86 :                 hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
     623                 :         86 :                 hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
     624                 :         86 :                 hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
     625                 :            : #ifdef CONFIG_P2P
     626                 :         86 :                 hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
     627                 :         86 :                 hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
     628                 :         86 :                 hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
     629                 :         86 :                 hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
     630                 :            :                                                                     ssid);
     631                 :            : #endif /* CONFIG_P2P */
     632                 :         86 :                 hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
     633                 :         86 :                 hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
     634                 :            :         }
     635                 :            : 
     636                 :         86 :         os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
     637                 :         86 :         hapd_iface->bss[0]->driver = wpa_s->driver;
     638                 :         86 :         hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
     639                 :            : 
     640                 :         86 :         wpa_s->current_ssid = ssid;
     641                 :         86 :         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
     642                 :         86 :         os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
     643                 :         86 :         wpa_s->assoc_freq = ssid->frequency;
     644                 :            : 
     645         [ -  + ]:         86 :         if (hostapd_setup_interface(wpa_s->ap_iface)) {
     646                 :          0 :                 wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
     647                 :          0 :                 wpa_supplicant_ap_deinit(wpa_s);
     648                 :          0 :                 return -1;
     649                 :            :         }
     650                 :            : 
     651                 :         88 :         return 0;
     652                 :            : }
     653                 :            : 
     654                 :            : 
     655                 :       2234 : void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
     656                 :            : {
     657                 :            : #ifdef CONFIG_WPS
     658                 :       2234 :         eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
     659                 :            : #endif /* CONFIG_WPS */
     660                 :            : 
     661         [ +  + ]:       2234 :         if (wpa_s->ap_iface == NULL)
     662                 :       2234 :                 return;
     663                 :            : 
     664                 :         86 :         wpa_s->current_ssid = NULL;
     665                 :         86 :         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
     666                 :         86 :         wpa_s->assoc_freq = 0;
     667                 :            : #ifdef CONFIG_P2P
     668         [ +  - ]:         86 :         if (wpa_s->ap_iface->bss)
     669                 :         86 :                 wpa_s->ap_iface->bss[0]->p2p_group = NULL;
     670                 :         86 :         wpas_p2p_group_deinit(wpa_s);
     671                 :            : #endif /* CONFIG_P2P */
     672                 :         86 :         hostapd_interface_deinit(wpa_s->ap_iface);
     673                 :         86 :         hostapd_interface_free(wpa_s->ap_iface);
     674                 :         86 :         wpa_s->ap_iface = NULL;
     675                 :         86 :         wpa_drv_deinit_ap(wpa_s);
     676                 :            : }
     677                 :            : 
     678                 :            : 
     679                 :          2 : void ap_tx_status(void *ctx, const u8 *addr,
     680                 :            :                   const u8 *buf, size_t len, int ack)
     681                 :            : {
     682                 :            : #ifdef NEED_AP_MLME
     683                 :          2 :         struct wpa_supplicant *wpa_s = ctx;
     684                 :          2 :         hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
     685                 :            : #endif /* NEED_AP_MLME */
     686                 :          2 : }
     687                 :            : 
     688                 :            : 
     689                 :        783 : void ap_eapol_tx_status(void *ctx, const u8 *dst,
     690                 :            :                         const u8 *data, size_t len, int ack)
     691                 :            : {
     692                 :            : #ifdef NEED_AP_MLME
     693                 :        783 :         struct wpa_supplicant *wpa_s = ctx;
     694         [ -  + ]:        783 :         if (!wpa_s->ap_iface)
     695                 :        783 :                 return;
     696                 :        783 :         hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
     697                 :            : #endif /* NEED_AP_MLME */
     698                 :            : }
     699                 :            : 
     700                 :            : 
     701                 :          0 : void ap_client_poll_ok(void *ctx, const u8 *addr)
     702                 :            : {
     703                 :            : #ifdef NEED_AP_MLME
     704                 :          0 :         struct wpa_supplicant *wpa_s = ctx;
     705         [ #  # ]:          0 :         if (wpa_s->ap_iface)
     706                 :          0 :                 hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
     707                 :            : #endif /* NEED_AP_MLME */
     708                 :          0 : }
     709                 :            : 
     710                 :            : 
     711                 :          0 : void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
     712                 :            : {
     713                 :            : #ifdef NEED_AP_MLME
     714                 :          0 :         struct wpa_supplicant *wpa_s = ctx;
     715                 :          0 :         ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
     716                 :            : #endif /* NEED_AP_MLME */
     717                 :          0 : }
     718                 :            : 
     719                 :            : 
     720                 :        896 : void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
     721                 :            : {
     722                 :            : #ifdef NEED_AP_MLME
     723                 :        896 :         struct wpa_supplicant *wpa_s = ctx;
     724                 :            :         struct hostapd_frame_info fi;
     725                 :        896 :         os_memset(&fi, 0, sizeof(fi));
     726                 :        896 :         fi.datarate = rx_mgmt->datarate;
     727                 :        896 :         fi.ssi_signal = rx_mgmt->ssi_signal;
     728                 :        896 :         ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
     729                 :            :                         rx_mgmt->frame_len, &fi);
     730                 :            : #endif /* NEED_AP_MLME */
     731                 :        896 : }
     732                 :            : 
     733                 :            : 
     734                 :        572 : void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
     735                 :            : {
     736                 :            : #ifdef NEED_AP_MLME
     737                 :        572 :         struct wpa_supplicant *wpa_s = ctx;
     738                 :        572 :         ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
     739                 :            : #endif /* NEED_AP_MLME */
     740                 :        572 : }
     741                 :            : 
     742                 :            : 
     743                 :        698 : void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
     744                 :            :                                 const u8 *src_addr, const u8 *buf, size_t len)
     745                 :            : {
     746                 :        698 :         ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
     747                 :        698 : }
     748                 :            : 
     749                 :            : 
     750                 :            : #ifdef CONFIG_WPS
     751                 :            : 
     752                 :          6 : int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
     753                 :            :                               const u8 *p2p_dev_addr)
     754                 :            : {
     755         [ -  + ]:          6 :         if (!wpa_s->ap_iface)
     756                 :          0 :                 return -1;
     757                 :          6 :         return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
     758                 :            :                                          p2p_dev_addr);
     759                 :            : }
     760                 :            : 
     761                 :            : 
     762                 :          6 : int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
     763                 :            : {
     764                 :            :         struct wps_registrar *reg;
     765                 :          6 :         int reg_sel = 0, wps_sta = 0;
     766                 :            : 
     767 [ +  - ][ +  + ]:          6 :         if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
     768                 :          1 :                 return -1;
     769                 :            : 
     770                 :          5 :         reg = wpa_s->ap_iface->bss[0]->wps->registrar;
     771                 :          5 :         reg_sel = wps_registrar_wps_cancel(reg);
     772                 :          5 :         wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
     773                 :            :                                   ap_sta_wps_cancel, NULL);
     774                 :            : 
     775 [ +  + ][ +  - ]:          5 :         if (!reg_sel && !wps_sta) {
     776                 :          4 :                 wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
     777                 :            :                            "time");
     778                 :          4 :                 return -1;
     779                 :            :         }
     780                 :            : 
     781                 :            :         /*
     782                 :            :          * There are 2 cases to return wps cancel as success:
     783                 :            :          * 1. When wps cancel was initiated but no connection has been
     784                 :            :          *    established with client yet.
     785                 :            :          * 2. Client is in the middle of exchanging WPS messages.
     786                 :            :          */
     787                 :            : 
     788                 :          6 :         return 0;
     789                 :            : }
     790                 :            : 
     791                 :            : 
     792                 :         64 : int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
     793                 :            :                               const char *pin, char *buf, size_t buflen,
     794                 :            :                               int timeout)
     795                 :            : {
     796                 :         64 :         int ret, ret_len = 0;
     797                 :            : 
     798         [ -  + ]:         64 :         if (!wpa_s->ap_iface)
     799                 :          0 :                 return -1;
     800                 :            : 
     801         [ -  + ]:         64 :         if (pin == NULL) {
     802                 :          0 :                 unsigned int rpin = wps_generate_pin();
     803                 :          0 :                 ret_len = os_snprintf(buf, buflen, "%08d", rpin);
     804                 :          0 :                 pin = buf;
     805                 :            :         } else
     806                 :         64 :                 ret_len = os_snprintf(buf, buflen, "%s", pin);
     807                 :            : 
     808                 :         64 :         ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
     809                 :            :                                   timeout);
     810         [ -  + ]:         64 :         if (ret)
     811                 :          0 :                 return -1;
     812                 :         64 :         return ret_len;
     813                 :            : }
     814                 :            : 
     815                 :            : 
     816                 :          1 : static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
     817                 :            : {
     818                 :          1 :         struct wpa_supplicant *wpa_s = eloop_data;
     819                 :          1 :         wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
     820                 :          1 :         wpas_wps_ap_pin_disable(wpa_s);
     821                 :          1 : }
     822                 :            : 
     823                 :            : 
     824                 :          3 : static void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
     825                 :            : {
     826                 :            :         struct hostapd_data *hapd;
     827                 :            : 
     828         [ -  + ]:          3 :         if (wpa_s->ap_iface == NULL)
     829                 :          3 :                 return;
     830                 :          3 :         hapd = wpa_s->ap_iface->bss[0];
     831                 :          3 :         wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
     832                 :          3 :         hapd->ap_pin_failures = 0;
     833                 :          3 :         eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
     834         [ +  - ]:          3 :         if (timeout > 0)
     835                 :          3 :                 eloop_register_timeout(timeout, 0,
     836                 :            :                                        wpas_wps_ap_pin_timeout, wpa_s, NULL);
     837                 :            : }
     838                 :            : 
     839                 :            : 
     840                 :          2 : void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
     841                 :            : {
     842                 :            :         struct hostapd_data *hapd;
     843                 :            : 
     844         [ -  + ]:          2 :         if (wpa_s->ap_iface == NULL)
     845                 :          2 :                 return;
     846                 :          2 :         wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
     847                 :          2 :         hapd = wpa_s->ap_iface->bss[0];
     848                 :          2 :         os_free(hapd->conf->ap_pin);
     849                 :          2 :         hapd->conf->ap_pin = NULL;
     850                 :          2 :         eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
     851                 :            : }
     852                 :            : 
     853                 :            : 
     854                 :          1 : const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
     855                 :            : {
     856                 :            :         struct hostapd_data *hapd;
     857                 :            :         unsigned int pin;
     858                 :            :         char pin_txt[9];
     859                 :            : 
     860         [ -  + ]:          1 :         if (wpa_s->ap_iface == NULL)
     861                 :          0 :                 return NULL;
     862                 :          1 :         hapd = wpa_s->ap_iface->bss[0];
     863                 :          1 :         pin = wps_generate_pin();
     864                 :          1 :         os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
     865                 :          1 :         os_free(hapd->conf->ap_pin);
     866                 :          1 :         hapd->conf->ap_pin = os_strdup(pin_txt);
     867         [ -  + ]:          1 :         if (hapd->conf->ap_pin == NULL)
     868                 :          0 :                 return NULL;
     869                 :          1 :         wpas_wps_ap_pin_enable(wpa_s, timeout);
     870                 :            : 
     871                 :          1 :         return hapd->conf->ap_pin;
     872                 :            : }
     873                 :            : 
     874                 :            : 
     875                 :          2 : const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
     876                 :            : {
     877                 :            :         struct hostapd_data *hapd;
     878         [ -  + ]:          2 :         if (wpa_s->ap_iface == NULL)
     879                 :          0 :                 return NULL;
     880                 :          2 :         hapd = wpa_s->ap_iface->bss[0];
     881                 :          2 :         return hapd->conf->ap_pin;
     882                 :            : }
     883                 :            : 
     884                 :            : 
     885                 :          2 : int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
     886                 :            :                         int timeout)
     887                 :            : {
     888                 :            :         struct hostapd_data *hapd;
     889                 :            :         char pin_txt[9];
     890                 :            :         int ret;
     891                 :            : 
     892         [ -  + ]:          2 :         if (wpa_s->ap_iface == NULL)
     893                 :          0 :                 return -1;
     894                 :          2 :         hapd = wpa_s->ap_iface->bss[0];
     895                 :          2 :         ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
     896 [ +  - ][ -  + ]:          2 :         if (ret < 0 || ret >= (int) sizeof(pin_txt))
     897                 :          0 :                 return -1;
     898                 :          2 :         os_free(hapd->conf->ap_pin);
     899                 :          2 :         hapd->conf->ap_pin = os_strdup(pin_txt);
     900         [ -  + ]:          2 :         if (hapd->conf->ap_pin == NULL)
     901                 :          0 :                 return -1;
     902                 :          2 :         wpas_wps_ap_pin_enable(wpa_s, timeout);
     903                 :            : 
     904                 :          2 :         return 0;
     905                 :            : }
     906                 :            : 
     907                 :            : 
     908                 :          0 : void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
     909                 :            : {
     910                 :            :         struct hostapd_data *hapd;
     911                 :            : 
     912         [ #  # ]:          0 :         if (wpa_s->ap_iface == NULL)
     913                 :          0 :                 return;
     914                 :          0 :         hapd = wpa_s->ap_iface->bss[0];
     915                 :            : 
     916                 :            :         /*
     917                 :            :          * Registrar failed to prove its knowledge of the AP PIN. Disable AP
     918                 :            :          * PIN if this happens multiple times to slow down brute force attacks.
     919                 :            :          */
     920                 :          0 :         hapd->ap_pin_failures++;
     921                 :          0 :         wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
     922                 :            :                    hapd->ap_pin_failures);
     923         [ #  # ]:          0 :         if (hapd->ap_pin_failures < 3)
     924                 :          0 :                 return;
     925                 :            : 
     926                 :          0 :         wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
     927                 :          0 :         hapd->ap_pin_failures = 0;
     928                 :          0 :         os_free(hapd->conf->ap_pin);
     929                 :          0 :         hapd->conf->ap_pin = NULL;
     930                 :            : }
     931                 :            : 
     932                 :            : 
     933                 :            : #ifdef CONFIG_WPS_NFC
     934                 :            : 
     935                 :          1 : struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
     936                 :            :                                              int ndef)
     937                 :            : {
     938                 :            :         struct hostapd_data *hapd;
     939                 :            : 
     940         [ -  + ]:          1 :         if (wpa_s->ap_iface == NULL)
     941                 :          0 :                 return NULL;
     942                 :          1 :         hapd = wpa_s->ap_iface->bss[0];
     943                 :          1 :         return hostapd_wps_nfc_config_token(hapd, ndef);
     944                 :            : }
     945                 :            : 
     946                 :            : 
     947                 :          4 : struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
     948                 :            :                                              int ndef)
     949                 :            : {
     950                 :            :         struct hostapd_data *hapd;
     951                 :            : 
     952         [ +  + ]:          4 :         if (wpa_s->ap_iface == NULL)
     953                 :          3 :                 return NULL;
     954                 :          1 :         hapd = wpa_s->ap_iface->bss[0];
     955                 :          4 :         return hostapd_wps_nfc_hs_cr(hapd, ndef);
     956                 :            : }
     957                 :            : 
     958                 :            : 
     959                 :          4 : int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
     960                 :            :                                     const struct wpabuf *req,
     961                 :            :                                     const struct wpabuf *sel)
     962                 :            : {
     963                 :            :         struct hostapd_data *hapd;
     964                 :            : 
     965         [ +  + ]:          4 :         if (wpa_s->ap_iface == NULL)
     966                 :          3 :                 return -1;
     967                 :          1 :         hapd = wpa_s->ap_iface->bss[0];
     968                 :          4 :         return hostapd_wps_nfc_report_handover(hapd, req, sel);
     969                 :            : }
     970                 :            : 
     971                 :            : #endif /* CONFIG_WPS_NFC */
     972                 :            : 
     973                 :            : #endif /* CONFIG_WPS */
     974                 :            : 
     975                 :            : 
     976                 :            : #ifdef CONFIG_CTRL_IFACE
     977                 :            : 
     978                 :          1 : int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
     979                 :            :                             char *buf, size_t buflen)
     980                 :            : {
     981         [ -  + ]:          1 :         if (wpa_s->ap_iface == NULL)
     982                 :          0 :                 return -1;
     983                 :          1 :         return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0],
     984                 :            :                                             buf, buflen);
     985                 :            : }
     986                 :            : 
     987                 :            : 
     988                 :          1 : int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
     989                 :            :                       char *buf, size_t buflen)
     990                 :            : {
     991         [ -  + ]:          1 :         if (wpa_s->ap_iface == NULL)
     992                 :          0 :                 return -1;
     993                 :          1 :         return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr,
     994                 :            :                                       buf, buflen);
     995                 :            : }
     996                 :            : 
     997                 :            : 
     998                 :          2 : int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
     999                 :            :                            char *buf, size_t buflen)
    1000                 :            : {
    1001         [ -  + ]:          2 :         if (wpa_s->ap_iface == NULL)
    1002                 :          0 :                 return -1;
    1003                 :          2 :         return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr,
    1004                 :            :                                            buf, buflen);
    1005                 :            : }
    1006                 :            : 
    1007                 :            : 
    1008                 :          1 : int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
    1009                 :            :                                    const char *txtaddr)
    1010                 :            : {
    1011         [ -  + ]:          1 :         if (wpa_s->ap_iface == NULL)
    1012                 :          0 :                 return -1;
    1013                 :          1 :         return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
    1014                 :            :                                                txtaddr);
    1015                 :            : }
    1016                 :            : 
    1017                 :            : 
    1018                 :          1 : int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
    1019                 :            :                                      const char *txtaddr)
    1020                 :            : {
    1021         [ -  + ]:          1 :         if (wpa_s->ap_iface == NULL)
    1022                 :          0 :                 return -1;
    1023                 :          1 :         return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
    1024                 :            :                                                  txtaddr);
    1025                 :            : }
    1026                 :            : 
    1027                 :            : 
    1028                 :         32 : int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
    1029                 :            :                                  size_t buflen, int verbose)
    1030                 :            : {
    1031                 :         32 :         char *pos = buf, *end = buf + buflen;
    1032                 :            :         int ret;
    1033                 :            :         struct hostapd_bss_config *conf;
    1034                 :            : 
    1035         [ -  + ]:         32 :         if (wpa_s->ap_iface == NULL)
    1036                 :          0 :                 return -1;
    1037                 :            : 
    1038                 :         32 :         conf = wpa_s->ap_iface->bss[0]->conf;
    1039         [ +  + ]:         32 :         if (conf->wpa == 0)
    1040                 :          1 :                 return 0;
    1041                 :            : 
    1042                 :         31 :         ret = os_snprintf(pos, end - pos,
    1043                 :            :                           "pairwise_cipher=%s\n"
    1044                 :            :                           "group_cipher=%s\n"
    1045                 :            :                           "key_mgmt=%s\n",
    1046                 :            :                           wpa_cipher_txt(conf->rsn_pairwise),
    1047                 :            :                           wpa_cipher_txt(conf->wpa_group),
    1048                 :            :                           wpa_key_mgmt_txt(conf->wpa_key_mgmt,
    1049                 :            :                                            conf->wpa));
    1050 [ +  - ][ -  + ]:         31 :         if (ret < 0 || ret >= end - pos)
    1051                 :          0 :                 return pos - buf;
    1052                 :         31 :         pos += ret;
    1053                 :         32 :         return pos - buf;
    1054                 :            : }
    1055                 :            : 
    1056                 :            : #endif /* CONFIG_CTRL_IFACE */
    1057                 :            : 
    1058                 :            : 
    1059                 :        446 : int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
    1060                 :            : {
    1061                 :        446 :         struct hostapd_iface *iface = wpa_s->ap_iface;
    1062                 :        446 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    1063                 :            :         struct hostapd_data *hapd;
    1064                 :            : 
    1065 [ +  + ][ +  - ]:        446 :         if (ssid == NULL || wpa_s->ap_iface == NULL ||
                 [ +  - ]
    1066         [ -  + ]:        331 :             ssid->mode == WPAS_MODE_INFRA ||
    1067                 :        331 :             ssid->mode == WPAS_MODE_IBSS)
    1068                 :        115 :                 return -1;
    1069                 :            : 
    1070                 :            : #ifdef CONFIG_P2P
    1071         [ +  + ]:        331 :         if (ssid->mode == WPAS_MODE_P2P_GO)
    1072                 :        285 :                 iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
    1073         [ +  - ]:         46 :         else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
    1074                 :         46 :                 iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
    1075                 :            :                         P2P_GROUP_FORMATION;
    1076                 :            : #endif /* CONFIG_P2P */
    1077                 :            : 
    1078                 :        331 :         hapd = iface->bss[0];
    1079         [ -  + ]:        331 :         if (hapd->drv_priv == NULL)
    1080                 :          0 :                 return -1;
    1081                 :        331 :         ieee802_11_set_beacons(iface);
    1082                 :        331 :         hostapd_set_ap_wps_ie(hapd);
    1083                 :            : 
    1084                 :        446 :         return 0;
    1085                 :            : }
    1086                 :            : 
    1087                 :            : 
    1088                 :          1 : int ap_switch_channel(struct wpa_supplicant *wpa_s,
    1089                 :            :                       struct csa_settings *settings)
    1090                 :            : {
    1091                 :            : #ifdef NEED_AP_MLME
    1092 [ +  - ][ -  + ]:          1 :         if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
    1093                 :          0 :                 return -1;
    1094                 :            : 
    1095                 :          1 :         return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings);
    1096                 :            : #else /* NEED_AP_MLME */
    1097                 :            :         return -1;
    1098                 :            : #endif /* NEED_AP_MLME */
    1099                 :            : }
    1100                 :            : 
    1101                 :            : 
    1102                 :          1 : int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
    1103                 :            : {
    1104                 :            :         struct csa_settings settings;
    1105                 :          1 :         int ret = hostapd_parse_csa_settings(pos, &settings);
    1106                 :            : 
    1107         [ -  + ]:          1 :         if (ret)
    1108                 :          0 :                 return ret;
    1109                 :            : 
    1110                 :          1 :         return ap_switch_channel(wpa_s, &settings);
    1111                 :            : }
    1112                 :            : 
    1113                 :            : 
    1114                 :          0 : void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
    1115                 :            :                        int offset, int width, int cf1, int cf2)
    1116                 :            : {
    1117         [ #  # ]:          0 :         if (!wpa_s->ap_iface)
    1118                 :          0 :                 return;
    1119                 :            : 
    1120                 :          0 :         wpa_s->assoc_freq = freq;
    1121                 :          0 :         hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht, offset, width, cf1, cf1);
    1122                 :            : }
    1123                 :            : 
    1124                 :            : 
    1125                 :         89 : int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
    1126                 :            :                                       const u8 *addr)
    1127                 :            : {
    1128                 :            :         struct hostapd_data *hapd;
    1129                 :            :         struct hostapd_bss_config *conf;
    1130                 :            : 
    1131         [ -  + ]:         89 :         if (!wpa_s->ap_iface)
    1132                 :          0 :                 return -1;
    1133                 :            : 
    1134         [ +  + ]:         89 :         if (addr)
    1135                 :         45 :                 wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
    1136                 :        270 :                            MAC2STR(addr));
    1137                 :            :         else
    1138                 :         44 :                 wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
    1139                 :            : 
    1140                 :         89 :         hapd = wpa_s->ap_iface->bss[0];
    1141                 :         89 :         conf = hapd->conf;
    1142                 :            : 
    1143                 :         89 :         os_free(conf->accept_mac);
    1144                 :         89 :         conf->accept_mac = NULL;
    1145                 :         89 :         conf->num_accept_mac = 0;
    1146                 :         89 :         os_free(conf->deny_mac);
    1147                 :         89 :         conf->deny_mac = NULL;
    1148                 :         89 :         conf->num_deny_mac = 0;
    1149                 :            : 
    1150         [ +  + ]:         89 :         if (addr == NULL) {
    1151                 :         44 :                 conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
    1152                 :         44 :                 return 0;
    1153                 :            :         }
    1154                 :            : 
    1155                 :         45 :         conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
    1156                 :         45 :         conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
    1157         [ -  + ]:         45 :         if (conf->accept_mac == NULL)
    1158                 :          0 :                 return -1;
    1159                 :         45 :         os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
    1160                 :         45 :         conf->num_accept_mac = 1;
    1161                 :            : 
    1162                 :         89 :         return 0;
    1163                 :            : }
    1164                 :            : 
    1165                 :            : 
    1166                 :            : #ifdef CONFIG_WPS_NFC
    1167                 :         10 : int wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
    1168                 :            :                            const struct wpabuf *pw, const u8 *pubkey_hash)
    1169                 :            : {
    1170                 :            :         struct hostapd_data *hapd;
    1171                 :            :         struct wps_context *wps;
    1172                 :            : 
    1173         [ -  + ]:         10 :         if (!wpa_s->ap_iface)
    1174                 :          0 :                 return -1;
    1175                 :         10 :         hapd = wpa_s->ap_iface->bss[0];
    1176                 :         10 :         wps = hapd->wps;
    1177                 :            : 
    1178 [ +  - ][ -  + ]:         10 :         if (wpa_s->parent->conf->wps_nfc_dh_pubkey == NULL ||
    1179                 :         10 :             wpa_s->parent->conf->wps_nfc_dh_privkey == NULL) {
    1180                 :          0 :                 wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known");
    1181                 :          0 :                 return -1;
    1182                 :            :         }
    1183                 :            : 
    1184                 :         10 :         dh5_free(wps->dh_ctx);
    1185                 :         10 :         wpabuf_free(wps->dh_pubkey);
    1186                 :         10 :         wpabuf_free(wps->dh_privkey);
    1187                 :         10 :         wps->dh_privkey = wpabuf_dup(
    1188                 :         10 :                 wpa_s->parent->conf->wps_nfc_dh_privkey);
    1189                 :         10 :         wps->dh_pubkey = wpabuf_dup(
    1190                 :         10 :                 wpa_s->parent->conf->wps_nfc_dh_pubkey);
    1191 [ +  - ][ -  + ]:         10 :         if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
    1192                 :          0 :                 wps->dh_ctx = NULL;
    1193                 :          0 :                 wpabuf_free(wps->dh_pubkey);
    1194                 :          0 :                 wps->dh_pubkey = NULL;
    1195                 :          0 :                 wpabuf_free(wps->dh_privkey);
    1196                 :          0 :                 wps->dh_privkey = NULL;
    1197                 :          0 :                 return -1;
    1198                 :            :         }
    1199                 :         10 :         wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
    1200         [ -  + ]:         10 :         if (wps->dh_ctx == NULL)
    1201                 :          0 :                 return -1;
    1202                 :            : 
    1203 [ +  + ][ +  + ]:         10 :         return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash,
    1204                 :            :                                               pw_id,
    1205                 :            :                                               pw ? wpabuf_head(pw) : NULL,
    1206                 :            :                                               pw ? wpabuf_len(pw) : 0, 1);
    1207                 :            : }
    1208                 :            : #endif /* CONFIG_WPS_NFC */

Generated by: LCOV version 1.9