• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * EAP peer method: EAP-OTP (RFC 3748)
3  * Copyright (c) 2004-2006, Jouni Malinen <j@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 
eap_otp_init(struct eap_sm * sm)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 
eap_otp_deinit(struct eap_sm * sm,void * priv)30 static void eap_otp_deinit(struct eap_sm *sm, void *priv)
31 {
32 }
33 
34 
eap_otp_process(struct eap_sm * sm,void * priv,struct eap_method_ret * ret,const u8 * reqData,size_t reqDataLen,size_t * respDataLen)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 
eap_peer_otp_register(void)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