eap_server_vendor_test.c revision 214501
1/*
2 * hostapd / Test method for vendor specific (expanded) EAP type
3 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
4 *
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.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#include "common.h"
18#include "eap_i.h"
19
20
21#define EAP_VENDOR_ID 0xfffefd
22#define EAP_VENDOR_TYPE 0xfcfbfaf9
23
24
25struct eap_vendor_test_data {
26	enum { INIT, CONFIRM, SUCCESS, FAILURE } state;
27};
28
29
30static const char * eap_vendor_test_state_txt(int state)
31{
32	switch (state) {
33	case INIT:
34		return "INIT";
35	case CONFIRM:
36		return "CONFIRM";
37	case SUCCESS:
38		return "SUCCESS";
39	case FAILURE:
40		return "FAILURE";
41	default:
42		return "?";
43	}
44}
45
46
47static void eap_vendor_test_state(struct eap_vendor_test_data *data,
48				  int state)
49{
50	wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s",
51		   eap_vendor_test_state_txt(data->state),
52		   eap_vendor_test_state_txt(state));
53	data->state = state;
54}
55
56
57static void * eap_vendor_test_init(struct eap_sm *sm)
58{
59	struct eap_vendor_test_data *data;
60
61	data = os_zalloc(sizeof(*data));
62	if (data == NULL)
63		return NULL;
64	data->state = INIT;
65
66	return data;
67}
68
69
70static void eap_vendor_test_reset(struct eap_sm *sm, void *priv)
71{
72	struct eap_vendor_test_data *data = priv;
73	os_free(data);
74}
75
76
77static struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv,
78						u8 id)
79{
80	struct eap_vendor_test_data *data = priv;
81	struct wpabuf *req;
82
83	req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1,
84			    EAP_CODE_REQUEST, id);
85	if (req == NULL) {
86		wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate "
87			   "memory for request");
88		return NULL;
89	}
90
91	wpabuf_put_u8(req, data->state == INIT ? 1 : 3);
92
93	return req;
94}
95
96
97static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv,
98				     struct wpabuf *respData)
99{
100	const u8 *pos;
101	size_t len;
102
103	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len);
104	if (pos == NULL || len < 1) {
105		wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame");
106		return TRUE;
107	}
108
109	return FALSE;
110}
111
112
113static void eap_vendor_test_process(struct eap_sm *sm, void *priv,
114				    struct wpabuf *respData)
115{
116	struct eap_vendor_test_data *data = priv;
117	const u8 *pos;
118	size_t len;
119
120	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len);
121	if (pos == NULL || len < 1)
122		return;
123
124	if (data->state == INIT) {
125		if (*pos == 2)
126			eap_vendor_test_state(data, CONFIRM);
127		else
128			eap_vendor_test_state(data, FAILURE);
129	} else if (data->state == CONFIRM) {
130		if (*pos == 4)
131			eap_vendor_test_state(data, SUCCESS);
132		else
133			eap_vendor_test_state(data, FAILURE);
134	} else
135		eap_vendor_test_state(data, FAILURE);
136}
137
138
139static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv)
140{
141	struct eap_vendor_test_data *data = priv;
142	return data->state == SUCCESS;
143}
144
145
146static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
147{
148	struct eap_vendor_test_data *data = priv;
149	u8 *key;
150	const int key_len = 64;
151
152	if (data->state != SUCCESS)
153		return NULL;
154
155	key = os_malloc(key_len);
156	if (key == NULL)
157		return NULL;
158
159	os_memset(key, 0x11, key_len / 2);
160	os_memset(key + key_len / 2, 0x22, key_len / 2);
161	*len = key_len;
162
163	return key;
164}
165
166
167static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv)
168{
169	struct eap_vendor_test_data *data = priv;
170	return data->state == SUCCESS;
171}
172
173
174int eap_server_vendor_test_register(void)
175{
176	struct eap_method *eap;
177	int ret;
178
179	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
180				      EAP_VENDOR_ID, EAP_VENDOR_TYPE,
181				      "VENDOR-TEST");
182	if (eap == NULL)
183		return -1;
184
185	eap->init = eap_vendor_test_init;
186	eap->reset = eap_vendor_test_reset;
187	eap->buildReq = eap_vendor_test_buildReq;
188	eap->check = eap_vendor_test_check;
189	eap->process = eap_vendor_test_process;
190	eap->isDone = eap_vendor_test_isDone;
191	eap->getKey = eap_vendor_test_getKey;
192	eap->isSuccess = eap_vendor_test_isSuccess;
193
194	ret = eap_server_method_register(eap);
195	if (ret)
196		eap_server_method_free(eap);
197	return ret;
198}
199