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