Crypto build cleanup: remove INTERNAL_MD4
[libeap.git] / eap_example / eap_example_peer.c
1 /*
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  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Alternatively, this software may be distributed under the terms of BSD
11  * license.
12  *
13  * See README and COPYING for more details.
14  */
15
16 #include "includes.h"
17
18 #include "common.h"
19 #include "eap_peer/eap.h"
20 #include "eap_peer/eap_config.h"
21 #include "wpabuf.h"
22
23 void eap_example_server_rx(const u8 *data, size_t data_len);
24
25
26 struct eap_peer_ctx {
27         Boolean eapSuccess;
28         Boolean eapRestart;
29         Boolean eapFail;
30         Boolean eapResp;
31         Boolean eapNoResp;
32         Boolean eapReq;
33         Boolean portEnabled;
34         Boolean altAccept; /* for EAP */
35         Boolean altReject; /* for EAP */
36
37         struct wpabuf *eapReqData; /* for EAP */
38
39         unsigned int idleWhile; /* for EAP state machine */
40
41         struct eap_peer_config eap_config;
42         struct eap_sm *eap;
43 };
44
45
46 static struct eap_peer_ctx eap_ctx;
47
48
49 static struct eap_peer_config * peer_get_config(void *ctx)
50 {
51         struct eap_peer_ctx *peer = ctx;
52         return &peer->eap_config;
53 }
54
55
56 static Boolean peer_get_bool(void *ctx, enum eapol_bool_var variable)
57 {
58         struct eap_peer_ctx *peer = ctx;
59         if (peer == NULL)
60                 return FALSE;
61         switch (variable) {
62         case EAPOL_eapSuccess:
63                 return peer->eapSuccess;
64         case EAPOL_eapRestart:
65                 return peer->eapRestart;
66         case EAPOL_eapFail:
67                 return peer->eapFail;
68         case EAPOL_eapResp:
69                 return peer->eapResp;
70         case EAPOL_eapNoResp:
71                 return peer->eapNoResp;
72         case EAPOL_eapReq:
73                 return peer->eapReq;
74         case EAPOL_portEnabled:
75                 return peer->portEnabled;
76         case EAPOL_altAccept:
77                 return peer->altAccept;
78         case EAPOL_altReject:
79                 return peer->altReject;
80         }
81         return FALSE;
82 }
83
84
85 static void peer_set_bool(void *ctx, enum eapol_bool_var variable,
86                           Boolean value)
87 {
88         struct eap_peer_ctx *peer = ctx;
89         if (peer == NULL)
90                 return;
91         switch (variable) {
92         case EAPOL_eapSuccess:
93                 peer->eapSuccess = value;
94                 break;
95         case EAPOL_eapRestart:
96                 peer->eapRestart = value;
97                 break;
98         case EAPOL_eapFail:
99                 peer->eapFail = value;
100                 break;
101         case EAPOL_eapResp:
102                 peer->eapResp = value;
103                 break;
104         case EAPOL_eapNoResp:
105                 peer->eapNoResp = value;
106                 break;
107         case EAPOL_eapReq:
108                 peer->eapReq = value;
109                 break;
110         case EAPOL_portEnabled:
111                 peer->portEnabled = value;
112                 break;
113         case EAPOL_altAccept:
114                 peer->altAccept = value;
115                 break;
116         case EAPOL_altReject:
117                 peer->altReject = value;
118                 break;
119         }
120 }
121
122
123 static unsigned int peer_get_int(void *ctx, enum eapol_int_var variable)
124 {
125         struct eap_peer_ctx *peer = ctx;
126         if (peer == NULL)
127                 return 0;
128         switch (variable) {
129         case EAPOL_idleWhile:
130                 return peer->idleWhile;
131         }
132         return 0;
133 }
134
135
136 static void peer_set_int(void *ctx, enum eapol_int_var variable,
137                          unsigned int value)
138 {
139         struct eap_peer_ctx *peer = ctx;
140         if (peer == NULL)
141                 return;
142         switch (variable) {
143         case EAPOL_idleWhile:
144                 peer->idleWhile = value;
145                 break;
146         }
147 }
148
149
150 static struct wpabuf * peer_get_eapReqData(void *ctx)
151 {
152         struct eap_peer_ctx *peer = ctx;
153         if (peer == NULL || peer->eapReqData == NULL)
154                 return NULL;
155
156         return peer->eapReqData;
157 }
158
159
160 static void peer_set_config_blob(void *ctx, struct wpa_config_blob *blob)
161 {
162         printf("TODO: %s\n", __func__);
163 }
164
165
166 static const struct wpa_config_blob *
167 peer_get_config_blob(void *ctx, const char *name)
168 {
169         printf("TODO: %s\n", __func__);
170         return NULL;
171 }
172
173
174 static void peer_notify_pending(void *ctx)
175 {
176         printf("TODO: %s\n", __func__);
177 }
178
179
180 static struct eapol_callbacks eap_cb;
181 static struct eap_config eap_conf;
182
183 int eap_example_peer_init(void)
184 {
185         if (eap_peer_register_methods() < 0)
186                 return -1;
187
188         os_memset(&eap_ctx, 0, sizeof(eap_ctx));
189
190         eap_ctx.eap_config.identity = (u8 *) os_strdup("user");
191         eap_ctx.eap_config.identity_len = 4;
192         eap_ctx.eap_config.password = (u8 *) os_strdup("password");
193         eap_ctx.eap_config.password_len = 8;
194         eap_ctx.eap_config.ca_cert = (u8 *) os_strdup("ca.pem");
195         eap_ctx.eap_config.fragment_size = 1398;
196
197         os_memset(&eap_cb, 0, sizeof(eap_cb));
198         eap_cb.get_config = peer_get_config;
199         eap_cb.get_bool = peer_get_bool;
200         eap_cb.set_bool = peer_set_bool;
201         eap_cb.get_int = peer_get_int;
202         eap_cb.set_int = peer_set_int;
203         eap_cb.get_eapReqData = peer_get_eapReqData;
204         eap_cb.set_config_blob = peer_set_config_blob;
205         eap_cb.get_config_blob = peer_get_config_blob;
206         eap_cb.notify_pending = peer_notify_pending;
207
208         os_memset(&eap_conf, 0, sizeof(eap_conf));
209         eap_ctx.eap = eap_peer_sm_init(&eap_ctx, &eap_cb, &eap_ctx, &eap_conf);
210         if (eap_ctx.eap == NULL)
211                 return -1;
212
213         /* Enable "port" to allow authentication */
214         eap_ctx.portEnabled = TRUE;
215
216         return 0;
217 }
218
219
220 void eap_example_peer_deinit(void)
221 {
222         eap_peer_sm_deinit(eap_ctx.eap);
223         eap_peer_unregister_methods();
224         wpabuf_free(eap_ctx.eapReqData);
225         os_free(eap_ctx.eap_config.identity);
226         os_free(eap_ctx.eap_config.password);
227         os_free(eap_ctx.eap_config.ca_cert);
228 }
229
230
231 int eap_example_peer_step(void)
232 {
233         int res;
234         res = eap_peer_sm_step(eap_ctx.eap);
235
236         if (eap_ctx.eapResp) {
237                 struct wpabuf *resp;
238                 printf("==> Response\n");
239                 eap_ctx.eapResp = FALSE;
240                 resp = eap_get_eapRespData(eap_ctx.eap);
241                 if (resp) {
242                         /* Send EAP response to the server */
243                         eap_example_server_rx(wpabuf_head(resp),
244                                               wpabuf_len(resp));
245                         wpabuf_free(resp);
246                 }
247         }
248
249         if (eap_ctx.eapSuccess) {
250                 res = 0;
251                 if (eap_key_available(eap_ctx.eap)) {
252                         const u8 *key;
253                         size_t key_len;
254                         key = eap_get_eapKeyData(eap_ctx.eap, &key_len);
255                         wpa_hexdump(MSG_DEBUG, "EAP keying material",
256                                     key, key_len);
257                 }
258         }
259
260         return res;
261 }
262
263
264 void eap_example_peer_rx(const u8 *data, size_t data_len)
265 {
266         /* Make received EAP message available to the EAP library */
267         eap_ctx.eapReq = TRUE;
268         wpabuf_free(eap_ctx.eapReqData);
269         eap_ctx.eapReqData = wpabuf_alloc_copy(data, data_len);
270 }