xref: /dflybsd-src/contrib/wpa_supplicant/src/eap_peer/eap_otp.c (revision 6d49e1aea1f916afb9e202b8d2ad09cfab6e48c3)
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