xref: /dflybsd-src/contrib/wpa_supplicant/src/eap_peer/eap_otp.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer  * EAP peer method: EAP-OTP (RFC 3748)
36d49e1aeSJan Lentfer  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
76d49e1aeSJan Lentfer  */
86d49e1aeSJan Lentfer 
96d49e1aeSJan Lentfer #include "includes.h"
106d49e1aeSJan Lentfer 
116d49e1aeSJan Lentfer #include "common.h"
126d49e1aeSJan Lentfer #include "eap_i.h"
136d49e1aeSJan Lentfer 
146d49e1aeSJan Lentfer 
eap_otp_init(struct eap_sm * sm)156d49e1aeSJan Lentfer static void * eap_otp_init(struct eap_sm *sm)
166d49e1aeSJan Lentfer {
176d49e1aeSJan Lentfer 	/* No need for private data. However, must return non-NULL to indicate
186d49e1aeSJan Lentfer 	 * success. */
196d49e1aeSJan Lentfer 	return (void *) 1;
206d49e1aeSJan Lentfer }
216d49e1aeSJan Lentfer 
226d49e1aeSJan Lentfer 
eap_otp_deinit(struct eap_sm * sm,void * priv)236d49e1aeSJan Lentfer static void eap_otp_deinit(struct eap_sm *sm, void *priv)
246d49e1aeSJan Lentfer {
256d49e1aeSJan Lentfer }
266d49e1aeSJan Lentfer 
276d49e1aeSJan Lentfer 
eap_otp_process(struct eap_sm * sm,void * priv,struct eap_method_ret * ret,const struct wpabuf * reqData)286d49e1aeSJan Lentfer static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv,
296d49e1aeSJan Lentfer 				       struct eap_method_ret *ret,
306d49e1aeSJan Lentfer 				       const struct wpabuf *reqData)
316d49e1aeSJan Lentfer {
326d49e1aeSJan Lentfer 	struct wpabuf *resp;
336d49e1aeSJan Lentfer 	const u8 *pos, *password;
346d49e1aeSJan Lentfer 	size_t password_len, len;
356d49e1aeSJan Lentfer 	int otp;
366d49e1aeSJan Lentfer 
376d49e1aeSJan Lentfer 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len);
386d49e1aeSJan Lentfer 	if (pos == NULL) {
396d49e1aeSJan Lentfer 		ret->ignore = TRUE;
406d49e1aeSJan Lentfer 		return NULL;
416d49e1aeSJan Lentfer 	}
426d49e1aeSJan Lentfer 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
436d49e1aeSJan Lentfer 			  pos, len);
446d49e1aeSJan Lentfer 
456d49e1aeSJan Lentfer 	password = eap_get_config_otp(sm, &password_len);
466d49e1aeSJan Lentfer 	if (password)
476d49e1aeSJan Lentfer 		otp = 1;
486d49e1aeSJan Lentfer 	else {
496d49e1aeSJan Lentfer 		password = eap_get_config_password(sm, &password_len);
506d49e1aeSJan Lentfer 		otp = 0;
516d49e1aeSJan Lentfer 	}
526d49e1aeSJan Lentfer 
536d49e1aeSJan Lentfer 	if (password == NULL) {
546d49e1aeSJan Lentfer 		wpa_printf(MSG_INFO, "EAP-OTP: Password not configured");
556d49e1aeSJan Lentfer 		eap_sm_request_otp(sm, (const char *) pos, len);
566d49e1aeSJan Lentfer 		ret->ignore = TRUE;
576d49e1aeSJan Lentfer 		return NULL;
586d49e1aeSJan Lentfer 	}
596d49e1aeSJan Lentfer 
606d49e1aeSJan Lentfer 	ret->ignore = FALSE;
616d49e1aeSJan Lentfer 
626d49e1aeSJan Lentfer 	ret->methodState = METHOD_DONE;
636d49e1aeSJan Lentfer 	ret->decision = DECISION_COND_SUCC;
646d49e1aeSJan Lentfer 	ret->allowNotifications = FALSE;
656d49e1aeSJan Lentfer 
666d49e1aeSJan Lentfer 	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len,
676d49e1aeSJan Lentfer 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
686d49e1aeSJan Lentfer 	if (resp == NULL)
696d49e1aeSJan Lentfer 		return NULL;
706d49e1aeSJan Lentfer 	wpabuf_put_data(resp, password, password_len);
716d49e1aeSJan Lentfer 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
726d49e1aeSJan Lentfer 			      password, password_len);
736d49e1aeSJan Lentfer 
746d49e1aeSJan Lentfer 	if (otp) {
756d49e1aeSJan Lentfer 		wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password");
766d49e1aeSJan Lentfer 		eap_clear_config_otp(sm);
776d49e1aeSJan Lentfer 	}
786d49e1aeSJan Lentfer 
796d49e1aeSJan Lentfer 	return resp;
806d49e1aeSJan Lentfer }
816d49e1aeSJan Lentfer 
826d49e1aeSJan Lentfer 
eap_peer_otp_register(void)836d49e1aeSJan Lentfer int eap_peer_otp_register(void)
846d49e1aeSJan Lentfer {
856d49e1aeSJan Lentfer 	struct eap_method *eap;
866d49e1aeSJan Lentfer 
876d49e1aeSJan Lentfer 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
886d49e1aeSJan Lentfer 				    EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP");
896d49e1aeSJan Lentfer 	if (eap == NULL)
906d49e1aeSJan Lentfer 		return -1;
916d49e1aeSJan Lentfer 
926d49e1aeSJan Lentfer 	eap->init = eap_otp_init;
936d49e1aeSJan Lentfer 	eap->deinit = eap_otp_deinit;
946d49e1aeSJan Lentfer 	eap->process = eap_otp_process;
956d49e1aeSJan Lentfer 
96*a1157835SDaniel Fojt 	return eap_peer_method_register(eap);
976d49e1aeSJan Lentfer }
98