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

📄 wpa.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * hostapd - IEEE 802.11i-2004 / WPA Authenticator * Copyright (c) 2004-2008, Jouni Malinen <j@w1.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 "common.h"#include "config.h"#include "eapol_sm.h"#include "wpa.h"#include "sha1.h"#include "sha256.h"#include "rc4.h"#include "aes_wrap.h"#include "crypto.h"#include "eloop.h"#include "ieee802_11.h"#include "pmksa_cache.h"#include "state_machine.h"#include "wpa_auth_i.h"#include "wpa_auth_ie.h"#define STATE_MACHINE_DATA struct wpa_state_machine#define STATE_MACHINE_DEBUG_PREFIX "WPA"#define STATE_MACHINE_ADDR sm->addrstatic 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,			      struct wpa_group *group);static void wpa_request_new_ptk(struct wpa_state_machine *sm);static const u32 dot11RSNAConfigGroupUpdateCount = 4;static const u32 dot11RSNAConfigPairwiseUpdateCount = 4;static const u32 eapol_key_timeout_first = 100; /* ms */static const u32 eapol_key_timeout_subseq = 1000; /* ms *//* TODO: make these configurable */static const int dot11RSNAConfigPMKLifetime = 43200;static const int dot11RSNAConfigPMKReauthThreshold = 70;static const int dot11RSNAConfigSATimeout = 60;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_msk(struct wpa_authenticator *wpa_auth,				   const u8 *addr, u8 *msk, size_t *len){	if (wpa_auth->cb.get_msk == NULL)		return -1;	return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len);}static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,				   int vlan_id,				   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, vlan_id, 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 int wpa_auth_get_seqnum_igtk(struct wpa_authenticator *wpa_auth,					   const u8 *addr, int idx, u8 *seq){	if (wpa_auth->cb.get_seqnum_igtk == NULL)		return -1;	return wpa_auth->cb.get_seqnum_igtk(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);}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);}int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,			   int (*cb)(struct wpa_authenticator *a, void *ctx),			   void *cb_ctx){	if (wpa_auth->cb.for_each_auth == NULL)		return 0;	return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx);}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);}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 = os_strlen(fmt) + 100;	format = os_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);	os_free(format);}static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,			       const u8 *addr){	if (wpa_auth->cb.disconnect == NULL)		return;	wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr,				WLAN_REASON_PREV_AUTH_NOT_VALID);}static int wpa_use_aes_cmac(struct wpa_state_machine *sm){	int ret = 0;#ifdef CONFIG_IEEE80211R	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt))		ret = 1;#endif /* CONFIG_IEEE80211R */#ifdef CONFIG_IEEE80211W	if (wpa_key_mgmt_sha256(sm->wpa_key_mgmt))		ret = 1;#endif /* CONFIG_IEEE80211W */	return ret;}static void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx){	struct wpa_authenticator *wpa_auth = eloop_ctx;	if (os_get_random(wpa_auth->group->GMK, WPA_GMK_LEN)) {		wpa_printf(MSG_ERROR, "Failed to get random data for WPA "			   "initialization.");	} else {		wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "GMK rekeyd");	}	if (wpa_auth->conf.wpa_gmk_rekey) {		eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0,				       wpa_rekey_gmk, wpa_auth, NULL);	}}static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx){	struct wpa_authenticator *wpa_auth = eloop_ctx;	struct wpa_group *group;	wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK");	for (group = wpa_auth->group; group; group = group->next) {		group->GTKReKey = TRUE;		do {			group->changed = FALSE;			wpa_group_sm_step(wpa_auth, group);		} while (group->changed);	}	if (wpa_auth->conf.wpa_group_rekey) {		eloop_register_timeout(wpa_auth->conf.wpa_group_rekey,				       0, wpa_rekey_gtk, wpa_auth, NULL);	}}static void wpa_rekey_ptk(void *eloop_ctx, void *timeout_ctx){	struct wpa_authenticator *wpa_auth = eloop_ctx;	struct wpa_state_machine *sm = timeout_ctx;	wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "rekeying PTK");	wpa_request_new_ptk(sm);	wpa_sm_step(sm);}static int wpa_auth_pmksa_clear_cb(struct wpa_state_machine *sm, void *ctx){	if (sm->pmksa == ctx)		sm->pmksa = NULL;	return 0;}static void wpa_auth_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,				   void *ctx){	struct wpa_authenticator *wpa_auth = ctx;	wpa_auth_for_each_sta(wpa_auth, wpa_auth_pmksa_clear_cb, entry);}static struct wpa_group * wpa_group_init(struct wpa_authenticator *wpa_auth,					 int vlan_id){	struct wpa_group *group;	u8 buf[ETH_ALEN + 8 + sizeof(group)];	u8 rkey[32];	group = os_zalloc(sizeof(struct wpa_group));	if (group == NULL)		return NULL;	group->GTKAuthenticator = TRUE;	group->vlan_id = vlan_id;	switch (wpa_auth->conf.wpa_group) {	case WPA_CIPHER_CCMP:		group->GTK_len = 16;		break;	case WPA_CIPHER_TKIP:		group->GTK_len = 32;		break;	case WPA_CIPHER_WEP104:		group->GTK_len = 13;		break;	case WPA_CIPHER_WEP40:		group->GTK_len = 5;		break;	}	/* Counter = PRF-256(Random number, "Init Counter",	 *                   Local MAC Address || Time)	 */	os_memcpy(buf, wpa_auth->addr, ETH_ALEN);	wpa_get_ntp_timestamp(buf + ETH_ALEN);	os_memcpy(buf + ETH_ALEN + 8, &group, sizeof(group));	if (os_get_random(rkey, sizeof(rkey)) ||	    os_get_random(group->GMK, WPA_GMK_LEN)) {		wpa_printf(MSG_ERROR, "Failed to get random data for WPA "			   "initialization.");		os_free(group);		return NULL;	}	sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf),		 group->Counter, WPA_NONCE_LEN);	group->GInit = TRUE;	wpa_group_sm_step(wpa_auth, group);	group->GInit = FALSE;	wpa_group_sm_step(wpa_auth, group);	return group;}/** * wpa_init - Initialize WPA authenticator * @addr: Authenticator address * @conf: Configuration for WPA authenticator * @cb: Callback functions for WPA authenticator * Returns: Pointer to WPA authenticator data or %NULL on failure */struct wpa_authenticator * wpa_init(const u8 *addr,				    struct wpa_auth_config *conf,				    struct wpa_auth_callbacks *cb){	struct wpa_authenticator *wpa_auth;	wpa_auth = os_zalloc(sizeof(struct wpa_authenticator));	if (wpa_auth == NULL)		return NULL;	os_memcpy(wpa_auth->addr, addr, ETH_ALEN);	os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));	os_memcpy(&wpa_auth->cb, cb, sizeof(*cb));	if (wpa_auth_gen_wpa_ie(wpa_auth)) {		wpa_printf(MSG_ERROR, "Could not generate WPA IE.");		os_free(wpa_auth);		return NULL;	}	wpa_auth->group = wpa_group_init(wpa_auth, 0);	if (wpa_auth->group == NULL) {		os_free(wpa_auth->wpa_ie);		os_free(wpa_auth);		return NULL;	}	wpa_auth->pmksa = pmksa_cache_init(wpa_auth_pmksa_free_cb, wpa_auth);	if (wpa_auth->pmksa == NULL) {		wpa_printf(MSG_ERROR, "PMKSA cache initialization failed.");		os_free(wpa_auth->wpa_ie);		os_free(wpa_auth);		return NULL;	}#ifdef CONFIG_IEEE80211R	wpa_auth->ft_pmk_cache = wpa_ft_pmk_cache_init();	if (wpa_auth->ft_pmk_cache == NULL) {		wpa_printf(MSG_ERROR, "FT PMK cache initialization failed.");		os_free(wpa_auth->wpa_ie);		pmksa_cache_deinit(wpa_auth->pmksa);		os_free(wpa_auth);		return NULL;	}#endif /* CONFIG_IEEE80211R */	if (wpa_auth->conf.wpa_gmk_rekey) {		eloop_register_timeout(wpa_auth->conf.wpa_gmk_rekey, 0,				       wpa_rekey_gmk, wpa_auth, NULL);	}	if (wpa_auth->conf.wpa_group_rekey) {		eloop_register_timeout(wpa_auth->conf.wpa_group_rekey, 0,				       wpa_rekey_gtk, wpa_auth, NULL);	}	return wpa_auth;}/** * wpa_deinit - Deinitialize WPA authenticator * @wpa_auth: Pointer to WPA authenticator data from wpa_init() */void wpa_deinit(struct wpa_authenticator *wpa_auth){	struct wpa_group *group, *prev;	eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL);	eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);#ifdef CONFIG_PEERKEY	while (wpa_auth->stsl_negotiations)		wpa_stsl_remove(wpa_auth, wpa_auth->stsl_negotiations);#endif /* CONFIG_PEERKEY */	pmksa_cache_deinit(wpa_auth->pmksa);#ifdef CONFIG_IEEE80211R	wpa_ft_pmk_cache_deinit(wpa_auth->ft_pmk_cache);	wpa_auth->ft_pmk_cache = NULL;#endif /* CONFIG_IEEE80211R */	os_free(wpa_auth->wpa_ie);	group = wpa_auth->group;	while (group) {		prev = group;		group = group->next;		os_free(prev);	}	os_free(wpa_auth);}/** * wpa_reconfig - Update WPA authenticator configuration * @wpa_auth: Pointer to WPA authenticator data from wpa_init() * @conf: Configuration for WPA authenticator */int wpa_reconfig(struct wpa_authenticator *wpa_auth,		 struct wpa_auth_config *conf){	if (wpa_auth == NULL)		return 0;	os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));	if (wpa_auth_gen_wpa_ie(wpa_auth)) {		wpa_printf(MSG_ERROR, "Could not generate WPA IE.");		return -1;	}	return 0;}struct wpa_state_machine *wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr){	struct wpa_state_machine *sm;	sm = os_zalloc(sizeof(struct wpa_state_machine));	if (sm == NULL)		return NULL;	os_memcpy(sm->addr, addr, ETH_ALEN);	sm->wpa_auth = wpa_auth;	sm->group = wpa_auth->group;	return sm;}void wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,			     struct wpa_state_machine *sm){	if (wpa_auth == NULL || !wpa_auth->conf.wpa || sm == NULL)		return;#ifdef CONFIG_IEEE80211R

⌨️ 快捷键说明

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