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