2 * hostapd / EAP-GTC (RFC 3748)
3 * Copyright (c) 2004, 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.
18 #include <netinet/in.h>
26 enum { CONTINUE
, SUCCESS
, FAILURE
} state
;
30 static void * eap_gtc_init(struct eap_sm
*sm
)
32 struct eap_gtc_data
*data
;
34 data
= malloc(sizeof(*data
));
37 memset(data
, 0, sizeof(*data
));
38 data
->state
= CONTINUE
;
44 static void eap_gtc_reset(struct eap_sm
*sm
, void *priv
)
46 struct eap_gtc_data
*data
= priv
;
51 static u8
* eap_gtc_buildReq(struct eap_sm
*sm
, void *priv
, int id
,
54 struct eap_gtc_data
*data
= priv
;
57 char *msg
= "Password";
60 msg_len
= strlen(msg
);
61 *reqDataLen
= sizeof(*req
) + 1 + msg_len
;
62 req
= malloc(*reqDataLen
);
64 wpa_printf(MSG_ERROR
, "EAP-GTC: Failed to allocate memory for "
66 data
->state
= FAILURE
;
70 req
->code
= EAP_CODE_REQUEST
;
72 req
->length
= htons(*reqDataLen
);
73 pos
= (u8
*) (req
+ 1);
74 *pos
++ = EAP_TYPE_GTC
;
75 memcpy(pos
, msg
, msg_len
);
77 data
->state
= CONTINUE
;
83 static Boolean
eap_gtc_check(struct eap_sm
*sm
, void *priv
,
84 u8
*respData
, size_t respDataLen
)
90 resp
= (struct eap_hdr
*) respData
;
91 pos
= (u8
*) (resp
+ 1);
92 if (respDataLen
< sizeof(*resp
) + 2 || *pos
!= EAP_TYPE_GTC
||
93 (len
= ntohs(resp
->length
)) > respDataLen
) {
94 wpa_printf(MSG_INFO
, "EAP-GTC: Invalid frame");
102 static void eap_gtc_process(struct eap_sm
*sm
, void *priv
,
103 u8
*respData
, size_t respDataLen
)
105 struct eap_gtc_data
*data
= priv
;
106 struct eap_hdr
*resp
;
110 if (sm
->user
== NULL
|| sm
->user
->password
== NULL
) {
111 wpa_printf(MSG_INFO
, "EAP-GTC: Password not configured");
112 data
->state
= FAILURE
;
116 resp
= (struct eap_hdr
*) respData
;
117 pos
= (u8
*) (resp
+ 1);
119 rlen
= ntohs(resp
->length
) - sizeof(*resp
) - 1;
120 wpa_hexdump_key(MSG_MSGDUMP
, "EAP-GTC: Response", pos
, rlen
);
122 if (rlen
!= sm
->user
->password_len
||
123 memcmp(pos
, sm
->user
->password
, rlen
) != 0) {
124 wpa_printf(MSG_DEBUG
, "EAP-GTC: Done - Failure");
125 data
->state
= FAILURE
;
127 wpa_printf(MSG_DEBUG
, "EAP-GTC: Done - Success");
128 data
->state
= SUCCESS
;
133 static Boolean
eap_gtc_isDone(struct eap_sm
*sm
, void *priv
)
135 struct eap_gtc_data
*data
= priv
;
136 return data
->state
!= CONTINUE
;
140 static Boolean
eap_gtc_isSuccess(struct eap_sm
*sm
, void *priv
)
142 struct eap_gtc_data
*data
= priv
;
143 return data
->state
== SUCCESS
;
147 const struct eap_method eap_method_gtc
=
149 .method
= EAP_TYPE_GTC
,
151 .init
= eap_gtc_init
,
152 .reset
= eap_gtc_reset
,
153 .buildReq
= eap_gtc_buildReq
,
154 .check
= eap_gtc_check
,
155 .process
= eap_gtc_process
,
156 .isDone
= eap_gtc_isDone
,
157 .isSuccess
= eap_gtc_isSuccess
,