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