Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant - test code
      3  * Copyright (c) 2003-2006, 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_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 
     37 extern int wpa_debug_level;
     38 extern int wpa_debug_show_keys;
     39 
     40 struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL };
     41 
     42 
     43 struct eapol_test_data {
     44 	struct wpa_supplicant *wpa_s;
     45 
     46 	int eapol_test_num_reauths;
     47 	int no_mppe_keys;
     48 	int num_mppe_ok, num_mppe_mismatch;
     49 
     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 
     73 static struct eapol_test_data eapol_test;
     74 
     75 
     76 static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx);
     77 
     78 
     79 void 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 
    109 const 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 
    131 int hostapd_ip_diff(struct hostapd_ip_addr *a, struct hostapd_ip_addr *b)
    132 {
    133 	return 0;
    134 }
    135 
    136 
    137 static 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 
    247 static 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 
    261 static 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 
    269 static const struct wpa_config_blob *
    270 eapol_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 
    277 static void eapol_test_eapol_done_cb(void *ctx)
    278 {
    279 	printf("WPA: EAPOL processing complete\n");
    280 }
    281 
    282 
    283 static 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 
    292 static 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 
    328 static 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 
    342 static 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 
    393 static 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 
    421 static 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 
    446 static 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 
    455 static 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 
    476 static 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 
    564 static 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 */
    601 static RadiusRxResult
    602 ieee802_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 
    664 static 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 
    712 static 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 
    810 failed:
    811 	scard_deinit(scard);
    812 
    813 	return 0;
    814 #undef num_triplets
    815 }
    816 
    817 
    818 static 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 
    883 static 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 
    892 static 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 
    923 int 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