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 software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #include "common.h"
     12 #include "eap_i.h"
     13 
     14 
     15 static void * eap_otp_init(struct eap_sm *sm)
     16 {
     17 	/* No need for private data. However, must return non-NULL to indicate
     18 	 * success. */
     19 	return (void *) 1;
     20 }
     21 
     22 
     23 static void eap_otp_deinit(struct eap_sm *sm, void *priv)
     24 {
     25 }
     26 
     27 
     28 static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv,
     29 				       struct eap_method_ret *ret,
     30 				       const struct wpabuf *reqData)
     31 {
     32 	struct wpabuf *resp;
     33 	const u8 *pos, *password;
     34 	size_t password_len, len;
     35 	int otp;
     36 
     37 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len);
     38 	if (pos == NULL) {
     39 		ret->ignore = TRUE;
     40 		return NULL;
     41 	}
     42 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
     43 			  pos, len);
     44 
     45 	password = eap_get_config_otp(sm, &password_len);
     46 	if (password)
     47 		otp = 1;
     48 	else {
     49 		password = eap_get_config_password(sm, &password_len);
     50 		otp = 0;
     51 	}
     52 
     53 	if (password == NULL) {
     54 		wpa_printf(MSG_INFO, "EAP-OTP: Password not configured");
     55 		eap_sm_request_otp(sm, (const char *) pos, len);
     56 		ret->ignore = TRUE;
     57 		return NULL;
     58 	}
     59 
     60 	ret->ignore = FALSE;
     61 
     62 	ret->methodState = METHOD_DONE;
     63 	ret->decision = DECISION_COND_SUCC;
     64 	ret->allowNotifications = FALSE;
     65 
     66 	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len,
     67 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
     68 	if (resp == NULL)
     69 		return NULL;
     70 	wpabuf_put_data(resp, password, password_len);
     71 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
     72 			      password, password_len);
     73 
     74 	if (otp) {
     75 		wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password");
     76 		eap_clear_config_otp(sm);
     77 	}
     78 
     79 	return resp;
     80 }
     81 
     82 
     83 int eap_peer_otp_register(void)
     84 {
     85 	struct eap_method *eap;
     86 
     87 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
     88 				    EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP");
     89 	if (eap == NULL)
     90 		return -1;
     91 
     92 	eap->init = eap_otp_init;
     93 	eap->deinit = eap_otp_deinit;
     94 	eap->process = eap_otp_process;
     95 
     96 	return eap_peer_method_register(eap);
     97 }
     98