Exemplo n.º 1
0
static struct gas_dialog_info *
gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token)
{
	struct sta_info *sta;
	struct gas_dialog_info *dia = NULL;
	int i, j;

	sta = ap_get_sta(hapd, addr);
	if (!sta) {
		/*
		 * We need a STA entry to be able to maintain state for
		 * the GAS query.
		 */
		wpa_printf(MSG_DEBUG, "ANQP: Add a temporary STA entry for "
			   "GAS query");
		sta = ap_sta_add(hapd, addr);
		if (!sta) {
			wpa_printf(MSG_DEBUG, "Failed to add STA " MACSTR
				   " for GAS query", MAC2STR(addr));
			return NULL;
		}
		sta->flags |= WLAN_STA_GAS;
		/*
		 * The default inactivity is 300 seconds. We don't need
		 * it to be that long.
		 */
		ap_sta_session_timeout(hapd, sta, 5);
	} else {
		ap_sta_replenish_timeout(hapd, sta, 5);
	}

	if (sta->gas_dialog == NULL) {
		sta->gas_dialog = os_zalloc(GAS_DIALOG_MAX *
					    sizeof(struct gas_dialog_info));
		if (sta->gas_dialog == NULL)
			return NULL;
	}

	for (i = sta->gas_dialog_next, j = 0; j < GAS_DIALOG_MAX; i++, j++) {
		if (i == GAS_DIALOG_MAX)
			i = 0;
		if (sta->gas_dialog[i].valid)
			continue;
		dia = &sta->gas_dialog[i];
		dia->valid = 1;
		dia->index = i;
		dia->dialog_token = dialog_token;
		sta->gas_dialog_next = (++i == GAS_DIALOG_MAX) ? 0 : i;
		return dia;
	}

	wpa_msg(hapd->msg_ctx, MSG_ERROR, "ANQP: Could not create dialog for "
		MACSTR " dialog_token %u. Consider increasing "
		"GAS_DIALOG_MAX.", MAC2STR(addr), dialog_token);

	return NULL;
}
Exemplo n.º 2
0
static void handle_auth(hostapd *hapd, struct ieee80211_mgmt *mgmt, size_t len)
{
    u16 auth_alg, auth_transaction, status_code;
    u16 resp = WLAN_STATUS_SUCCESS;
    struct sta_info *sta = NULL;
    int res;
    u16 fc;
    u8 *challenge = NULL;
    u32 session_timeout, acct_interim_interval;

    if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
        printf("handle_auth - too short payload (len=%lu)\n",
               (unsigned long) len);
        return;
    }

    auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
    auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
    status_code = le_to_host16(mgmt->u.auth.status_code);
    fc = le_to_host16(mgmt->frame_control);

    if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
            2 + WLAN_AUTH_CHALLENGE_LEN &&
            mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
            mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
        challenge = &mgmt->u.auth.variable[2];

    HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
                  "authentication: STA=" MACSTR " auth_alg=%d "
                  "auth_transaction=%d status_code=%d wep=%d%s\n",
                  MAC2STR(mgmt->sa), auth_alg, auth_transaction,
                  status_code, !!(fc & WLAN_FC_ISWEP),
                  challenge ? " challenge" : "");

    if (hapd->assoc_ap_state == AUTHENTICATE && auth_transaction == 2 &&
            memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0 &&
            memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
        if (status_code != 0) {
            printf("Authentication (as station) with AP "
                   MACSTR " failed (status_code=%d)\n",
                   MAC2STR(hapd->conf->assoc_ap_addr),
                   status_code);
            return;
        }
        printf("Authenticated (as station) with AP " MACSTR "\n",
               MAC2STR(hapd->conf->assoc_ap_addr));
        ieee802_11_sta_associate(hapd, NULL);
        return;
    }

    if (hapd->tkip_countermeasures) {
        resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
        goto fail;
    }

    if (!(((hapd->conf->auth_algs & HOSTAPD_AUTH_OPEN) &&
            auth_alg == WLAN_AUTH_OPEN) ||
            ((hapd->conf->auth_algs & HOSTAPD_AUTH_SHARED_KEY) &&
             auth_alg == WLAN_AUTH_SHARED_KEY))) {
        printf("Unsupported authentication algorithm (%d)\n",
               auth_alg);
        resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
        goto fail;
    }

    if (!(auth_transaction == 1 ||
            (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
        printf("Unknown authentication transaction number (%d)\n",
               auth_transaction);
        resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
        goto fail;
    }

    if (memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
        printf("Station " MACSTR " not allowed to authenticate.\n",
               MAC2STR(mgmt->sa));
        resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
        goto fail;
    }

    res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
                                  &session_timeout,
                                  &acct_interim_interval);
    if (res == HOSTAPD_ACL_REJECT) {
        printf("Station " MACSTR " not allowed to authenticate.\n",
               MAC2STR(mgmt->sa));
        resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
        goto fail;
    }
    if (res == HOSTAPD_ACL_PENDING) {
        HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Authentication frame "
                      "from " MACSTR " waiting for an external "
                      "authentication\n", MAC2STR(mgmt->sa));
        /* Authentication code will re-send the authentication frame
         * after it has received (and cached) information from the
         * external source. */
        return;
    }

    sta = ap_sta_add(hapd, mgmt->sa);
    if (!sta) {
        resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
        goto fail;
    }
    sta->flags &= ~WLAN_STA_PREAUTH;
    ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);

    if (hapd->conf->radius->acct_interim_interval == 0 &&
            acct_interim_interval)
        sta->acct_interim_interval = acct_interim_interval;
    if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
        ap_sta_session_timeout(hapd, sta, session_timeout);
    else
        ap_sta_no_session_timeout(hapd, sta);

    switch (auth_alg) {
    case WLAN_AUTH_OPEN:
        hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
                       HOSTAPD_LEVEL_DEBUG,
                       "authentication OK (open system)");
#ifdef IEEE80211_REQUIRE_AUTH_ACK
        /* Station will be marked authenticated if it ACKs the
         * authentication reply. */
#else
        sta->flags |= WLAN_STA_AUTH;
        wpa_sm_event(hapd, sta, WPA_AUTH);
#endif
        break;
    case WLAN_AUTH_SHARED_KEY:
        resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
                               fc & WLAN_FC_ISWEP);
        break;
    }

fail:
    send_auth_reply(hapd, mgmt, auth_alg, auth_transaction + 1, resp,
                    sta ? sta->challenge : NULL);
}
Exemplo n.º 3
0
/* Process the RADIUS frames from Authentication Server */
static RadiusRxResult
ieee802_1x_receive_auth(struct wpa_supplicant *wpa_s,
			struct radius_msg *msg, struct radius_msg *req,
			u8 *shared_secret, size_t shared_secret_len,
			void *data)
{
#if 0
	u32 session_timeout, termination_action;
	int session_timeout_set;
	int acct_interim_interval;
#endif

#if 0
	sta = ap_get_sta_radius_identifier(hapd, msg->hdr->identifier);
	if (sta == NULL) {
		wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not "
		      "find matching station for this RADIUS "
		      "message\n");
		return RADIUS_RX_UNKNOWN;
	}
#endif

	/* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
	 * present when packet contains an EAP-Message attribute */
	if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&
	    radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
				0) < 0 &&
	    radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG, "Allowing RADIUS "
			      "Access-Reject without Message-Authenticator "
			      "since it does not include EAP-Message\n");
	} else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
				     req)) {
		printf("Incoming RADIUS packet did not have correct "
		       "Message-Authenticator - dropped\n");
		return RADIUS_RX_UNKNOWN;
	}

	if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
	    msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&
	    msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
		printf("Unknown RADIUS message code\n");
		return RADIUS_RX_UNKNOWN;
	}

	wpa_s->radius_identifier = -1;
	wpa_printf(MSG_DEBUG, "RADIUS packet matching with station");

	if (wpa_s->last_recv_radius) {
		radius_msg_free(wpa_s->last_recv_radius);
		free(wpa_s->last_recv_radius);
	}

	wpa_s->last_recv_radius = msg;

#if 0
	session_timeout_set =
		!radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,
					   &session_timeout);
	if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION,
				      &termination_action))
		termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;

	if (hapd->conf->radius_acct_interim_interval == 0 &&
	    msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
	    radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
				      &acct_interim_interval) == 0) {
		if (acct_interim_interval < 60) {
			hostapd_logger(hapd, sta->addr,
				       HOSTAPD_MODULE_IEEE8021X,
				       HOSTAPD_LEVEL_INFO,
				       "ignored too small "
				       "Acct-Interim-Interval %d",
				       acct_interim_interval);
		} else
			sta->acct_interim_interval = acct_interim_interval;
	}


	switch (msg->hdr->code) {
	case RADIUS_CODE_ACCESS_ACCEPT:
		/* draft-congdon-radius-8021x-22.txt, Ch. 3.17 */
		if (session_timeout_set &&
			termination_action ==
		    RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
			sta->eapol_sm->reauth_timer.reAuthPeriod =
				session_timeout;
		} else if (session_timeout_set)
			ap_sta_session_timeout(hapd, sta, session_timeout);

		sta->eapol_sm->be_auth.aSuccess = TRUE;
		ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret,
				    shared_secret_len);
		if (sta->eapol_sm->keyAvailable) {
			pmksa_cache_add(hapd, sta, sta->eapol_key_crypt,
					session_timeout_set ?
					session_timeout : -1);
		}
		break;
	case RADIUS_CODE_ACCESS_REJECT:
		sta->eapol_sm->be_auth.aFail = TRUE;
		break;
	case RADIUS_CODE_ACCESS_CHALLENGE:
		if (session_timeout_set) {
			/* RFC 2869, Ch. 2.3.2
			 * draft-congdon-radius-8021x-22.txt, Ch. 3.17 */
			sta->eapol_sm->be_auth.suppTimeout = session_timeout;
		}
		sta->eapol_sm->be_auth.aReq = TRUE;
		break;
	}
#else

	switch (msg->hdr->code) {
	case RADIUS_CODE_ACCESS_ACCEPT:
		wpa_s->radius_access_accept_received = 1;
		ieee802_1x_get_keys(wpa_s, msg, req, shared_secret,
				    shared_secret_len);
		break;
	case RADIUS_CODE_ACCESS_REJECT:
		wpa_s->radius_access_reject_received = 1;
		break;
	}
#endif

	ieee802_1x_decapsulate_radius(wpa_s);

	/* eapol_sm_step(sta->eapol_sm); */

	if (msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT ||
	    msg->hdr->code == RADIUS_CODE_ACCESS_REJECT) {
		eloop_terminate();
	}

	return RADIUS_RX_QUEUED;
}
Exemplo n.º 4
0
/*AC代理终端发起MAC认证请求*/
static void mac_auth_req(struct hostapd_data * hapd, struct sta_info * sta)
{
	AC_USER_DATA_QOS_T user_qos = {0} ;
	u32 session_timeout =0, acct_interim_interval = 0 ;
	int res ;
		
	if(hapd == NULL
		|| hapd->iface == NULL
		|| hapd->iface->pstWtp == NULL
		|| sta == NULL){
		ModuleLogMsg(APP_MODULE_HOSTAPD, APP_FATAL,
			"%s, point is NULL.\n", __func__) ;
		return ;
	}
	
	res = hostapd_allowed_address(hapd, sta->addr, NULL, 0, & session_timeout, & acct_interim_interval, NULL, & user_qos) ;	
	switch(res){
	case HOSTAPD_ACL_REJECT :{
		ModuleLogMsg(APP_MODULE_HOSTAPD, APP_MSG,
			"%s, sta(%u/%u/%u/"MACSTR") is not allowed to authenticate.\n", 
			__func__, hapd->iface->pstWtp->usWtpId, hapd->iface->interface_id, hapd->vap_id, MAC2STR(sta->addr)) ;
		mac_auth_disconnect(hapd, sta) ;
		return ;
	}
	case HOSTAPD_ACL_PENDING :{
		if(sta->access_reason == WLAN_REASON_ACCESS_HANDOVER){
			ModuleLogMsg(APP_MODULE_HOSTAPD, APP_MSG,
				"%s, sta(%u/%u/%u/"MACSTR") is allowed to authenticate, due to handover.\n", 
				__func__, hapd->iface->pstWtp->usWtpId, hapd->iface->interface_id, hapd->vap_id, MAC2STR(sta->addr)) ;
			sta->flags |= WLAN_STA_AUTHORIZED_MAC ;

			if(! hapd->conf->ieee802_1x){
				mac_auth_update_sta_identity(hapd, sta) ;
				/*QOS信息在切换时,从OLD STA拷贝,故此处无需获取QOS信息*/
			}
			
			return ;	
		}
		else{
			ModuleLogMsg(APP_MODULE_HOSTAPD, APP_MSG,
				"%s, sta(%u/%u/%u/"MACSTR") waiting for external authentication.\n", 
				__func__, hapd->iface->pstWtp->usWtpId, hapd->iface->interface_id, hapd->vap_id, MAC2STR(sta->addr)) ;
			mac_auth_set_sta_authorized(hapd, sta, 0) ;
			return ;
		}
	}
	case HOSTAPD_ACL_ACCEPT_TIMEOUT: {
		ap_sta_session_timeout(hapd, sta, session_timeout) ;

		/*follow on*/
	}
	case HOSTAPD_ACL_ACCEPT :{
		if (acct_interim_interval > 60){
			sta->acct_interim_interval = acct_interim_interval;
		}

		ModuleLogMsg(APP_MODULE_HOSTAPD, APP_MSG,
			"%s, sta(%u/%u/%u/"MACSTR") is allowed to authenticate, due to it's in accept_mac_list or acl_cache (%s).\n", 
			__func__, hapd->iface->pstWtp->usWtpId, hapd->iface->interface_id, hapd->vap_id, MAC2STR(sta->addr), res == HOSTAPD_ACL_ACCEPT_TIMEOUT ? "accept timeout" : "accept") ;
		sta->flags |= WLAN_STA_AUTHORIZED_MAC ;

		mac_auth_update_sta_identity(hapd, sta) ;
		mac_auth_update_sta_info(hapd, sta, & user_qos) ;
		
		return  ;
	}
	default :
		ModuleLogMsg(APP_MODULE_HOSTAPD, APP_WARN,
			"%s, unknown res(%d).\n", __func__, res) ;
		return ;
	}

	return ;
}
Exemplo n.º 5
0
static void handle_auth(struct hostapd_data *hapd,
			const struct ieee80211_mgmt *mgmt, size_t len)
{
	u16 auth_alg, auth_transaction, status_code;
	u16 resp = WLAN_STATUS_SUCCESS;
	struct sta_info *sta = NULL;
	int res;
	u16 fc;
	const u8 *challenge = NULL;
	u32 session_timeout, acct_interim_interval;
	int vlan_id = 0;
	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
	size_t resp_ies_len = 0;

	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
		printf("handle_auth - too short payload (len=%lu)\n",
		       (unsigned long) len);
		return;
	}

	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
	status_code = le_to_host16(mgmt->u.auth.status_code);
	fc = le_to_host16(mgmt->frame_control);

	if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
	    2 + WLAN_AUTH_CHALLENGE_LEN &&
	    mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
	    mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
		challenge = &mgmt->u.auth.variable[2];

	wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
		   "auth_transaction=%d status_code=%d wep=%d%s",
		   MAC2STR(mgmt->sa), auth_alg, auth_transaction,
		   status_code, !!(fc & WLAN_FC_ISWEP),
		   challenge ? " challenge" : "");

	if (hapd->tkip_countermeasures) {
		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
		goto fail;
	}

	if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
	       auth_alg == WLAN_AUTH_OPEN) ||
#ifdef CONFIG_IEEE80211R
	      (hapd->conf->wpa &&
	       (hapd->conf->wpa_key_mgmt &
		(WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK)) &&
	       auth_alg == WLAN_AUTH_FT) ||
#endif /* CONFIG_IEEE80211R */
	      ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
	       auth_alg == WLAN_AUTH_SHARED_KEY))) {
		printf("Unsupported authentication algorithm (%d)\n",
		       auth_alg);
		resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
		goto fail;
	}

	if (!(auth_transaction == 1 ||
	      (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
		printf("Unknown authentication transaction number (%d)\n",
		       auth_transaction);
		resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
		goto fail;
	}

	if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
		printf("Station " MACSTR " not allowed to authenticate.\n",
		       MAC2STR(mgmt->sa));
		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
		goto fail;
	}

	res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
				      &session_timeout,
				      &acct_interim_interval, &vlan_id);
	if (res == HOSTAPD_ACL_REJECT) {
		printf("Station " MACSTR " not allowed to authenticate.\n",
		       MAC2STR(mgmt->sa));
		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
		goto fail;
	}
	if (res == HOSTAPD_ACL_PENDING) {
		wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
			   " waiting for an external authentication",
			   MAC2STR(mgmt->sa));
		/* Authentication code will re-send the authentication frame
		 * after it has received (and cached) information from the
		 * external source. */
		return;
	}

	sta = ap_sta_add(hapd, mgmt->sa);
	if (!sta) {
		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
		goto fail;
	}

	if (vlan_id > 0) {
		if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
					       vlan_id) == NULL) {
			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
				       HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
				       "%d received from RADIUS server",
				       vlan_id);
			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
			goto fail;
		}
		sta->vlan_id = vlan_id;
		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
	}

	sta->flags &= ~WLAN_STA_PREAUTH;
	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);

	if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
		sta->acct_interim_interval = acct_interim_interval;
	if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
		ap_sta_session_timeout(hapd, sta, session_timeout);
	else
		ap_sta_no_session_timeout(hapd, sta);

	switch (auth_alg) {
	case WLAN_AUTH_OPEN:
		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "authentication OK (open system)");
#ifdef IEEE80211_REQUIRE_AUTH_ACK
		/* Station will be marked authenticated if it ACKs the
		 * authentication reply. */
#else
		sta->flags |= WLAN_STA_AUTH;
		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
		sta->auth_alg = WLAN_AUTH_OPEN;
		mlme_authenticate_indication(hapd, sta);
#endif
		break;
	case WLAN_AUTH_SHARED_KEY:
		resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
				       fc & WLAN_FC_ISWEP);
		sta->auth_alg = WLAN_AUTH_SHARED_KEY;
		mlme_authenticate_indication(hapd, sta);
		if (sta->challenge && auth_transaction == 1) {
			resp_ies[0] = WLAN_EID_CHALLENGE;
			resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
			os_memcpy(resp_ies + 2, sta->challenge,
				  WLAN_AUTH_CHALLENGE_LEN);
			resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
		}
		break;
#ifdef CONFIG_IEEE80211R
	case WLAN_AUTH_FT:
		sta->auth_alg = WLAN_AUTH_FT;
		if (sta->wpa_sm == NULL)
			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
							sta->addr);
		if (sta->wpa_sm == NULL) {
			wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
				   "state machine");
			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
			goto fail;
		}
		wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
				    auth_transaction, mgmt->u.auth.variable,
				    len - IEEE80211_HDRLEN -
				    sizeof(mgmt->u.auth),
				    handle_auth_ft_finish, hapd);
		/* handle_auth_ft_finish() callback will complete auth. */
		return;
#endif /* CONFIG_IEEE80211R */
	}

 fail:
	send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
			auth_transaction + 1, resp, resp_ies, resp_ies_len);
}