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
->method
== EAP_TYPE_FAST
) {
34 wpa_printf(MSG_DEBUG
, "EAP-GTC: EAP-FAST tunnel - use prefix "
35 "with challenge/response");
42 static void eap_gtc_deinit(struct eap_sm
*sm
, void *priv
)
44 struct eap_gtc_data
*data
= priv
;
49 static u8
* eap_gtc_process(struct eap_sm
*sm
, void *priv
,
50 struct eap_method_ret
*ret
,
51 const u8
*reqData
, size_t reqDataLen
,
54 struct eap_gtc_data
*data
= priv
;
55 const struct eap_hdr
*req
;
57 const u8
*pos
, *password
, *identity
;
59 size_t password_len
, identity_len
, len
, plen
;
62 pos
= eap_hdr_validate(EAP_VENDOR_IETF
, EAP_TYPE_GTC
,
63 reqData
, reqDataLen
, &len
);
68 req
= (const struct eap_hdr
*) reqData
;
70 wpa_hexdump_ascii(MSG_MSGDUMP
, "EAP-GTC: Request message", pos
, len
);
72 (len
< 10 || os_memcmp(pos
, "CHALLENGE=", 10) != 0)) {
73 wpa_printf(MSG_DEBUG
, "EAP-GTC: Challenge did not start with "
76 /* Send an empty response in order to allow tunneled
77 * acknowledgement of the failure. This will also cover the
78 * error case which seems to use EAP-MSCHAPv2 like error
79 * reporting with EAP-GTC inside EAP-FAST tunnel. */
80 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_GTC
,
81 respDataLen
, 0, EAP_CODE_RESPONSE
,
82 req
->identifier
, NULL
);
86 password
= eap_get_config_otp(sm
, &password_len
);
90 password
= eap_get_config_password(sm
, &password_len
);
94 if (password
== NULL
) {
95 wpa_printf(MSG_INFO
, "EAP-GTC: Password not configured");
96 eap_sm_request_otp(sm
, (const char *) pos
, len
);
103 ret
->methodState
= data
->prefix
? METHOD_MAY_CONT
: METHOD_DONE
;
104 ret
->decision
= DECISION_COND_SUCC
;
105 ret
->allowNotifications
= FALSE
;
108 identity
= eap_get_config_identity(sm
, &identity_len
);
109 if (identity
== NULL
)
112 plen
+= 9 + identity_len
+ 1;
113 resp
= eap_msg_alloc(EAP_VENDOR_IETF
, EAP_TYPE_GTC
, respDataLen
,
114 plen
, EAP_CODE_RESPONSE
, req
->identifier
, &rpos
);
118 os_memcpy(rpos
, "RESPONSE=", 9);
120 os_memcpy(rpos
, identity
, identity_len
);
121 rpos
+= identity_len
;
124 os_memcpy(rpos
, password
, password_len
);
125 wpa_hexdump_ascii_key(MSG_MSGDUMP
, "EAP-GTC: Response",
126 (u8
*) (resp
+ 1) + 1, plen
);
129 wpa_printf(MSG_DEBUG
, "EAP-GTC: Forgetting used password");
130 eap_clear_config_otp(sm
);
137 int eap_peer_gtc_register(void)
139 struct eap_method
*eap
;
142 eap
= eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION
,
143 EAP_VENDOR_IETF
, EAP_TYPE_GTC
, "GTC");
147 eap
->init
= eap_gtc_init
;
148 eap
->deinit
= eap_gtc_deinit
;
149 eap
->process
= eap_gtc_process
;
151 ret
= eap_peer_method_register(eap
);
153 eap_peer_method_free(eap
);