2 * EAP peer method: EAP-GTC (RFC 3748)
3 * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
26 static void * eap_gtc_init(struct eap_sm
*sm
)
28 struct eap_gtc_data
*data
;
29 data
= os_zalloc(sizeof(*data
));
33 if (sm
->m
&& sm
->m
->vendor
== EAP_VENDOR_IETF
&&
34 sm
->m
->method
== EAP_TYPE_FAST
) {
35 wpa_printf(MSG_DEBUG
, "EAP-GTC: EAP-FAST tunnel - use prefix "
36 "with challenge/response");
43 static void eap_gtc_deinit(struct eap_sm
*sm
, void *priv
)
45 struct eap_gtc_data
*data
= priv
;
50 static struct wpabuf
* eap_gtc_process(struct eap_sm
*sm
, void *priv
,
51 struct eap_method_ret
*ret
,
52 const struct wpabuf
*reqData
)
54 struct eap_gtc_data
*data
= priv
;
56 const u8
*pos
, *password
, *identity
;
57 size_t password_len
, identity_len
, len
, plen
;
61 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_GTC
, reqData
, &len
);
66 id
= eap_get_id(reqData
);
68 wpa_hexdump_ascii(MSG_MSGDUMP
, "EAP-GTC: Request message", pos
, len
);
70 (len
< 10 || os_memcmp(pos
, "CHALLENGE=", 10) != 0)) {
71 wpa_printf(MSG_DEBUG
, "EAP-GTC: Challenge did not start with "
74 /* Send an empty response in order to allow tunneled
75 * acknowledgement of the failure. This will also cover the
76 * error case which seems to use EAP-MSCHAPv2 like error
77 * reporting with EAP-GTC inside EAP-FAST tunnel. */
78 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_GTC
,
79 0, EAP_CODE_RESPONSE
, id
);
83 password
= eap_get_config_otp(sm
, &password_len
);
87 password
= eap_get_config_password(sm
, &password_len
);
91 if (password
== NULL
) {
92 wpa_printf(MSG_INFO
, "EAP-GTC: Password not configured");
93 eap_sm_request_otp(sm
, (const char *) pos
, len
);
100 ret
->methodState
= data
->prefix
? METHOD_MAY_CONT
: METHOD_DONE
;
101 ret
->decision
= DECISION_COND_SUCC
;
102 ret
->allowNotifications
= FALSE
;
105 identity
= eap_get_config_identity(sm
, &identity_len
);
106 if (identity
== NULL
)
109 plen
+= 9 + identity_len
+ 1;
110 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_GTC
, plen
,
111 EAP_CODE_RESPONSE
, id
);
115 wpabuf_put_data(resp
, "RESPONSE=", 9);
116 wpabuf_put_data(resp
, identity
, identity_len
);
117 wpabuf_put_u8(resp
, '\0');
119 wpabuf_put_data(resp
, password
, password_len
);
120 wpa_hexdump_ascii_key(MSG_MSGDUMP
, "EAP-GTC: Response",
121 wpabuf_head_u8(resp
) + sizeof(struct eap_hdr
) +
125 wpa_printf(MSG_DEBUG
, "EAP-GTC: Forgetting used password");
126 eap_clear_config_otp(sm
);
133 int eap_peer_gtc_register(void)
135 struct eap_method
*eap
;
138 eap
= eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION
,
139 EAP_VENDOR_IETF
, EAP_TYPE_GTC
, "GTC");
143 eap
->init
= eap_gtc_init
;
144 eap
->deinit
= eap_gtc_deinit
;
145 eap
->process
= eap_gtc_process
;
147 ret
= eap_peer_method_register(eap
);
149 eap_peer_method_free(eap
);