1/* 2 * EAP peer method: EAP-OTP (RFC 3748) 3 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10 11#include "common.h" 12#include "eap_i.h" 13 14 15static void * eap_otp_init(struct eap_sm *sm) 16{ 17 /* No need for private data. However, must return non-NULL to indicate 18 * success. */ 19 return (void *) 1; 20} 21 22 23static void eap_otp_deinit(struct eap_sm *sm, void *priv) 24{ 25} 26 27 28static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv, 29 struct eap_method_ret *ret, 30 const struct wpabuf *reqData) 31{ 32 struct wpabuf *resp; 33 const u8 *pos, *password; 34 size_t password_len, len; 35 int otp; 36 37 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len); 38 if (pos == NULL) { 39 ret->ignore = TRUE; 40 return NULL; 41 } 42 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message", 43 pos, len); 44 45 password = eap_get_config_otp(sm, &password_len); 46 if (password) 47 otp = 1; 48 else { 49 password = eap_get_config_password(sm, &password_len); 50 otp = 0; 51 } 52 53 if (password == NULL) { 54 wpa_printf(MSG_INFO, "EAP-OTP: Password not configured"); 55 eap_sm_request_otp(sm, (const char *) pos, len); 56 ret->ignore = TRUE; 57 return NULL; 58 } 59 60 ret->ignore = FALSE; 61 62 ret->methodState = METHOD_DONE; 63 ret->decision = DECISION_COND_SUCC; 64 ret->allowNotifications = FALSE; 65 66 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len, 67 EAP_CODE_RESPONSE, eap_get_id(reqData)); 68 if (resp == NULL) 69 return NULL; 70 wpabuf_put_data(resp, password, password_len); 71 wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response", 72 password, password_len); 73 74 if (otp) { 75 wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password"); 76 eap_clear_config_otp(sm); 77 } 78 79 return resp; 80} 81 82 83int eap_peer_otp_register(void) 84{ 85 struct eap_method *eap; 86 int ret; 87 88 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 89 EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP"); 90 if (eap == NULL) 91 return -1; 92 93 eap->init = eap_otp_init; 94 eap->deinit = eap_otp_deinit; 95 eap->process = eap_otp_process; 96 97 ret = eap_peer_method_register(eap); 98 if (ret) 99 eap_peer_method_free(eap); 100 return ret; 101} 102