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

📄 wpa.c

📁 hostapd无线AP工具
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (pmkid)		entry = hapd->pmkid[PMKID_HASH(pmkid)];	else		entry = hapd->pmksa;	while (entry) {		if ((spa == NULL || memcmp(entry->spa, spa, ETH_ALEN) == 0) &&		    (pmkid == NULL ||		     memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0))			return entry;		entry = pmkid ? entry->hnext : entry->next;	}	return NULL;}struct wpa_ie_data {	int pairwise_cipher;	int group_cipher;	int key_mgmt;	int capabilities;	size_t num_pmkid;	u8 *pmkid;};static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,				struct wpa_ie_data *data){	struct wpa_ie_hdr *hdr;	u8 *pos;	int left;	int i, count;	memset(data, 0, sizeof(*data));	data->pairwise_cipher = WPA_CIPHER_TKIP;	data->group_cipher = WPA_CIPHER_TKIP;	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;	if (wpa_ie_len < sizeof(struct wpa_ie_hdr))		return -1;	hdr = (struct wpa_ie_hdr *) wpa_ie;	if (hdr->elem_id != WLAN_EID_GENERIC ||	    hdr->len != wpa_ie_len - 2 ||	    memcmp(&hdr->oui, WPA_OUI_TYPE, WPA_SELECTOR_LEN) != 0 ||	    le_to_host16(hdr->version) != WPA_VERSION) {		return -2;	}	pos = (u8 *) (hdr + 1);	left = wpa_ie_len - sizeof(*hdr);	if (left >= WPA_SELECTOR_LEN) {		data->group_cipher = wpa_selector_to_bitfield(pos);		pos += WPA_SELECTOR_LEN;		left -= WPA_SELECTOR_LEN;	} else if (left > 0)		  return -3;	if (left >= 2) {		data->pairwise_cipher = 0;		count = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;		if (count == 0 || left < count * WPA_SELECTOR_LEN)			return -4;		for (i = 0; i < count; i++) {			data->pairwise_cipher |= wpa_selector_to_bitfield(pos);			pos += WPA_SELECTOR_LEN;			left -= WPA_SELECTOR_LEN;		}	} else if (left == 1)		return -5;	if (left >= 2) {		data->key_mgmt = 0;		count = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;		if (count == 0 || left < count * WPA_SELECTOR_LEN)			return -6;		for (i = 0; i < count; i++) {			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);			pos += WPA_SELECTOR_LEN;			left -= WPA_SELECTOR_LEN;		}	} else if (left == 1)		return -7;	if (left >= 2) {		data->capabilities = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;	}	if (left > 0) {		return -8;	}	return 0;}static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,				struct wpa_ie_data *data){	struct rsn_ie_hdr *hdr;	u8 *pos;	int left;	int i, count;	memset(data, 0, sizeof(*data));	data->pairwise_cipher = WPA_CIPHER_CCMP;	data->group_cipher = WPA_CIPHER_CCMP;	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;	if (rsn_ie_len < sizeof(struct rsn_ie_hdr))		return -1;	hdr = (struct rsn_ie_hdr *) rsn_ie;	if (hdr->elem_id != WLAN_EID_RSN ||	    hdr->len != rsn_ie_len - 2 ||	    le_to_host16(hdr->version) != RSN_VERSION) {		return -2;	}	pos = (u8 *) (hdr + 1);	left = rsn_ie_len - sizeof(*hdr);	if (left >= RSN_SELECTOR_LEN) {		data->group_cipher = rsn_selector_to_bitfield(pos);		pos += RSN_SELECTOR_LEN;		left -= RSN_SELECTOR_LEN;	} else if (left > 0)		  return -3;	if (left >= 2) {		data->pairwise_cipher = 0;		count = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;		if (count == 0 || left < count * RSN_SELECTOR_LEN)			return -4;		for (i = 0; i < count; i++) {			data->pairwise_cipher |= rsn_selector_to_bitfield(pos);			pos += RSN_SELECTOR_LEN;			left -= RSN_SELECTOR_LEN;		}	} else if (left == 1)		return -5;	if (left >= 2) {		data->key_mgmt = 0;		count = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;		if (count == 0 || left < count * RSN_SELECTOR_LEN)			return -6;		for (i = 0; i < count; i++) {			data->key_mgmt |= rsn_key_mgmt_to_bitfield(pos);			pos += RSN_SELECTOR_LEN;			left -= RSN_SELECTOR_LEN;		}	} else if (left == 1)		return -7;	if (left >= 2) {		data->capabilities = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;	}	if (left >= 2) {		data->num_pmkid = pos[0] | (pos[1] << 8);		pos += 2;		left -= 2;		if (left < data->num_pmkid * PMKID_LEN) {			printf("RSN: too short RSN IE for PMKIDs "			       "(num=%lu, left=%d)\n",			       (unsigned long) data->num_pmkid, left);			return -9;		}		data->pmkid = pos;		pos += data->num_pmkid * PMKID_LEN;		left -= data->num_pmkid * PMKID_LEN;	}	if (left > 0) {		return -8;	}	return 0;}int wpa_validate_wpa_ie(struct hostapd_data *hapd, struct sta_info *sta,			const u8 *wpa_ie, size_t wpa_ie_len, int version){	struct wpa_ie_data data;	int ciphers, key_mgmt, res, i;	const u8 *selector;	if (version == HOSTAPD_WPA_VERSION_WPA2) {		res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);		selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;		if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)			selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;		else if (data.key_mgmt & WPA_KEY_MGMT_PSK)			selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X;		memcpy(hapd->wpa_auth->dot11RSNAAuthenticationSuiteSelected,		       selector, RSN_SELECTOR_LEN);		selector = RSN_CIPHER_SUITE_CCMP;		if (data.pairwise_cipher & WPA_CIPHER_CCMP)			selector = RSN_CIPHER_SUITE_CCMP;		else if (data.pairwise_cipher & WPA_CIPHER_TKIP)			selector = RSN_CIPHER_SUITE_TKIP;		else if (data.pairwise_cipher & WPA_CIPHER_WEP104)			selector = RSN_CIPHER_SUITE_WEP104;		else if (data.pairwise_cipher & WPA_CIPHER_WEP40)			selector = RSN_CIPHER_SUITE_WEP40;		else if (data.pairwise_cipher & WPA_CIPHER_NONE)			selector = RSN_CIPHER_SUITE_NONE;		memcpy(hapd->wpa_auth->dot11RSNAPairwiseCipherSelected,		       selector, RSN_SELECTOR_LEN);		selector = RSN_CIPHER_SUITE_CCMP;		if (data.group_cipher & WPA_CIPHER_CCMP)			selector = RSN_CIPHER_SUITE_CCMP;		else if (data.group_cipher & WPA_CIPHER_TKIP)			selector = RSN_CIPHER_SUITE_TKIP;		else if (data.group_cipher & WPA_CIPHER_WEP104)			selector = RSN_CIPHER_SUITE_WEP104;		else if (data.group_cipher & WPA_CIPHER_WEP40)			selector = RSN_CIPHER_SUITE_WEP40;		else if (data.group_cipher & WPA_CIPHER_NONE)			selector = RSN_CIPHER_SUITE_NONE;		memcpy(hapd->wpa_auth->dot11RSNAGroupCipherSelected,		       selector, RSN_SELECTOR_LEN);	} else {		res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data);		selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;		if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X)			selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X;		else if (data.key_mgmt & WPA_KEY_MGMT_PSK)			selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X;		memcpy(hapd->wpa_auth->dot11RSNAAuthenticationSuiteSelected,		       selector, WPA_SELECTOR_LEN);		selector = WPA_CIPHER_SUITE_TKIP;		if (data.pairwise_cipher & WPA_CIPHER_CCMP)			selector = WPA_CIPHER_SUITE_CCMP;		else if (data.pairwise_cipher & WPA_CIPHER_TKIP)			selector = WPA_CIPHER_SUITE_TKIP;		else if (data.pairwise_cipher & WPA_CIPHER_WEP104)			selector = WPA_CIPHER_SUITE_WEP104;		else if (data.pairwise_cipher & WPA_CIPHER_WEP40)			selector = WPA_CIPHER_SUITE_WEP40;		else if (data.pairwise_cipher & WPA_CIPHER_NONE)			selector = WPA_CIPHER_SUITE_NONE;		memcpy(hapd->wpa_auth->dot11RSNAPairwiseCipherSelected,		       selector, WPA_SELECTOR_LEN);		selector = WPA_CIPHER_SUITE_TKIP;		if (data.group_cipher & WPA_CIPHER_CCMP)			selector = WPA_CIPHER_SUITE_CCMP;		else if (data.group_cipher & WPA_CIPHER_TKIP)			selector = WPA_CIPHER_SUITE_TKIP;		else if (data.group_cipher & WPA_CIPHER_WEP104)			selector = WPA_CIPHER_SUITE_WEP104;		else if (data.group_cipher & WPA_CIPHER_WEP40)			selector = WPA_CIPHER_SUITE_WEP40;		else if (data.group_cipher & WPA_CIPHER_NONE)			selector = WPA_CIPHER_SUITE_NONE;		memcpy(hapd->wpa_auth->dot11RSNAGroupCipherSelected,		       selector, WPA_SELECTOR_LEN);	}	if (res) {		printf("Failed to parse WPA/RSN IE from " MACSTR " (res=%d)\n",		       MAC2STR(sta->addr), res);		hostapd_hexdump("WPA/RSN IE", wpa_ie, wpa_ie_len);		return WPA_INVALID_IE;	}	if (data.group_cipher != hapd->conf->wpa_group) {		printf("Invalid WPA group cipher (0x%x) from " MACSTR "\n",		       data.group_cipher, MAC2STR(sta->addr));		return WPA_INVALID_GROUP;	}	key_mgmt = data.key_mgmt & hapd->conf->wpa_key_mgmt;	if (!key_mgmt) {		printf("Invalid WPA key mgmt (0x%x) from " MACSTR "\n",		       data.key_mgmt, MAC2STR(sta->addr));		return WPA_INVALID_AKMP;	}	if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)		sta->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X;	else		sta->wpa_key_mgmt = WPA_KEY_MGMT_PSK;	ciphers = data.pairwise_cipher & hapd->conf->wpa_pairwise;	if (!ciphers) {		printf("Invalid WPA pairwise cipher (0x%x) from " MACSTR "\n",		       data.pairwise_cipher, MAC2STR(sta->addr));		return WPA_INVALID_PAIRWISE;	}	if (ciphers & WPA_CIPHER_CCMP)		sta->pairwise = WPA_CIPHER_CCMP;	else		sta->pairwise = WPA_CIPHER_TKIP;	/* TODO: clear WPA/WPA2 state if STA changes from one to another */	if (wpa_ie[0] == WLAN_EID_RSN)		sta->wpa = WPA_VERSION_WPA2;	else		sta->wpa = WPA_VERSION_WPA;	for (i = 0; i < data.num_pmkid; i++) {		if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MINIMAL)) {			hostapd_hexdump("RSN IE: STA PMKID",					&data.pmkid[i * PMKID_LEN], PMKID_LEN);		}		sta->pmksa = pmksa_cache_get(hapd, sta->addr,					     &data.pmkid[i * PMKID_LEN]);		if (sta->pmksa) {			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,				       HOSTAPD_LEVEL_DEBUG,				       "PMKID found from PMKSA cache");			if (hapd->wpa_auth) {				memcpy(hapd->wpa_auth->dot11RSNAPMKIDUsed,				       sta->pmksa->pmkid, PMKID_LEN);			}			break;		}	}	return WPA_IE_OK;}void wpa_new_station(struct hostapd_data *hapd, struct sta_info *sta){	struct wpa_state_machine *sm;	if (!hapd->conf->wpa)		return;	if (sta->wpa_sm) {		sm = sta->wpa_sm;		memset(sm->key_replay_counter, 0, WPA_REPLAY_COUNTER_LEN);		sm->ReAuthenticationRequest = TRUE;		wpa_sm_step(sm);		return;	}	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,		       HOSTAPD_LEVEL_DEBUG, "start authentication");	sm = malloc(sizeof(struct wpa_state_machine));	if (sm == NULL)		return;	memset(sm, 0, sizeof(struct wpa_state_machine));	sm->hapd = hapd;	sm->sta = sta;	sta->wpa_sm = sm;	sm->Init = TRUE;	wpa_sm_step(sm);	sm->Init = FALSE;	sm->AuthenticationRequest = TRUE;	wpa_sm_step(sm);}void wpa_free_station(struct sta_info *sta){	struct wpa_state_machine *sm = sta->wpa_sm;	if (sm == NULL)		return;	if (sm->hapd->conf->wpa_strict_rekey && sm->has_GTK) {		hostapd_logger(sm->hapd, sta->addr, HOSTAPD_MODULE_WPA,			       HOSTAPD_LEVEL_DEBUG, "strict rekeying - force "			       "GTK rekey since STA is leaving");		eloop_cancel_timeout(wpa_rekey_gtk, sm->hapd, NULL);		eloop_register_timeout(0, 500000, wpa_rekey_gtk, sm->hapd,				       NULL);	}	eloop_cancel_timeout(wpa_send_eapol_timeout, sm->hapd, sta);	eloop_cancel_timeout(wpa_sm_call_step, sm->hapd, sta->wpa_sm);	free(sm->last_rx_eapol_key);	free(sm);	sta->wpa_sm = NULL;}static void wpa_request_new_ptk(struct hostapd_data *hapd,				struct sta_info *sta){	struct wpa_state_machine *sm = sta->wpa_sm;	if (sm == NULL)		return;	sm->PTKRequest = TRUE;	sm->PTK_valid = 0;}void wpa_receive(struct hostapd_data *hapd, struct sta_info *sta,		 u8 *data, size_t data_len){	struct wpa_state_machine *sm = sta->wpa_sm;	struct ieee802_1x_hdr *hdr;	struct wpa_eapol_key *key;	u16 key_info, key_data_length;	enum { PAIRWISE_2, PAIRWISE_4, GROUP_2, REQUEST } msg;	char *msgtxt;	if (!hapd->conf->wpa)		return;	if (sm == NULL)		return;	if (data_len < sizeof(*hdr) + sizeof(*key))		return;	hdr = (struct ieee802_1x_hdr *) data;	key = (struct wpa_eapol_key *) (hdr + 1);	key_info = ntohs(key->key_info);	key_data_length = ntohs(key->key_data_length);	if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {		wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "			   "key_data overflow (%d > %lu)",			   key_data_length,			   (unsigned long) (data_len - sizeof(*hdr) -					    sizeof(*key)));		return;	}	/* FIX: verify that the EAPOL-Key frame was encrypted if pairwise keys	 * are set */	if (key_info & WPA_KEY_INFO_REQUEST) {		msg = REQUEST;		msgtxt = "Request";	} else if (!(key_info & WPA_KEY_INFO_KEY_TYPE)) {		msg = GROUP_2;		msgtxt = "2/2 Group";	} else if (key_data_length == 0) {		msg = PAIRWISE_4;		msgtxt = "4/4 Pairwise";	} else {		msg = PAIRWISE_2;		msgtxt = "2/4 Pairwise";	}	if (key_info & WPA_KEY_INFO_REQUEST) {		if (sta->req_replay_counter_used &&		    memcmp(key->replay_counter, sta->req_replay_counter,			   WPA_REPLAY_COUNTER_LEN) <= 0) {			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,				       HOSTAPD_LEVEL_WARNING,				       "received EAPOL-Key request with "				       "replayed counter");			return;		}	}	if (!(key_info & WPA_KEY_INFO_REQUEST) &&	    (!sm->key_replay_counter_valid ||	     memcmp(key->replay_counter, sm->key_replay_counter,		    WPA_REPLAY_COUNTER_LEN) != 0)) {		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,			       HOSTAPD_LEVEL_INFO,			       "received EAPOL-Key %s with unexpected replay "			       "counter", msgtxt);		if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MINIMAL)) {			hostapd_hexdump("expected replay counter",

⌨️ 快捷键说明

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