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