Example #1
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);
}
Example #2
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 ;
}
Example #3
0
static void
bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
{
	struct bsd_driver_data *drv = ctx;
	char buf[2048];
	struct if_announcemsghdr *ifan;
	struct rt_msghdr *rtm;
	struct ieee80211_michael_event *mic;
	struct ieee80211_join_event *join;
	struct ieee80211_leave_event *leave;
#ifdef CONFIG_DRIVER_RADIUS_ACL
	struct ieee80211_auth_event *auth;
#endif
	int n;
	union wpa_event_data data;

	n = read(sock, buf, sizeof(buf));
	if (n < 0) {
		if (errno != EINTR && errno != EAGAIN)
			perror("read(PF_ROUTE)");
		return;
	}

	rtm = (struct rt_msghdr *) buf;
	if (rtm->rtm_version != RTM_VERSION) {
		wpa_printf(MSG_DEBUG, "Routing message version %d not "
			"understood\n", rtm->rtm_version);
		return;
	}
	ifan = (struct if_announcemsghdr *) rtm;
	if (ifan->ifan_index != drv->ifindex) {
		wpa_printf(MSG_DEBUG, "Discard routing message to if#%d "
			"(not for us %d)\n",
			ifan->ifan_index, drv->ifindex);
		return;
	}
	switch (rtm->rtm_type) {
	case RTM_IEEE80211:
		switch (ifan->ifan_what) {
		case RTM_IEEE80211_ASSOC:
		case RTM_IEEE80211_REASSOC:
		case RTM_IEEE80211_DISASSOC:
		case RTM_IEEE80211_SCAN:
			break;
		case RTM_IEEE80211_LEAVE:
			leave = (struct ieee80211_leave_event *) &ifan[1];
			drv_event_disassoc(drv->hapd, leave->iev_addr);
			break;
		case RTM_IEEE80211_JOIN:
#ifdef RTM_IEEE80211_REJOIN
		case RTM_IEEE80211_REJOIN:
#endif
			join = (struct ieee80211_join_event *) &ifan[1];
			bsd_new_sta(drv, drv->hapd, join->iev_addr);
			break;
		case RTM_IEEE80211_REPLAY:
			/* ignore */
			break;
		case RTM_IEEE80211_MICHAEL:
			mic = (struct ieee80211_michael_event *) &ifan[1];
			wpa_printf(MSG_DEBUG,
				"Michael MIC failure wireless event: "
				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
				MAC2STR(mic->iev_src));
			os_memset(&data, 0, sizeof(data));
			data.michael_mic_failure.unicast = 1;
			data.michael_mic_failure.src = mic->iev_src;
			wpa_supplicant_event(drv->hapd,
					     EVENT_MICHAEL_MIC_FAILURE, &data);
			break;
#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET
		case RTM_IEEE80211_AUTH:
			auth = (struct ieee80211_auth_event *) &ifan[1];
			wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR,
			    MAC2STR(auth->iev_addr));
			n = hostapd_allowed_address(drv->hapd, auth->iev_addr,
				NULL, 0, NULL, NULL, NULL);
			switch (n) {
			case HOSTAPD_ACL_ACCEPT:
			case HOSTAPD_ACL_REJECT:
				hostapd_set_radius_acl_auth(drv->hapd,
				    auth->iev_addr, n, 0);
				wpa_printf(MSG_DEBUG,
				    "802.11 AUTH, STA = " MACSTR " hostapd says: %s",
				    MAC2STR(auth->iev_addr),
				    (n == HOSTAPD_ACL_ACCEPT ?
					"ACCEPT" : "REJECT" ));
				break;
			case HOSTAPD_ACL_PENDING:
				wpa_printf(MSG_DEBUG,
				    "802.11 AUTH, STA = " MACSTR " pending",
				    MAC2STR(auth->iev_addr));
				break;
			}
			break;
#endif /* CONFIG_DRIVER_RADIUS_ACL */
		}
		break;
	}
}
static int hostapd_config_reload_sta(struct hostapd_data *hapd,
				     struct sta_info *sta, void *data)
{
	struct hostapd_config_change *change = data;
	struct hostapd_bss_config *newbss, *oldbss;
	int deauth = 0;
	u8 reason = WLAN_REASON_PREV_AUTH_NOT_VALID;

	newbss = change->newbss;
	oldbss = change->oldbss;
	hapd = change->hapd;

	if (sta->ssid == &oldbss->ssid) {
		sta->ssid = &newbss->ssid;

		if (newbss->ssid.ssid_len != oldbss->ssid.ssid_len ||
		    memcmp(newbss->ssid.ssid, oldbss->ssid.ssid,
			   newbss->ssid.ssid_len) != 0) {
			/* main SSID was changed - kick STA out */
			deauth++;
		}
	}
	sta->ssid_probe = sta->ssid;

	/*
	 * If MAC ACL configuration has changed, deauthenticate stations that
	 * have been removed from accepted list or have been added to denied
	 * list. If external RADIUS server is used for ACL, all stations are
	 * deauthenticated and they will need to authenticate again. This
	 * limits sudden load on the RADIUS server since the verification will
	 * be done over the time needed for the STAs to reauthenticate
	 * themselves.
	 */
	if (change->mac_acl_changed &&
	    (newbss->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH ||
	     !hostapd_allowed_address(hapd, sta->addr, NULL, 0, NULL, NULL,
				      NULL)))
		deauth++;

	if (newbss->ieee802_1x != oldbss->ieee802_1x &&
	    sta->ssid == &hapd->conf->ssid)
		deauth++;

	if (newbss->wpa != oldbss->wpa)
		deauth++;

	if (!newbss->wme_enabled && (sta->flags & WLAN_STA_WME))
		deauth++;

	if (newbss->auth_algs != oldbss->auth_algs &&
	    ((sta->auth_alg == WLAN_AUTH_OPEN &&
	      !(newbss->auth_algs & HOSTAPD_AUTH_OPEN)) ||
	     (sta->auth_alg == WLAN_AUTH_SHARED_KEY &&
	      !(newbss->auth_algs & HOSTAPD_AUTH_SHARED_KEY))))
		deauth++;

	if (change->num_sta_remove > 0) {
		deauth++;
		reason = WLAN_REASON_DISASSOC_AP_BUSY;
	}

	if (deauth) {
		HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "STA " MACSTR
			      " deauthenticated during config reloading "
			      "(reason=%d)\n", MAC2STR(sta->addr), reason);
		ieee802_11_send_deauth(hapd, sta->addr, reason);
		ap_sta_deauthenticate(hapd, sta, reason);
		change->num_sta_remove--;
	}

	return 0;
}
Example #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);
}