blob: bfeafa00fbdce7595301f57d473d2cfced21d401 [file] [log] [blame]
Jouni Malinen6fc68792008-02-27 17:34:43 -08001/*
2 * Example application showing how EAP peer code from wpa_supplicant can be
3 * used as a library.
4 * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
5 *
Jouni Malinen0f3d5782012-02-11 16:46:35 +02006 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
Jouni Malinen6fc68792008-02-27 17:34:43 -08008 */
9
10#include "includes.h"
11
12#include "common.h"
13#include "eap_peer/eap.h"
14#include "eap_peer/eap_config.h"
15#include "wpabuf.h"
16
17void eap_example_server_rx(const u8 *data, size_t data_len);
18
19
20struct eap_peer_ctx {
21 Boolean eapSuccess;
22 Boolean eapRestart;
23 Boolean eapFail;
24 Boolean eapResp;
25 Boolean eapNoResp;
26 Boolean eapReq;
27 Boolean portEnabled;
28 Boolean altAccept; /* for EAP */
29 Boolean altReject; /* for EAP */
30
31 struct wpabuf *eapReqData; /* for EAP */
32
33 unsigned int idleWhile; /* for EAP state machine */
34
35 struct eap_peer_config eap_config;
36 struct eap_sm *eap;
37};
38
39
40static struct eap_peer_ctx eap_ctx;
41
42
43static struct eap_peer_config * peer_get_config(void *ctx)
44{
45 struct eap_peer_ctx *peer = ctx;
46 return &peer->eap_config;
47}
48
49
50static Boolean peer_get_bool(void *ctx, enum eapol_bool_var variable)
51{
52 struct eap_peer_ctx *peer = ctx;
53 if (peer == NULL)
54 return FALSE;
55 switch (variable) {
56 case EAPOL_eapSuccess:
57 return peer->eapSuccess;
58 case EAPOL_eapRestart:
59 return peer->eapRestart;
60 case EAPOL_eapFail:
61 return peer->eapFail;
62 case EAPOL_eapResp:
63 return peer->eapResp;
64 case EAPOL_eapNoResp:
65 return peer->eapNoResp;
66 case EAPOL_eapReq:
67 return peer->eapReq;
68 case EAPOL_portEnabled:
69 return peer->portEnabled;
70 case EAPOL_altAccept:
71 return peer->altAccept;
72 case EAPOL_altReject:
73 return peer->altReject;
74 }
75 return FALSE;
76}
77
78
79static void peer_set_bool(void *ctx, enum eapol_bool_var variable,
80 Boolean value)
81{
82 struct eap_peer_ctx *peer = ctx;
83 if (peer == NULL)
84 return;
85 switch (variable) {
86 case EAPOL_eapSuccess:
87 peer->eapSuccess = value;
88 break;
89 case EAPOL_eapRestart:
90 peer->eapRestart = value;
91 break;
92 case EAPOL_eapFail:
93 peer->eapFail = value;
94 break;
95 case EAPOL_eapResp:
96 peer->eapResp = value;
97 break;
98 case EAPOL_eapNoResp:
99 peer->eapNoResp = value;
100 break;
101 case EAPOL_eapReq:
102 peer->eapReq = value;
103 break;
104 case EAPOL_portEnabled:
105 peer->portEnabled = value;
106 break;
107 case EAPOL_altAccept:
108 peer->altAccept = value;
109 break;
110 case EAPOL_altReject:
111 peer->altReject = value;
112 break;
113 }
114}
115
116
117static unsigned int peer_get_int(void *ctx, enum eapol_int_var variable)
118{
119 struct eap_peer_ctx *peer = ctx;
120 if (peer == NULL)
121 return 0;
122 switch (variable) {
123 case EAPOL_idleWhile:
124 return peer->idleWhile;
125 }
126 return 0;
127}
128
129
130static void peer_set_int(void *ctx, enum eapol_int_var variable,
131 unsigned int value)
132{
133 struct eap_peer_ctx *peer = ctx;
134 if (peer == NULL)
135 return;
136 switch (variable) {
137 case EAPOL_idleWhile:
138 peer->idleWhile = value;
139 break;
140 }
141}
142
143
144static struct wpabuf * peer_get_eapReqData(void *ctx)
145{
146 struct eap_peer_ctx *peer = ctx;
147 if (peer == NULL || peer->eapReqData == NULL)
148 return NULL;
149
150 return peer->eapReqData;
151}
152
153
154static void peer_set_config_blob(void *ctx, struct wpa_config_blob *blob)
155{
156 printf("TODO: %s\n", __func__);
157}
158
159
160static const struct wpa_config_blob *
161peer_get_config_blob(void *ctx, const char *name)
162{
163 printf("TODO: %s\n", __func__);
164 return NULL;
165}
166
167
168static void peer_notify_pending(void *ctx)
169{
170 printf("TODO: %s\n", __func__);
171}
172
173
Jouni Malinen12760812009-12-06 11:28:41 +0200174static int eap_peer_register_methods(void)
175{
176 int ret = 0;
177
178#ifdef EAP_MD5
179 if (ret == 0)
180 ret = eap_peer_md5_register();
181#endif /* EAP_MD5 */
182
183#ifdef EAP_TLS
184 if (ret == 0)
185 ret = eap_peer_tls_register();
186#endif /* EAP_TLS */
187
188#ifdef EAP_MSCHAPv2
189 if (ret == 0)
190 ret = eap_peer_mschapv2_register();
191#endif /* EAP_MSCHAPv2 */
192
193#ifdef EAP_PEAP
194 if (ret == 0)
195 ret = eap_peer_peap_register();
196#endif /* EAP_PEAP */
197
198#ifdef EAP_TTLS
199 if (ret == 0)
200 ret = eap_peer_ttls_register();
201#endif /* EAP_TTLS */
202
203#ifdef EAP_GTC
204 if (ret == 0)
205 ret = eap_peer_gtc_register();
206#endif /* EAP_GTC */
207
208#ifdef EAP_OTP
209 if (ret == 0)
210 ret = eap_peer_otp_register();
211#endif /* EAP_OTP */
212
213#ifdef EAP_SIM
214 if (ret == 0)
215 ret = eap_peer_sim_register();
216#endif /* EAP_SIM */
217
218#ifdef EAP_LEAP
219 if (ret == 0)
220 ret = eap_peer_leap_register();
221#endif /* EAP_LEAP */
222
223#ifdef EAP_PSK
224 if (ret == 0)
225 ret = eap_peer_psk_register();
226#endif /* EAP_PSK */
227
228#ifdef EAP_AKA
229 if (ret == 0)
230 ret = eap_peer_aka_register();
231#endif /* EAP_AKA */
232
233#ifdef EAP_AKA_PRIME
234 if (ret == 0)
235 ret = eap_peer_aka_prime_register();
236#endif /* EAP_AKA_PRIME */
237
238#ifdef EAP_FAST
239 if (ret == 0)
240 ret = eap_peer_fast_register();
241#endif /* EAP_FAST */
242
243#ifdef EAP_PAX
244 if (ret == 0)
245 ret = eap_peer_pax_register();
246#endif /* EAP_PAX */
247
248#ifdef EAP_SAKE
249 if (ret == 0)
250 ret = eap_peer_sake_register();
251#endif /* EAP_SAKE */
252
253#ifdef EAP_GPSK
254 if (ret == 0)
255 ret = eap_peer_gpsk_register();
256#endif /* EAP_GPSK */
257
258#ifdef EAP_WSC
259 if (ret == 0)
260 ret = eap_peer_wsc_register();
261#endif /* EAP_WSC */
262
263#ifdef EAP_IKEV2
264 if (ret == 0)
265 ret = eap_peer_ikev2_register();
266#endif /* EAP_IKEV2 */
267
268#ifdef EAP_VENDOR_TEST
269 if (ret == 0)
270 ret = eap_peer_vendor_test_register();
271#endif /* EAP_VENDOR_TEST */
272
273#ifdef EAP_TNC
274 if (ret == 0)
275 ret = eap_peer_tnc_register();
276#endif /* EAP_TNC */
277
278 return ret;
279}
280
281
Jouni Malinen6fc68792008-02-27 17:34:43 -0800282static struct eapol_callbacks eap_cb;
283static struct eap_config eap_conf;
284
285int eap_example_peer_init(void)
286{
287 if (eap_peer_register_methods() < 0)
288 return -1;
289
290 os_memset(&eap_ctx, 0, sizeof(eap_ctx));
291
292 eap_ctx.eap_config.identity = (u8 *) os_strdup("user");
293 eap_ctx.eap_config.identity_len = 4;
294 eap_ctx.eap_config.password = (u8 *) os_strdup("password");
295 eap_ctx.eap_config.password_len = 8;
296 eap_ctx.eap_config.ca_cert = (u8 *) os_strdup("ca.pem");
297 eap_ctx.eap_config.fragment_size = 1398;
298
299 os_memset(&eap_cb, 0, sizeof(eap_cb));
300 eap_cb.get_config = peer_get_config;
301 eap_cb.get_bool = peer_get_bool;
302 eap_cb.set_bool = peer_set_bool;
303 eap_cb.get_int = peer_get_int;
304 eap_cb.set_int = peer_set_int;
305 eap_cb.get_eapReqData = peer_get_eapReqData;
306 eap_cb.set_config_blob = peer_set_config_blob;
307 eap_cb.get_config_blob = peer_get_config_blob;
308 eap_cb.notify_pending = peer_notify_pending;
309
310 os_memset(&eap_conf, 0, sizeof(eap_conf));
311 eap_ctx.eap = eap_peer_sm_init(&eap_ctx, &eap_cb, &eap_ctx, &eap_conf);
312 if (eap_ctx.eap == NULL)
313 return -1;
314
315 /* Enable "port" to allow authentication */
316 eap_ctx.portEnabled = TRUE;
317
318 return 0;
319}
320
321
322void eap_example_peer_deinit(void)
323{
324 eap_peer_sm_deinit(eap_ctx.eap);
325 eap_peer_unregister_methods();
326 wpabuf_free(eap_ctx.eapReqData);
327 os_free(eap_ctx.eap_config.identity);
328 os_free(eap_ctx.eap_config.password);
329 os_free(eap_ctx.eap_config.ca_cert);
330}
331
332
333int eap_example_peer_step(void)
334{
335 int res;
336 res = eap_peer_sm_step(eap_ctx.eap);
337
338 if (eap_ctx.eapResp) {
339 struct wpabuf *resp;
340 printf("==> Response\n");
341 eap_ctx.eapResp = FALSE;
342 resp = eap_get_eapRespData(eap_ctx.eap);
343 if (resp) {
344 /* Send EAP response to the server */
345 eap_example_server_rx(wpabuf_head(resp),
346 wpabuf_len(resp));
347 wpabuf_free(resp);
348 }
349 }
350
351 if (eap_ctx.eapSuccess) {
352 res = 0;
353 if (eap_key_available(eap_ctx.eap)) {
354 const u8 *key;
355 size_t key_len;
356 key = eap_get_eapKeyData(eap_ctx.eap, &key_len);
357 wpa_hexdump(MSG_DEBUG, "EAP keying material",
358 key, key_len);
359 }
360 }
361
362 return res;
363}
364
365
366void eap_example_peer_rx(const u8 *data, size_t data_len)
367{
368 /* Make received EAP message available to the EAP library */
369 eap_ctx.eapReq = TRUE;
370 wpabuf_free(eap_ctx.eapReqData);
371 eap_ctx.eapReqData = wpabuf_alloc_copy(data, data_len);
372}