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

📄 eap.c

📁 IEEE 802.11a/b/g 服务器端AP
💻 C
📖 第 1 页 / 共 4 页
字号:
	for (i = 0; i < msg_len; i++)		msg[i] = isprint(pos[i]) ? (char) pos[i] : '_';	msg[msg_len] = '\0';	wpa_msg(sm->msg_ctx, MSG_INFO, "%s%s",		WPA_EVENT_EAP_NOTIFICATION, msg);	os_free(msg);}static struct wpabuf * eap_sm_buildNotify(int id){	struct wpabuf *resp;	wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, 0,			     EAP_CODE_RESPONSE, id);	if (resp == NULL)		return NULL;	return resp;}static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req){	const struct eap_hdr *hdr;	size_t plen;	const u8 *pos;	sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE;	sm->reqId = 0;	sm->reqMethod = EAP_TYPE_NONE;	sm->reqVendor = EAP_VENDOR_IETF;	sm->reqVendorMethod = EAP_TYPE_NONE;	if (req == NULL || wpabuf_len(req) < sizeof(*hdr))		return;	hdr = wpabuf_head(req);	plen = be_to_host16(hdr->length);	if (plen > wpabuf_len(req)) {		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "			   "(len=%lu plen=%lu)",			   (unsigned long) wpabuf_len(req),			   (unsigned long) plen);		return;	}	sm->reqId = hdr->identifier;	if (sm->workaround) {		const u8 *addr[1];		addr[0] = wpabuf_head(req);		md5_vector(1, addr, &plen, sm->req_md5);	}	switch (hdr->code) {	case EAP_CODE_REQUEST:		if (plen < sizeof(*hdr) + 1) {			wpa_printf(MSG_DEBUG, "EAP: Too short EAP-Request - "				   "no Type field");			return;		}		sm->rxReq = TRUE;		pos = (const u8 *) (hdr + 1);		sm->reqMethod = *pos++;		if (sm->reqMethod == EAP_TYPE_EXPANDED) {			if (plen < sizeof(*hdr) + 8) {				wpa_printf(MSG_DEBUG, "EAP: Ignored truncated "					   "expanded EAP-Packet (plen=%lu)",					   (unsigned long) plen);				return;			}			sm->reqVendor = WPA_GET_BE24(pos);			pos += 3;			sm->reqVendorMethod = WPA_GET_BE32(pos);		}		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request id=%d "			   "method=%u vendor=%u vendorMethod=%u",			   sm->reqId, sm->reqMethod, sm->reqVendor,			   sm->reqVendorMethod);		break;	case EAP_CODE_RESPONSE:		if (sm->selectedMethod == EAP_TYPE_LEAP) {			/*			 * LEAP differs from RFC 4137 by using reversed roles			 * for mutual authentication and because of this, we			 * need to accept EAP-Response frames if LEAP is used.			 */			if (plen < sizeof(*hdr) + 1) {				wpa_printf(MSG_DEBUG, "EAP: Too short "					   "EAP-Response - no Type field");				return;			}			sm->rxResp = TRUE;			pos = (const u8 *) (hdr + 1);			sm->reqMethod = *pos;			wpa_printf(MSG_DEBUG, "EAP: Received EAP-Response for "				   "LEAP method=%d id=%d",				   sm->reqMethod, sm->reqId);			break;		}		wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Response");		break;	case EAP_CODE_SUCCESS:		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");		sm->rxSuccess = TRUE;		break;	case EAP_CODE_FAILURE:		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");		sm->rxFailure = TRUE;		break;	default:		wpa_printf(MSG_DEBUG, "EAP: Ignored EAP-Packet with unknown "			   "code %d", hdr->code);		break;	}}/** * eap_peer_sm_init - Allocate and initialize EAP peer state machine * @eapol_ctx: Context data to be used with eapol_cb calls * @eapol_cb: Pointer to EAPOL callback functions * @msg_ctx: Context data for wpa_msg() calls * @conf: EAP configuration * Returns: Pointer to the allocated EAP state machine or %NULL on failure * * This function allocates and initializes an EAP state machine. In addition, * this initializes TLS library for the new EAP state machine. eapol_cb pointer * will be in use until eap_peer_sm_deinit() is used to deinitialize this EAP * state machine. Consequently, the caller must make sure that this data * structure remains alive while the EAP state machine is active. */struct eap_sm * eap_peer_sm_init(void *eapol_ctx,				 struct eapol_callbacks *eapol_cb,				 void *msg_ctx, struct eap_config *conf){	struct eap_sm *sm;	struct tls_config tlsconf;	sm = os_zalloc(sizeof(*sm));	if (sm == NULL)		return NULL;	sm->eapol_ctx = eapol_ctx;	sm->eapol_cb = eapol_cb;	sm->msg_ctx = msg_ctx;	sm->ClientTimeout = 60;	if (conf->mac_addr)		os_memcpy(sm->mac_addr, conf->mac_addr, ETH_ALEN);	os_memset(&tlsconf, 0, sizeof(tlsconf));	tlsconf.opensc_engine_path = conf->opensc_engine_path;	tlsconf.pkcs11_engine_path = conf->pkcs11_engine_path;	tlsconf.pkcs11_module_path = conf->pkcs11_module_path;	sm->ssl_ctx = tls_init(&tlsconf);	if (sm->ssl_ctx == NULL) {		wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "			   "context.");		os_free(sm);		return NULL;	}	return sm;}/** * eap_peer_sm_deinit - Deinitialize and free an EAP peer state machine * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * * This function deinitializes EAP state machine and frees all allocated * resources. */void eap_peer_sm_deinit(struct eap_sm *sm){	if (sm == NULL)		return;	eap_deinit_prev_method(sm, "EAP deinit");	eap_sm_abort(sm);	tls_deinit(sm->ssl_ctx);	os_free(sm);}/** * eap_peer_sm_step - Step EAP peer state machine * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * Returns: 1 if EAP state was changed or 0 if not * * This function advances EAP state machine to a new state to match with the * current variables. This should be called whenever variables used by the EAP * state machine have changed. */int eap_peer_sm_step(struct eap_sm *sm){	int res = 0;	do {		sm->changed = FALSE;		SM_STEP_RUN(EAP);		if (sm->changed)			res = 1;	} while (sm->changed);	return res;}/** * eap_sm_abort - Abort EAP authentication * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * * Release system resources that have been allocated for the authentication * session without fully deinitializing the EAP state machine. */void eap_sm_abort(struct eap_sm *sm){	wpabuf_free(sm->lastRespData);	sm->lastRespData = NULL;	wpabuf_free(sm->eapRespData);	sm->eapRespData = NULL;	os_free(sm->eapKeyData);	sm->eapKeyData = NULL;	/* This is not clearly specified in the EAP statemachines draft, but	 * it seems necessary to make sure that some of the EAPOL variables get	 * cleared for the next authentication. */	eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);}#ifdef CONFIG_CTRL_IFACEstatic const char * eap_sm_state_txt(int state){	switch (state) {	case EAP_INITIALIZE:		return "INITIALIZE";	case EAP_DISABLED:		return "DISABLED";	case EAP_IDLE:		return "IDLE";	case EAP_RECEIVED:		return "RECEIVED";	case EAP_GET_METHOD:		return "GET_METHOD";	case EAP_METHOD:		return "METHOD";	case EAP_SEND_RESPONSE:		return "SEND_RESPONSE";	case EAP_DISCARD:		return "DISCARD";	case EAP_IDENTITY:		return "IDENTITY";	case EAP_NOTIFICATION:		return "NOTIFICATION";	case EAP_RETRANSMIT:		return "RETRANSMIT";	case EAP_SUCCESS:		return "SUCCESS";	case EAP_FAILURE:		return "FAILURE";	default:		return "UNKNOWN";	}}#endif /* CONFIG_CTRL_IFACE */#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)static const char * eap_sm_method_state_txt(EapMethodState state){	switch (state) {	case METHOD_NONE:		return "NONE";	case METHOD_INIT:		return "INIT";	case METHOD_CONT:		return "CONT";	case METHOD_MAY_CONT:		return "MAY_CONT";	case METHOD_DONE:		return "DONE";	default:		return "UNKNOWN";	}}static const char * eap_sm_decision_txt(EapDecision decision){	switch (decision) {	case DECISION_FAIL:		return "FAIL";	case DECISION_COND_SUCC:		return "COND_SUCC";	case DECISION_UNCOND_SUCC:		return "UNCOND_SUCC";	default:		return "UNKNOWN";	}}#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */#ifdef CONFIG_CTRL_IFACE/** * eap_sm_get_status - Get EAP state machine status * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * @buf: Buffer for status information * @buflen: Maximum buffer length * @verbose: Whether to include verbose status information * Returns: Number of bytes written to buf. * * Query EAP state machine for status information. This function fills in a * text area with current status information from the EAPOL state machine. If * the buffer (buf) is not large enough, status information will be truncated * to fit the buffer. */int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose){	int len, ret;	if (sm == NULL)		return 0;	len = os_snprintf(buf, buflen,			  "EAP state=%s\n",			  eap_sm_state_txt(sm->EAP_state));	if (len < 0 || (size_t) len >= buflen)		return 0;	if (sm->selectedMethod != EAP_TYPE_NONE) {		const char *name;		if (sm->m) {			name = sm->m->name;		} else {			const struct eap_method *m =				eap_peer_get_eap_method(EAP_VENDOR_IETF,							sm->selectedMethod);			if (m)				name = m->name;			else				name = "?";		}		ret = os_snprintf(buf + len, buflen - len,				  "selectedMethod=%d (EAP-%s)\n",				  sm->selectedMethod, name);		if (ret < 0 || (size_t) ret >= buflen - len)			return len;		len += ret;		if (sm->m && sm->m->get_status) {			len += sm->m->get_status(sm, sm->eap_method_priv,						 buf + len, buflen - len,						 verbose);		}	}	if (verbose) {		ret = os_snprintf(buf + len, buflen - len,				  "reqMethod=%d\n"				  "methodState=%s\n"				  "decision=%s\n"				  "ClientTimeout=%d\n",				  sm->reqMethod,				  eap_sm_method_state_txt(sm->methodState),				  eap_sm_decision_txt(sm->decision),				  sm->ClientTimeout);		if (ret < 0 || (size_t) ret >= buflen - len)			return len;		len += ret;	}	return len;}#endif /* CONFIG_CTRL_IFACE */#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)typedef enum {	TYPE_IDENTITY, TYPE_PASSWORD, TYPE_OTP, TYPE_PIN, TYPE_NEW_PASSWORD,	TYPE_PASSPHRASE} eap_ctrl_req_type;static void eap_sm_request(struct eap_sm *sm, eap_ctrl_req_type type,			   const char *msg, size_t msglen){	struct eap_peer_config *config;	char *field, *txt, *tmp;	if (sm == NULL)		return;	config = eap_get_config(sm);	if (config == NULL)		return;	switch (type) {	case TYPE_IDENTITY:		field = "IDENTITY";		txt = "Identity";		config->pending_req_identity++;		break;	case TYPE_PASSWORD:		field = "PASSWORD";		txt = "Password";		config->pending_req_password++;		break;	case TYPE_NEW_PASSWORD:		field = "NEW_PASSWORD";		txt = "New Password";		config->pending_req_new_password++;		break;	case TYPE_PIN:		field = "PIN";		txt = "PIN";		config->pending_req_pin++;		break;	case TYPE_OTP:		field = "OTP";		if (msg) {			tmp = os_malloc(msglen + 3);			if (tmp == NULL)				return;			tmp[0] = '[';			os_memcpy(tmp + 1, msg, msglen);			tmp[msglen + 1] = ']';			tmp[msglen + 2] = '\0';			txt = tmp;			os_free(config->pending_req_otp);			config->pending_req_otp = tmp;			config->pending_req_otp_len = msglen + 3;		} else {			if (config->pending_req_otp == NULL)				return;			txt = config->pending_req_otp;		}		break;	case TYPE_PASSPHRASE:		field = "PASSPHRASE";		txt = "Private key passphrase";		config->pending_req_passphrase++;		break;	default:		return;	}	if (sm->eapol_cb->eap_param_needed)		sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt);}#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */#define eap_sm_request(sm, type, msg, msglen) do { } while (0)#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG *//** * eap_sm_request_identity - Request identity from user (ctrl_iface) * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * * EAP methods can call this function to request identity information for the * current network. This is normally called when the identity is not included * in the network configuration. The request will be sent to monitor programs * through the control interface. */void eap_sm_request_identity(struct eap_sm *sm){	eap_sm_request(sm, TYPE_IDENTITY, NULL, 0);}/** * eap_sm_request_password - Request password from user (ctrl_iface) * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * * EAP methods can call this function to request password information for the * current network. This is normally called when the password is not included * in the network configuration. The request will be sent to monitor programs * through the control interface. */void eap_sm_request_password(struct eap_sm *sm){	eap_sm_request(sm, TYPE_PASSWORD, NULL, 0);}/** * eap_sm_request_new_password - Request new password from user (ctrl_iface) * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * * EAP methods can call this function to request new password information for * the current network. This is normally called when the EAP method indicates * that the current password has expired and password change is required. The * request will be sent to monitor programs through the control interface. */void eap_sm_request_new_password(struct eap_sm *sm){	eap_sm_request(sm, TYPE_NEW_PASSWORD, NULL, 0);}/** * eap_sm_request_pin - Request SIM or smart card PIN from user (ctrl_iface) * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * * EAP methods can call this function to request SIM or smart card PIN * information for the current network. This is normally called when the PIN is * not included in the network configuration. The request will be sent to * monitor programs through the control interface. */

⌨️ 快捷键说明

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