2 * hostapd / EAP-Identity
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.
18 #include <netinet/in.h>
25 struct eap_identity_data
{
26 enum { CONTINUE
, SUCCESS
, FAILURE
} state
;
31 static void * eap_identity_init(struct eap_sm
*sm
)
33 struct eap_identity_data
*data
;
35 data
= malloc(sizeof(*data
));
38 memset(data
, 0, sizeof(*data
));
39 data
->state
= CONTINUE
;
45 static void * eap_identity_initPickUp(struct eap_sm
*sm
)
47 struct eap_identity_data
*data
;
48 data
= eap_identity_init(sm
);
56 static void eap_identity_reset(struct eap_sm
*sm
, void *priv
)
58 struct eap_identity_data
*data
= priv
;
63 static u8
* eap_identity_buildReq(struct eap_sm
*sm
, void *priv
, int id
,
66 struct eap_identity_data
*data
= priv
;
72 if (sm
->eapol_cb
->get_eap_req_id_text
) {
73 req_data
= sm
->eapol_cb
->get_eap_req_id_text(sm
->eapol_ctx
,
79 *reqDataLen
= sizeof(*req
) + 1 + req_data_len
;
80 req
= malloc(*reqDataLen
);
82 wpa_printf(MSG_ERROR
, "EAP-Identity: Failed to allocate "
83 "memory for request");
84 data
->state
= FAILURE
;
88 req
->code
= EAP_CODE_REQUEST
;
90 req
->length
= htons(*reqDataLen
);
91 pos
= (u8
*) (req
+ 1);
92 *pos
++ = EAP_TYPE_IDENTITY
;
94 memcpy(pos
, req_data
, req_data_len
);
100 static Boolean
eap_identity_check(struct eap_sm
*sm
, void *priv
,
101 u8
*respData
, size_t respDataLen
)
103 struct eap_hdr
*resp
;
107 resp
= (struct eap_hdr
*) respData
;
108 pos
= (u8
*) (resp
+ 1);
109 if (respDataLen
< sizeof(*resp
) + 1 || *pos
!= EAP_TYPE_IDENTITY
||
110 (len
= ntohs(resp
->length
)) > respDataLen
) {
111 wpa_printf(MSG_INFO
, "EAP-Identity: Invalid frame");
119 static void eap_identity_process(struct eap_sm
*sm
, void *priv
,
120 u8
*respData
, size_t respDataLen
)
122 struct eap_identity_data
*data
= priv
;
123 struct eap_hdr
*resp
;
128 if (eap_identity_check(sm
, data
, respData
, respDataLen
)) {
129 wpa_printf(MSG_DEBUG
, "EAP-Identity: failed to pick "
130 "up already started negotiation");
131 data
->state
= FAILURE
;
137 resp
= (struct eap_hdr
*) respData
;
138 len
= ntohs(resp
->length
);
139 pos
= (u8
*) (resp
+ 1);
141 len
-= sizeof(*resp
) + 1;
143 data
->state
= FAILURE
;
146 wpa_hexdump_ascii(MSG_DEBUG
, "EAP-Identity: Peer identity", pos
, len
);
148 sm
->identity
= malloc(len
);
149 if (sm
->identity
== NULL
) {
150 data
->state
= FAILURE
;
152 memcpy(sm
->identity
, pos
, len
);
153 sm
->identity_len
= len
;
154 data
->state
= SUCCESS
;
159 static Boolean
eap_identity_isDone(struct eap_sm
*sm
, void *priv
)
161 struct eap_identity_data
*data
= priv
;
162 return data
->state
!= CONTINUE
;
166 static Boolean
eap_identity_isSuccess(struct eap_sm
*sm
, void *priv
)
168 struct eap_identity_data
*data
= priv
;
169 return data
->state
== SUCCESS
;
173 const struct eap_method eap_method_identity
=
175 .method
= EAP_TYPE_IDENTITY
,
177 .init
= eap_identity_init
,
178 .initPickUp
= eap_identity_initPickUp
,
179 .reset
= eap_identity_reset
,
180 .buildReq
= eap_identity_buildReq
,
181 .check
= eap_identity_check
,
182 .process
= eap_identity_process
,
183 .isDone
= eap_identity_isDone
,
184 .isSuccess
= eap_identity_isSuccess
,