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#include "config_ssid.h" 20 21 22static void * eap_otp_init(struct eap_sm *sm) 23{ 24 /* No need for private data. However, must return non-NULL to indicate 25 * success. */ 26 return (void *) 1; 27} 28 29 30static void eap_otp_deinit(struct eap_sm *sm, void *priv) 31{ 32} 33 34 35static u8 * eap_otp_process(struct eap_sm *sm, void *priv, 36 struct eap_method_ret *ret, 37 const u8 *reqData, size_t reqDataLen, 38 size_t *respDataLen) 39{ 40 const struct eap_hdr *req; 41 struct eap_hdr *resp; 42 const u8 *pos, *password; 43 u8 *rpos; 44 size_t password_len, len; 45 int otp; 46 47 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, 48 reqData, reqDataLen, &len); 49 if (pos == NULL) { 50 ret->ignore = TRUE; 51 return NULL; 52 } 53 req = (const struct eap_hdr *) reqData; 54 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message", 55 pos, len); 56 57 password = eap_get_config_otp(sm, &password_len); 58 if (password) 59 otp = 1; 60 else { 61 password = eap_get_config_password(sm, &password_len); 62 otp = 0; 63 } 64 65 if (password == NULL) { 66 wpa_printf(MSG_INFO, "EAP-OTP: Password not configured"); 67 eap_sm_request_otp(sm, (const char *) pos, len); 68 ret->ignore = TRUE; 69 return NULL; 70 } 71 72 ret->ignore = FALSE; 73 74 ret->methodState = METHOD_DONE; 75 ret->decision = DECISION_COND_SUCC; 76 ret->allowNotifications = FALSE; 77 78 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, respDataLen, 79 password_len, EAP_CODE_RESPONSE, req->identifier, 80 &rpos); 81 if (resp == NULL) 82 return NULL; 83 os_memcpy(rpos, password, password_len); 84 wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response", 85 password, password_len); 86 87 if (otp) { 88 wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password"); 89 eap_clear_config_otp(sm); 90 } 91 92 return (u8 *) resp; 93} 94 95 96int eap_peer_otp_register(void) 97{ 98 struct eap_method *eap; 99 int ret; 100 101 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 102 EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP"); 103 if (eap == NULL) 104 return -1; 105 106 eap->init = eap_otp_init; 107 eap->deinit = eap_otp_deinit; 108 eap->process = eap_otp_process; 109 110 ret = eap_peer_method_register(eap); 111 if (ret) 112 eap_peer_method_free(eap); 113 return ret; 114} 115