Home | History | Annotate | Download | only in eap_peer
      1 /*
      2  * EAP peer method: EAP-OTP (RFC 3748)
      3  * Copyright (c) 2004-2006, Jouni Malinen <j (at) 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