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