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

📄 wpa.c

📁 WPA在Linux下实现的原代码 WPA在Linux下实现的原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * WPA Supplicant - WPA state machine and EAPOL-Key processing * Copyright (c) 2003-2007, 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 <stdlib.h>#include <stdio.h>#ifndef CONFIG_NATIVE_WINDOWS#include <netinet/in.h>#endif /* CONFIG_NATIVE_WINDOWS */#include <string.h>#include "common.h"#include "md5.h"#include "sha1.h"#include "rc4.h"#include "aes_wrap.h"#include "wpa.h"#include "eloop.h"#include "wpa_supplicant.h"#include "config.h"#include "l2_packet.h"#include "eapol_sm.h"#include "preauth.h"#include "wpa_i.h"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_NONE[] = { 0x00, 0x50, 0xf2, 0 };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 };/* 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;	u8 version[2];} __attribute__ ((packed));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 };/* 1/4: PMKID * 2/4: RSN IE * 3/4: one or two RSN IEs + GTK IE (encrypted) * 4/4: empty * 1/2: GTK IE (encrypted) * 2/2: empty *//* 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;	u8 version[2];} __attribute__ ((packed));struct wpa_eapol_key {	u8 type;	/* Note: key_info, key_length, and key_data_length are unaligned */	u8 key_info[2];	u8 key_length[2];	u8 replay_counter[WPA_REPLAY_COUNTER_LEN];	u8 key_nonce[WPA_NONCE_LEN];	u8 key_iv[16];	u8 key_rsc[8];	u8 key_id[8]; /* Reserved in IEEE 802.11i/RSN */	u8 key_mic[16];	u8 key_data_length[2];	/* followed by key_data_length bytes of key_data */} __attribute__ ((packed));#define WPA_KEY_INFO_TYPE_MASK (BIT(0) | BIT(1) | BIT(2))#define WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 BIT(0)#define WPA_KEY_INFO_TYPE_HMAC_SHA1_AES BIT(1)#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key *//* bit4..5 is used in WPA, but is reserved in IEEE 802.11i/RSN */#define WPA_KEY_INFO_KEY_INDEX_MASK (BIT(4) | BIT(5))#define WPA_KEY_INFO_KEY_INDEX_SHIFT 4#define WPA_KEY_INFO_INSTALL BIT(6) /* pairwise */#define WPA_KEY_INFO_TXRX BIT(6) /* group */#define WPA_KEY_INFO_ACK BIT(7)#define WPA_KEY_INFO_MIC BIT(8)#define WPA_KEY_INFO_SECURE BIT(9)#define WPA_KEY_INFO_ERROR BIT(10)#define WPA_KEY_INFO_REQUEST BIT(11)#define WPA_KEY_INFO_ENCR_KEY_DATA BIT(12) /* IEEE 802.11i/RSN only *//** * wpa_cipher_txt - Convert cipher suite to a text string * @cipher: Cipher suite (WPA_CIPHER_* enum) * Returns: Pointer to a text string of the cipher suite name */static const char * wpa_cipher_txt(int cipher){	switch (cipher) {	case WPA_CIPHER_NONE:		return "NONE";	case WPA_CIPHER_WEP40:		return "WEP-40";	case WPA_CIPHER_WEP104:		return "WEP-104";	case WPA_CIPHER_TKIP:		return "TKIP";	case WPA_CIPHER_CCMP:		return "CCMP";	default:		return "UNKNOWN";	}}/** * wpa_key_mgmt_txt - Convert key management suite to a text string * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum) * @proto: WPA/WPA2 version (WPA_PROTO_*) * Returns: Pointer to a text string of the key management suite name */static const char * wpa_key_mgmt_txt(int key_mgmt, int proto){	switch (key_mgmt) {	case WPA_KEY_MGMT_IEEE8021X:		return proto == WPA_PROTO_RSN ?			"WPA2/IEEE 802.1X/EAP" : "WPA/IEEE 802.1X/EAP";	case WPA_KEY_MGMT_PSK:		return proto == WPA_PROTO_RSN ?			"WPA2-PSK" : "WPA-PSK";	case WPA_KEY_MGMT_NONE:		return "NONE";	case WPA_KEY_MGMT_IEEE8021X_NO_WPA:		return "IEEE 802.1X (no WPA)";	default:		return "UNKNOWN";	}}static int wpa_selector_to_bitfield(const 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(const 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;	if (memcmp(s, WPA_AUTH_KEY_MGMT_NONE, WPA_SELECTOR_LEN) == 0)		return WPA_KEY_MGMT_WPA_NONE;	return 0;}static int rsn_selector_to_bitfield(const 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(const 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;}static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,				struct wpa_ie_data *data){	const struct wpa_ie_hdr *hdr;	const u8 *pos;	int left;	int i, count;	data->proto = WPA_PROTO_WPA;	data->pairwise_cipher = WPA_CIPHER_TKIP;	data->group_cipher = WPA_CIPHER_TKIP;	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;	data->capabilities = 0;	data->pmkid = NULL;	data->num_pmkid = 0;	if (wpa_ie_len == 0) {		/* No WPA IE - fail silently */		return -1;	}	if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {		wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",			   __func__, (unsigned long) wpa_ie_len);		return -1;	}	hdr = (const struct wpa_ie_hdr *) wpa_ie;	if (hdr->elem_id != GENERIC_INFO_ELEM ||	    hdr->len != wpa_ie_len - 2 ||	    memcmp(&hdr->oui, WPA_OUI_TYPE, WPA_SELECTOR_LEN) != 0 ||	    WPA_GET_LE16(hdr->version) != WPA_VERSION) {		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",			   __func__);		return -1;	}	pos = (const 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) {		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",			   __func__, left);		return -1;	}	if (left >= 2) {		data->pairwise_cipher = 0;		count = WPA_GET_LE16(pos);		pos += 2;		left -= 2;		if (count == 0 || left < count * WPA_SELECTOR_LEN) {			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "				   "count %u left %u", __func__, count, left);			return -1;		}		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) {		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",			   __func__);		return -1;	}	if (left >= 2) {		data->key_mgmt = 0;		count = WPA_GET_LE16(pos);		pos += 2;		left -= 2;		if (count == 0 || left < count * WPA_SELECTOR_LEN) {			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "				   "count %u left %u", __func__, count, left);			return -1;		}		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) {		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",			   __func__);		return -1;	}	if (left >= 2) {		data->capabilities = WPA_GET_LE16(pos);		pos += 2;		left -= 2;	}	if (left > 0) {		wpa_printf(MSG_DEBUG, "%s: ie has %u trailing bytes - ignored",			   __func__, left);	}	return 0;}static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,				struct wpa_ie_data *data){	const struct rsn_ie_hdr *hdr;	const u8 *pos;	int left;	int i, count;	data->proto = WPA_PROTO_RSN;	data->pairwise_cipher = WPA_CIPHER_CCMP;	data->group_cipher = WPA_CIPHER_CCMP;	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;	data->capabilities = 0;	data->pmkid = NULL;	data->num_pmkid = 0;	if (rsn_ie_len == 0) {		/* No RSN IE - fail silently */		return -1;	}	if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {		wpa_printf(MSG_DEBUG, "%s: ie len too short %lu",			   __func__, (unsigned long) rsn_ie_len);		return -1;	}	hdr = (const struct rsn_ie_hdr *) rsn_ie;	if (hdr->elem_id != RSN_INFO_ELEM ||	    hdr->len != rsn_ie_len - 2 ||	    WPA_GET_LE16(hdr->version) != RSN_VERSION) {		wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",			   __func__);		return -1;	}	pos = (const 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) {		wpa_printf(MSG_DEBUG, "%s: ie length mismatch, %u too much",			   __func__, left);		return -1;	}	if (left >= 2) {		data->pairwise_cipher = 0;		count = WPA_GET_LE16(pos);		pos += 2;		left -= 2;		if (count == 0 || left < count * RSN_SELECTOR_LEN) {			wpa_printf(MSG_DEBUG, "%s: ie count botch (pairwise), "				   "count %u left %u", __func__, count, left);			return -1;		}		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) {		wpa_printf(MSG_DEBUG, "%s: ie too short (for key mgmt)",			   __func__);		return -1;	}	if (left >= 2) {		data->key_mgmt = 0;		count = WPA_GET_LE16(pos);		pos += 2;		left -= 2;		if (count == 0 || left < count * RSN_SELECTOR_LEN) {			wpa_printf(MSG_DEBUG, "%s: ie count botch (key mgmt), "				   "count %u left %u", __func__, count, left);			return -1;		}		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) {		wpa_printf(MSG_DEBUG, "%s: ie too short (for capabilities)",			   __func__);		return -1;	}

⌨️ 快捷键说明

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