~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to eapol_test.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * WPA Supplicant - test code
3
 
 * Copyright (c) 2003-2006, 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
 
 * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c.
15
 
 * Not used in production version.
16
 
 */
17
 
 
18
 
#include "includes.h"
19
 
#include <assert.h>
20
 
 
21
 
#include "common.h"
22
 
#include "config.h"
23
 
#include "eapol_sm.h"
24
 
#include "eap.h"
25
 
#include "eloop.h"
26
 
#include "wpa.h"
27
 
#include "eap_i.h"
28
 
#include "wpa_supplicant.h"
29
 
#include "wpa_supplicant_i.h"
30
 
#include "radius.h"
31
 
#include "radius_client.h"
32
 
#include "l2_packet.h"
33
 
#include "ctrl_iface.h"
34
 
#include "pcsc_funcs.h"
35
 
 
36
 
 
37
 
extern int wpa_debug_level;
38
 
extern int wpa_debug_show_keys;
39
 
 
40
 
struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL };
41
 
 
42
 
 
43
 
struct eapol_test_data {
44
 
        struct wpa_supplicant *wpa_s;
45
 
 
46
 
        int eapol_test_num_reauths;
47
 
        int no_mppe_keys;
48
 
        int num_mppe_ok, num_mppe_mismatch;
49
 
 
50
 
        u8 radius_identifier;
51
 
        struct radius_msg *last_recv_radius;
52
 
        struct in_addr own_ip_addr;
53
 
        struct radius_client_data *radius;
54
 
        struct hostapd_radius_servers *radius_conf;
55
 
 
56
 
        u8 *last_eap_radius; /* last received EAP Response from Authentication
57
 
                              * Server */
58
 
        size_t last_eap_radius_len;
59
 
 
60
 
        u8 authenticator_pmk[PMK_LEN];
61
 
        size_t authenticator_pmk_len;
62
 
        int radius_access_accept_received;
63
 
        int radius_access_reject_received;
64
 
        int auth_timed_out;
65
 
 
66
 
        u8 *eap_identity;
67
 
        size_t eap_identity_len;
68
 
 
69
 
        char *connect_info;
70
 
        u8 own_addr[ETH_ALEN];
71
 
};
72
 
 
73
 
static struct eapol_test_data eapol_test;
74
 
 
75
 
 
76
 
static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx);
77
 
 
78
 
 
79
 
void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
80
 
                    char *fmt, ...)
81
 
{
82
 
        char *format;
83
 
        int maxlen;
84
 
        va_list ap;
85
 
 
86
 
        maxlen = os_strlen(fmt) + 100;
87
 
        format = os_malloc(maxlen);
88
 
        if (!format)
89
 
                return;
90
 
 
91
 
        va_start(ap, fmt);
92
 
 
93
 
 
94
 
        if (addr)
95
 
                os_snprintf(format, maxlen, "STA " MACSTR ": %s",
96
 
                            MAC2STR(addr), fmt);
97
 
        else
98
 
                os_snprintf(format, maxlen, "%s", fmt);
99
 
 
100
 
        vprintf(format, ap);
101
 
        printf("\n");
102
 
 
103
 
        os_free(format);
104
 
 
105
 
        va_end(ap);
106
 
}
107
 
 
108
 
 
109
 
const char * hostapd_ip_txt(const struct hostapd_ip_addr *addr, char *buf,
110
 
                            size_t buflen)
111
 
{
112
 
        if (buflen == 0 || addr == NULL)
113
 
                return NULL;
114
 
 
115
 
        if (addr->af == AF_INET) {
116
 
                os_snprintf(buf, buflen, "%s", inet_ntoa(addr->u.v4));
117
 
        } else {
118
 
                buf[0] = '\0';
119
 
        }
120
 
#ifdef CONFIG_IPV6
121
 
        if (addr->af == AF_INET6) {
122
 
                if (inet_ntop(AF_INET6, &addr->u.v6, buf, buflen) == NULL)
123
 
                        buf[0] = '\0';
124
 
        }
125
 
#endif /* CONFIG_IPV6 */
126
 
 
127
 
        return buf;
128
 
}
129
 
 
130
 
 
131
 
int hostapd_ip_diff(struct hostapd_ip_addr *a, struct hostapd_ip_addr *b)
132
 
{
133
 
        return 0;
134
 
}
135
 
 
136
 
 
137
 
static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
138
 
                                          const u8 *eap, size_t len)
139
 
{
140
 
        struct radius_msg *msg;
141
 
        char buf[128];
142
 
        const struct eap_hdr *hdr;
143
 
        const u8 *pos;
144
 
 
145
 
        wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
146
 
                   "packet");
147
 
 
148
 
        e->radius_identifier = radius_client_get_id(e->radius);
149
 
        msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
150
 
                             e->radius_identifier);
151
 
        if (msg == NULL) {
152
 
                printf("Could not create net RADIUS packet\n");
153
 
                return;
154
 
        }
155
 
 
156
 
        radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e));
157
 
 
158
 
        hdr = (const struct eap_hdr *) eap;
159
 
        pos = (const u8 *) (hdr + 1);
160
 
        if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE &&
161
 
            pos[0] == EAP_TYPE_IDENTITY) {
162
 
                pos++;
163
 
                os_free(e->eap_identity);
164
 
                e->eap_identity_len = len - sizeof(*hdr) - 1;
165
 
                e->eap_identity = os_malloc(e->eap_identity_len);
166
 
                if (e->eap_identity) {
167
 
                        os_memcpy(e->eap_identity, pos, e->eap_identity_len);
168
 
                        wpa_hexdump(MSG_DEBUG, "Learned identity from "
169
 
                                    "EAP-Response-Identity",
170
 
                                    e->eap_identity, e->eap_identity_len);
171
 
                }
172
 
        }
173
 
 
174
 
        if (e->eap_identity &&
175
 
            !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
176
 
                                 e->eap_identity, e->eap_identity_len)) {
177
 
                printf("Could not add User-Name\n");
178
 
                goto fail;
179
 
        }
180
 
 
181
 
        if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
182
 
                                 (u8 *) &e->own_ip_addr, 4)) {
183
 
                printf("Could not add NAS-IP-Address\n");
184
 
                goto fail;
185
 
        }
186
 
 
187
 
        os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
188
 
                    MAC2STR(e->wpa_s->own_addr));
189
 
        if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
190
 
                                 (u8 *) buf, os_strlen(buf))) {
191
 
                printf("Could not add Calling-Station-Id\n");
192
 
                goto fail;
193
 
        }
194
 
 
195
 
        /* TODO: should probably check MTU from driver config; 2304 is max for
196
 
         * IEEE 802.11, but use 1400 to avoid problems with too large packets
197
 
         */
198
 
        if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
199
 
                printf("Could not add Framed-MTU\n");
200
 
                goto fail;
201
 
        }
202
 
 
203
 
        if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
204
 
                                       RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
205
 
                printf("Could not add NAS-Port-Type\n");
206
 
                goto fail;
207
 
        }
208
 
 
209
 
        os_snprintf(buf, sizeof(buf), "%s", e->connect_info);
210
 
        if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
211
 
                                 (u8 *) buf, os_strlen(buf))) {
212
 
                printf("Could not add Connect-Info\n");
213
 
                goto fail;
214
 
        }
215
 
 
216
 
        if (eap && !radius_msg_add_eap(msg, eap, len)) {
217
 
                printf("Could not add EAP-Message\n");
218
 
                goto fail;
219
 
        }
220
 
 
221
 
        /* State attribute must be copied if and only if this packet is
222
 
         * Access-Request reply to the previous Access-Challenge */
223
 
        if (e->last_recv_radius && e->last_recv_radius->hdr->code ==
224
 
            RADIUS_CODE_ACCESS_CHALLENGE) {
225
 
                int res = radius_msg_copy_attr(msg, e->last_recv_radius,
226
 
                                               RADIUS_ATTR_STATE);
227
 
                if (res < 0) {
228
 
                        printf("Could not copy State attribute from previous "
229
 
                               "Access-Challenge\n");
230
 
                        goto fail;
231
 
                }
232
 
                if (res > 0) {
233
 
                        wpa_printf(MSG_DEBUG, "  Copied RADIUS State "
234
 
                                   "Attribute");
235
 
                }
236
 
        }
237
 
 
238
 
        radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr);
239
 
        return;
240
 
 
241
 
 fail:
242
 
        radius_msg_free(msg);
243
 
        os_free(msg);
244
 
}
245
 
 
246
 
 
247
 
static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf,
248
 
                                 size_t len)
249
 
{
250
 
        /* struct wpa_supplicant *wpa_s = ctx; */
251
 
        printf("WPA: eapol_test_eapol_send(type=%d len=%d)\n", type, len);
252
 
        if (type == IEEE802_1X_TYPE_EAP_PACKET) {
253
 
                wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len);
254
 
                ieee802_1x_encapsulate_radius(&eapol_test, buf, len);
255
 
        }
256
 
        return 0;
257
 
}
258
 
 
259
 
 
260
 
static void eapol_test_set_config_blob(void *ctx,
261
 
                                       struct wpa_config_blob *blob)
262
 
{
263
 
        struct wpa_supplicant *wpa_s = ctx;
264
 
        wpa_config_set_blob(wpa_s->conf, blob);
265
 
}
266
 
 
267
 
 
268
 
static const struct wpa_config_blob *
269
 
eapol_test_get_config_blob(void *ctx, const char *name)
270
 
{
271
 
        struct wpa_supplicant *wpa_s = ctx;
272
 
        return wpa_config_get_blob(wpa_s->conf, name);
273
 
}
274
 
 
275
 
 
276
 
static void eapol_test_eapol_done_cb(void *ctx)
277
 
{
278
 
        printf("WPA: EAPOL processing complete\n");
279
 
}
280
 
 
281
 
 
282
 
static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx)
283
 
{
284
 
        struct eapol_test_data *e = eloop_ctx;
285
 
        printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n");
286
 
        e->radius_access_accept_received = 0;
287
 
        send_eap_request_identity(e->wpa_s, NULL);
288
 
}
289
 
 
290
 
 
291
 
static int eapol_test_compare_pmk(struct eapol_test_data *e)
292
 
{
293
 
        u8 pmk[PMK_LEN];
294
 
        int ret = 1;
295
 
 
296
 
        if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) {
297
 
                wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN);
298
 
                if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) {
299
 
                        printf("WARNING: PMK mismatch\n");
300
 
                        wpa_hexdump(MSG_DEBUG, "PMK from AS",
301
 
                                    e->authenticator_pmk, PMK_LEN);
302
 
                } else if (e->radius_access_accept_received)
303
 
                        ret = 0;
304
 
        } else if (e->authenticator_pmk_len == 16 &&
305
 
                   eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) {
306
 
                wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16);
307
 
                if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) {
308
 
                        printf("WARNING: PMK mismatch\n");
309
 
                        wpa_hexdump(MSG_DEBUG, "PMK from AS",
310
 
                                    e->authenticator_pmk, 16);
311
 
                } else if (e->radius_access_accept_received)
312
 
                        ret = 0;
313
 
        } else if (e->radius_access_accept_received && e->no_mppe_keys) {
314
 
                /* No keying material expected */
315
 
                ret = 0;
316
 
        }
317
 
 
318
 
        if (ret && !e->no_mppe_keys)
319
 
                e->num_mppe_mismatch++;
320
 
        else if (!e->no_mppe_keys)
321
 
                e->num_mppe_ok++;
322
 
 
323
 
        return ret;
324
 
}
325
 
 
326
 
 
327
 
static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx)
328
 
{
329
 
        struct eapol_test_data *e = ctx;
330
 
        printf("eapol_sm_cb: success=%d\n", success);
331
 
        e->eapol_test_num_reauths--;
332
 
        if (e->eapol_test_num_reauths < 0)
333
 
                eloop_terminate();
334
 
        else {
335
 
                eapol_test_compare_pmk(e);
336
 
                eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL);
337
 
        }
338
 
}
339
 
 
340
 
 
341
 
static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
342
 
                      struct wpa_ssid *ssid)
343
 
{
344
 
        struct eapol_config eapol_conf;
345
 
        struct eapol_ctx *ctx;
346
 
 
347
 
        ctx = os_zalloc(sizeof(*ctx));
348
 
        if (ctx == NULL) {
349
 
                printf("Failed to allocate EAPOL context.\n");
350
 
                return -1;
351
 
        }
352
 
        ctx->ctx = wpa_s;
353
 
        ctx->msg_ctx = wpa_s;
354
 
        ctx->scard_ctx = wpa_s->scard;
355
 
        ctx->cb = eapol_sm_cb;
356
 
        ctx->cb_ctx = e;
357
 
        ctx->eapol_send_ctx = wpa_s;
358
 
        ctx->preauth = 0;
359
 
        ctx->eapol_done_cb = eapol_test_eapol_done_cb;
360
 
        ctx->eapol_send = eapol_test_eapol_send;
361
 
        ctx->set_config_blob = eapol_test_set_config_blob;
362
 
        ctx->get_config_blob = eapol_test_get_config_blob;
363
 
        ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
364
 
        ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
365
 
        ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
366
 
 
367
 
        wpa_s->eapol = eapol_sm_init(ctx);
368
 
        if (wpa_s->eapol == NULL) {
369
 
                os_free(ctx);
370
 
                printf("Failed to initialize EAPOL state machines.\n");
371
 
                return -1;
372
 
        }
373
 
 
374
 
        wpa_s->current_ssid = ssid;
375
 
        os_memset(&eapol_conf, 0, sizeof(eapol_conf));
376
 
        eapol_conf.accept_802_1x_keys = 1;
377
 
        eapol_conf.required_keys = 0;
378
 
        eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
379
 
        eapol_conf.workaround = ssid->eap_workaround;
380
 
        eapol_sm_notify_config(wpa_s->eapol, ssid, &eapol_conf);
381
 
        eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
382
 
 
383
 
 
384
 
        eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
385
 
        /* 802.1X::portControl = Auto */
386
 
        eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
387
 
 
388
 
        return 0;
389
 
}
390
 
 
391
 
 
392
 
static void test_eapol_clean(struct eapol_test_data *e,
393
 
                             struct wpa_supplicant *wpa_s)
394
 
{
395
 
        radius_client_deinit(e->radius);
396
 
        os_free(e->last_eap_radius);
397
 
        if (e->last_recv_radius) {
398
 
                radius_msg_free(e->last_recv_radius);
399
 
                os_free(e->last_recv_radius);
400
 
        }
401
 
        os_free(e->eap_identity);
402
 
        e->eap_identity = NULL;
403
 
        eapol_sm_deinit(wpa_s->eapol);
404
 
        wpa_s->eapol = NULL;
405
 
        if (e->radius_conf && e->radius_conf->auth_server) {
406
 
                os_free(e->radius_conf->auth_server->shared_secret);
407
 
                os_free(e->radius_conf->auth_server);
408
 
        }
409
 
        os_free(e->radius_conf);
410
 
        e->radius_conf = NULL;
411
 
        scard_deinit(wpa_s->scard);
412
 
        if (wpa_s->ctrl_iface) {
413
 
                wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
414
 
                wpa_s->ctrl_iface = NULL;
415
 
        }
416
 
        wpa_config_free(wpa_s->conf);
417
 
}
418
 
 
419
 
 
420
 
static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx)
421
 
{
422
 
        struct wpa_supplicant *wpa_s = eloop_ctx;
423
 
        u8 buf[100], *pos;
424
 
        struct ieee802_1x_hdr *hdr;
425
 
        struct eap_hdr *eap;
426
 
 
427
 
        hdr = (struct ieee802_1x_hdr *) buf;
428
 
        hdr->version = EAPOL_VERSION;
429
 
        hdr->type = IEEE802_1X_TYPE_EAP_PACKET;
430
 
        hdr->length = htons(5);
431
 
 
432
 
        eap = (struct eap_hdr *) (hdr + 1);
433
 
        eap->code = EAP_CODE_REQUEST;
434
 
        eap->identifier = 0;
435
 
        eap->length = htons(5);
436
 
        pos = (u8 *) (eap + 1);
437
 
        *pos = EAP_TYPE_IDENTITY;
438
 
 
439
 
        printf("Sending fake EAP-Request-Identity\n");
440
 
        eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf,
441
 
                          sizeof(*hdr) + 5);
442
 
}
443
 
 
444
 
 
445
 
static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx)
446
 
{
447
 
        struct eapol_test_data *e = eloop_ctx;
448
 
        printf("EAPOL test timed out\n");
449
 
        e->auth_timed_out = 1;
450
 
        eloop_terminate();
451
 
}
452
 
 
453
 
 
454
 
static char *eap_type_text(u8 type)
455
 
{
456
 
        switch (type) {
457
 
        case EAP_TYPE_IDENTITY: return "Identity";
458
 
        case EAP_TYPE_NOTIFICATION: return "Notification";
459
 
        case EAP_TYPE_NAK: return "Nak";
460
 
        case EAP_TYPE_TLS: return "TLS";
461
 
        case EAP_TYPE_TTLS: return "TTLS";
462
 
        case EAP_TYPE_PEAP: return "PEAP";
463
 
        case EAP_TYPE_SIM: return "SIM";
464
 
        case EAP_TYPE_GTC: return "GTC";
465
 
        case EAP_TYPE_MD5: return "MD5";
466
 
        case EAP_TYPE_OTP: return "OTP";
467
 
        case EAP_TYPE_FAST: return "FAST";
468
 
        case EAP_TYPE_SAKE: return "SAKE";
469
 
        case EAP_TYPE_PSK: return "PSK";
470
 
        default: return "Unknown";
471
 
        }
472
 
}
473
 
 
474
 
 
475
 
static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
476
 
{
477
 
        u8 *eap;
478
 
        size_t len;
479
 
        struct eap_hdr *hdr;
480
 
        int eap_type = -1;
481
 
        char buf[64];
482
 
        struct radius_msg *msg;
483
 
 
484
 
        if (e->last_recv_radius == NULL)
485
 
                return;
486
 
 
487
 
        msg = e->last_recv_radius;
488
 
 
489
 
        eap = radius_msg_get_eap(msg, &len);
490
 
        if (eap == NULL) {
491
 
                /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
492
 
                 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
493
 
                 * attribute */
494
 
                wpa_printf(MSG_DEBUG, "could not extract "
495
 
                               "EAP-Message from RADIUS message");
496
 
                os_free(e->last_eap_radius);
497
 
                e->last_eap_radius = NULL;
498
 
                e->last_eap_radius_len = 0;
499
 
                return;
500
 
        }
501
 
 
502
 
        if (len < sizeof(*hdr)) {
503
 
                wpa_printf(MSG_DEBUG, "too short EAP packet "
504
 
                               "received from authentication server");
505
 
                os_free(eap);
506
 
                return;
507
 
        }
508
 
 
509
 
        if (len > sizeof(*hdr))
510
 
                eap_type = eap[sizeof(*hdr)];
511
 
 
512
 
        hdr = (struct eap_hdr *) eap;
513
 
        switch (hdr->code) {
514
 
        case EAP_CODE_REQUEST:
515
 
                os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
516
 
                            eap_type >= 0 ? eap_type_text(eap_type) : "??",
517
 
                            eap_type);
518
 
                break;
519
 
        case EAP_CODE_RESPONSE:
520
 
                os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
521
 
                            eap_type >= 0 ? eap_type_text(eap_type) : "??",
522
 
                            eap_type);
523
 
                break;
524
 
        case EAP_CODE_SUCCESS:
525
 
                os_snprintf(buf, sizeof(buf), "EAP Success");
526
 
                /* LEAP uses EAP Success within an authentication, so must not
527
 
                 * stop here with eloop_terminate(); */
528
 
                break;
529
 
        case EAP_CODE_FAILURE:
530
 
                os_snprintf(buf, sizeof(buf), "EAP Failure");
531
 
                eloop_terminate();
532
 
                break;
533
 
        default:
534
 
                os_snprintf(buf, sizeof(buf), "unknown EAP code");
535
 
                wpa_hexdump(MSG_DEBUG, "Decapsulated EAP packet", eap, len);
536
 
                break;
537
 
        }
538
 
        wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d "
539
 
                       "id=%d len=%d) from RADIUS server: %s",
540
 
                      hdr->code, hdr->identifier, ntohs(hdr->length), buf);
541
 
 
542
 
        /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */
543
 
 
544
 
        os_free(e->last_eap_radius);
545
 
        e->last_eap_radius = eap;
546
 
        e->last_eap_radius_len = len;
547
 
 
548
 
        {
549
 
                struct ieee802_1x_hdr *dot1x;
550
 
                dot1x = os_malloc(sizeof(*dot1x) + len);
551
 
                assert(dot1x != NULL);
552
 
                dot1x->version = EAPOL_VERSION;
553
 
                dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
554
 
                dot1x->length = htons(len);
555
 
                os_memcpy((u8 *) (dot1x + 1), eap, len);
556
 
                eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
557
 
                                  (u8 *) dot1x, sizeof(*dot1x) + len);
558
 
                os_free(dot1x);
559
 
        }
560
 
}
561
 
 
562
 
 
563
 
static void ieee802_1x_get_keys(struct eapol_test_data *e,
564
 
                                struct radius_msg *msg, struct radius_msg *req,
565
 
                                u8 *shared_secret, size_t shared_secret_len)
566
 
{
567
 
        struct radius_ms_mppe_keys *keys;
568
 
 
569
 
        keys = radius_msg_get_ms_keys(msg, req, shared_secret,
570
 
                                      shared_secret_len);
571
 
        if (keys && keys->send == NULL && keys->recv == NULL) {
572
 
                os_free(keys);
573
 
                keys = radius_msg_get_cisco_keys(msg, req, shared_secret,
574
 
                                                 shared_secret_len);
575
 
        }
576
 
 
577
 
        if (keys) {
578
 
                if (keys->send) {
579
 
                        wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)",
580
 
                                    keys->send, keys->send_len);
581
 
                }
582
 
                if (keys->recv) {
583
 
                        wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)",
584
 
                                    keys->recv, keys->recv_len);
585
 
                        e->authenticator_pmk_len =
586
 
                                keys->recv_len > PMK_LEN ? PMK_LEN :
587
 
                                keys->recv_len;
588
 
                        os_memcpy(e->authenticator_pmk, keys->recv,
589
 
                                  e->authenticator_pmk_len);
590
 
                }
591
 
 
592
 
                os_free(keys->send);
593
 
                os_free(keys->recv);
594
 
                os_free(keys);
595
 
        }
596
 
}
597
 
 
598
 
 
599
 
/* Process the RADIUS frames from Authentication Server */
600
 
static RadiusRxResult
601
 
ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
602
 
                        u8 *shared_secret, size_t shared_secret_len,
603
 
                        void *data)
604
 
{
605
 
        struct eapol_test_data *e = data;
606
 
 
607
 
        /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
608
 
         * present when packet contains an EAP-Message attribute */
609
 
        if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT &&
610
 
            radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
611
 
                                0) < 0 &&
612
 
            radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
613
 
                wpa_printf(MSG_DEBUG, "Allowing RADIUS "
614
 
                              "Access-Reject without Message-Authenticator "
615
 
                              "since it does not include EAP-Message\n");
616
 
        } else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
617
 
                                     req, 1)) {
618
 
                printf("Incoming RADIUS packet did not have correct "
619
 
                       "Message-Authenticator - dropped\n");
620
 
                return RADIUS_RX_UNKNOWN;
621
 
        }
622
 
 
623
 
        if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
624
 
            msg->hdr->code != RADIUS_CODE_ACCESS_REJECT &&
625
 
            msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
626
 
                printf("Unknown RADIUS message code\n");
627
 
                return RADIUS_RX_UNKNOWN;
628
 
        }
629
 
 
630
 
        e->radius_identifier = -1;
631
 
        wpa_printf(MSG_DEBUG, "RADIUS packet matching with station");
632
 
 
633
 
        if (e->last_recv_radius) {
634
 
                radius_msg_free(e->last_recv_radius);
635
 
                os_free(e->last_recv_radius);
636
 
        }
637
 
 
638
 
        e->last_recv_radius = msg;
639
 
 
640
 
        switch (msg->hdr->code) {
641
 
        case RADIUS_CODE_ACCESS_ACCEPT:
642
 
                e->radius_access_accept_received = 1;
643
 
                ieee802_1x_get_keys(e, msg, req, shared_secret,
644
 
                                    shared_secret_len);
645
 
                break;
646
 
        case RADIUS_CODE_ACCESS_REJECT:
647
 
                e->radius_access_reject_received = 1;
648
 
                break;
649
 
        }
650
 
 
651
 
        ieee802_1x_decapsulate_radius(e);
652
 
 
653
 
        if ((msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
654
 
             e->eapol_test_num_reauths < 0) ||
655
 
            msg->hdr->code == RADIUS_CODE_ACCESS_REJECT) {
656
 
                eloop_terminate();
657
 
        }
658
 
 
659
 
        return RADIUS_RX_QUEUED;
660
 
}
661
 
 
662
 
 
663
 
static void wpa_init_conf(struct eapol_test_data *e,
664
 
                          struct wpa_supplicant *wpa_s, const char *authsrv,
665
 
                          int port, const char *secret)
666
 
{
667
 
        struct hostapd_radius_server *as;
668
 
        int res;
669
 
 
670
 
        wpa_s->bssid[5] = 1;
671
 
        os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN);
672
 
        e->own_ip_addr.s_addr = htonl((127 << 24) | 1);
673
 
        os_strncpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname));
674
 
 
675
 
        e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers));
676
 
        assert(e->radius_conf != NULL);
677
 
        e->radius_conf->num_auth_servers = 1;
678
 
        as = os_zalloc(sizeof(struct hostapd_radius_server));
679
 
        assert(as != NULL);
680
 
#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
681
 
        {
682
 
                int a[4];
683
 
                u8 *pos;
684
 
                sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
685
 
                pos = (u8 *) &as->addr.u.v4;
686
 
                *pos++ = a[0];
687
 
                *pos++ = a[1];
688
 
                *pos++ = a[2];
689
 
                *pos++ = a[3];
690
 
        }
691
 
#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
692
 
        inet_aton(authsrv, &as->addr.u.v4);
693
 
#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
694
 
        as->addr.af = AF_INET;
695
 
        as->port = port;
696
 
        as->shared_secret = (u8 *) os_strdup(secret);
697
 
        as->shared_secret_len = os_strlen(secret);
698
 
        e->radius_conf->auth_server = as;
699
 
        e->radius_conf->auth_servers = as;
700
 
        e->radius_conf->msg_dumps = 1;
701
 
 
702
 
        e->radius = radius_client_init(wpa_s, e->radius_conf);
703
 
        assert(e->radius != NULL);
704
 
 
705
 
        res = radius_client_register(e->radius, RADIUS_AUTH,
706
 
                                     ieee802_1x_receive_auth, e);
707
 
        assert(res == 0);
708
 
}
709
 
 
710
 
 
711
 
static int scard_test(void)
712
 
{
713
 
        struct scard_data *scard;
714
 
        size_t len;
715
 
        char imsi[20];
716
 
        unsigned char _rand[16];
717
 
#ifdef PCSC_FUNCS
718
 
        unsigned char sres[4];
719
 
        unsigned char kc[8];
720
 
#endif /* PCSC_FUNCS */
721
 
#define num_triplets 5
722
 
        unsigned char rand_[num_triplets][16];
723
 
        unsigned char sres_[num_triplets][4];
724
 
        unsigned char kc_[num_triplets][8];
725
 
        int i, res;
726
 
        size_t j;
727
 
 
728
 
#define AKA_RAND_LEN 16
729
 
#define AKA_AUTN_LEN 16
730
 
#define AKA_AUTS_LEN 14
731
 
#define RES_MAX_LEN 16
732
 
#define IK_LEN 16
733
 
#define CK_LEN 16
734
 
        unsigned char aka_rand[AKA_RAND_LEN];
735
 
        unsigned char aka_autn[AKA_AUTN_LEN];
736
 
        unsigned char aka_auts[AKA_AUTS_LEN];
737
 
        unsigned char aka_res[RES_MAX_LEN];
738
 
        size_t aka_res_len;
739
 
        unsigned char aka_ik[IK_LEN];
740
 
        unsigned char aka_ck[CK_LEN];
741
 
 
742
 
        scard = scard_init(SCARD_TRY_BOTH);
743
 
        if (scard == NULL)
744
 
                return -1;
745
 
        if (scard_set_pin(scard, "1234")) {
746
 
                wpa_printf(MSG_WARNING, "PIN validation failed");
747
 
                scard_deinit(scard);
748
 
                return -1;
749
 
        }
750
 
 
751
 
        len = sizeof(imsi);
752
 
        if (scard_get_imsi(scard, imsi, &len))
753
 
                goto failed;
754
 
        wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len);
755
 
        /* NOTE: Permanent Username: 1 | IMSI */
756
 
 
757
 
        os_memset(_rand, 0, sizeof(_rand));
758
 
        if (scard_gsm_auth(scard, _rand, sres, kc))
759
 
                goto failed;
760
 
 
761
 
        os_memset(_rand, 0xff, sizeof(_rand));
762
 
        if (scard_gsm_auth(scard, _rand, sres, kc))
763
 
                goto failed;
764
 
 
765
 
        for (i = 0; i < num_triplets; i++) {
766
 
                os_memset(rand_[i], i, sizeof(rand_[i]));
767
 
                if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i]))
768
 
                        goto failed;
769
 
        }
770
 
 
771
 
        for (i = 0; i < num_triplets; i++) {
772
 
                printf("1");
773
 
                for (j = 0; j < len; j++)
774
 
                        printf("%c", imsi[j]);
775
 
                printf(",");
776
 
                for (j = 0; j < 16; j++)
777
 
                        printf("%02X", rand_[i][j]);
778
 
                printf(",");
779
 
                for (j = 0; j < 4; j++)
780
 
                        printf("%02X", sres_[i][j]);
781
 
                printf(",");
782
 
                for (j = 0; j < 8; j++)
783
 
                        printf("%02X", kc_[i][j]);
784
 
                printf("\n");
785
 
        }
786
 
 
787
 
        wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication");
788
 
 
789
 
        /* seq 39 (0x28) */
790
 
        os_memset(aka_rand, 0xaa, 16);
791
 
        os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf"
792
 
                  "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16);
793
 
 
794
 
        res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len,
795
 
                              aka_ik, aka_ck, aka_auts);
796
 
        if (res == 0) {
797
 
                wpa_printf(MSG_DEBUG, "UMTS auth completed successfully");
798
 
                wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len);
799
 
                wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN);
800
 
                wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN);
801
 
        } else if (res == -2) {
802
 
                wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization "
803
 
                           "failure");
804
 
                wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN);
805
 
        } else {
806
 
                wpa_printf(MSG_DEBUG, "UMTS auth failed");
807
 
        }
808
 
 
809
 
failed:
810
 
        scard_deinit(scard);
811
 
 
812
 
        return 0;
813
 
#undef num_triplets
814
 
}
815
 
 
816
 
 
817
 
static int scard_get_triplets(int argc, char *argv[])
818
 
{
819
 
        struct scard_data *scard;
820
 
        size_t len;
821
 
        char imsi[20];
822
 
        unsigned char _rand[16];
823
 
        unsigned char sres[4];
824
 
        unsigned char kc[8];
825
 
        int num_triplets;
826
 
        int i;
827
 
        size_t j;
828
 
 
829
 
        if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) {
830
 
                printf("invalid parameters for sim command\n");
831
 
                return -1;
832
 
        }
833
 
 
834
 
        if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) {
835
 
                /* disable debug output */
836
 
                wpa_debug_level = 99;
837
 
        }
838
 
 
839
 
        scard = scard_init(SCARD_GSM_SIM_ONLY);
840
 
        if (scard == NULL) {
841
 
                printf("Failed to open smartcard connection\n");
842
 
                return -1;
843
 
        }
844
 
        if (scard_set_pin(scard, argv[0])) {
845
 
                wpa_printf(MSG_WARNING, "PIN validation failed");
846
 
                scard_deinit(scard);
847
 
                return -1;
848
 
        }
849
 
 
850
 
        len = sizeof(imsi);
851
 
        if (scard_get_imsi(scard, imsi, &len)) {
852
 
                scard_deinit(scard);
853
 
                return -1;
854
 
        }
855
 
 
856
 
        for (i = 0; i < num_triplets; i++) {
857
 
                os_memset(_rand, i, sizeof(_rand));
858
 
                if (scard_gsm_auth(scard, _rand, sres, kc))
859
 
                        break;
860
 
 
861
 
                /* IMSI:Kc:SRES:RAND */
862
 
                for (j = 0; j < len; j++)
863
 
                        printf("%c", imsi[j]);
864
 
                printf(":");
865
 
                for (j = 0; j < 8; j++)
866
 
                        printf("%02X", kc[j]);
867
 
                printf(":");
868
 
                for (j = 0; j < 4; j++)
869
 
                        printf("%02X", sres[j]);
870
 
                printf(":");
871
 
                for (j = 0; j < 16; j++)
872
 
                        printf("%02X", _rand[j]);
873
 
                printf("\n");
874
 
        }
875
 
 
876
 
        scard_deinit(scard);
877
 
 
878
 
        return 0;
879
 
}
880
 
 
881
 
 
882
 
static void eapol_test_terminate(int sig, void *eloop_ctx,
883
 
                                 void *signal_ctx)
884
 
{
885
 
        struct wpa_supplicant *wpa_s = eloop_ctx;
886
 
        wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig);
887
 
        eloop_terminate();
888
 
}
889
 
 
890
 
 
891
 
static void usage(void)
892
 
{
893
 
        printf("usage:\n"
894
 
               "eapol_test [-nWS] -c<conf> [-a<AS IP>] [-p<AS port>] "
895
 
               "[-s<AS secret>] \\\n"
896
 
               "           [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
897
 
               "           [-M<client MAC address>]\n"
898
 
               "eapol_test scard\n"
899
 
               "eapol_test sim <PIN> <num triplets> [debug]\n"
900
 
               "\n");
901
 
        printf("options:\n"
902
 
               "  -c<conf> = configuration file\n"
903
 
               "  -a<AS IP> = IP address of the authentication server, "
904
 
               "default 127.0.0.1\n"
905
 
               "  -p<AS port> = UDP port of the authentication server, "
906
 
               "default 1812\n"
907
 
               "  -s<AS secret> = shared secret with the authentication "
908
 
               "server, default 'radius'\n"
909
 
               "  -r<count> = number of re-authentications\n"
910
 
               "  -W = wait for a control interface monitor before starting\n"
911
 
               "  -S = save configuration after authentiation\n"
912
 
               "  -n = no MPPE keys expected\n"
913
 
               "  -t<timeout> = sets timeout in seconds (default: 30 s)\n"
914
 
               "  -C<Connect-Info> = RADIUS Connect-Info (default: "
915
 
               "CONNECT 11Mbps 802.11b)\n"
916
 
               "  -M<client MAC address> = Set own MAC address "
917
 
               "(Calling-Station-Id,\n"
918
 
               "                           default: 02:00:00:00:00:01)\n");
919
 
}
920
 
 
921
 
 
922
 
int main(int argc, char *argv[])
923
 
{
924
 
        struct wpa_supplicant wpa_s;
925
 
        int c, ret = 1, wait_for_monitor = 0, save_config = 0;
926
 
        char *as_addr = "127.0.0.1";
927
 
        int as_port = 1812;
928
 
        char *as_secret = "radius";
929
 
        char *conf = NULL;
930
 
        int timeout = 30;
931
 
 
932
 
        if (os_program_init())
933
 
                return -1;
934
 
 
935
 
        os_memset(&eapol_test, 0, sizeof(eapol_test));
936
 
        eapol_test.connect_info = "CONNECT 11Mbps 802.11b";
937
 
        os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN);
938
 
 
939
 
        wpa_debug_level = 0;
940
 
        wpa_debug_show_keys = 1;
941
 
 
942
 
        for (;;) {
943
 
                c = getopt(argc, argv, "a:c:C:M:np:r:s:St:W");
944
 
                if (c < 0)
945
 
                        break;
946
 
                switch (c) {
947
 
                case 'a':
948
 
                        as_addr = optarg;
949
 
                        break;
950
 
                case 'c':
951
 
                        conf = optarg;
952
 
                        break;
953
 
                case 'C':
954
 
                        eapol_test.connect_info = optarg;
955
 
                        break;
956
 
                case 'M':
957
 
                        if (hwaddr_aton(optarg, eapol_test.own_addr)) {
958
 
                                usage();
959
 
                                return -1;
960
 
                        }
961
 
                        break;
962
 
                case 'n':
963
 
                        eapol_test.no_mppe_keys++;
964
 
                        break;
965
 
                case 'p':
966
 
                        as_port = atoi(optarg);
967
 
                        break;
968
 
                case 'r':
969
 
                        eapol_test.eapol_test_num_reauths = atoi(optarg);
970
 
                        break;
971
 
                case 's':
972
 
                        as_secret = optarg;
973
 
                        break;
974
 
                case 'S':
975
 
                        save_config++;
976
 
                        break;
977
 
                case 't':
978
 
                        timeout = atoi(optarg);
979
 
                        break;
980
 
                case 'W':
981
 
                        wait_for_monitor++;
982
 
                        break;
983
 
                default:
984
 
                        usage();
985
 
                        return -1;
986
 
                }
987
 
        }
988
 
 
989
 
        if (argc > optind && os_strcmp(argv[optind], "scard") == 0) {
990
 
                return scard_test();
991
 
        }
992
 
 
993
 
        if (argc > optind && os_strcmp(argv[optind], "sim") == 0) {
994
 
                return scard_get_triplets(argc - optind - 1,
995
 
                                          &argv[optind + 1]);
996
 
        }
997
 
 
998
 
        if (conf == NULL) {
999
 
                usage();
1000
 
                printf("Configuration file is required.\n");
1001
 
                return -1;
1002
 
        }
1003
 
 
1004
 
        if (eap_peer_register_methods()) {
1005
 
                wpa_printf(MSG_ERROR, "Failed to register EAP methods");
1006
 
                return -1;
1007
 
        }
1008
 
 
1009
 
        if (eloop_init(&wpa_s)) {
1010
 
                wpa_printf(MSG_ERROR, "Failed to initialize event loop");
1011
 
                return -1;
1012
 
        }
1013
 
 
1014
 
        os_memset(&wpa_s, 0, sizeof(wpa_s));
1015
 
        eapol_test.wpa_s = &wpa_s;
1016
 
        wpa_s.conf = wpa_config_read(conf);
1017
 
        if (wpa_s.conf == NULL) {
1018
 
                printf("Failed to parse configuration file '%s'.\n", conf);
1019
 
                return -1;
1020
 
        }
1021
 
        if (wpa_s.conf->ssid == NULL) {
1022
 
                printf("No networks defined.\n");
1023
 
                return -1;
1024
 
        }
1025
 
 
1026
 
        wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret);
1027
 
        wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s);
1028
 
        if (wpa_s.ctrl_iface == NULL) {
1029
 
                printf("Failed to initialize control interface '%s'.\n"
1030
 
                       "You may have another eapol_test process already "
1031
 
                       "running or the file was\n"
1032
 
                       "left by an unclean termination of eapol_test in "
1033
 
                       "which case you will need\n"
1034
 
                       "to manually remove this file before starting "
1035
 
                       "eapol_test again.\n",
1036
 
                       wpa_s.conf->ctrl_interface);
1037
 
                return -1;
1038
 
        }
1039
 
        if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid))
1040
 
                return -1;
1041
 
 
1042
 
        if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid))
1043
 
                return -1;
1044
 
 
1045
 
        if (wait_for_monitor)
1046
 
                wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface);
1047
 
 
1048
 
        eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test,
1049
 
                               NULL);
1050
 
        eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL);
1051
 
        eloop_register_signal_terminate(eapol_test_terminate, NULL);
1052
 
        eloop_register_signal_reconfig(eapol_test_terminate, NULL);
1053
 
        eloop_run();
1054
 
 
1055
 
        if (eapol_test_compare_pmk(&eapol_test) == 0 ||
1056
 
            eapol_test.no_mppe_keys)
1057
 
                ret = 0;
1058
 
        if (eapol_test.auth_timed_out)
1059
 
                ret = -2;
1060
 
        if (eapol_test.radius_access_reject_received)
1061
 
                ret = -3;
1062
 
 
1063
 
        if (save_config)
1064
 
                wpa_config_write(conf, wpa_s.conf);
1065
 
 
1066
 
        test_eapol_clean(&eapol_test, &wpa_s);
1067
 
 
1068
 
        eap_peer_unregister_methods();
1069
 
 
1070
 
        eloop_destroy();
1071
 
 
1072
 
        printf("MPPE keys OK: %d  mismatch: %d\n",
1073
 
               eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch);
1074
 
        if (eapol_test.num_mppe_mismatch)
1075
 
                ret = -4;
1076
 
        if (ret)
1077
 
                printf("FAILURE\n");
1078
 
        else
1079
 
                printf("SUCCESS\n");
1080
 
 
1081
 
        os_program_deinit();
1082
 
 
1083
 
        return ret;
1084
 
}