Home | History | Annotate | Line # | Download | only in pppd
eap.c revision 1.1.1.4
      1 /*
      2  * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
      3  *
      4  * Copyright (c) 2001 by Sun Microsystems, Inc.
      5  * All rights reserved.
      6  *
      7  * Non-exclusive rights to redistribute, modify, translate, and use
      8  * this software in source and binary forms, in whole or in part, is
      9  * hereby granted, provided that the above copyright notice is
     10  * duplicated in any source form, and that neither the name of the
     11  * copyright holder nor the author is used to endorse or promote
     12  * products derived from this software.
     13  *
     14  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
     15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
     16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     17  *
     18  * Original version by James Carlson
     19  *
     20  * This implementation of EAP supports MD5-Challenge and SRP-SHA1
     21  * authentication styles.  Note that support of MD5-Challenge is a
     22  * requirement of RFC 2284, and that it's essentially just a
     23  * reimplementation of regular RFC 1994 CHAP using EAP messages.
     24  *
     25  * As an authenticator ("server"), there are multiple phases for each
     26  * style.  In the first phase of each style, the unauthenticated peer
     27  * name is queried using the EAP Identity request type.  If the
     28  * "remotename" option is used, then this phase is skipped, because
     29  * the peer's name is presumed to be known.
     30  *
     31  * For MD5-Challenge, there are two phases, and the second phase
     32  * consists of sending the challenge itself and handling the
     33  * associated response.
     34  *
     35  * For SRP-SHA1, there are four phases.  The second sends 's', 'N',
     36  * and 'g'.  The reply contains 'A'.  The third sends 'B', and the
     37  * reply contains 'M1'.  The forth sends the 'M2' value.
     38  *
     39  * As an authenticatee ("client"), there's just a single phase --
     40  * responding to the queries generated by the peer.  EAP is an
     41  * authenticator-driven protocol.
     42  *
     43  * Based on draft-ietf-pppext-eap-srp-03.txt.
     44  */
     45 
     46 /*
     47  * Modification by Beniamino Galvani, Mar 2005
     48  * Implemented EAP-TLS authentication
     49  */
     50 
     51 #include <stdio.h>
     52 #include <stdlib.h>
     53 #include <string.h>
     54 #include <unistd.h>
     55 #include <pwd.h>
     56 #include <sys/types.h>
     57 #include <sys/stat.h>
     58 #include <fcntl.h>
     59 #include <assert.h>
     60 #include <errno.h>
     61 
     62 #include "pppd.h"
     63 #include "pathnames.h"
     64 #include "md5.h"
     65 #include "eap.h"
     66 
     67 #ifdef CHAPMS
     68 #include "chap_ms.h"
     69 #endif
     70 
     71 #ifdef USE_SRP
     72 #include <t_pwd.h>
     73 #include <t_server.h>
     74 #include <t_client.h>
     75 #include "pppcrypt.h"
     76 #endif /* USE_SRP */
     77 
     78 #ifndef SHA_DIGESTSIZE
     79 #define	SHA_DIGESTSIZE 20
     80 #endif
     81 
     82 #ifdef USE_EAPTLS
     83 #include "eap-tls.h"
     84 #endif /* USE_EAPTLS */
     85 #ifdef CHAPMS
     86 #include "magic.h"
     87 #include "chap_ms.h"
     88 #include "chap-new.h"
     89 #endif /* CHAPMS */
     90 
     91 eap_state eap_states[NUM_PPP];		/* EAP state; one for each unit */
     92 #ifdef USE_SRP
     93 static char *pn_secret = NULL;		/* Pseudonym generating secret */
     94 #endif
     95 
     96 /*
     97  * Command-line options.
     98  */
     99 static option_t eap_option_list[] = {
    100     { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
    101       "Set retransmit timeout for EAP Requests (server)" },
    102     { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
    103       "Set max number of EAP Requests sent (server)" },
    104     { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
    105       "Set time limit for peer EAP authentication" },
    106     { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
    107       "Set max number of EAP Requests allows (client)" },
    108     { "eap-interval", o_int, &eap_states[0].es_rechallenge,
    109       "Set interval for EAP rechallenge" },
    110 #ifdef USE_SRP
    111     { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
    112       "Set interval for SRP lightweight rechallenge" },
    113     { "srp-pn-secret", o_string, &pn_secret,
    114       "Long term pseudonym generation secret" },
    115     { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
    116       "Use pseudonym if offered one by server", 1 },
    117 #endif
    118     { NULL }
    119 };
    120 
    121 /*
    122  * Protocol entry points.
    123  */
    124 static void eap_init (int unit);
    125 static void eap_input (int unit, u_char *inp, int inlen);
    126 static void eap_protrej (int unit);
    127 static void eap_lowerup (int unit);
    128 static void eap_lowerdown (int unit);
    129 static int  eap_printpkt (u_char *inp, int inlen,
    130     void (*)(void *arg, char *fmt, ...), void *arg);
    131 
    132 struct protent eap_protent = {
    133 	PPP_EAP,		/* protocol number */
    134 	eap_init,		/* initialization procedure */
    135 	eap_input,		/* process a received packet */
    136 	eap_protrej,		/* process a received protocol-reject */
    137 	eap_lowerup,		/* lower layer has gone up */
    138 	eap_lowerdown,		/* lower layer has gone down */
    139 	NULL,			/* open the protocol */
    140 	NULL,			/* close the protocol */
    141 	eap_printpkt,		/* print a packet in readable form */
    142 	NULL,			/* process a received data packet */
    143 	1,			/* protocol enabled */
    144 	"EAP",			/* text name of protocol */
    145 	NULL,			/* text name of corresponding data protocol */
    146 	eap_option_list,	/* list of command-line options */
    147 	NULL,			/* check requested options; assign defaults */
    148 	NULL,			/* configure interface for demand-dial */
    149 	NULL			/* say whether to bring up link for this pkt */
    150 };
    151 
    152 #ifdef USE_SRP
    153 /*
    154  * A well-known 2048 bit modulus.
    155  */
    156 static const u_char wkmodulus[] = {
    157 	0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
    158 	0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
    159 	0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
    160 	0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
    161 	0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
    162 	0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
    163 	0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
    164 	0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
    165 	0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
    166 	0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
    167 	0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
    168 	0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
    169 	0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
    170 	0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
    171 	0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
    172 	0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
    173 	0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
    174 	0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
    175 	0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
    176 	0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
    177 	0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
    178 	0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
    179 	0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
    180 	0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
    181 	0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
    182 	0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
    183 	0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
    184 	0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
    185 	0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
    186 	0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
    187 	0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
    188 	0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
    189 };
    190 #endif /* USE_SRP */
    191 
    192 /* Local forward declarations. */
    193 static void eap_server_timeout (void *arg);
    194 
    195 /*
    196  * Convert EAP state code to printable string for debug.
    197  */
    198 static const char *
    199 eap_state_name(enum eap_state_code esc)
    200 {
    201 	static const char *state_names[] = { EAP_STATES };
    202 
    203 	return (state_names[(int)esc]);
    204 }
    205 
    206 /*
    207  * eap_init - Initialize state for an EAP user.  This is currently
    208  * called once by main() during start-up.
    209  */
    210 static void
    211 eap_init(int unit)
    212 {
    213 	eap_state *esp = &eap_states[unit];
    214 
    215 	BZERO(esp, sizeof (*esp));
    216 	esp->es_unit = unit;
    217 	esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
    218 	esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
    219 	esp->es_server.ea_id = (u_char)(drand48() * 0x100);
    220 	esp->es_client.ea_timeout = EAP_DEFREQTIME;
    221 	esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
    222 #ifdef USE_EAPTLS
    223 	esp->es_client.ea_using_eaptls = 0;
    224 #endif /* USE_EAPTLS */
    225 #ifdef CHAPMS
    226         esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
    227 #endif
    228 }
    229 
    230 /*
    231  * eap_client_timeout - Give up waiting for the peer to send any
    232  * Request messages.
    233  */
    234 static void
    235 eap_client_timeout(void *arg)
    236 {
    237 	eap_state *esp = (eap_state *) arg;
    238 
    239 	if (!eap_client_active(esp))
    240 		return;
    241 
    242 	error("EAP: timeout waiting for Request from peer");
    243 	auth_withpeer_fail(esp->es_unit, PPP_EAP);
    244 	esp->es_client.ea_state = eapBadAuth;
    245 }
    246 
    247 /*
    248  * eap_authwithpeer - Authenticate to our peer (behave as client).
    249  *
    250  * Start client state and wait for requests.  This is called only
    251  * after eap_lowerup.
    252  */
    253 void
    254 eap_authwithpeer(int unit, char *localname)
    255 {
    256 	eap_state *esp = &eap_states[unit];
    257 
    258 	/* Save the peer name we're given */
    259 	esp->es_client.ea_name = localname;
    260 	esp->es_client.ea_namelen = strlen(localname);
    261 
    262 	esp->es_client.ea_state = eapListen;
    263 
    264 	/*
    265 	 * Start a timer so that if the other end just goes
    266 	 * silent, we don't sit here waiting forever.
    267 	 */
    268 	if (esp->es_client.ea_timeout > 0)
    269 		TIMEOUT(eap_client_timeout, (void *)esp,
    270 		    esp->es_client.ea_timeout);
    271 }
    272 
    273 /*
    274  * Format a standard EAP Failure message and send it to the peer.
    275  * (Server operation)
    276  */
    277 static void
    278 eap_send_failure(eap_state *esp)
    279 {
    280 	u_char *outp;
    281 
    282 	outp = outpacket_buf;
    283 
    284 	MAKEHEADER(outp, PPP_EAP);
    285 
    286 	PUTCHAR(EAP_FAILURE, outp);
    287 	esp->es_server.ea_id++;
    288 	PUTCHAR(esp->es_server.ea_id, outp);
    289 	PUTSHORT(EAP_HEADERLEN, outp);
    290 
    291 	output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
    292 
    293 	esp->es_server.ea_state = eapBadAuth;
    294 	auth_peer_fail(esp->es_unit, PPP_EAP);
    295 }
    296 
    297 /*
    298  * Format a standard EAP Success message and send it to the peer.
    299  * (Server operation)
    300  */
    301 static void
    302 eap_send_success(eap_state *esp)
    303 {
    304 	u_char *outp;
    305 
    306 	outp = outpacket_buf;
    307 
    308 	MAKEHEADER(outp, PPP_EAP);
    309 
    310 	PUTCHAR(EAP_SUCCESS, outp);
    311 	esp->es_server.ea_id++;
    312 	PUTCHAR(esp->es_server.ea_id, outp);
    313 	PUTSHORT(EAP_HEADERLEN, outp);
    314 
    315 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
    316 
    317 	auth_peer_success(esp->es_unit, PPP_EAP, 0,
    318 	    esp->es_server.ea_peer, esp->es_server.ea_peerlen);
    319 }
    320 
    321 #ifdef USE_SRP
    322 /*
    323  * Set DES key according to pseudonym-generating secret and current
    324  * date.
    325  */
    326 static bool
    327 pncrypt_setkey(int timeoffs)
    328 {
    329 	struct tm *tp;
    330 	char tbuf[9];
    331 	SHA1_CTX ctxt;
    332 	u_char dig[SHA_DIGESTSIZE];
    333 	time_t reftime;
    334 
    335 	if (pn_secret == NULL)
    336 		return (0);
    337 	reftime = time(NULL) + timeoffs;
    338 	tp = localtime(&reftime);
    339 	SHA1Init(&ctxt);
    340 	SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
    341 	strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
    342 	SHA1Update(&ctxt, tbuf, strlen(tbuf));
    343 	SHA1Final(dig, &ctxt);
    344 	return (DesSetkey(dig));
    345 }
    346 
    347 static char base64[] =
    348 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    349 
    350 struct b64state {
    351 	u_int32_t bs_bits;
    352 	int bs_offs;
    353 };
    354 
    355 static int
    356 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
    357 {
    358 	int outlen = 0;
    359 
    360 	while (inlen > 0) {
    361 		bs->bs_bits = (bs->bs_bits << 8) | *inp++;
    362 		inlen--;
    363 		bs->bs_offs += 8;
    364 		if (bs->bs_offs >= 24) {
    365 			*outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
    366 			*outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
    367 			*outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
    368 			*outp++ = base64[bs->bs_bits & 0x3F];
    369 			outlen += 4;
    370 			bs->bs_offs = 0;
    371 			bs->bs_bits = 0;
    372 		}
    373 	}
    374 	return (outlen);
    375 }
    376 
    377 static int
    378 b64flush(struct b64state *bs, u_char *outp)
    379 {
    380 	int outlen = 0;
    381 
    382 	if (bs->bs_offs == 8) {
    383 		*outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
    384 		*outp++ = base64[(bs->bs_bits << 4) & 0x3F];
    385 		outlen = 2;
    386 	} else if (bs->bs_offs == 16) {
    387 		*outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
    388 		*outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
    389 		*outp++ = base64[(bs->bs_bits << 2) & 0x3F];
    390 		outlen = 3;
    391 	}
    392 	bs->bs_offs = 0;
    393 	bs->bs_bits = 0;
    394 	return (outlen);
    395 }
    396 
    397 static int
    398 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
    399 {
    400 	int outlen = 0;
    401 	char *cp;
    402 
    403 	while (inlen > 0) {
    404 		if ((cp = strchr(base64, *inp++)) == NULL)
    405 			break;
    406 		bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
    407 		inlen--;
    408 		bs->bs_offs += 6;
    409 		if (bs->bs_offs >= 8) {
    410 			*outp++ = bs->bs_bits >> (bs->bs_offs - 8);
    411 			outlen++;
    412 			bs->bs_offs -= 8;
    413 		}
    414 	}
    415 	return (outlen);
    416 }
    417 #endif /* USE_SRP */
    418 
    419 /*
    420  * Assume that current waiting server state is complete and figure
    421  * next state to use based on available authentication data.  'status'
    422  * indicates if there was an error in handling the last query.  It is
    423  * 0 for success and non-zero for failure.
    424  */
    425 static void
    426 eap_figure_next_state(eap_state *esp, int status)
    427 {
    428 #ifdef USE_SRP
    429 	unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
    430 	struct t_pw tpw;
    431 	struct t_confent *tce, mytce;
    432 	char *cp, *cp2;
    433 	struct t_server *ts;
    434 	int id, i, plen, toffs;
    435 	u_char vals[2];
    436 	struct b64state bs;
    437 #endif /* USE_SRP */
    438 #ifdef USE_EAPTLS
    439 	struct eaptls_session *ets;
    440 	int secret_len;
    441 	char secret[MAXWORDLEN];
    442 #endif /* USE_EAPTLS */
    443 
    444 	esp->es_server.ea_timeout = esp->es_savedtime;
    445 #ifdef USE_EAPTLS
    446 	esp->es_server.ea_prev_state = esp->es_server.ea_state;
    447 #endif /* USE_EAPTLS */
    448 	switch (esp->es_server.ea_state) {
    449 	case eapBadAuth:
    450 		return;
    451 
    452 	case eapIdentify:
    453 #ifdef USE_SRP
    454 		/* Discard any previous session. */
    455 		ts = (struct t_server *)esp->es_server.ea_session;
    456 		if (ts != NULL) {
    457 			t_serverclose(ts);
    458 			esp->es_server.ea_session = NULL;
    459 			esp->es_server.ea_skey = NULL;
    460 		}
    461 #endif /* USE_SRP */
    462 		if (status != 0) {
    463 			esp->es_server.ea_state = eapBadAuth;
    464 			break;
    465 		}
    466 #ifdef USE_SRP
    467 		/* If we've got a pseudonym, try to decode to real name. */
    468 		if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
    469 		    strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
    470 			SRP_PSEUDO_LEN) == 0 &&
    471 		    (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
    472 		    sizeof (secbuf)) {
    473 			BZERO(&bs, sizeof (bs));
    474 			plen = b64dec(&bs,
    475 			    esp->es_server.ea_peer + SRP_PSEUDO_LEN,
    476 			    esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
    477 			    secbuf);
    478 			toffs = 0;
    479 			for (i = 0; i < 5; i++) {
    480 				pncrypt_setkey(toffs);
    481 				toffs -= 86400;
    482 				if (!DesDecrypt(secbuf, clear)) {
    483 					dbglog("no DES here; cannot decode "
    484 					    "pseudonym");
    485 					return;
    486 				}
    487 				id = *(unsigned char *)clear;
    488 				if (id + 1 <= plen && id + 9 > plen)
    489 					break;
    490 			}
    491 			if (plen % 8 == 0 && i < 5) {
    492 				/*
    493 				 * Note that this is always shorter than the
    494 				 * original stored string, so there's no need
    495 				 * to realloc.
    496 				 */
    497 				if ((i = plen = *(unsigned char *)clear) > 7)
    498 					i = 7;
    499 				esp->es_server.ea_peerlen = plen;
    500 				dp = (unsigned char *)esp->es_server.ea_peer;
    501 				BCOPY(clear + 1, dp, i);
    502 				plen -= i;
    503 				dp += i;
    504 				sp = secbuf + 8;
    505 				while (plen > 0) {
    506 					(void) DesDecrypt(sp, dp);
    507 					sp += 8;
    508 					dp += 8;
    509 					plen -= 8;
    510 				}
    511 				esp->es_server.ea_peer[
    512 					esp->es_server.ea_peerlen] = '\0';
    513 				dbglog("decoded pseudonym to \"%.*q\"",
    514 				    esp->es_server.ea_peerlen,
    515 				    esp->es_server.ea_peer);
    516 			} else {
    517 				dbglog("failed to decode real name");
    518 				/* Stay in eapIdentfy state; requery */
    519 				break;
    520 			}
    521 		}
    522 		/* Look up user in secrets database. */
    523 		if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
    524 		    esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
    525 			/* Set up default in case SRP entry is bad */
    526 			esp->es_server.ea_state = eapMD5Chall;
    527 			/* Get t_confent based on index in srp-secrets */
    528 			id = strtol((char *)secbuf, &cp, 10);
    529 			if (*cp++ != ':' || id < 0)
    530 				break;
    531 			if (id == 0) {
    532 				mytce.index = 0;
    533 				mytce.modulus.data = (u_char *)wkmodulus;
    534 				mytce.modulus.len = sizeof (wkmodulus);
    535 				mytce.generator.data = (u_char *)"\002";
    536 				mytce.generator.len = 1;
    537 				tce = &mytce;
    538 			} else if ((tce = gettcid(id)) != NULL) {
    539 				/*
    540 				 * Client will have to verify this modulus/
    541 				 * generator combination, and that will take
    542 				 * a while.  Lengthen the timeout here.
    543 				 */
    544 				if (esp->es_server.ea_timeout > 0 &&
    545 				    esp->es_server.ea_timeout < 30)
    546 					esp->es_server.ea_timeout = 30;
    547 			} else {
    548 				break;
    549 			}
    550 			if ((cp2 = strchr(cp, ':')) == NULL)
    551 				break;
    552 			*cp2++ = '\0';
    553 			tpw.pebuf.name = esp->es_server.ea_peer;
    554 			tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
    555 			    cp);
    556 			tpw.pebuf.password.data = tpw.pwbuf;
    557 			tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
    558 			    cp2);
    559 			tpw.pebuf.salt.data = tpw.saltbuf;
    560 			if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
    561 				break;
    562 			esp->es_server.ea_session = (void *)ts;
    563 			esp->es_server.ea_state = eapSRP1;
    564 			vals[0] = esp->es_server.ea_id + 1;
    565 			vals[1] = EAPT_SRP;
    566 			t_serveraddexdata(ts, vals, 2);
    567 			/* Generate B; must call before t_servergetkey() */
    568 			t_servergenexp(ts);
    569 			break;
    570 		}
    571 #endif /* USE_SRP */
    572 #ifdef USE_EAPTLS
    573                 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
    574                     esp->es_server.ea_name, secret, &secret_len, 1)) {
    575 
    576 			esp->es_server.ea_state = eapTlsStart;
    577 			break;
    578 		}
    579 #endif /* USE_EAPTLS */
    580 
    581 		esp->es_server.ea_state = eapMD5Chall;
    582 		break;
    583 
    584 #ifdef USE_EAPTLS
    585 	case eapTlsStart:
    586 		/* Initialize ssl session */
    587 		if(!eaptls_init_ssl_server(esp)) {
    588 			esp->es_server.ea_state = eapBadAuth;
    589 			break;
    590 		}
    591 
    592 		esp->es_server.ea_state = eapTlsRecv;
    593 		break;
    594 
    595 	case eapTlsRecv:
    596 		ets = (struct eaptls_session *) esp->es_server.ea_session;
    597 
    598 		if(ets->alert_sent) {
    599 			esp->es_server.ea_state = eapTlsSendAlert;
    600 			break;
    601 		}
    602 
    603 		if (status) {
    604 			esp->es_server.ea_state = eapBadAuth;
    605 			break;
    606 		}
    607 		ets = (struct eaptls_session *) esp->es_server.ea_session;
    608 
    609 		if(ets->frag)
    610 			esp->es_server.ea_state = eapTlsSendAck;
    611 		else
    612 			esp->es_server.ea_state = eapTlsSend;
    613 		break;
    614 
    615 	case eapTlsSend:
    616 		ets = (struct eaptls_session *) esp->es_server.ea_session;
    617 
    618 		if(ets->frag)
    619 			esp->es_server.ea_state = eapTlsRecvAck;
    620 		else
    621 			if(SSL_is_init_finished(ets->ssl))
    622 				esp->es_server.ea_state = eapTlsRecvClient;
    623 			else
    624 				/* JJK Add "TLS empty record" message here ??? */
    625 				esp->es_server.ea_state = eapTlsRecv;
    626 		break;
    627 
    628 	case eapTlsSendAck:
    629 		esp->es_server.ea_state = eapTlsRecv;
    630 		break;
    631 
    632 	case eapTlsRecvAck:
    633 		if (status)
    634 		{
    635 			esp->es_server.ea_state = eapBadAuth;
    636 			break;
    637 		}
    638 
    639 		esp->es_server.ea_state = eapTlsSend;
    640 		break;
    641 
    642 	case eapTlsSendAlert:
    643 		esp->es_server.ea_state = eapTlsRecvAlertAck;
    644 		break;
    645 #endif /* USE_EAPTLS */
    646 
    647 	case eapSRP1:
    648 #ifdef USE_SRP
    649 		ts = (struct t_server *)esp->es_server.ea_session;
    650 		if (ts != NULL && status != 0) {
    651 			t_serverclose(ts);
    652 			esp->es_server.ea_session = NULL;
    653 			esp->es_server.ea_skey = NULL;
    654 		}
    655 #endif /* USE_SRP */
    656 		if (status == 1) {
    657 			esp->es_server.ea_state = eapMD5Chall;
    658 		} else if (status != 0 || esp->es_server.ea_session == NULL) {
    659 			esp->es_server.ea_state = eapBadAuth;
    660 		} else {
    661 			esp->es_server.ea_state = eapSRP2;
    662 		}
    663 		break;
    664 
    665 	case eapSRP2:
    666 #ifdef USE_SRP
    667 		ts = (struct t_server *)esp->es_server.ea_session;
    668 		if (ts != NULL && status != 0) {
    669 			t_serverclose(ts);
    670 			esp->es_server.ea_session = NULL;
    671 			esp->es_server.ea_skey = NULL;
    672 		}
    673 #endif /* USE_SRP */
    674 		if (status != 0 || esp->es_server.ea_session == NULL) {
    675 			esp->es_server.ea_state = eapBadAuth;
    676 		} else {
    677 			esp->es_server.ea_state = eapSRP3;
    678 		}
    679 		break;
    680 
    681 	case eapSRP3:
    682 	case eapSRP4:
    683 #ifdef USE_SRP
    684 		ts = (struct t_server *)esp->es_server.ea_session;
    685 		if (ts != NULL && status != 0) {
    686 			t_serverclose(ts);
    687 			esp->es_server.ea_session = NULL;
    688 			esp->es_server.ea_skey = NULL;
    689 		}
    690 #endif /* USE_SRP */
    691 		if (status != 0 || esp->es_server.ea_session == NULL) {
    692 			esp->es_server.ea_state = eapBadAuth;
    693 		} else {
    694 			esp->es_server.ea_state = eapOpen;
    695 		}
    696 		break;
    697 
    698 #ifdef CHAPMS
    699 	case eapMSCHAPv2Chall:
    700 #endif
    701 	case eapMD5Chall:
    702 		if (status != 0) {
    703 			esp->es_server.ea_state = eapBadAuth;
    704 		} else {
    705 			esp->es_server.ea_state = eapOpen;
    706 		}
    707 		break;
    708 
    709 	default:
    710 		esp->es_server.ea_state = eapBadAuth;
    711 		break;
    712 	}
    713 	if (esp->es_server.ea_state == eapBadAuth)
    714 		eap_send_failure(esp);
    715 
    716 #ifdef USE_EAPTLS
    717 	dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state));
    718 #endif /* USE_EAPTLS */
    719 }
    720 
    721 #if CHAPMS
    722 static int
    723 eap_chapms2_verify_response(int id, char *name,
    724 			    unsigned char *secret, int secret_len,
    725 			    unsigned char *challenge, unsigned char *response,
    726 			    char *message, int message_space)
    727 {
    728 	unsigned char md[MS_CHAP2_RESPONSE_LEN];
    729 	char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
    730 	int challenge_len, response_len;
    731 
    732 	challenge_len = *challenge++;	/* skip length, is 16 */
    733 	response_len = *response++;
    734 	if (response_len != MS_CHAP2_RESPONSE_LEN)
    735 		goto bad;	/* not even the right length */
    736 
    737 	/* Generate the expected response and our mutual auth. */
    738 	ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
    739 		(char *)secret, secret_len, md,
    740 		(unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
    741 
    742 	/* compare MDs and send the appropriate status */
    743 	/*
    744 	 * Per RFC 2759, success message must be formatted as
    745 	 *     "S=<auth_string> M=<message>"
    746 	 * where
    747 	 *     <auth_string> is the Authenticator Response (mutual auth)
    748 	 *     <message> is a text message
    749 	 *
    750 	 * However, some versions of Windows (win98 tested) do not know
    751 	 * about the M=<message> part (required per RFC 2759) and flag
    752 	 * it as an error (reported incorrectly as an encryption error
    753 	 * to the user).  Since the RFC requires it, and it can be
    754 	 * useful information, we supply it if the peer is a conforming
    755 	 * system.  Luckily (?), win98 sets the Flags field to 0x04
    756 	 * (contrary to RFC requirements) so we can use that to
    757 	 * distinguish between conforming and non-conforming systems.
    758 	 *
    759 	 * Special thanks to Alex Swiridov <say (at) real.kharkov.ua> for
    760 	 * help debugging this.
    761 	 */
    762 	if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
    763 		   MS_CHAP2_NTRESP_LEN) == 0) {
    764 		if (response[MS_CHAP2_FLAGS])
    765 			slprintf(message, message_space, "S=%s", saresponse);
    766 		else
    767 			slprintf(message, message_space, "S=%s M=%s",
    768 				 saresponse, "Access granted");
    769 		return 1;
    770 	}
    771 
    772  bad:
    773 	/*
    774 	 * Failure message must be formatted as
    775 	 *     "E=e R=r C=c V=v M=m"
    776 	 * where
    777 	 *     e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
    778 	 *     r = retry (we use 1, ok to retry)
    779 	 *     c = challenge to use for next response, we reuse previous
    780 	 *     v = Change Password version supported, we use 0
    781 	 *     m = text message
    782 	 *
    783 	 * The M=m part is only for MS-CHAPv2.  Neither win2k nor
    784 	 * win98 (others untested) display the message to the user anyway.
    785 	 * They also both ignore the E=e code.
    786 	 *
    787 	 * Note that it's safe to reuse the same challenge as we don't
    788 	 * actually accept another response based on the error message
    789 	 * (and no clients try to resend a response anyway).
    790 	 *
    791 	 * Basically, this whole bit is useless code, even the small
    792 	 * implementation here is only because of overspecification.
    793 	 */
    794 	slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
    795 		 challenge_len, challenge, "Access denied");
    796 	return 0;
    797 }
    798 
    799 static struct chap_digest_type eap_chapms2_digest = {
    800 	CHAP_MICROSOFT_V2,	/* code */
    801 	NULL, /* chapms2_generate_challenge, */
    802 	eap_chapms2_verify_response,
    803 	NULL, /* chapms2_make_response, */
    804 	NULL, /* chapms2_check_success, */
    805 	NULL, /* chapms_handle_failure, */
    806 };
    807 
    808 /*
    809  * eap_chap_verify_response - check whether the peer's response matches
    810  * what we think it should be.  Returns 1 if it does (authentication
    811  * succeeded), or 0 if it doesn't.
    812  */
    813 static int
    814 eap_chap_verify_response(char *name, char *ourname, int id,
    815 			 struct chap_digest_type *digest,
    816 			 unsigned char *challenge, unsigned char *response,
    817 			 char *message, int message_space)
    818 {
    819 	int ok;
    820 	unsigned char secret[MAXSECRETLEN];
    821 	int secret_len;
    822 
    823 	/* Get the secret that the peer is supposed to know */
    824 	if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
    825 		error("No CHAP secret found for authenticating %q", name);
    826 		return 0;
    827 	}
    828 
    829 	ok = digest->verify_response(id, name, secret, secret_len, challenge,
    830 				     response, message, message_space);
    831 	memset(secret, 0, sizeof(secret));
    832 
    833 	return ok;
    834 }
    835 
    836 /*
    837  * Format and send an CHAPV2-Success/Failure EAP Request message.
    838  */
    839 static void
    840 eap_chapms2_send_request(eap_state *esp, u_char id,
    841 			 u_char opcode, u_char chapid,
    842 			 char *message, int message_len)
    843 {
    844 	u_char *outp;
    845 	int msglen;
    846 
    847 	outp = outpacket_buf;
    848 
    849 	MAKEHEADER(outp, PPP_EAP);
    850 
    851 	msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
    852 	msglen += message_len;
    853 
    854 	PUTCHAR(EAP_REQUEST, outp);
    855 	PUTCHAR(id, outp);
    856 	PUTSHORT(msglen, outp);
    857 	PUTCHAR(EAPT_MSCHAPV2, outp);
    858 	PUTCHAR(opcode, outp);
    859 	PUTCHAR(chapid, outp);
    860 	/* MS len */
    861 	PUTSHORT(msglen - 5, outp);
    862 	BCOPY(message, outp, message_len);
    863 
    864 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
    865 
    866 	if (opcode == CHAP_SUCCESS) {
    867 		auth_peer_success(esp->es_unit, PPP_EAP, 0,
    868 				esp->es_server.ea_peer, esp->es_server.ea_peerlen);
    869 	}
    870 	else {
    871 		esp->es_server.ea_state = eapBadAuth;
    872 		auth_peer_fail(esp->es_unit, PPP_EAP);
    873 	}
    874 }
    875 #endif /* CHAPMS */
    876 
    877 /*
    878  * Format an EAP Request message and send it to the peer.  Message
    879  * type depends on current state.  (Server operation)
    880  */
    881 static void
    882 eap_send_request(eap_state *esp)
    883 {
    884 	u_char *outp;
    885 	u_char *lenloc;
    886 	u_char *ptr;
    887 	int outlen;
    888 	int challen;
    889 	char *str;
    890 #ifdef USE_SRP
    891 	struct t_server *ts;
    892 	u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
    893 	int i, j;
    894 	struct b64state b64;
    895 	SHA1_CTX ctxt;
    896 #endif /* USE_SRP */
    897 
    898 	/* Handle both initial auth and restart */
    899 	if (esp->es_server.ea_state < eapIdentify &&
    900 	    esp->es_server.ea_state != eapInitial) {
    901 		esp->es_server.ea_state = eapIdentify;
    902 		if (explicit_remote) {
    903 			/*
    904 			 * If we already know the peer's
    905 			 * unauthenticated name, then there's no
    906 			 * reason to ask.  Go to next state instead.
    907 			 */
    908 			esp->es_server.ea_peer = remote_name;
    909 			esp->es_server.ea_peerlen = strlen(remote_name);
    910 			eap_figure_next_state(esp, 0);
    911 		}
    912 	}
    913 
    914 	if (esp->es_server.ea_maxrequests > 0 &&
    915 	    esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
    916 		if (esp->es_server.ea_responses > 0)
    917 			error("EAP: too many Requests sent");
    918 		else
    919 			error("EAP: no response to Requests");
    920 		eap_send_failure(esp);
    921 		return;
    922 	}
    923 
    924 	outp = outpacket_buf;
    925 
    926 	MAKEHEADER(outp, PPP_EAP);
    927 
    928 	PUTCHAR(EAP_REQUEST, outp);
    929 	PUTCHAR(esp->es_server.ea_id, outp);
    930 	lenloc = outp;
    931 	INCPTR(2, outp);
    932 
    933 	switch (esp->es_server.ea_state) {
    934 	case eapIdentify:
    935 		PUTCHAR(EAPT_IDENTITY, outp);
    936 		str = "Name";
    937 		challen = strlen(str);
    938 		BCOPY(str, outp, challen);
    939 		INCPTR(challen, outp);
    940 		break;
    941 
    942 	case eapMD5Chall:
    943 		PUTCHAR(EAPT_MD5CHAP, outp);
    944 		/*
    945 		 * pick a random challenge length between
    946 		 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
    947 		 */
    948 		challen = (drand48() *
    949 		    (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
    950 			    MIN_CHALLENGE_LENGTH;
    951 		PUTCHAR(challen, outp);
    952 		esp->es_challen = challen;
    953 		ptr = esp->es_challenge;
    954 		while (--challen >= 0)
    955 			*ptr++ = (u_char) (drand48() * 0x100);
    956 		BCOPY(esp->es_challenge, outp, esp->es_challen);
    957 		INCPTR(esp->es_challen, outp);
    958 		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
    959 		INCPTR(esp->es_server.ea_namelen, outp);
    960 		break;
    961 
    962 #ifdef CHAPMS
    963 	case eapMSCHAPv2Chall:
    964 		challen = 0x10;
    965 		esp->es_challen = challen;
    966 		esp->es_challenge[0] = challen;
    967 		random_bytes(&esp->es_challenge[1], challen);
    968 
    969 		PUTCHAR(EAPT_MSCHAPV2, outp);
    970 		PUTCHAR(CHAP_CHALLENGE, outp);
    971 		PUTCHAR(esp->es_server.ea_id, outp);
    972 		/* MS len */
    973 		PUTSHORT(5 + challen +
    974 				esp->es_server.ea_namelen,
    975 				outp);
    976 		/* challen + challenge */
    977 		BCOPY(esp->es_challenge, outp, challen+1);
    978 		INCPTR(challen+1, outp);
    979 		BCOPY(esp->es_server.ea_name,
    980 				outp,
    981 				esp->es_server.ea_namelen);
    982 		INCPTR(esp->es_server.ea_namelen, outp);
    983 		break;
    984 #endif /* CHAPMS */
    985 
    986 #ifdef USE_EAPTLS
    987 	case eapTlsStart:
    988 		PUTCHAR(EAPT_TLS, outp);
    989 		PUTCHAR(EAP_TLS_FLAGS_START, outp);
    990 		eap_figure_next_state(esp, 0);
    991 		break;
    992 
    993 	case eapTlsSend:
    994 		eaptls_send(esp->es_server.ea_session, &outp);
    995 		eap_figure_next_state(esp, 0);
    996 		break;
    997 
    998 	case eapTlsSendAck:
    999 		PUTCHAR(EAPT_TLS, outp);
   1000 		PUTCHAR(0, outp);
   1001 		eap_figure_next_state(esp, 0);
   1002 		break;
   1003 
   1004 	case eapTlsSendAlert:
   1005 		eaptls_send(esp->es_server.ea_session, &outp);
   1006 		eap_figure_next_state(esp, 0);
   1007 		break;
   1008 #endif /* USE_EAPTLS */
   1009 
   1010 #ifdef USE_SRP
   1011 	case eapSRP1:
   1012 		PUTCHAR(EAPT_SRP, outp);
   1013 		PUTCHAR(EAPSRP_CHALLENGE, outp);
   1014 
   1015 		PUTCHAR(esp->es_server.ea_namelen, outp);
   1016 		BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
   1017 		INCPTR(esp->es_server.ea_namelen, outp);
   1018 
   1019 		ts = (struct t_server *)esp->es_server.ea_session;
   1020 		assert(ts != NULL);
   1021 		PUTCHAR(ts->s.len, outp);
   1022 		BCOPY(ts->s.data, outp, ts->s.len);
   1023 		INCPTR(ts->s.len, outp);
   1024 
   1025 		if (ts->g.len == 1 && ts->g.data[0] == 2) {
   1026 			PUTCHAR(0, outp);
   1027 		} else {
   1028 			PUTCHAR(ts->g.len, outp);
   1029 			BCOPY(ts->g.data, outp, ts->g.len);
   1030 			INCPTR(ts->g.len, outp);
   1031 		}
   1032 
   1033 		if (ts->n.len != sizeof (wkmodulus) ||
   1034 		    BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
   1035 			BCOPY(ts->n.data, outp, ts->n.len);
   1036 			INCPTR(ts->n.len, outp);
   1037 		}
   1038 		break;
   1039 
   1040 	case eapSRP2:
   1041 		PUTCHAR(EAPT_SRP, outp);
   1042 		PUTCHAR(EAPSRP_SKEY, outp);
   1043 
   1044 		ts = (struct t_server *)esp->es_server.ea_session;
   1045 		assert(ts != NULL);
   1046 		BCOPY(ts->B.data, outp, ts->B.len);
   1047 		INCPTR(ts->B.len, outp);
   1048 		break;
   1049 
   1050 	case eapSRP3:
   1051 		PUTCHAR(EAPT_SRP, outp);
   1052 		PUTCHAR(EAPSRP_SVALIDATOR, outp);
   1053 		PUTLONG(SRPVAL_EBIT, outp);
   1054 		ts = (struct t_server *)esp->es_server.ea_session;
   1055 		assert(ts != NULL);
   1056 		BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
   1057 		INCPTR(SHA_DIGESTSIZE, outp);
   1058 
   1059 		if (pncrypt_setkey(0)) {
   1060 			/* Generate pseudonym */
   1061 			optr = outp;
   1062 			cp = (unsigned char *)esp->es_server.ea_peer;
   1063 			if ((j = i = esp->es_server.ea_peerlen) > 7)
   1064 				j = 7;
   1065 			clear[0] = i;
   1066 			BCOPY(cp, clear + 1, j);
   1067 			i -= j;
   1068 			cp += j;
   1069 			if (!DesEncrypt(clear, cipher)) {
   1070 				dbglog("no DES here; not generating pseudonym");
   1071 				break;
   1072 			}
   1073 			BZERO(&b64, sizeof (b64));
   1074 			outp++;		/* space for pseudonym length */
   1075 			outp += b64enc(&b64, cipher, 8, outp);
   1076 			while (i >= 8) {
   1077 				(void) DesEncrypt(cp, cipher);
   1078 				outp += b64enc(&b64, cipher, 8, outp);
   1079 				cp += 8;
   1080 				i -= 8;
   1081 			}
   1082 			if (i > 0) {
   1083 				BCOPY(cp, clear, i);
   1084 				cp += i;
   1085 				while (i < 8) {
   1086 					*cp++ = drand48() * 0x100;
   1087 					i++;
   1088 				}
   1089 				(void) DesEncrypt(clear, cipher);
   1090 				outp += b64enc(&b64, cipher, 8, outp);
   1091 			}
   1092 			outp += b64flush(&b64, outp);
   1093 
   1094 			/* Set length and pad out to next 20 octet boundary */
   1095 			i = outp - optr - 1;
   1096 			*optr = i;
   1097 			i %= SHA_DIGESTSIZE;
   1098 			if (i != 0) {
   1099 				while (i < SHA_DIGESTSIZE) {
   1100 					*outp++ = drand48() * 0x100;
   1101 					i++;
   1102 				}
   1103 			}
   1104 
   1105 			/* Obscure the pseudonym with SHA1 hash */
   1106 			SHA1Init(&ctxt);
   1107 			SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
   1108 			SHA1Update(&ctxt, esp->es_server.ea_skey,
   1109 			    SESSION_KEY_LEN);
   1110 			SHA1Update(&ctxt, esp->es_server.ea_peer,
   1111 			    esp->es_server.ea_peerlen);
   1112 			while (optr < outp) {
   1113 				SHA1Final(dig, &ctxt);
   1114 				cp = dig;
   1115 				while (cp < dig + SHA_DIGESTSIZE)
   1116 					*optr++ ^= *cp++;
   1117 				SHA1Init(&ctxt);
   1118 				SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
   1119 				SHA1Update(&ctxt, esp->es_server.ea_skey,
   1120 				    SESSION_KEY_LEN);
   1121 				SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
   1122 				    SHA_DIGESTSIZE);
   1123 			}
   1124 		}
   1125 		break;
   1126 
   1127 	case eapSRP4:
   1128 		PUTCHAR(EAPT_SRP, outp);
   1129 		PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
   1130 		challen = MIN_CHALLENGE_LENGTH +
   1131 		    ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
   1132 		esp->es_challen = challen;
   1133 		ptr = esp->es_challenge;
   1134 		while (--challen >= 0)
   1135 			*ptr++ = drand48() * 0x100;
   1136 		BCOPY(esp->es_challenge, outp, esp->es_challen);
   1137 		INCPTR(esp->es_challen, outp);
   1138 		break;
   1139 #endif /* USE_SRP */
   1140 
   1141 	default:
   1142 		return;
   1143 	}
   1144 
   1145 	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
   1146 	PUTSHORT(outlen, lenloc);
   1147 
   1148 	output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
   1149 
   1150 	esp->es_server.ea_requests++;
   1151 
   1152 	if (esp->es_server.ea_timeout > 0)
   1153 		TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
   1154 }
   1155 
   1156 /*
   1157  * eap_authpeer - Authenticate our peer (behave as server).
   1158  *
   1159  * Start server state and send first request.  This is called only
   1160  * after eap_lowerup.
   1161  */
   1162 void
   1163 eap_authpeer(int unit, char *localname)
   1164 {
   1165 	eap_state *esp = &eap_states[unit];
   1166 
   1167 	/* Save the name we're given. */
   1168 	esp->es_server.ea_name = localname;
   1169 	esp->es_server.ea_namelen = strlen(localname);
   1170 
   1171 	esp->es_savedtime = esp->es_server.ea_timeout;
   1172 
   1173 	/* Lower layer up yet? */
   1174 	if (esp->es_server.ea_state == eapInitial ||
   1175 	    esp->es_server.ea_state == eapPending) {
   1176 		esp->es_server.ea_state = eapPending;
   1177 		return;
   1178 	}
   1179 
   1180 	esp->es_server.ea_state = eapPending;
   1181 
   1182 	/* ID number not updated here intentionally; hashed into M1 */
   1183 	eap_send_request(esp);
   1184 }
   1185 
   1186 /*
   1187  * eap_server_timeout - Retransmission timer for sending Requests
   1188  * expired.
   1189  */
   1190 static void
   1191 eap_server_timeout(void *arg)
   1192 {
   1193 #ifdef USE_EAPTLS
   1194 	u_char *outp;
   1195 	u_char *lenloc;
   1196 	int outlen;
   1197 #endif /* USE_EAPTLS */
   1198 
   1199 	eap_state *esp = (eap_state *) arg;
   1200 
   1201 	if (!eap_server_active(esp))
   1202 		return;
   1203 
   1204 #ifdef USE_EAPTLS
   1205 	switch(esp->es_server.ea_prev_state) {
   1206 
   1207 	/*
   1208 	 *  In eap-tls the state changes after a request, so we return to
   1209 	 *  previous state ...
   1210 	 */
   1211 	case(eapTlsStart):
   1212 	case(eapTlsSendAck):
   1213 		esp->es_server.ea_state = esp->es_server.ea_prev_state;
   1214 		break;
   1215 
   1216 	/*
   1217 	 *  ... or resend the stored data
   1218 	 */
   1219 	case(eapTlsSend):
   1220 	case(eapTlsSendAlert):
   1221 		outp = outpacket_buf;
   1222 		MAKEHEADER(outp, PPP_EAP);
   1223 		PUTCHAR(EAP_REQUEST, outp);
   1224 		PUTCHAR(esp->es_server.ea_id, outp);
   1225 		lenloc = outp;
   1226 		INCPTR(2, outp);
   1227 
   1228 		eaptls_retransmit(esp->es_server.ea_session, &outp);
   1229 
   1230 		outlen = (outp - outpacket_buf) - PPP_HDRLEN;
   1231 		PUTSHORT(outlen, lenloc);
   1232 		output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
   1233 		esp->es_server.ea_requests++;
   1234 
   1235 		if (esp->es_server.ea_timeout > 0)
   1236 			TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
   1237 
   1238 		return;
   1239 	default:
   1240 		break;
   1241 	}
   1242 #endif /* USE_EAPTLS */
   1243 
   1244 	/* EAP ID number must not change on timeout. */
   1245 	eap_send_request(esp);
   1246 }
   1247 
   1248 /*
   1249  * When it's time to send rechallenge the peer, this timeout is
   1250  * called.  Once the rechallenge is successful, the response handler
   1251  * will restart the timer.  If it fails, then the link is dropped.
   1252  */
   1253 static void
   1254 eap_rechallenge(void *arg)
   1255 {
   1256 	eap_state *esp = (eap_state *)arg;
   1257 
   1258 	if (esp->es_server.ea_state != eapOpen &&
   1259 	    esp->es_server.ea_state != eapSRP4)
   1260 		return;
   1261 
   1262 	esp->es_server.ea_requests = 0;
   1263 	esp->es_server.ea_state = eapIdentify;
   1264 	eap_figure_next_state(esp, 0);
   1265 	esp->es_server.ea_id++;
   1266 	eap_send_request(esp);
   1267 }
   1268 
   1269 static void
   1270 srp_lwrechallenge(void *arg)
   1271 {
   1272 	eap_state *esp = (eap_state *)arg;
   1273 
   1274 	if (esp->es_server.ea_state != eapOpen ||
   1275 	    esp->es_server.ea_type != EAPT_SRP)
   1276 		return;
   1277 
   1278 	esp->es_server.ea_requests = 0;
   1279 	esp->es_server.ea_state = eapSRP4;
   1280 	esp->es_server.ea_id++;
   1281 	eap_send_request(esp);
   1282 }
   1283 
   1284 /*
   1285  * eap_lowerup - The lower layer is now up.
   1286  *
   1287  * This is called before either eap_authpeer or eap_authwithpeer.  See
   1288  * link_established() in auth.c.  All that's necessary here is to
   1289  * return to closed state so that those two routines will do the right
   1290  * thing.
   1291  */
   1292 static void
   1293 eap_lowerup(int unit)
   1294 {
   1295 	eap_state *esp = &eap_states[unit];
   1296 
   1297 	/* Discard any (possibly authenticated) peer name. */
   1298 	if (esp->es_server.ea_peer != NULL &&
   1299 	    esp->es_server.ea_peer != remote_name)
   1300 		free(esp->es_server.ea_peer);
   1301 	esp->es_server.ea_peer = NULL;
   1302 	if (esp->es_client.ea_peer != NULL)
   1303 		free(esp->es_client.ea_peer);
   1304 	esp->es_client.ea_peer = NULL;
   1305 
   1306 	esp->es_client.ea_state = eapClosed;
   1307 	esp->es_server.ea_state = eapClosed;
   1308 }
   1309 
   1310 /*
   1311  * eap_lowerdown - The lower layer is now down.
   1312  *
   1313  * Cancel all timeouts and return to initial state.
   1314  */
   1315 static void
   1316 eap_lowerdown(int unit)
   1317 {
   1318 	eap_state *esp = &eap_states[unit];
   1319 
   1320 	if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
   1321 		UNTIMEOUT(eap_client_timeout, (void *)esp);
   1322 	}
   1323 	if (eap_server_active(esp)) {
   1324 		if (esp->es_server.ea_timeout > 0) {
   1325 			UNTIMEOUT(eap_server_timeout, (void *)esp);
   1326 		}
   1327 	} else {
   1328 		if ((esp->es_server.ea_state == eapOpen ||
   1329 		    esp->es_server.ea_state == eapSRP4) &&
   1330 		    esp->es_rechallenge > 0) {
   1331 			UNTIMEOUT(eap_rechallenge, (void *)esp);
   1332 		}
   1333 		if (esp->es_server.ea_state == eapOpen &&
   1334 		    esp->es_lwrechallenge > 0) {
   1335 			UNTIMEOUT(srp_lwrechallenge, (void *)esp);
   1336 		}
   1337 	}
   1338 
   1339 	esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
   1340 	esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
   1341 }
   1342 
   1343 /*
   1344  * eap_protrej - Peer doesn't speak this protocol.
   1345  *
   1346  * This shouldn't happen.  If it does, it represents authentication
   1347  * failure.
   1348  */
   1349 static void
   1350 eap_protrej(int unit)
   1351 {
   1352 	eap_state *esp = &eap_states[unit];
   1353 
   1354 	if (eap_client_active(esp)) {
   1355 		error("EAP authentication failed due to Protocol-Reject");
   1356 		auth_withpeer_fail(unit, PPP_EAP);
   1357 	}
   1358 	if (eap_server_active(esp)) {
   1359 		error("EAP authentication of peer failed on Protocol-Reject");
   1360 		auth_peer_fail(unit, PPP_EAP);
   1361 	}
   1362 	eap_lowerdown(unit);
   1363 }
   1364 
   1365 /*
   1366  * Format and send a regular EAP Response message.
   1367  */
   1368 static void
   1369 eap_send_response(eap_state *esp, u_char id, u_char typenum,
   1370 		  u_char *str, int lenstr)
   1371 {
   1372 	u_char *outp;
   1373 	int msglen;
   1374 
   1375 	outp = outpacket_buf;
   1376 
   1377 	MAKEHEADER(outp, PPP_EAP);
   1378 
   1379 	PUTCHAR(EAP_RESPONSE, outp);
   1380 	PUTCHAR(id, outp);
   1381 	esp->es_client.ea_id = id;
   1382 	msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
   1383 	PUTSHORT(msglen, outp);
   1384 	PUTCHAR(typenum, outp);
   1385 	if (lenstr > 0) {
   1386 		BCOPY(str, outp, lenstr);
   1387 	}
   1388 
   1389 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
   1390 }
   1391 
   1392 /*
   1393  * Format and send an MD5-Challenge EAP Response message.
   1394  */
   1395 static void
   1396 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
   1397 		  char *name, int namelen)
   1398 {
   1399 	u_char *outp;
   1400 	int msglen;
   1401 
   1402 	outp = outpacket_buf;
   1403 
   1404 	MAKEHEADER(outp, PPP_EAP);
   1405 
   1406 	PUTCHAR(EAP_RESPONSE, outp);
   1407 	PUTCHAR(id, outp);
   1408 	esp->es_client.ea_id = id;
   1409 	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
   1410 	    namelen;
   1411 	PUTSHORT(msglen, outp);
   1412 	PUTCHAR(EAPT_MD5CHAP, outp);
   1413 	PUTCHAR(MD5_SIGNATURE_SIZE, outp);
   1414 	BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
   1415 	INCPTR(MD5_SIGNATURE_SIZE, outp);
   1416 	if (namelen > 0) {
   1417 		BCOPY(name, outp, namelen);
   1418 	}
   1419 
   1420 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
   1421 }
   1422 
   1423 #ifdef USE_SRP
   1424 /*
   1425  * Format and send a SRP EAP Response message.
   1426  */
   1427 static void
   1428 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
   1429 		 u_char *str, int lenstr)
   1430 {
   1431 	u_char *outp;
   1432 	int msglen;
   1433 
   1434 	outp = outpacket_buf;
   1435 
   1436 	MAKEHEADER(outp, PPP_EAP);
   1437 
   1438 	PUTCHAR(EAP_RESPONSE, outp);
   1439 	PUTCHAR(id, outp);
   1440 	esp->es_client.ea_id = id;
   1441 	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
   1442 	PUTSHORT(msglen, outp);
   1443 	PUTCHAR(EAPT_SRP, outp);
   1444 	PUTCHAR(subtypenum, outp);
   1445 	if (lenstr > 0) {
   1446 		BCOPY(str, outp, lenstr);
   1447 	}
   1448 
   1449 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
   1450 }
   1451 
   1452 /*
   1453  * Format and send a SRP EAP Client Validator Response message.
   1454  */
   1455 static void
   1456 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
   1457 {
   1458 	u_char *outp;
   1459 	int msglen;
   1460 
   1461 	outp = outpacket_buf;
   1462 
   1463 	MAKEHEADER(outp, PPP_EAP);
   1464 
   1465 	PUTCHAR(EAP_RESPONSE, outp);
   1466 	PUTCHAR(id, outp);
   1467 	esp->es_client.ea_id = id;
   1468 	msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
   1469 	    SHA_DIGESTSIZE;
   1470 	PUTSHORT(msglen, outp);
   1471 	PUTCHAR(EAPT_SRP, outp);
   1472 	PUTCHAR(EAPSRP_CVALIDATOR, outp);
   1473 	PUTLONG(flags, outp);
   1474 	BCOPY(str, outp, SHA_DIGESTSIZE);
   1475 
   1476 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
   1477 }
   1478 #endif /* USE_SRP */
   1479 
   1480 #ifdef USE_EAPTLS
   1481 /*
   1482  * Send an EAP-TLS response message with tls data
   1483  */
   1484 static void
   1485 eap_tls_response(eap_state *esp, u_char id)
   1486 {
   1487 	u_char *outp;
   1488 	int outlen;
   1489 	u_char *lenloc;
   1490 
   1491 	outp = outpacket_buf;
   1492 
   1493 	MAKEHEADER(outp, PPP_EAP);
   1494 
   1495 	PUTCHAR(EAP_RESPONSE, outp);
   1496 	PUTCHAR(id, outp);
   1497 
   1498 	lenloc = outp;
   1499 	INCPTR(2, outp);
   1500 
   1501 	/*
   1502 	   If the id in the request is unchanged, we must retransmit
   1503 	   the old data
   1504 	*/
   1505 	if(id == esp->es_client.ea_id)
   1506 		eaptls_retransmit(esp->es_client.ea_session, &outp);
   1507 	else
   1508 		eaptls_send(esp->es_client.ea_session, &outp);
   1509 
   1510 	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
   1511 	PUTSHORT(outlen, lenloc);
   1512 
   1513 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
   1514 
   1515 	esp->es_client.ea_id = id;
   1516 }
   1517 
   1518 /*
   1519  * Send an EAP-TLS ack
   1520  */
   1521 static void
   1522 eap_tls_sendack(eap_state *esp, u_char id)
   1523 {
   1524 	u_char *outp;
   1525 	int outlen;
   1526 	u_char *lenloc;
   1527 
   1528 	outp = outpacket_buf;
   1529 
   1530 	MAKEHEADER(outp, PPP_EAP);
   1531 
   1532 	PUTCHAR(EAP_RESPONSE, outp);
   1533 	PUTCHAR(id, outp);
   1534 	esp->es_client.ea_id = id;
   1535 
   1536 	lenloc = outp;
   1537 	INCPTR(2, outp);
   1538 
   1539 	PUTCHAR(EAPT_TLS, outp);
   1540 	PUTCHAR(0, outp);
   1541 
   1542 	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
   1543 	PUTSHORT(outlen, lenloc);
   1544 
   1545 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
   1546 }
   1547 #endif /* USE_EAPTLS */
   1548 
   1549 static void
   1550 eap_send_nak(eap_state *esp, u_char id, u_char type)
   1551 {
   1552 	u_char *outp;
   1553 	int msglen;
   1554 
   1555 	outp = outpacket_buf;
   1556 
   1557 	MAKEHEADER(outp, PPP_EAP);
   1558 
   1559 	PUTCHAR(EAP_RESPONSE, outp);
   1560 	PUTCHAR(id, outp);
   1561 	esp->es_client.ea_id = id;
   1562 	msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
   1563 	PUTSHORT(msglen, outp);
   1564 	PUTCHAR(EAPT_NAK, outp);
   1565 	PUTCHAR(type, outp);
   1566 
   1567 	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
   1568 }
   1569 
   1570 #ifdef USE_SRP
   1571 static char *
   1572 name_of_pn_file(void)
   1573 {
   1574 	char *user, *path, *file;
   1575 	struct passwd *pw;
   1576 	size_t pl;
   1577 	static bool pnlogged = 0;
   1578 
   1579 	pw = getpwuid(getuid());
   1580 	if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
   1581 		errno = EINVAL;
   1582 		return (NULL);
   1583 	}
   1584 	file = _PATH_PSEUDONYM;
   1585 	pl = strlen(user) + strlen(file) + 2;
   1586 	path = malloc(pl);
   1587 	if (path == NULL)
   1588 		return (NULL);
   1589 	(void) slprintf(path, pl, "%s/%s", user, file);
   1590 	if (!pnlogged) {
   1591 		dbglog("pseudonym file: %s", path);
   1592 		pnlogged = 1;
   1593 	}
   1594 	return (path);
   1595 }
   1596 
   1597 static int
   1598 open_pn_file(mode_t modebits)
   1599 {
   1600 	char *path;
   1601 	int fd, err;
   1602 
   1603 	if ((path = name_of_pn_file()) == NULL)
   1604 		return (-1);
   1605 	fd = open(path, modebits, S_IRUSR | S_IWUSR);
   1606 	err = errno;
   1607 	free(path);
   1608 	errno = err;
   1609 	return (fd);
   1610 }
   1611 
   1612 static void
   1613 remove_pn_file(void)
   1614 {
   1615 	char *path;
   1616 
   1617 	if ((path = name_of_pn_file()) != NULL) {
   1618 		(void) unlink(path);
   1619 		(void) free(path);
   1620 	}
   1621 }
   1622 
   1623 static void
   1624 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
   1625 {
   1626 	u_char val;
   1627 	u_char *datp, *digp;
   1628 	SHA1_CTX ctxt;
   1629 	u_char dig[SHA_DIGESTSIZE];
   1630 	int dsize, fd, olen = len;
   1631 
   1632 	/*
   1633 	 * Do the decoding by working backwards.  This eliminates the need
   1634 	 * to save the decoded output in a separate buffer.
   1635 	 */
   1636 	val = id;
   1637 	while (len > 0) {
   1638 		if ((dsize = len % SHA_DIGESTSIZE) == 0)
   1639 			dsize = SHA_DIGESTSIZE;
   1640 		len -= dsize;
   1641 		datp = inp + len;
   1642 		SHA1Init(&ctxt);
   1643 		SHA1Update(&ctxt, &val, 1);
   1644 		SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
   1645 		if (len > 0) {
   1646 			SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
   1647 		} else {
   1648 			SHA1Update(&ctxt, esp->es_client.ea_name,
   1649 			    esp->es_client.ea_namelen);
   1650 		}
   1651 		SHA1Final(dig, &ctxt);
   1652 		for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
   1653 			*datp++ ^= *digp;
   1654 	}
   1655 
   1656 	/* Now check that the result is sane */
   1657 	if (olen <= 0 || *inp + 1 > olen) {
   1658 		dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
   1659 		return;
   1660 	}
   1661 
   1662 	/* Save it away */
   1663 	fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
   1664 	if (fd < 0) {
   1665 		dbglog("EAP: error saving pseudonym: %m");
   1666 		return;
   1667 	}
   1668 	len = write(fd, inp + 1, *inp);
   1669 	if (close(fd) != -1 && len == *inp) {
   1670 		dbglog("EAP: saved pseudonym");
   1671 		esp->es_usedpseudo = 0;
   1672 	} else {
   1673 		dbglog("EAP: failed to save pseudonym");
   1674 		remove_pn_file();
   1675 	}
   1676 }
   1677 #endif /* USE_SRP */
   1678 
   1679 #if CHAPMS
   1680 /*
   1681  * Format and send an CHAPV2-Challenge EAP Response message.
   1682  */
   1683 static void
   1684 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
   1685 {
   1686     u_char *outp;
   1687     int msglen;
   1688 
   1689     outp = outpacket_buf;
   1690 
   1691     MAKEHEADER(outp, PPP_EAP);
   1692 
   1693     PUTCHAR(EAP_RESPONSE, outp);
   1694     PUTCHAR(id, outp);
   1695     esp->es_client.ea_id = id;
   1696     msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
   1697     PUTSHORT(msglen, outp);
   1698     PUTCHAR(EAPT_MSCHAPV2, outp);
   1699     PUTCHAR(CHAP_RESPONSE, outp);
   1700     PUTCHAR(chapid, outp);
   1701     PUTCHAR(0, outp);
   1702     /* len */
   1703     PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
   1704     BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
   1705     INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
   1706     BCOPY(user, outp, user_len);
   1707 
   1708     output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
   1709 }
   1710 #endif
   1711 
   1712 /*
   1713  * eap_request - Receive EAP Request message (client mode).
   1714  */
   1715 static void
   1716 eap_request(eap_state *esp, u_char *inp, int id, int len)
   1717 {
   1718 	u_char typenum;
   1719 	u_char vallen;
   1720 	int secret_len;
   1721 	char secret[MAXWORDLEN];
   1722 	char rhostname[256];
   1723 	MD5_CTX mdContext;
   1724 	u_char hash[MD5_SIGNATURE_SIZE];
   1725 #ifdef USE_EAPTLS
   1726 	u_char flags;
   1727 	struct eaptls_session *ets = esp->es_client.ea_session;
   1728 #endif /* USE_EAPTLS */
   1729 
   1730 #ifdef USE_SRP
   1731 	struct t_client *tc;
   1732 	struct t_num sval, gval, Nval, *Ap, Bval;
   1733 	u_char vals[2];
   1734 	SHA1_CTX ctxt;
   1735 	u_char dig[SHA_DIGESTSIZE];
   1736 	int fd;
   1737 #endif /* USE_SRP */
   1738 
   1739 	/*
   1740 	 * Ignore requests if we're not open
   1741 	 */
   1742 	if (esp->es_client.ea_state <= eapClosed)
   1743 		return;
   1744 
   1745 	/*
   1746 	 * Note: we update es_client.ea_id *only if* a Response
   1747 	 * message is being generated.  Otherwise, we leave it the
   1748 	 * same for duplicate detection purposes.
   1749 	 */
   1750 
   1751 	esp->es_client.ea_requests++;
   1752 	if (esp->es_client.ea_maxrequests != 0 &&
   1753 	    esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
   1754 		info("EAP: received too many Request messages");
   1755 		if (esp->es_client.ea_timeout > 0) {
   1756 			UNTIMEOUT(eap_client_timeout, (void *)esp);
   1757 		}
   1758 		auth_withpeer_fail(esp->es_unit, PPP_EAP);
   1759 		return;
   1760 	}
   1761 
   1762 	if (len <= 0) {
   1763 		error("EAP: empty Request message discarded");
   1764 		return;
   1765 	}
   1766 
   1767 	GETCHAR(typenum, inp);
   1768 	len--;
   1769 
   1770 	switch (typenum) {
   1771 	case EAPT_IDENTITY:
   1772 		if (len > 0)
   1773 			info("EAP: Identity prompt \"%.*q\"", len, inp);
   1774 #ifdef USE_SRP
   1775 		if (esp->es_usepseudo &&
   1776 		    (esp->es_usedpseudo == 0 ||
   1777 			(esp->es_usedpseudo == 1 &&
   1778 			    id == esp->es_client.ea_id))) {
   1779 			esp->es_usedpseudo = 1;
   1780 			/* Try to get a pseudonym */
   1781 			if ((fd = open_pn_file(O_RDONLY)) >= 0) {
   1782 				strcpy(rhostname, SRP_PSEUDO_ID);
   1783 				len = read(fd, rhostname + SRP_PSEUDO_LEN,
   1784 				    sizeof (rhostname) - SRP_PSEUDO_LEN);
   1785 				/* XXX NAI unsupported */
   1786 				if (len > 0) {
   1787 					eap_send_response(esp, id, typenum,
   1788 					    rhostname, len + SRP_PSEUDO_LEN);
   1789 				}
   1790 				(void) close(fd);
   1791 				if (len > 0)
   1792 					break;
   1793 			}
   1794 		}
   1795 		/* Stop using pseudonym now. */
   1796 		if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
   1797 			remove_pn_file();
   1798 			esp->es_usedpseudo = 2;
   1799 		}
   1800 #endif /* USE_SRP */
   1801 		eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
   1802 		    esp->es_client.ea_namelen);
   1803 		break;
   1804 
   1805 	case EAPT_NOTIFICATION:
   1806 		if (len > 0)
   1807 			info("EAP: Notification \"%.*q\"", len, inp);
   1808 		eap_send_response(esp, id, typenum, NULL, 0);
   1809 		break;
   1810 
   1811 	case EAPT_NAK:
   1812 		/*
   1813 		 * Avoid the temptation to send Response Nak in reply
   1814 		 * to Request Nak here.  It can only lead to trouble.
   1815 		 */
   1816 		warn("EAP: unexpected Nak in Request; ignored");
   1817 		/* Return because we're waiting for something real. */
   1818 		return;
   1819 
   1820 	case EAPT_MD5CHAP:
   1821 		if (len < 1) {
   1822 			error("EAP: received MD5-Challenge with no data");
   1823 			/* Bogus request; wait for something real. */
   1824 			return;
   1825 		}
   1826 		GETCHAR(vallen, inp);
   1827 		len--;
   1828 		if (vallen < 8 || vallen > len) {
   1829 			error("EAP: MD5-Challenge with bad length %d (8..%d)",
   1830 			    vallen, len);
   1831 			/* Try something better. */
   1832 			eap_send_nak(esp, id, EAPT_SRP);
   1833 			break;
   1834 		}
   1835 
   1836 		/* Not so likely to happen. */
   1837 		if (len - vallen >= sizeof (rhostname)) {
   1838 			dbglog("EAP: trimming really long peer name down");
   1839 			BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
   1840 			rhostname[sizeof (rhostname) - 1] = '\0';
   1841 		} else {
   1842 			BCOPY(inp + vallen, rhostname, len - vallen);
   1843 			rhostname[len - vallen] = '\0';
   1844 		}
   1845 
   1846 		/* In case the remote doesn't give us his name. */
   1847 		if (explicit_remote ||
   1848 		    (remote_name[0] != '\0' && vallen == len))
   1849 			strlcpy(rhostname, remote_name, sizeof (rhostname));
   1850 
   1851 		/*
   1852 		 * Get the secret for authenticating ourselves with
   1853 		 * the specified host.
   1854 		 */
   1855 		if (!get_secret(esp->es_unit, esp->es_client.ea_name,
   1856 		    rhostname, secret, &secret_len, 0)) {
   1857 			dbglog("EAP: no MD5 secret for auth to %q", rhostname);
   1858 			eap_send_nak(esp, id, EAPT_SRP);
   1859 			break;
   1860 		}
   1861 		MD5_Init(&mdContext);
   1862 		typenum = id;
   1863 		MD5_Update(&mdContext, &typenum, 1);
   1864 		MD5_Update(&mdContext, (u_char *)secret, secret_len);
   1865 		BZERO(secret, sizeof (secret));
   1866 		MD5_Update(&mdContext, inp, vallen);
   1867 		MD5_Final(hash, &mdContext);
   1868 		eap_chap_response(esp, id, hash, esp->es_client.ea_name,
   1869 		    esp->es_client.ea_namelen);
   1870 		break;
   1871 
   1872 #ifdef USE_EAPTLS
   1873 	case EAPT_TLS:
   1874 
   1875 		switch(esp->es_client.ea_state) {
   1876 
   1877 		case eapListen:
   1878 
   1879 			if (len < 1) {
   1880 				error("EAP: received EAP-TLS Listen packet with no data");
   1881 				/* Bogus request; wait for something real. */
   1882 				return;
   1883 			}
   1884 			GETCHAR(flags, inp);
   1885 			if(flags & EAP_TLS_FLAGS_START){
   1886 
   1887 				esp->es_client.ea_using_eaptls = 1;
   1888 
   1889 				if (explicit_remote){
   1890 					esp->es_client.ea_peer = strdup(remote_name);
   1891 					esp->es_client.ea_peerlen = strlen(remote_name);
   1892 				} else
   1893 					esp->es_client.ea_peer = NULL;
   1894 
   1895 				/* Init ssl session */
   1896 				if(!eaptls_init_ssl_client(esp)) {
   1897 					dbglog("cannot init ssl");
   1898 					eap_send_nak(esp, id, EAPT_MSCHAPV2);
   1899 					esp->es_client.ea_using_eaptls = 0;
   1900 					break;
   1901 				}
   1902 
   1903 				ets = esp->es_client.ea_session;
   1904 				eap_tls_response(esp, id);
   1905 				esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
   1906 				break;
   1907 			}
   1908 
   1909 			/* The server has sent a bad start packet. */
   1910 			eap_send_nak(esp, id, EAPT_MSCHAPV2);
   1911 			break;
   1912 
   1913 		case eapTlsRecvAck:
   1914 			eap_tls_response(esp, id);
   1915 			esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
   1916 			break;
   1917 
   1918 		case eapTlsRecv:
   1919 			if (len < 1) {
   1920 				error("EAP: discarding EAP-TLS Receive packet with no data");
   1921 				/* Bogus request; wait for something real. */
   1922 				return;
   1923 			}
   1924 			eaptls_receive(ets, inp, len);
   1925 
   1926 			if(ets->frag) {
   1927 				eap_tls_sendack(esp, id);
   1928 				esp->es_client.ea_state = eapTlsRecv;
   1929 				break;
   1930 			}
   1931 
   1932 			if(ets->alert_recv) {
   1933 				eap_tls_sendack(esp, id);
   1934 				esp->es_client.ea_state = eapTlsRecvFailure;
   1935 				break;
   1936 			}
   1937 
   1938 			/* Check if TLS handshake is finished */
   1939 			if(eaptls_is_init_finished(ets)) {
   1940 #ifdef MPPE
   1941 				eaptls_gen_mppe_keys(ets, 1);
   1942 #endif
   1943 				eaptls_free_session(ets);
   1944 				eap_tls_sendack(esp, id);
   1945 				esp->es_client.ea_state = eapTlsRecvSuccess;
   1946 				break;
   1947 			}
   1948 
   1949 			eap_tls_response(esp,id);
   1950 			esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
   1951 			break;
   1952 
   1953 		default:
   1954 			eap_send_nak(esp, id, EAPT_MSCHAPV2);
   1955 			esp->es_client.ea_using_eaptls = 0;
   1956 			break;
   1957 		}
   1958 
   1959 		break;
   1960 #endif /* USE_EAPTLS */
   1961 
   1962 #ifdef USE_SRP
   1963 	case EAPT_SRP:
   1964 		if (len < 1) {
   1965 			error("EAP: received empty SRP Request");
   1966 			/* Bogus request; wait for something real. */
   1967 			return;
   1968 		}
   1969 
   1970 		/* Get subtype */
   1971 		GETCHAR(vallen, inp);
   1972 		len--;
   1973 		switch (vallen) {
   1974 		case EAPSRP_CHALLENGE:
   1975 			tc = NULL;
   1976 			if (esp->es_client.ea_session != NULL) {
   1977 				tc = (struct t_client *)esp->es_client.
   1978 				    ea_session;
   1979 				/*
   1980 				 * If this is a new challenge, then start
   1981 				 * over with a new client session context.
   1982 				 * Otherwise, just resend last response.
   1983 				 */
   1984 				if (id != esp->es_client.ea_id) {
   1985 					t_clientclose(tc);
   1986 					esp->es_client.ea_session = NULL;
   1987 					tc = NULL;
   1988 				}
   1989 			}
   1990 			/* No session key just yet */
   1991 			esp->es_client.ea_skey = NULL;
   1992 			if (tc == NULL) {
   1993 				GETCHAR(vallen, inp);
   1994 				len--;
   1995 				if (vallen >= len) {
   1996 					error("EAP: badly-formed SRP Challenge"
   1997 					    " (name)");
   1998 					/* Ignore badly-formed messages */
   1999 					return;
   2000 				}
   2001 				BCOPY(inp, rhostname, vallen);
   2002 				rhostname[vallen] = '\0';
   2003 				INCPTR(vallen, inp);
   2004 				len -= vallen;
   2005 
   2006 				/*
   2007 				 * In case the remote doesn't give us his name,
   2008 				 * use configured name.
   2009 				 */
   2010 				if (explicit_remote ||
   2011 				    (remote_name[0] != '\0' && vallen == 0)) {
   2012 					strlcpy(rhostname, remote_name,
   2013 					    sizeof (rhostname));
   2014 				}
   2015 
   2016 				if (esp->es_client.ea_peer != NULL)
   2017 					free(esp->es_client.ea_peer);
   2018 				esp->es_client.ea_peer = strdup(rhostname);
   2019 				esp->es_client.ea_peerlen = strlen(rhostname);
   2020 
   2021 				GETCHAR(vallen, inp);
   2022 				len--;
   2023 				if (vallen >= len) {
   2024 					error("EAP: badly-formed SRP Challenge"
   2025 					    " (s)");
   2026 					/* Ignore badly-formed messages */
   2027 					return;
   2028 				}
   2029 				sval.data = inp;
   2030 				sval.len = vallen;
   2031 				INCPTR(vallen, inp);
   2032 				len -= vallen;
   2033 
   2034 				GETCHAR(vallen, inp);
   2035 				len--;
   2036 				if (vallen > len) {
   2037 					error("EAP: badly-formed SRP Challenge"
   2038 					    " (g)");
   2039 					/* Ignore badly-formed messages */
   2040 					return;
   2041 				}
   2042 				/* If no generator present, then use value 2 */
   2043 				if (vallen == 0) {
   2044 					gval.data = (u_char *)"\002";
   2045 					gval.len = 1;
   2046 				} else {
   2047 					gval.data = inp;
   2048 					gval.len = vallen;
   2049 				}
   2050 				INCPTR(vallen, inp);
   2051 				len -= vallen;
   2052 
   2053 				/*
   2054 				 * If no modulus present, then use well-known
   2055 				 * value.
   2056 				 */
   2057 				if (len == 0) {
   2058 					Nval.data = (u_char *)wkmodulus;
   2059 					Nval.len = sizeof (wkmodulus);
   2060 				} else {
   2061 					Nval.data = inp;
   2062 					Nval.len = len;
   2063 				}
   2064 				tc = t_clientopen(esp->es_client.ea_name,
   2065 				    &Nval, &gval, &sval);
   2066 				if (tc == NULL) {
   2067 					eap_send_nak(esp, id, EAPT_MD5CHAP);
   2068 					break;
   2069 				}
   2070 				esp->es_client.ea_session = (void *)tc;
   2071 
   2072 				/* Add Challenge ID & type to verifier */
   2073 				vals[0] = id;
   2074 				vals[1] = EAPT_SRP;
   2075 				t_clientaddexdata(tc, vals, 2);
   2076 			}
   2077 			Ap = t_clientgenexp(tc);
   2078 			eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
   2079 			    Ap->len);
   2080 			break;
   2081 
   2082 		case EAPSRP_SKEY:
   2083 			tc = (struct t_client *)esp->es_client.ea_session;
   2084 			if (tc == NULL) {
   2085 				warn("EAP: peer sent Subtype 2 without 1");
   2086 				eap_send_nak(esp, id, EAPT_MD5CHAP);
   2087 				break;
   2088 			}
   2089 			if (esp->es_client.ea_skey != NULL) {
   2090 				/*
   2091 				 * ID number should not change here.  Warn
   2092 				 * if it does (but otherwise ignore).
   2093 				 */
   2094 				if (id != esp->es_client.ea_id) {
   2095 					warn("EAP: ID changed from %d to %d "
   2096 					    "in SRP Subtype 2 rexmit",
   2097 					    esp->es_client.ea_id, id);
   2098 				}
   2099 			} else {
   2100 				if (get_srp_secret(esp->es_unit,
   2101 				    esp->es_client.ea_name,
   2102 				    esp->es_client.ea_peer, secret, 0) == 0) {
   2103 					/*
   2104 					 * Can't work with this peer because
   2105 					 * the secret is missing.  Just give
   2106 					 * up.
   2107 					 */
   2108 					eap_send_nak(esp, id, EAPT_MD5CHAP);
   2109 					break;
   2110 				}
   2111 				Bval.data = inp;
   2112 				Bval.len = len;
   2113 				t_clientpasswd(tc, secret);
   2114 				BZERO(secret, sizeof (secret));
   2115 				esp->es_client.ea_skey =
   2116 				    t_clientgetkey(tc, &Bval);
   2117 				if (esp->es_client.ea_skey == NULL) {
   2118 					/* Server is rogue; stop now */
   2119 					error("EAP: SRP server is rogue");
   2120 					goto client_failure;
   2121 				}
   2122 			}
   2123 			eap_srpval_response(esp, id, SRPVAL_EBIT,
   2124 			    t_clientresponse(tc));
   2125 			break;
   2126 
   2127 		case EAPSRP_SVALIDATOR:
   2128 			tc = (struct t_client *)esp->es_client.ea_session;
   2129 			if (tc == NULL || esp->es_client.ea_skey == NULL) {
   2130 				warn("EAP: peer sent Subtype 3 without 1/2");
   2131 				eap_send_nak(esp, id, EAPT_MD5CHAP);
   2132 				break;
   2133 			}
   2134 			/*
   2135 			 * If we're already open, then this ought to be a
   2136 			 * duplicate.  Otherwise, check that the server is
   2137 			 * who we think it is.
   2138 			 */
   2139 			if (esp->es_client.ea_state == eapOpen) {
   2140 				if (id != esp->es_client.ea_id) {
   2141 					warn("EAP: ID changed from %d to %d "
   2142 					    "in SRP Subtype 3 rexmit",
   2143 					    esp->es_client.ea_id, id);
   2144 				}
   2145 			} else {
   2146 				len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
   2147 				if (len < 0 || t_clientverify(tc, inp +
   2148 					sizeof (u_int32_t)) != 0) {
   2149 					error("EAP: SRP server verification "
   2150 					    "failed");
   2151 					goto client_failure;
   2152 				}
   2153 				GETLONG(esp->es_client.ea_keyflags, inp);
   2154 				/* Save pseudonym if user wants it. */
   2155 				if (len > 0 && esp->es_usepseudo) {
   2156 					INCPTR(SHA_DIGESTSIZE, inp);
   2157 					write_pseudonym(esp, inp, len, id);
   2158 				}
   2159 			}
   2160 			/*
   2161 			 * We've verified our peer.  We're now mostly done,
   2162 			 * except for waiting on the regular EAP Success
   2163 			 * message.
   2164 			 */
   2165 			eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
   2166 			break;
   2167 
   2168 		case EAPSRP_LWRECHALLENGE:
   2169 			if (len < 4) {
   2170 				warn("EAP: malformed Lightweight rechallenge");
   2171 				return;
   2172 			}
   2173 			SHA1Init(&ctxt);
   2174 			vals[0] = id;
   2175 			SHA1Update(&ctxt, vals, 1);
   2176 			SHA1Update(&ctxt, esp->es_client.ea_skey,
   2177 			    SESSION_KEY_LEN);
   2178 			SHA1Update(&ctxt, inp, len);
   2179 			SHA1Update(&ctxt, esp->es_client.ea_name,
   2180 			    esp->es_client.ea_namelen);
   2181 			SHA1Final(dig, &ctxt);
   2182 			eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
   2183 			    SHA_DIGESTSIZE);
   2184 			break;
   2185 
   2186 		default:
   2187 			error("EAP: unknown SRP Subtype %d", vallen);
   2188 			eap_send_nak(esp, id, EAPT_MD5CHAP);
   2189 			break;
   2190 		}
   2191 		break;
   2192 #endif /* USE_SRP */
   2193 
   2194 #ifdef CHAPMS
   2195         case EAPT_MSCHAPV2:
   2196 	    if (len < 4) {
   2197 		error("EAP: received invalid MSCHAPv2 packet, too short");
   2198 		return;
   2199 	    }
   2200 	    unsigned char opcode;
   2201 	    GETCHAR(opcode, inp);
   2202 	    unsigned char chapid; /* Chapv2-ID */
   2203 	    GETCHAR(chapid, inp);
   2204 	    short mssize;
   2205 	    GETSHORT(mssize, inp);
   2206 
   2207 	    /* Validate the mssize field */
   2208 	    if (len != mssize) {
   2209 		error("EAP: received invalid MSCHAPv2 packet, invalid length");
   2210 		return;
   2211 	    }
   2212 	    len -= 4;
   2213 
   2214 	    /* If MSCHAPv2 digest was not found, NAK the packet */
   2215 	    if (!esp->es_client.digest) {
   2216 		error("EAP MSCHAPv2 not supported");
   2217 		eap_send_nak(esp, id, EAPT_SRP);
   2218 		return;
   2219 	    }
   2220 
   2221 	    switch (opcode) {
   2222 	    case CHAP_CHALLENGE: {
   2223 
   2224 		/* make_response() expects: VLEN + VALUE */
   2225 		u_char *challenge = inp;
   2226 
   2227 		unsigned char vsize;
   2228 		GETCHAR(vsize, inp);
   2229                 len -= 1;
   2230 
   2231 		/* Validate the VALUE field */
   2232                 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
   2233                     error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
   2234                     return;
   2235                 }
   2236 
   2237 		/* Increment past the VALUE field */
   2238 		INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
   2239 		len -= MS_CHAP2_PEER_CHAL_LEN;
   2240 
   2241 		/* Extract the hostname */
   2242 		rhostname[0] = '\0';
   2243 		if (len > 0) {
   2244 		    if (len >= sizeof (rhostname)) {
   2245 			dbglog("EAP: trimming really long peer name down");
   2246 			len = sizeof(rhostname) - 1;
   2247 		    }
   2248 		    BCOPY(inp, rhostname, len);
   2249 		    rhostname[len] = '\0';
   2250 		}
   2251 
   2252 		/* In case the remote doesn't give us his name. */
   2253 		if (explicit_remote || (remote_name[0] != '\0' && len == 0))
   2254 		    strlcpy(rhostname, remote_name, sizeof(rhostname));
   2255 
   2256 		/* Get the secret for authenticating ourselves with the specified host. */
   2257 		if (!get_secret(esp->es_unit, esp->es_client.ea_name,
   2258 		    rhostname, secret, &secret_len, 0)) {
   2259 		    dbglog("EAP: no CHAP secret for auth to %q", rhostname);
   2260 		    eap_send_nak(esp, id, EAPT_SRP);
   2261 		    break;
   2262 		}
   2263 
   2264 		/* Create the MSCHAPv2 response (and add to cache) */
   2265 		unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
   2266 		esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
   2267 			challenge, secret, secret_len, NULL);
   2268 
   2269 		eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
   2270 		break;
   2271 	    }
   2272 	    case CHAP_SUCCESS: {
   2273 
   2274 		/* Check response for mutual authentication */
   2275 		u_char status = CHAP_FAILURE;
   2276 		if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
   2277 		     info("Chap authentication succeeded! %.*v", len, inp);
   2278 		     status = CHAP_SUCCESS;
   2279 		}
   2280 		eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
   2281 		break;
   2282 	    }
   2283 	    case CHAP_FAILURE: {
   2284 
   2285 		/* Process the failure string, and log appropriate information */
   2286 		esp->es_client.digest->handle_failure(inp, len);
   2287 
   2288 		u_char status = CHAP_FAILURE;
   2289 		eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
   2290 		goto client_failure; /* force termination */
   2291 	    }
   2292 	    default:
   2293 
   2294                 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
   2295 		eap_send_nak(esp, id, EAPT_SRP);
   2296 	    }
   2297 
   2298 	    break;
   2299 #endif /* CHAPMS */
   2300 
   2301 	default:
   2302 		info("EAP: unknown authentication type %d; Naking", typenum);
   2303 		eap_send_nak(esp, id, EAPT_SRP);
   2304 		break;
   2305 	}
   2306 
   2307 	if (esp->es_client.ea_timeout > 0) {
   2308 		UNTIMEOUT(eap_client_timeout, (void *)esp);
   2309 		TIMEOUT(eap_client_timeout, (void *)esp,
   2310 		    esp->es_client.ea_timeout);
   2311 	}
   2312 	return;
   2313 
   2314 client_failure:
   2315 	esp->es_client.ea_state = eapBadAuth;
   2316 	if (esp->es_client.ea_timeout > 0) {
   2317 		UNTIMEOUT(eap_client_timeout, (void *)esp);
   2318 	}
   2319 	esp->es_client.ea_session = NULL;
   2320 #ifdef USE_SRP
   2321 	t_clientclose(tc);
   2322 	auth_withpeer_fail(esp->es_unit, PPP_EAP);
   2323 #endif /* USE_SRP */
   2324 }
   2325 
   2326 /*
   2327  * eap_response - Receive EAP Response message (server mode).
   2328  */
   2329 static void
   2330 eap_response(eap_state *esp, u_char *inp, int id, int len)
   2331 {
   2332 	u_char typenum;
   2333 	u_char vallen;
   2334 	int secret_len;
   2335 	char secret[MAXSECRETLEN];
   2336 	char rhostname[256];
   2337 	MD5_CTX mdContext;
   2338 	u_char hash[MD5_SIGNATURE_SIZE];
   2339 #ifdef USE_SRP
   2340 	struct t_server *ts;
   2341 	struct t_num A;
   2342 	SHA1_CTX ctxt;
   2343 	u_char dig[SHA_DIGESTSIZE];
   2344 	SHA1_CTX ctxt;
   2345 	u_char dig[SHA_DIGESTSIZE];
   2346 #endif /* USE_SRP */
   2347 
   2348 #ifdef USE_EAPTLS
   2349 	struct eaptls_session *ets;
   2350 	u_char flags;
   2351 #endif /* USE_EAPTLS */
   2352 #ifdef CHAPMS
   2353 	u_char opcode;
   2354 	int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
   2355 		unsigned char *, unsigned char *, char *, int);
   2356 	char response_message[256];
   2357 #endif /* CHAPMS */
   2358 
   2359 	/*
   2360 	 * Ignore responses if we're not open
   2361 	 */
   2362 	if (esp->es_server.ea_state <= eapClosed)
   2363 		return;
   2364 
   2365 	if (esp->es_server.ea_id != id) {
   2366 		dbglog("EAP: discarding Response %d; expected ID %d", id,
   2367 		    esp->es_server.ea_id);
   2368 		return;
   2369 	}
   2370 
   2371 	esp->es_server.ea_responses++;
   2372 
   2373 	if (len <= 0) {
   2374 		error("EAP: empty Response message discarded");
   2375 		return;
   2376 	}
   2377 
   2378 	GETCHAR(typenum, inp);
   2379 	len--;
   2380 
   2381 	switch (typenum) {
   2382 	case EAPT_IDENTITY:
   2383 		if (esp->es_server.ea_state != eapIdentify) {
   2384 			dbglog("EAP discarding unwanted Identify \"%.q\"", len,
   2385 			    inp);
   2386 			break;
   2387 		}
   2388 		info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
   2389 		if (esp->es_server.ea_peer != NULL &&
   2390 		    esp->es_server.ea_peer != remote_name)
   2391 			free(esp->es_server.ea_peer);
   2392 		esp->es_server.ea_peer = malloc(len + 1);
   2393 		if (esp->es_server.ea_peer == NULL) {
   2394 			esp->es_server.ea_peerlen = 0;
   2395 			eap_figure_next_state(esp, 1);
   2396 			break;
   2397 		}
   2398 		BCOPY(inp, esp->es_server.ea_peer, len);
   2399 		esp->es_server.ea_peer[len] = '\0';
   2400 		esp->es_server.ea_peerlen = len;
   2401 		eap_figure_next_state(esp, 0);
   2402 		break;
   2403 
   2404 #ifdef USE_EAPTLS
   2405 	case EAPT_TLS:
   2406 		switch(esp->es_server.ea_state) {
   2407 
   2408 		case eapTlsRecv:
   2409 
   2410 			ets = (struct eaptls_session *) esp->es_server.ea_session;
   2411 
   2412 			eap_figure_next_state(esp,
   2413 				eaptls_receive(esp->es_server.ea_session, inp, len));
   2414 
   2415 			if(ets->alert_recv) {
   2416 				eap_send_failure(esp);
   2417 				break;
   2418 			}
   2419 			break;
   2420 
   2421 		case eapTlsRecvAck:
   2422 			if(len > 1) {
   2423 				dbglog("EAP-TLS ACK with extra data");
   2424 			}
   2425 			eap_figure_next_state(esp, 0);
   2426 			break;
   2427 
   2428 		case eapTlsRecvClient:
   2429 			/* Receive authentication response from client */
   2430 			if (len > 0) {
   2431 				GETCHAR(flags, inp);
   2432 
   2433 				if(len == 1 && !flags) {	/* Ack = ok */
   2434 #ifdef MPPE
   2435 					eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
   2436 #endif
   2437 					eap_send_success(esp);
   2438 				}
   2439 				else {			/* failure */
   2440 					warn("Server authentication failed");
   2441 					eap_send_failure(esp);
   2442 				}
   2443 			}
   2444 			else
   2445 				warn("Bogus EAP-TLS packet received from client");
   2446 
   2447 			eaptls_free_session(esp->es_server.ea_session);
   2448 
   2449 			break;
   2450 
   2451 		case eapTlsRecvAlertAck:
   2452 			eap_send_failure(esp);
   2453 			break;
   2454 
   2455 		default:
   2456 			eap_figure_next_state(esp, 1);
   2457 			break;
   2458 		}
   2459 		break;
   2460 #endif /* USE_EAPTLS */
   2461 
   2462 	case EAPT_NOTIFICATION:
   2463 		dbglog("EAP unexpected Notification; response discarded");
   2464 		break;
   2465 
   2466 	case EAPT_NAK:
   2467 		if (len < 1) {
   2468 			info("EAP: Nak Response with no suggested protocol");
   2469 			eap_figure_next_state(esp, 1);
   2470 			break;
   2471 		}
   2472 
   2473 		GETCHAR(vallen, inp);
   2474 		len--;
   2475 
   2476 		if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
   2477 			/* Peer cannot Nak Identify Request */
   2478 			eap_figure_next_state(esp, 1);
   2479 			break;
   2480 		}
   2481 
   2482 		switch (vallen) {
   2483 		case EAPT_SRP:
   2484 			/* Run through SRP validator selection again. */
   2485 			esp->es_server.ea_state = eapIdentify;
   2486 			eap_figure_next_state(esp, 0);
   2487 			break;
   2488 
   2489 		case EAPT_MD5CHAP:
   2490 			esp->es_server.ea_state = eapMD5Chall;
   2491 			break;
   2492 
   2493 #ifdef USE_EAPTLS
   2494 			/* Send EAP-TLS start packet */
   2495 		case EAPT_TLS:
   2496 			esp->es_server.ea_state = eapTlsStart;
   2497 			break;
   2498 #endif /* USE_EAPTLS */
   2499 
   2500 #ifdef CHAPMS
   2501 		case EAPT_MSCHAPV2:
   2502 			info("EAP: peer proposes MSCHAPv2");
   2503 			esp->es_server.ea_state = eapMSCHAPv2Chall;
   2504 			break;
   2505 #endif /* CHAPMS */
   2506 
   2507 		default:
   2508 			dbglog("EAP: peer requesting unknown Type %d", vallen);
   2509 			switch (esp->es_server.ea_state) {
   2510 			case eapSRP1:
   2511 			case eapSRP2:
   2512 			case eapSRP3:
   2513 				esp->es_server.ea_state = eapMD5Chall;
   2514 				break;
   2515 			case eapMD5Chall:
   2516 			case eapSRP4:
   2517 				esp->es_server.ea_state = eapIdentify;
   2518 				eap_figure_next_state(esp, 0);
   2519 				break;
   2520 			default:
   2521 				break;
   2522 			}
   2523 			break;
   2524 		}
   2525 		break;
   2526 
   2527 	case EAPT_MD5CHAP:
   2528 		if (esp->es_server.ea_state != eapMD5Chall) {
   2529 			error("EAP: unexpected MD5-Response");
   2530 			eap_figure_next_state(esp, 1);
   2531 			break;
   2532 		}
   2533 		if (len < 1) {
   2534 			error("EAP: received MD5-Response with no data");
   2535 			eap_figure_next_state(esp, 1);
   2536 			break;
   2537 		}
   2538 		GETCHAR(vallen, inp);
   2539 		len--;
   2540 		if (vallen != 16 || vallen > len) {
   2541 			error("EAP: MD5-Response with bad length %d", vallen);
   2542 			eap_figure_next_state(esp, 1);
   2543 			break;
   2544 		}
   2545 
   2546 		/* Not so likely to happen. */
   2547 		if (len - vallen >= sizeof (rhostname)) {
   2548 			dbglog("EAP: trimming really long peer name down");
   2549 			BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
   2550 			rhostname[sizeof (rhostname) - 1] = '\0';
   2551 		} else {
   2552 			BCOPY(inp + vallen, rhostname, len - vallen);
   2553 			rhostname[len - vallen] = '\0';
   2554 		}
   2555 
   2556 		/* In case the remote doesn't give us his name. */
   2557 		if (explicit_remote ||
   2558 		    (remote_name[0] != '\0' && vallen == len))
   2559 			strlcpy(rhostname, remote_name, sizeof (rhostname));
   2560 
   2561 		/*
   2562 		 * Get the secret for authenticating the specified
   2563 		 * host.
   2564 		 */
   2565 		if (!get_secret(esp->es_unit, rhostname,
   2566 		    esp->es_server.ea_name, secret, &secret_len, 1)) {
   2567 			dbglog("EAP: no MD5 secret for auth of %q", rhostname);
   2568 			eap_send_failure(esp);
   2569 			break;
   2570 		}
   2571 		MD5_Init(&mdContext);
   2572 		MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
   2573 		MD5_Update(&mdContext, (u_char *)secret, secret_len);
   2574 		BZERO(secret, sizeof (secret));
   2575 		MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
   2576 		MD5_Final(hash, &mdContext);
   2577 		if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
   2578 			eap_send_failure(esp);
   2579 			break;
   2580 		}
   2581 		esp->es_server.ea_type = EAPT_MD5CHAP;
   2582 		eap_send_success(esp);
   2583 		eap_figure_next_state(esp, 0);
   2584 		if (esp->es_rechallenge != 0)
   2585 			TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
   2586 		break;
   2587 
   2588 #ifdef CHAPMS
   2589 	case EAPT_MSCHAPV2:
   2590 		if (len < 1) {
   2591 			error("EAP: received MSCHAPv2 with no data");
   2592 			eap_figure_next_state(esp, 1);
   2593 			break;
   2594 		}
   2595 		GETCHAR(opcode, inp);
   2596 		len--;
   2597 
   2598 		switch (opcode) {
   2599 		case CHAP_RESPONSE:
   2600 			if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
   2601 				error("EAP: unexpected MSCHAPv2-Response");
   2602 				eap_figure_next_state(esp, 1);
   2603 				break;
   2604 			}
   2605 			/* skip MS ID + len */
   2606 			INCPTR(3, inp);
   2607 			GETCHAR(vallen, inp);
   2608 			len -= 4;
   2609 
   2610 			if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
   2611 				error("EAP: Invalid MSCHAPv2-Response "
   2612 						"length %d", vallen);
   2613 				eap_figure_next_state(esp, 1);
   2614 				break;
   2615 			}
   2616 
   2617 			/* Not so likely to happen. */
   2618 			if (len - vallen >= sizeof (rhostname)) {
   2619 				dbglog("EAP: trimming really long peer name down");
   2620 				BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
   2621 				rhostname[sizeof (rhostname) - 1] = '\0';
   2622 			} else {
   2623 				BCOPY(inp + vallen, rhostname, len - vallen);
   2624 				rhostname[len - vallen] = '\0';
   2625 			}
   2626 
   2627 			/* In case the remote doesn't give us his name. */
   2628 			if (explicit_remote ||
   2629 					(remote_name[0] != '\0' && vallen == len))
   2630 				strlcpy(rhostname, remote_name, sizeof (rhostname));
   2631 
   2632 			if (chap_verify_hook)
   2633 				chap_verifier = chap_verify_hook;
   2634 			else
   2635 				chap_verifier = eap_chap_verify_response;
   2636 
   2637 			esp->es_server.ea_id += 1;
   2638 			if ((*chap_verifier)(rhostname,
   2639 						esp->es_server.ea_name,
   2640 						id,
   2641 						&eap_chapms2_digest,
   2642 						esp->es_challenge,
   2643 						inp - 1,
   2644 						response_message,
   2645 						sizeof(response_message)))
   2646 			{
   2647 				info("EAP: MSCHAPv2 success for peer %q",
   2648 						rhostname);
   2649 				esp->es_server.ea_type = EAPT_MSCHAPV2;
   2650 				eap_chapms2_send_request(esp,
   2651 						esp->es_server.ea_id,
   2652 						CHAP_SUCCESS,
   2653 						esp->es_server.ea_id,
   2654 						response_message,
   2655 						strlen(response_message));
   2656 				eap_figure_next_state(esp, 0);
   2657 				if (esp->es_rechallenge != 0)
   2658 					TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
   2659 			}
   2660 			else {
   2661 				warn("EAP: MSCHAPv2 failure for peer %q",
   2662 						rhostname);
   2663 				eap_chapms2_send_request(esp,
   2664 						esp->es_server.ea_id,
   2665 						CHAP_FAILURE,
   2666 						esp->es_server.ea_id,
   2667 						response_message,
   2668 						strlen(response_message));
   2669 			}
   2670 			break;
   2671 		case CHAP_SUCCESS:
   2672 			info("EAP: MSCHAPv2 success confirmed");
   2673 			break;
   2674 		case CHAP_FAILURE:
   2675 			info("EAP: MSCHAPv2 failure confirmed");
   2676 			break;
   2677 		default:
   2678 			error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
   2679 			eap_send_nak(esp, id, EAPT_SRP);
   2680 		}
   2681 
   2682 		break;
   2683 #endif /* CHAPMS */
   2684 
   2685 #ifdef USE_SRP
   2686 	case EAPT_SRP:
   2687 		if (len < 1) {
   2688 			error("EAP: empty SRP Response");
   2689 			eap_figure_next_state(esp, 1);
   2690 			break;
   2691 		}
   2692 		GETCHAR(typenum, inp);
   2693 		len--;
   2694 		switch (typenum) {
   2695 		case EAPSRP_CKEY:
   2696 			if (esp->es_server.ea_state != eapSRP1) {
   2697 				error("EAP: unexpected SRP Subtype 1 Response");
   2698 				eap_figure_next_state(esp, 1);
   2699 				break;
   2700 			}
   2701 			A.data = inp;
   2702 			A.len = len;
   2703 			ts = (struct t_server *)esp->es_server.ea_session;
   2704 			assert(ts != NULL);
   2705 			esp->es_server.ea_skey = t_servergetkey(ts, &A);
   2706 			if (esp->es_server.ea_skey == NULL) {
   2707 				/* Client's A value is bogus; terminate now */
   2708 				error("EAP: bogus A value from client");
   2709 				eap_send_failure(esp);
   2710 			} else {
   2711 				eap_figure_next_state(esp, 0);
   2712 			}
   2713 			break;
   2714 
   2715 		case EAPSRP_CVALIDATOR:
   2716 			if (esp->es_server.ea_state != eapSRP2) {
   2717 				error("EAP: unexpected SRP Subtype 2 Response");
   2718 				eap_figure_next_state(esp, 1);
   2719 				break;
   2720 			}
   2721 			if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
   2722 				error("EAP: M1 length %d < %d", len,
   2723 				    sizeof (u_int32_t) + SHA_DIGESTSIZE);
   2724 				eap_figure_next_state(esp, 1);
   2725 				break;
   2726 			}
   2727 			GETLONG(esp->es_server.ea_keyflags, inp);
   2728 			ts = (struct t_server *)esp->es_server.ea_session;
   2729 			assert(ts != NULL);
   2730 			if (t_serververify(ts, inp)) {
   2731 				info("EAP: unable to validate client identity");
   2732 				eap_send_failure(esp);
   2733 				break;
   2734 			}
   2735 			eap_figure_next_state(esp, 0);
   2736 			break;
   2737 
   2738 		case EAPSRP_ACK:
   2739 			if (esp->es_server.ea_state != eapSRP3) {
   2740 				error("EAP: unexpected SRP Subtype 3 Response");
   2741 				eap_send_failure(esp);
   2742 				break;
   2743 			}
   2744 			esp->es_server.ea_type = EAPT_SRP;
   2745 			eap_send_success(esp);
   2746 			eap_figure_next_state(esp, 0);
   2747 			if (esp->es_rechallenge != 0)
   2748 				TIMEOUT(eap_rechallenge, esp,
   2749 				    esp->es_rechallenge);
   2750 			if (esp->es_lwrechallenge != 0)
   2751 				TIMEOUT(srp_lwrechallenge, esp,
   2752 				    esp->es_lwrechallenge);
   2753 			break;
   2754 
   2755 		case EAPSRP_LWRECHALLENGE:
   2756 			if (esp->es_server.ea_state != eapSRP4) {
   2757 				info("EAP: unexpected SRP Subtype 4 Response");
   2758 				return;
   2759 			}
   2760 			if (len != SHA_DIGESTSIZE) {
   2761 				error("EAP: bad Lightweight rechallenge "
   2762 				    "response");
   2763 				return;
   2764 			}
   2765 			SHA1Init(&ctxt);
   2766 			vallen = id;
   2767 			SHA1Update(&ctxt, &vallen, 1);
   2768 			SHA1Update(&ctxt, esp->es_server.ea_skey,
   2769 			    SESSION_KEY_LEN);
   2770 			SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
   2771 			SHA1Update(&ctxt, esp->es_server.ea_peer,
   2772 			    esp->es_server.ea_peerlen);
   2773 			SHA1Final(dig, &ctxt);
   2774 			if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
   2775 				error("EAP: failed Lightweight rechallenge");
   2776 				eap_send_failure(esp);
   2777 				break;
   2778 			}
   2779 			esp->es_server.ea_state = eapOpen;
   2780 			if (esp->es_lwrechallenge != 0)
   2781 				TIMEOUT(srp_lwrechallenge, esp,
   2782 				    esp->es_lwrechallenge);
   2783 			break;
   2784 		}
   2785 		break;
   2786 #endif /* USE_SRP */
   2787 
   2788 	default:
   2789 		/* This can't happen. */
   2790 		error("EAP: unknown Response type %d; ignored", typenum);
   2791 		return;
   2792 	}
   2793 
   2794 	if (esp->es_server.ea_timeout > 0) {
   2795 		UNTIMEOUT(eap_server_timeout, (void *)esp);
   2796 	}
   2797 
   2798 	if (esp->es_server.ea_state != eapBadAuth &&
   2799 	    esp->es_server.ea_state != eapOpen) {
   2800 		esp->es_server.ea_id++;
   2801 		eap_send_request(esp);
   2802 	}
   2803 }
   2804 
   2805 /*
   2806  * eap_success - Receive EAP Success message (client mode).
   2807  */
   2808 static void
   2809 eap_success(eap_state *esp, u_char *inp, int id, int len)
   2810 {
   2811 	if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
   2812 #ifdef USE_EAPTLS
   2813 		&& esp->es_client.ea_state != eapTlsRecvSuccess
   2814 #endif /* USE_EAPTLS */
   2815 		) {
   2816 		dbglog("EAP unexpected success message in state %s (%d)",
   2817 		    eap_state_name(esp->es_client.ea_state),
   2818 		    esp->es_client.ea_state);
   2819 		return;
   2820 	}
   2821 
   2822 #ifdef USE_EAPTLS
   2823 	if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
   2824 		eapTlsRecvSuccess) {
   2825 		dbglog("EAP-TLS unexpected success message in state %s (%d)",
   2826                     eap_state_name(esp->es_client.ea_state),
   2827                     esp->es_client.ea_state);
   2828 		return;
   2829 	}
   2830 #endif /* USE_EAPTLS */
   2831 
   2832 	if (esp->es_client.ea_timeout > 0) {
   2833 		UNTIMEOUT(eap_client_timeout, (void *)esp);
   2834 	}
   2835 
   2836 	if (len > 0) {
   2837 		/* This is odd.  The spec doesn't allow for this. */
   2838 		PRINTMSG(inp, len);
   2839 	}
   2840 
   2841 	esp->es_client.ea_state = eapOpen;
   2842 	auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
   2843 }
   2844 
   2845 /*
   2846  * eap_failure - Receive EAP Failure message (client mode).
   2847  */
   2848 static void
   2849 eap_failure(eap_state *esp, u_char *inp, int id, int len)
   2850 {
   2851 	/*
   2852 	 * Ignore failure messages if we're not open
   2853 	 */
   2854 	if (esp->es_client.ea_state <= eapClosed)
   2855 		return;
   2856 
   2857 	if (!eap_client_active(esp)) {
   2858 		dbglog("EAP unexpected failure message in state %s (%d)",
   2859 		    eap_state_name(esp->es_client.ea_state),
   2860 		    esp->es_client.ea_state);
   2861 	}
   2862 
   2863 	if (esp->es_client.ea_timeout > 0) {
   2864 		UNTIMEOUT(eap_client_timeout, (void *)esp);
   2865 	}
   2866 
   2867 	if (len > 0) {
   2868 		/* This is odd.  The spec doesn't allow for this. */
   2869 		PRINTMSG(inp, len);
   2870 	}
   2871 
   2872 	esp->es_client.ea_state = eapBadAuth;
   2873 
   2874 	error("EAP: peer reports authentication failure");
   2875 	auth_withpeer_fail(esp->es_unit, PPP_EAP);
   2876 }
   2877 
   2878 /*
   2879  * eap_input - Handle received EAP message.
   2880  */
   2881 static void
   2882 eap_input(int unit, u_char *inp, int inlen)
   2883 {
   2884 	eap_state *esp = &eap_states[unit];
   2885 	u_char code, id;
   2886 	int len;
   2887 
   2888 	/*
   2889 	 * Parse header (code, id and length).  If packet too short,
   2890 	 * drop it.
   2891 	 */
   2892 	if (inlen < EAP_HEADERLEN) {
   2893 		error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
   2894 		return;
   2895 	}
   2896 	GETCHAR(code, inp);
   2897 	GETCHAR(id, inp);
   2898 	GETSHORT(len, inp);
   2899 	if (len < EAP_HEADERLEN || len > inlen) {
   2900 		error("EAP: packet has illegal length field %d (%d..%d)", len,
   2901 		    EAP_HEADERLEN, inlen);
   2902 		return;
   2903 	}
   2904 	len -= EAP_HEADERLEN;
   2905 
   2906 	/* Dispatch based on message code */
   2907 	switch (code) {
   2908 	case EAP_REQUEST:
   2909 		eap_request(esp, inp, id, len);
   2910 		break;
   2911 
   2912 	case EAP_RESPONSE:
   2913 		eap_response(esp, inp, id, len);
   2914 		break;
   2915 
   2916 	case EAP_SUCCESS:
   2917 		eap_success(esp, inp, id, len);
   2918 		break;
   2919 
   2920 	case EAP_FAILURE:
   2921 		eap_failure(esp, inp, id, len);
   2922 		break;
   2923 
   2924 	default:				/* XXX Need code reject */
   2925 		/* Note: it's not legal to send EAP Nak here. */
   2926 		warn("EAP: unknown code %d received", code);
   2927 		break;
   2928 	}
   2929 }
   2930 
   2931 /*
   2932  * eap_printpkt - print the contents of an EAP packet.
   2933  */
   2934 static char *eap_codenames[] = {
   2935 	"Request", "Response", "Success", "Failure"
   2936 };
   2937 
   2938 static char *eap_typenames[] = {
   2939 	"Identity", "Notification", "Nak", "MD5-Challenge",
   2940 	"OTP", "Generic-Token", NULL, NULL,
   2941 	"RSA", "DSS", "KEA", "KEA-Validate",
   2942 	"TLS", "Defender", "Windows 2000", "Arcot",
   2943 	"Cisco", "Nokia", "SRP", NULL,
   2944 	"TTLS", "RAS", "AKA", "3COM", "PEAP",
   2945 	"MSCHAPv2"
   2946 };
   2947 
   2948 static int
   2949 eap_printpkt(u_char *inp, int inlen,
   2950 	     void (*printer) (void *, char *, ...), void *arg)
   2951 {
   2952 	int code, id, len, rtype, vallen;
   2953 	u_char *pstart;
   2954 	u_int32_t uval;
   2955 #ifdef USE_EAPTLS
   2956 	u_char flags;
   2957 #endif /* USE_EAPTLS */
   2958 #ifdef CHAPMS
   2959 	u_char opcode;
   2960 #endif /* CHAPMS */
   2961 
   2962 	if (inlen < EAP_HEADERLEN)
   2963 		return (0);
   2964 	pstart = inp;
   2965 	GETCHAR(code, inp);
   2966 	GETCHAR(id, inp);
   2967 	GETSHORT(len, inp);
   2968 	if (len < EAP_HEADERLEN || len > inlen)
   2969 		return (0);
   2970 
   2971 	if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
   2972 		printer(arg, " %s", eap_codenames[code-1]);
   2973 	else
   2974 		printer(arg, " code=0x%x", code);
   2975 	printer(arg, " id=0x%x", id);
   2976 	len -= EAP_HEADERLEN;
   2977 	switch (code) {
   2978 	case EAP_REQUEST:
   2979 		if (len < 1) {
   2980 			printer(arg, " <missing type>");
   2981 			break;
   2982 		}
   2983 		GETCHAR(rtype, inp);
   2984 		len--;
   2985 		if (rtype >= 1 &&
   2986 		    rtype <= sizeof (eap_typenames) / sizeof (char *))
   2987 			printer(arg, " %s", eap_typenames[rtype-1]);
   2988 		else
   2989 			printer(arg, " type=0x%x", rtype);
   2990 		switch (rtype) {
   2991 		case EAPT_IDENTITY:
   2992 		case EAPT_NOTIFICATION:
   2993 			if (len > 0) {
   2994 				printer(arg, " <Message ");
   2995 				print_string((char *)inp, len, printer, arg);
   2996 				printer(arg, ">");
   2997 				INCPTR(len, inp);
   2998 				len = 0;
   2999 			} else {
   3000 				printer(arg, " <No message>");
   3001 			}
   3002 			break;
   3003 
   3004 		case EAPT_MD5CHAP:
   3005 			if (len <= 0)
   3006 				break;
   3007 			GETCHAR(vallen, inp);
   3008 			len--;
   3009 			if (vallen > len)
   3010 				goto truncated;
   3011 			printer(arg, " <Value%.*B>", vallen, inp);
   3012 			INCPTR(vallen, inp);
   3013 			len -= vallen;
   3014 			if (len > 0) {
   3015 				printer(arg, " <Name ");
   3016 				print_string((char *)inp, len, printer, arg);
   3017 				printer(arg, ">");
   3018 				INCPTR(len, inp);
   3019 				len = 0;
   3020 			} else {
   3021 				printer(arg, " <No name>");
   3022 			}
   3023 			break;
   3024 
   3025 #ifdef CHAPMS
   3026 		case EAPT_MSCHAPV2:
   3027 			if (len <= 0)
   3028 				break;
   3029 			GETCHAR(opcode, inp);
   3030 			len--;
   3031 			switch (opcode) {
   3032 			case CHAP_CHALLENGE:
   3033 				INCPTR(3, inp);
   3034 				len -= 3;
   3035 				GETCHAR(vallen, inp);
   3036 				len--;
   3037 				if (vallen > len)
   3038 					goto truncated;
   3039 				len -= vallen;
   3040 				printer(arg, " Challenge <");
   3041 				for (; vallen > 0; --vallen) {
   3042 					u_char val;
   3043 					GETCHAR(val, inp);
   3044 					printer(arg, "%.2x", val);
   3045 				}
   3046 				printer(arg, ">");
   3047 				if (len > 0) {
   3048 					printer(arg, ", <Name ");
   3049 					print_string((char *)inp, len, printer, arg);
   3050 					printer(arg, ">");
   3051 					INCPTR(len, inp);
   3052 					len = 0;
   3053 				} else {
   3054 					printer(arg, ", <No name>");
   3055 				}
   3056 				break;
   3057 			case CHAP_SUCCESS:
   3058 				INCPTR(3, inp);
   3059 				len -= 3;
   3060 				printer(arg, " Success <Message ");
   3061 				print_string((char *)inp, len, printer, arg);
   3062 				printer(arg, ">");
   3063 				break;
   3064 			case CHAP_FAILURE:
   3065 				INCPTR(3, inp);
   3066 				len -= 3;
   3067 				printer(arg, " Failure <Message ");
   3068 				print_string((char *)inp, len, printer, arg);
   3069 				printer(arg, ">");
   3070 				break;
   3071 			default:
   3072 				INCPTR(3, inp);
   3073 				len -= 3;
   3074 				printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
   3075 				break;
   3076 			}
   3077 			break;
   3078 #endif /* CHAPMS */
   3079 
   3080 #ifdef USE_EAPTLS
   3081 		case EAPT_TLS:
   3082 			if (len < 1)
   3083 				break;
   3084 			GETCHAR(flags, inp);
   3085 			len--;
   3086 
   3087                         if(flags == 0 && len == 0){
   3088                                 printer(arg, " Ack");
   3089                                 break;
   3090                         }
   3091 
   3092 			printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
   3093 			printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
   3094 			printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
   3095 			break;
   3096 #endif /* USE_EAPTLS */
   3097 
   3098 		case EAPT_SRP:
   3099 			if (len < 3)
   3100 				goto truncated;
   3101 			GETCHAR(vallen, inp);
   3102 			len--;
   3103 			printer(arg, "-%d", vallen);
   3104 			switch (vallen) {
   3105 			case EAPSRP_CHALLENGE:
   3106 				GETCHAR(vallen, inp);
   3107 				len--;
   3108 				if (vallen >= len)
   3109 					goto truncated;
   3110 				if (vallen > 0) {
   3111 					printer(arg, " <Name ");
   3112 					print_string((char *)inp, vallen, printer,
   3113 					    arg);
   3114 					printer(arg, ">");
   3115 				} else {
   3116 					printer(arg, " <No name>");
   3117 				}
   3118 				INCPTR(vallen, inp);
   3119 				len -= vallen;
   3120 				GETCHAR(vallen, inp);
   3121 				len--;
   3122 				if (vallen >= len)
   3123 					goto truncated;
   3124 				printer(arg, " <s%.*B>", vallen, inp);
   3125 				INCPTR(vallen, inp);
   3126 				len -= vallen;
   3127 				GETCHAR(vallen, inp);
   3128 				len--;
   3129 				if (vallen > len)
   3130 					goto truncated;
   3131 				if (vallen == 0) {
   3132 					printer(arg, " <Default g=2>");
   3133 				} else {
   3134 					printer(arg, " <g%.*B>", vallen, inp);
   3135 				}
   3136 				INCPTR(vallen, inp);
   3137 				len -= vallen;
   3138 				if (len == 0) {
   3139 					printer(arg, " <Default N>");
   3140 				} else {
   3141 					printer(arg, " <N%.*B>", len, inp);
   3142 					INCPTR(len, inp);
   3143 					len = 0;
   3144 				}
   3145 				break;
   3146 
   3147 			case EAPSRP_SKEY:
   3148 				printer(arg, " <B%.*B>", len, inp);
   3149 				INCPTR(len, inp);
   3150 				len = 0;
   3151 				break;
   3152 
   3153 			case EAPSRP_SVALIDATOR:
   3154 				if (len < sizeof (u_int32_t))
   3155 					break;
   3156 				GETLONG(uval, inp);
   3157 				len -= sizeof (u_int32_t);
   3158 				if (uval & SRPVAL_EBIT) {
   3159 					printer(arg, " E");
   3160 					uval &= ~SRPVAL_EBIT;
   3161 				}
   3162 				if (uval != 0) {
   3163 					printer(arg, " f<%X>", uval);
   3164 				}
   3165 				if ((vallen = len) > SHA_DIGESTSIZE)
   3166 					vallen = SHA_DIGESTSIZE;
   3167 				printer(arg, " <M2%.*B%s>", len, inp,
   3168 				    len < SHA_DIGESTSIZE ? "?" : "");
   3169 				INCPTR(vallen, inp);
   3170 				len -= vallen;
   3171 				if (len > 0) {
   3172 					printer(arg, " <PN%.*B>", len, inp);
   3173 					INCPTR(len, inp);
   3174 					len = 0;
   3175 				}
   3176 				break;
   3177 
   3178 			case EAPSRP_LWRECHALLENGE:
   3179 				printer(arg, " <Challenge%.*B>", len, inp);
   3180 				INCPTR(len, inp);
   3181 				len = 0;
   3182 				break;
   3183 			}
   3184 			break;
   3185 		}
   3186 		break;
   3187 
   3188 	case EAP_RESPONSE:
   3189 		if (len < 1)
   3190 			break;
   3191 		GETCHAR(rtype, inp);
   3192 		len--;
   3193 		if (rtype >= 1 &&
   3194 		    rtype <= sizeof (eap_typenames) / sizeof (char *))
   3195 			printer(arg, " %s", eap_typenames[rtype-1]);
   3196 		else
   3197 			printer(arg, " type=0x%x", rtype);
   3198 		switch (rtype) {
   3199 		case EAPT_IDENTITY:
   3200 			if (len > 0) {
   3201 				printer(arg, " <Name ");
   3202 				print_string((char *)inp, len, printer, arg);
   3203 				printer(arg, ">");
   3204 				INCPTR(len, inp);
   3205 				len = 0;
   3206 			}
   3207 			break;
   3208 
   3209 #ifdef USE_EAPTLS
   3210 		case EAPT_TLS:
   3211 			if (len < 1)
   3212 				break;
   3213 			GETCHAR(flags, inp);
   3214 			len--;
   3215 
   3216                         if(flags == 0 && len == 0){
   3217                                 printer(arg, " Ack");
   3218                                 break;
   3219                         }
   3220 
   3221 			printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
   3222 			printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
   3223 			printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
   3224 
   3225 			break;
   3226 #endif /* USE_EAPTLS */
   3227 
   3228 		case EAPT_NAK:
   3229 			if (len <= 0) {
   3230 				printer(arg, " <missing hint>");
   3231 				break;
   3232 			}
   3233 			GETCHAR(rtype, inp);
   3234 			len--;
   3235 			printer(arg, " <Suggested-type %02X", rtype);
   3236 			if (rtype >= 1 &&
   3237 			    rtype <= sizeof (eap_typenames) / sizeof (char *))
   3238 				printer(arg, " (%s)", eap_typenames[rtype-1]);
   3239 			printer(arg, ">");
   3240 			break;
   3241 
   3242 		case EAPT_MD5CHAP:
   3243 			if (len <= 0) {
   3244 				printer(arg, " <missing length>");
   3245 				break;
   3246 			}
   3247 			GETCHAR(vallen, inp);
   3248 			len--;
   3249 			if (vallen > len)
   3250 				goto truncated;
   3251 			printer(arg, " <Value%.*B>", vallen, inp);
   3252 			INCPTR(vallen, inp);
   3253 			len -= vallen;
   3254 			if (len > 0) {
   3255 				printer(arg, " <Name ");
   3256 				print_string((char *)inp, len, printer, arg);
   3257 				printer(arg, ">");
   3258 				INCPTR(len, inp);
   3259 				len = 0;
   3260 			} else {
   3261 				printer(arg, " <No name>");
   3262 			}
   3263 			break;
   3264 
   3265 #ifdef CHAPMS
   3266 		case EAPT_MSCHAPV2:
   3267 			if (len <= 0)
   3268 				break;
   3269 			GETCHAR(opcode, inp);
   3270 			len--;
   3271 			switch (opcode) {
   3272 			case CHAP_RESPONSE:
   3273 				INCPTR(3, inp);
   3274 				len -= 3;
   3275 				GETCHAR(vallen, inp);
   3276 				len--;
   3277 				if (vallen > len)
   3278 					goto truncated;
   3279 				len -= vallen;
   3280 				printer(arg, " Response <");
   3281 				for (; vallen > 0; --vallen) {
   3282 					u_char val;
   3283 					GETCHAR(val, inp);
   3284 					printer(arg, "%.2x", val);
   3285 				}
   3286 				printer(arg, ">");
   3287 				if (len > 0) {
   3288 					printer(arg, ", <Name ");
   3289 					print_string((char *)inp, len, printer, arg);
   3290 					printer(arg, ">");
   3291 					INCPTR(len, inp);
   3292 					len = 0;
   3293 				} else {
   3294 					printer(arg, ", <No name>");
   3295 				}
   3296 				break;
   3297 			case CHAP_SUCCESS:
   3298 				printer(arg, " Success");
   3299 				break;
   3300 			case CHAP_FAILURE:
   3301 				printer(arg, " Failure");
   3302 				break;
   3303 			default:
   3304 				printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
   3305 				break;
   3306 			}
   3307 			break;
   3308 #endif /* CHAPMS */
   3309 
   3310 		case EAPT_SRP:
   3311 			if (len < 1)
   3312 				goto truncated;
   3313 			GETCHAR(vallen, inp);
   3314 			len--;
   3315 			printer(arg, "-%d", vallen);
   3316 			switch (vallen) {
   3317 			case EAPSRP_CKEY:
   3318 				printer(arg, " <A%.*B>", len, inp);
   3319 				INCPTR(len, inp);
   3320 				len = 0;
   3321 				break;
   3322 
   3323 			case EAPSRP_CVALIDATOR:
   3324 				if (len < sizeof (u_int32_t))
   3325 					break;
   3326 				GETLONG(uval, inp);
   3327 				len -= sizeof (u_int32_t);
   3328 				if (uval & SRPVAL_EBIT) {
   3329 					printer(arg, " E");
   3330 					uval &= ~SRPVAL_EBIT;
   3331 				}
   3332 				if (uval != 0) {
   3333 					printer(arg, " f<%X>", uval);
   3334 				}
   3335 				printer(arg, " <M1%.*B%s>", len, inp,
   3336 				    len == SHA_DIGESTSIZE ? "" : "?");
   3337 				INCPTR(len, inp);
   3338 				len = 0;
   3339 				break;
   3340 
   3341 			case EAPSRP_ACK:
   3342 				break;
   3343 
   3344 			case EAPSRP_LWRECHALLENGE:
   3345 				printer(arg, " <Response%.*B%s>", len, inp,
   3346 				    len == SHA_DIGESTSIZE ? "" : "?");
   3347 				if ((vallen = len) > SHA_DIGESTSIZE)
   3348 					vallen = SHA_DIGESTSIZE;
   3349 				INCPTR(vallen, inp);
   3350 				len -= vallen;
   3351 				break;
   3352 			}
   3353 			break;
   3354 		}
   3355 		break;
   3356 
   3357 	case EAP_SUCCESS:	/* No payload expected for these! */
   3358 	case EAP_FAILURE:
   3359 		break;
   3360 
   3361 	truncated:
   3362 		printer(arg, " <truncated>");
   3363 		break;
   3364 	}
   3365 
   3366 	if (len > 8)
   3367 		printer(arg, "%8B...", inp);
   3368 	else if (len > 0)
   3369 		printer(arg, "%.*B", len, inp);
   3370 	INCPTR(len, inp);
   3371 
   3372 	return (inp - pstart);
   3373 }
   3374