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