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