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