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