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