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

📄 wpa.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* WPA Capabilities; use defaults, so no need to include it */	hdr->len = (pos - buf) - 2;	return pos - buf;}static int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len){	struct rsn_ie_hdr *hdr;	int num_suites;	u8 *pos, *count;	hdr = (struct rsn_ie_hdr *) buf;	hdr->elem_id = WLAN_EID_RSN;	pos = (u8 *) &hdr->version;	*pos++ = RSN_VERSION & 0xff;	*pos++ = RSN_VERSION >> 8;	pos = (u8 *) (hdr + 1);	if (conf->wpa_group == WPA_CIPHER_CCMP) {		memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);	} else if (conf->wpa_group == WPA_CIPHER_TKIP) {		memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);	} else if (conf->wpa_group == WPA_CIPHER_WEP104) {		memcpy(pos, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN);	} else if (conf->wpa_group == WPA_CIPHER_WEP40) {		memcpy(pos, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN);	} else {		wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",			   conf->wpa_group);		return -1;	}	pos += RSN_SELECTOR_LEN;	num_suites = 0;	count = pos;	pos += 2;	if (conf->wpa_pairwise & WPA_CIPHER_CCMP) {		memcpy(pos, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN);		pos += RSN_SELECTOR_LEN;		num_suites++;	}	if (conf->wpa_pairwise & WPA_CIPHER_TKIP) {		memcpy(pos, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN);		pos += RSN_SELECTOR_LEN;		num_suites++;	}	if (conf->wpa_pairwise & WPA_CIPHER_NONE) {		memcpy(pos, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN);		pos += RSN_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, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN);		pos += RSN_SELECTOR_LEN;		num_suites++;	}	if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {		memcpy(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X,		       RSN_SELECTOR_LEN);		pos += RSN_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;	/* RSN Capabilities */	*pos++ = conf->rsn_preauth ? BIT(0) : 0;	*pos++ = 0;	hdr->len = (pos - buf) - 2;	return pos - buf;}static int wpa_gen_wpa_ie(struct wpa_authenticator *wpa_auth){	u8 *pos, buf[100];	int res;	pos = buf;	if (wpa_auth->conf.wpa & HOSTAPD_WPA_VERSION_WPA2) {		res = wpa_write_rsn_ie(&wpa_auth->conf,				       pos, buf + sizeof(buf) - pos);		if (res < 0)			return res;		pos += res;	}	if (wpa_auth->conf.wpa & HOSTAPD_WPA_VERSION_WPA) {		res = wpa_write_wpa_ie(&wpa_auth->conf,				       pos, buf + sizeof(buf) - pos);		if (res < 0)			return res;		pos += res;	}	free(wpa_auth->wpa_ie);	wpa_auth->wpa_ie = malloc(pos - buf);	if (wpa_auth->wpa_ie == NULL)		return -1;	memcpy(wpa_auth->wpa_ie, buf, pos - buf);	wpa_auth->wpa_ie_len = pos - buf;	return 0;}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 void wpa_rekey_gmk(void *eloop_ctx, void *timeout_ctx){	struct wpa_authenticator *wpa_auth = eloop_ctx;	if (hostapd_get_rand(wpa_auth->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;	wpa_auth_logger(wpa_auth, NULL, LOGGER_DEBUG, "rekeying GTK");	wpa_auth->GTKReKey = TRUE;	do {		wpa_auth->changed = FALSE;		wpa_group_sm_step(wpa_auth);	} while (wpa_auth->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 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);}/** * wpa_init - Initialize WPA authenticator * @addr: Authenticator address * @conf: Configuration 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;	u8 rkey[32];	u8 buf[ETH_ALEN + 8];	wpa_auth = wpa_zalloc(sizeof(struct wpa_authenticator));	if (wpa_auth == NULL)		return NULL;	memcpy(wpa_auth->addr, addr, ETH_ALEN);	memcpy(&wpa_auth->conf, conf, sizeof(*conf));	memcpy(&wpa_auth->cb, cb, sizeof(*cb));	if (wpa_gen_wpa_ie(wpa_auth)) {		wpa_printf(MSG_ERROR, "Could not generate WPA IE.");		free(wpa_auth);		return NULL;	}	wpa_auth->GTKAuthenticator = TRUE;	switch (wpa_auth->conf.wpa_group) {	case WPA_CIPHER_CCMP:		wpa_auth->GTK_len = 16;		break;	case WPA_CIPHER_TKIP:		wpa_auth->GTK_len = 32;		break;	case WPA_CIPHER_WEP104:		wpa_auth->GTK_len = 13;		break;	case WPA_CIPHER_WEP40:		wpa_auth->GTK_len = 5;		break;	}	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.");		free(wpa_auth->wpa_ie);		free(wpa_auth);		return NULL;	}	/* Counter = PRF-256(Random number, "Init Counter",	 *                   Local MAC Address || Time)	 */	memcpy(buf, wpa_auth->addr, ETH_ALEN);	wpa_get_ntp_timestamp(buf + ETH_ALEN);	if (hostapd_get_rand(rkey, sizeof(rkey)) ||	    hostapd_get_rand(wpa_auth->GMK, WPA_GMK_LEN)) {		wpa_printf(MSG_ERROR, "Failed to get random data for WPA "			   "initialization.");		pmksa_cache_deinit(wpa_auth->pmksa);		free(wpa_auth->wpa_ie);		free(wpa_auth);		return NULL;	}	sha1_prf(rkey, sizeof(rkey), "Init Counter", buf, sizeof(buf),		 wpa_auth->Counter, WPA_NONCE_LEN);	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);	}	wpa_auth->GInit = TRUE;	wpa_group_sm_step(wpa_auth);	wpa_auth->GInit = FALSE;	wpa_group_sm_step(wpa_auth);	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){	eloop_cancel_timeout(wpa_rekey_gmk, wpa_auth, NULL);	eloop_cancel_timeout(wpa_rekey_gtk, wpa_auth, NULL);	while (wpa_auth->stakey_negotiations)		wpa_stakey_remove(wpa_auth, wpa_auth->stakey_negotiations);	pmksa_cache_deinit(wpa_auth->pmksa);	free(wpa_auth->wpa_ie);	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;	memcpy(&wpa_auth->conf, conf, sizeof(*conf));	/*	 * TODO:	 * Disassociate stations if configuration changed	 * Update WPA/RSN IE	 */	return 0;}static int wpa_selector_to_bitfield(u8 *s){	if (memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == 0)		return WPA_CIPHER_NONE;	if (memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == 0)		return WPA_CIPHER_WEP40;	if (memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == 0)		return WPA_CIPHER_TKIP;	if (memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == 0)		return WPA_CIPHER_CCMP;	if (memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == 0)		return WPA_CIPHER_WEP104;	return 0;}static int wpa_key_mgmt_to_bitfield(u8 *s){	if (memcmp(s, WPA_AUTH_KEY_MGMT_UNSPEC_802_1X, WPA_SELECTOR_LEN) == 0)		return WPA_KEY_MGMT_IEEE8021X;	if (memcmp(s, WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X, WPA_SELECTOR_LEN) ==	    0)		return WPA_KEY_MGMT_PSK;	return 0;}static int rsn_selector_to_bitfield(u8 *s){	if (memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == 0)		return WPA_CIPHER_NONE;	if (memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == 0)		return WPA_CIPHER_WEP40;	if (memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == 0)		return WPA_CIPHER_TKIP;	if (memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == 0)		return WPA_CIPHER_CCMP;	if (memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == 0)		return WPA_CIPHER_WEP104;	return 0;}static int rsn_key_mgmt_to_bitfield(u8 *s){	if (memcmp(s, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X, RSN_SELECTOR_LEN) == 0)		return WPA_KEY_MGMT_IEEE8021X;	if (memcmp(s, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X, RSN_SELECTOR_LEN) ==	    0)		return WPA_KEY_MGMT_PSK;	return 0;}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);

⌨️ 快捷键说明

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