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