1/* 2 * WPA Supplicant - test code 3 * Copyright (c) 2003-2006, Jouni Malinen <j@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_sm.h" 24#include "eap.h" 25#include "eloop.h" 26#include "wpa.h" 27#include "eap_i.h" 28#include "wpa_supplicant.h" 29#include "wpa_supplicant_i.h" 30#include "radius.h" 31#include "radius_client.h" 32#include "l2_packet.h" 33#include "ctrl_iface.h" 34#include "pcsc_funcs.h" 35 36 37extern int wpa_debug_level; 38extern int wpa_debug_show_keys; 39 40struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL }; 41 42 43struct 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 50 u8 radius_identifier; 51 struct radius_msg *last_recv_radius; 52 struct in_addr own_ip_addr; 53 struct radius_client_data *radius; 54 struct hostapd_radius_servers *radius_conf; 55 56 u8 *last_eap_radius; /* last received EAP Response from Authentication 57 * Server */ 58 size_t last_eap_radius_len; 59 60 u8 authenticator_pmk[PMK_LEN]; 61 size_t authenticator_pmk_len; 62 int radius_access_accept_received; 63 int radius_access_reject_received; 64 int auth_timed_out; 65 66 u8 *eap_identity; 67 size_t eap_identity_len; 68 69 char *connect_info; 70 u8 own_addr[ETH_ALEN]; 71}; 72 73static struct eapol_test_data eapol_test; 74 75 76static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx); 77 78 79void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, 80 char *fmt, ...) 81{ 82 char *format; 83 int maxlen; 84 va_list ap; 85 86 maxlen = os_strlen(fmt) + 100; 87 format = os_malloc(maxlen); 88 if (!format) 89 return; 90 91 va_start(ap, fmt); 92 93 94 if (addr) 95 os_snprintf(format, maxlen, "STA " MACSTR ": %s", 96 MAC2STR(addr), fmt); 97 else 98 os_snprintf(format, maxlen, "%s", fmt); 99 100 vprintf(format, ap); 101 printf("\n"); 102 103 os_free(format); 104 105 va_end(ap); 106} 107 108 109const char * hostapd_ip_txt(const struct hostapd_ip_addr *addr, char *buf, 110 size_t buflen) 111{ 112 if (buflen == 0 || addr == NULL) 113 return NULL; 114 115 if (addr->af == AF_INET) { 116 os_snprintf(buf, buflen, "%s", inet_ntoa(addr->u.v4)); 117 } else { 118 buf[0] = '\0'; 119 } 120#ifdef CONFIG_IPV6 121 if (addr->af == AF_INET6) { 122 if (inet_ntop(AF_INET6, &addr->u.v6, buf, buflen) == NULL) 123 buf[0] = '\0'; 124 } 125#endif /* CONFIG_IPV6 */ 126 127 return buf; 128} 129 130 131int hostapd_ip_diff(struct hostapd_ip_addr *a, struct hostapd_ip_addr *b) 132{ 133 return 0; 134} 135 136 137static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, 138 const u8 *eap, size_t len) 139{ 140 struct radius_msg *msg; 141 char buf[128]; 142 const struct eap_hdr *hdr; 143 const u8 *pos; 144 145 wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS " 146 "packet"); 147 148 e->radius_identifier = radius_client_get_id(e->radius); 149 msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST, 150 e->radius_identifier); 151 if (msg == NULL) { 152 printf("Could not create net RADIUS packet\n"); 153 return; 154 } 155 156 radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e)); 157 158 hdr = (const struct eap_hdr *) eap; 159 pos = (const u8 *) (hdr + 1); 160 if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE && 161 pos[0] == EAP_TYPE_IDENTITY) { 162 pos++; 163 os_free(e->eap_identity); 164 e->eap_identity_len = len - sizeof(*hdr) - 1; 165 e->eap_identity = os_malloc(e->eap_identity_len); 166 if (e->eap_identity) { 167 os_memcpy(e->eap_identity, pos, e->eap_identity_len); 168 wpa_hexdump(MSG_DEBUG, "Learned identity from " 169 "EAP-Response-Identity", 170 e->eap_identity, e->eap_identity_len); 171 } 172 } 173 174 if (e->eap_identity && 175 !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, 176 e->eap_identity, e->eap_identity_len)) { 177 printf("Could not add User-Name\n"); 178 goto fail; 179 } 180 181 if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, 182 (u8 *) &e->own_ip_addr, 4)) { 183 printf("Could not add NAS-IP-Address\n"); 184 goto fail; 185 } 186 187 os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, 188 MAC2STR(e->wpa_s->own_addr)); 189 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, 190 (u8 *) buf, os_strlen(buf))) { 191 printf("Could not add Calling-Station-Id\n"); 192 goto fail; 193 } 194 195 /* TODO: should probably check MTU from driver config; 2304 is max for 196 * IEEE 802.11, but use 1400 to avoid problems with too large packets 197 */ 198 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) { 199 printf("Could not add Framed-MTU\n"); 200 goto fail; 201 } 202 203 if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE, 204 RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { 205 printf("Could not add NAS-Port-Type\n"); 206 goto fail; 207 } 208 209 os_snprintf(buf, sizeof(buf), "%s", e->connect_info); 210 if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, 211 (u8 *) buf, os_strlen(buf))) { 212 printf("Could not add Connect-Info\n"); 213 goto fail; 214 } 215 216 if (eap && !radius_msg_add_eap(msg, eap, len)) { 217 printf("Could not add EAP-Message\n"); 218 goto fail; 219 } 220 221 /* State attribute must be copied if and only if this packet is 222 * Access-Request reply to the previous Access-Challenge */ 223 if (e->last_recv_radius && e->last_recv_radius->hdr->code == 224 RADIUS_CODE_ACCESS_CHALLENGE) { 225 int res = radius_msg_copy_attr(msg, e->last_recv_radius, 226 RADIUS_ATTR_STATE); 227 if (res < 0) { 228 printf("Could not copy State attribute from previous " 229 "Access-Challenge\n"); 230 goto fail; 231 } 232 if (res > 0) { 233 wpa_printf(MSG_DEBUG, " Copied RADIUS State " 234 "Attribute"); 235 } 236 } 237 238 radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr); 239 return; 240 241 fail: 242 radius_msg_free(msg); 243 os_free(msg); 244} 245 246 247static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, 248 size_t len) 249{ 250 /* struct wpa_supplicant *wpa_s = ctx; */ 251 printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n", 252 type, (unsigned long) len); 253 if (type == IEEE802_1X_TYPE_EAP_PACKET) { 254 wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len); 255 ieee802_1x_encapsulate_radius(&eapol_test, buf, len); 256 } 257 return 0; 258} 259 260 261static void eapol_test_set_config_blob(void *ctx, 262 struct wpa_config_blob *blob) 263{ 264 struct wpa_supplicant *wpa_s = ctx; 265 wpa_config_set_blob(wpa_s->conf, blob); 266} 267 268 269static const struct wpa_config_blob * 270eapol_test_get_config_blob(void *ctx, const char *name) 271{ 272 struct wpa_supplicant *wpa_s = ctx; 273 return wpa_config_get_blob(wpa_s->conf, name); 274} 275 276 277static void eapol_test_eapol_done_cb(void *ctx) 278{ 279 printf("WPA: EAPOL processing complete\n"); 280} 281 282 283static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx) 284{ 285 struct eapol_test_data *e = eloop_ctx; 286 printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n"); 287 e->radius_access_accept_received = 0; 288 send_eap_request_identity(e->wpa_s, NULL); 289} 290 291 292static int eapol_test_compare_pmk(struct eapol_test_data *e) 293{ 294 u8 pmk[PMK_LEN]; 295 int ret = 1; 296 297 if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) { 298 wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN); 299 if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) { 300 printf("WARNING: PMK mismatch\n"); 301 wpa_hexdump(MSG_DEBUG, "PMK from AS", 302 e->authenticator_pmk, PMK_LEN); 303 } else if (e->radius_access_accept_received) 304 ret = 0; 305 } else if (e->authenticator_pmk_len == 16 && 306 eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) { 307 wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16); 308 if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) { 309 printf("WARNING: PMK mismatch\n"); 310 wpa_hexdump(MSG_DEBUG, "PMK from AS", 311 e->authenticator_pmk, 16); 312 } else if (e->radius_access_accept_received) 313 ret = 0; 314 } else if (e->radius_access_accept_received && e->no_mppe_keys) { 315 /* No keying material expected */ 316 ret = 0; 317 } 318 319 if (ret && !e->no_mppe_keys) 320 e->num_mppe_mismatch++; 321 else if (!e->no_mppe_keys) 322 e->num_mppe_ok++; 323 324 return ret; 325} 326 327 328static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx) 329{ 330 struct eapol_test_data *e = ctx; 331 printf("eapol_sm_cb: success=%d\n", success); 332 e->eapol_test_num_reauths--; 333 if (e->eapol_test_num_reauths < 0) 334 eloop_terminate(); 335 else { 336 eapol_test_compare_pmk(e); 337 eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL); 338 } 339} 340 341 342static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, 343 struct wpa_ssid *ssid) 344{ 345 struct eapol_config eapol_conf; 346 struct eapol_ctx *ctx; 347 348 ctx = os_zalloc(sizeof(*ctx)); 349 if (ctx == NULL) { 350 printf("Failed to allocate EAPOL context.\n"); 351 return -1; 352 } 353 ctx->ctx = wpa_s; 354 ctx->msg_ctx = wpa_s; 355 ctx->scard_ctx = wpa_s->scard; 356 ctx->cb = eapol_sm_cb; 357 ctx->cb_ctx = e; 358 ctx->eapol_send_ctx = wpa_s; 359 ctx->preauth = 0; 360 ctx->eapol_done_cb = eapol_test_eapol_done_cb; 361 ctx->eapol_send = eapol_test_eapol_send; 362 ctx->set_config_blob = eapol_test_set_config_blob; 363 ctx->get_config_blob = eapol_test_get_config_blob; 364 ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; 365 ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; 366 ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; 367 368 wpa_s->eapol = eapol_sm_init(ctx); 369 if (wpa_s->eapol == NULL) { 370 os_free(ctx); 371 printf("Failed to initialize EAPOL state machines.\n"); 372 return -1; 373 } 374 375 wpa_s->current_ssid = ssid; 376 os_memset(&eapol_conf, 0, sizeof(eapol_conf)); 377 eapol_conf.accept_802_1x_keys = 1; 378 eapol_conf.required_keys = 0; 379 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; 380 eapol_conf.workaround = ssid->eap_workaround; 381 eapol_sm_notify_config(wpa_s->eapol, ssid, &eapol_conf); 382 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 383 384 385 eapol_sm_notify_portValid(wpa_s->eapol, FALSE); 386 /* 802.1X::portControl = Auto */ 387 eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); 388 389 return 0; 390} 391 392 393static void test_eapol_clean(struct eapol_test_data *e, 394 struct wpa_supplicant *wpa_s) 395{ 396 radius_client_deinit(e->radius); 397 os_free(e->last_eap_radius); 398 if (e->last_recv_radius) { 399 radius_msg_free(e->last_recv_radius); 400 os_free(e->last_recv_radius); 401 } 402 os_free(e->eap_identity); 403 e->eap_identity = NULL; 404 eapol_sm_deinit(wpa_s->eapol); 405 wpa_s->eapol = NULL; 406 if (e->radius_conf && e->radius_conf->auth_server) { 407 os_free(e->radius_conf->auth_server->shared_secret); 408 os_free(e->radius_conf->auth_server); 409 } 410 os_free(e->radius_conf); 411 e->radius_conf = NULL; 412 scard_deinit(wpa_s->scard); 413 if (wpa_s->ctrl_iface) { 414 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface); 415 wpa_s->ctrl_iface = NULL; 416 } 417 wpa_config_free(wpa_s->conf); 418} 419 420 421static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx) 422{ 423 struct wpa_supplicant *wpa_s = eloop_ctx; 424 u8 buf[100], *pos; 425 struct ieee802_1x_hdr *hdr; 426 struct eap_hdr *eap; 427 428 hdr = (struct ieee802_1x_hdr *) buf; 429 hdr->version = EAPOL_VERSION; 430 hdr->type = IEEE802_1X_TYPE_EAP_PACKET; 431 hdr->length = htons(5); 432 433 eap = (struct eap_hdr *) (hdr + 1); 434 eap->code = EAP_CODE_REQUEST; 435 eap->identifier = 0; 436 eap->length = htons(5); 437 pos = (u8 *) (eap + 1); 438 *pos = EAP_TYPE_IDENTITY; 439 440 printf("Sending fake EAP-Request-Identity\n"); 441 eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf, 442 sizeof(*hdr) + 5); 443} 444 445 446static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx) 447{ 448 struct eapol_test_data *e = eloop_ctx; 449 printf("EAPOL test timed out\n"); 450 e->auth_timed_out = 1; 451 eloop_terminate(); 452} 453 454 455static char *eap_type_text(u8 type) 456{ 457 switch (type) { 458 case EAP_TYPE_IDENTITY: return "Identity"; 459 case EAP_TYPE_NOTIFICATION: return "Notification"; 460 case EAP_TYPE_NAK: return "Nak"; 461 case EAP_TYPE_TLS: return "TLS"; 462 case EAP_TYPE_TTLS: return "TTLS"; 463 case EAP_TYPE_PEAP: return "PEAP"; 464 case EAP_TYPE_SIM: return "SIM"; 465 case EAP_TYPE_GTC: return "GTC"; 466 case EAP_TYPE_MD5: return "MD5"; 467 case EAP_TYPE_OTP: return "OTP"; 468 case EAP_TYPE_FAST: return "FAST"; 469 case EAP_TYPE_SAKE: return "SAKE"; 470 case EAP_TYPE_PSK: return "PSK"; 471 default: return "Unknown"; 472 } 473} 474 475 476static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) 477{ 478 u8 *eap; 479 size_t len; 480 struct eap_hdr *hdr; 481 int eap_type = -1; 482 char buf[64]; 483 struct radius_msg *msg; 484 485 if (e->last_recv_radius == NULL) 486 return; 487 488 msg = e->last_recv_radius; 489 490 eap = radius_msg_get_eap(msg, &len); 491 if (eap == NULL) { 492 /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3: 493 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message 494 * attribute */ 495 wpa_printf(MSG_DEBUG, "could not extract " 496 "EAP-Message from RADIUS message"); 497 os_free(e->last_eap_radius); 498 e->last_eap_radius = NULL; 499 e->last_eap_radius_len = 0; 500 return; 501 } 502 503 if (len < sizeof(*hdr)) { 504 wpa_printf(MSG_DEBUG, "too short EAP packet " 505 "received from authentication server"); 506 os_free(eap); 507 return; 508 } 509 510 if (len > sizeof(*hdr)) 511 eap_type = eap[sizeof(*hdr)]; 512 513 hdr = (struct eap_hdr *) eap; 514 switch (hdr->code) { 515 case EAP_CODE_REQUEST: 516 os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", 517 eap_type >= 0 ? eap_type_text(eap_type) : "??", 518 eap_type); 519 break; 520 case EAP_CODE_RESPONSE: 521 os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)", 522 eap_type >= 0 ? eap_type_text(eap_type) : "??", 523 eap_type); 524 break; 525 case EAP_CODE_SUCCESS: 526 os_snprintf(buf, sizeof(buf), "EAP Success"); 527 /* LEAP uses EAP Success within an authentication, so must not 528 * stop here with eloop_terminate(); */ 529 break; 530 case EAP_CODE_FAILURE: 531 os_snprintf(buf, sizeof(buf), "EAP Failure"); 532 eloop_terminate(); 533 break; 534 default: 535 os_snprintf(buf, sizeof(buf), "unknown EAP code"); 536 wpa_hexdump(MSG_DEBUG, "Decapsulated EAP packet", eap, len); 537 break; 538 } 539 wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d " 540 "id=%d len=%d) from RADIUS server: %s", 541 hdr->code, hdr->identifier, ntohs(hdr->length), buf); 542 543 /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */ 544 545 os_free(e->last_eap_radius); 546 e->last_eap_radius = eap; 547 e->last_eap_radius_len = len; 548 549 { 550 struct ieee802_1x_hdr *dot1x; 551 dot1x = os_malloc(sizeof(*dot1x) + len); 552 assert(dot1x != NULL); 553 dot1x->version = EAPOL_VERSION; 554 dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; 555 dot1x->length = htons(len); 556 os_memcpy((u8 *) (dot1x + 1), eap, len); 557 eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, 558 (u8 *) dot1x, sizeof(*dot1x) + len); 559 os_free(dot1x); 560 } 561} 562 563 564static void ieee802_1x_get_keys(struct eapol_test_data *e, 565 struct radius_msg *msg, struct radius_msg *req, 566 u8 *shared_secret, size_t shared_secret_len) 567{ 568 struct radius_ms_mppe_keys *keys; 569 570 keys = radius_msg_get_ms_keys(msg, req, shared_secret, 571 shared_secret_len); 572 if (keys && keys->send == NULL && keys->recv == NULL) { 573 os_free(keys); 574 keys = radius_msg_get_cisco_keys(msg, req, shared_secret, 575 shared_secret_len); 576 } 577 578 if (keys) { 579 if (keys->send) { 580 wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)", 581 keys->send, keys->send_len); 582 } 583 if (keys->recv) { 584 wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)", 585 keys->recv, keys->recv_len); 586 e->authenticator_pmk_len = 587 keys->recv_len > PMK_LEN ? PMK_LEN : 588 keys->recv_len; 589 os_memcpy(e->authenticator_pmk, keys->recv, 590 e->authenticator_pmk_len); 591 } 592 593 os_free(keys->send); 594 os_free(keys->recv); 595 os_free(keys); 596 } 597} 598 599 600/* Process the RADIUS frames from Authentication Server */ 601static RadiusRxResult 602ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, 603 u8 *shared_secret, size_t shared_secret_len, 604 void *data) 605{ 606 struct eapol_test_data *e = data; 607 608 /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be 609 * present when packet contains an EAP-Message attribute */ 610 if (msg->hdr->code == RADIUS_CODE_ACCESS_REJECT && 611 radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL, 612 0) < 0 && 613 radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) { 614 wpa_printf(MSG_DEBUG, "Allowing RADIUS " 615 "Access-Reject without Message-Authenticator " 616 "since it does not include EAP-Message\n"); 617 } else if (radius_msg_verify(msg, shared_secret, shared_secret_len, 618 req, 1)) { 619 printf("Incoming RADIUS packet did not have correct " 620 "Message-Authenticator - dropped\n"); 621 return RADIUS_RX_UNKNOWN; 622 } 623 624 if (msg->hdr->code != RADIUS_CODE_ACCESS_ACCEPT && 625 msg->hdr->code != RADIUS_CODE_ACCESS_REJECT && 626 msg->hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) { 627 printf("Unknown RADIUS message code\n"); 628 return RADIUS_RX_UNKNOWN; 629 } 630 631 e->radius_identifier = -1; 632 wpa_printf(MSG_DEBUG, "RADIUS packet matching with station"); 633 634 if (e->last_recv_radius) { 635 radius_msg_free(e->last_recv_radius); 636 os_free(e->last_recv_radius); 637 } 638 639 e->last_recv_radius = msg; 640 641 switch (msg->hdr->code) { 642 case RADIUS_CODE_ACCESS_ACCEPT: 643 e->radius_access_accept_received = 1; 644 ieee802_1x_get_keys(e, msg, req, shared_secret, 645 shared_secret_len); 646 break; 647 case RADIUS_CODE_ACCESS_REJECT: 648 e->radius_access_reject_received = 1; 649 break; 650 } 651 652 ieee802_1x_decapsulate_radius(e); 653 654 if ((msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT && 655 e->eapol_test_num_reauths < 0) || 656 msg->hdr->code == RADIUS_CODE_ACCESS_REJECT) { 657 eloop_terminate(); 658 } 659 660 return RADIUS_RX_QUEUED; 661} 662 663 664static void wpa_init_conf(struct eapol_test_data *e, 665 struct wpa_supplicant *wpa_s, const char *authsrv, 666 int port, const char *secret) 667{ 668 struct hostapd_radius_server *as; 669 int res; 670 671 wpa_s->bssid[5] = 1; 672 os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN); 673 e->own_ip_addr.s_addr = htonl((127 << 24) | 1); 674 os_strncpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname)); 675 676 e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers)); 677 assert(e->radius_conf != NULL); 678 e->radius_conf->num_auth_servers = 1; 679 as = os_zalloc(sizeof(struct hostapd_radius_server)); 680 assert(as != NULL); 681#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 682 { 683 int a[4]; 684 u8 *pos; 685 sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 686 pos = (u8 *) &as->addr.u.v4; 687 *pos++ = a[0]; 688 *pos++ = a[1]; 689 *pos++ = a[2]; 690 *pos++ = a[3]; 691 } 692#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 693 inet_aton(authsrv, &as->addr.u.v4); 694#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 695 as->addr.af = AF_INET; 696 as->port = port; 697 as->shared_secret = (u8 *) os_strdup(secret); 698 as->shared_secret_len = os_strlen(secret); 699 e->radius_conf->auth_server = as; 700 e->radius_conf->auth_servers = as; 701 e->radius_conf->msg_dumps = 1; 702 703 e->radius = radius_client_init(wpa_s, e->radius_conf); 704 assert(e->radius != NULL); 705 706 res = radius_client_register(e->radius, RADIUS_AUTH, 707 ieee802_1x_receive_auth, e); 708 assert(res == 0); 709} 710 711 712static int scard_test(void) 713{ 714 struct scard_data *scard; 715 size_t len; 716 char imsi[20]; 717 unsigned char _rand[16]; 718#ifdef PCSC_FUNCS 719 unsigned char sres[4]; 720 unsigned char kc[8]; 721#endif /* PCSC_FUNCS */ 722#define num_triplets 5 723 unsigned char rand_[num_triplets][16]; 724 unsigned char sres_[num_triplets][4]; 725 unsigned char kc_[num_triplets][8]; 726 int i, res; 727 size_t j; 728 729#define AKA_RAND_LEN 16 730#define AKA_AUTN_LEN 16 731#define AKA_AUTS_LEN 14 732#define RES_MAX_LEN 16 733#define IK_LEN 16 734#define CK_LEN 16 735 unsigned char aka_rand[AKA_RAND_LEN]; 736 unsigned char aka_autn[AKA_AUTN_LEN]; 737 unsigned char aka_auts[AKA_AUTS_LEN]; 738 unsigned char aka_res[RES_MAX_LEN]; 739 size_t aka_res_len; 740 unsigned char aka_ik[IK_LEN]; 741 unsigned char aka_ck[CK_LEN]; 742 743 scard = scard_init(SCARD_TRY_BOTH); 744 if (scard == NULL) 745 return -1; 746 if (scard_set_pin(scard, "1234")) { 747 wpa_printf(MSG_WARNING, "PIN validation failed"); 748 scard_deinit(scard); 749 return -1; 750 } 751 752 len = sizeof(imsi); 753 if (scard_get_imsi(scard, imsi, &len)) 754 goto failed; 755 wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len); 756 /* NOTE: Permanent Username: 1 | IMSI */ 757 758 os_memset(_rand, 0, sizeof(_rand)); 759 if (scard_gsm_auth(scard, _rand, sres, kc)) 760 goto failed; 761 762 os_memset(_rand, 0xff, sizeof(_rand)); 763 if (scard_gsm_auth(scard, _rand, sres, kc)) 764 goto failed; 765 766 for (i = 0; i < num_triplets; i++) { 767 os_memset(rand_[i], i, sizeof(rand_[i])); 768 if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i])) 769 goto failed; 770 } 771 772 for (i = 0; i < num_triplets; i++) { 773 printf("1"); 774 for (j = 0; j < len; j++) 775 printf("%c", imsi[j]); 776 printf(","); 777 for (j = 0; j < 16; j++) 778 printf("%02X", rand_[i][j]); 779 printf(","); 780 for (j = 0; j < 4; j++) 781 printf("%02X", sres_[i][j]); 782 printf(","); 783 for (j = 0; j < 8; j++) 784 printf("%02X", kc_[i][j]); 785 printf("\n"); 786 } 787 788 wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication"); 789 790 /* seq 39 (0x28) */ 791 os_memset(aka_rand, 0xaa, 16); 792 os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf" 793 "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16); 794 795 res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len, 796 aka_ik, aka_ck, aka_auts); 797 if (res == 0) { 798 wpa_printf(MSG_DEBUG, "UMTS auth completed successfully"); 799 wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len); 800 wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN); 801 wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN); 802 } else if (res == -2) { 803 wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization " 804 "failure"); 805 wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN); 806 } else { 807 wpa_printf(MSG_DEBUG, "UMTS auth failed"); 808 } 809 810failed: 811 scard_deinit(scard); 812 813 return 0; 814#undef num_triplets 815} 816 817 818static int scard_get_triplets(int argc, char *argv[]) 819{ 820 struct scard_data *scard; 821 size_t len; 822 char imsi[20]; 823 unsigned char _rand[16]; 824 unsigned char sres[4]; 825 unsigned char kc[8]; 826 int num_triplets; 827 int i; 828 size_t j; 829 830 if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) { 831 printf("invalid parameters for sim command\n"); 832 return -1; 833 } 834 835 if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) { 836 /* disable debug output */ 837 wpa_debug_level = 99; 838 } 839 840 scard = scard_init(SCARD_GSM_SIM_ONLY); 841 if (scard == NULL) { 842 printf("Failed to open smartcard connection\n"); 843 return -1; 844 } 845 if (scard_set_pin(scard, argv[0])) { 846 wpa_printf(MSG_WARNING, "PIN validation failed"); 847 scard_deinit(scard); 848 return -1; 849 } 850 851 len = sizeof(imsi); 852 if (scard_get_imsi(scard, imsi, &len)) { 853 scard_deinit(scard); 854 return -1; 855 } 856 857 for (i = 0; i < num_triplets; i++) { 858 os_memset(_rand, i, sizeof(_rand)); 859 if (scard_gsm_auth(scard, _rand, sres, kc)) 860 break; 861 862 /* IMSI:Kc:SRES:RAND */ 863 for (j = 0; j < len; j++) 864 printf("%c", imsi[j]); 865 printf(":"); 866 for (j = 0; j < 8; j++) 867 printf("%02X", kc[j]); 868 printf(":"); 869 for (j = 0; j < 4; j++) 870 printf("%02X", sres[j]); 871 printf(":"); 872 for (j = 0; j < 16; j++) 873 printf("%02X", _rand[j]); 874 printf("\n"); 875 } 876 877 scard_deinit(scard); 878 879 return 0; 880} 881 882 883static void eapol_test_terminate(int sig, void *eloop_ctx, 884 void *signal_ctx) 885{ 886 struct wpa_supplicant *wpa_s = eloop_ctx; 887 wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig); 888 eloop_terminate(); 889} 890 891 892static void usage(void) 893{ 894 printf("usage:\n" 895 "eapol_test [-nWS] -c<conf> [-a<AS IP>] [-p<AS port>] " 896 "[-s<AS secret>] \\\n" 897 " [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n" 898 " [-M<client MAC address>]\n" 899 "eapol_test scard\n" 900 "eapol_test sim <PIN> <num triplets> [debug]\n" 901 "\n"); 902 printf("options:\n" 903 " -c<conf> = configuration file\n" 904 " -a<AS IP> = IP address of the authentication server, " 905 "default 127.0.0.1\n" 906 " -p<AS port> = UDP port of the authentication server, " 907 "default 1812\n" 908 " -s<AS secret> = shared secret with the authentication " 909 "server, default 'radius'\n" 910 " -r<count> = number of re-authentications\n" 911 " -W = wait for a control interface monitor before starting\n" 912 " -S = save configuration after authentiation\n" 913 " -n = no MPPE keys expected\n" 914 " -t<timeout> = sets timeout in seconds (default: 30 s)\n" 915 " -C<Connect-Info> = RADIUS Connect-Info (default: " 916 "CONNECT 11Mbps 802.11b)\n" 917 " -M<client MAC address> = Set own MAC address " 918 "(Calling-Station-Id,\n" 919 " default: 02:00:00:00:00:01)\n"); 920} 921 922 923int main(int argc, char *argv[]) 924{ 925 struct wpa_supplicant wpa_s; 926 int c, ret = 1, wait_for_monitor = 0, save_config = 0; 927 char *as_addr = "127.0.0.1"; 928 int as_port = 1812; 929 char *as_secret = "radius"; 930 char *conf = NULL; 931 int timeout = 30; 932 933 if (os_program_init()) 934 return -1; 935 936 os_memset(&eapol_test, 0, sizeof(eapol_test)); 937 eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; 938 os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); 939 940 wpa_debug_level = 0; 941 wpa_debug_show_keys = 1; 942 943 for (;;) { 944 c = getopt(argc, argv, "a:c:C:M:np:r:s:St:W"); 945 if (c < 0) 946 break; 947 switch (c) { 948 case 'a': 949 as_addr = optarg; 950 break; 951 case 'c': 952 conf = optarg; 953 break; 954 case 'C': 955 eapol_test.connect_info = optarg; 956 break; 957 case 'M': 958 if (hwaddr_aton(optarg, eapol_test.own_addr)) { 959 usage(); 960 return -1; 961 } 962 break; 963 case 'n': 964 eapol_test.no_mppe_keys++; 965 break; 966 case 'p': 967 as_port = atoi(optarg); 968 break; 969 case 'r': 970 eapol_test.eapol_test_num_reauths = atoi(optarg); 971 break; 972 case 's': 973 as_secret = optarg; 974 break; 975 case 'S': 976 save_config++; 977 break; 978 case 't': 979 timeout = atoi(optarg); 980 break; 981 case 'W': 982 wait_for_monitor++; 983 break; 984 default: 985 usage(); 986 return -1; 987 } 988 } 989 990 if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { 991 return scard_test(); 992 } 993 994 if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { 995 return scard_get_triplets(argc - optind - 1, 996 &argv[optind + 1]); 997 } 998 999 if (conf == NULL) { 1000 usage(); 1001 printf("Configuration file is required.\n"); 1002 return -1; 1003 } 1004 1005 if (eap_peer_register_methods()) { 1006 wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 1007 return -1; 1008 } 1009 1010 if (eloop_init(&wpa_s)) { 1011 wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 1012 return -1; 1013 } 1014 1015 os_memset(&wpa_s, 0, sizeof(wpa_s)); 1016 eapol_test.wpa_s = &wpa_s; 1017 wpa_s.conf = wpa_config_read(conf); 1018 if (wpa_s.conf == NULL) { 1019 printf("Failed to parse configuration file '%s'.\n", conf); 1020 return -1; 1021 } 1022 if (wpa_s.conf->ssid == NULL) { 1023 printf("No networks defined.\n"); 1024 return -1; 1025 } 1026 1027 wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret); 1028 wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); 1029 if (wpa_s.ctrl_iface == NULL) { 1030 printf("Failed to initialize control interface '%s'.\n" 1031 "You may have another eapol_test process already " 1032 "running or the file was\n" 1033 "left by an unclean termination of eapol_test in " 1034 "which case you will need\n" 1035 "to manually remove this file before starting " 1036 "eapol_test again.\n", 1037 wpa_s.conf->ctrl_interface); 1038 return -1; 1039 } 1040 if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) 1041 return -1; 1042 1043 if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) 1044 return -1; 1045 1046 if (wait_for_monitor) 1047 wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); 1048 1049 eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, 1050 NULL); 1051 eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); 1052 eloop_register_signal_terminate(eapol_test_terminate, NULL); 1053 eloop_register_signal_reconfig(eapol_test_terminate, NULL); 1054 eloop_run(); 1055 1056 eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); 1057 eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); 1058 1059 if (eapol_test_compare_pmk(&eapol_test) == 0 || 1060 eapol_test.no_mppe_keys) 1061 ret = 0; 1062 if (eapol_test.auth_timed_out) 1063 ret = -2; 1064 if (eapol_test.radius_access_reject_received) 1065 ret = -3; 1066 1067 if (save_config) 1068 wpa_config_write(conf, wpa_s.conf); 1069 1070 test_eapol_clean(&eapol_test, &wpa_s); 1071 1072 eap_peer_unregister_methods(); 1073 1074 eloop_destroy(); 1075 1076 printf("MPPE keys OK: %d mismatch: %d\n", 1077 eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); 1078 if (eapol_test.num_mppe_mismatch) 1079 ret = -4; 1080 if (ret) 1081 printf("FAILURE\n"); 1082 else 1083 printf("SUCCESS\n"); 1084 1085 os_program_deinit(); 1086 1087 return ret; 1088} 1089