/*
 * WPA Supplicant - test code
 * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 *
 * IEEE 802.1X Supplicant test code (to be used in place of wpa_supplicant.c.
 * Not used in production version.
 */

#include "includes.h"
#include <assert.h>

#include "common.h"
#include "utils/ext_password.h"
#include "config.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
#include "eap_server/eap_methods.h"
#include "eloop.h"
#include "utils/base64.h"
#include "rsn_supp/wpa.h"
#include "wpa_supplicant_i.h"
#include "radius/radius.h"
#include "radius/radius_client.h"
#include "common/wpa_ctrl.h"
#include "ctrl_iface.h"
#include "pcsc_funcs.h"
#include "wpas_glue.h"


struct wpa_driver_ops *wpa_drivers[] = { NULL };


struct extra_radius_attr {
	u8 type;
	char syntax;
	char *data;
	struct extra_radius_attr *next;
};

struct eapol_test_data {
	struct wpa_supplicant *wpa_s;

	int eapol_test_num_reauths;
	int no_mppe_keys;
	int num_mppe_ok, num_mppe_mismatch;
	int req_eap_key_name;

	u8 radius_identifier;
	struct radius_msg *last_recv_radius;
	struct in_addr own_ip_addr;
	struct radius_client_data *radius;
	struct hostapd_radius_servers *radius_conf;

	 /* last received EAP Response from Authentication Server */
	struct wpabuf *last_eap_radius;

	u8 authenticator_pmk[PMK_LEN];
	size_t authenticator_pmk_len;
	u8 authenticator_eap_key_name[256];
	size_t authenticator_eap_key_name_len;
	int radius_access_accept_received;
	int radius_access_reject_received;
	int auth_timed_out;

	u8 *eap_identity;
	size_t eap_identity_len;

	char *connect_info;
	u8 own_addr[ETH_ALEN];
	struct extra_radius_attr *extra_attrs;

	FILE *server_cert_file;

	const char *pcsc_reader;
	const char *pcsc_pin;
};

static struct eapol_test_data eapol_test;


static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx);


static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
			      int level, const char *txt, size_t len)
{
	if (addr)
		wpa_printf(MSG_DEBUG, "STA " MACSTR ": %s\n",
			   MAC2STR(addr), txt);
	else
		wpa_printf(MSG_DEBUG, "%s", txt);
}


static int add_extra_attr(struct radius_msg *msg,
			  struct extra_radius_attr *attr)
{
	size_t len;
	char *pos;
	u32 val;
	char buf[RADIUS_MAX_ATTR_LEN + 1];

	switch (attr->syntax) {
	case 's':
		os_snprintf(buf, sizeof(buf), "%s", attr->data);
		len = os_strlen(buf);
		break;
	case 'n':
		buf[0] = '\0';
		len = 1;
		break;
	case 'x':
		pos = attr->data;
		if (pos[0] == '0' && pos[1] == 'x')
			pos += 2;
		len = os_strlen(pos);
		if ((len & 1) || (len / 2) > RADIUS_MAX_ATTR_LEN) {
			printf("Invalid extra attribute hexstring\n");
			return -1;
		}
		len /= 2;
		if (hexstr2bin(pos, (u8 *) buf, len) < 0) {
			printf("Invalid extra attribute hexstring\n");
			return -1;
		}
		break;
	case 'd':
		val = htonl(atoi(attr->data));
		os_memcpy(buf, &val, 4);
		len = 4;
		break;
	default:
		printf("Incorrect extra attribute syntax specification\n");
		return -1;
	}

	if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) {
		printf("Could not add attribute %d\n", attr->type);
		return -1;
	}

	return 0;
}


static int add_extra_attrs(struct radius_msg *msg,
			   struct extra_radius_attr *attrs)
{
	struct extra_radius_attr *p;
	for (p = attrs; p; p = p->next) {
		if (add_extra_attr(msg, p) < 0)
			return -1;
	}
	return 0;
}


static struct extra_radius_attr *
find_extra_attr(struct extra_radius_attr *attrs, u8 type)
{
	struct extra_radius_attr *p;
	for (p = attrs; p; p = p->next) {
		if (p->type == type)
			return p;
	}
	return NULL;
}


static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e,
					  const u8 *eap, size_t len)
{
	struct radius_msg *msg;
	char buf[RADIUS_MAX_ATTR_LEN + 1];
	const struct eap_hdr *hdr;
	const u8 *pos;

	wpa_printf(MSG_DEBUG, "Encapsulating EAP message into a RADIUS "
		   "packet");

	e->radius_identifier = radius_client_get_id(e->radius);
	msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
			     e->radius_identifier);
	if (msg == NULL) {
		printf("Could not create net RADIUS packet\n");
		return;
	}

	radius_msg_make_authenticator(msg, (u8 *) e, sizeof(*e));

	hdr = (const struct eap_hdr *) eap;
	pos = (const u8 *) (hdr + 1);
	if (len > sizeof(*hdr) && hdr->code == EAP_CODE_RESPONSE &&
	    pos[0] == EAP_TYPE_IDENTITY) {
		pos++;
		os_free(e->eap_identity);
		e->eap_identity_len = len - sizeof(*hdr) - 1;
		e->eap_identity = os_malloc(e->eap_identity_len);
		if (e->eap_identity) {
			os_memcpy(e->eap_identity, pos, e->eap_identity_len);
			wpa_hexdump(MSG_DEBUG, "Learned identity from "
				    "EAP-Response-Identity",
				    e->eap_identity, e->eap_identity_len);
		}
	}

	if (e->eap_identity &&
	    !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
				 e->eap_identity, e->eap_identity_len)) {
		printf("Could not add User-Name\n");
		goto fail;
	}

	if (e->req_eap_key_name &&
	    !radius_msg_add_attr(msg, RADIUS_ATTR_EAP_KEY_NAME, (u8 *) "\0",
				 1)) {
		printf("Could not add EAP-Key-Name\n");
		goto fail;
	}

	if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_IP_ADDRESS) &&
	    !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
				 (u8 *) &e->own_ip_addr, 4)) {
		printf("Could not add NAS-IP-Address\n");
		goto fail;
	}

	os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
		    MAC2STR(e->wpa_s->own_addr));
	if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CALLING_STATION_ID)
	    &&
	    !radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
				 (u8 *) buf, os_strlen(buf))) {
		printf("Could not add Calling-Station-Id\n");
		goto fail;
	}

	/* TODO: should probably check MTU from driver config; 2304 is max for
	 * IEEE 802.11, but use 1400 to avoid problems with too large packets
	 */
	if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_FRAMED_MTU) &&
	    !radius_msg_add_attr_int32(msg, RADIUS_ATTR_FRAMED_MTU, 1400)) {
		printf("Could not add Framed-MTU\n");
		goto fail;
	}

	if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_NAS_PORT_TYPE) &&
	    !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT_TYPE,
				       RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
		printf("Could not add NAS-Port-Type\n");
		goto fail;
	}

	os_snprintf(buf, sizeof(buf), "%s", e->connect_info);
	if (!find_extra_attr(e->extra_attrs, RADIUS_ATTR_CONNECT_INFO) &&
	    !radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
				 (u8 *) buf, os_strlen(buf))) {
		printf("Could not add Connect-Info\n");
		goto fail;
	}

	if (add_extra_attrs(msg, e->extra_attrs) < 0)
		goto fail;

	if (eap && !radius_msg_add_eap(msg, eap, len)) {
		printf("Could not add EAP-Message\n");
		goto fail;
	}

	/* State attribute must be copied if and only if this packet is
	 * Access-Request reply to the previous Access-Challenge */
	if (e->last_recv_radius &&
	    radius_msg_get_hdr(e->last_recv_radius)->code ==
	    RADIUS_CODE_ACCESS_CHALLENGE) {
		int res = radius_msg_copy_attr(msg, e->last_recv_radius,
					       RADIUS_ATTR_STATE);
		if (res < 0) {
			printf("Could not copy State attribute from previous "
			       "Access-Challenge\n");
			goto fail;
		}
		if (res > 0) {
			wpa_printf(MSG_DEBUG, "  Copied RADIUS State "
				   "Attribute");
		}
	}

	if (radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr)
	    < 0)
		goto fail;
	return;

 fail:
	radius_msg_free(msg);
}


static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf,
				 size_t len)
{
	printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n",
	       type, (unsigned long) len);
	if (type == IEEE802_1X_TYPE_EAP_PACKET) {
		wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len);
		ieee802_1x_encapsulate_radius(&eapol_test, buf, len);
	}
	return 0;
}


static void eapol_test_set_config_blob(void *ctx,
				       struct wpa_config_blob *blob)
{
	struct eapol_test_data *e = ctx;
	wpa_config_set_blob(e->wpa_s->conf, blob);
}


static const struct wpa_config_blob *
eapol_test_get_config_blob(void *ctx, const char *name)
{
	struct eapol_test_data *e = ctx;
	return wpa_config_get_blob(e->wpa_s->conf, name);
}


static void eapol_test_eapol_done_cb(void *ctx)
{
	printf("WPA: EAPOL processing complete\n");
}


static void eapol_sm_reauth(void *eloop_ctx, void *timeout_ctx)
{
	struct eapol_test_data *e = eloop_ctx;
	printf("\n\n\n\n\neapol_test: Triggering EAP reauthentication\n\n");
	e->radius_access_accept_received = 0;
	send_eap_request_identity(e->wpa_s, NULL);
}


static int eapol_test_compare_pmk(struct eapol_test_data *e)
{
	u8 pmk[PMK_LEN];
	int ret = 1;
	const u8 *sess_id;
	size_t sess_id_len;

	if (eapol_sm_get_key(e->wpa_s->eapol, pmk, PMK_LEN) == 0) {
		wpa_hexdump(MSG_DEBUG, "PMK from EAPOL", pmk, PMK_LEN);
		if (os_memcmp(pmk, e->authenticator_pmk, PMK_LEN) != 0) {
			printf("WARNING: PMK mismatch\n");
			wpa_hexdump(MSG_DEBUG, "PMK from AS",
				    e->authenticator_pmk, PMK_LEN);
		} else if (e->radius_access_accept_received)
			ret = 0;
	} else if (e->authenticator_pmk_len == 16 &&
		   eapol_sm_get_key(e->wpa_s->eapol, pmk, 16) == 0) {
		wpa_hexdump(MSG_DEBUG, "LEAP PMK from EAPOL", pmk, 16);
		if (os_memcmp(pmk, e->authenticator_pmk, 16) != 0) {
			printf("WARNING: PMK mismatch\n");
			wpa_hexdump(MSG_DEBUG, "PMK from AS",
				    e->authenticator_pmk, 16);
		} else if (e->radius_access_accept_received)
			ret = 0;
	} else if (e->radius_access_accept_received && e->no_mppe_keys) {
		/* No keying material expected */
		ret = 0;
	}

	if (ret && !e->no_mppe_keys)
		e->num_mppe_mismatch++;
	else if (!e->no_mppe_keys)
		e->num_mppe_ok++;

	sess_id = eapol_sm_get_session_id(e->wpa_s->eapol, &sess_id_len);
	if (!sess_id)
		return ret;
	if (e->authenticator_eap_key_name_len == 0) {
		wpa_printf(MSG_INFO, "No EAP-Key-Name received from server");
		return ret;
	}

	if (e->authenticator_eap_key_name_len != sess_id_len ||
	    os_memcmp(e->authenticator_eap_key_name, sess_id, sess_id_len) != 0)
	{
		wpa_printf(MSG_INFO,
			   "Locally derived EAP Session-Id does not match EAP-Key-Name from server");
		wpa_hexdump(MSG_DEBUG, "EAP Session-Id", sess_id, sess_id_len);
		wpa_hexdump(MSG_DEBUG, "EAP-Key-Name from server",
			    e->authenticator_eap_key_name,
			    e->authenticator_eap_key_name_len);
	} else {
		wpa_printf(MSG_INFO,
			   "Locally derived EAP Session-Id matches EAP-Key-Name from server");
	}

	return ret;
}


static void eapol_sm_cb(struct eapol_sm *eapol, enum eapol_supp_result result,
			void *ctx)
{
	struct eapol_test_data *e = ctx;
	printf("eapol_sm_cb: result=%d\n", result);
	e->eapol_test_num_reauths--;
	if (e->eapol_test_num_reauths < 0)
		eloop_terminate();
	else {
		eapol_test_compare_pmk(e);
		eloop_register_timeout(0, 100000, eapol_sm_reauth, e, NULL);
	}
}


static void eapol_test_write_cert(FILE *f, const char *subject,
				  const struct wpabuf *cert)
{
	unsigned char *encoded;

	encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL);
	if (encoded == NULL)
		return;
	fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s"
		"-----END CERTIFICATE-----\n\n", subject, encoded);
	os_free(encoded);
}


#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
static void eapol_test_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field,
					const char *default_txt)
{
	struct eapol_test_data *e = ctx;
	struct wpa_supplicant *wpa_s = e->wpa_s;
	struct wpa_ssid *ssid = wpa_s->current_ssid;
	const char *field_name, *txt = NULL;
	char *buf;
	size_t buflen;
	int len;

	if (ssid == NULL)
		return;

	field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,
						       &txt);
	if (field_name == NULL) {
		wpa_printf(MSG_WARNING, "Unhandled EAP param %d needed",
			   field);
		return;
	}

	buflen = 100 + os_strlen(txt) + ssid->ssid_len;
	buf = os_malloc(buflen);
	if (buf == NULL)
		return;
	len = os_snprintf(buf, buflen,
			  WPA_CTRL_REQ "%s-%d:%s needed for SSID ",
			  field_name, ssid->id, txt);
	if (os_snprintf_error(buflen, len)) {
		os_free(buf);
		return;
	}
	if (ssid->ssid && buflen > len + ssid->ssid_len) {
		os_memcpy(buf + len, ssid->ssid, ssid->ssid_len);
		len += ssid->ssid_len;
		buf[len] = '\0';
	}
	buf[buflen - 1] = '\0';
	wpa_msg(wpa_s, MSG_INFO, "%s", buf);
	os_free(buf);
}
#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
#define eapol_test_eap_param_needed NULL
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */


static void eapol_test_cert_cb(void *ctx, int depth, const char *subject,
			       const char *cert_hash,
			       const struct wpabuf *cert)
{
	struct eapol_test_data *e = ctx;

	wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
		"depth=%d subject='%s'%s%s",
		depth, subject,
		cert_hash ? " hash=" : "",
		cert_hash ? cert_hash : "");

	if (cert) {
		char *cert_hex;
		size_t len = wpabuf_len(cert) * 2 + 1;
		cert_hex = os_malloc(len);
		if (cert_hex) {
			wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert),
					 wpabuf_len(cert));
			wpa_msg_ctrl(e->wpa_s, MSG_INFO,
				     WPA_EVENT_EAP_PEER_CERT
				     "depth=%d subject='%s' cert=%s",
				     depth, subject, cert_hex);
			os_free(cert_hex);
		}

		if (e->server_cert_file)
			eapol_test_write_cert(e->server_cert_file,
					      subject, cert);
	}
}


static void eapol_test_set_anon_id(void *ctx, const u8 *id, size_t len)
{
	struct eapol_test_data *e = ctx;
	struct wpa_supplicant *wpa_s = e->wpa_s;
	char *str;
	int res;

	wpa_hexdump_ascii(MSG_DEBUG, "EAP method updated anonymous_identity",
			  id, len);

	if (wpa_s->current_ssid == NULL)
		return;

	if (id == NULL) {
		if (wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
				   "NULL", 0) < 0)
			return;
	} else {
		str = os_malloc(len * 2 + 1);
		if (str == NULL)
			return;
		wpa_snprintf_hex(str, len * 2 + 1, id, len);
		res = wpa_config_set(wpa_s->current_ssid, "anonymous_identity",
				     str, 0);
		os_free(str);
		if (res < 0)
			return;
	}
}


static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
		      struct wpa_ssid *ssid)
{
	struct eapol_config eapol_conf;
	struct eapol_ctx *ctx;

	ctx = os_zalloc(sizeof(*ctx));
	if (ctx == NULL) {
		printf("Failed to allocate EAPOL context.\n");
		return -1;
	}
	ctx->ctx = e;
	ctx->msg_ctx = wpa_s;
	ctx->scard_ctx = wpa_s->scard;
	ctx->cb = eapol_sm_cb;
	ctx->cb_ctx = e;
	ctx->eapol_send_ctx = wpa_s;
	ctx->preauth = 0;
	ctx->eapol_done_cb = eapol_test_eapol_done_cb;
	ctx->eapol_send = eapol_test_eapol_send;
	ctx->set_config_blob = eapol_test_set_config_blob;
	ctx->get_config_blob = eapol_test_get_config_blob;
	ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
	ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
	ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
	ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers;
	ctx->eap_param_needed = eapol_test_eap_param_needed;
	ctx->cert_cb = eapol_test_cert_cb;
	ctx->cert_in_cb = 1;
	ctx->set_anon_id = eapol_test_set_anon_id;

	wpa_s->eapol = eapol_sm_init(ctx);
	if (wpa_s->eapol == NULL) {
		os_free(ctx);
		printf("Failed to initialize EAPOL state machines.\n");
		return -1;
	}

	wpa_s->current_ssid = ssid;
	os_memset(&eapol_conf, 0, sizeof(eapol_conf));
	eapol_conf.accept_802_1x_keys = 1;
	eapol_conf.required_keys = 0;
	eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
	eapol_conf.workaround = ssid->eap_workaround;
	eapol_conf.external_sim = wpa_s->conf->external_sim;
	eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
	eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);


	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
	/* 802.1X::portControl = Auto */
	eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);

	return 0;
}


static void test_eapol_clean(struct eapol_test_data *e,
			     struct wpa_supplicant *wpa_s)
{
	struct extra_radius_attr *p, *prev;

	radius_client_deinit(e->radius);
	wpabuf_free(e->last_eap_radius);
	radius_msg_free(e->last_recv_radius);
	e->last_recv_radius = NULL;
	os_free(e->eap_identity);
	e->eap_identity = NULL;
	eapol_sm_deinit(wpa_s->eapol);
	wpa_s->eapol = NULL;
	if (e->radius_conf && e->radius_conf->auth_server) {
		os_free(e->radius_conf->auth_server->shared_secret);
		os_free(e->radius_conf->auth_server);
	}
	os_free(e->radius_conf);
	e->radius_conf = NULL;
	scard_deinit(wpa_s->scard);
	if (wpa_s->ctrl_iface) {
		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
		wpa_s->ctrl_iface = NULL;
	}

	ext_password_deinit(wpa_s->ext_pw);
	wpa_s->ext_pw = NULL;

	wpa_config_free(wpa_s->conf);

	p = e->extra_attrs;
	while (p) {
		prev = p;
		p = p->next;
		os_free(prev);
	}
}


static void send_eap_request_identity(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_supplicant *wpa_s = eloop_ctx;
	u8 buf[100], *pos;
	struct ieee802_1x_hdr *hdr;
	struct eap_hdr *eap;

	hdr = (struct ieee802_1x_hdr *) buf;
	hdr->version = EAPOL_VERSION;
	hdr->type = IEEE802_1X_TYPE_EAP_PACKET;
	hdr->length = htons(5);

	eap = (struct eap_hdr *) (hdr + 1);
	eap->code = EAP_CODE_REQUEST;
	eap->identifier = 0;
	eap->length = htons(5);
	pos = (u8 *) (eap + 1);
	*pos = EAP_TYPE_IDENTITY;

	printf("Sending fake EAP-Request-Identity\n");
	eapol_sm_rx_eapol(wpa_s->eapol, wpa_s->bssid, buf,
			  sizeof(*hdr) + 5);
}


static void eapol_test_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct eapol_test_data *e = eloop_ctx;
	printf("EAPOL test timed out\n");
	e->auth_timed_out = 1;
	eloop_terminate();
}


static char *eap_type_text(u8 type)
{
	switch (type) {
	case EAP_TYPE_IDENTITY: return "Identity";
	case EAP_TYPE_NOTIFICATION: return "Notification";
	case EAP_TYPE_NAK: return "Nak";
	case EAP_TYPE_TLS: return "TLS";
	case EAP_TYPE_TTLS: return "TTLS";
	case EAP_TYPE_PEAP: return "PEAP";
	case EAP_TYPE_SIM: return "SIM";
	case EAP_TYPE_GTC: return "GTC";
	case EAP_TYPE_MD5: return "MD5";
	case EAP_TYPE_OTP: return "OTP";
	case EAP_TYPE_FAST: return "FAST";
	case EAP_TYPE_SAKE: return "SAKE";
	case EAP_TYPE_PSK: return "PSK";
	default: return "Unknown";
	}
}


static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
{
	struct wpabuf *eap;
	const struct eap_hdr *hdr;
	int eap_type = -1;
	char buf[64];
	struct radius_msg *msg;

	if (e->last_recv_radius == NULL)
		return;

	msg = e->last_recv_radius;

	eap = radius_msg_get_eap(msg);
	if (eap == NULL) {
		/* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
		 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
		 * attribute */
		wpa_printf(MSG_DEBUG, "could not extract "
			       "EAP-Message from RADIUS message");
		wpabuf_free(e->last_eap_radius);
		e->last_eap_radius = NULL;
		return;
	}

	if (wpabuf_len(eap) < sizeof(*hdr)) {
		wpa_printf(MSG_DEBUG, "too short EAP packet "
			       "received from authentication server");
		wpabuf_free(eap);
		return;
	}

	if (wpabuf_len(eap) > sizeof(*hdr))
		eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];

	hdr = wpabuf_head(eap);
	switch (hdr->code) {
	case EAP_CODE_REQUEST:
		os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
			    eap_type >= 0 ? eap_type_text(eap_type) : "??",
			    eap_type);
		break;
	case EAP_CODE_RESPONSE:
		os_snprintf(buf, sizeof(buf), "EAP Response-%s (%d)",
			    eap_type >= 0 ? eap_type_text(eap_type) : "??",
			    eap_type);
		break;
	case EAP_CODE_SUCCESS:
		os_strlcpy(buf, "EAP Success", sizeof(buf));
		/* LEAP uses EAP Success within an authentication, so must not
		 * stop here with eloop_terminate(); */
		break;
	case EAP_CODE_FAILURE:
		os_strlcpy(buf, "EAP Failure", sizeof(buf));
		eloop_terminate();
		break;
	default:
		os_strlcpy(buf, "unknown EAP code", sizeof(buf));
		wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap);
		break;
	}
	wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d "
		       "id=%d len=%d) from RADIUS server: %s",
		      hdr->code, hdr->identifier, ntohs(hdr->length), buf);

	/* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */

	wpabuf_free(e->last_eap_radius);
	e->last_eap_radius = eap;

	{
		struct ieee802_1x_hdr *dot1x;
		dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap));
		assert(dot1x != NULL);
		dot1x->version = EAPOL_VERSION;
		dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
		dot1x->length = htons(wpabuf_len(eap));
		os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap),
			  wpabuf_len(eap));
		eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
				  (u8 *) dot1x,
				  sizeof(*dot1x) + wpabuf_len(eap));
		os_free(dot1x);
	}
}


static void ieee802_1x_get_keys(struct eapol_test_data *e,
				struct radius_msg *msg, struct radius_msg *req,
				const u8 *shared_secret,
				size_t shared_secret_len)
{
	struct radius_ms_mppe_keys *keys;
	u8 *buf;
	size_t len;

	keys = radius_msg_get_ms_keys(msg, req, shared_secret,
				      shared_secret_len);
	if (keys && keys->send == NULL && keys->recv == NULL) {
		os_free(keys);
		keys = radius_msg_get_cisco_keys(msg, req, shared_secret,
						 shared_secret_len);
	}

	if (keys) {
		if (keys->send) {
			wpa_hexdump(MSG_DEBUG, "MS-MPPE-Send-Key (sign)",
				    keys->send, keys->send_len);
		}
		if (keys->recv) {
			wpa_hexdump(MSG_DEBUG, "MS-MPPE-Recv-Key (crypt)",
				    keys->recv, keys->recv_len);
			e->authenticator_pmk_len =
				keys->recv_len > PMK_LEN ? PMK_LEN :
				keys->recv_len;
			os_memcpy(e->authenticator_pmk, keys->recv,
				  e->authenticator_pmk_len);
			if (e->authenticator_pmk_len == 16 && keys->send &&
			    keys->send_len == 16) {
				/* MS-CHAP-v2 derives 16 octet keys */
				wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key "
					   "to extend PMK to 32 octets");
				os_memcpy(e->authenticator_pmk +
					  e->authenticator_pmk_len,
					  keys->send, keys->send_len);
				e->authenticator_pmk_len += keys->send_len;
			}
		}

		os_free(keys->send);
		os_free(keys->recv);
		os_free(keys);
	}

	if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_EAP_KEY_NAME, &buf, &len,
				    NULL) == 0) {
		os_memcpy(e->authenticator_eap_key_name, buf, len);
		e->authenticator_eap_key_name_len = len;
	} else {
		e->authenticator_eap_key_name_len = 0;
	}
}


/* Process the RADIUS frames from Authentication Server */
static RadiusRxResult
ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
			const u8 *shared_secret, size_t shared_secret_len,
			void *data)
{
	struct eapol_test_data *e = data;
	struct radius_hdr *hdr = radius_msg_get_hdr(msg);

	/* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
	 * present when packet contains an EAP-Message attribute */
	if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
	    radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
				0) < 0 &&
	    radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
		wpa_printf(MSG_DEBUG, "Allowing RADIUS "
			      "Access-Reject without Message-Authenticator "
			      "since it does not include EAP-Message\n");
	} else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
				     req, 1)) {
		printf("Incoming RADIUS packet did not have correct "
		       "Message-Authenticator - dropped\n");
		return RADIUS_RX_UNKNOWN;
	}

	if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
	    hdr->code != RADIUS_CODE_ACCESS_REJECT &&
	    hdr->code != RADIUS_CODE_ACCESS_CHALLENGE) {
		printf("Unknown RADIUS message code\n");
		return RADIUS_RX_UNKNOWN;
	}

	e->radius_identifier = -1;
	wpa_printf(MSG_DEBUG, "RADIUS packet matching with station");

	radius_msg_free(e->last_recv_radius);
	e->last_recv_radius = msg;

	switch (hdr->code) {
	case RADIUS_CODE_ACCESS_ACCEPT:
		e->radius_access_accept_received = 1;
		ieee802_1x_get_keys(e, msg, req, shared_secret,
				    shared_secret_len);
		break;
	case RADIUS_CODE_ACCESS_REJECT:
		e->radius_access_reject_received = 1;
		break;
	}

	ieee802_1x_decapsulate_radius(e);

	if ((hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
	     e->eapol_test_num_reauths < 0) ||
	    hdr->code == RADIUS_CODE_ACCESS_REJECT) {
		eloop_terminate();
	}

	return RADIUS_RX_QUEUED;
}


static void wpa_init_conf(struct eapol_test_data *e,
			  struct wpa_supplicant *wpa_s, const char *authsrv,
			  int port, const char *secret,
			  const char *cli_addr)
{
	struct hostapd_radius_server *as;
	int res;

	wpa_s->bssid[5] = 1;
	os_memcpy(wpa_s->own_addr, e->own_addr, ETH_ALEN);
	e->own_ip_addr.s_addr = htonl((127 << 24) | 1);
	os_strlcpy(wpa_s->ifname, "test", sizeof(wpa_s->ifname));

	e->radius_conf = os_zalloc(sizeof(struct hostapd_radius_servers));
	assert(e->radius_conf != NULL);
	e->radius_conf->num_auth_servers = 1;
	as = os_zalloc(sizeof(struct hostapd_radius_server));
	assert(as != NULL);
#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
	{
		int a[4];
		u8 *pos;
		sscanf(authsrv, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
		pos = (u8 *) &as->addr.u.v4;
		*pos++ = a[0];
		*pos++ = a[1];
		*pos++ = a[2];
		*pos++ = a[3];
	}
#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
	if (inet_aton(authsrv, &as->addr.u.v4) < 0) {
		wpa_printf(MSG_ERROR, "Invalid IP address '%s'",
			   authsrv);
		assert(0);
	}
#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
	as->addr.af = AF_INET;
	as->port = port;
	as->shared_secret = (u8 *) os_strdup(secret);
	as->shared_secret_len = os_strlen(secret);
	e->radius_conf->auth_server = as;
	e->radius_conf->auth_servers = as;
	e->radius_conf->msg_dumps = 1;
	if (cli_addr) {
		if (hostapd_parse_ip_addr(cli_addr,
					  &e->radius_conf->client_addr) == 0)
			e->radius_conf->force_client_addr = 1;
		else {
			wpa_printf(MSG_ERROR, "Invalid IP address '%s'",
				   cli_addr);
			assert(0);
		}
	}

	e->radius = radius_client_init(wpa_s, e->radius_conf);
	assert(e->radius != NULL);

	res = radius_client_register(e->radius, RADIUS_AUTH,
				     ieee802_1x_receive_auth, e);
	assert(res == 0);
}


static int scard_test(struct eapol_test_data *e)
{
	struct scard_data *scard;
	size_t len;
	char imsi[20];
	unsigned char _rand[16];
#ifdef PCSC_FUNCS
	unsigned char sres[4];
	unsigned char kc[8];
#endif /* PCSC_FUNCS */
#define num_triplets 5
	unsigned char rand_[num_triplets][16];
	unsigned char sres_[num_triplets][4];
	unsigned char kc_[num_triplets][8];
	int i, res;
	size_t j;

#define AKA_RAND_LEN 16
#define AKA_AUTN_LEN 16
#define AKA_AUTS_LEN 14
#define RES_MAX_LEN 16
#define IK_LEN 16
#define CK_LEN 16
	unsigned char aka_rand[AKA_RAND_LEN];
	unsigned char aka_autn[AKA_AUTN_LEN];
	unsigned char aka_auts[AKA_AUTS_LEN];
	unsigned char aka_res[RES_MAX_LEN];
	size_t aka_res_len;
	unsigned char aka_ik[IK_LEN];
	unsigned char aka_ck[CK_LEN];

	scard = scard_init(e->pcsc_reader);
	if (scard == NULL)
		return -1;
	if (scard_set_pin(scard, e->pcsc_pin)) {
		wpa_printf(MSG_WARNING, "PIN validation failed");
		scard_deinit(scard);
		return -1;
	}

	len = sizeof(imsi);
	if (scard_get_imsi(scard, imsi, &len))
		goto failed;
	wpa_hexdump_ascii(MSG_DEBUG, "SCARD: IMSI", (u8 *) imsi, len);
	/* NOTE: Permanent Username: 1 | IMSI */

	wpa_printf(MSG_DEBUG, "SCARD: MNC length %d",
		   scard_get_mnc_len(scard));

	os_memset(_rand, 0, sizeof(_rand));
	if (scard_gsm_auth(scard, _rand, sres, kc))
		goto failed;

	os_memset(_rand, 0xff, sizeof(_rand));
	if (scard_gsm_auth(scard, _rand, sres, kc))
		goto failed;

	for (i = 0; i < num_triplets; i++) {
		os_memset(rand_[i], i, sizeof(rand_[i]));
		if (scard_gsm_auth(scard, rand_[i], sres_[i], kc_[i]))
			goto failed;
	}

	for (i = 0; i < num_triplets; i++) {
		printf("1");
		for (j = 0; j < len; j++)
			printf("%c", imsi[j]);
		printf(",");
		for (j = 0; j < 16; j++)
			printf("%02X", rand_[i][j]);
		printf(",");
		for (j = 0; j < 4; j++)
			printf("%02X", sres_[i][j]);
		printf(",");
		for (j = 0; j < 8; j++)
			printf("%02X", kc_[i][j]);
		printf("\n");
	}

	wpa_printf(MSG_DEBUG, "Trying to use UMTS authentication");

	/* seq 39 (0x28) */
	os_memset(aka_rand, 0xaa, 16);
	os_memcpy(aka_autn, "\x86\x71\x31\xcb\xa2\xfc\x61\xdf"
		  "\xa3\xb3\x97\x9d\x07\x32\xa2\x12", 16);

	res = scard_umts_auth(scard, aka_rand, aka_autn, aka_res, &aka_res_len,
			      aka_ik, aka_ck, aka_auts);
	if (res == 0) {
		wpa_printf(MSG_DEBUG, "UMTS auth completed successfully");
		wpa_hexdump(MSG_DEBUG, "RES", aka_res, aka_res_len);
		wpa_hexdump(MSG_DEBUG, "IK", aka_ik, IK_LEN);
		wpa_hexdump(MSG_DEBUG, "CK", aka_ck, CK_LEN);
	} else if (res == -2) {
		wpa_printf(MSG_DEBUG, "UMTS auth resulted in synchronization "
			   "failure");
		wpa_hexdump(MSG_DEBUG, "AUTS", aka_auts, AKA_AUTS_LEN);
	} else {
		wpa_printf(MSG_DEBUG, "UMTS auth failed");
	}

failed:
	scard_deinit(scard);

	return 0;
#undef num_triplets
}


static int scard_get_triplets(struct eapol_test_data *e, int argc, char *argv[])
{
	struct scard_data *scard;
	size_t len;
	char imsi[20];
	unsigned char _rand[16];
	unsigned char sres[4];
	unsigned char kc[8];
	int num_triplets;
	int i;
	size_t j;

	if (argc < 2 || ((num_triplets = atoi(argv[1])) <= 0)) {
		printf("invalid parameters for sim command\n");
		return -1;
	}

	if (argc <= 2 || os_strcmp(argv[2], "debug") != 0) {
		/* disable debug output */
		wpa_debug_level = 99;
	}

	scard = scard_init(e->pcsc_reader);
	if (scard == NULL) {
		printf("Failed to open smartcard connection\n");
		return -1;
	}
	if (scard_set_pin(scard, argv[0])) {
		wpa_printf(MSG_WARNING, "PIN validation failed");
		scard_deinit(scard);
		return -1;
	}

	len = sizeof(imsi);
	if (scard_get_imsi(scard, imsi, &len)) {
		scard_deinit(scard);
		return -1;
	}

	for (i = 0; i < num_triplets; i++) {
		os_memset(_rand, i, sizeof(_rand));
		if (scard_gsm_auth(scard, _rand, sres, kc))
			break;

		/* IMSI:Kc:SRES:RAND */
		for (j = 0; j < len; j++)
			printf("%c", imsi[j]);
		printf(":");
		for (j = 0; j < 8; j++)
			printf("%02X", kc[j]);
		printf(":");
		for (j = 0; j < 4; j++)
			printf("%02X", sres[j]);
		printf(":");
		for (j = 0; j < 16; j++)
			printf("%02X", _rand[j]);
		printf("\n");
	}

	scard_deinit(scard);

	return 0;
}


static void eapol_test_terminate(int sig, void *signal_ctx)
{
	struct wpa_supplicant *wpa_s = signal_ctx;
	wpa_msg(wpa_s, MSG_INFO, "Signal %d received - terminating", sig);
	eloop_terminate();
}


static void usage(void)
{
	printf("usage:\n"
	       "eapol_test [-enWS] -c<conf> [-a<AS IP>] [-p<AS port>] "
	       "[-s<AS secret>]\\\n"
	       "           [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
	       "           [-M<client MAC address>] [-o<server cert file] \\\n"
	       "           [-N<attr spec>] [-R<PC/SC reader>] "
	       "[-P<PC/SC PIN>] \\\n"
	       "           [-A<client IP>]\n"
	       "eapol_test scard\n"
	       "eapol_test sim <PIN> <num triplets> [debug]\n"
	       "\n");
	printf("options:\n"
	       "  -c<conf> = configuration file\n"
	       "  -a<AS IP> = IP address of the authentication server, "
	       "default 127.0.0.1\n"
	       "  -p<AS port> = UDP port of the authentication server, "
	       "default 1812\n"
	       "  -s<AS secret> = shared secret with the authentication "
	       "server, default 'radius'\n"
	       "  -A<client IP> = IP address of the client, default: select "
	       "automatically\n"
	       "  -r<count> = number of re-authentications\n"
	       "  -e = Request EAP-Key-Name\n"
	       "  -W = wait for a control interface monitor before starting\n"
	       "  -S = save configuration after authentication\n"
	       "  -n = no MPPE keys expected\n"
	       "  -t<timeout> = sets timeout in seconds (default: 30 s)\n"
	       "  -C<Connect-Info> = RADIUS Connect-Info (default: "
	       "CONNECT 11Mbps 802.11b)\n"
	       "  -M<client MAC address> = Set own MAC address "
	       "(Calling-Station-Id,\n"
	       "                           default: 02:00:00:00:00:01)\n"
	       "  -o<server cert file> = Write received server certificate\n"
	       "                         chain to the specified file\n"
	       "  -N<attr spec> = send arbitrary attribute specified by:\n"
	       "                  attr_id:syntax:value or attr_id\n"
	       "                  attr_id - number id of the attribute\n"
	       "                  syntax - one of: s, d, x\n"
	       "                     s = string\n"
	       "                     d = integer\n"
	       "                     x = octet string\n"
	       "                  value - attribute value.\n"
	       "       When only attr_id is specified, NULL will be used as "
	       "value.\n"
	       "       Multiple attributes can be specified by using the "
	       "option several times.\n");
}


int main(int argc, char *argv[])
{
	struct wpa_global global;
	struct wpa_supplicant wpa_s;
	int c, ret = 1, wait_for_monitor = 0, save_config = 0;
	char *as_addr = "127.0.0.1";
	int as_port = 1812;
	char *as_secret = "radius";
	char *cli_addr = NULL;
	char *conf = NULL;
	int timeout = 30;
	char *pos;
	struct extra_radius_attr *p = NULL, *p1;

	if (os_program_init())
		return -1;

	hostapd_logger_register_cb(hostapd_logger_cb);

	os_memset(&eapol_test, 0, sizeof(eapol_test));
	eapol_test.connect_info = "CONNECT 11Mbps 802.11b";
	os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN);
	eapol_test.pcsc_pin = "1234";

	wpa_debug_level = 0;
	wpa_debug_show_keys = 1;

	for (;;) {
		c = getopt(argc, argv, "a:A:c:C:eM:nN:o:p:P:r:R:s:St:W");
		if (c < 0)
			break;
		switch (c) {
		case 'a':
			as_addr = optarg;
			break;
		case 'A':
			cli_addr = optarg;
			break;
		case 'c':
			conf = optarg;
			break;
		case 'C':
			eapol_test.connect_info = optarg;
			break;
		case 'e':
			eapol_test.req_eap_key_name = 1;
			break;
		case 'M':
			if (hwaddr_aton(optarg, eapol_test.own_addr)) {
				usage();
				return -1;
			}
			break;
		case 'n':
			eapol_test.no_mppe_keys++;
			break;
		case 'o':
			if (eapol_test.server_cert_file)
				fclose(eapol_test.server_cert_file);
			eapol_test.server_cert_file = fopen(optarg, "w");
			if (eapol_test.server_cert_file == NULL) {
				printf("Could not open '%s' for writing\n",
				       optarg);
				return -1;
			}
			break;
		case 'p':
			as_port = atoi(optarg);
			break;
		case 'P':
			eapol_test.pcsc_pin = optarg;
			break;
		case 'r':
			eapol_test.eapol_test_num_reauths = atoi(optarg);
			break;
		case 'R':
			eapol_test.pcsc_reader = optarg;
			break;
		case 's':
			as_secret = optarg;
			break;
		case 'S':
			save_config++;
			break;
		case 't':
			timeout = atoi(optarg);
			break;
		case 'W':
			wait_for_monitor++;
			break;
		case 'N':
			p1 = os_zalloc(sizeof(*p1));
			if (p1 == NULL)
				break;
			if (!p)
				eapol_test.extra_attrs = p1;
			else
				p->next = p1;
			p = p1;

			p->type = atoi(optarg);
			pos = os_strchr(optarg, ':');
			if (pos == NULL) {
				p->syntax = 'n';
				p->data = NULL;
				break;
			}

			pos++;
			if (pos[0] == '\0' || pos[1] != ':') {
				printf("Incorrect format of attribute "
				       "specification\n");
				break;
			}

			p->syntax = pos[0];
			p->data = pos + 2;
			break;
		default:
			usage();
			return -1;
		}
	}

	if (argc > optind && os_strcmp(argv[optind], "scard") == 0) {
		return scard_test(&eapol_test);
	}

	if (argc > optind && os_strcmp(argv[optind], "sim") == 0) {
		return scard_get_triplets(&eapol_test, argc - optind - 1,
					  &argv[optind + 1]);
	}

	if (conf == NULL) {
		usage();
		printf("Configuration file is required.\n");
		return -1;
	}

	if (eap_register_methods()) {
		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
		return -1;
	}

	if (eloop_init()) {
		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
		return -1;
	}

	os_memset(&global, 0, sizeof(global));
	os_memset(&wpa_s, 0, sizeof(wpa_s));
	wpa_s.global = &global;
	eapol_test.wpa_s = &wpa_s;
	dl_list_init(&wpa_s.bss);
	dl_list_init(&wpa_s.bss_id);
	wpa_s.conf = wpa_config_read(conf, NULL);
	if (wpa_s.conf == NULL) {
		printf("Failed to parse configuration file '%s'.\n", conf);
		return -1;
	}
	if (wpa_s.conf->ssid == NULL) {
		printf("No networks defined.\n");
		return -1;
	}

	if (eapol_test.pcsc_reader) {
		os_free(wpa_s.conf->pcsc_reader);
		wpa_s.conf->pcsc_reader = os_strdup(eapol_test.pcsc_reader);
	}

	wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret,
		      cli_addr);
	wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s);
	if (wpa_s.ctrl_iface == NULL) {
		printf("Failed to initialize control interface '%s'.\n"
		       "You may have another eapol_test process already "
		       "running or the file was\n"
		       "left by an unclean termination of eapol_test in "
		       "which case you will need\n"
		       "to manually remove this file before starting "
		       "eapol_test again.\n",
		       wpa_s.conf->ctrl_interface);
		return -1;
	}
	if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid))
		return -1;

	if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid))
		return -1;

	if (wpas_init_ext_pw(&wpa_s) < 0)
		return -1;

	if (wait_for_monitor)
		wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface);

	eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test,
			       NULL);
	eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL);
	eloop_register_signal_terminate(eapol_test_terminate, &wpa_s);
	eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s);
	eloop_run();

	eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL);
	eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL);

	if (eapol_test_compare_pmk(&eapol_test) == 0 ||
	    eapol_test.no_mppe_keys)
		ret = 0;
	if (eapol_test.auth_timed_out)
		ret = -2;
	if (eapol_test.radius_access_reject_received)
		ret = -3;

	if (save_config)
		wpa_config_write(conf, wpa_s.conf);

	test_eapol_clean(&eapol_test, &wpa_s);

	eap_peer_unregister_methods();
#ifdef CONFIG_AP
	eap_server_unregister_methods();
#endif /* CONFIG_AP */

	eloop_destroy();

	if (eapol_test.server_cert_file)
		fclose(eapol_test.server_cert_file);

	printf("MPPE keys OK: %d  mismatch: %d\n",
	       eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch);
	if (eapol_test.num_mppe_mismatch)
		ret = -4;
	if (ret)
		printf("FAILURE\n");
	else
		printf("SUCCESS\n");

	os_program_deinit();

	return ret;
}
