2 * WPA Supplicant / EAP-GTC (RFC 2284)
3 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.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.
21 #include "wpa_supplicant.h"
22 #include "config_ssid.h"
30 static void * eap_gtc_init(struct eap_sm
*sm
)
32 struct eap_gtc_data
*data
;
33 data
= malloc(sizeof(*data
));
36 memset(data
, 0, sizeof(*data
));
38 if (sm
->m
&& sm
->m
->method
== EAP_TYPE_FAST
) {
39 wpa_printf(MSG_DEBUG
, "EAP-GTC: EAP-FAST tunnel - use prefix "
40 "with challenge/response");
47 static void eap_gtc_deinit(struct eap_sm
*sm
, void *priv
)
49 struct eap_gtc_data
*data
= priv
;
54 static u8
* eap_gtc_process(struct eap_sm
*sm
, void *priv
,
55 struct eap_method_ret
*ret
,
56 const u8
*reqData
, size_t reqDataLen
,
59 struct eap_gtc_data
*data
= priv
;
60 struct wpa_ssid
*config
= eap_get_config(sm
);
61 const struct eap_hdr
*req
;
63 const u8
*pos
, *password
;
65 size_t password_len
, len
;
67 pos
= eap_hdr_validate(EAP_TYPE_GTC
, reqData
, reqDataLen
, &len
);
72 req
= (const struct eap_hdr
*) reqData
;
74 wpa_hexdump_ascii(MSG_MSGDUMP
, "EAP-GTC: Request message", pos
, len
);
76 (len
< 10 || memcmp(pos
, "CHALLENGE=", 10) != 0)) {
77 wpa_printf(MSG_DEBUG
, "EAP-GTC: Challenge did not start with "
80 /* Send an empty response in order to allow tunneled
81 * acknowledgement of the failure. This will also cover the
82 * error case which seems to use EAP-MSCHAPv2 like error
83 * reporting with EAP-GTC inside EAP-FAST tunnel. */
84 *respDataLen
= sizeof(struct eap_hdr
) + 1;
85 resp
= malloc(*respDataLen
);
88 resp
->code
= EAP_CODE_RESPONSE
;
89 resp
->identifier
= req
->identifier
;
90 resp
->length
= host_to_be16(*respDataLen
);
91 rpos
= (u8
*) (resp
+ 1);
92 *rpos
++ = EAP_TYPE_GTC
;
97 (config
->password
== NULL
&& config
->otp
== NULL
)) {
98 wpa_printf(MSG_INFO
, "EAP-GTC: Password not configured");
99 eap_sm_request_otp(sm
, config
, (const char *) pos
, len
);
105 password
= config
->otp
;
106 password_len
= config
->otp_len
;
108 password
= config
->password
;
109 password_len
= config
->password_len
;
114 ret
->methodState
= data
->prefix
? METHOD_MAY_CONT
: METHOD_DONE
;
115 ret
->decision
= DECISION_COND_SUCC
;
116 ret
->allowNotifications
= FALSE
;
118 *respDataLen
= sizeof(struct eap_hdr
) + 1 + password_len
;
120 *respDataLen
+= 9 + config
->identity_len
+ 1;
122 resp
= malloc(*respDataLen
);
125 resp
->code
= EAP_CODE_RESPONSE
;
126 resp
->identifier
= req
->identifier
;
127 resp
->length
= host_to_be16(*respDataLen
);
128 rpos
= (u8
*) (resp
+ 1);
129 *rpos
++ = EAP_TYPE_GTC
;
131 memcpy(rpos
, "RESPONSE=", 9);
133 memcpy(rpos
, config
->identity
, config
->identity_len
);
134 rpos
+= config
->identity_len
;
137 memcpy(rpos
, password
, password_len
);
138 wpa_hexdump_ascii_key(MSG_MSGDUMP
, "EAP-GTC: Response",
139 (u8
*) (resp
+ 1) + 1,
140 *respDataLen
- sizeof(struct eap_hdr
) - 1);
143 wpa_printf(MSG_DEBUG
, "EAP-GTC: Forgetting used password");
144 memset(config
->otp
, 0, config
->otp_len
);
154 const struct eap_method eap_method_gtc
=
156 .method
= EAP_TYPE_GTC
,
158 .init
= eap_gtc_init
,
159 .deinit
= eap_gtc_deinit
,
160 .process
= eap_gtc_process
,