/*
 * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
 *
 * Copyright (c) 2001 by Sun Microsystems, Inc.
 * All rights reserved.
 *
 * Non-exclusive rights to redistribute, modify, translate, and use
 * this software in source and binary forms, in whole or in part, is
 * hereby granted, provided that the above copyright notice is
 * duplicated in any source form, and that neither the name of the
 * copyright holder nor the author is used to endorse or promote
 * products derived from this software.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Original version by James Carlson
 *
 * This implementation of EAP supports MD5-Challenge and SRP-SHA1
 * authentication styles.  Note that support of MD5-Challenge is a
 * requirement of RFC 2284, and that it's essentially just a
 * reimplementation of regular RFC 1994 CHAP using EAP messages.
 *
 * As an authenticator ("server"), there are multiple phases for each
 * style.  In the first phase of each style, the unauthenticated peer
 * name is queried using the EAP Identity request type.  If the
 * "remotename" option is used, then this phase is skipped, because
 * the peer's name is presumed to be known.
 *
 * For MD5-Challenge, there are two phases, and the second phase
 * consists of sending the challenge itself and handling the
 * associated response.
 *
 * For SRP-SHA1, there are four phases.  The second sends 's', 'N',
 * and 'g'.  The reply contains 'A'.  The third sends 'B', and the
 * reply contains 'M1'.  The forth sends the 'M2' value.
 *
 * As an authenticatee ("client"), there's just a single phase --
 * responding to the queries generated by the peer.  EAP is an
 * authenticator-driven protocol.
 *
 * Based on draft-ietf-pppext-eap-srp-03.txt.
 */

#define RCSID	"$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"

/*
 * TODO:
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>

#include "pppd.h"
#include "pathnames.h"
#include "md5.h"
#include "eap.h"

#ifdef USE_SRP
#include <t_pwd.h>
#include <t_server.h>
#include <t_client.h>
#include "pppcrypt.h"
#endif /* USE_SRP */

#ifndef SHA_DIGESTSIZE
#define	SHA_DIGESTSIZE 20
#endif

static const char rcsid[] = RCSID;

eap_state eap_states[NUM_PPP];		/* EAP state; one for each unit */
#ifdef USE_SRP
static char *pn_secret = NULL;		/* Pseudonym generating secret */
#endif

/*
 * Command-line options.
 */
static option_t eap_option_list[] = {
    { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
      "Set retransmit timeout for EAP Requests (server)" },
    { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
      "Set max number of EAP Requests sent (server)" },
    { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
      "Set time limit for peer EAP authentication" },
    { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
      "Set max number of EAP Requests allows (client)" },
    { "eap-interval", o_int, &eap_states[0].es_rechallenge,
      "Set interval for EAP rechallenge" },
#ifdef USE_SRP
    { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
      "Set interval for SRP lightweight rechallenge" },
    { "srp-pn-secret", o_string, &pn_secret,
      "Long term pseudonym generation secret" },
    { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
      "Use pseudonym if offered one by server", 1 },
#endif
    { NULL }
};

/*
 * Protocol entry points.
 */
static void eap_init __P((int unit));
static void eap_input __P((int unit, u_char *inp, int inlen));
static void eap_protrej __P((int unit));
static void eap_lowerup __P((int unit));
static void eap_lowerdown __P((int unit));
static int  eap_printpkt __P((u_char *inp, int inlen,
    void (*)(void *arg, char *fmt, ...), void *arg));

struct protent eap_protent = {
	PPP_EAP,		/* protocol number */
	eap_init,		/* initialization procedure */
	eap_input,		/* process a received packet */
	eap_protrej,		/* process a received protocol-reject */
	eap_lowerup,		/* lower layer has gone up */
	eap_lowerdown,		/* lower layer has gone down */
	NULL,			/* open the protocol */
	NULL,			/* close the protocol */
	eap_printpkt,		/* print a packet in readable form */
	NULL,			/* process a received data packet */
	1,			/* protocol enabled */
	"EAP",			/* text name of protocol */
	NULL,			/* text name of corresponding data protocol */
	eap_option_list,	/* list of command-line options */
	NULL,			/* check requested options; assign defaults */
	NULL,			/* configure interface for demand-dial */
	NULL			/* say whether to bring up link for this pkt */
};

/*
 * A well-known 2048 bit modulus.
 */
static const u_char wkmodulus[] = {
	0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
	0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
	0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
	0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
	0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
	0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
	0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
	0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
	0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
	0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
	0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
	0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
	0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
	0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
	0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
	0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
	0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
	0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
	0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
	0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
	0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
	0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
	0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
	0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
	0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
	0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
	0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
	0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
	0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
	0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
	0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
	0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
};

/* Local forward declarations. */
static void eap_server_timeout __P((void *arg));

/*
 * Convert EAP state code to printable string for debug.
 */
static const char *
eap_state_name(esc)
enum eap_state_code esc;
{
	static const char *state_names[] = { EAP_STATES };

	return (state_names[(int)esc]);
}

/*
 * eap_init - Initialize state for an EAP user.  This is currently
 * called once by main() during start-up.
 */
static void
eap_init(unit)
int unit;
{
	eap_state *esp = &eap_states[unit];

	BZERO(esp, sizeof (*esp));
	esp->es_unit = unit;
	esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
	esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
	esp->es_server.ea_id = (u_char)(drand48() * 0x100);
	esp->es_client.ea_timeout = EAP_DEFREQTIME;
	esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
}

/*
 * eap_client_timeout - Give up waiting for the peer to send any
 * Request messages.
 */
static void
eap_client_timeout(arg)
void *arg;
{
	eap_state *esp = (eap_state *) arg;

	if (!eap_client_active(esp))
		return;

	error("EAP: timeout waiting for Request from peer");
	auth_withpeer_fail(esp->es_unit, PPP_EAP);
	esp->es_client.ea_state = eapBadAuth;
}

/*
 * eap_authwithpeer - Authenticate to our peer (behave as client).
 *
 * Start client state and wait for requests.  This is called only
 * after eap_lowerup.
 */
void
eap_authwithpeer(unit, localname)
int unit;
char *localname;
{
	eap_state *esp = &eap_states[unit];

	/* Save the peer name we're given */
	esp->es_client.ea_name = localname;
	esp->es_client.ea_namelen = strlen(localname);

	esp->es_client.ea_state = eapListen;

	/*
	 * Start a timer so that if the other end just goes
	 * silent, we don't sit here waiting forever.
	 */
	if (esp->es_client.ea_timeout > 0)
		TIMEOUT(eap_client_timeout, (void *)esp,
		    esp->es_client.ea_timeout);
}

/*
 * Format a standard EAP Failure message and send it to the peer.
 * (Server operation)
 */
static void
eap_send_failure(esp)
eap_state *esp;
{
	u_char *outp;

	outp = outpacket_buf;
    
	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_FAILURE, outp);
	esp->es_server.ea_id++;
	PUTCHAR(esp->es_server.ea_id, outp);
	PUTSHORT(EAP_HEADERLEN, outp);

	output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);

	esp->es_server.ea_state = eapBadAuth;
	auth_peer_fail(esp->es_unit, PPP_EAP);
}

/*
 * Format a standard EAP Success message and send it to the peer.
 * (Server operation)
 */
static void
eap_send_success(esp)
eap_state *esp;
{
	u_char *outp;

	outp = outpacket_buf;
    
	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_SUCCESS, outp);
	esp->es_server.ea_id++;
	PUTCHAR(esp->es_server.ea_id, outp);
	PUTSHORT(EAP_HEADERLEN, outp);

	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);

	auth_peer_success(esp->es_unit, PPP_EAP, 0,
	    esp->es_server.ea_peer, esp->es_server.ea_peerlen);
}

#ifdef USE_SRP
/*
 * Set DES key according to pseudonym-generating secret and current
 * date.
 */
static bool
pncrypt_setkey(int timeoffs)
{
	struct tm *tp;
	char tbuf[9];
	SHA1_CTX ctxt;
	u_char dig[SHA_DIGESTSIZE];
	time_t reftime;

	if (pn_secret == NULL)
		return (0);
	reftime = time(NULL) + timeoffs;
	tp = localtime(&reftime);
	SHA1Init(&ctxt);
	SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
	strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
	SHA1Update(&ctxt, tbuf, strlen(tbuf));
	SHA1Final(dig, &ctxt);
	return (DesSetkey(dig));
}

static char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

struct b64state {
	u_int32_t bs_bits;
	int bs_offs;
};

static int
b64enc(bs, inp, inlen, outp)
struct b64state *bs;
u_char *inp;
int inlen;
u_char *outp;
{
	int outlen = 0;

	while (inlen > 0) {
		bs->bs_bits = (bs->bs_bits << 8) | *inp++;
		inlen--;
		bs->bs_offs += 8;
		if (bs->bs_offs >= 24) {
			*outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
			*outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
			*outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
			*outp++ = base64[bs->bs_bits & 0x3F];
			outlen += 4;
			bs->bs_offs = 0;
			bs->bs_bits = 0;
		}
	}
	return (outlen);
}

static int
b64flush(bs, outp)
struct b64state *bs;
u_char *outp;
{
	int outlen = 0;

	if (bs->bs_offs == 8) {
		*outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
		*outp++ = base64[(bs->bs_bits << 4) & 0x3F];
		outlen = 2;
	} else if (bs->bs_offs == 16) {
		*outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
		*outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
		*outp++ = base64[(bs->bs_bits << 2) & 0x3F];
		outlen = 3;
	}
	bs->bs_offs = 0;
	bs->bs_bits = 0;
	return (outlen);
}

static int
b64dec(bs, inp, inlen, outp)
struct b64state *bs;
u_char *inp;
int inlen;
u_char *outp;
{
	int outlen = 0;
	char *cp;

	while (inlen > 0) {
		if ((cp = strchr(base64, *inp++)) == NULL)
			break;
		bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
		inlen--;
		bs->bs_offs += 6;
		if (bs->bs_offs >= 8) {
			*outp++ = bs->bs_bits >> (bs->bs_offs - 8);
			outlen++;
			bs->bs_offs -= 8;
		}
	}
	return (outlen);
}
#endif /* USE_SRP */

/*
 * Assume that current waiting server state is complete and figure
 * next state to use based on available authentication data.  'status'
 * indicates if there was an error in handling the last query.  It is
 * 0 for success and non-zero for failure.
 */
static void
eap_figure_next_state(esp, status)
eap_state *esp;
int status;
{
#ifdef USE_SRP
	unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
	struct t_pw tpw;
	struct t_confent *tce, mytce;
	char *cp, *cp2;
	struct t_server *ts;
	int id, i, plen, toffs;
	u_char vals[2];
	struct b64state bs;
#endif /* USE_SRP */

	esp->es_server.ea_timeout = esp->es_savedtime;
	switch (esp->es_server.ea_state) {
	case eapBadAuth:
		return;

	case eapIdentify:
#ifdef USE_SRP
		/* Discard any previous session. */
		ts = (struct t_server *)esp->es_server.ea_session;
		if (ts != NULL) {
			t_serverclose(ts);
			esp->es_server.ea_session = NULL;
			esp->es_server.ea_skey = NULL;
		}
#endif /* USE_SRP */
		if (status != 0) {
			esp->es_server.ea_state = eapBadAuth;
			break;
		}
#ifdef USE_SRP
		/* If we've got a pseudonym, try to decode to real name. */
		if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
		    strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
			SRP_PSEUDO_LEN) == 0 &&
		    (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
		    sizeof (secbuf)) {
			BZERO(&bs, sizeof (bs));
			plen = b64dec(&bs,
			    esp->es_server.ea_peer + SRP_PSEUDO_LEN,
			    esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
			    secbuf);
			toffs = 0;
			for (i = 0; i < 5; i++) {
				pncrypt_setkey(toffs);
				toffs -= 86400;
				if (!DesDecrypt(secbuf, clear)) {
					dbglog("no DES here; cannot decode "
					    "pseudonym");
					return;
				}
				id = *(unsigned char *)clear;
				if (id + 1 <= plen && id + 9 > plen)
					break;
			}
			if (plen % 8 == 0 && i < 5) {
				/*
				 * Note that this is always shorter than the
				 * original stored string, so there's no need
				 * to realloc.
				 */
				if ((i = plen = *(unsigned char *)clear) > 7)
					i = 7;
				esp->es_server.ea_peerlen = plen;
				dp = (unsigned char *)esp->es_server.ea_peer;
				BCOPY(clear + 1, dp, i);
				plen -= i;
				dp += i;
				sp = secbuf + 8;
				while (plen > 0) {
					(void) DesDecrypt(sp, dp);
					sp += 8;
					dp += 8;
					plen -= 8;
				}
				esp->es_server.ea_peer[
					esp->es_server.ea_peerlen] = '\0';
				dbglog("decoded pseudonym to \"%.*q\"",
				    esp->es_server.ea_peerlen,
				    esp->es_server.ea_peer);
			} else {
				dbglog("failed to decode real name");
				/* Stay in eapIdentfy state; requery */
				break;
			}
		}
		/* Look up user in secrets database. */
		if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
		    esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
			/* Set up default in case SRP entry is bad */
			esp->es_server.ea_state = eapMD5Chall;
			/* Get t_confent based on index in srp-secrets */
			id = strtol((char *)secbuf, &cp, 10);
			if (*cp++ != ':' || id < 0)
				break;
			if (id == 0) {
				mytce.index = 0;
				mytce.modulus.data = (u_char *)wkmodulus;
				mytce.modulus.len = sizeof (wkmodulus);
				mytce.generator.data = (u_char *)"\002";
				mytce.generator.len = 1;
				tce = &mytce;
			} else if ((tce = gettcid(id)) != NULL) {
				/*
				 * Client will have to verify this modulus/
				 * generator combination, and that will take
				 * a while.  Lengthen the timeout here.
				 */
				if (esp->es_server.ea_timeout > 0 &&
				    esp->es_server.ea_timeout < 30)
					esp->es_server.ea_timeout = 30;
			} else {
				break;
			}
			if ((cp2 = strchr(cp, ':')) == NULL)
				break;
			*cp2++ = '\0';
			tpw.pebuf.name = esp->es_server.ea_peer;
			tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
			    cp);
			tpw.pebuf.password.data = tpw.pwbuf;
			tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
			    cp2);
			tpw.pebuf.salt.data = tpw.saltbuf;
			if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
				break;
			esp->es_server.ea_session = (void *)ts;
			esp->es_server.ea_state = eapSRP1;
			vals[0] = esp->es_server.ea_id + 1;
			vals[1] = EAPT_SRP;
			t_serveraddexdata(ts, vals, 2);
			/* Generate B; must call before t_servergetkey() */
			t_servergenexp(ts);
			break;
		}
#endif /* USE_SRP */
		esp->es_server.ea_state = eapMD5Chall;
		break;

	case eapSRP1:
#ifdef USE_SRP
		ts = (struct t_server *)esp->es_server.ea_session;
		if (ts != NULL && status != 0) {
			t_serverclose(ts);
			esp->es_server.ea_session = NULL;
			esp->es_server.ea_skey = NULL;
		}
#endif /* USE_SRP */
		if (status == 1) {
			esp->es_server.ea_state = eapMD5Chall;
		} else if (status != 0 || esp->es_server.ea_session == NULL) {
			esp->es_server.ea_state = eapBadAuth;
		} else {
			esp->es_server.ea_state = eapSRP2;
		}
		break;

	case eapSRP2:
#ifdef USE_SRP
		ts = (struct t_server *)esp->es_server.ea_session;
		if (ts != NULL && status != 0) {
			t_serverclose(ts);
			esp->es_server.ea_session = NULL;
			esp->es_server.ea_skey = NULL;
		}
#endif /* USE_SRP */
		if (status != 0 || esp->es_server.ea_session == NULL) {
			esp->es_server.ea_state = eapBadAuth;
		} else {
			esp->es_server.ea_state = eapSRP3;
		}
		break;

	case eapSRP3:
	case eapSRP4:
#ifdef USE_SRP
		ts = (struct t_server *)esp->es_server.ea_session;
		if (ts != NULL && status != 0) {
			t_serverclose(ts);
			esp->es_server.ea_session = NULL;
			esp->es_server.ea_skey = NULL;
		}
#endif /* USE_SRP */
		if (status != 0 || esp->es_server.ea_session == NULL) {
			esp->es_server.ea_state = eapBadAuth;
		} else {
			esp->es_server.ea_state = eapOpen;
		}
		break;

	case eapMD5Chall:
		if (status != 0) {
			esp->es_server.ea_state = eapBadAuth;
		} else {
			esp->es_server.ea_state = eapOpen;
		}
		break;

	default:
		esp->es_server.ea_state = eapBadAuth;
		break;
	}
	if (esp->es_server.ea_state == eapBadAuth)
		eap_send_failure(esp);
}

/*
 * Format an EAP Request message and send it to the peer.  Message
 * type depends on current state.  (Server operation)
 */
static void
eap_send_request(esp)
eap_state *esp;
{
	u_char *outp;
	u_char *lenloc;
	u_char *ptr;
	int outlen;
	int challen;
	char *str;
#ifdef USE_SRP
	struct t_server *ts;
	u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
	int i, j;
	struct b64state b64;
	SHA1_CTX ctxt;
#endif /* USE_SRP */

	/* Handle both initial auth and restart */
	if (esp->es_server.ea_state < eapIdentify &&
	    esp->es_server.ea_state != eapInitial) {
		esp->es_server.ea_state = eapIdentify;
		if (explicit_remote) {
			/*
			 * If we already know the peer's
			 * unauthenticated name, then there's no
			 * reason to ask.  Go to next state instead.
			 */
			esp->es_server.ea_peer = remote_name;
			esp->es_server.ea_peerlen = strlen(remote_name);
			eap_figure_next_state(esp, 0);
		}
	}

	if (esp->es_server.ea_maxrequests > 0 &&
	    esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
		if (esp->es_server.ea_responses > 0)
			error("EAP: too many Requests sent");
		else
			error("EAP: no response to Requests");
		eap_send_failure(esp);
		return;
	}

	outp = outpacket_buf;
    
	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_REQUEST, outp);
	PUTCHAR(esp->es_server.ea_id, outp);
	lenloc = outp;
	INCPTR(2, outp);

	switch (esp->es_server.ea_state) {
	case eapIdentify:
		PUTCHAR(EAPT_IDENTITY, outp);
		str = "Name";
		challen = strlen(str);
		BCOPY(str, outp, challen);
		INCPTR(challen, outp);
		break;

	case eapMD5Chall:
		PUTCHAR(EAPT_MD5CHAP, outp);
		/*
		 * pick a random challenge length between
		 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
		 */
		challen = (drand48() *
		    (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
			    MIN_CHALLENGE_LENGTH;
		PUTCHAR(challen, outp);
		esp->es_challen = challen;
		ptr = esp->es_challenge;
		while (--challen >= 0)
			*ptr++ = (u_char) (drand48() * 0x100);
		BCOPY(esp->es_challenge, outp, esp->es_challen);
		INCPTR(esp->es_challen, outp);
		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
		INCPTR(esp->es_server.ea_namelen, outp);
		break;

#ifdef USE_SRP
	case eapSRP1:
		PUTCHAR(EAPT_SRP, outp);
		PUTCHAR(EAPSRP_CHALLENGE, outp);

		PUTCHAR(esp->es_server.ea_namelen, outp);
		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
		INCPTR(esp->es_server.ea_namelen, outp);

		ts = (struct t_server *)esp->es_server.ea_session;
		assert(ts != NULL);
		PUTCHAR(ts->s.len, outp);
		BCOPY(ts->s.data, outp, ts->s.len);
		INCPTR(ts->s.len, outp);

		if (ts->g.len == 1 && ts->g.data[0] == 2) {
			PUTCHAR(0, outp);
		} else {
			PUTCHAR(ts->g.len, outp);
			BCOPY(ts->g.data, outp, ts->g.len);
			INCPTR(ts->g.len, outp);
		}

		if (ts->n.len != sizeof (wkmodulus) ||
		    BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
			BCOPY(ts->n.data, outp, ts->n.len);
			INCPTR(ts->n.len, outp);
		}
		break;

	case eapSRP2:
		PUTCHAR(EAPT_SRP, outp);
		PUTCHAR(EAPSRP_SKEY, outp);

		ts = (struct t_server *)esp->es_server.ea_session;
		assert(ts != NULL);
		BCOPY(ts->B.data, outp, ts->B.len);
		INCPTR(ts->B.len, outp);
		break;

	case eapSRP3:
		PUTCHAR(EAPT_SRP, outp);
		PUTCHAR(EAPSRP_SVALIDATOR, outp);
		PUTLONG(SRPVAL_EBIT, outp);
		ts = (struct t_server *)esp->es_server.ea_session;
		assert(ts != NULL);
		BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
		INCPTR(SHA_DIGESTSIZE, outp);

		if (pncrypt_setkey(0)) {
			/* Generate pseudonym */
			optr = outp;
			cp = (unsigned char *)esp->es_server.ea_peer;
			if ((j = i = esp->es_server.ea_peerlen) > 7)
				j = 7;
			clear[0] = i;
			BCOPY(cp, clear + 1, j);
			i -= j;
			cp += j;
			if (!DesEncrypt(clear, cipher)) {
				dbglog("no DES here; not generating pseudonym");
				break;
			}
			BZERO(&b64, sizeof (b64));
			outp++;		/* space for pseudonym length */
			outp += b64enc(&b64, cipher, 8, outp);
			while (i >= 8) {
				(void) DesEncrypt(cp, cipher);
				outp += b64enc(&b64, cipher, 8, outp);
				cp += 8;
				i -= 8;
			}
			if (i > 0) {
				BCOPY(cp, clear, i);
				cp += i;
				while (i < 8) {
					*cp++ = drand48() * 0x100;
					i++;
				}
				(void) DesEncrypt(clear, cipher);
				outp += b64enc(&b64, cipher, 8, outp);
			}
			outp += b64flush(&b64, outp);

			/* Set length and pad out to next 20 octet boundary */
			i = outp - optr - 1;
			*optr = i;
			i %= SHA_DIGESTSIZE;
			if (i != 0) {
				while (i < SHA_DIGESTSIZE) {
					*outp++ = drand48() * 0x100;
					i++;
				}
			}

			/* Obscure the pseudonym with SHA1 hash */
			SHA1Init(&ctxt);
			SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
			SHA1Update(&ctxt, esp->es_server.ea_skey,
			    SESSION_KEY_LEN);
			SHA1Update(&ctxt, esp->es_server.ea_peer,
			    esp->es_server.ea_peerlen);
			while (optr < outp) {
				SHA1Final(dig, &ctxt);
				cp = dig;
				while (cp < dig + SHA_DIGESTSIZE)
					*optr++ ^= *cp++;
				SHA1Init(&ctxt);
				SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
				SHA1Update(&ctxt, esp->es_server.ea_skey,
				    SESSION_KEY_LEN);
				SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
				    SHA_DIGESTSIZE);
			}
		}
		break;

	case eapSRP4:
		PUTCHAR(EAPT_SRP, outp);
		PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
		challen = MIN_CHALLENGE_LENGTH +
		    ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
		esp->es_challen = challen;
		ptr = esp->es_challenge;
		while (--challen >= 0)
			*ptr++ = drand48() * 0x100;
		BCOPY(esp->es_challenge, outp, esp->es_challen);
		INCPTR(esp->es_challen, outp);
		break;
#endif /* USE_SRP */

	default:
		return;
	}

	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
	PUTSHORT(outlen, lenloc);

	output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);

	esp->es_server.ea_requests++;

	if (esp->es_server.ea_timeout > 0)
		TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
}

/*
 * eap_authpeer - Authenticate our peer (behave as server).
 *
 * Start server state and send first request.  This is called only
 * after eap_lowerup.
 */
void
eap_authpeer(unit, localname)
int unit;
char *localname;
{
	eap_state *esp = &eap_states[unit];

	/* Save the name we're given. */
	esp->es_server.ea_name = localname;
	esp->es_server.ea_namelen = strlen(localname);

	esp->es_savedtime = esp->es_server.ea_timeout;

	/* Lower layer up yet? */
	if (esp->es_server.ea_state == eapInitial ||
	    esp->es_server.ea_state == eapPending) {
		esp->es_server.ea_state = eapPending;
		return;
	}

	esp->es_server.ea_state = eapPending;

	/* ID number not updated here intentionally; hashed into M1 */
	eap_send_request(esp);
}

/*
 * eap_server_timeout - Retransmission timer for sending Requests
 * expired.
 */
static void
eap_server_timeout(arg)
void *arg;
{
	eap_state *esp = (eap_state *) arg;

	if (!eap_server_active(esp))
		return;

	/* EAP ID number must not change on timeout. */
	eap_send_request(esp);
}

/*
 * When it's time to send rechallenge the peer, this timeout is
 * called.  Once the rechallenge is successful, the response handler
 * will restart the timer.  If it fails, then the link is dropped.
 */
static void
eap_rechallenge(arg)
void *arg;
{
	eap_state *esp = (eap_state *)arg;

	if (esp->es_server.ea_state != eapOpen &&
	    esp->es_server.ea_state != eapSRP4)
		return;

	esp->es_server.ea_requests = 0;
	esp->es_server.ea_state = eapIdentify;
	eap_figure_next_state(esp, 0);
	esp->es_server.ea_id++;
	eap_send_request(esp);
}

static void
srp_lwrechallenge(arg)
void *arg;
{
	eap_state *esp = (eap_state *)arg;

	if (esp->es_server.ea_state != eapOpen ||
	    esp->es_server.ea_type != EAPT_SRP)
		return;

	esp->es_server.ea_requests = 0;
	esp->es_server.ea_state = eapSRP4;
	esp->es_server.ea_id++;
	eap_send_request(esp);
}

/*
 * eap_lowerup - The lower layer is now up.
 *
 * This is called before either eap_authpeer or eap_authwithpeer.  See
 * link_established() in auth.c.  All that's necessary here is to
 * return to closed state so that those two routines will do the right
 * thing.
 */
static void
eap_lowerup(unit)
int unit;
{
	eap_state *esp = &eap_states[unit];

	/* Discard any (possibly authenticated) peer name. */
	if (esp->es_server.ea_peer != NULL &&
	    esp->es_server.ea_peer != remote_name)
		free(esp->es_server.ea_peer);
	esp->es_server.ea_peer = NULL;
	if (esp->es_client.ea_peer != NULL)
		free(esp->es_client.ea_peer);
	esp->es_client.ea_peer = NULL;

	esp->es_client.ea_state = eapClosed;
	esp->es_server.ea_state = eapClosed;
}

/*
 * eap_lowerdown - The lower layer is now down.
 *
 * Cancel all timeouts and return to initial state.
 */
static void
eap_lowerdown(unit)
int unit;
{
	eap_state *esp = &eap_states[unit];

	if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
		UNTIMEOUT(eap_client_timeout, (void *)esp);
	}
	if (eap_server_active(esp)) {
		if (esp->es_server.ea_timeout > 0) {
			UNTIMEOUT(eap_server_timeout, (void *)esp);
		}
	} else {
		if ((esp->es_server.ea_state == eapOpen ||
		    esp->es_server.ea_state == eapSRP4) &&
		    esp->es_rechallenge > 0) {
			UNTIMEOUT(eap_rechallenge, (void *)esp);
		}
		if (esp->es_server.ea_state == eapOpen &&
		    esp->es_lwrechallenge > 0) {
			UNTIMEOUT(srp_lwrechallenge, (void *)esp);
		}
	}

	esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
	esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
}

/*
 * eap_protrej - Peer doesn't speak this protocol.
 *
 * This shouldn't happen.  If it does, it represents authentication
 * failure.
 */
static void
eap_protrej(unit)
int unit;
{
	eap_state *esp = &eap_states[unit];

	if (eap_client_active(esp)) {
		error("EAP authentication failed due to Protocol-Reject");
		auth_withpeer_fail(unit, PPP_EAP);
	}
	if (eap_server_active(esp)) {
		error("EAP authentication of peer failed on Protocol-Reject");
		auth_peer_fail(unit, PPP_EAP);
	}
	eap_lowerdown(unit);
}

/*
 * Format and send a regular EAP Response message.
 */
static void
eap_send_response(esp, id, typenum, str, lenstr)
eap_state *esp;
u_char id;
u_char typenum;
u_char *str;
int lenstr;
{
	u_char *outp;
	int msglen;

	outp = outpacket_buf;

	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_RESPONSE, outp);
	PUTCHAR(id, outp);
	esp->es_client.ea_id = id;
	msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
	PUTSHORT(msglen, outp);
	PUTCHAR(typenum, outp);
	if (lenstr > 0) {
		BCOPY(str, outp, lenstr);
	}

	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
}

/*
 * Format and send an MD5-Challenge EAP Response message.
 */
static void
eap_chap_response(esp, id, hash, name, namelen)
eap_state *esp;
u_char id;
u_char *hash;
char *name;
int namelen;
{
	u_char *outp;
	int msglen;

	outp = outpacket_buf;
    
	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_RESPONSE, outp);
	PUTCHAR(id, outp);
	esp->es_client.ea_id = id;
	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
	    namelen;
	PUTSHORT(msglen, outp);
	PUTCHAR(EAPT_MD5CHAP, outp);
	PUTCHAR(MD5_SIGNATURE_SIZE, outp);
	BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
	INCPTR(MD5_SIGNATURE_SIZE, outp);
	if (namelen > 0) {
		BCOPY(name, outp, namelen);
	}

	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
}

#ifdef USE_SRP
/*
 * Format and send a SRP EAP Response message.
 */
static void
eap_srp_response(esp, id, subtypenum, str, lenstr)
eap_state *esp;
u_char id;
u_char subtypenum;
u_char *str;
int lenstr;
{
	u_char *outp;
	int msglen;

	outp = outpacket_buf;
    
	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_RESPONSE, outp);
	PUTCHAR(id, outp);
	esp->es_client.ea_id = id;
	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
	PUTSHORT(msglen, outp);
	PUTCHAR(EAPT_SRP, outp);
	PUTCHAR(subtypenum, outp);
	if (lenstr > 0) {
		BCOPY(str, outp, lenstr);
	}

	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
}

/*
 * Format and send a SRP EAP Client Validator Response message.
 */
static void
eap_srpval_response(esp, id, flags, str)
eap_state *esp;
u_char id;
u_int32_t flags;
u_char *str;
{
	u_char *outp;
	int msglen;

	outp = outpacket_buf;
    
	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_RESPONSE, outp);
	PUTCHAR(id, outp);
	esp->es_client.ea_id = id;
	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
	    SHA_DIGESTSIZE;
	PUTSHORT(msglen, outp);
	PUTCHAR(EAPT_SRP, outp);
	PUTCHAR(EAPSRP_CVALIDATOR, outp);
	PUTLONG(flags, outp);
	BCOPY(str, outp, SHA_DIGESTSIZE);

	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
}
#endif /* USE_SRP */

static void
eap_send_nak(esp, id, type)
eap_state *esp;
u_char id;
u_char type;
{
	u_char *outp;
	int msglen;

	outp = outpacket_buf;

	MAKEHEADER(outp, PPP_EAP);

	PUTCHAR(EAP_RESPONSE, outp);
	PUTCHAR(id, outp);
	esp->es_client.ea_id = id;
	msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
	PUTSHORT(msglen, outp);
	PUTCHAR(EAPT_NAK, outp);
	PUTCHAR(type, outp);

	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
}

#ifdef USE_SRP
static char *
name_of_pn_file()
{
	char *user, *path, *file;
	struct passwd *pw;
	size_t pl;
	static bool pnlogged = 0;

	pw = getpwuid(getuid());
	if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
		errno = EINVAL;
		return (NULL);
	}
	file = _PATH_PSEUDONYM;
	pl = strlen(user) + strlen(file) + 2;
	path = malloc(pl);
	if (path == NULL)
		return (NULL);
	(void) slprintf(path, pl, "%s/%s", user, file);
	if (!pnlogged) {
		dbglog("pseudonym file: %s", path);
		pnlogged = 1;
	}
	return (path);
}

static int
open_pn_file(modebits)
mode_t modebits;
{
	char *path;
	int fd, err;

	if ((path = name_of_pn_file()) == NULL)
		return (-1);
	fd = open(path, modebits, S_IRUSR | S_IWUSR);
	err = errno;
	free(path);
	errno = err;
	return (fd);
}

static void
remove_pn_file()
{
	char *path;

	if ((path = name_of_pn_file()) != NULL) {
		(void) unlink(path);
		(void) free(path);
	}
}

static void
write_pseudonym(esp, inp, len, id)
eap_state *esp;
u_char *inp;
int len, id;
{
	u_char val;
	u_char *datp, *digp;
	SHA1_CTX ctxt;
	u_char dig[SHA_DIGESTSIZE];
	int dsize, fd, olen = len;

	/*
	 * Do the decoding by working backwards.  This eliminates the need
	 * to save the decoded output in a separate buffer.
	 */
	val = id;
	while (len > 0) {
		if ((dsize = len % SHA_DIGESTSIZE) == 0)
			dsize = SHA_DIGESTSIZE;
		len -= dsize;
		datp = inp + len;
		SHA1Init(&ctxt);
		SHA1Update(&ctxt, &val, 1);
		SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
		if (len > 0) {
			SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
		} else {
			SHA1Update(&ctxt, esp->es_client.ea_name,
			    esp->es_client.ea_namelen);
		}
		SHA1Final(dig, &ctxt);
		for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
			*datp++ ^= *digp;
	}

	/* Now check that the result is sane */
	if (olen <= 0 || *inp + 1 > olen) {
		dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
		return;
	}

	/* Save it away */
	fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
	if (fd < 0) {
		dbglog("EAP: error saving pseudonym: %m");
		return;
	}
	len = write(fd, inp + 1, *inp);
	if (close(fd) != -1 && len == *inp) {
		dbglog("EAP: saved pseudonym");
		esp->es_usedpseudo = 0;
	} else {
		dbglog("EAP: failed to save pseudonym");
		remove_pn_file();
	}
}
#endif /* USE_SRP */

/*
 * eap_request - Receive EAP Request message (client mode).
 */
static void
eap_request(esp, inp, id, len)
eap_state *esp;
u_char *inp;
int id;
int len;
{
	u_char typenum;
	u_char vallen;
	int secret_len;
	char secret[MAXWORDLEN];
	char rhostname[256];
	MD5_CTX mdContext;
	u_char hash[MD5_SIGNATURE_SIZE];
#ifdef USE_SRP
	struct t_client *tc;
	struct t_num sval, gval, Nval, *Ap, Bval;
	u_char vals[2];
	SHA1_CTX ctxt;
	u_char dig[SHA_DIGESTSIZE];
	int fd;
#endif /* USE_SRP */

	/*
	 * Note: we update es_client.ea_id *only if* a Response
	 * message is being generated.  Otherwise, we leave it the
	 * same for duplicate detection purposes.
	 */

	esp->es_client.ea_requests++;
	if (esp->es_client.ea_maxrequests != 0 &&
	    esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
		info("EAP: received too many Request messages");
		if (esp->es_client.ea_timeout > 0) {
			UNTIMEOUT(eap_client_timeout, (void *)esp);
		}
		auth_withpeer_fail(esp->es_unit, PPP_EAP);
		return;
	}

	if (len <= 0) {
		error("EAP: empty Request message discarded");
		return;
	}

	GETCHAR(typenum, inp);
	len--;

	switch (typenum) {
	case EAPT_IDENTITY:
		if (len > 0)
			info("EAP: Identity prompt \"%.*q\"", len, inp);
#ifdef USE_SRP
		if (esp->es_usepseudo &&
		    (esp->es_usedpseudo == 0 ||
			(esp->es_usedpseudo == 1 &&
			    id == esp->es_client.ea_id))) {
			esp->es_usedpseudo = 1;
			/* Try to get a pseudonym */
			if ((fd = open_pn_file(O_RDONLY)) >= 0) {
				strcpy(rhostname, SRP_PSEUDO_ID);
				len = read(fd, rhostname + SRP_PSEUDO_LEN,
				    sizeof (rhostname) - SRP_PSEUDO_LEN);
				/* XXX NAI unsupported */
				if (len > 0) {
					eap_send_response(esp, id, typenum,
					    rhostname, len + SRP_PSEUDO_LEN);
				}
				(void) close(fd);
				if (len > 0)
					break;
			}
		}
		/* Stop using pseudonym now. */
		if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
			remove_pn_file();
			esp->es_usedpseudo = 2;
		}
#endif /* USE_SRP */
		eap_send_response(esp, id, typenum, esp->es_client.ea_name,
		    esp->es_client.ea_namelen);
		break;

	case EAPT_NOTIFICATION:
		if (len > 0)
			info("EAP: Notification \"%.*q\"", len, inp);
		eap_send_response(esp, id, typenum, NULL, 0);
		break;

	case EAPT_NAK:
		/*
		 * Avoid the temptation to send Response Nak in reply
		 * to Request Nak here.  It can only lead to trouble.
		 */
		warn("EAP: unexpected Nak in Request; ignored");
		/* Return because we're waiting for something real. */
		return;

	case EAPT_MD5CHAP:
		if (len < 1) {
			error("EAP: received MD5-Challenge with no data");
			/* Bogus request; wait for something real. */
			return;
		}
		GETCHAR(vallen, inp);
		len--;
		if (vallen < 8 || vallen > len) {
			error("EAP: MD5-Challenge with bad length %d (8..%d)",
			    vallen, len);
			/* Try something better. */
			eap_send_nak(esp, id, EAPT_SRP);
			break;
		}

		/* Not so likely to happen. */
		if (vallen >= len + sizeof (rhostname)) {
			dbglog("EAP: trimming really long peer name down");
			BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
			rhostname[sizeof (rhostname) - 1] = '\0';
		} else {
			BCOPY(inp + vallen, rhostname, len - vallen);
			rhostname[len - vallen] = '\0';
		}

		/* In case the remote doesn't give us his name. */
		if (explicit_remote ||
		    (remote_name[0] != '\0' && vallen == len))
			strlcpy(rhostname, remote_name, sizeof (rhostname));

		/*
		 * Get the secret for authenticating ourselves with
		 * the specified host.
		 */
		if (!get_secret(esp->es_unit, esp->es_client.ea_name,
		    rhostname, secret, &secret_len, 0)) {
			dbglog("EAP: no MD5 secret for auth to %q", rhostname);
			eap_send_nak(esp, id, EAPT_SRP);
			break;
		}
		MD5_Init(&mdContext);
		typenum = id;
		MD5_Update(&mdContext, &typenum, 1);
		MD5_Update(&mdContext, secret, secret_len);
		BZERO(secret, sizeof (secret));
		MD5_Update(&mdContext, inp, vallen);
		MD5_Final(hash, &mdContext);
		eap_chap_response(esp, id, hash, esp->es_client.ea_name,
		    esp->es_client.ea_namelen);
		break;

#ifdef USE_SRP
	case EAPT_SRP:
		if (len < 1) {
			error("EAP: received empty SRP Request");
			/* Bogus request; wait for something real. */
			return;
		}

		/* Get subtype */
		GETCHAR(vallen, inp);
		len--;
		switch (vallen) {
		case EAPSRP_CHALLENGE:
			tc = NULL;
			if (esp->es_client.ea_session != NULL) {
				tc = (struct t_client *)esp->es_client.
				    ea_session;
				/*
				 * If this is a new challenge, then start
				 * over with a new client session context.
				 * Otherwise, just resend last response.
				 */
				if (id != esp->es_client.ea_id) {
					t_clientclose(tc);
					esp->es_client.ea_session = NULL;
					tc = NULL;
				}
			}
			/* No session key just yet */
			esp->es_client.ea_skey = NULL;
			if (tc == NULL) {
				GETCHAR(vallen, inp);
				len--;
				if (vallen >= len) {
					error("EAP: badly-formed SRP Challenge"
					    " (name)");
					/* Ignore badly-formed messages */
					return;
				}
				BCOPY(inp, rhostname, vallen);
				rhostname[vallen] = '\0';
				INCPTR(vallen, inp);
				len -= vallen;

				/*
				 * In case the remote doesn't give us his name,
				 * use configured name.
				 */
				if (explicit_remote ||
				    (remote_name[0] != '\0' && vallen == 0)) {
					strlcpy(rhostname, remote_name,
					    sizeof (rhostname));
				}

				if (esp->es_client.ea_peer != NULL)
					free(esp->es_client.ea_peer);
				esp->es_client.ea_peer = strdup(rhostname);
				esp->es_client.ea_peerlen = strlen(rhostname);

				GETCHAR(vallen, inp);
				len--;
				if (vallen >= len) {
					error("EAP: badly-formed SRP Challenge"
					    " (s)");
					/* Ignore badly-formed messages */
					return;
				}
				sval.data = inp;
				sval.len = vallen;
				INCPTR(vallen, inp);
				len -= vallen;

				GETCHAR(vallen, inp);
				len--;
				if (vallen > len) {
					error("EAP: badly-formed SRP Challenge"
					    " (g)");
					/* Ignore badly-formed messages */
					return;
				}
				/* If no generator present, then use value 2 */
				if (vallen == 0) {
					gval.data = (u_char *)"\002";
					gval.len = 1;
				} else {
					gval.data = inp;
					gval.len = vallen;
				}
				INCPTR(vallen, inp);
				len -= vallen;

				/*
				 * If no modulus present, then use well-known
				 * value.
				 */
				if (len == 0) {
					Nval.data = (u_char *)wkmodulus;
					Nval.len = sizeof (wkmodulus);
				} else {
					Nval.data = inp;
					Nval.len = len;
				}
				tc = t_clientopen(esp->es_client.ea_name,
				    &Nval, &gval, &sval);
				if (tc == NULL) {
					eap_send_nak(esp, id, EAPT_MD5CHAP);
					break;
				}
				esp->es_client.ea_session = (void *)tc;

				/* Add Challenge ID & type to verifier */
				vals[0] = id;
				vals[1] = EAPT_SRP;
				t_clientaddexdata(tc, vals, 2);
			}
			Ap = t_clientgenexp(tc);
			eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
			    Ap->len);
			break;

		case EAPSRP_SKEY:
			tc = (struct t_client *)esp->es_client.ea_session;
			if (tc == NULL) {
				warn("EAP: peer sent Subtype 2 without 1");
				eap_send_nak(esp, id, EAPT_MD5CHAP);
				break;
			}
			if (esp->es_client.ea_skey != NULL) {
				/*
				 * ID number should not change here.  Warn
				 * if it does (but otherwise ignore).
				 */
				if (id != esp->es_client.ea_id) {
					warn("EAP: ID changed from %d to %d "
					    "in SRP Subtype 2 rexmit",
					    esp->es_client.ea_id, id);
				}
			} else {
				if (get_srp_secret(esp->es_unit,
				    esp->es_client.ea_name,
				    esp->es_client.ea_peer, secret, 0) == 0) {
					/*
					 * Can't work with this peer because
					 * the secret is missing.  Just give
					 * up.
					 */
					eap_send_nak(esp, id, EAPT_MD5CHAP);
					break;
				}
				Bval.data = inp;
				Bval.len = len;
				t_clientpasswd(tc, secret);
				BZERO(secret, sizeof (secret));
				esp->es_client.ea_skey =
				    t_clientgetkey(tc, &Bval);
				if (esp->es_client.ea_skey == NULL) {
					/* Server is rogue; stop now */
					error("EAP: SRP server is rogue");
					goto client_failure;
				}
			}
			eap_srpval_response(esp, id, SRPVAL_EBIT,
			    t_clientresponse(tc));
			break;

		case EAPSRP_SVALIDATOR:
			tc = (struct t_client *)esp->es_client.ea_session;
			if (tc == NULL || esp->es_client.ea_skey == NULL) {
				warn("EAP: peer sent Subtype 3 without 1/2");
				eap_send_nak(esp, id, EAPT_MD5CHAP);
				break;
			}
			/*
			 * If we're already open, then this ought to be a
			 * duplicate.  Otherwise, check that the server is
			 * who we think it is.
			 */
			if (esp->es_client.ea_state == eapOpen) {
				if (id != esp->es_client.ea_id) {
					warn("EAP: ID changed from %d to %d "
					    "in SRP Subtype 3 rexmit",
					    esp->es_client.ea_id, id);
				}
			} else {
				len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
				if (len < 0 || t_clientverify(tc, inp +
					sizeof (u_int32_t)) != 0) {
					error("EAP: SRP server verification "
					    "failed");
					goto client_failure;
				}
				GETLONG(esp->es_client.ea_keyflags, inp);
				/* Save pseudonym if user wants it. */
				if (len > 0 && esp->es_usepseudo) {
					INCPTR(SHA_DIGESTSIZE, inp);
					write_pseudonym(esp, inp, len, id);
				}
			}
			/*
			 * We've verified our peer.  We're now mostly done,
			 * except for waiting on the regular EAP Success
			 * message.
			 */
			eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
			break;

		case EAPSRP_LWRECHALLENGE:
			if (len < 4) {
				warn("EAP: malformed Lightweight rechallenge");
				return;
			}
			SHA1Init(&ctxt);
			vals[0] = id;
			SHA1Update(&ctxt, vals, 1);
			SHA1Update(&ctxt, esp->es_client.ea_skey,
			    SESSION_KEY_LEN);
			SHA1Update(&ctxt, inp, len);
			SHA1Update(&ctxt, esp->es_client.ea_name,
			    esp->es_client.ea_namelen);
			SHA1Final(dig, &ctxt);
			eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
			    SHA_DIGESTSIZE);
			break;

		default:
			error("EAP: unknown SRP Subtype %d", vallen);
			eap_send_nak(esp, id, EAPT_MD5CHAP);
			break;
		}
		break;
#endif /* USE_SRP */

	default:
		info("EAP: unknown authentication type %d; Naking", typenum);
		eap_send_nak(esp, id, EAPT_SRP);
		break;
	}

	if (esp->es_client.ea_timeout > 0) {
		UNTIMEOUT(eap_client_timeout, (void *)esp);
		TIMEOUT(eap_client_timeout, (void *)esp,
		    esp->es_client.ea_timeout);
	}
	return;

#ifdef USE_SRP
client_failure:
	esp->es_client.ea_state = eapBadAuth;
	if (esp->es_client.ea_timeout > 0) {
		UNTIMEOUT(eap_client_timeout, (void *)esp);
	}
	esp->es_client.ea_session = NULL;
	t_clientclose(tc);
	auth_withpeer_fail(esp->es_unit, PPP_EAP);
#endif /* USE_SRP */
}

/*
 * eap_response - Receive EAP Response message (server mode).
 */
static void
eap_response(esp, inp, id, len)
eap_state *esp;
u_char *inp;
int id;
int len;
{
	u_char typenum;
	u_char vallen;
	int secret_len;
	char secret[MAXSECRETLEN];
	char rhostname[256];
	MD5_CTX mdContext;
	u_char hash[MD5_SIGNATURE_SIZE];
#ifdef USE_SRP
	struct t_server *ts;
	struct t_num A;
	SHA1_CTX ctxt;
	u_char dig[SHA_DIGESTSIZE];
#endif /* USE_SRP */

	if (esp->es_server.ea_id != id) {
		dbglog("EAP: discarding Response %d; expected ID %d", id,
		    esp->es_server.ea_id);
		return;
	}

	esp->es_server.ea_responses++;

	if (len <= 0) {
		error("EAP: empty Response message discarded");
		return;
	}

	GETCHAR(typenum, inp);
	len--;

	switch (typenum) {
	case EAPT_IDENTITY:
		if (esp->es_server.ea_state != eapIdentify) {
			dbglog("EAP discarding unwanted Identify \"%.q\"", len,
			    inp);
			break;
		}
		info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
		if (esp->es_server.ea_peer != NULL &&
		    esp->es_server.ea_peer != remote_name)
			free(esp->es_server.ea_peer);
		esp->es_server.ea_peer = malloc(len + 1);
		if (esp->es_server.ea_peer == NULL) {
			esp->es_server.ea_peerlen = 0;
			eap_figure_next_state(esp, 1);
			break;
		}
		BCOPY(inp, esp->es_server.ea_peer, len);
		esp->es_server.ea_peer[len] = '\0';
		esp->es_server.ea_peerlen = len;
		eap_figure_next_state(esp, 0);
		break;

	case EAPT_NOTIFICATION:
		dbglog("EAP unexpected Notification; response discarded");
		break;

	case EAPT_NAK:
		if (len < 1) {
			info("EAP: Nak Response with no suggested protocol");
			eap_figure_next_state(esp, 1);
			break;
		}

		GETCHAR(vallen, inp);
		len--;

		if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
			/* Peer cannot Nak Identify Request */
			eap_figure_next_state(esp, 1);
			break;
		}

		switch (vallen) {
		case EAPT_SRP:
			/* Run through SRP validator selection again. */
			esp->es_server.ea_state = eapIdentify;
			eap_figure_next_state(esp, 0);
			break;

		case EAPT_MD5CHAP:
			esp->es_server.ea_state = eapMD5Chall;
			break;

		default:
			dbglog("EAP: peer requesting unknown Type %d", vallen);
			switch (esp->es_server.ea_state) {
			case eapSRP1:
			case eapSRP2:
			case eapSRP3:
				esp->es_server.ea_state = eapMD5Chall;
				break;
			case eapMD5Chall:
			case eapSRP4:
				esp->es_server.ea_state = eapIdentify;
				eap_figure_next_state(esp, 0);
				break;
			default:
				break;
			}
			break;
		}
		break;

	case EAPT_MD5CHAP:
		if (esp->es_server.ea_state != eapMD5Chall) {
			error("EAP: unexpected MD5-Response");
			eap_figure_next_state(esp, 1);
			break;
		}
		if (len < 1) {
			error("EAP: received MD5-Response with no data");
			eap_figure_next_state(esp, 1);
			break;
		}
		GETCHAR(vallen, inp);
		len--;
		if (vallen != 16 || vallen > len) {
			error("EAP: MD5-Response with bad length %d", vallen);
			eap_figure_next_state(esp, 1);
			break;
		}

		/* Not so likely to happen. */
		if (vallen >= len + sizeof (rhostname)) {
			dbglog("EAP: trimming really long peer name down");
			BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
			rhostname[sizeof (rhostname) - 1] = '\0';
		} else {
			BCOPY(inp + vallen, rhostname, len - vallen);
			rhostname[len - vallen] = '\0';
		}

		/* In case the remote doesn't give us his name. */
		if (explicit_remote ||
		    (remote_name[0] != '\0' && vallen == len))
			strlcpy(rhostname, remote_name, sizeof (rhostname));

		/*
		 * Get the secret for authenticating the specified
		 * host.
		 */
		if (!get_secret(esp->es_unit, rhostname,
		    esp->es_server.ea_name, secret, &secret_len, 1)) {
			dbglog("EAP: no MD5 secret for auth of %q", rhostname);
			eap_send_failure(esp);
			break;
		}
		MD5_Init(&mdContext);
		MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
		MD5_Update(&mdContext, secret, secret_len);
		BZERO(secret, sizeof (secret));
		MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
		MD5_Final(hash, &mdContext);
		if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
			eap_send_failure(esp);
			break;
		}
		esp->es_server.ea_type = EAPT_MD5CHAP;
		eap_send_success(esp);
		eap_figure_next_state(esp, 0);
		if (esp->es_rechallenge != 0)
			TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
		break;

#ifdef USE_SRP
	case EAPT_SRP:
		if (len < 1) {
			error("EAP: empty SRP Response");
			eap_figure_next_state(esp, 1);
			break;
		}
		GETCHAR(typenum, inp);
		len--;
		switch (typenum) {
		case EAPSRP_CKEY:
			if (esp->es_server.ea_state != eapSRP1) {
				error("EAP: unexpected SRP Subtype 1 Response");
				eap_figure_next_state(esp, 1);
				break;
			}
			A.data = inp;
			A.len = len;
			ts = (struct t_server *)esp->es_server.ea_session;
			assert(ts != NULL);
			esp->es_server.ea_skey = t_servergetkey(ts, &A);
			if (esp->es_server.ea_skey == NULL) {
				/* Client's A value is bogus; terminate now */
				error("EAP: bogus A value from client");
				eap_send_failure(esp);
			} else {
				eap_figure_next_state(esp, 0);
			}
			break;

		case EAPSRP_CVALIDATOR:
			if (esp->es_server.ea_state != eapSRP2) {
				error("EAP: unexpected SRP Subtype 2 Response");
				eap_figure_next_state(esp, 1);
				break;
			}
			if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
				error("EAP: M1 length %d < %d", len,
				    sizeof (u_int32_t) + SHA_DIGESTSIZE);
				eap_figure_next_state(esp, 1);
				break;
			}
			GETLONG(esp->es_server.ea_keyflags, inp);
			ts = (struct t_server *)esp->es_server.ea_session;
			assert(ts != NULL);
			if (t_serververify(ts, inp)) {
				info("EAP: unable to validate client identity");
				eap_send_failure(esp);
				break;
			}
			eap_figure_next_state(esp, 0);
			break;

		case EAPSRP_ACK:
			if (esp->es_server.ea_state != eapSRP3) {
				error("EAP: unexpected SRP Subtype 3 Response");
				eap_send_failure(esp);
				break;
			}
			esp->es_server.ea_type = EAPT_SRP;
			eap_send_success(esp);
			eap_figure_next_state(esp, 0);
			if (esp->es_rechallenge != 0)
				TIMEOUT(eap_rechallenge, esp,
				    esp->es_rechallenge);
			if (esp->es_lwrechallenge != 0)
				TIMEOUT(srp_lwrechallenge, esp,
				    esp->es_lwrechallenge);
			break;

		case EAPSRP_LWRECHALLENGE:
			if (esp->es_server.ea_state != eapSRP4) {
				info("EAP: unexpected SRP Subtype 4 Response");
				return;
			}
			if (len != SHA_DIGESTSIZE) {
				error("EAP: bad Lightweight rechallenge "
				    "response");
				return;
			}
			SHA1Init(&ctxt);
			vallen = id;
			SHA1Update(&ctxt, &vallen, 1);
			SHA1Update(&ctxt, esp->es_server.ea_skey,
			    SESSION_KEY_LEN);
			SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
			SHA1Update(&ctxt, esp->es_server.ea_peer,
			    esp->es_server.ea_peerlen);
			SHA1Final(dig, &ctxt);
			if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
				error("EAP: failed Lightweight rechallenge");
				eap_send_failure(esp);
				break;
			}
			esp->es_server.ea_state = eapOpen;
			if (esp->es_lwrechallenge != 0)
				TIMEOUT(srp_lwrechallenge, esp,
				    esp->es_lwrechallenge);
			break;
		}
		break;
#endif /* USE_SRP */

	default:
		/* This can't happen. */
		error("EAP: unknown Response type %d; ignored", typenum);
		return;
	}

	if (esp->es_server.ea_timeout > 0) {
		UNTIMEOUT(eap_server_timeout, (void *)esp);
	}

	if (esp->es_server.ea_state != eapBadAuth &&
	    esp->es_server.ea_state != eapOpen) {
		esp->es_server.ea_id++;
		eap_send_request(esp);
	}
}

/*
 * eap_success - Receive EAP Success message (client mode).
 */
static void
eap_success(esp, inp, id, len)
eap_state *esp;
u_char *inp;
int id;
int len;
{
	if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
		dbglog("EAP unexpected success message in state %s (%d)",
		    eap_state_name(esp->es_client.ea_state),
		    esp->es_client.ea_state);
		return;
	}

	if (esp->es_client.ea_timeout > 0) {
		UNTIMEOUT(eap_client_timeout, (void *)esp);
	}

	if (len > 0) {
		/* This is odd.  The spec doesn't allow for this. */
		PRINTMSG(inp, len);
	}

	esp->es_client.ea_state = eapOpen;
	auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
}

/*
 * eap_failure - Receive EAP Failure message (client mode).
 */
static void
eap_failure(esp, inp, id, len)
eap_state *esp;
u_char *inp;
int id;
int len;
{
	if (!eap_client_active(esp)) {
		dbglog("EAP unexpected failure message in state %s (%d)",
		    eap_state_name(esp->es_client.ea_state),
		    esp->es_client.ea_state);
	}

	if (esp->es_client.ea_timeout > 0) {
		UNTIMEOUT(eap_client_timeout, (void *)esp);
	}

	if (len > 0) {
		/* This is odd.  The spec doesn't allow for this. */
		PRINTMSG(inp, len);
	}

	esp->es_client.ea_state = eapBadAuth;

	error("EAP: peer reports authentication failure");
	auth_withpeer_fail(esp->es_unit, PPP_EAP);
}

/*
 * eap_input - Handle received EAP message.
 */
static void
eap_input(unit, inp, inlen)
int unit;
u_char *inp;
int inlen;
{
	eap_state *esp = &eap_states[unit];
	u_char code, id;
	int len;

	/*
	 * Parse header (code, id and length).  If packet too short,
	 * drop it.
	 */
	if (inlen < EAP_HEADERLEN) {
		error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
		return;
	}
	GETCHAR(code, inp);
	GETCHAR(id, inp);
	GETSHORT(len, inp);
	if (len < EAP_HEADERLEN || len > inlen) {
		error("EAP: packet has illegal length field %d (%d..%d)", len,
		    EAP_HEADERLEN, inlen);
		return;
	}
	len -= EAP_HEADERLEN;

	/* Dispatch based on message code */
	switch (code) {
	case EAP_REQUEST:
		eap_request(esp, inp, id, len);
		break;

	case EAP_RESPONSE:
		eap_response(esp, inp, id, len);
		break;

	case EAP_SUCCESS:
		eap_success(esp, inp, id, len);
		break;

	case EAP_FAILURE:
		eap_failure(esp, inp, id, len);
		break;

	default:				/* XXX Need code reject */
		/* Note: it's not legal to send EAP Nak here. */
		warn("EAP: unknown code %d received", code);
		break;
	}
}

/*
 * eap_printpkt - print the contents of an EAP packet.
 */
static char *eap_codenames[] = {
	"Request", "Response", "Success", "Failure"
};

static char *eap_typenames[] = {
	"Identity", "Notification", "Nak", "MD5-Challenge",
	"OTP", "Generic-Token", NULL, NULL,
	"RSA", "DSS", "KEA", "KEA-Validate",
	"TLS", "Defender", "Windows 2000", "Arcot",
	"Cisco", "Nokia", "SRP"
};

static int
eap_printpkt(inp, inlen, printer, arg)
u_char *inp;
int inlen;
void (*printer) __P((void *, char *, ...));
void *arg;
{
	int code, id, len, rtype, vallen;
	u_char *pstart;
	u_int32_t uval;

	if (inlen < EAP_HEADERLEN)
		return (0);
	pstart = inp;
	GETCHAR(code, inp);
	GETCHAR(id, inp);
	GETSHORT(len, inp);
	if (len < EAP_HEADERLEN || len > inlen)
		return (0);

	if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
		printer(arg, " %s", eap_codenames[code-1]);
	else
		printer(arg, " code=0x%x", code);
	printer(arg, " id=0x%x", id);
	len -= EAP_HEADERLEN;
	switch (code) {
	case EAP_REQUEST:
		if (len < 1) {
			printer(arg, " <missing type>");
			break;
		}
		GETCHAR(rtype, inp);
		len--;
		if (rtype >= 1 &&
		    rtype <= sizeof (eap_typenames) / sizeof (char *))
			printer(arg, " %s", eap_typenames[rtype-1]);
		else
			printer(arg, " type=0x%x", rtype);
		switch (rtype) {
		case EAPT_IDENTITY:
		case EAPT_NOTIFICATION:
			if (len > 0) {
				printer(arg, " <Message ");
				print_string((char *)inp, len, printer, arg);
				printer(arg, ">");
				INCPTR(len, inp);
				len = 0;
			} else {
				printer(arg, " <No message>");
			}
			break;

		case EAPT_MD5CHAP:
			if (len <= 0)
				break;
			GETCHAR(vallen, inp);
			len--;
			if (vallen > len)
				goto truncated;
			printer(arg, " <Value%.*B>", vallen, inp);
			INCPTR(vallen, inp);
			len -= vallen;
			if (len > 0) {
				printer(arg, " <Name ");
				print_string((char *)inp, len, printer, arg);
				printer(arg, ">");
				INCPTR(len, inp);
				len = 0;
			} else {
				printer(arg, " <No name>");
			}
			break;

		case EAPT_SRP:
			if (len < 3)
				goto truncated;
			GETCHAR(vallen, inp);
			len--;
			printer(arg, "-%d", vallen);
			switch (vallen) {
			case EAPSRP_CHALLENGE:
				GETCHAR(vallen, inp);
				len--;
				if (vallen >= len)
					goto truncated;
				if (vallen > 0) {
					printer(arg, " <Name ");
					print_string((char *)inp, vallen, printer,
					    arg);
					printer(arg, ">");
				} else {
					printer(arg, " <No name>");
				}
				INCPTR(vallen, inp);
				len -= vallen;
				GETCHAR(vallen, inp);
				len--;
				if (vallen >= len)
					goto truncated;
				printer(arg, " <s%.*B>", vallen, inp);
				INCPTR(vallen, inp);
				len -= vallen;
				GETCHAR(vallen, inp);
				len--;
				if (vallen > len)
					goto truncated;
				if (vallen == 0) {
					printer(arg, " <Default g=2>");
				} else {
					printer(arg, " <g%.*B>", vallen, inp);
				}
				INCPTR(vallen, inp);
				len -= vallen;
				if (len == 0) {
					printer(arg, " <Default N>");
				} else {
					printer(arg, " <N%.*B>", len, inp);
					INCPTR(len, inp);
					len = 0;
				}
				break;

			case EAPSRP_SKEY:
				printer(arg, " <B%.*B>", len, inp);
				INCPTR(len, inp);
				len = 0;
				break;

			case EAPSRP_SVALIDATOR:
				if (len < sizeof (u_int32_t))
					break;
				GETLONG(uval, inp);
				len -= sizeof (u_int32_t);
				if (uval & SRPVAL_EBIT) {
					printer(arg, " E");
					uval &= ~SRPVAL_EBIT;
				}
				if (uval != 0) {
					printer(arg, " f<%X>", uval);
				}
				if ((vallen = len) > SHA_DIGESTSIZE)
					vallen = SHA_DIGESTSIZE;
				printer(arg, " <M2%.*B%s>", len, inp,
				    len < SHA_DIGESTSIZE ? "?" : "");
				INCPTR(vallen, inp);
				len -= vallen;
				if (len > 0) {
					printer(arg, " <PN%.*B>", len, inp);
					INCPTR(len, inp);
					len = 0;
				}
				break;

			case EAPSRP_LWRECHALLENGE:
				printer(arg, " <Challenge%.*B>", len, inp);
				INCPTR(len, inp);
				len = 0;
				break;
			}
			break;
		}
		break;

	case EAP_RESPONSE:
		if (len < 1)
			break;
		GETCHAR(rtype, inp);
		len--;
		if (rtype >= 1 &&
		    rtype <= sizeof (eap_typenames) / sizeof (char *))
			printer(arg, " %s", eap_typenames[rtype-1]);
		else
			printer(arg, " type=0x%x", rtype);
		switch (rtype) {
		case EAPT_IDENTITY:
			if (len > 0) {
				printer(arg, " <Name ");
				print_string((char *)inp, len, printer, arg);
				printer(arg, ">");
				INCPTR(len, inp);
				len = 0;
			}
			break;

		case EAPT_NAK:
			if (len <= 0) {
				printer(arg, " <missing hint>");
				break;
			}
			GETCHAR(rtype, inp);
			len--;
			printer(arg, " <Suggested-type %02X", rtype);
			if (rtype >= 1 &&
			    rtype < sizeof (eap_typenames) / sizeof (char *))
				printer(arg, " (%s)", eap_typenames[rtype-1]);
			printer(arg, ">");
			break;

		case EAPT_MD5CHAP:
			if (len <= 0) {
				printer(arg, " <missing length>");
				break;
			}
			GETCHAR(vallen, inp);
			len--;
			if (vallen > len)
				goto truncated;
			printer(arg, " <Value%.*B>", vallen, inp);
			INCPTR(vallen, inp);
			len -= vallen;
			if (len > 0) {
				printer(arg, " <Name ");
				print_string((char *)inp, len, printer, arg);
				printer(arg, ">");
				INCPTR(len, inp);
				len = 0;
			} else {
				printer(arg, " <No name>");
			}
			break;

		case EAPT_SRP:
			if (len < 1)
				goto truncated;
			GETCHAR(vallen, inp);
			len--;
			printer(arg, "-%d", vallen);
			switch (vallen) {
			case EAPSRP_CKEY:
				printer(arg, " <A%.*B>", len, inp);
				INCPTR(len, inp);
				len = 0;
				break;

			case EAPSRP_CVALIDATOR:
				if (len < sizeof (u_int32_t))
					break;
				GETLONG(uval, inp);
				len -= sizeof (u_int32_t);
				if (uval & SRPVAL_EBIT) {
					printer(arg, " E");
					uval &= ~SRPVAL_EBIT;
				}
				if (uval != 0) {
					printer(arg, " f<%X>", uval);
				}
				printer(arg, " <M1%.*B%s>", len, inp,
				    len == SHA_DIGESTSIZE ? "" : "?");
				INCPTR(len, inp);
				len = 0;
				break;

			case EAPSRP_ACK:
				break;

			case EAPSRP_LWRECHALLENGE:
				printer(arg, " <Response%.*B%s>", len, inp,
				    len == SHA_DIGESTSIZE ? "" : "?");
				if ((vallen = len) > SHA_DIGESTSIZE)
					vallen = SHA_DIGESTSIZE;
				INCPTR(vallen, inp);
				len -= vallen;
				break;
			}
			break;
		}
		break;

	case EAP_SUCCESS:	/* No payload expected for these! */
	case EAP_FAILURE:
		break;

	truncated:
		printer(arg, " <truncated>");
		break;
	}

	if (len > 8)
		printer(arg, "%8B...", inp);
	else if (len > 0)
		printer(arg, "%.*B", len, inp);
	INCPTR(len, inp);

	return (inp - pstart);
}
