xref: /freebsd/contrib/wpa/src/eap_peer/eap_otp.c (revision c1d255d3ffdbe447de3ab875bf4e7d7accc5bfc5)
139beb93cSSam Leffler /*
239beb93cSSam Leffler  * EAP peer method: EAP-OTP (RFC 3748)
339beb93cSSam Leffler  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
5f05cddf9SRui Paulo  * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo  * See README for more details.
739beb93cSSam Leffler  */
839beb93cSSam Leffler 
939beb93cSSam Leffler #include "includes.h"
1039beb93cSSam Leffler 
1139beb93cSSam Leffler #include "common.h"
1239beb93cSSam Leffler #include "eap_i.h"
1339beb93cSSam Leffler 
1439beb93cSSam Leffler 
eap_otp_init(struct eap_sm * sm)1539beb93cSSam Leffler static void * eap_otp_init(struct eap_sm *sm)
1639beb93cSSam Leffler {
1739beb93cSSam Leffler 	/* No need for private data. However, must return non-NULL to indicate
1839beb93cSSam Leffler 	 * success. */
1939beb93cSSam Leffler 	return (void *) 1;
2039beb93cSSam Leffler }
2139beb93cSSam Leffler 
2239beb93cSSam Leffler 
eap_otp_deinit(struct eap_sm * sm,void * priv)2339beb93cSSam Leffler static void eap_otp_deinit(struct eap_sm *sm, void *priv)
2439beb93cSSam Leffler {
2539beb93cSSam Leffler }
2639beb93cSSam Leffler 
2739beb93cSSam Leffler 
eap_otp_process(struct eap_sm * sm,void * priv,struct eap_method_ret * ret,const struct wpabuf * reqData)2839beb93cSSam Leffler static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv,
2939beb93cSSam Leffler 				       struct eap_method_ret *ret,
3039beb93cSSam Leffler 				       const struct wpabuf *reqData)
3139beb93cSSam Leffler {
3239beb93cSSam Leffler 	struct wpabuf *resp;
3339beb93cSSam Leffler 	const u8 *pos, *password;
3439beb93cSSam Leffler 	size_t password_len, len;
3539beb93cSSam Leffler 	int otp;
3639beb93cSSam Leffler 
3739beb93cSSam Leffler 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len);
3839beb93cSSam Leffler 	if (pos == NULL) {
39*c1d255d3SCy Schubert 		ret->ignore = true;
4039beb93cSSam Leffler 		return NULL;
4139beb93cSSam Leffler 	}
4239beb93cSSam Leffler 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
4339beb93cSSam Leffler 			  pos, len);
4439beb93cSSam Leffler 
4539beb93cSSam Leffler 	password = eap_get_config_otp(sm, &password_len);
4639beb93cSSam Leffler 	if (password)
4739beb93cSSam Leffler 		otp = 1;
4839beb93cSSam Leffler 	else {
4939beb93cSSam Leffler 		password = eap_get_config_password(sm, &password_len);
5039beb93cSSam Leffler 		otp = 0;
5139beb93cSSam Leffler 	}
5239beb93cSSam Leffler 
5339beb93cSSam Leffler 	if (password == NULL) {
5439beb93cSSam Leffler 		wpa_printf(MSG_INFO, "EAP-OTP: Password not configured");
5539beb93cSSam Leffler 		eap_sm_request_otp(sm, (const char *) pos, len);
56*c1d255d3SCy Schubert 		ret->ignore = true;
5739beb93cSSam Leffler 		return NULL;
5839beb93cSSam Leffler 	}
5939beb93cSSam Leffler 
60*c1d255d3SCy Schubert 	ret->ignore = false;
6139beb93cSSam Leffler 
6239beb93cSSam Leffler 	ret->methodState = METHOD_DONE;
6339beb93cSSam Leffler 	ret->decision = DECISION_COND_SUCC;
64*c1d255d3SCy Schubert 	ret->allowNotifications = false;
6539beb93cSSam Leffler 
6639beb93cSSam Leffler 	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len,
6739beb93cSSam Leffler 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
6839beb93cSSam Leffler 	if (resp == NULL)
6939beb93cSSam Leffler 		return NULL;
7039beb93cSSam Leffler 	wpabuf_put_data(resp, password, password_len);
7139beb93cSSam Leffler 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
7239beb93cSSam Leffler 			      password, password_len);
7339beb93cSSam Leffler 
7439beb93cSSam Leffler 	if (otp) {
7539beb93cSSam Leffler 		wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password");
7639beb93cSSam Leffler 		eap_clear_config_otp(sm);
7739beb93cSSam Leffler 	}
7839beb93cSSam Leffler 
7939beb93cSSam Leffler 	return resp;
8039beb93cSSam Leffler }
8139beb93cSSam Leffler 
8239beb93cSSam Leffler 
eap_peer_otp_register(void)8339beb93cSSam Leffler int eap_peer_otp_register(void)
8439beb93cSSam Leffler {
8539beb93cSSam Leffler 	struct eap_method *eap;
8639beb93cSSam Leffler 
8739beb93cSSam Leffler 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
8839beb93cSSam Leffler 				    EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP");
8939beb93cSSam Leffler 	if (eap == NULL)
9039beb93cSSam Leffler 		return -1;
9139beb93cSSam Leffler 
9239beb93cSSam Leffler 	eap->init = eap_otp_init;
9339beb93cSSam Leffler 	eap->deinit = eap_otp_deinit;
9439beb93cSSam Leffler 	eap->process = eap_otp_process;
9539beb93cSSam Leffler 
96780fb4a2SCy Schubert 	return eap_peer_method_register(eap);
9739beb93cSSam Leffler }
98