Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e549ab9 authored by Pankaj Singh's avatar Pankaj Singh
Browse files

wlan: Process external auth command and set preauth node state

Hostapd sends SAE authentication status with the NL command
NL80211_CMD_EXTERNAL_AUTH. Extract status and peer mac address
from the command data and set mlmState in preauth node accordingly.

Change-Id: If507a2f56c031ae1885a11d5f7cbe31a18aa8821
CRs-Fixed: 2734667
parent f9c4ca79
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
@@ -19848,6 +19848,7 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
    hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
    hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
    int ret;
    tSirMacAddr peer_mac_addr;
    if (hdd_get_conparam() == VOS_FTM_MODE) {
        hddLog(VOS_TRACE_LEVEL_ERROR, FL("Command not allowed in FTM mode"));
@@ -19858,10 +19859,13 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
    if (ret)
        return ret;
   hddLog(VOS_TRACE_LEVEL_DEBUG, FL("external_auth status: %d"),
          params->status);
    hddLog(VOS_TRACE_LEVEL_DEBUG,
            FL("external_auth status: %d peer mac: " MAC_ADDRESS_STR),
            params->status, MAC_ADDR_ARRAY(params->bssid));
    vos_mem_copy(peer_mac_addr, params->bssid, VOS_MAC_ADDR_SIZE);
   sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status);
    sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status,
                        peer_mac_addr);
    return ret;
}
+2 −0
Original line number Diff line number Diff line
@@ -6489,11 +6489,13 @@ struct sir_sae_info {
 * @length: message length
 * @session_id: SME session id
 * @sae_status: SAE status, 0: Success, Non-zero: Failure.
 * @peer_mac_addr: peer MAC address
 */
struct sir_sae_msg {
    uint16_t message_type;
    uint16_t length;
    uint16_t session_id;
    uint8_t sae_status;
    tSirMacAddr peer_mac_addr;
};
#endif /* __SIR_API_H */
+124 −24
Original line number Diff line number Diff line
@@ -98,6 +98,116 @@
void limLogSessionStates(tpAniSirGlobal pMac);

#ifdef WLAN_FEATURE_SAE
/**
 * lim_process_sae_msg_sta() - Process SAE message for STA
 * @mac: Global MAC pointer
 * @session: Pointer to the PE session entry
 * @sae_msg: SAE message buffer pointer
 *
 * Return: None
 */
static void lim_process_sae_msg_sta(tpAniSirGlobal mac,
                                    tpPESession session,
                                    struct sir_sae_msg *sae_msg)
{
        switch (session->limMlmState) {
        case eLIM_MLM_WT_SAE_AUTH_STATE:
                /* SAE authentication is completed.
                 * Restore from auth state
                 */
                if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
                        limDeactivateAndChangeTimer(mac,
                                                    eLIM_AUTH_SAE_TIMER);
                /* success */
                if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
                        limRestoreFromAuthState(mac,
                                                eSIR_SME_SUCCESS,
                                                eSIR_MAC_SUCCESS_STATUS,
                                                session);
                else
                        limRestoreFromAuthState(mac, eSIR_SME_AUTH_REFUSED,
                                                eSIR_MAC_UNSPEC_FAILURE_STATUS,
                                                session);
        break;
        default:
                /* SAE msg is received in unexpected state */
                limLog(mac, LOGE, FL("received SAE msg in state %X"),
                        session->limMlmState);
                limPrintMlmState(mac, LOGE, session->limMlmState);
        break;
        }
}

/**
 * lim_process_sae_msg_ap() - Process SAE message
 * @mac: Global MAC pointer
 * @session: Pointer to the PE session entry
 * @sae_msg: SAE message buffer pointer
 *
 * Return: None
 */
static void lim_process_sae_msg_ap(tpAniSirGlobal mac,
                                   tpPESession session,
                                   struct sir_sae_msg *sae_msg)
{
        struct tLimPreAuthNode *sta_pre_auth_ctx;
        struct lim_assoc_data *assoc_req;
       /* Extract pre-auth context for the STA and move limMlmState
        * of preauth node to eLIM_MLM_AUTHENTICATED_STATE
        */
        sta_pre_auth_ctx = limSearchPreAuthList(mac, sae_msg->peer_mac_addr);

        if (!sta_pre_auth_ctx) {
                limLog(mac, LOGE, FL("No preauth node created for "
                        MAC_ADDRESS_STR),
                        MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
                return;
        }

        assoc_req = &sta_pre_auth_ctx->assoc_req;

        if (sae_msg->sae_status != IEEE80211_STATUS_SUCCESS) {
                limLog(mac, LOGE, FL("SAE authentication failed for "
                        MAC_ADDRESS_STR " status: %u"),
                        MAC_ADDR_ARRAY(sae_msg->peer_mac_addr),
                        sae_msg->sae_status);
                if (assoc_req->present) {
                   limLog(mac, LOGE, FL("Assoc req cached; clean it up"));
                        lim_process_assoc_cleanup(mac, session,
                                                assoc_req->assoc_req,
                                                assoc_req->sta_ds,
                                                assoc_req->assoc_req_copied);
                        assoc_req->present = false;
                }
                limDeletePreAuthNode(mac, sae_msg->peer_mac_addr);

                return;
        }
        sta_pre_auth_ctx->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
        /* Send assoc indication to SME if any assoc request is cached*/
        if (assoc_req->present) {
                /* Assoc request is present in preauth context. Get the assoc
                 * request and make it invalid in preauth context. It'll be
                 * freed later in the legacy path.
                 */
                bool assoc_req_copied;

                assoc_req->present = false;
                limLog(mac, LOG1, FL("Assoc req cached; handle it"));
                if (lim_send_assoc_ind_to_sme(mac, session,
                                            assoc_req->sub_type,
                                            &assoc_req->hdr,
                                            assoc_req->assoc_req,
                                            ANI_AKM_TYPE_SAE,
                                            assoc_req->pmf_connection,
                                            &assoc_req_copied) == false)
                        lim_process_assoc_cleanup(mac, session,
                                                assoc_req->assoc_req,
                                                assoc_req->sta_ds,
                                                assoc_req_copied);
        }
}

/**
 * lim_process_sae_msg() - Process SAE message
 * @mac: Global MAC pointer
@@ -121,35 +231,25 @@ static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
        return;
    }

    if (session->pePersona != VOS_STA_MODE) {
    if (session->pePersona != VOS_STA_MODE &&
        session->pePersona != VOS_STA_SAP_MODE) {
        limLog(mac, LOGE, FL("SAE:Not supported in this mode %d"),
               session->pePersona);
        return;
    }

    limLog(mac, LOG1, FL("SAE:status %d limMlmState %d pePersona %d"),
    limLog(mac, LOG1,
            FL("SAE:status %d limMlmState %d pePersona %d peer:"
            MAC_ADDRESS_STR),
            sae_msg->sae_status, session->limMlmState,
           session->pePersona);
    switch (session->limMlmState) {
    case eLIM_MLM_WT_SAE_AUTH_STATE:
        /* SAE authentication is completed. Restore from auth state */
        if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
            limDeactivateAndChangeTimer(mac, eLIM_AUTH_SAE_TIMER);
        /* success */
        if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
            limRestoreFromAuthState(mac, eSIR_SME_SUCCESS,
                                    eSIR_MAC_SUCCESS_STATUS, session);
            session->pePersona, MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));

    if (LIM_IS_STA_ROLE(session))
            lim_process_sae_msg_sta(mac, session, sae_msg);
    else if (LIM_IS_AP_ROLE(session))
            lim_process_sae_msg_ap(mac, session, sae_msg);
    else
            limRestoreFromAuthState(mac, eSIR_SME_AUTH_REFUSED,
                                    eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
       break;
    default:
       /* SAE msg is received in unexpected state */
       limLog(mac, LOGE, FL("received SAE msg in state %X"),
              session->limMlmState);
       limPrintMlmState(mac, LOGE, session->limMlmState);
       break;
    }
            limLog(mac, LOGE, FL("SAE message on unsupported interface"));
}
#else
static void lim_process_sae_msg(tpAniSirGlobal mac, struct sir_sae_msg *body)
+6 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
@@ -4134,14 +4134,17 @@ eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
 * @hal: The handle returned by mac_open
 * @session_id: session id
 * @sae_status: status of SAE authentication
 * @peer_mac_addr: mac address of the peer to be authenticated
 *
 * Return: HAL_STATUS
 */
eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
                              uint8_t sae_status);
                            uint8_t sae_status,
                            tSirMacAddr peer_mac_addr);
#else
static inline eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
                                            uint8_t sae_status)
                                            uint8_t sae_status,
                                            tSirMacAddr peer_mac_addr)
{
	return eHAL_STATUS_SUCCESS;
}
+11 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
@@ -15470,7 +15470,8 @@ eHalStatus sme_send_mgmt_tx(tHalHandle hal, uint8_t session_id,
#ifdef WLAN_FEATURE_SAE
eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
                              uint8_t sae_status)
                              uint8_t sae_status,
                              tSirMacAddr peer_mac_addr)
{
    eHalStatus hal_status = eHAL_STATUS_SUCCESS;
    tpAniSirGlobal mac = PMAC_STRUCT(hal);
@@ -15490,11 +15491,17 @@ eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
            sae_msg->length = sizeof(*sae_msg);
            sae_msg->session_id = session_id;
            sae_msg->sae_status = sae_status;
            vos_mem_copy(sae_msg->peer_mac_addr,
                         peer_mac_addr,
                         VOS_MAC_ADDR_SIZE);
            vos_message.bodyptr = sae_msg;
            vos_message.type =  eWNI_SME_SEND_SAE_MSG;
            VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
                      "SAE: sae_status %d session_id %d", sae_msg->sae_status,
                      sae_msg->session_id);
                    "SAE: sae_status %d session_id %d Peer: "
                    MAC_ADDRESS_STR,
                    sae_msg->sae_status,
                    sae_msg->session_id,
                    MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
            vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vos_message);
            if (!VOS_IS_STATUS_SUCCESS(vos_status)) {