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

📄 wpa.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * hostapd - IEEE 802.11i-2004 / WPA Authenticator * Copyright (c) 2004-2006, Jouni Malinen <jkmaline@cc.hut.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#ifndef CONFIG_NATIVE_WINDOWS#include "hostapd.h"#include "eapol_sm.h"#include "wpa.h"#include "sha1.h"#include "md5.h"#include "rc4.h"#include "aes_wrap.h"#include "eloop.h"#include "hostap_common.h"#include "pmksa_cache.h"#include "state_machine.h"#define STATE_MACHINE_DATA struct wpa_state_machine#define STATE_MACHINE_DEBUG_PREFIX "WPA"#define STATE_MACHINE_ADDR sm->addrstruct wpa_stakey_negotiation {	struct wpa_stakey_negotiation *next;	u8 initiator[ETH_ALEN];	u8 peer[ETH_ALEN];	enum { PEER, INITIATOR } state;	unsigned int num_retries;	u8 key[32];	size_t key_len;	int alg;};struct wpa_state_machine {	struct wpa_authenticator *wpa_auth;	u8 addr[ETH_ALEN];	enum {		WPA_PTK_INITIALIZE, WPA_PTK_DISCONNECT, WPA_PTK_DISCONNECTED,		WPA_PTK_AUTHENTICATION, WPA_PTK_AUTHENTICATION2,		WPA_PTK_INITPMK, WPA_PTK_INITPSK, WPA_PTK_PTKSTART,		WPA_PTK_PTKCALCNEGOTIATING, WPA_PTK_PTKCALCNEGOTIATING2,		WPA_PTK_PTKINITNEGOTIATING, WPA_PTK_PTKINITDONE	} wpa_ptk_state;	enum {		WPA_PTK_GROUP_IDLE = 0,		WPA_PTK_GROUP_REKEYNEGOTIATING,		WPA_PTK_GROUP_REKEYESTABLISHED,		WPA_PTK_GROUP_KEYERROR	} wpa_ptk_group_state;	Boolean Init;	Boolean DeauthenticationRequest;	Boolean AuthenticationRequest;	Boolean ReAuthenticationRequest;	Boolean Disconnect;	int TimeoutCtr;	int GTimeoutCtr;	Boolean TimeoutEvt;	Boolean EAPOLKeyReceived;	Boolean EAPOLKeyPairwise;	Boolean EAPOLKeyRequest;	Boolean MICVerified;	Boolean GUpdateStationKeys;	u8 ANonce[WPA_NONCE_LEN];	u8 SNonce[WPA_NONCE_LEN];	u8 PMK[WPA_PMK_LEN];	struct wpa_ptk PTK;	Boolean PTK_valid;	Boolean pairwise_set;	int keycount;	Boolean Pair;	u8 key_replay_counter[WPA_REPLAY_COUNTER_LEN];	Boolean key_replay_counter_valid;	Boolean PInitAKeys; /* WPA only, not in IEEE 802.11i */	Boolean PTKRequest; /* not in IEEE 802.11i state machine */	Boolean has_GTK;	u8 *last_rx_eapol_key; /* starting from IEEE 802.1X header */	size_t last_rx_eapol_key_len;	unsigned int changed:1;	unsigned int in_step_loop:1;	unsigned int pending_deinit:1;	unsigned int started:1;	u8 req_replay_counter[WPA_REPLAY_COUNTER_LEN];	int req_replay_counter_used;	u8 *wpa_ie;	size_t wpa_ie_len;	enum {		WPA_VERSION_NO_WPA = 0 /* WPA not used */,		WPA_VERSION_WPA = 1 /* WPA / IEEE 802.11i/D3.0 */,		WPA_VERSION_WPA2 = 2 /* WPA2 / IEEE 802.11i */	} wpa;	int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */	int wpa_key_mgmt; /* the selected WPA_KEY_MGMT_* */	struct rsn_pmksa_cache_entry *pmksa;	u32 dot11RSNAStatsTKIPLocalMICFailures;	u32 dot11RSNAStatsTKIPRemoteMICFailures;};/* per authenticator data */struct wpa_authenticator {	Boolean GInit;	int GNoStations;	int GKeyDoneStations;	Boolean GTKReKey;	int GTK_len;	int GN, GM;	Boolean GTKAuthenticator;	u8 Counter[WPA_NONCE_LEN];	enum {		WPA_GROUP_GTK_INIT = 0,		WPA_GROUP_SETKEYS, WPA_GROUP_SETKEYSDONE	} wpa_group_state;	u8 GMK[WPA_GMK_LEN];	u8 GTK[2][WPA_GTK_MAX_LEN];	u8 GNonce[WPA_NONCE_LEN];	Boolean changed;	unsigned int dot11RSNAStatsTKIPRemoteMICFailures;	u8 dot11RSNAAuthenticationSuiteSelected[4];	u8 dot11RSNAPairwiseCipherSelected[4];	u8 dot11RSNAGroupCipherSelected[4];	u8 dot11RSNAPMKIDUsed[PMKID_LEN];	u8 dot11RSNAAuthenticationSuiteRequested[4]; /* FIX: update */	u8 dot11RSNAPairwiseCipherRequested[4]; /* FIX: update */	u8 dot11RSNAGroupCipherRequested[4]; /* FIX: update */	unsigned int dot11RSNATKIPCounterMeasuresInvoked;	unsigned int dot11RSNA4WayHandshakeFailures;	struct wpa_stakey_negotiation *stakey_negotiations;	struct wpa_auth_config conf;	struct wpa_auth_callbacks cb;	u8 *wpa_ie;	size_t wpa_ie_len;	u8 addr[ETH_ALEN];	struct rsn_pmksa_cache *pmksa;};static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx);static void wpa_sm_step(struct wpa_state_machine *sm);static int wpa_verify_key_mic(struct wpa_ptk *PTK, u8 *data, size_t data_len);static void wpa_sm_call_step(void *eloop_ctx, void *timeout_ctx);static void wpa_group_sm_step(struct wpa_authenticator *wpa_auth);static int wpa_stakey_remove(struct wpa_authenticator *wpa_auth,			     struct wpa_stakey_negotiation *neg);static void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,			     struct wpa_state_machine *sm,			     int secure, int mic, int ack, int install,			     int pairwise, u8 *key_rsc, u8 *nonce,			     u8 *ie, size_t ie_len, u8 *gtk, size_t gtk_len,			     int keyidx, int encr, int force_version);/* Default timeouts are 100 ms, but this seems to be a bit too fast for most * WPA Supplicants, so use a bit longer timeout. */static const u32 dot11RSNAConfigGroupUpdateTimeOut = 1000; /* ms */static const u32 dot11RSNAConfigGroupUpdateCount = 3;static const u32 dot11RSNAConfigPairwiseUpdateTimeOut = 1000; /* ms */static const u32 dot11RSNAConfigPairwiseUpdateCount = 3;/* TODO: make these configurable */static const int dot11RSNAConfigPMKLifetime = 43200;static const int dot11RSNAConfigPMKReauthThreshold = 70;static const int dot11RSNAConfigSATimeout = 60;static const int WPA_SELECTOR_LEN = 4;static const u8 WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };static const u16 WPA_VERSION = 1;static const u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 };static const u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 };static const u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 };static const u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 };static const u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 };static const u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 };static const u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };static const u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };static const int RSN_SELECTOR_LEN = 4;static const u16 RSN_VERSION = 1;static const u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };static const u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };static const u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };static const u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };static const u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };static const u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 };static const u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };static const u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };/* EAPOL-Key Key Data Encapsulation * GroupKey and STAKey require encryption, otherwise, encryption is optional. */static const u8 RSN_KEY_DATA_GROUPKEY[] = { 0x00, 0x0f, 0xac, 1 };static const u8 RSN_KEY_DATA_STAKEY[] = { 0x00, 0x0f, 0xac, 2 };static const u8 RSN_KEY_DATA_MAC_ADDR[] = { 0x00, 0x0f, 0xac, 3 };static const u8 RSN_KEY_DATA_PMKID[] = { 0x00, 0x0f, 0xac, 4 };#define GENERIC_INFO_ELEM 0xdd#define RSN_INFO_ELEM 0x30#ifdef _MSC_VER#pragma pack(push, 1)#endif /* _MSC_VER *//* WPA IE version 1 * 00-50-f2:1 (OUI:OUI type) * 0x01 0x00 (version; little endian) * (all following fields are optional:) * Group Suite Selector (4 octets) (default: TKIP) * Pairwise Suite Count (2 octets, little endian) (default: 1) * Pairwise Suite List (4 * n octets) (default: TKIP) * Authenticated Key Management Suite Count (2 octets, little endian) *    (default: 1) * Authenticated Key Management Suite List (4 * n octets) *    (default: unspec 802.1X) * WPA Capabilities (2 octets, little endian) (default: 0) */struct wpa_ie_hdr {	u8 elem_id;	u8 len;	u8 oui[3];	u8 oui_type;	u16 version;} STRUCT_PACKED;/* RSN IE version 1 * 0x01 0x00 (version; little endian) * (all following fields are optional:) * Group Suite Selector (4 octets) (default: CCMP) * Pairwise Suite Count (2 octets, little endian) (default: 1) * Pairwise Suite List (4 * n octets) (default: CCMP) * Authenticated Key Management Suite Count (2 octets, little endian) *    (default: 1) * Authenticated Key Management Suite List (4 * n octets) *    (default: unspec 802.1X) * RSN Capabilities (2 octets, little endian) (default: 0) * PMKID Count (2 octets) (default: 0) * PMKID List (16 * n octets) */struct rsn_ie_hdr {	u8 elem_id; /* WLAN_EID_RSN */	u8 len;	u16 version;} STRUCT_PACKED;struct rsn_stakey_kde {	u8 id;	u8 len;	u8 oui[3];	u8 oui_type;	u8 reserved[2];	u8 mac_addr[ETH_ALEN];	u8 stakey[32]; /* up to 32 bytes */} STRUCT_PACKED;#ifdef _MSC_VER#pragma pack(pop)#endif /* _MSC_VER */static inline void wpa_auth_mic_failure_report(	struct wpa_authenticator *wpa_auth, const u8 *addr){	if (wpa_auth->cb.mic_failure_report)		wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);}static inline void wpa_auth_set_eapol(struct wpa_authenticator *wpa_auth,				      const u8 *addr, wpa_eapol_variable var,				      int value){	if (wpa_auth->cb.set_eapol)		wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value);}static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,				     const u8 *addr, wpa_eapol_variable var){	if (wpa_auth->cb.get_eapol == NULL)		return -1;	return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var);}static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,					  const u8 *addr, const u8 *prev_psk){	if (wpa_auth->cb.get_psk == NULL)		return NULL;	return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, prev_psk);}static inline int wpa_auth_get_pmk(struct wpa_authenticator *wpa_auth,				   const u8 *addr, u8 *pmk, size_t *len){	if (wpa_auth->cb.get_pmk == NULL)		return -1;	return wpa_auth->cb.get_pmk(wpa_auth->cb.ctx, addr, pmk, len);}static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,				   const char *alg, const u8 *addr, int idx,				   u8 *key, size_t key_len){	if (wpa_auth->cb.set_key == NULL)		return -1;	return wpa_auth->cb.set_key(wpa_auth->cb.ctx, alg, addr, idx, key,				    key_len);}static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,				      const u8 *addr, int idx, u8 *seq){	if (wpa_auth->cb.get_seqnum == NULL)		return -1;	return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);}static inline intwpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,		    const u8 *data, size_t data_len, int encrypt){	if (wpa_auth->cb.send_eapol == NULL)		return -1;	return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len,				       encrypt);}static inline int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,					int (*cb)(struct wpa_state_machine *sm,						  void *ctx),					void *cb_ctx){	if (wpa_auth->cb.for_each_sta == NULL)		return 0;	return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx);}static void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,			    logger_level level, const char *txt){	if (wpa_auth->cb.logger == NULL)		return;	wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt);}static void wpa_auth_vlogger(struct wpa_authenticator *wpa_auth,			     const u8 *addr, logger_level level,			     const char *fmt, ...){	char *format;	int maxlen;	va_list ap;	if (wpa_auth->cb.logger == NULL)		return;	maxlen = strlen(fmt) + 100;	format = malloc(maxlen);	if (!format)		return;	va_start(ap, fmt);	vsnprintf(format, maxlen, fmt, ap);	va_end(ap);	wpa_auth_logger(wpa_auth, addr, level, format);	free(format);}static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len){	struct wpa_ie_hdr *hdr;	int num_suites;	u8 *pos, *count;	hdr = (struct wpa_ie_hdr *) buf;	hdr->elem_id = WLAN_EID_GENERIC;	memcpy(&hdr->oui, WPA_OUI_TYPE, WPA_SELECTOR_LEN);	hdr->version = host_to_le16(WPA_VERSION);	pos = (u8 *) (hdr + 1);	if (conf->wpa_group == WPA_CIPHER_CCMP) {		memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);	} else if (conf->wpa_group == WPA_CIPHER_TKIP) {		memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);	} else if (conf->wpa_group == WPA_CIPHER_WEP104) {		memcpy(pos, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN);	} else if (conf->wpa_group == WPA_CIPHER_WEP40) {		memcpy(pos, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN);	} else {		wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",			   conf->wpa_group);		return -1;	}	pos += WPA_SELECTOR_LEN;	num_suites = 0;	count = pos;	pos += 2;	if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {		memcpy(pos, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN);		pos += WPA_SELECTOR_LEN;		num_suites++;	}	if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {		memcpy(pos, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN);		pos += WPA_SELECTOR_LEN;		num_suites++;	}	if (conf->wpa_pairwise & WPA_CIPHER_NONE) {		memcpy(pos, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN);		pos += WPA_SELECTOR_LEN;		num_suites++;	}	if (num_suites == 0) {		wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",			   conf->wpa_pairwise);		return -1;	}	*count++ = num_suites & 0xff;	*count = (num_suites >> 8) & 0xff;	num_suites = 0;	count = pos;	pos += 2;	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {		memcpy(pos, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN);		pos += WPA_SELECTOR_LEN;		num_suites++;	}	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {		memcpy(pos, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X,		       WPA_SELECTOR_LEN);		pos += WPA_SELECTOR_LEN;		num_suites++;	}	if (num_suites == 0) {		wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",			   conf->wpa_key_mgmt);		return -1;	}	*count++ = num_suites & 0xff;	*count = (num_suites >> 8) & 0xff;

⌨️ 快捷键说明

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