2
* hostapd / Test method for vendor specific (expanded) EAP type
3
* Copyright (c) 2005, 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.
22
#define EAP_VENDOR_ID 0xfffefd
23
#define EAP_VENDOR_TYPE 0xfcfbfaf9
26
struct eap_vendor_test_data {
27
enum { INIT, CONFIRM, SUCCESS, FAILURE } state;
31
static const char * eap_vendor_test_state_txt(int state)
48
static void eap_vendor_test_state(struct eap_vendor_test_data *data,
51
wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s",
52
eap_vendor_test_state_txt(data->state),
53
eap_vendor_test_state_txt(state));
58
static void * eap_vendor_test_init(struct eap_sm *sm)
60
struct eap_vendor_test_data *data;
62
data = wpa_zalloc(sizeof(*data));
71
static void eap_vendor_test_reset(struct eap_sm *sm, void *priv)
73
struct eap_vendor_test_data *data = priv;
78
static u8 * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, int id,
81
struct eap_vendor_test_data *data = priv;
85
*reqDataLen = sizeof(*req) + 8 + 1;
86
req = malloc(*reqDataLen);
88
wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate "
89
"memory for request");
93
req->code = EAP_CODE_REQUEST;
95
req->length = htons(*reqDataLen);
96
pos = (u8 *) (req + 1);
97
*pos++ = EAP_TYPE_EXPANDED;
98
WPA_PUT_BE24(pos, EAP_VENDOR_ID);
100
WPA_PUT_BE32(pos, EAP_VENDOR_TYPE);
102
*pos = data->state == INIT ? 1 : 3;
108
static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv,
109
u8 *respData, size_t respDataLen)
111
struct eap_hdr *resp;
117
resp = (struct eap_hdr *) respData;
118
pos = (u8 *) (resp + 1);
119
if (respDataLen < sizeof(*resp))
121
len = ntohs(resp->length);
122
if (len > respDataLen)
125
if (len < sizeof(*resp) + 8 || *pos != EAP_TYPE_EXPANDED) {
126
wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame");
131
vendor = WPA_GET_BE24(pos);
133
method = WPA_GET_BE32(pos);
136
if (vendor != EAP_VENDOR_ID || method != EAP_VENDOR_TYPE)
143
static void eap_vendor_test_process(struct eap_sm *sm, void *priv,
144
u8 *respData, size_t respDataLen)
146
struct eap_vendor_test_data *data = priv;
147
struct eap_hdr *resp;
150
resp = (struct eap_hdr *) respData;
151
pos = (u8 *) (resp + 1);
152
pos += 8; /* Skip expanded header */
154
if (data->state == INIT) {
156
eap_vendor_test_state(data, CONFIRM);
158
eap_vendor_test_state(data, FAILURE);
159
} else if (data->state == CONFIRM) {
161
eap_vendor_test_state(data, SUCCESS);
163
eap_vendor_test_state(data, FAILURE);
165
eap_vendor_test_state(data, FAILURE);
169
static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv)
171
struct eap_vendor_test_data *data = priv;
172
return data->state == SUCCESS;
176
static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
178
struct eap_vendor_test_data *data = priv;
180
const int key_len = 64;
182
if (data->state != SUCCESS)
185
key = malloc(key_len);
189
memset(key, 0x11, key_len / 2);
190
memset(key + key_len / 2, 0x22, key_len / 2);
197
static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv)
199
struct eap_vendor_test_data *data = priv;
200
return data->state == SUCCESS;
204
int eap_server_vendor_test_register(void)
206
struct eap_method *eap;
209
eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
210
EAP_VENDOR_ID, EAP_VENDOR_TYPE,
215
eap->init = eap_vendor_test_init;
216
eap->reset = eap_vendor_test_reset;
217
eap->buildReq = eap_vendor_test_buildReq;
218
eap->check = eap_vendor_test_check;
219
eap->process = eap_vendor_test_process;
220
eap->isDone = eap_vendor_test_isDone;
221
eap->getKey = eap_vendor_test_getKey;
222
eap->isSuccess = eap_vendor_test_isSuccess;
224
ret = eap_server_method_register(eap);
226
eap_server_method_free(eap);