xref: /freebsd-src/contrib/wpa/src/eap_server/eap_server_vendor_test.c (revision ae77177087c655fc883075af4f425b37e032cd05)
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 
25 struct eap_vendor_test_data {
26 	enum { INIT, CONFIRM, SUCCESS, FAILURE } state;
27 };
28 
29 
30 static 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 
47 static 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 
57 static 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 
70 static 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 
77 static 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 
97 static 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 
113 static 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 
139 static 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 
146 static 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 
167 static 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 
174 int 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