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