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