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

📄 wpa.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 5 页
字号:
				wpa_printf(MSG_DEBUG, "RSN: Cancelled PMKSA "					   "caching attempt");				sm->cur_pmksa = NULL;				abort_cached = 1;			} else {				return -1;			}		}	}	if (abort_cached && sm->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {		/* Send EAPOL-Start to trigger full EAP authentication. */		u8 *buf;		size_t buflen;		wpa_printf(MSG_DEBUG, "RSN: no PMKSA entry found - trigger "			   "full EAP authentication");		buf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_START,					 NULL, 0, &buflen, NULL);		if (buf) {			wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,					  buf, buflen);			os_free(buf);		}		return -1;	}	return 0;}static int wpa_supplicant_send_2_of_4(struct wpa_sm *sm,				      const unsigned char *dst,				      const struct wpa_eapol_key *key,				      int ver, const u8 *nonce,				      const u8 *wpa_ie, size_t wpa_ie_len,				      struct wpa_ptk *ptk){	size_t rlen;	struct wpa_eapol_key *reply;	u8 *rbuf;	if (wpa_ie == NULL) {		wpa_printf(MSG_WARNING, "WPA: No wpa_ie set - cannot "			   "generate msg 2/4");		return -1;	}	wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);	rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,				  NULL, sizeof(*reply) + wpa_ie_len,				  &rlen, (void *) &reply);	if (rbuf == NULL)		return -1;	reply->type = sm->proto == WPA_PROTO_RSN ?		EAPOL_KEY_TYPE_RSN : EAPOL_KEY_TYPE_WPA;	WPA_PUT_BE16(reply->key_info,		     ver | WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC);	if (sm->proto == WPA_PROTO_RSN)		WPA_PUT_BE16(reply->key_length, 0);	else		os_memcpy(reply->key_length, key->key_length, 2);	os_memcpy(reply->replay_counter, key->replay_counter,		  WPA_REPLAY_COUNTER_LEN);	WPA_PUT_BE16(reply->key_data_length, wpa_ie_len);	os_memcpy(reply + 1, wpa_ie, wpa_ie_len);	os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);	wpa_printf(MSG_DEBUG, "WPA: Sending EAPOL-Key 2/4");	wpa_eapol_key_send(sm, ptk->kck, ver, dst, ETH_P_EAPOL,			   rbuf, rlen, reply->key_mic);	return 0;}static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,					  const unsigned char *src_addr,					  const struct wpa_eapol_key *key,					  u16 ver){	struct wpa_eapol_ie_parse ie;	struct wpa_ptk *ptk;	u8 buf[8];	if (wpa_sm_get_ssid(sm) == NULL) {		wpa_printf(MSG_WARNING, "WPA: No SSID info found (msg 1 of "			   "4).");		return;	}	wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);	wpa_printf(MSG_DEBUG, "WPA: RX message 1 of 4-Way Handshake from "		   MACSTR " (ver=%d)", MAC2STR(src_addr), ver);	os_memset(&ie, 0, sizeof(ie));#ifndef CONFIG_NO_WPA2	if (sm->proto == WPA_PROTO_RSN) {		/* RSN: msg 1/4 should contain PMKID for the selected PMK */		const u8 *_buf = (const u8 *) (key + 1);		size_t len = WPA_GET_BE16(key->key_data_length);		wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data", _buf, len);		wpa_supplicant_parse_ies(_buf, len, &ie);		if (ie.pmkid) {			wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "				    "Authenticator", ie.pmkid, PMKID_LEN);		}	}#endif /* CONFIG_NO_WPA2 */	if (wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid))		return;	if (sm->renew_snonce) {		if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) {			wpa_msg(sm->ctx->ctx, MSG_WARNING,				"WPA: Failed to get random data for SNonce");			return;		}		sm->renew_snonce = 0;		wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",			    sm->snonce, WPA_NONCE_LEN);	}	/* Calculate PTK which will be stored as a temporary PTK until it has	 * been verified when processing message 3/4. */	ptk = &sm->tptk;	wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",		       sm->own_addr, sm->bssid, sm->snonce, key->key_nonce,		       (u8 *) ptk, sizeof(*ptk));	/* Supplicant: swap tx/rx Mic keys */	os_memcpy(buf, ptk->u.auth.tx_mic_key, 8);	os_memcpy(ptk->u.auth.tx_mic_key, ptk->u.auth.rx_mic_key, 8);	os_memcpy(ptk->u.auth.rx_mic_key, buf, 8);	sm->tptk_set = 1;	if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,				       sm->assoc_wpa_ie, sm->assoc_wpa_ie_len,				       ptk))		return;	os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);}static void wpa_sm_start_preauth(void *eloop_ctx, void *timeout_ctx){	struct wpa_sm *sm = eloop_ctx;	rsn_preauth_candidate_process(sm);}static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,					    const u8 *addr, int secure){	wpa_msg(sm->ctx->ctx, MSG_INFO, "WPA: Key negotiation completed with "		MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),		wpa_cipher_txt(sm->pairwise_cipher),		wpa_cipher_txt(sm->group_cipher));	eloop_cancel_timeout(sm->ctx->scan, sm->ctx->ctx, NULL);	wpa_sm_cancel_auth_timeout(sm);	wpa_sm_set_state(sm, WPA_COMPLETED);	if (secure) {		wpa_sm_mlme_setprotection(			sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX,			MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);		eapol_sm_notify_portValid(sm->eapol, TRUE);		if (sm->key_mgmt == WPA_KEY_MGMT_PSK)			eapol_sm_notify_eap_success(sm->eapol, TRUE);		/*		 * Start preauthentication after a short wait to avoid a		 * possible race condition between the data receive and key		 * configuration after the 4-Way Handshake. This increases the		 * likelyhood of the first preauth EAPOL-Start frame getting to		 * the target AP.		 */		eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL);	}	if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) {		wpa_printf(MSG_DEBUG, "RSN: Authenticator accepted "			   "opportunistic PMKSA entry - marking it valid");		sm->cur_pmksa->opportunistic = 0;	}}static int wpa_supplicant_install_ptk(struct wpa_sm *sm,				      const struct wpa_eapol_key *key){	int keylen, rsclen;	wpa_alg alg;	const u8 *key_rsc;	u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };	wpa_printf(MSG_DEBUG, "WPA: Installing PTK to the driver.");	switch (sm->pairwise_cipher) {	case WPA_CIPHER_CCMP:		alg = WPA_ALG_CCMP;		keylen = 16;		rsclen = 6;		break;	case WPA_CIPHER_TKIP:		alg = WPA_ALG_TKIP;		keylen = 32;		rsclen = 6;		break;	case WPA_CIPHER_NONE:		wpa_printf(MSG_DEBUG, "WPA: Pairwise Cipher Suite: "			   "NONE - do not use pairwise keys");		return 0;	default:		wpa_printf(MSG_WARNING, "WPA: Unsupported pairwise cipher %d",			   sm->pairwise_cipher);		return -1;	}	if (sm->proto == WPA_PROTO_RSN) {		key_rsc = null_rsc;	} else {		key_rsc = key->key_rsc;		wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, rsclen);	}	if (wpa_sm_set_key(sm, alg, sm->bssid, 0, 1, key_rsc, rsclen,			   (u8 *) sm->ptk.tk1, keylen) < 0) {		wpa_printf(MSG_WARNING, "WPA: Failed to set PTK to the "			   "driver.");		return -1;	}	return 0;}static int wpa_supplicant_check_group_cipher(int group_cipher,					     int keylen, int maxkeylen,					     int *key_rsc_len, wpa_alg *alg){	int ret = 0;	switch (group_cipher) {	case WPA_CIPHER_CCMP:		if (keylen != 16 || maxkeylen < 16) {			ret = -1;			break;		}		*key_rsc_len = 6;		*alg = WPA_ALG_CCMP;		break;	case WPA_CIPHER_TKIP:		if (keylen != 32 || maxkeylen < 32) {			ret = -1;			break;		}		*key_rsc_len = 6;		*alg = WPA_ALG_TKIP;		break;	case WPA_CIPHER_WEP104:		if (keylen != 13 || maxkeylen < 13) {			ret = -1;			break;		}		*key_rsc_len = 0;		*alg = WPA_ALG_WEP;		break;	case WPA_CIPHER_WEP40:		if (keylen != 5 || maxkeylen < 5) {			ret = -1;			break;		}		*key_rsc_len = 0;		*alg = WPA_ALG_WEP;		break;	default:		wpa_printf(MSG_WARNING, "WPA: Unsupported Group Cipher %d",			   group_cipher);		return -1;	}	if (ret < 0 ) {		wpa_printf(MSG_WARNING, "WPA: Unsupported %s Group Cipher key "			   "length %d (%d).",			   wpa_cipher_txt(group_cipher), keylen, maxkeylen);	}	return ret;}struct wpa_gtk_data {	wpa_alg alg;	int tx, key_rsc_len, keyidx;	u8 gtk[32];	int gtk_len;};static int wpa_supplicant_install_gtk(struct wpa_sm *sm,				      const struct wpa_gtk_data *gd,				      const u8 *key_rsc){	const u8 *_gtk = gd->gtk;	u8 gtk_buf[32];	wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len);	wpa_printf(MSG_DEBUG, "WPA: Installing GTK to the driver "		   "(keyidx=%d tx=%d).", gd->keyidx, gd->tx);	wpa_hexdump(MSG_DEBUG, "WPA: RSC", key_rsc, gd->key_rsc_len);	if (sm->group_cipher == WPA_CIPHER_TKIP) {		/* Swap Tx/Rx keys for Michael MIC */		os_memcpy(gtk_buf, gd->gtk, 16);		os_memcpy(gtk_buf + 16, gd->gtk + 24, 8);		os_memcpy(gtk_buf + 24, gd->gtk + 16, 8);		_gtk = gtk_buf;	}	if (sm->pairwise_cipher == WPA_CIPHER_NONE) {		if (wpa_sm_set_key(sm, gd->alg,				   (u8 *) "\xff\xff\xff\xff\xff\xff",				   gd->keyidx, 1, key_rsc, gd->key_rsc_len,				   _gtk, gd->gtk_len) < 0) {			wpa_printf(MSG_WARNING, "WPA: Failed to set "				   "GTK to the driver (Group only).");			return -1;		}	} else if (wpa_sm_set_key(sm, gd->alg,				  (u8 *) "\xff\xff\xff\xff\xff\xff",				  gd->keyidx, gd->tx, key_rsc, gd->key_rsc_len,				  _gtk, gd->gtk_len) < 0) {		wpa_printf(MSG_WARNING, "WPA: Failed to set GTK to "			   "the driver.");		return -1;	}	return 0;}static int wpa_supplicant_gtk_tx_bit_workaround(const struct wpa_sm *sm,						int tx){	if (tx && sm->pairwise_cipher != WPA_CIPHER_NONE) {		/* Ignore Tx bit for GTK if a pairwise key is used. One AP		 * seemed to set this bit (incorrectly, since Tx is only when		 * doing Group Key only APs) and without this workaround, the		 * data connection does not work because wpa_supplicant		 * configured non-zero keyidx to be used for unicast. */		wpa_printf(MSG_INFO, "WPA: Tx bit set for GTK, but pairwise "			   "keys are used - ignore Tx bit");		return 0;	}	return tx;}static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm,				       const struct wpa_eapol_key *key,				       const u8 *gtk, size_t gtk_len,				       int key_info){#ifndef CONFIG_NO_WPA2	struct wpa_gtk_data gd;	/*	 * IEEE Std 802.11i-2004 - 8.5.2 EAPOL-Key frames - Figure 43x	 * GTK KDE format:	 * KeyID[bits 0-1], Tx [bit 2], Reserved [bits 3-7]	 * Reserved [bits 0-7]	 * GTK	 */	os_memset(&gd, 0, sizeof(gd));	wpa_hexdump_key(MSG_DEBUG, "RSN: received GTK in pairwise handshake",			gtk, gtk_len);	if (gtk_len < 2 || gtk_len - 2 > sizeof(gd.gtk))		return -1;	gd.keyidx = gtk[0] & 0x3;	gd.tx = wpa_supplicant_gtk_tx_bit_workaround(sm,						     !!(gtk[0] & BIT(2)));	gtk += 2;	gtk_len -= 2;	os_memcpy(gd.gtk, gtk, gtk_len);	gd.gtk_len = gtk_len;	if (wpa_supplicant_check_group_cipher(sm->group_cipher,					      gtk_len, gtk_len,					      &gd.key_rsc_len, &gd.alg) ||	    wpa_supplicant_install_gtk(sm, &gd, key->key_rsc)) {		wpa_printf(MSG_DEBUG, "RSN: Failed to install GTK");		return -1;	}	wpa_supplicant_key_neg_complete(sm, sm->bssid,					key_info & WPA_KEY_INFO_SECURE);	return 0;#else /* CONFIG_NO_WPA2 */	return -1;#endif /* CONFIG_NO_WPA2 */}static int ieee80211w_set_keys(struct wpa_sm *sm,			       struct wpa_eapol_ie_parse *ie){#ifdef CONFIG_IEEE80211W	if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)		return 0;	if (ie->igtk) {		const struct wpa_igtk_kde *igtk;		u16 keyidx;		if (ie->igtk_len != sizeof(*igtk))			return -1;		igtk = (const struct wpa_igtk_kde *) ie->igtk;		keyidx = WPA_GET_LE16(igtk->keyid);		wpa_printf(MSG_DEBUG, "WPA: IGTK keyid %d "			   "pn %02x%02x%02x%02x%02x%02x",			   keyidx, MAC2STR(igtk->pn));		wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK",				igtk->igtk, WPA_IGTK_LEN);		if (keyidx > 4095) {			wpa_printf(MSG_WARNING, "WPA: Invalid IGTK KeyID %d",				   keyidx);			return -1;		}		if (wpa_sm_set_key(sm, WPA_ALG_IGTK,				   (u8 *) "\xff\xff\xff\xff\xff\xff",				   keyidx, 0, igtk->pn, sizeof(igtk->pn),				   igtk->igtk, WPA_IGTK_LEN) < 0) {			wpa_printf(MSG_WARNING, "WPA: Failed to configure IGTK"				   " to the driver");			return -1;		}	}	if (ie->dhv) {		const struct wpa_dhv_kde *dhv;		if (ie->dhv_len != sizeof(*dhv))			return -1;		dhv = (const struct wpa_dhv_kde *) ie->dhv;		wpa_hexdump_key(MSG_DEBUG, "WPA: DHV", dhv->dhv, WPA_DHV_LEN);		if (wpa_sm_set_key(sm, WPA_ALG_DHV,				   (u8 *) "\xff\xff\xff\xff\xff\xff", 0, 0,				   NULL, 0, dhv->dhv, WPA_DHV_LEN) < 0) {			wpa_printf(MSG_WARNING, "WPA: Failed to configure DHV "				   "to the driver");			return -1;		}	}	return 0;#else /* CONFIG_IEEE80211W */	return 0;#endif /* CONFIG_IEEE80211W */}static void wpa_report_ie_mismatch(struct wpa_sm *sm,

⌨️ 快捷键说明

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