⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wpa.c

📁 hostapd无线AP工具
💻 C
📖 第 1 页 / 共 5 页
字号:
		break;	}	sm->PTK_valid = FALSE;	memset(&sm->PTK, 0, sizeof(sm->PTK));	if (event != WPA_REAUTH_EAPOL) {		sm->pairwise_set = FALSE;		hostapd_set_encryption(sm->hapd, "none", sm->sta->addr, 0,				       (u8 *) "", 0);	}	wpa_sm_step(sm);}static const char * wpa_alg_txt(int alg){	switch (alg) {	case WPA_CIPHER_CCMP:		return "CCMP";	case WPA_CIPHER_TKIP:		return "TKIP";	case WPA_CIPHER_WEP104:	case WPA_CIPHER_WEP40:		return "WEP";	default:		return "";	}}/* Definitions for clarifying state machine implementation */#define SM_STATE(machine, state) \static void sm_ ## machine ## _ ## state ## _Enter(struct wpa_state_machine \*sm)#define SM_ENTRY(machine, _state, _data) \sm->changed = TRUE; \sm->_data ## _ ## state = machine ## _ ## _state; \if (sm->hapd->conf->debug >= HOSTAPD_DEBUG_MINIMAL) \	printf("WPA: " MACSTR " " #machine " entering state " #_state \		"\n", MAC2STR(sm->sta->addr));#define SM_ENTER(machine, state) sm_ ## machine ## _ ## state ## _Enter(sm)#define SM_STEP(machine) \static void sm_ ## machine ## _Step(struct wpa_state_machine *sm)#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)SM_STATE(WPA_PTK, INITIALIZE){	struct hostapd_data *hapd = sm->hapd;	SM_ENTRY(WPA_PTK, INITIALIZE, wpa_ptk);	if (sm->Init) {		/* Init flag is not cleared here, so avoid busy		 * loop by claiming nothing changed. */		sm->changed = FALSE;	}	sm->keycount = 0;	if (sm->GUpdateStationKeys)		hapd->wpa_auth->GKeyDoneStations--;	sm->GUpdateStationKeys = FALSE;	if (sm->sta->wpa == WPA_VERSION_WPA)		sm->PInitAKeys = FALSE;	if (1 /* Unicast cipher supported AND (ESS OR ((IBSS or WDS) and	       * Local AA > Remote AA)) */) {		sm->Pair = TRUE;	}	ieee802_1x_notify_port_enabled(sm->sta->eapol_sm, 0);	hostapd_set_encryption(sm->hapd, "none", sm->sta->addr, 0, (u8 *) "",			       0);	sm->pairwise_set = FALSE;	sm->PTK_valid = FALSE;	memset(&sm->PTK, 0, sizeof(sm->PTK));	ieee802_1x_notify_port_valid(sm->sta->eapol_sm, 0);	sm->TimeoutCtr = 0;	if (sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK)		ieee802_1x_set_sta_authorized(sm->hapd, sm->sta, 0);}SM_STATE(WPA_PTK, DISCONNECT){	SM_ENTRY(WPA_PTK, DISCONNECT, wpa_ptk);	sm->Disconnect = FALSE;	wpa_sta_disconnect(sm->hapd, sm->sta);}SM_STATE(WPA_PTK, DISCONNECTED){	SM_ENTRY(WPA_PTK, DISCONNECTED, wpa_ptk);	sm->hapd->wpa_auth->GNoStations--;	sm->DeauthenticationRequest = FALSE;}SM_STATE(WPA_PTK, AUTHENTICATION){	SM_ENTRY(WPA_PTK, AUTHENTICATION, wpa_ptk);	sm->hapd->wpa_auth->GNoStations++;	memset(&sm->PTK, 0, sizeof(sm->PTK));	sm->PTK_valid = FALSE;	if (sm->sta->eapol_sm) {		sm->sta->eapol_sm->portControl = Auto;		sm->sta->eapol_sm->portEnabled = TRUE;	}	sm->AuthenticationRequest = FALSE;}SM_STATE(WPA_PTK, AUTHENTICATION2){	SM_ENTRY(WPA_PTK, AUTHENTICATION2, wpa_ptk);	memcpy(sm->ANonce, sm->hapd->wpa_auth->Counter, WPA_NONCE_LEN);	inc_byte_array(sm->hapd->wpa_auth->Counter, WPA_NONCE_LEN);	sm->ReAuthenticationRequest = FALSE;	/* IEEE 802.11i/D9.0 does not clear TimeoutCtr here, but this is more	 * logical place than INITIALIZE since AUTHENTICATION2 can be	 * re-entered on ReAuthenticationRequest without going through	 * INITIALIZE. */	sm->TimeoutCtr = 0;}SM_STATE(WPA_PTK, INITPMK){	u8 *key;	size_t len;	SM_ENTRY(WPA_PTK, INITPMK, wpa_ptk);	if (sm->sta->pmksa) {		wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache");		memcpy(sm->PMK, sm->sta->pmksa->pmk, WPA_PMK_LEN);	} else if ((key = ieee802_1x_get_key_crypt(sm->sta->eapol_sm, &len))) {		wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine "			   "(len=%lu)", (unsigned long) len);		if (len > WPA_PMK_LEN)			len = WPA_PMK_LEN;		memcpy(sm->PMK, key, len);	} else {		wpa_printf(MSG_DEBUG, "WPA: Could not get PMK");	}	sm->sta->req_replay_counter_used = 0;	/* IEEE 802.11i/D9.0 does not set keyRun to FALSE, but not doing this	 * will break reauthentication since EAPOL state machines may not be	 * get into AUTHENTICATING state that clears keyRun before WPA state	 * machine enters AUTHENTICATION2 state and goes immediately to INITPMK	 * state and takes PMK from the previously used AAA Key. This will	 * eventually fail in 4-Way Handshake because Supplicant uses PMK	 * derived from the new AAA Key. Setting keyRun = FALSE here seems to	 * be good workaround for this issue. */	if (sm->sta->eapol_sm)		sm->sta->eapol_sm->keyRun = FALSE;}SM_STATE(WPA_PTK, INITPSK){	const u8 *psk;	SM_ENTRY(WPA_PTK, INITPSK, wpa_ptk);	psk = hostapd_get_psk(sm->hapd->conf, sm->sta->addr, NULL);	if (psk)		memcpy(sm->PMK, psk, WPA_PMK_LEN);	sm->sta->req_replay_counter_used = 0;}SM_STATE(WPA_PTK, PTKSTART){	u8 *pmkid = NULL;	size_t pmkid_len = 0;	SM_ENTRY(WPA_PTK, PTKSTART, wpa_ptk);	sm->PTKRequest = FALSE;	sm->TimeoutEvt = FALSE;	hostapd_logger(sm->hapd, sm->sta->addr, HOSTAPD_MODULE_WPA,		       HOSTAPD_LEVEL_DEBUG,		       "sending 1/4 msg of 4-Way Handshake");	if (sm->sta->pmksa &&	    (pmkid = malloc(2 + RSN_SELECTOR_LEN + PMKID_LEN))) {		pmkid_len = 2 + RSN_SELECTOR_LEN + PMKID_LEN;		pmkid[0] = WLAN_EID_GENERIC;		pmkid[1] = RSN_SELECTOR_LEN + PMKID_LEN;		memcpy(&pmkid[2], RSN_KEY_DATA_PMKID, RSN_SELECTOR_LEN);		memcpy(&pmkid[2 + RSN_SELECTOR_LEN], sm->sta->pmksa->pmkid,		       PMKID_LEN);	}	wpa_send_eapol(sm->hapd, sm->sta, 0, 0, 1, 0, 1, NULL, sm->ANonce,		       pmkid, pmkid_len, NULL, 0, 0);	free(pmkid);	sm->TimeoutCtr++;}SM_STATE(WPA_PTK, PTKCALCNEGOTIATING){	struct wpa_ptk PTK;	int ok = 0;	const u8 *pmk = NULL;	SM_ENTRY(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);	sm->EAPOLKeyReceived = FALSE;	/* WPA with IEEE 802.1X: use the derived PMK from EAP	 * WPA-PSK: iterate through possible PSKs and select the one matching	 * the packet */	for (;;) {		if (sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK) {			pmk = hostapd_get_psk(sm->hapd->conf, sm->sta->addr,					      pmk);			if (pmk == NULL)				break;		} else			pmk = sm->PMK;		wpa_pmk_to_ptk(sm->hapd, pmk, sm->hapd->own_addr,			       sm->sta->addr, sm->ANonce, sm->SNonce,			       (u8 *) &PTK, sizeof(PTK));		if (wpa_verify_key_mic(&PTK, sm->last_rx_eapol_key,				       sm->last_rx_eapol_key_len) == 0) {			ok = 1;			break;		}		if (sm->sta->wpa_key_mgmt != WPA_KEY_MGMT_PSK)			break;	}	if (!ok) {		hostapd_logger(sm->hapd, sm->sta->addr, HOSTAPD_MODULE_WPA,			       HOSTAPD_LEVEL_DEBUG, "invalid MIC in msg 2/4 "			       "of 4-Way Handshake");		return;	}	eloop_cancel_timeout(wpa_send_eapol_timeout, sm->hapd, sm->sta);	if (sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK) {		/* PSK may have changed from the previous choice, so update		 * state machine data based on whatever PSK was selected here.		 */		memcpy(sm->PMK, pmk, WPA_PMK_LEN);	}	sm->MICVerified = TRUE;	memcpy(&sm->PTK, &PTK, sizeof(PTK));	sm->PTK_valid = TRUE;}SM_STATE(WPA_PTK, PTKCALCNEGOTIATING2){	SM_ENTRY(WPA_PTK, PTKCALCNEGOTIATING2, wpa_ptk);	sm->TimeoutCtr = 0;}SM_STATE(WPA_PTK, PTKINITNEGOTIATING){	u8 rsc[WPA_KEY_RSC_LEN];	struct wpa_authenticator *gsm = sm->hapd->wpa_auth;	u8 *wpa_ie;	int wpa_ie_len;	SM_ENTRY(WPA_PTK, PTKINITNEGOTIATING, wpa_ptk);	sm->TimeoutEvt = FALSE;	/* Send EAPOL(1, 1, 1, Pair, P, RSC, ANonce, MIC(PTK), RSNIE, GTK[GN])	 */	memset(rsc, 0, WPA_KEY_RSC_LEN);	hostapd_get_seqnum(sm->hapd, NULL, gsm->GN, rsc);	wpa_ie = sm->hapd->wpa_ie;	wpa_ie_len = sm->hapd->wpa_ie_len;	if (sm->sta->wpa == WPA_VERSION_WPA &&	    (sm->hapd->conf->wpa & HOSTAPD_WPA_VERSION_WPA2) &&	    wpa_ie_len > wpa_ie[1] + 2 && wpa_ie[0] == WLAN_EID_RSN) {		/* WPA-only STA, remove RSN IE */		wpa_ie = wpa_ie + wpa_ie[1] + 2;		wpa_ie_len = wpa_ie[1] + 2;	}	hostapd_logger(sm->hapd, sm->sta->addr, HOSTAPD_MODULE_WPA,		       HOSTAPD_LEVEL_DEBUG,		       "sending 3/4 msg of 4-Way Handshake");	wpa_send_eapol(sm->hapd, sm->sta,		       sm->sta->wpa == WPA_VERSION_WPA2 ? 1 : 0,		       1, 1, 1, 1, rsc, sm->ANonce,		       wpa_ie, wpa_ie_len,		       gsm->GTK[gsm->GN - 1], gsm->GTK_len, gsm->GN);	sm->TimeoutCtr++;}SM_STATE(WPA_PTK, PTKINITDONE){	SM_ENTRY(WPA_PTK, PTKINITDONE, wpa_ptk);	sm->EAPOLKeyReceived = FALSE;	if (sm->Pair) {		char *alg;		int klen;		if (sm->sta->pairwise == WPA_CIPHER_TKIP) {			alg = "TKIP";			klen = 32;		} else {			alg = "CCMP";			klen = 16;		}		if (hostapd_set_encryption(sm->hapd, alg, sm->sta->addr, 0,					   sm->PTK.tk1, klen)) {			wpa_sta_disconnect(sm->hapd, sm->sta);			return;		}		/* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */		sm->pairwise_set = TRUE;		if (sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK)			ieee802_1x_set_sta_authorized(sm->hapd, sm->sta, 1);	}	if (0 /* IBSS == TRUE */) {		sm->keycount++;		if (sm->keycount == 2) {			ieee802_1x_notify_port_valid(sm->sta->eapol_sm, 1);		}	} else {		ieee802_1x_notify_port_valid(sm->sta->eapol_sm, 1);	}	if (sm->sta->eapol_sm) {		sm->sta->eapol_sm->keyAvailable = FALSE;		sm->sta->eapol_sm->keyDone = TRUE;	}	if (sm->sta->wpa == WPA_VERSION_WPA)		sm->PInitAKeys = TRUE;	else		sm->has_GTK = TRUE;	hostapd_logger(sm->hapd, sm->sta->addr, HOSTAPD_MODULE_WPA,		       HOSTAPD_LEVEL_INFO, "pairwise key handshake completed "		       "(%s)",		       sm->sta->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");}SM_STEP(WPA_PTK){	struct wpa_authenticator *wpa_auth = sm->hapd->wpa_auth;	if (sm->Init)		SM_ENTER(WPA_PTK, INITIALIZE);	else if (sm->Disconnect		 /* || FIX: dot11RSNAConfigSALifetime timeout */)		SM_ENTER(WPA_PTK, DISCONNECT);	else if (sm->DeauthenticationRequest)		SM_ENTER(WPA_PTK, DISCONNECTED);	else if (sm->AuthenticationRequest)		SM_ENTER(WPA_PTK, AUTHENTICATION);	else if (sm->ReAuthenticationRequest)		SM_ENTER(WPA_PTK, AUTHENTICATION2);	else if (sm->PTKRequest)		SM_ENTER(WPA_PTK, PTKSTART);	else switch (sm->wpa_ptk_state) {	case WPA_PTK_INITIALIZE:		break;	case WPA_PTK_DISCONNECT:		SM_ENTER(WPA_PTK, DISCONNECTED);		break;	case WPA_PTK_DISCONNECTED:		SM_ENTER(WPA_PTK, INITIALIZE);		break;	case WPA_PTK_AUTHENTICATION:		SM_ENTER(WPA_PTK, AUTHENTICATION2);		break;	case WPA_PTK_AUTHENTICATION2:		if ((sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_IEEE8021X) &&		    sm->sta->eapol_sm && sm->sta->eapol_sm->keyRun)			SM_ENTER(WPA_PTK, INITPMK);		else if ((sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK)			 /* FIX: && 802.1X::keyRun */)			SM_ENTER(WPA_PTK, INITPSK);		break;	case WPA_PTK_INITPMK:		if (sm->sta->eapol_sm && sm->sta->eapol_sm->keyAvailable)			SM_ENTER(WPA_PTK, PTKSTART);		else {			wpa_auth->dot11RSNA4WayHandshakeFailures++;			SM_ENTER(WPA_PTK, DISCONNECT);		}		break;	case WPA_PTK_INITPSK:		if (hostapd_get_psk(sm->hapd->conf, sm->sta->addr, NULL))			SM_ENTER(WPA_PTK, PTKSTART);		else {			hostapd_logger(sm->hapd, sm->sta->addr,				       HOSTAPD_MODULE_WPA,				       HOSTAPD_LEVEL_INFO,				       "no PSK configured for the STA");			wpa_auth->dot11RSNA4WayHandshakeFailures++;			SM_ENTER(WPA_PTK, DISCONNECT);		}		break;	case WPA_PTK_PTKSTART:		if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&		    sm->EAPOLKeyPairwise)			SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);		else if (sm->TimeoutCtr > dot11RSNAConfigPairwiseUpdateCount) {			wpa_auth->dot11RSNA4WayHandshakeFailures++;			SM_ENTER(WPA_PTK, DISCONNECT);		} else if (sm->TimeoutEvt)			SM_ENTER(WPA_PTK, PTKSTART);		break;	case WPA_PTK_PTKCALCNEGOTIATING:		if (sm->MICVerified)			SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING2);		else if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&			 sm->EAPOLKeyPairwise)			SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING);		else if (sm->TimeoutEvt)			SM_ENTER(WPA_PTK, PTKSTART);		break;	case WPA_PTK_PTKCALCNEGOTIATING2:		SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);		break;	case WPA_PTK_PTKINITNEGOTIATING:		if (sm->EAPOLKeyReceived && !sm->EAPOLKeyRequest &&		    sm->EAPOLKeyPairwise && sm->MICVerified)			SM_ENTER(WPA_PTK, PTKINITDONE);		else if (sm->TimeoutCtr > dot11RSNAConfigPairwiseUpdateCount) {			wpa_auth->dot11RSNA4WayHandshakeFailures++;			SM_ENTER(WPA_PTK, DISCONNECT);		} else if (sm->TimeoutEvt)			SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);		break;	case WPA_PTK_PTKINITDONE:		break;	}}SM_STATE(WPA_PTK_GROUP, IDLE){	SM_ENTRY(WPA_PTK_GROUP, IDLE, wpa_ptk_group);	if (sm->Init) {		/* Init flag is not cleared here, so avoid busy		 * loop by claiming nothing changed. */		sm->changed = FALSE;	}	sm->GTimeoutCtr = 0;}SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING){	u8 rsc[WPA_KEY_RSC_LEN];	struct wpa_authenticator *gsm = sm->hapd->wpa_auth;	SM_ENTRY(WPA_PTK_GROUP, REKEYNEGOTIATING, wpa_ptk_group);	if (sm->sta->wpa == WPA_VERSION_WPA)		sm->PInitAKeys = FALSE;	sm->TimeoutEvt = FALSE;	/* Send EAPOL(1, 1, 1, !Pair, G, RSC, GNonce, MIC(PTK), GTK[GN]) */	memset(rsc, 0, WPA_KEY_RSC_LEN);	if (gsm->wpa_group_state == WPA_GROUP_SETKEYSDONE)		hostapd_get_seqnum(sm->hapd, NULL, gsm->GN, rsc);	hostapd_logger(sm->hapd, sm->sta->addr, HOSTAPD_MODULE_WPA,		       HOSTAPD_LEVEL_DEBUG,		       "sending 1/2 msg of Group Key Handshake");	wpa_send_eapol(sm->hapd, sm->sta, 1, 1, 1, !sm->Pair, 0, rsc,		       gsm->GNonce, NULL, 0,		       gsm->GTK[gsm->GN - 1], gsm->GTK_len, gsm->GN);	sm->GTimeoutCtr++;}SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED){	SM_ENTRY(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group);	sm->EAPOLKeyReceived = FALSE;	sm->GUpdateStationKeys = FALSE;	sm->hapd->wpa_auth->GKeyDoneStations--;	sm->GTimeoutCtr = 0;	/* FIX: MLME.SetProtection.Request(TA, Tx_Rx) */	hos

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -