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