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);