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 1443382998 Lines: 556 703 79.1 %
Date: 2015-09-27 Functions: 46 52 88.5 %

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

Generated by: LCOV version 1.10