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

📄 ieee802_1x.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
		printf("Could not add Connect-Info\n");		goto fail;	}	if (eap && !radius_msg_add_eap(msg, eap, len)) {		printf("Could not add EAP-Message\n");		goto fail;	}	/* State attribute must be copied if and only if this packet is	 * Access-Request reply to the previous Access-Challenge */	if (sm->last_recv_radius && sm->last_recv_radius->hdr->code ==	    RADIUS_CODE_ACCESS_CHALLENGE) {		int res = radius_msg_copy_attr(msg, sm->last_recv_radius,					       RADIUS_ATTR_STATE);		if (res < 0) {			printf("Could not copy State attribute from previous "			       "Access-Challenge\n");			goto fail;		}		if (res > 0) {			wpa_printf(MSG_DEBUG, "Copied RADIUS State Attribute");		}	}	radius_client_send(hapd->radius, msg, RADIUS_AUTH, sta->addr);	return; fail:	radius_msg_free(msg);	os_free(msg);}char *eap_type_text(u8 type){	switch (type) {	case EAP_TYPE_IDENTITY: return "Identity";	case EAP_TYPE_NOTIFICATION: return "Notification";	case EAP_TYPE_NAK: return "Nak";	case EAP_TYPE_MD5: return "MD5-Challenge";	case EAP_TYPE_OTP: return "One-Time Password";	case EAP_TYPE_GTC: return "Generic Token Card";	case EAP_TYPE_TLS: return "TLS";	case EAP_TYPE_TTLS: return "TTLS";	case EAP_TYPE_PEAP: return "PEAP";	case EAP_TYPE_SIM: return "SIM";	case EAP_TYPE_FAST: return "FAST";	case EAP_TYPE_SAKE: return "SAKE";	case EAP_TYPE_PSK: return "PSK";	case EAP_TYPE_PAX: return "PAX";	default: return "Unknown";	}}static void handle_eap_response(struct hostapd_data *hapd,				struct sta_info *sta, struct eap_hdr *eap,				size_t len){	u8 type, *data;	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL)		return;	data = (u8 *) (eap + 1);	if (len < sizeof(*eap) + 1) {		printf("handle_eap_response: too short response data\n");		return;	}	sm->eap_type_supp = type = data[0];	hostapd_logger(hapd, sm->addr, HOSTAPD_MODULE_IEEE8021X,		       HOSTAPD_LEVEL_DEBUG, "received EAP packet (code=%d "		       "id=%d len=%d) from STA: EAP Response-%s (%d)",		       eap->code, eap->identifier, be_to_host16(eap->length),		       eap_type_text(type), type);	sm->dot1xAuthEapolRespFramesRx++;	wpabuf_free(sm->eap_if->eapRespData);	sm->eap_if->eapRespData = wpabuf_alloc_copy(eap, len);	sm->eapolEap = TRUE;}/* Process incoming EAP packet from Supplicant */static void handle_eap(struct hostapd_data *hapd, struct sta_info *sta,		       u8 *buf, size_t len){	struct eap_hdr *eap;	u16 eap_len;	if (len < sizeof(*eap)) {		printf("   too short EAP packet\n");		return;	}	eap = (struct eap_hdr *) buf;	eap_len = be_to_host16(eap->length);	wpa_printf(MSG_DEBUG, "EAP: code=%d identifier=%d length=%d",		   eap->code, eap->identifier, eap_len);	if (eap_len < sizeof(*eap)) {		wpa_printf(MSG_DEBUG, "   Invalid EAP length");		return;	} else if (eap_len > len) {		wpa_printf(MSG_DEBUG, "   Too short frame to contain this EAP "			   "packet");		return;	} else if (eap_len < len) {		wpa_printf(MSG_DEBUG, "   Ignoring %lu extra bytes after EAP "			   "packet", (unsigned long) len - eap_len);	}	switch (eap->code) {	case EAP_CODE_REQUEST:		wpa_printf(MSG_DEBUG, " (request)");		return;	case EAP_CODE_RESPONSE:		wpa_printf(MSG_DEBUG, " (response)");		handle_eap_response(hapd, sta, eap, eap_len);		break;	case EAP_CODE_SUCCESS:		wpa_printf(MSG_DEBUG, " (success)");		return;	case EAP_CODE_FAILURE:		wpa_printf(MSG_DEBUG, " (failure)");		return;	default:		wpa_printf(MSG_DEBUG, " (unknown code)");		return;	}}/** * ieee802_1x_receive - Process the EAPOL frames from the Supplicant * @hapd: hostapd BSS data * @sa: Source address (sender of the EAPOL frame) * @buf: EAPOL frame * @len: Length of buf in octets * * This function is called for each incoming EAPOL frame from the interface */void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,			size_t len){	struct sta_info *sta;	struct ieee802_1x_hdr *hdr;	struct ieee802_1x_eapol_key *key;	u16 datalen;	struct rsn_pmksa_cache_entry *pmksa;	if (!hapd->conf->ieee802_1x && !hapd->conf->wpa &&	    !hapd->conf->wps_state)		return;	wpa_printf(MSG_DEBUG, "IEEE 802.1X: %lu bytes from " MACSTR,		   (unsigned long) len, MAC2STR(sa));	sta = ap_get_sta(hapd, sa);	if (!sta) {		printf("   no station information available\n");		return;	}	if (len < sizeof(*hdr)) {		printf("   too short IEEE 802.1X packet\n");		return;	}	hdr = (struct ieee802_1x_hdr *) buf;	datalen = be_to_host16(hdr->length);	wpa_printf(MSG_DEBUG, "   IEEE 802.1X: version=%d type=%d length=%d",		   hdr->version, hdr->type, datalen);	if (len - sizeof(*hdr) < datalen) {		printf("   frame too short for this IEEE 802.1X packet\n");		if (sta->eapol_sm)			sta->eapol_sm->dot1xAuthEapLengthErrorFramesRx++;		return;	}	if (len - sizeof(*hdr) > datalen) {		wpa_printf(MSG_DEBUG, "   ignoring %lu extra octets after "			   "IEEE 802.1X packet",			   (unsigned long) len - sizeof(*hdr) - datalen);	}	if (sta->eapol_sm) {		sta->eapol_sm->dot1xAuthLastEapolFrameVersion = hdr->version;		sta->eapol_sm->dot1xAuthEapolFramesRx++;	}	key = (struct ieee802_1x_eapol_key *) (hdr + 1);	if (datalen >= sizeof(struct ieee802_1x_eapol_key) &&	    hdr->type == IEEE802_1X_TYPE_EAPOL_KEY &&	    (key->type == EAPOL_KEY_TYPE_WPA ||	     key->type == EAPOL_KEY_TYPE_RSN)) {		wpa_receive(hapd->wpa_auth, sta->wpa_sm, (u8 *) hdr,			    sizeof(*hdr) + datalen);		return;	}	if ((!hapd->conf->ieee802_1x &&	     !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) ||	    wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm)))		return;	if (!sta->eapol_sm) {		sta->eapol_sm = eapol_auth_alloc(hapd->eapol_auth, sta->addr,						 sta->flags & WLAN_STA_PREAUTH,						 sta);		if (!sta->eapol_sm)			return;#ifdef CONFIG_WPS		if (!hapd->conf->ieee802_1x &&		    ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) ==		     WLAN_STA_MAYBE_WPS)) {			/*			 * Delay EAPOL frame transmission until a possible WPS			 * STA initiates the handshake with EAPOL-Start.			 */			sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;		}#endif /* CONFIG_WPS */		sta->eapol_sm->eap_if->portEnabled = TRUE;	}	/* since we support version 1, we can ignore version field and proceed	 * as specified in version 1 standard [IEEE Std 802.1X-2001, 7.5.5] */	/* TODO: actually, we are not version 1 anymore.. However, Version 2	 * does not change frame contents, so should be ok to process frames	 * more or less identically. Some changes might be needed for	 * verification of fields. */	switch (hdr->type) {	case IEEE802_1X_TYPE_EAP_PACKET:		handle_eap(hapd, sta, (u8 *) (hdr + 1), datalen);		break;	case IEEE802_1X_TYPE_EAPOL_START:		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_DEBUG, "received EAPOL-Start "			       "from STA");		sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;		pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);		if (pmksa) {			hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_WPA,				       HOSTAPD_LEVEL_DEBUG, "cached PMKSA "				       "available - ignore it since "				       "STA sent EAPOL-Start");			wpa_auth_sta_clear_pmksa(sta->wpa_sm, pmksa);		}		sta->eapol_sm->eapolStart = TRUE;		sta->eapol_sm->dot1xAuthEapolStartFramesRx++;		wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH_EAPOL);		break;	case IEEE802_1X_TYPE_EAPOL_LOGOFF:		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_DEBUG, "received EAPOL-Logoff "			       "from STA");		sta->acct_terminate_cause =			RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;		accounting_sta_stop(hapd, sta);		sta->eapol_sm->eapolLogoff = TRUE;		sta->eapol_sm->dot1xAuthEapolLogoffFramesRx++;		break;	case IEEE802_1X_TYPE_EAPOL_KEY:		wpa_printf(MSG_DEBUG, "   EAPOL-Key");		if (!(sta->flags & WLAN_STA_AUTHORIZED)) {			wpa_printf(MSG_DEBUG, "   Dropped key data from "				   "unauthorized Supplicant");			break;		}		break;	case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:		wpa_printf(MSG_DEBUG, "   EAPOL-Encapsulated-ASF-Alert");		/* TODO: implement support for this; show data */		break;	default:		wpa_printf(MSG_DEBUG, "   unknown IEEE 802.1X packet type");		sta->eapol_sm->dot1xAuthInvalidEapolFramesRx++;		break;	}	eapol_auth_step(sta->eapol_sm);}/** * ieee802_1x_new_station - Start IEEE 802.1X authentication * @hapd: hostapd BSS data * @sta: The station * * This function is called to start IEEE 802.1X authentication when a new * station completes IEEE 802.11 association. */void ieee802_1x_new_station(struct hostapd_data *hapd, struct sta_info *sta){	struct rsn_pmksa_cache_entry *pmksa;	int reassoc = 1;	int force_1x = 0;#ifdef CONFIG_WPS	if (hapd->conf->wps_state && hapd->conf->wpa &&	    (sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {		/*		 * Need to enable IEEE 802.1X/EAPOL state machines for possible		 * WPS handshake even if IEEE 802.1X/EAPOL is not used for		 * authentication in this BSS.		 */		force_1x = 1;	}#endif /* CONFIG_WPS */	if ((!force_1x && !hapd->conf->ieee802_1x) ||	    wpa_key_mgmt_wpa_psk(wpa_auth_sta_key_mgmt(sta->wpa_sm)))		return;	if (sta->eapol_sm == NULL) {		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_DEBUG, "start authentication");		sta->eapol_sm = eapol_auth_alloc(hapd->eapol_auth, sta->addr,						 sta->flags & WLAN_STA_PREAUTH,						 sta);		if (sta->eapol_sm == NULL) {			hostapd_logger(hapd, sta->addr,				       HOSTAPD_MODULE_IEEE8021X,				       HOSTAPD_LEVEL_INFO,				       "failed to allocate state machine");			return;		}		reassoc = 0;	}#ifdef CONFIG_WPS	sta->eapol_sm->flags &= ~EAPOL_SM_WAIT_START;	if (!hapd->conf->ieee802_1x && !(sta->flags & WLAN_STA_WPS)) {		/*		 * Delay EAPOL frame transmission until a possible WPS		 * initiates the handshake with EAPOL-Start.		 */		sta->eapol_sm->flags |= EAPOL_SM_WAIT_START;	}#endif /* CONFIG_WPS */	sta->eapol_sm->eap_if->portEnabled = TRUE;	pmksa = wpa_auth_sta_get_pmksa(sta->wpa_sm);	if (pmksa) {		int old_vlanid;		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_DEBUG,			       "PMK from PMKSA cache - skip IEEE 802.1X/EAP");		/* Setup EAPOL state machines to already authenticated state		 * because of existing PMKSA information in the cache. */		sta->eapol_sm->keyRun = TRUE;		sta->eapol_sm->eap_if->eapKeyAvailable = TRUE;		sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;		sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;		sta->eapol_sm->authSuccess = TRUE;		if (sta->eapol_sm->eap)			eap_sm_notify_cached(sta->eapol_sm->eap);		old_vlanid = sta->vlan_id;		pmksa_cache_to_eapol_data(pmksa, sta->eapol_sm);		if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)			sta->vlan_id = 0;		ap_sta_bind_vlan(hapd, sta, old_vlanid);	} else {		if (reassoc) {			/*			 * Force EAPOL state machines to start			 * re-authentication without having to wait for the			 * Supplicant to send EAPOL-Start.			 */			sta->eapol_sm->reAuthenticate = TRUE;		}		eapol_auth_step(sta->eapol_sm);	}}void ieee802_1x_free_radius_class(struct radius_class_data *class){	size_t i;	if (class == NULL)		return;	for (i = 0; i < class->count; i++)		os_free(class->attr[i].data);	os_free(class->attr);	class->attr = NULL;	class->count = 0;}int ieee802_1x_copy_radius_class(struct radius_class_data *dst,				 const struct radius_class_data *src){	size_t i;	if (src->attr == NULL)		return 0;	dst->attr = os_zalloc(src->count * sizeof(struct radius_attr_data));	if (dst->attr == NULL)		return -1;	dst->count = 0;	for (i = 0; i < src->count; i++) {		dst->attr[i].data = os_malloc(src->attr[i].len);		if (dst->attr[i].data == NULL)			break;		dst->count++;		os_memcpy(dst->attr[i].data, src->attr[i].data,			  src->attr[i].len);		dst->attr[i].len = src->attr[i].len;	}	return 0;}void ieee802_1x_free_station(struct sta_info *sta){	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL)		return;	sta->eapol_sm = NULL;	if (sm->last_recv_radius) {		radius_msg_free(sm->last_recv_radius);		os_free(sm->last_recv_radius);	}	os_free(sm->identity);	ieee802_1x_free_radius_class(&sm->radius_class);	eapol_auth_free(sm);}static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,					  struct sta_info *sta){	u8 *eap;	size_t len;	struct eap_hdr *hdr;	int eap_type = -1;	char buf[64];	struct radius_msg *msg;	struct eapol_state_machine *sm = sta->eapol_sm;	if (sm == NULL || sm->last_recv_radius == NULL) {		if (sm)			sm->eap_if->aaaEapNoReq = TRUE;		return;	}	msg = sm->last_recv_radius;	eap = radius_msg_get_eap(msg, &len);	if (eap == NULL) {		/* RFC 3579, Chap. 2.6.3:		 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message		 * attribute */		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_WARNING, "could not extract "			       "EAP-Message from RADIUS message");		sm->eap_if->aaaEapNoReq = TRUE;		return;	}	if (len < sizeof(*hdr)) {		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,			       HOSTAPD_LEVEL_WARNING, "too short EAP packet "			       "received from authentication server");		os_free(eap);		sm->eap_if->aaaEapNoReq = TRUE;		return;	}	if (len > sizeof(*hdr))		eap_type = eap[sizeof(*hdr)];	hdr = (struct eap_hdr *) eap;	switch (hdr->code) {	case EAP_CODE_REQUEST:		if (eap_type >= 0)			sm->eap_type_authsrv = eap_type;		os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",			    eap_type >= 0 ? eap_type_text(eap_type) : "??",			    eap_type);		break;	case EAP_CODE_RESPONSE:		os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",			    eap_type >= 0 ? eap_type_text(eap_type) : "??",			    eap_type);		break;	case EAP_CODE_SUCCESS:		os_strlcpy(buf, "EAP Success", sizeof(buf));

⌨️ 快捷键说明

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