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

📄 ieee802_1x.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;	case EAP_CODE_FAILURE:		os_strlcpy(buf, "EAP Failure", sizeof(buf));		break;	default:		os_strlcpy(buf, "unknown EAP code", sizeof(buf));		break;	}	buf[sizeof(buf) - 1] = '\0';	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,		       HOSTAPD_LEVEL_DEBUG, "decapsulated EAP packet (code=%d "		       "id=%d len=%d) from RADIUS server: %s",		       hdr->code, hdr->identifier, be_to_host16(hdr->length),		       buf);	sm->eap_if->aaaEapReq = TRUE;	wpabuf_free(sm->eap_if->aaaEapReqData);	sm->eap_if->aaaEapReqData = wpabuf_alloc_ext_data(eap, len);}static void ieee802_1x_get_keys(struct hostapd_data *hapd,				struct sta_info *sta, struct radius_msg *msg,				struct radius_msg *req,				const u8 *shared_secret,				size_t shared_secret_len){	struct radius_ms_mppe_keys *keys;	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL)		return;	keys = radius_msg_get_ms_keys(msg, req, shared_secret,				      shared_secret_len);	if (keys && keys->send && keys->recv) {		size_t len = keys->send_len + keys->recv_len;		wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key",				keys->send, keys->send_len);		wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key",				keys->recv, keys->recv_len);		os_free(sm->eap_if->aaaEapKeyData);		sm->eap_if->aaaEapKeyData = os_malloc(len);		if (sm->eap_if->aaaEapKeyData) {			os_memcpy(sm->eap_if->aaaEapKeyData, keys->recv,				  keys->recv_len);			os_memcpy(sm->eap_if->aaaEapKeyData + keys->recv_len,				  keys->send, keys->send_len);			sm->eap_if->aaaEapKeyDataLen = len;			sm->eap_if->aaaEapKeyAvailable = TRUE;		}	}	if (keys) {		os_free(keys->send);		os_free(keys->recv);		os_free(keys);	}}static void ieee802_1x_store_radius_class(struct hostapd_data *hapd,					  struct sta_info *sta,					  struct radius_msg *msg){	u8 *class;	size_t class_len;	struct eapol_state_machine *sm = sta->eapol_sm;	int count, i;	struct radius_attr_data *nclass;	size_t nclass_count;	if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||	    sm == NULL)		return;	ieee802_1x_free_radius_class(&sm->radius_class);	count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);	if (count <= 0)		return;	nclass = os_zalloc(count * sizeof(struct radius_attr_data));	if (nclass == NULL)		return;	nclass_count = 0;	class = NULL;	for (i = 0; i < count; i++) {		do {			if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS,						    &class, &class_len,						    class) < 0) {				i = count;				break;			}		} while (class_len < 1);		nclass[nclass_count].data = os_malloc(class_len);		if (nclass[nclass_count].data == NULL)			break;		os_memcpy(nclass[nclass_count].data, class, class_len);		nclass[nclass_count].len = class_len;		nclass_count++;	}	sm->radius_class.attr = nclass;	sm->radius_class.count = nclass_count;	wpa_printf(MSG_DEBUG, "IEEE 802.1X: Stored %lu RADIUS Class "		   "attributes for " MACSTR,		   (unsigned long) sm->radius_class.count,		   MAC2STR(sta->addr));}/* Update sta->identity based on User-Name attribute in Access-Accept */static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd,					   struct sta_info *sta,					   struct radius_msg *msg){	u8 *buf, *identity;	size_t len;	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL)		return;	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len,				    NULL) < 0)		return;	identity = os_malloc(len + 1);	if (identity == NULL)		return;	os_memcpy(identity, buf, len);	identity[len] = '\0';	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,		       HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with "		       "User-Name from Access-Accept '%s'",		       sm->identity ? (char *) sm->identity : "N/A",		       (char *) identity);	os_free(sm->identity);	sm->identity = identity;	sm->identity_len = len;}struct sta_id_search {	u8 identifier;	struct eapol_state_machine *sm;};static int ieee802_1x_select_radius_identifier(struct hostapd_data *hapd,					       struct sta_info *sta,					       void *ctx){	struct sta_id_search *id_search = ctx;	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm && sm->radius_identifier >= 0 &&	    sm->radius_identifier == id_search->identifier) {		id_search->sm = sm;		return 1;	}	return 0;}static struct eapol_state_machine *ieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier){	struct sta_id_search id_search;	id_search.identifier = identifier;	id_search.sm = NULL;	ap_for_each_sta(hapd, ieee802_1x_select_radius_identifier, &id_search);	return id_search.sm;}/** * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server * @msg: RADIUS response message * @req: RADIUS request message * @shared_secret: RADIUS shared secret * @shared_secret_len: Length of shared_secret in octets * @data: Context data (struct hostapd_data *) * Returns: Processing status */static RadiusRxResultieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,			const u8 *shared_secret, size_t shared_secret_len,			void *data){	struct hostapd_data *hapd = data;	struct sta_info *sta;	u32 session_timeout = 0, termination_action, acct_interim_interval;	int session_timeout_set, old_vlanid = 0;	struct eapol_state_machine *sm;	int override_eapReq = 0;	sm = ieee802_1x_search_radius_identifier(hapd, msg->hdr->identifier);	if (sm == NULL) {		wpa_printf(MSG_DEBUG, "IEEE 802.1X: Could not find matching "			   "station for this RADIUS message");		return RADIUS_RX_UNKNOWN;	}	sta = sm->sta;	/* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be	 * present when packet contains an EAP-Message attribute */	if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&	    radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,				0) < 0 &&	    radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {		wpa_printf(MSG_DEBUG, "Allowing RADIUS Access-Reject without "			   "Message-Authenticator since it does not include "			   "EAP-Message");	} else if (radius_msg_verify(msg, shared_secret, shared_secret_len,				     req, 1)) {		printf("Incoming RADIUS packet did not have correct "		       "Message-Authenticator - dropped\n");		return RADIUS_RX_INVALID_AUTHENTICATOR;	}	if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&	    msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&	    msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {		printf("Unknown RADIUS message code\n");		return RADIUS_RX_UNKNOWN;	}	sm->radius_identifier = -1;	wpa_printf(MSG_DEBUG, "RADIUS packet matching with station " MACSTR,		   MAC2STR(sta->addr));	if (sm->last_recv_radius) {		radius_msg_free(sm->last_recv_radius);		os_free(sm->last_recv_radius);	}	sm->last_recv_radius = msg;	session_timeout_set =		!radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT,					   &session_timeout);	if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_TERMINATION_ACTION,				      &termination_action))		termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;	if (hapd->conf->radius->acct_interim_interval == 0 &&	    msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&	    radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,				      &acct_interim_interval) == 0) {		if (acct_interim_interval < 60) {			hostapd_logger(hapd, sta->addr,				       HOSTAPD_MODULE_IEEE8021X,				       HOSTAPD_LEVEL_INFO,				       "ignored too small "				       "Acct-Interim-Interval %d",				       acct_interim_interval);		} else			sta->acct_interim_interval = acct_interim_interval;	}	switch (msg->hdr->code) {	case RADIUS_CODE_ACCESS_ACCEPT:		if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)			sta->vlan_id = 0;		else {			old_vlanid = sta->vlan_id;			sta->vlan_id = radius_msg_get_vlanid(msg);		}		if (sta->vlan_id > 0 &&		    hostapd_get_vlan_id_ifname(hapd->conf->vlan,					       sta->vlan_id)) {			hostapd_logger(hapd, sta->addr,				       HOSTAPD_MODULE_RADIUS,				       HOSTAPD_LEVEL_INFO,				       "VLAN ID %d", sta->vlan_id);		} else if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_REQUIRED) {			sta->eapol_sm->authFail = TRUE;			hostapd_logger(hapd, sta->addr,				       HOSTAPD_MODULE_IEEE8021X,				       HOSTAPD_LEVEL_INFO, "authentication "				       "server did not include required VLAN "				       "ID in Access-Accept");			break;		}		ap_sta_bind_vlan(hapd, sta, old_vlanid);		/* RFC 3580, Ch. 3.17 */		if (session_timeout_set && termination_action ==		    RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {			sm->reAuthPeriod = session_timeout;		} else if (session_timeout_set)			ap_sta_session_timeout(hapd, sta, session_timeout);		sm->eap_if->aaaSuccess = TRUE;		override_eapReq = 1;		ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret,				    shared_secret_len);		ieee802_1x_store_radius_class(hapd, sta, msg);		ieee802_1x_update_sta_identity(hapd, sta, msg);		if (sm->eap_if->eapKeyAvailable &&		    wpa_auth_pmksa_add(sta->wpa_sm, sm->eapol_key_crypt,				       session_timeout_set ?				       (int) session_timeout : -1, sm) == 0) {			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,				       HOSTAPD_LEVEL_DEBUG,				       "Added PMKSA cache entry");		}		break;	case RADIUS_CODE_ACCESS_REJECT:		sm->eap_if->aaaFail = TRUE;		override_eapReq = 1;		break;	case RADIUS_CODE_ACCESS_CHALLENGE:		sm->eap_if->aaaEapReq = TRUE;		if (session_timeout_set) {			/* RFC 2869, Ch. 2.3.2; RFC 3580, Ch. 3.17 */			sm->eap_if->aaaMethodTimeout = session_timeout;			hostapd_logger(hapd, sm->addr,				       HOSTAPD_MODULE_IEEE8021X,				       HOSTAPD_LEVEL_DEBUG,				       "using EAP timeout of %d seconds (from "				       "RADIUS)",				       sm->eap_if->aaaMethodTimeout);		} else {			/*			 * Use dynamic retransmission behavior per EAP			 * specification.			 */			sm->eap_if->aaaMethodTimeout = 0;		}		break;	}	ieee802_1x_decapsulate_radius(hapd, sta);	if (override_eapReq)		sm->eap_if->aaaEapReq = FALSE;	eapol_auth_step(sm);	return RADIUS_RX_QUEUED;}void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta){	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL)		return;	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,		       HOSTAPD_LEVEL_DEBUG, "aborting authentication");	if (sm->last_recv_radius) {		radius_msg_free(sm->last_recv_radius);		os_free(sm->last_recv_radius);		sm->last_recv_radius = NULL;	}	if (sm->eap_if->eapTimeout) {		/*		 * Disconnect the STA since it did not reply to the last EAP		 * request and we cannot continue EAP processing (EAP-Failure		 * could only be sent if the EAP peer actually replied).		 */		sm->eap_if->portEnabled = FALSE;		hostapd_sta_deauth(hapd, sta->addr,				   WLAN_REASON_PREV_AUTH_NOT_VALID);		sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |				WLAN_STA_AUTHORIZED);		eloop_cancel_timeout(ap_handle_timer, hapd, sta);		eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);		sta->timeout_next = STA_REMOVE;	}}#ifdef HOSTAPD_DUMP_STATEstatic void fprint_char(FILE *f, char c){	if (c >= 32 && c < 127)		fprintf(f, "%c", c);	else		fprintf(f, "<%02x>", c);}void ieee802_1x_dump_state(FILE *f, const char *prefix, struct sta_info *sta){	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL)		return;	fprintf(f, "%sIEEE 802.1X:\n", prefix);	if (sm->identity) {		size_t i;		fprintf(f, "%sidentity=", prefix);		for (i = 0; i < sm->identity_len; i++)			fprint_char(f, sm->identity[i]);		fprintf(f, "\n");	}	fprintf(f, "%slast EAP type: Authentication Server: %d (%s) "		"Supplicant: %d (%s)\n", prefix,		sm->eap_type_authsrv, eap_type_text(sm->eap_type_authsrv),		sm->eap_type_supp, eap_type_text(sm->eap_type_supp));	fprintf(f, "%scached_packets=%s\n", prefix,		sm->last_recv_radius ? "[RX RADIUS]" : "");	eapol_auth_dump_state(f, prefix, sm);}#endif /* HOSTAPD_DUMP_STATE */static int ieee802_1x_rekey_broadcast(struct hostapd_data *hapd){	if (hapd->conf->default_wep_key_len < 1)		return 0;	os_free(hapd->default_wep_key);	hapd->default_wep_key = os_malloc(hapd->conf->default_wep_key_len);	if (hapd->default_wep_key == NULL ||	    os_get_random(hapd->default_wep_key,			  hapd->conf->default_wep_key_len)) {		printf("Could not generate random WEP key.\n");		os_free(hapd->default_wep_key);		hapd->default_wep_key = NULL;		return -1;	}	wpa_hexdump_key(MSG_DEBUG, "IEEE 802.1X: New default WEP key",			hapd->default_wep_key,			hapd->conf->default_wep_key_len);	return 0;}static int ieee802_1x_sta_key_available(struct hostapd_data *hapd,					struct sta_info *sta, void *ctx){	if (sta->eapol_sm) {		sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;		eapol_auth_step(sta->eapol_sm);	}	return 0;}static void ieee802_1x_rekey(void *eloop_ctx, void *timeout_ctx){	struct hostapd_data *hapd = eloop_ctx;	if (hapd->default_wep_key_idx >= 3)		hapd->default_wep_key_idx =			hapd->conf->individual_wep_key_len > 0 ? 1 : 0;	else		hapd->default_wep_key_idx++;	wpa_printf(MSG_DEBUG, "IEEE 802.1X: New default WEP key index %d",		   hapd->default_wep_key_idx);		      	if (ieee802_1x_rekey_broadcast(hapd)) {		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_WARNING, "failed to generate a "			       "new broadcast key");		os_free(hapd->default_wep_key);		hapd->default_wep_key = NULL;		return;	}	/* TODO: Could setup key for RX here, but change default TX keyid only	 * after new broadcast key has been sent to all stations. */	if (hostapd_set_encryption(hapd->conf->iface, hapd, "WEP", NULL,				   hapd->default_wep_key_idx,				   hapd->default_wep_key,				   hapd->conf->default_wep_key_len, 1)) {		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_WARNING, "failed to configure a "			       "new broadcast key");		os_free(hapd->default_wep_key);		hapd->default_wep_key = NULL;		return;	}	ap_for_each_sta(hapd, ieee802_1x_sta_key_available, NULL);	if (hapd->conf->wep_rekeying_period > 0) {		eloop_register_timeout(hapd->conf->wep_rekeying_period, 0,				       ieee802_1x_rekey, hapd, NULL);	}}static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,				  const u8 *data, size_t datalen){	ieee802_1x_send(ctx, sta_ctx, type, data, datalen);

⌨️ 快捷键说明

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