1 /* 2 * WPA Supplicant - test code 3 * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 * 8 * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c. 9 * Not used in production version. 10 */ 11 12 #include "includes.h" 13 #include <assert.h> 14 15 #include "common.h" 16 #include "utils/ext_password.h" 17 #include "config.h" 18 #include "eapol_supp/eapol_supp_sm.h" 19 #include "eap_peer/eap.h" 20 #include "eap_server/eap_methods.h" 21 #include "eloop.h" 22 #include "utils/base64.h" 23 #include "rsn_supp/wpa.h" 24 #include "wpa_supplicant_i.h" 25 #include "radius/radius.h" 26 #include "radius/radius_client.h" 27 #include "common/wpa_ctrl.h" 28 #include "ctrl_iface.h" 29 #include "pcsc_funcs.h" 30 #include "wpas_glue.h" 31 32 33 struct wpa_driver_ops *wpa_drivers[] = { NULL }; 34 35 36 struct extra_radius_attr { 37 u8 type; 38 char syntax; 39 char *data; 40 struct extra_radius_attr *next; 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 /* last received EAP Response from Authentication Server */ 57 struct wpabuf *last_eap_radius; 58 59 u8 authenticator_pmk[PMK_LEN]; 60 size_t authenticator_pmk_len; 61 int radius_access_accept_received; 62 int radius_access_reject_received; 63 int auth_timed_out; 64 65 u8 *eap_identity; 66 size_t eap_identity_len; 67 68 char *connect_info; 69 u8 own_addr[ETH_ALEN]; 70 struct extra_radius_attr *extra_attrs; 71 72 FILE *server_cert_file; 73 }; 74 75 static struct eapol_test_data eapol_test; 76 77 78 static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx); 79 80 81 static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 82 int level, const char *txt, size_t len) 83 { 84 if (addr) 85 wpa_printf(MSG_DEBUG, "STA " MACSTR ": %s\n", 86 MAC2STR(addr), txt); 87 else 88 wpa_printf(MSG_DEBUG, "%s", txt); 89 } 90 91 92 static int add_extra_attr(struct radius_msg *msg, 93 struct extra_radius_attr *attr) 94 { 95 size_t len; 96 char *pos; 97 u32 val; 98 char buf[RADIUS_MAX_ATTR_LEN + 1]; 99 100 switch (attr->syntax) { 101 case 's': 102 os_snprintf(buf, sizeof(buf), "%s", attr->data); 103 len = os_strlen(buf); 104 break; 105 case 'n': 106 buf[0] = '\0'; 107 len = 1; 108 break; 109 case 'x': 110 pos = attr->data; 111 if (pos[0] == '0' && pos[1] == 'x') 112 pos += 2; 113 len = os_strlen(pos); 114 if ((len & 1) || (len / 2) > RADIUS_MAX_ATTR_LEN) { 115 printf("Invalid extra attribute hexstring\n"); 116 return -1; 117 } 118 len /= 2; 119 if (hexstr2bin(pos, (u8 *) buf, len) < 0) { 120 printf("Invalid extra attribute hexstring\n"); 121 return -1; 122 } 123 break; 124 case 'd': 125 val = htonl(atoi(attr->data)); 126 os_memcpy(buf, &val, 4); 127 len = 4; 128 break; 129 default: 130 printf("Incorrect extra attribute syntax specification\n"); 131 return -1; 132 } 133 134 if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) { 135 printf("Could not add attribute %d\n", attr->type); 136 return -1; 137 } 138 139 return 0; 140 } 141 142 143 static int add_extra_attrs(struct radius_msg *msg, 144 struct extra_radius_attr *attrs) 145 { 146 struct extra_radius_attr *p; 147 for (p = attrs; p; p = p->next) { 148 if (add_extra_attr(msg, p) < 0) 149 return -1; 150 } 151 return 0; 152 } 153 154 155 static struct extra_radius_attr * 156 find_extra_attr(struct extra_radius_attr *attrs, u8 type) 157 { 158 struct extra_radius_attr *p; 159 for (p = attrs; p; p = p->next) { 160 if (p->type == type) 161 return p; 162 } 163 return NULL; 164 } 165 166 167 static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, 168 const u8 *eap, size_t len) 169 { 170 struct radius_msg *msg; 171 char buf[RADIUS_MAX_ATTR_LEN + 1]; 172 const struct eap_hdr *hdr; 173 const u8 *pos; 174 175 wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 176 "packet"); 177 178 e->radius_identifier = radius_client_get_id(e->radius); 179 msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 180 e->radius_identifier); 181 if (msg == NULL) { 182 printf("Could not create net RADIUS packet\n"); 183 return; 184 } 185 186 radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e)); 187 188 hdr = (const struct eap_hdr *) eap; 189 pos = (const u8 *) (hdr + 1); 190 if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE && 191 pos[0] == EAP_TYPE_IDENTITY) { 192 pos++; 193 os_free(e->eap_identity); 194 e->eap_identity_len = len - sizeof(*hdr) - 1; 195 e->eap_identity = os_malloc(e->eap_identity_len); 196 if (e->eap_identity) { 197 os_memcpy(e->eap_identity, pos, e->eap_identity_len); 198 wpa_hexdump(MSG_DEBUG, "Learned identity from " 199 "EAP-Response-Identity", 200 e->eap_identity, e->eap_identity_len); 201 } 202 } 203 204 if (e->eap_identity && 205 !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 206 e->eap_identity, e->eap_identity_len)) { 207 printf("Could not add User-Name\n"); 208 goto fail; 209 } 210 211 if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) && 212 !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 213 (u8 *) &e->own_ip_addr, 4)) { 214 printf("Could not add NAS-IP-Address\n"); 215 goto fail; 216 } 217 218 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 219 MAC2STR(e->wpa_s->own_addr)); 220 if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID) 221 && 222 !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 223 (u8 *) buf, os_strlen(buf))) { 224 printf("Could not add Calling-Station-Id\n"); 225 goto fail; 226 } 227 228 /* TODO: should probably check MTU from driver config; 2304 is max for 229 * IEEE 802.11, but use 1400 to avoid problems with too large packets 230 */ 231 if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) && 232 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 233 printf("Could not add Framed-MTU\n"); 234 goto fail; 235 } 236 237 if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_PORT_TYPE) && 238 !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 239 RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 240 printf("Could not add NAS-Port-Type\n"); 241 goto fail; 242 } 243 244 os_snprintf(buf, sizeof(buf), "%s", e->connect_info); 245 if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CONNECT_INFO) && 246 !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 247 (u8 *) buf, os_strlen(buf))) { 248 printf("Could not add Connect-Info\n"); 249 goto fail; 250 } 251 252 if (add_extra_attrs(msg, e->extra_attrs) < 0) 253 goto fail; 254 255 if (eap && !radius_msg_add_eap(msg, eap, len)) { 256 printf("Could not add EAP-Message\n"); 257 goto fail; 258 } 259 260 /* State attribute must be copied if and only if this packet is 261 * Access-Request reply to the previous Access-Challenge */ 262 if (e->last_recv_radius && 263 radius_msg_get_hdr(e->last_recv_radius)->code == 264 RADIUS_CODE_ACCESS_CHALLENGE) { 265 int res = radius_msg_copy_attr(msg, e->last_recv_radius, 266 RADIUS_ATTR_STATE); 267 if (res < 0) { 268 printf("Could not copy State attribute from previous " 269 "Access-Challenge\n"); 270 goto fail; 271 } 272 if (res > 0) { 273 wpa_printf(MSG_DEBUG, " Copied RADIUS State " 274 "Attribute"); 275 } 276 } 277 278 if (radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr) 279 < 0) 280 goto fail; 281 return; 282 283 fail: 284 radius_msg_free(msg); 285 } 286 287 288 static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, 289 size_t len) 290 { 291 printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n", 292 type, (unsigned long) len); 293 if (type == IEEE802_1X_TYPE_EAP_PACKET) { 294 wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len); 295 ieee802_1x_encapsulate_radius(&eapol_test, buf, len); 296 } 297 return 0; 298 } 299 300 301 static void eapol_test_set_config_blob(void *ctx, 302 struct wpa_config_blob *blob) 303 { 304 struct eapol_test_data *e = ctx; 305 wpa_config_set_blob(e->wpa_s->conf, blob); 306 } 307 308 309 static const struct wpa_config_blob * 310 eapol_test_get_config_blob(void *ctx, const char *name) 311 { 312 struct eapol_test_data *e = ctx; 313 return wpa_config_get_blob(e->wpa_s->conf, name); 314 } 315 316 317 static void eapol_test_eapol_done_cb(void *ctx) 318 { 319 printf("WPA: EAPOL processing complete\n"); 320 } 321 322 323 static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx) 324 { 325 struct eapol_test_data *e = eloop_ctx; 326 printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n"); 327 e->radius_access_accept_received = 0; 328 send_eap_request_identity(e->wpa_s, NULL); 329 } 330 331 332 static int eapol_test_compare_pmk(struct eapol_test_data *e) 333 { 334 u8 pmk[PMK_LEN]; 335 int ret = 1; 336 337 if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) { 338 wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN); 339 if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) { 340 printf("WARNING: PMK mismatch\n"); 341 wpa_hexdump(MSG_DEBUG, "PMK from AS", 342 e->authenticator_pmk, PMK_LEN); 343 } else if (e->radius_access_accept_received) 344 ret = 0; 345 } else if (e->authenticator_pmk_len == 16 && 346 eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) { 347 wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16); 348 if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) { 349 printf("WARNING: PMK mismatch\n"); 350 wpa_hexdump(MSG_DEBUG, "PMK from AS", 351 e->authenticator_pmk, 16); 352 } else if (e->radius_access_accept_received) 353 ret = 0; 354 } else if (e->radius_access_accept_received && e->no_mppe_keys) { 355 /* No keying material expected */ 356 ret = 0; 357 } 358 359 if (ret && !e->no_mppe_keys) 360 e->num_mppe_mismatch++; 361 else if (!e->no_mppe_keys) 362 e->num_mppe_ok++; 363 364 return ret; 365 } 366 367 368 static void eapol_sm_cb(struct eapol_sm *eapol, enum eapol_supp_result result, 369 void *ctx) 370 { 371 struct eapol_test_data *e = ctx; 372 printf("eapol_sm_cb: result=%d\n", result); 373 e->eapol_test_num_reauths--; 374 if (e->eapol_test_num_reauths < 0) 375 eloop_terminate(); 376 else { 377 eapol_test_compare_pmk(e); 378 eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL); 379 } 380 } 381 382 383 static void eapol_test_write_cert(FILE *f, const char *subject, 384 const struct wpabuf *cert) 385 { 386 unsigned char *encoded; 387 388 encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL); 389 if (encoded == NULL) 390 return; 391 fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s" 392 "-----END CERTIFICATE-----\n\n", subject, encoded); 393 os_free(encoded); 394 } 395 396 397 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) 398 static void eapol_test_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field, 399 const char *default_txt) 400 { 401 struct eapol_test_data *e = ctx; 402 struct wpa_supplicant *wpa_s = e->wpa_s; 403 struct wpa_ssid *ssid = wpa_s->current_ssid; 404 const char *field_name, *txt = NULL; 405 char *buf; 406 size_t buflen; 407 int len; 408 409 if (ssid == NULL) 410 return; 411 412 field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt, 413 &txt); 414 if (field_name == NULL) { 415 wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed", 416 field); 417 return; 418 } 419 420 buflen = 100 + os_strlen(txt) + ssid->ssid_len; 421 buf = os_malloc(buflen); 422 if (buf == NULL) 423 return; 424 len = os_snprintf(buf, buflen, 425 WPA_CTRL_REQ "%s-%d:%s needed for SSID ", 426 field_name, ssid->id, txt); 427 if (len < 0 || (size_t) len >= buflen) { 428 os_free(buf); 429 return; 430 } 431 if (ssid->ssid && buflen > len + ssid->ssid_len) { 432 os_memcpy(buf + len, ssid->ssid, ssid->ssid_len); 433 len += ssid->ssid_len; 434 buf[len] = '\0'; 435 } 436 buf[buflen - 1] = '\0'; 437 wpa_msg(wpa_s, MSG_INFO, "%s", buf); 438 os_free(buf); 439 } 440 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 441 #define eapol_test_eap_param_needed NULL 442 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ 443 444 445 static void eapol_test_cert_cb(void *ctx, int depth, const char *subject, 446 const char *cert_hash, 447 const struct wpabuf *cert) 448 { 449 struct eapol_test_data *e = ctx; 450 451 wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT 452 "depth=%d subject='%s'%s%s", 453 depth, subject, 454 cert_hash ? " hash=" : "", 455 cert_hash ? cert_hash : ""); 456 457 if (cert) { 458 char *cert_hex; 459 size_t len = wpabuf_len(cert) * 2 + 1; 460 cert_hex = os_malloc(len); 461 if (cert_hex) { 462 wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), 463 wpabuf_len(cert)); 464 wpa_msg_ctrl(e->wpa_s, MSG_INFO, 465 WPA_EVENT_EAP_PEER_CERT 466 "depth=%d subject='%s' cert=%s", 467 depth, subject, cert_hex); 468 os_free(cert_hex); 469 } 470 471 if (e->server_cert_file) 472 eapol_test_write_cert(e->server_cert_file, 473 subject, cert); 474 } 475 } 476 477 478 static void eapol_test_set_anon_id(void *ctx, const u8 *id, size_t len) 479 { 480 struct eapol_test_data *e = ctx; 481 struct wpa_supplicant *wpa_s = e->wpa_s; 482 char *str; 483 int res; 484 485 wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity", 486 id, len); 487 488 if (wpa_s->current_ssid == NULL) 489 return; 490 491 if (id == NULL) { 492 if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 493 "NULL", 0) < 0) 494 return; 495 } else { 496 str = os_malloc(len * 2 + 1); 497 if (str == NULL) 498 return; 499 wpa_snprintf_hex(str, len * 2 + 1, id, len); 500 res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 501 str, 0); 502 os_free(str); 503 if (res < 0) 504 return; 505 } 506 } 507 508 509 static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, 510 struct wpa_ssid *ssid) 511 { 512 struct eapol_config eapol_conf; 513 struct eapol_ctx *ctx; 514 515 ctx = os_zalloc(sizeof(*ctx)); 516 if (ctx == NULL) { 517 printf("Failed to allocate EAPOL context.\n"); 518 return -1; 519 } 520 ctx->ctx = e; 521 ctx->msg_ctx = wpa_s; 522 ctx->scard_ctx = wpa_s->scard; 523 ctx->cb = eapol_sm_cb; 524 ctx->cb_ctx = e; 525 ctx->eapol_send_ctx = wpa_s; 526 ctx->preauth = 0; 527 ctx->eapol_done_cb = eapol_test_eapol_done_cb; 528 ctx->eapol_send = eapol_test_eapol_send; 529 ctx->set_config_blob = eapol_test_set_config_blob; 530 ctx->get_config_blob = eapol_test_get_config_blob; 531 ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 532 ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 533 ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 534 ctx->eap_param_needed = eapol_test_eap_param_needed; 535 ctx->cert_cb = eapol_test_cert_cb; 536 ctx->cert_in_cb = 1; 537 ctx->set_anon_id = eapol_test_set_anon_id; 538 539 wpa_s->eapol = eapol_sm_init(ctx); 540 if (wpa_s->eapol == NULL) { 541 os_free(ctx); 542 printf("Failed to initialize EAPOL state machines.\n"); 543 return -1; 544 } 545 546 wpa_s->current_ssid = ssid; 547 os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 548 eapol_conf.accept_802_1x_keys = 1; 549 eapol_conf.required_keys = 0; 550 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; 551 eapol_conf.workaround = ssid->eap_workaround; 552 eapol_conf.external_sim = wpa_s->conf->external_sim; 553 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); 554 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 555 556 557 eapol_sm_notify_portValid(wpa_s->eapol, FALSE); 558 /* 802.1X::portControl = Auto */ 559 eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); 560 561 return 0; 562 } 563 564 565 static void test_eapol_clean(struct eapol_test_data *e, 566 struct wpa_supplicant *wpa_s) 567 { 568 struct extra_radius_attr *p, *prev; 569 570 radius_client_deinit(e->radius); 571 wpabuf_free(e->last_eap_radius); 572 radius_msg_free(e->last_recv_radius); 573 e->last_recv_radius = NULL; 574 os_free(e->eap_identity); 575 e->eap_identity = NULL; 576 eapol_sm_deinit(wpa_s->eapol); 577 wpa_s->eapol = NULL; 578 if (e->radius_conf && e->radius_conf->auth_server) { 579 os_free(e->radius_conf->auth_server->shared_secret); 580 os_free(e->radius_conf->auth_server); 581 } 582 os_free(e->radius_conf); 583 e->radius_conf = NULL; 584 scard_deinit(wpa_s->scard); 585 if (wpa_s->ctrl_iface) { 586 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); 587 wpa_s->ctrl_iface = NULL; 588 } 589 590 ext_password_deinit(wpa_s->ext_pw); 591 wpa_s->ext_pw = NULL; 592 593 wpa_config_free(wpa_s->conf); 594 595 p = e->extra_attrs; 596 while (p) { 597 prev = p; 598 p = p->next; 599 os_free(prev); 600 } 601 } 602 603 604 static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) 605 { 606 struct wpa_supplicant *wpa_s = eloop_ctx; 607 u8 buf[100], *pos; 608 struct ieee802_1x_hdr *hdr; 609 struct eap_hdr *eap; 610 611 hdr = (struct ieee802_1x_hdr *) buf; 612 hdr->version = EAPOL_VERSION; 613 hdr->type = IEEE802_1X_TYPE_EAP_PACKET; 614 hdr->length = htons(5); 615 616 eap = (struct eap_hdr *) (hdr + 1); 617 eap->code = EAP_CODE_REQUEST; 618 eap->identifier = 0; 619 eap->length = htons(5); 620 pos = (u8 *) (eap + 1); 621 *pos = EAP_TYPE_IDENTITY; 622 623 printf("Sending fake EAP-Request-Identity\n"); 624 eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf, 625 sizeof(*hdr) + 5); 626 } 627 628 629 static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 630 { 631 struct eapol_test_data *e = eloop_ctx; 632 printf("EAPOL test timed out\n"); 633 e->auth_timed_out = 1; 634 eloop_terminate(); 635 } 636 637 638 static char *eap_type_text(u8 type) 639 { 640 switch (type) { 641 case EAP_TYPE_IDENTITY: return "Identity"; 642 case EAP_TYPE_NOTIFICATION: return "Notification"; 643 case EAP_TYPE_NAK: return "Nak"; 644 case EAP_TYPE_TLS: return "TLS"; 645 case EAP_TYPE_TTLS: return "TTLS"; 646 case EAP_TYPE_PEAP: return "PEAP"; 647 case EAP_TYPE_SIM: return "SIM"; 648 case EAP_TYPE_GTC: return "GTC"; 649 case EAP_TYPE_MD5: return "MD5"; 650 case EAP_TYPE_OTP: return "OTP"; 651 case EAP_TYPE_FAST: return "FAST"; 652 case EAP_TYPE_SAKE: return "SAKE"; 653 case EAP_TYPE_PSK: return "PSK"; 654 default: return "Unknown"; 655 } 656 } 657 658 659 static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) 660 { 661 struct wpabuf *eap; 662 const struct eap_hdr *hdr; 663 int eap_type = -1; 664 char buf[64]; 665 struct radius_msg *msg; 666 667 if (e->last_recv_radius == NULL) 668 return; 669 670 msg = e->last_recv_radius; 671 672 eap = radius_msg_get_eap(msg); 673 if (eap == NULL) { 674 /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3: 675 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 676 * attribute */ 677 wpa_printf(MSG_DEBUG, "could not extract " 678 "EAP-Message from RADIUS message"); 679 wpabuf_free(e->last_eap_radius); 680 e->last_eap_radius = NULL; 681 return; 682 } 683 684 if (wpabuf_len(eap) < sizeof(*hdr)) { 685 wpa_printf(MSG_DEBUG, "too short EAP packet " 686 "received from authentication server"); 687 wpabuf_free(eap); 688 return; 689 } 690 691 if (wpabuf_len(eap) > sizeof(*hdr)) 692 eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; 693 694 hdr = wpabuf_head(eap); 695 switch (hdr->code) { 696 case EAP_CODE_REQUEST: 697 os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 698 eap_type >= 0 ? eap_type_text(eap_type) : "??", 699 eap_type); 700 break; 701 case EAP_CODE_RESPONSE: 702 os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 703 eap_type >= 0 ? eap_type_text(eap_type) : "??", 704 eap_type); 705 break; 706 case EAP_CODE_SUCCESS: 707 os_strlcpy(buf, "EAP Success", sizeof(buf)); 708 /* LEAP uses EAP Success within an authentication, so must not 709 * stop here with eloop_terminate(); */ 710 break; 711 case EAP_CODE_FAILURE: 712 os_strlcpy(buf, "EAP Failure", sizeof(buf)); 713 eloop_terminate(); 714 break; 715 default: 716 os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 717 wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap); 718 break; 719 } 720 wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d " 721 "id=%d len=%d) from RADIUS server: %s", 722 hdr->code, hdr->identifier, ntohs(hdr->length), buf); 723 724 /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */ 725 726 wpabuf_free(e->last_eap_radius); 727 e->last_eap_radius = eap; 728 729 { 730 struct ieee802_1x_hdr *dot1x; 731 dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap)); 732 assert(dot1x != NULL); 733 dot1x->version = EAPOL_VERSION; 734 dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; 735 dot1x->length = htons(wpabuf_len(eap)); 736 os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap), 737 wpabuf_len(eap)); 738 eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, 739 (u8 *) dot1x, 740 sizeof(*dot1x) + wpabuf_len(eap)); 741 os_free(dot1x); 742 } 743 } 744 745 746 static void ieee802_1x_get_keys(struct eapol_test_data *e, 747 struct radius_msg *msg, struct radius_msg *req, 748 const u8 *shared_secret, 749 size_t shared_secret_len) 750 { 751 struct radius_ms_mppe_keys *keys; 752 753 keys = radius_msg_get_ms_keys(msg, req, shared_secret, 754 shared_secret_len); 755 if (keys && keys->send == NULL && keys->recv == NULL) { 756 os_free(keys); 757 keys = radius_msg_get_cisco_keys(msg, req, shared_secret, 758 shared_secret_len); 759 } 760 761 if (keys) { 762 if (keys->send) { 763 wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)", 764 keys->send, keys->send_len); 765 } 766 if (keys->recv) { 767 wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)", 768 keys->recv, keys->recv_len); 769 e->authenticator_pmk_len = 770 keys->recv_len > PMK_LEN ? PMK_LEN : 771 keys->recv_len; 772 os_memcpy(e->authenticator_pmk, keys->recv, 773 e->authenticator_pmk_len); 774 if (e->authenticator_pmk_len == 16 && keys->send && 775 keys->send_len == 16) { 776 /* MS-CHAP-v2 derives 16 octet keys */ 777 wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key " 778 "to extend PMK to 32 octets"); 779 os_memcpy(e->authenticator_pmk + 780 e->authenticator_pmk_len, 781 keys->send, keys->send_len); 782 e->authenticator_pmk_len += keys->send_len; 783 } 784 } 785 786 os_free(keys->send); 787 os_free(keys->recv); 788 os_free(keys); 789 } 790 } 791 792 793 /* Process the RADIUS frames from Authentication Server */ 794 static RadiusRxResult 795 ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 796 const u8 *shared_secret, size_t shared_secret_len, 797 void *data) 798 { 799 struct eapol_test_data *e = data; 800 struct radius_hdr *hdr = radius_msg_get_hdr(msg); 801 802 /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 803 * present when packet contains an EAP-Message attribute */ 804 if (hdr->code == RADIUS_CODE_ACCESS_REJECT && 805 radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 806 0) < 0 && 807 radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 808 wpa_printf(MSG_DEBUG, "Allowing RADIUS " 809 "Access-Reject without Message-Authenticator " 810 "since it does not include EAP-Message\n"); 811 } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 812 req, 1)) { 813 printf("Incoming RADIUS packet did not have correct " 814 "Message-Authenticator - dropped\n"); 815 return RADIUS_RX_UNKNOWN; 816 } 817 818 if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 819 hdr->code != RADIUS_CODE_ACCESS_REJECT && 820 hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 821 printf("Unknown RADIUS message code\n"); 822 return RADIUS_RX_UNKNOWN; 823 } 824 825 e->radius_identifier = -1; 826 wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); 827 828 radius_msg_free(e->last_recv_radius); 829 e->last_recv_radius = msg; 830 831 switch (hdr->code) { 832 case RADIUS_CODE_ACCESS_ACCEPT: 833 e->radius_access_accept_received = 1; 834 ieee802_1x_get_keys(e, msg, req, shared_secret, 835 shared_secret_len); 836 break; 837 case RADIUS_CODE_ACCESS_REJECT: 838 e->radius_access_reject_received = 1; 839 break; 840 } 841 842 ieee802_1x_decapsulate_radius(e); 843 844 if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 845 e->eapol_test_num_reauths < 0) || 846 hdr->code == RADIUS_CODE_ACCESS_REJECT) { 847 eloop_terminate(); 848 } 849 850 return RADIUS_RX_QUEUED; 851 } 852 853 854 static void wpa_init_conf(struct eapol_test_data *e, 855 struct wpa_supplicant *wpa_s, const char *authsrv, 856 int port, const char *secret, 857 const char *cli_addr) 858 { 859 struct hostapd_radius_server *as; 860 int res; 861 862 wpa_s->bssid[5] = 1; 863 os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN); 864 e->own_ip_addr.s_addr = htonl((127 << 24) | 1); 865 os_strlcpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname)); 866 867 e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers)); 868 assert(e->radius_conf != NULL); 869 e->radius_conf->num_auth_servers = 1; 870 as = os_zalloc(sizeof(struct hostapd_radius_server)); 871 assert(as != NULL); 872 #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 873 { 874 int a[4]; 875 u8 *pos; 876 sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 877 pos = (u8 *) &as->addr.u.v4; 878 *pos++ = a[0]; 879 *pos++ = a[1]; 880 *pos++ = a[2]; 881 *pos++ = a[3]; 882 } 883 #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 884 inet_aton(authsrv, &as->addr.u.v4); 885 #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 886 as->addr.af = AF_INET; 887 as->port = port; 888 as->shared_secret = (u8 *) os_strdup(secret); 889 as->shared_secret_len = os_strlen(secret); 890 e->radius_conf->auth_server = as; 891 e->radius_conf->auth_servers = as; 892 e->radius_conf->msg_dumps = 1; 893 if (cli_addr) { 894 if (hostapd_parse_ip_addr(cli_addr, 895 &e->radius_conf->client_addr) == 0) 896 e->radius_conf->force_client_addr = 1; 897 else { 898 wpa_printf(MSG_ERROR, "Invalid IP address '%s'", 899 cli_addr); 900 assert(0); 901 } 902 } 903 904 e->radius = radius_client_init(wpa_s, e->radius_conf); 905 assert(e->radius != NULL); 906 907 res = radius_client_register(e->radius, RADIUS_AUTH, 908 ieee802_1x_receive_auth, e); 909 assert(res == 0); 910 } 911 912 913 static int scard_test(void) 914 { 915 struct scard_data *scard; 916 size_t len; 917 char imsi[20]; 918 unsigned char _rand[16]; 919 #ifdef PCSC_FUNCS 920 unsigned char sres[4]; 921 unsigned char kc[8]; 922 #endif /* PCSC_FUNCS */ 923 #define num_triplets 5 924 unsigned char rand_[num_triplets][16]; 925 unsigned char sres_[num_triplets][4]; 926 unsigned char kc_[num_triplets][8]; 927 int i, res; 928 size_t j; 929 930 #define AKA_RAND_LEN 16 931 #define AKA_AUTN_LEN 16 932 #define AKA_AUTS_LEN 14 933 #define RES_MAX_LEN 16 934 #define IK_LEN 16 935 #define CK_LEN 16 936 unsigned char aka_rand[AKA_RAND_LEN]; 937 unsigned char aka_autn[AKA_AUTN_LEN]; 938 unsigned char aka_auts[AKA_AUTS_LEN]; 939 unsigned char aka_res[RES_MAX_LEN]; 940 size_t aka_res_len; 941 unsigned char aka_ik[IK_LEN]; 942 unsigned char aka_ck[CK_LEN]; 943 944 scard = scard_init(NULL); 945 if (scard == NULL) 946 return -1; 947 if (scard_set_pin(scard, "1234")) { 948 wpa_printf(MSG_WARNING, "PIN validation failed"); 949 scard_deinit(scard); 950 return -1; 951 } 952 953 len = sizeof(imsi); 954 if (scard_get_imsi(scard, imsi, &len)) 955 goto failed; 956 wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); 957 /* NOTE: Permanent Username: 1 | IMSI */ 958 959 wpa_printf(MSG_DEBUG, "SCARD: MNC length %d", 960 scard_get_mnc_len(scard)); 961 962 os_memset(_rand, 0, sizeof(_rand)); 963 if (scard_gsm_auth(scard, _rand, sres, kc)) 964 goto failed; 965 966 os_memset(_rand, 0xff, sizeof(_rand)); 967 if (scard_gsm_auth(scard, _rand, sres, kc)) 968 goto failed; 969 970 for (i = 0; i < num_triplets; i++) { 971 os_memset(rand_[i], i, sizeof(rand_[i])); 972 if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) 973 goto failed; 974 } 975 976 for (i = 0; i < num_triplets; i++) { 977 printf("1"); 978 for (j = 0; j < len; j++) 979 printf("%c", imsi[j]); 980 printf(","); 981 for (j = 0; j < 16; j++) 982 printf("%02X", rand_[i][j]); 983 printf(","); 984 for (j = 0; j < 4; j++) 985 printf("%02X", sres_[i][j]); 986 printf(","); 987 for (j = 0; j < 8; j++) 988 printf("%02X", kc_[i][j]); 989 printf("\n"); 990 } 991 992 wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); 993 994 /* seq 39 (0x28) */ 995 os_memset(aka_rand, 0xaa, 16); 996 os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" 997 "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); 998 999 res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, 1000 aka_ik, aka_ck, aka_auts); 1001 if (res == 0) { 1002 wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); 1003 wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); 1004 wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); 1005 wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); 1006 } else if (res == -2) { 1007 wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " 1008 "failure"); 1009 wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); 1010 } else { 1011 wpa_printf(MSG_DEBUG, "UMTS auth failed"); 1012 } 1013 1014 failed: 1015 scard_deinit(scard); 1016 1017 return 0; 1018 #undef num_triplets 1019 } 1020 1021 1022 static int scard_get_triplets(int argc, char *argv[]) 1023 { 1024 struct scard_data *scard; 1025 size_t len; 1026 char imsi[20]; 1027 unsigned char _rand[16]; 1028 unsigned char sres[4]; 1029 unsigned char kc[8]; 1030 int num_triplets; 1031 int i; 1032 size_t j; 1033 1034 if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { 1035 printf("invalid parameters for sim command\n"); 1036 return -1; 1037 } 1038 1039 if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { 1040 /* disable debug output */ 1041 wpa_debug_level = 99; 1042 } 1043 1044 scard = scard_init(NULL); 1045 if (scard == NULL) { 1046 printf("Failed to open smartcard connection\n"); 1047 return -1; 1048 } 1049 if (scard_set_pin(scard, argv[0])) { 1050 wpa_printf(MSG_WARNING, "PIN validation failed"); 1051 scard_deinit(scard); 1052 return -1; 1053 } 1054 1055 len = sizeof(imsi); 1056 if (scard_get_imsi(scard, imsi, &len)) { 1057 scard_deinit(scard); 1058 return -1; 1059 } 1060 1061 for (i = 0; i < num_triplets; i++) { 1062 os_memset(_rand, i, sizeof(_rand)); 1063 if (scard_gsm_auth(scard, _rand, sres, kc)) 1064 break; 1065 1066 /* IMSI:Kc:SRES:RAND */ 1067 for (j = 0; j < len; j++) 1068 printf("%c", imsi[j]); 1069 printf(":"); 1070 for (j = 0; j < 8; j++) 1071 printf("%02X", kc[j]); 1072 printf(":"); 1073 for (j = 0; j < 4; j++) 1074 printf("%02X", sres[j]); 1075 printf(":"); 1076 for (j = 0; j < 16; j++) 1077 printf("%02X", _rand[j]); 1078 printf("\n"); 1079 } 1080 1081 scard_deinit(scard); 1082 1083 return 0; 1084 } 1085 1086 1087 static void eapol_test_terminate(int sig, void *signal_ctx) 1088 { 1089 struct wpa_supplicant *wpa_s = signal_ctx; 1090 wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 1091 eloop_terminate(); 1092 } 1093 1094 1095 static void usage(void) 1096 { 1097 printf("usage:\n" 1098 "eapol_test [-nWS] -c<conf> [-a<AS IP>] [-p<AS port>] " 1099 "[-s<AS secret>]\\\n" 1100 " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n" 1101 " [-M<client MAC address>] [-o<server cert file] \\\n" 1102 " [-N<attr spec>] \\\n" 1103 " [-A<client IP>]\n" 1104 "eapol_test scard\n" 1105 "eapol_test sim <PIN> <num triplets> [debug]\n" 1106 "\n"); 1107 printf("options:\n" 1108 " -c<conf> = configuration file\n" 1109 " -a<AS IP> = IP address of the authentication server, " 1110 "default 127.0.0.1\n" 1111 " -p<AS port> = UDP port of the authentication server, " 1112 "default 1812\n" 1113 " -s<AS secret> = shared secret with the authentication " 1114 "server, default 'radius'\n" 1115 " -A<client IP> = IP address of the client, default: select " 1116 "automatically\n" 1117 " -r<count> = number of re-authentications\n" 1118 " -W = wait for a control interface monitor before starting\n" 1119 " -S = save configuration after authentication\n" 1120 " -n = no MPPE keys expected\n" 1121 " -t<timeout> = sets timeout in seconds (default: 30 s)\n" 1122 " -C<Connect-Info> = RADIUS Connect-Info (default: " 1123 "CONNECT 11Mbps 802.11b)\n" 1124 " -M<client MAC address> = Set own MAC address " 1125 "(Calling-Station-Id,\n" 1126 " default: 02:00:00:00:00:01)\n" 1127 " -o<server cert file> = Write received server certificate\n" 1128 " chain to the specified file\n" 1129 " -N<attr spec> = send arbitrary attribute specified by:\n" 1130 " attr_id:syntax:value or attr_id\n" 1131 " attr_id - number id of the attribute\n" 1132 " syntax - one of: s, d, x\n" 1133 " s = string\n" 1134 " d = integer\n" 1135 " x = octet string\n" 1136 " value - attribute value.\n" 1137 " When only attr_id is specified, NULL will be used as " 1138 "value.\n" 1139 " Multiple attributes can be specified by using the " 1140 "option several times.\n"); 1141 } 1142 1143 1144 int main(int argc, char *argv[]) 1145 { 1146 struct wpa_global global; 1147 struct wpa_supplicant wpa_s; 1148 int c, ret = 1, wait_for_monitor = 0, save_config = 0; 1149 char *as_addr = "127.0.0.1"; 1150 int as_port = 1812; 1151 char *as_secret = "radius"; 1152 char *cli_addr = NULL; 1153 char *conf = NULL; 1154 int timeout = 30; 1155 char *pos; 1156 struct extra_radius_attr *p = NULL, *p1; 1157 1158 if (os_program_init()) 1159 return -1; 1160 1161 hostapd_logger_register_cb(hostapd_logger_cb); 1162 1163 os_memset(&eapol_test, 0, sizeof(eapol_test)); 1164 eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; 1165 os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); 1166 1167 wpa_debug_level = 0; 1168 wpa_debug_show_keys = 1; 1169 1170 for (;;) { 1171 c = getopt(argc, argv, "a:A:c:C:M:nN:o:p:r:s:St:W"); 1172 if (c < 0) 1173 break; 1174 switch (c) { 1175 case 'a': 1176 as_addr = optarg; 1177 break; 1178 case 'A': 1179 cli_addr = optarg; 1180 break; 1181 case 'c': 1182 conf = optarg; 1183 break; 1184 case 'C': 1185 eapol_test.connect_info = optarg; 1186 break; 1187 case 'M': 1188 if (hwaddr_aton(optarg, eapol_test.own_addr)) { 1189 usage(); 1190 return -1; 1191 } 1192 break; 1193 case 'n': 1194 eapol_test.no_mppe_keys++; 1195 break; 1196 case 'o': 1197 if (eapol_test.server_cert_file) 1198 fclose(eapol_test.server_cert_file); 1199 eapol_test.server_cert_file = fopen(optarg, "w"); 1200 if (eapol_test.server_cert_file == NULL) { 1201 printf("Could not open '%s' for writing\n", 1202 optarg); 1203 return -1; 1204 } 1205 break; 1206 case 'p': 1207 as_port = atoi(optarg); 1208 break; 1209 case 'r': 1210 eapol_test.eapol_test_num_reauths = atoi(optarg); 1211 break; 1212 case 's': 1213 as_secret = optarg; 1214 break; 1215 case 'S': 1216 save_config++; 1217 break; 1218 case 't': 1219 timeout = atoi(optarg); 1220 break; 1221 case 'W': 1222 wait_for_monitor++; 1223 break; 1224 case 'N': 1225 p1 = os_zalloc(sizeof(*p1)); 1226 if (p1 == NULL) 1227 break; 1228 if (!p) 1229 eapol_test.extra_attrs = p1; 1230 else 1231 p->next = p1; 1232 p = p1; 1233 1234 p->type = atoi(optarg); 1235 pos = os_strchr(optarg, ':'); 1236 if (pos == NULL) { 1237 p->syntax = 'n'; 1238 p->data = NULL; 1239 break; 1240 } 1241 1242 pos++; 1243 if (pos[0] == '\0' || pos[1] != ':') { 1244 printf("Incorrect format of attribute " 1245 "specification\n"); 1246 break; 1247 } 1248 1249 p->syntax = pos[0]; 1250 p->data = pos + 2; 1251 break; 1252 default: 1253 usage(); 1254 return -1; 1255 } 1256 } 1257 1258 if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { 1259 return scard_test(); 1260 } 1261 1262 if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { 1263 return scard_get_triplets(argc - optind - 1, 1264 &argv[optind + 1]); 1265 } 1266 1267 if (conf == NULL) { 1268 usage(); 1269 printf("Configuration file is required.\n"); 1270 return -1; 1271 } 1272 1273 if (eap_register_methods()) { 1274 wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 1275 return -1; 1276 } 1277 1278 if (eloop_init()) { 1279 wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 1280 return -1; 1281 } 1282 1283 os_memset(&global, 0, sizeof(global)); 1284 os_memset(&wpa_s, 0, sizeof(wpa_s)); 1285 wpa_s.global = &global; 1286 eapol_test.wpa_s = &wpa_s; 1287 dl_list_init(&wpa_s.bss); 1288 dl_list_init(&wpa_s.bss_id); 1289 wpa_s.conf = wpa_config_read(conf, NULL); 1290 if (wpa_s.conf == NULL) { 1291 printf("Failed to parse configuration file '%s'.\n", conf); 1292 return -1; 1293 } 1294 if (wpa_s.conf->ssid == NULL) { 1295 printf("No networks defined.\n"); 1296 return -1; 1297 } 1298 1299 wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret, 1300 cli_addr); 1301 wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 1302 if (wpa_s.ctrl_iface == NULL) { 1303 printf("Failed to initialize control interface '%s'.\n" 1304 "You may have another eapol_test process already " 1305 "running or the file was\n" 1306 "left by an unclean termination of eapol_test in " 1307 "which case you will need\n" 1308 "to manually remove this file before starting " 1309 "eapol_test again.\n", 1310 wpa_s.conf->ctrl_interface); 1311 return -1; 1312 } 1313 if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 1314 return -1; 1315 1316 if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) 1317 return -1; 1318 1319 if (wpas_init_ext_pw(&wpa_s) < 0) 1320 return -1; 1321 1322 if (wait_for_monitor) 1323 wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); 1324 1325 eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, 1326 NULL); 1327 eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); 1328 eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); 1329 eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); 1330 eloop_run(); 1331 1332 eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); 1333 eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); 1334 1335 if (eapol_test_compare_pmk(&eapol_test) == 0 || 1336 eapol_test.no_mppe_keys) 1337 ret = 0; 1338 if (eapol_test.auth_timed_out) 1339 ret = -2; 1340 if (eapol_test.radius_access_reject_received) 1341 ret = -3; 1342 1343 if (save_config) 1344 wpa_config_write(conf, wpa_s.conf); 1345 1346 test_eapol_clean(&eapol_test, &wpa_s); 1347 1348 eap_peer_unregister_methods(); 1349 #ifdef CONFIG_AP 1350 eap_server_unregister_methods(); 1351 #endif /* CONFIG_AP */ 1352 1353 eloop_destroy(); 1354 1355 if (eapol_test.server_cert_file) 1356 fclose(eapol_test.server_cert_file); 1357 1358 printf("MPPE keys OK: %d mismatch: %d\n", 1359 eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); 1360 if (eapol_test.num_mppe_mismatch) 1361 ret = -4; 1362 if (ret) 1363 printf("FAILURE\n"); 1364 else 1365 printf("SUCCESS\n"); 1366 1367 os_program_deinit(); 1368 1369 return ret; 1370 } 1371