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

📄 eap.c

📁 WPA在Linux下实现的原代码 WPA在Linux下实现的原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	} else {		identity = config->identity;		identity_len = config->identity_len;		wpa_hexdump_ascii(MSG_DEBUG, "EAP: using real identity",				  identity, identity_len);	}	if (identity == NULL) {		wpa_printf(MSG_WARNING, "EAP: buildIdentity: identity "			   "configuration was not available");		if (config->pcsc) {			if (eap_sm_get_scard_identity(sm, config) < 0)				return NULL;			identity = config->identity;			identity_len = config->identity_len;			wpa_hexdump_ascii(MSG_DEBUG, "permanent identity from "					  "IMSI", identity, identity_len);		} else {			eap_sm_request_identity(sm, config);			return NULL;		}	}	*len = sizeof(struct eap_hdr) + 1 + identity_len;	resp = malloc(*len);	if (resp == NULL)		return NULL;	resp->code = EAP_CODE_RESPONSE;	resp->identifier = id;	resp->length = host_to_be16(*len);	pos = (u8 *) (resp + 1);	*pos++ = EAP_TYPE_IDENTITY;	memcpy(pos, identity, identity_len);	return (u8 *) resp;}static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req, size_t len){	const struct eap_hdr *hdr = (const struct eap_hdr *) req;	const u8 *pos;	char *msg;	size_t msg_len;	int i;	pos = (const u8 *) (hdr + 1);	pos++;	msg_len = be_to_host16(hdr->length);	if (msg_len < 5)		return;	msg_len -= 5;	wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data",			  pos, msg_len);	msg = malloc(msg_len + 1);	if (msg == NULL)		return;	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);	free(msg);}static u8 * eap_sm_buildNotify(struct eap_sm *sm, int id, size_t *len){	struct eap_hdr *resp;	u8 *pos;	wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");	*len = sizeof(struct eap_hdr) + 1;	resp = malloc(*len);	if (resp == NULL)		return NULL;	resp->code = EAP_CODE_RESPONSE;	resp->identifier = id;	resp->length = host_to_be16(*len);	pos = (u8 *) (resp + 1);	*pos = EAP_TYPE_NOTIFICATION;	return (u8 *) resp;}static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len){	const struct eap_hdr *hdr;	size_t plen;	sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE;	sm->reqId = 0;	sm->reqMethod = EAP_TYPE_NONE;	if (req == NULL || len < sizeof(*hdr))		return;	hdr = (const struct eap_hdr *) req;	plen = be_to_host16(hdr->length);	if (plen > len) {		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "			   "(len=%lu plen=%lu)",			   (unsigned long) len, (unsigned long) plen);		return;	}	sm->reqId = hdr->identifier;	if (sm->workaround) {		md5_vector(1, (const u8 **) &req, &len, sm->req_md5);	}	switch (hdr->code) {	case EAP_CODE_REQUEST:		sm->rxReq = TRUE;		if (plen > sizeof(*hdr))			sm->reqMethod = *((u8 *) (hdr + 1));		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Request method=%d "			   "id=%d", sm->reqMethod, sm->reqId);		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.			 */			sm->rxResp = TRUE;			if (plen > sizeof(*hdr))				sm->reqMethod = *((u8 *) (hdr + 1));			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_sm_init - Allocate and initialize EAP 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_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_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 = malloc(sizeof(*sm));	if (sm == NULL)		return NULL;	memset(sm, 0, sizeof(*sm));	sm->eapol_ctx = eapol_ctx;	sm->eapol_cb = eapol_cb;	sm->msg_ctx = msg_ctx;	sm->ClientTimeout = 60;	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.");		free(sm);		return NULL;	}	return sm;}/** * eap_sm_deinit - Deinitialize and free an EAP state machine * @sm: Pointer to EAP state machine allocated with eap_sm_init() * * This function deinitializes EAP state machine and frees all allocated * resources. */void eap_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);	free(sm);}/** * eap_sm_step - Step EAP state machine * @sm: Pointer to EAP state machine allocated with eap_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_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_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){	free(sm->lastRespData);	sm->lastRespData = NULL;	free(sm->eapRespData);	sm->eapRespData = NULL;	free(sm->eapKeyData);	sm->eapKeyData = NULL;}static 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";	}}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";	}}/** * eap_sm_get_status - Get EAP state machine status * @sm: Pointer to EAP state machine allocated with eap_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;	if (sm == NULL)		return 0;	len = snprintf(buf, buflen,		       "EAP state=%s\n",		       eap_sm_state_txt(sm->EAP_state));	if (sm->selectedMethod != EAP_TYPE_NONE) {		const char *name;		if (sm->m) {			name = sm->m->name;		} else {			const struct eap_method *m =				eap_sm_get_eap_methods(sm->selectedMethod);			if (m)				name = m->name;			else				name = "?";		}		len += snprintf(buf + len, buflen - len,				"selectedMethod=%d (EAP-%s)\n",				sm->selectedMethod, name);		if (sm->m && sm->m->get_status) {			len += sm->m->get_status(sm, sm->eap_method_priv,						 buf + len, buflen - len,						 verbose);		}	}	if (verbose) {		len += 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);	}	return len;}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, struct wpa_ssid *config,			   eap_ctrl_req_type type, const char *msg,			   size_t msglen){	char *buf;	size_t buflen;	int len;	char *field;	char *txt, *tmp;	if (config == NULL || sm == 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 = malloc(msglen + 3);			if (tmp == NULL)				return;			tmp[0] = '[';			memcpy(tmp + 1, msg, msglen);			tmp[msglen + 1] = ']';			tmp[msglen + 2] = '\0';			txt = tmp;			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;	}	buflen = 100 + strlen(txt) + config->ssid_len;	buf = malloc(buflen);	if (buf == NULL)		return;	len = snprintf(buf, buflen, WPA_CTRL_REQ "%s-%d:%s needed for SSID ",		       field, config->id, txt);	if (config->ssid && buflen > len + config->ssid_len) {		memcpy(buf + len, config->ssid, config->ssid_len);		len += config->ssid_len;		buf[len] = '\0';	}	wpa_msg(sm->msg_ctx, MSG_INFO, "%s", buf);	free(buf);}/** * eap_sm_request_identity - Request identity from user (ctrl_iface) * @sm: Pointer to EAP state machine allocated with eap_sm_init() * @config: Pointer to the current network configuration * * 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.

⌨️ 快捷键说明

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