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