1 /* 2 * WPA Supplicant - test code 3 * Copyright (c) 2003-2013, Jouni Malinen <j (at) 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 (len < 0 || (size_t) len >= buflen) { 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 *cert_hash, 484 const struct wpabuf *cert) 485 { 486 struct eapol_test_data *e = ctx; 487 488 wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT 489 "depth=%d subject='%s'%s%s", 490 depth, subject, 491 cert_hash ? " hash=" : "", 492 cert_hash ? cert_hash : ""); 493 494 if (cert) { 495 char *cert_hex; 496 size_t len = wpabuf_len(cert) * 2 + 1; 497 cert_hex = os_malloc(len); 498 if (cert_hex) { 499 wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), 500 wpabuf_len(cert)); 501 wpa_msg_ctrl(e->wpa_s, MSG_INFO, 502 WPA_EVENT_EAP_PEER_CERT 503 "depth=%d subject='%s' cert=%s", 504 depth, subject, cert_hex); 505 os_free(cert_hex); 506 } 507 508 if (e->server_cert_file) 509 eapol_test_write_cert(e->server_cert_file, 510 subject, cert); 511 } 512 } 513 514 515 static void eapol_test_set_anon_id(void *ctx, const u8 *id, size_t len) 516 { 517 struct eapol_test_data *e = ctx; 518 struct wpa_supplicant *wpa_s = e->wpa_s; 519 char *str; 520 int res; 521 522 wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity", 523 id, len); 524 525 if (wpa_s->current_ssid == NULL) 526 return; 527 528 if (id == NULL) { 529 if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 530 "NULL", 0) < 0) 531 return; 532 } else { 533 str = os_malloc(len * 2 + 1); 534 if (str == NULL) 535 return; 536 wpa_snprintf_hex(str, len * 2 + 1, id, len); 537 res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity", 538 str, 0); 539 os_free(str); 540 if (res < 0) 541 return; 542 } 543 } 544 545 546 static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, 547 struct wpa_ssid *ssid) 548 { 549 struct eapol_config eapol_conf; 550 struct eapol_ctx *ctx; 551 552 ctx = os_zalloc(sizeof(*ctx)); 553 if (ctx == NULL) { 554 printf("Failed to allocate EAPOL context.\n"); 555 return -1; 556 } 557 ctx->ctx = e; 558 ctx->msg_ctx = wpa_s; 559 ctx->scard_ctx = wpa_s->scard; 560 ctx->cb = eapol_sm_cb; 561 ctx->cb_ctx = e; 562 ctx->eapol_send_ctx = wpa_s; 563 ctx->preauth = 0; 564 ctx->eapol_done_cb = eapol_test_eapol_done_cb; 565 ctx->eapol_send = eapol_test_eapol_send; 566 ctx->set_config_blob = eapol_test_set_config_blob; 567 ctx->get_config_blob = eapol_test_get_config_blob; 568 ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 569 ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 570 ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 571 ctx->eap_param_needed = eapol_test_eap_param_needed; 572 ctx->cert_cb = eapol_test_cert_cb; 573 ctx->cert_in_cb = 1; 574 ctx->set_anon_id = eapol_test_set_anon_id; 575 576 wpa_s->eapol = eapol_sm_init(ctx); 577 if (wpa_s->eapol == NULL) { 578 os_free(ctx); 579 printf("Failed to initialize EAPOL state machines.\n"); 580 return -1; 581 } 582 583 wpa_s->current_ssid = ssid; 584 os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 585 eapol_conf.accept_802_1x_keys = 1; 586 eapol_conf.required_keys = 0; 587 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; 588 eapol_conf.workaround = ssid->eap_workaround; 589 eapol_conf.external_sim = wpa_s->conf->external_sim; 590 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); 591 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 592 593 594 eapol_sm_notify_portValid(wpa_s->eapol, FALSE); 595 /* 802.1X::portControl = Auto */ 596 eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); 597 598 return 0; 599 } 600 601 602 static void test_eapol_clean(struct eapol_test_data *e, 603 struct wpa_supplicant *wpa_s) 604 { 605 struct extra_radius_attr *p, *prev; 606 607 radius_client_deinit(e->radius); 608 wpabuf_free(e->last_eap_radius); 609 radius_msg_free(e->last_recv_radius); 610 e->last_recv_radius = NULL; 611 os_free(e->eap_identity); 612 e->eap_identity = NULL; 613 eapol_sm_deinit(wpa_s->eapol); 614 wpa_s->eapol = NULL; 615 if (e->radius_conf && e->radius_conf->auth_server) { 616 os_free(e->radius_conf->auth_server->shared_secret); 617 os_free(e->radius_conf->auth_server); 618 } 619 os_free(e->radius_conf); 620 e->radius_conf = NULL; 621 scard_deinit(wpa_s->scard); 622 if (wpa_s->ctrl_iface) { 623 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); 624 wpa_s->ctrl_iface = NULL; 625 } 626 627 ext_password_deinit(wpa_s->ext_pw); 628 wpa_s->ext_pw = NULL; 629 630 wpa_config_free(wpa_s->conf); 631 632 p = e->extra_attrs; 633 while (p) { 634 prev = p; 635 p = p->next; 636 os_free(prev); 637 } 638 } 639 640 641 static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) 642 { 643 struct wpa_supplicant *wpa_s = eloop_ctx; 644 u8 buf[100], *pos; 645 struct ieee802_1x_hdr *hdr; 646 struct eap_hdr *eap; 647 648 hdr = (struct ieee802_1x_hdr *) buf; 649 hdr->version = EAPOL_VERSION; 650 hdr->type = IEEE802_1X_TYPE_EAP_PACKET; 651 hdr->length = htons(5); 652 653 eap = (struct eap_hdr *) (hdr + 1); 654 eap->code = EAP_CODE_REQUEST; 655 eap->identifier = 0; 656 eap->length = htons(5); 657 pos = (u8 *) (eap + 1); 658 *pos = EAP_TYPE_IDENTITY; 659 660 printf("Sending fake EAP-Request-Identity\n"); 661 eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf, 662 sizeof(*hdr) + 5); 663 } 664 665 666 static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 667 { 668 struct eapol_test_data *e = eloop_ctx; 669 printf("EAPOL test timed out\n"); 670 e->auth_timed_out = 1; 671 eloop_terminate(); 672 } 673 674 675 static char *eap_type_text(u8 type) 676 { 677 switch (type) { 678 case EAP_TYPE_IDENTITY: return "Identity"; 679 case EAP_TYPE_NOTIFICATION: return "Notification"; 680 case EAP_TYPE_NAK: return "Nak"; 681 case EAP_TYPE_TLS: return "TLS"; 682 case EAP_TYPE_TTLS: return "TTLS"; 683 case EAP_TYPE_PEAP: return "PEAP"; 684 case EAP_TYPE_SIM: return "SIM"; 685 case EAP_TYPE_GTC: return "GTC"; 686 case EAP_TYPE_MD5: return "MD5"; 687 case EAP_TYPE_OTP: return "OTP"; 688 case EAP_TYPE_FAST: return "FAST"; 689 case EAP_TYPE_SAKE: return "SAKE"; 690 case EAP_TYPE_PSK: return "PSK"; 691 default: return "Unknown"; 692 } 693 } 694 695 696 static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) 697 { 698 struct wpabuf *eap; 699 const struct eap_hdr *hdr; 700 int eap_type = -1; 701 char buf[64]; 702 struct radius_msg *msg; 703 704 if (e->last_recv_radius == NULL) 705 return; 706 707 msg = e->last_recv_radius; 708 709 eap = radius_msg_get_eap(msg); 710 if (eap == NULL) { 711 /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3: 712 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 713 * attribute */ 714 wpa_printf(MSG_DEBUG, "could not extract " 715 "EAP-Message from RADIUS message"); 716 wpabuf_free(e->last_eap_radius); 717 e->last_eap_radius = NULL; 718 return; 719 } 720 721 if (wpabuf_len(eap) < sizeof(*hdr)) { 722 wpa_printf(MSG_DEBUG, "too short EAP packet " 723 "received from authentication server"); 724 wpabuf_free(eap); 725 return; 726 } 727 728 if (wpabuf_len(eap) > sizeof(*hdr)) 729 eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; 730 731 hdr = wpabuf_head(eap); 732 switch (hdr->code) { 733 case EAP_CODE_REQUEST: 734 os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 735 eap_type >= 0 ? eap_type_text(eap_type) : "??", 736 eap_type); 737 break; 738 case EAP_CODE_RESPONSE: 739 os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 740 eap_type >= 0 ? eap_type_text(eap_type) : "??", 741 eap_type); 742 break; 743 case EAP_CODE_SUCCESS: 744 os_strlcpy(buf, "EAP Success", sizeof(buf)); 745 /* LEAP uses EAP Success within an authentication, so must not 746 * stop here with eloop_terminate(); */ 747 break; 748 case EAP_CODE_FAILURE: 749 os_strlcpy(buf, "EAP Failure", sizeof(buf)); 750 eloop_terminate(); 751 break; 752 default: 753 os_strlcpy(buf, "unknown EAP code", sizeof(buf)); 754 wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap); 755 break; 756 } 757 wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d " 758 "id=%d len=%d) from RADIUS server: %s", 759 hdr->code, hdr->identifier, ntohs(hdr->length), buf); 760 761 /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */ 762 763 wpabuf_free(e->last_eap_radius); 764 e->last_eap_radius = eap; 765 766 { 767 struct ieee802_1x_hdr *dot1x; 768 dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap)); 769 assert(dot1x != NULL); 770 dot1x->version = EAPOL_VERSION; 771 dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; 772 dot1x->length = htons(wpabuf_len(eap)); 773 os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap), 774 wpabuf_len(eap)); 775 eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, 776 (u8 *) dot1x, 777 sizeof(*dot1x) + wpabuf_len(eap)); 778 os_free(dot1x); 779 } 780 } 781 782 783 static void ieee802_1x_get_keys(struct eapol_test_data *e, 784 struct radius_msg *msg, struct radius_msg *req, 785 const u8 *shared_secret, 786 size_t shared_secret_len) 787 { 788 struct radius_ms_mppe_keys *keys; 789 u8 *buf; 790 size_t len; 791 792 keys = radius_msg_get_ms_keys(msg, req, shared_secret, 793 shared_secret_len); 794 if (keys && keys->send == NULL && keys->recv == NULL) { 795 os_free(keys); 796 keys = radius_msg_get_cisco_keys(msg, req, shared_secret, 797 shared_secret_len); 798 } 799 800 if (keys) { 801 if (keys->send) { 802 wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)", 803 keys->send, keys->send_len); 804 } 805 if (keys->recv) { 806 wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)", 807 keys->recv, keys->recv_len); 808 e->authenticator_pmk_len = 809 keys->recv_len > PMK_LEN ? PMK_LEN : 810 keys->recv_len; 811 os_memcpy(e->authenticator_pmk, keys->recv, 812 e->authenticator_pmk_len); 813 if (e->authenticator_pmk_len == 16 && keys->send && 814 keys->send_len == 16) { 815 /* MS-CHAP-v2 derives 16 octet keys */ 816 wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key " 817 "to extend PMK to 32 octets"); 818 os_memcpy(e->authenticator_pmk + 819 e->authenticator_pmk_len, 820 keys->send, keys->send_len); 821 e->authenticator_pmk_len += keys->send_len; 822 } 823 } 824 825 os_free(keys->send); 826 os_free(keys->recv); 827 os_free(keys); 828 } 829 830 if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_EAP_KEY_NAME, &buf, &len, 831 NULL) == 0) { 832 os_memcpy(e->authenticator_eap_key_name, buf, len); 833 e->authenticator_eap_key_name_len = len; 834 } else { 835 e->authenticator_eap_key_name_len = 0; 836 } 837 } 838 839 840 /* Process the RADIUS frames from Authentication Server */ 841 static RadiusRxResult 842 ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 843 const u8 *shared_secret, size_t shared_secret_len, 844 void *data) 845 { 846 struct eapol_test_data *e = data; 847 struct radius_hdr *hdr = radius_msg_get_hdr(msg); 848 849 /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 850 * present when packet contains an EAP-Message attribute */ 851 if (hdr->code == RADIUS_CODE_ACCESS_REJECT && 852 radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 853 0) < 0 && 854 radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 855 wpa_printf(MSG_DEBUG, "Allowing RADIUS " 856 "Access-Reject without Message-Authenticator " 857 "since it does not include EAP-Message\n"); 858 } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 859 req, 1)) { 860 printf("Incoming RADIUS packet did not have correct " 861 "Message-Authenticator - dropped\n"); 862 return RADIUS_RX_UNKNOWN; 863 } 864 865 if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 866 hdr->code != RADIUS_CODE_ACCESS_REJECT && 867 hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 868 printf("Unknown RADIUS message code\n"); 869 return RADIUS_RX_UNKNOWN; 870 } 871 872 e->radius_identifier = -1; 873 wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); 874 875 radius_msg_free(e->last_recv_radius); 876 e->last_recv_radius = msg; 877 878 switch (hdr->code) { 879 case RADIUS_CODE_ACCESS_ACCEPT: 880 e->radius_access_accept_received = 1; 881 ieee802_1x_get_keys(e, msg, req, shared_secret, 882 shared_secret_len); 883 break; 884 case RADIUS_CODE_ACCESS_REJECT: 885 e->radius_access_reject_received = 1; 886 break; 887 } 888 889 ieee802_1x_decapsulate_radius(e); 890 891 if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 892 e->eapol_test_num_reauths < 0) || 893 hdr->code == RADIUS_CODE_ACCESS_REJECT) { 894 eloop_terminate(); 895 } 896 897 return RADIUS_RX_QUEUED; 898 } 899 900 901 static void wpa_init_conf(struct eapol_test_data *e, 902 struct wpa_supplicant *wpa_s, const char *authsrv, 903 int port, const char *secret, 904 const char *cli_addr) 905 { 906 struct hostapd_radius_server *as; 907 int res; 908 909 wpa_s->bssid[5] = 1; 910 os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN); 911 e->own_ip_addr.s_addr = htonl((127 << 24) | 1); 912 os_strlcpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname)); 913 914 e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers)); 915 assert(e->radius_conf != NULL); 916 e->radius_conf->num_auth_servers = 1; 917 as = os_zalloc(sizeof(struct hostapd_radius_server)); 918 assert(as != NULL); 919 #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 920 { 921 int a[4]; 922 u8 *pos; 923 sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 924 pos = (u8 *) &as->addr.u.v4; 925 *pos++ = a[0]; 926 *pos++ = a[1]; 927 *pos++ = a[2]; 928 *pos++ = a[3]; 929 } 930 #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 931 inet_aton(authsrv, &as->addr.u.v4); 932 #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 933 as->addr.af = AF_INET; 934 as->port = port; 935 as->shared_secret = (u8 *) os_strdup(secret); 936 as->shared_secret_len = os_strlen(secret); 937 e->radius_conf->auth_server = as; 938 e->radius_conf->auth_servers = as; 939 e->radius_conf->msg_dumps = 1; 940 if (cli_addr) { 941 if (hostapd_parse_ip_addr(cli_addr, 942 &e->radius_conf->client_addr) == 0) 943 e->radius_conf->force_client_addr = 1; 944 else { 945 wpa_printf(MSG_ERROR, "Invalid IP address '%s'", 946 cli_addr); 947 assert(0); 948 } 949 } 950 951 e->radius = radius_client_init(wpa_s, e->radius_conf); 952 assert(e->radius != NULL); 953 954 res = radius_client_register(e->radius, RADIUS_AUTH, 955 ieee802_1x_receive_auth, e); 956 assert(res == 0); 957 } 958 959 960 static int scard_test(struct eapol_test_data *e) 961 { 962 struct scard_data *scard; 963 size_t len; 964 char imsi[20]; 965 unsigned char _rand[16]; 966 #ifdef PCSC_FUNCS 967 unsigned char sres[4]; 968 unsigned char kc[8]; 969 #endif /* PCSC_FUNCS */ 970 #define num_triplets 5 971 unsigned char rand_[num_triplets][16]; 972 unsigned char sres_[num_triplets][4]; 973 unsigned char kc_[num_triplets][8]; 974 int i, res; 975 size_t j; 976 977 #define AKA_RAND_LEN 16 978 #define AKA_AUTN_LEN 16 979 #define AKA_AUTS_LEN 14 980 #define RES_MAX_LEN 16 981 #define IK_LEN 16 982 #define CK_LEN 16 983 unsigned char aka_rand[AKA_RAND_LEN]; 984 unsigned char aka_autn[AKA_AUTN_LEN]; 985 unsigned char aka_auts[AKA_AUTS_LEN]; 986 unsigned char aka_res[RES_MAX_LEN]; 987 size_t aka_res_len; 988 unsigned char aka_ik[IK_LEN]; 989 unsigned char aka_ck[CK_LEN]; 990 991 scard = scard_init(e->pcsc_reader); 992 if (scard == NULL) 993 return -1; 994 if (scard_set_pin(scard, e->pcsc_pin)) { 995 wpa_printf(MSG_WARNING, "PIN validation failed"); 996 scard_deinit(scard); 997 return -1; 998 } 999 1000 len = sizeof(imsi); 1001 if (scard_get_imsi(scard, imsi, &len)) 1002 goto failed; 1003 wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); 1004 /* NOTE: Permanent Username: 1 | IMSI */ 1005 1006 wpa_printf(MSG_DEBUG, "SCARD: MNC length %d", 1007 scard_get_mnc_len(scard)); 1008 1009 os_memset(_rand, 0, sizeof(_rand)); 1010 if (scard_gsm_auth(scard, _rand, sres, kc)) 1011 goto failed; 1012 1013 os_memset(_rand, 0xff, sizeof(_rand)); 1014 if (scard_gsm_auth(scard, _rand, sres, kc)) 1015 goto failed; 1016 1017 for (i = 0; i < num_triplets; i++) { 1018 os_memset(rand_[i], i, sizeof(rand_[i])); 1019 if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) 1020 goto failed; 1021 } 1022 1023 for (i = 0; i < num_triplets; i++) { 1024 printf("1"); 1025 for (j = 0; j < len; j++) 1026 printf("%c", imsi[j]); 1027 printf(","); 1028 for (j = 0; j < 16; j++) 1029 printf("%02X", rand_[i][j]); 1030 printf(","); 1031 for (j = 0; j < 4; j++) 1032 printf("%02X", sres_[i][j]); 1033 printf(","); 1034 for (j = 0; j < 8; j++) 1035 printf("%02X", kc_[i][j]); 1036 printf("\n"); 1037 } 1038 1039 wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); 1040 1041 /* seq 39 (0x28) */ 1042 os_memset(aka_rand, 0xaa, 16); 1043 os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" 1044 "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); 1045 1046 res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, 1047 aka_ik, aka_ck, aka_auts); 1048 if (res == 0) { 1049 wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); 1050 wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); 1051 wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); 1052 wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); 1053 } else if (res == -2) { 1054 wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " 1055 "failure"); 1056 wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); 1057 } else { 1058 wpa_printf(MSG_DEBUG, "UMTS auth failed"); 1059 } 1060 1061 failed: 1062 scard_deinit(scard); 1063 1064 return 0; 1065 #undef num_triplets 1066 } 1067 1068 1069 static int scard_get_triplets(struct eapol_test_data *e, int argc, char *argv[]) 1070 { 1071 struct scard_data *scard; 1072 size_t len; 1073 char imsi[20]; 1074 unsigned char _rand[16]; 1075 unsigned char sres[4]; 1076 unsigned char kc[8]; 1077 int num_triplets; 1078 int i; 1079 size_t j; 1080 1081 if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { 1082 printf("invalid parameters for sim command\n"); 1083 return -1; 1084 } 1085 1086 if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { 1087 /* disable debug output */ 1088 wpa_debug_level = 99; 1089 } 1090 1091 scard = scard_init(e->pcsc_reader); 1092 if (scard == NULL) { 1093 printf("Failed to open smartcard connection\n"); 1094 return -1; 1095 } 1096 if (scard_set_pin(scard, argv[0])) { 1097 wpa_printf(MSG_WARNING, "PIN validation failed"); 1098 scard_deinit(scard); 1099 return -1; 1100 } 1101 1102 len = sizeof(imsi); 1103 if (scard_get_imsi(scard, imsi, &len)) { 1104 scard_deinit(scard); 1105 return -1; 1106 } 1107 1108 for (i = 0; i < num_triplets; i++) { 1109 os_memset(_rand, i, sizeof(_rand)); 1110 if (scard_gsm_auth(scard, _rand, sres, kc)) 1111 break; 1112 1113 /* IMSI:Kc:SRES:RAND */ 1114 for (j = 0; j < len; j++) 1115 printf("%c", imsi[j]); 1116 printf(":"); 1117 for (j = 0; j < 8; j++) 1118 printf("%02X", kc[j]); 1119 printf(":"); 1120 for (j = 0; j < 4; j++) 1121 printf("%02X", sres[j]); 1122 printf(":"); 1123 for (j = 0; j < 16; j++) 1124 printf("%02X", _rand[j]); 1125 printf("\n"); 1126 } 1127 1128 scard_deinit(scard); 1129 1130 return 0; 1131 } 1132 1133 1134 static void eapol_test_terminate(int sig, void *signal_ctx) 1135 { 1136 struct wpa_supplicant *wpa_s = signal_ctx; 1137 wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 1138 eloop_terminate(); 1139 } 1140 1141 1142 static void usage(void) 1143 { 1144 printf("usage:\n" 1145 "eapol_test [-enWS] -c<conf> [-a<AS IP>] [-p<AS port>] " 1146 "[-s<AS secret>]\\\n" 1147 " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n" 1148 " [-M<client MAC address>] [-o<server cert file] \\\n" 1149 " [-N<attr spec>] [-R<PC/SC reader>] " 1150 "[-P<PC/SC PIN>] \\\n" 1151 " [-A<client IP>]\n" 1152 "eapol_test scard\n" 1153 "eapol_test sim <PIN> <num triplets> [debug]\n" 1154 "\n"); 1155 printf("options:\n" 1156 " -c<conf> = configuration file\n" 1157 " -a<AS IP> = IP address of the authentication server, " 1158 "default 127.0.0.1\n" 1159 " -p<AS port> = UDP port of the authentication server, " 1160 "default 1812\n" 1161 " -s<AS secret> = shared secret with the authentication " 1162 "server, default 'radius'\n" 1163 " -A<client IP> = IP address of the client, default: select " 1164 "automatically\n" 1165 " -r<count> = number of re-authentications\n" 1166 " -e = Request EAP-Key-Name\n" 1167 " -W = wait for a control interface monitor before starting\n" 1168 " -S = save configuration after authentication\n" 1169 " -n = no MPPE keys expected\n" 1170 " -t<timeout> = sets timeout in seconds (default: 30 s)\n" 1171 " -C<Connect-Info> = RADIUS Connect-Info (default: " 1172 "CONNECT 11Mbps 802.11b)\n" 1173 " -M<client MAC address> = Set own MAC address " 1174 "(Calling-Station-Id,\n" 1175 " default: 02:00:00:00:00:01)\n" 1176 " -o<server cert file> = Write received server certificate\n" 1177 " chain to the specified file\n" 1178 " -N<attr spec> = send arbitrary attribute specified by:\n" 1179 " attr_id:syntax:value or attr_id\n" 1180 " attr_id - number id of the attribute\n" 1181 " syntax - one of: s, d, x\n" 1182 " s = string\n" 1183 " d = integer\n" 1184 " x = octet string\n" 1185 " value - attribute value.\n" 1186 " When only attr_id is specified, NULL will be used as " 1187 "value.\n" 1188 " Multiple attributes can be specified by using the " 1189 "option several times.\n"); 1190 } 1191 1192 1193 int main(int argc, char *argv[]) 1194 { 1195 struct wpa_global global; 1196 struct wpa_supplicant wpa_s; 1197 int c, ret = 1, wait_for_monitor = 0, save_config = 0; 1198 char *as_addr = "127.0.0.1"; 1199 int as_port = 1812; 1200 char *as_secret = "radius"; 1201 char *cli_addr = NULL; 1202 char *conf = NULL; 1203 int timeout = 30; 1204 char *pos; 1205 struct extra_radius_attr *p = NULL, *p1; 1206 1207 if (os_program_init()) 1208 return -1; 1209 1210 hostapd_logger_register_cb(hostapd_logger_cb); 1211 1212 os_memset(&eapol_test, 0, sizeof(eapol_test)); 1213 eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; 1214 os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); 1215 eapol_test.pcsc_pin = "1234"; 1216 1217 wpa_debug_level = 0; 1218 wpa_debug_show_keys = 1; 1219 1220 for (;;) { 1221 c = getopt(argc, argv, "a:A:c:C:eM:nN:o:p:P:r:R:s:St:W"); 1222 if (c < 0) 1223 break; 1224 switch (c) { 1225 case 'a': 1226 as_addr = optarg; 1227 break; 1228 case 'A': 1229 cli_addr = optarg; 1230 break; 1231 case 'c': 1232 conf = optarg; 1233 break; 1234 case 'C': 1235 eapol_test.connect_info = optarg; 1236 break; 1237 case 'e': 1238 eapol_test.req_eap_key_name = 1; 1239 break; 1240 case 'M': 1241 if (hwaddr_aton(optarg, eapol_test.own_addr)) { 1242 usage(); 1243 return -1; 1244 } 1245 break; 1246 case 'n': 1247 eapol_test.no_mppe_keys++; 1248 break; 1249 case 'o': 1250 if (eapol_test.server_cert_file) 1251 fclose(eapol_test.server_cert_file); 1252 eapol_test.server_cert_file = fopen(optarg, "w"); 1253 if (eapol_test.server_cert_file == NULL) { 1254 printf("Could not open '%s' for writing\n", 1255 optarg); 1256 return -1; 1257 } 1258 break; 1259 case 'p': 1260 as_port = atoi(optarg); 1261 break; 1262 case 'P': 1263 eapol_test.pcsc_pin = optarg; 1264 break; 1265 case 'r': 1266 eapol_test.eapol_test_num_reauths = atoi(optarg); 1267 break; 1268 case 'R': 1269 eapol_test.pcsc_reader = optarg; 1270 break; 1271 case 's': 1272 as_secret = optarg; 1273 break; 1274 case 'S': 1275 save_config++; 1276 break; 1277 case 't': 1278 timeout = atoi(optarg); 1279 break; 1280 case 'W': 1281 wait_for_monitor++; 1282 break; 1283 case 'N': 1284 p1 = os_zalloc(sizeof(*p1)); 1285 if (p1 == NULL) 1286 break; 1287 if (!p) 1288 eapol_test.extra_attrs = p1; 1289 else 1290 p->next = p1; 1291 p = p1; 1292 1293 p->type = atoi(optarg); 1294 pos = os_strchr(optarg, ':'); 1295 if (pos == NULL) { 1296 p->syntax = 'n'; 1297 p->data = NULL; 1298 break; 1299 } 1300 1301 pos++; 1302 if (pos[0] == '\0' || pos[1] != ':') { 1303 printf("Incorrect format of attribute " 1304 "specification\n"); 1305 break; 1306 } 1307 1308 p->syntax = pos[0]; 1309 p->data = pos + 2; 1310 break; 1311 default: 1312 usage(); 1313 return -1; 1314 } 1315 } 1316 1317 if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { 1318 return scard_test(&eapol_test); 1319 } 1320 1321 if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { 1322 return scard_get_triplets(&eapol_test, argc - optind - 1, 1323 &argv[optind + 1]); 1324 } 1325 1326 if (conf == NULL) { 1327 usage(); 1328 printf("Configuration file is required.\n"); 1329 return -1; 1330 } 1331 1332 if (eap_register_methods()) { 1333 wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 1334 return -1; 1335 } 1336 1337 if (eloop_init()) { 1338 wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 1339 return -1; 1340 } 1341 1342 os_memset(&global, 0, sizeof(global)); 1343 os_memset(&wpa_s, 0, sizeof(wpa_s)); 1344 wpa_s.global = &global; 1345 eapol_test.wpa_s = &wpa_s; 1346 dl_list_init(&wpa_s.bss); 1347 dl_list_init(&wpa_s.bss_id); 1348 wpa_s.conf = wpa_config_read(conf, NULL); 1349 if (wpa_s.conf == NULL) { 1350 printf("Failed to parse configuration file '%s'.\n", conf); 1351 return -1; 1352 } 1353 if (wpa_s.conf->ssid == NULL) { 1354 printf("No networks defined.\n"); 1355 return -1; 1356 } 1357 1358 if (eapol_test.pcsc_reader) { 1359 os_free(wpa_s.conf->pcsc_reader); 1360 wpa_s.conf->pcsc_reader = os_strdup(eapol_test.pcsc_reader); 1361 } 1362 1363 wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret, 1364 cli_addr); 1365 wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 1366 if (wpa_s.ctrl_iface == NULL) { 1367 printf("Failed to initialize control interface '%s'.\n" 1368 "You may have another eapol_test process already " 1369 "running or the file was\n" 1370 "left by an unclean termination of eapol_test in " 1371 "which case you will need\n" 1372 "to manually remove this file before starting " 1373 "eapol_test again.\n", 1374 wpa_s.conf->ctrl_interface); 1375 return -1; 1376 } 1377 if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 1378 return -1; 1379 1380 if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) 1381 return -1; 1382 1383 if (wpas_init_ext_pw(&wpa_s) < 0) 1384 return -1; 1385 1386 if (wait_for_monitor) 1387 wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); 1388 1389 eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, 1390 NULL); 1391 eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); 1392 eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); 1393 eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); 1394 eloop_run(); 1395 1396 eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); 1397 eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); 1398 1399 if (eapol_test_compare_pmk(&eapol_test) == 0 || 1400 eapol_test.no_mppe_keys) 1401 ret = 0; 1402 if (eapol_test.auth_timed_out) 1403 ret = -2; 1404 if (eapol_test.radius_access_reject_received) 1405 ret = -3; 1406 1407 if (save_config) 1408 wpa_config_write(conf, wpa_s.conf); 1409 1410 test_eapol_clean(&eapol_test, &wpa_s); 1411 1412 eap_peer_unregister_methods(); 1413 #ifdef CONFIG_AP 1414 eap_server_unregister_methods(); 1415 #endif /* CONFIG_AP */ 1416 1417 eloop_destroy(); 1418 1419 if (eapol_test.server_cert_file) 1420 fclose(eapol_test.server_cert_file); 1421 1422 printf("MPPE keys OK: %d mismatch: %d\n", 1423 eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); 1424 if (eapol_test.num_mppe_mismatch) 1425 ret = -4; 1426 if (ret) 1427 printf("FAILURE\n"); 1428 else 1429 printf("SUCCESS\n"); 1430 1431 os_program_deinit(); 1432 1433 return ret; 1434 } 1435