]>
Commit | Line | Data |
---|---|---|
6fc6879b JM |
1 | /* |
2 | * EAP peer method: EAP-OTP (RFC 3748) | |
3 | * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> | |
4 | * | |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
6fc6879b JM |
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 | int ret; | |
87 | ||
88 | eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, | |
89 | EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP"); | |
90 | if (eap == NULL) | |
91 | return -1; | |
92 | ||
93 | eap->init = eap_otp_init; | |
94 | eap->deinit = eap_otp_deinit; | |
95 | eap->process = eap_otp_process; | |
96 | ||
97 | ret = eap_peer_method_register(eap); | |
98 | if (ret) | |
99 | eap_peer_method_free(eap); | |
100 | return ret; | |
101 | } |