Home | History | Annotate | Download | only in wpa_supplicant
      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 #include "config_ssid.h"
     20 
     21 
     22 static 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 
     30 static void eap_otp_deinit(struct eap_sm *sm, void *priv)
     31 {
     32 }
     33 
     34 
     35 static 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 
     96 int 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