1189251Ssam/* 2189251Ssam * EAP peer method: EAP-OTP (RFC 3748) 3189251Ssam * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#include "includes.h" 10189251Ssam 11189251Ssam#include "common.h" 12189251Ssam#include "eap_i.h" 13189251Ssam 14189251Ssam 15189251Ssamstatic void * eap_otp_init(struct eap_sm *sm) 16189251Ssam{ 17189251Ssam /* No need for private data. However, must return non-NULL to indicate 18189251Ssam * success. */ 19189251Ssam return (void *) 1; 20189251Ssam} 21189251Ssam 22189251Ssam 23189251Ssamstatic void eap_otp_deinit(struct eap_sm *sm, void *priv) 24189251Ssam{ 25189251Ssam} 26189251Ssam 27189251Ssam 28189251Ssamstatic struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv, 29189251Ssam struct eap_method_ret *ret, 30189251Ssam const struct wpabuf *reqData) 31189251Ssam{ 32189251Ssam struct wpabuf *resp; 33189251Ssam const u8 *pos, *password; 34189251Ssam size_t password_len, len; 35189251Ssam int otp; 36189251Ssam 37189251Ssam pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len); 38189251Ssam if (pos == NULL) { 39189251Ssam ret->ignore = TRUE; 40189251Ssam return NULL; 41189251Ssam } 42189251Ssam wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message", 43189251Ssam pos, len); 44189251Ssam 45189251Ssam password = eap_get_config_otp(sm, &password_len); 46189251Ssam if (password) 47189251Ssam otp = 1; 48189251Ssam else { 49189251Ssam password = eap_get_config_password(sm, &password_len); 50189251Ssam otp = 0; 51189251Ssam } 52189251Ssam 53189251Ssam if (password == NULL) { 54189251Ssam wpa_printf(MSG_INFO, "EAP-OTP: Password not configured"); 55189251Ssam eap_sm_request_otp(sm, (const char *) pos, len); 56189251Ssam ret->ignore = TRUE; 57189251Ssam return NULL; 58189251Ssam } 59189251Ssam 60189251Ssam ret->ignore = FALSE; 61189251Ssam 62189251Ssam ret->methodState = METHOD_DONE; 63189251Ssam ret->decision = DECISION_COND_SUCC; 64189251Ssam ret->allowNotifications = FALSE; 65189251Ssam 66189251Ssam resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len, 67189251Ssam EAP_CODE_RESPONSE, eap_get_id(reqData)); 68189251Ssam if (resp == NULL) 69189251Ssam return NULL; 70189251Ssam wpabuf_put_data(resp, password, password_len); 71189251Ssam wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response", 72189251Ssam password, password_len); 73189251Ssam 74189251Ssam if (otp) { 75189251Ssam wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password"); 76189251Ssam eap_clear_config_otp(sm); 77189251Ssam } 78189251Ssam 79189251Ssam return resp; 80189251Ssam} 81189251Ssam 82189251Ssam 83189251Ssamint eap_peer_otp_register(void) 84189251Ssam{ 85189251Ssam struct eap_method *eap; 86189251Ssam int ret; 87189251Ssam 88189251Ssam eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 89189251Ssam EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP"); 90189251Ssam if (eap == NULL) 91189251Ssam return -1; 92189251Ssam 93189251Ssam eap->init = eap_otp_init; 94189251Ssam eap->deinit = eap_otp_deinit; 95189251Ssam eap->process = eap_otp_process; 96189251Ssam 97189251Ssam ret = eap_peer_method_register(eap); 98189251Ssam if (ret) 99189251Ssam eap_peer_method_free(eap); 100189251Ssam return ret; 101189251Ssam} 102