]> git.ozlabs.org Git - ppp.git/blob - pppd/eap.c
pppd man page: Update header to refer to pppd 2.5.x
[ppp.git] / pppd / eap.c
1 /*
2  * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
3  *
4  * Copyright (c) 2001 by Sun Microsystems, Inc.
5  * All rights reserved.
6  *
7  * Non-exclusive rights to redistribute, modify, translate, and use
8  * this software in source and binary forms, in whole or in part, is
9  * hereby granted, provided that the above copyright notice is
10  * duplicated in any source form, and that neither the name of the
11  * copyright holder nor the author is used to endorse or promote
12  * products derived from this software.
13  *
14  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  *
18  * Original version by James Carlson
19  *
20  * This implementation of EAP supports MD5-Challenge and SRP-SHA1
21  * authentication styles.  Note that support of MD5-Challenge is a
22  * requirement of RFC 2284, and that it's essentially just a
23  * reimplementation of regular RFC 1994 CHAP using EAP messages.
24  *
25  * As an authenticator ("server"), there are multiple phases for each
26  * style.  In the first phase of each style, the unauthenticated peer
27  * name is queried using the EAP Identity request type.  If the
28  * "remotename" option is used, then this phase is skipped, because
29  * the peer's name is presumed to be known.
30  *
31  * For MD5-Challenge, there are two phases, and the second phase
32  * consists of sending the challenge itself and handling the
33  * associated response.
34  *
35  * For SRP-SHA1, there are four phases.  The second sends 's', 'N',
36  * and 'g'.  The reply contains 'A'.  The third sends 'B', and the
37  * reply contains 'M1'.  The forth sends the 'M2' value.
38  *
39  * As an authenticatee ("client"), there's just a single phase --
40  * responding to the queries generated by the peer.  EAP is an
41  * authenticator-driven protocol.
42  *
43  * Based on draft-ietf-pppext-eap-srp-03.txt.
44  */
45
46 /*
47  * Modification by Beniamino Galvani, Mar 2005
48  * Implemented EAP-TLS authentication
49  */
50
51 #ifdef HAVE_CONFIG_H
52 #include "config.h"
53 #endif
54
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <unistd.h>
59 #include <pwd.h>
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 #include <fcntl.h>
63 #include <assert.h>
64 #include <errno.h>
65
66 #include "pppd.h"
67 #include "pathnames.h"
68 #include "ppp-crypto.h"
69 #include "pppcrypt.h"
70 #include "eap.h"
71 #ifdef PPP_WITH_PEAP
72 #include "peap.h"
73 #endif /* PPP_WITH_PEAP */
74
75 #ifdef PPP_WITH_SRP
76 #ifdef HAVE_TIME_H
77 #include <time.h>
78 #endif
79 #include <t_pwd.h>
80 #include <t_server.h>
81 #include <t_client.h>
82 #endif /* PPP_WITH_SRP */
83
84 #ifdef PPP_WITH_EAPTLS
85 #include "eap-tls.h"
86 #endif /* PPP_WITH_EAPTLS */
87
88 #ifdef PPP_WITH_CHAPMS
89 #include "chap_ms.h"
90 #include "chap-new.h"
91
92 extern int chapms_strip_domain;
93 #endif /* PPP_WITH_CHAPMS */
94
95 eap_state eap_states[NUM_PPP];          /* EAP state; one for each unit */
96 #ifdef PPP_WITH_SRP
97 static char *pn_secret = NULL;          /* Pseudonym generating secret */
98 #endif
99
100 /*
101  * Command-line options.
102  */
103 static option_t eap_option_list[] = {
104     { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
105       "Set retransmit timeout for EAP Requests (server)" },
106     { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
107       "Set max number of EAP Requests sent (server)" },
108     { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
109       "Set time limit for peer EAP authentication" },
110     { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
111       "Set max number of EAP Requests allows (client)" },
112     { "eap-interval", o_int, &eap_states[0].es_rechallenge,
113       "Set interval for EAP rechallenge" },
114 #ifdef PPP_WITH_SRP
115     { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
116       "Set interval for SRP lightweight rechallenge" },
117     { "srp-pn-secret", o_string, &pn_secret,
118       "Long term pseudonym generation secret" },
119     { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
120       "Use pseudonym if offered one by server", 1 },
121 #endif
122     { NULL }
123 };
124
125 /*
126  * Protocol entry points.
127  */
128 static void eap_init (int unit);
129 static void eap_input (int unit, u_char *inp, int inlen);
130 static void eap_protrej (int unit);
131 static void eap_lowerup (int unit);
132 static void eap_lowerdown (int unit);
133 static int  eap_printpkt (u_char *inp, int inlen,
134     void (*)(void *arg, char *fmt, ...), void *arg);
135
136 struct protent eap_protent = {
137         PPP_EAP,                /* protocol number */
138         eap_init,               /* initialization procedure */
139         eap_input,              /* process a received packet */
140         eap_protrej,            /* process a received protocol-reject */
141         eap_lowerup,            /* lower layer has gone up */
142         eap_lowerdown,          /* lower layer has gone down */
143         NULL,                   /* open the protocol */
144         NULL,                   /* close the protocol */
145         eap_printpkt,           /* print a packet in readable form */
146         NULL,                   /* process a received data packet */
147         1,                      /* protocol enabled */
148         "EAP",                  /* text name of protocol */
149         NULL,                   /* text name of corresponding data protocol */
150         eap_option_list,        /* list of command-line options */
151         NULL,                   /* check requested options; assign defaults */
152         NULL,                   /* configure interface for demand-dial */
153         NULL                    /* say whether to bring up link for this pkt */
154 };
155
156 #ifdef PPP_WITH_SRP
157 /*
158  * A well-known 2048 bit modulus.
159  */
160 static const u_char wkmodulus[] = {
161         0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
162         0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
163         0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
164         0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
165         0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
166         0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
167         0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
168         0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
169         0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
170         0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
171         0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
172         0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
173         0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
174         0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
175         0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
176         0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
177         0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
178         0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
179         0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
180         0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
181         0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
182         0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
183         0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
184         0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
185         0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
186         0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
187         0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
188         0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
189         0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
190         0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
191         0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
192         0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
193 };
194 #endif /* PPP_WITH_SRP */
195
196 /* Local forward declarations. */
197 static void eap_server_timeout (void *arg);
198
199 /*
200  * Convert EAP state code to printable string for debug.
201  */
202 static const char *
203 eap_state_name(enum eap_state_code esc)
204 {
205         static const char *state_names[] = { EAP_STATES };
206
207         return (state_names[(int)esc]);
208 }
209
210 /*
211  * eap_init - Initialize state for an EAP user.  This is currently
212  * called once by main() during start-up.
213  */
214 static void
215 eap_init(int unit)
216 {
217         eap_state *esp = &eap_states[unit];
218
219         BZERO(esp, sizeof (*esp));
220         esp->es_unit = unit;
221         esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
222         esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
223         esp->es_server.ea_id = (u_char)(drand48() * 0x100);
224         esp->es_client.ea_timeout = EAP_DEFREQTIME;
225         esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
226 #ifdef PPP_WITH_EAPTLS
227         esp->es_client.ea_using_eaptls = 0;
228 #endif /* PPP_WITH_EAPTLS */
229 #ifdef PPP_WITH_CHAPMS
230         esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
231         esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
232 #endif
233 }
234
235 /*
236  * eap_client_timeout - Give up waiting for the peer to send any
237  * Request messages.
238  */
239 static void
240 eap_client_timeout(void *arg)
241 {
242         eap_state *esp = (eap_state *) arg;
243
244         if (!eap_client_active(esp))
245                 return;
246
247         error("EAP: timeout waiting for Request from peer");
248         auth_withpeer_fail(esp->es_unit, PPP_EAP);
249         esp->es_client.ea_state = eapBadAuth;
250 }
251
252 /*
253  * eap_authwithpeer - Authenticate to our peer (behave as client).
254  *
255  * Start client state and wait for requests.  This is called only
256  * after eap_lowerup.
257  */
258 void
259 eap_authwithpeer(int unit, char *localname)
260 {
261         eap_state *esp = &eap_states[unit];
262
263         /* Save the peer name we're given */
264         esp->es_client.ea_name = localname;
265         esp->es_client.ea_namelen = strlen(localname);
266
267         esp->es_client.ea_state = eapListen;
268
269         /*
270          * Start a timer so that if the other end just goes
271          * silent, we don't sit here waiting forever.
272          */
273         if (esp->es_client.ea_timeout > 0)
274                 TIMEOUT(eap_client_timeout, (void *)esp,
275                     esp->es_client.ea_timeout);
276 }
277
278 /*
279  * Format a standard EAP Failure message and send it to the peer.
280  * (Server operation)
281  */
282 static void
283 eap_send_failure(eap_state *esp)
284 {
285         u_char *outp;
286
287         outp = outpacket_buf;
288     
289         MAKEHEADER(outp, PPP_EAP);
290
291         PUTCHAR(EAP_FAILURE, outp);
292         esp->es_server.ea_id++;
293         PUTCHAR(esp->es_server.ea_id, outp);
294         PUTSHORT(EAP_HEADERLEN, outp);
295
296         output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
297
298         esp->es_server.ea_state = eapBadAuth;
299         auth_peer_fail(esp->es_unit, PPP_EAP);
300 }
301
302 /*
303  * Format a standard EAP Success message and send it to the peer.
304  * (Server operation)
305  */
306 static void
307 eap_send_success(eap_state *esp)
308 {
309         u_char *outp;
310
311         outp = outpacket_buf;
312     
313         MAKEHEADER(outp, PPP_EAP);
314
315         PUTCHAR(EAP_SUCCESS, outp);
316         esp->es_server.ea_id++;
317         PUTCHAR(esp->es_server.ea_id, outp);
318         PUTSHORT(EAP_HEADERLEN, outp);
319
320         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
321
322         auth_peer_success(esp->es_unit, PPP_EAP, 0,
323             esp->es_server.ea_peer, esp->es_server.ea_peerlen);
324 }
325
326 #ifdef PPP_WITH_SRP
327 /*
328  * Set DES key according to pseudonym-generating secret and current
329  * date.
330  */
331 static bool
332 pncrypt_getkey(int timeoffs, unsigned char *key, int keylen)
333 {
334         struct tm *tp;
335         char tbuf[9];
336         PPP_MD_CTX *ctxt;
337         time_t reftime;
338
339         if (pn_secret == NULL)
340                 return (0);
341         reftime = time(NULL) + timeoffs;
342         tp = localtime(&reftime);
343
344         ctxt = PPP_MD_CTX_new();
345         if (ctxt) {
346
347             strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
348
349             PPP_DigestInit(ctxt, PPP_sha1());
350             PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
351             PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
352             PPP_DigestFinal(ctxt, key, &keylen);
353
354             PPP_MD_CTX_free(ctxt);
355             return 1;
356         }
357
358         return (0);
359 }
360
361 static char base64[] =
362 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
363
364 struct b64state {
365         u_int32_t bs_bits;
366         int bs_offs;
367 };
368
369 static int
370 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
371 {
372         int outlen = 0;
373
374         while (inlen > 0) {
375                 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
376                 inlen--;
377                 bs->bs_offs += 8;
378                 if (bs->bs_offs >= 24) {
379                         *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
380                         *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
381                         *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
382                         *outp++ = base64[bs->bs_bits & 0x3F];
383                         outlen += 4;
384                         bs->bs_offs = 0;
385                         bs->bs_bits = 0;
386                 }
387         }
388         return (outlen);
389 }
390
391 static int
392 b64flush(struct b64state *bs, u_char *outp)
393 {
394         int outlen = 0;
395
396         if (bs->bs_offs == 8) {
397                 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
398                 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
399                 outlen = 2;
400         } else if (bs->bs_offs == 16) {
401                 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
402                 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
403                 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
404                 outlen = 3;
405         }
406         bs->bs_offs = 0;
407         bs->bs_bits = 0;
408         return (outlen);
409 }
410
411 static int
412 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
413 {
414         int outlen = 0;
415         char *cp;
416
417         while (inlen > 0) {
418                 if ((cp = strchr(base64, *inp++)) == NULL)
419                         break;
420                 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
421                 inlen--;
422                 bs->bs_offs += 6;
423                 if (bs->bs_offs >= 8) {
424                         *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
425                         outlen++;
426                         bs->bs_offs -= 8;
427                 }
428         }
429         return (outlen);
430 }
431 #endif /* PPP_WITH_SRP */
432
433 /*
434  * Assume that current waiting server state is complete and figure
435  * next state to use based on available authentication data.  'status'
436  * indicates if there was an error in handling the last query.  It is
437  * 0 for success and non-zero for failure.
438  */
439 static void
440 eap_figure_next_state(eap_state *esp, int status)
441 {
442 #ifdef PPP_WITH_SRP
443         unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp, key[SHA_DIGEST_LENGTH];
444         struct t_pw tpw;
445         struct t_confent *tce, mytce;
446         char *cp, *cp2;
447         struct t_server *ts;
448         int id, i, plen, clen, toffs, keylen;
449         u_char vals[2];
450         struct b64state bs;
451 #endif /* PPP_WITH_SRP */
452 #ifdef PPP_WITH_EAPTLS
453         struct eaptls_session *ets;
454         int secret_len;
455         char secret[MAXWORDLEN];
456 #endif /* PPP_WITH_EAPTLS */
457
458         esp->es_server.ea_timeout = esp->es_savedtime;
459 #ifdef PPP_WITH_EAPTLS
460         esp->es_server.ea_prev_state = esp->es_server.ea_state;
461 #endif /* PPP_WITH_EAPTLS */
462         switch (esp->es_server.ea_state) {
463         case eapBadAuth:
464                 return;
465
466         case eapIdentify:
467 #ifdef PPP_WITH_SRP
468                 /* Discard any previous session. */
469                 ts = (struct t_server *)esp->es_server.ea_session;
470                 if (ts != NULL) {
471                         t_serverclose(ts);
472                         esp->es_server.ea_session = NULL;
473                         esp->es_server.ea_skey = NULL;
474                 }
475 #endif /* PPP_WITH_SRP */
476                 if (status != 0) {
477                         esp->es_server.ea_state = eapBadAuth;
478                         break;
479                 }
480 #ifdef PPP_WITH_SRP
481                 /* If we've got a pseudonym, try to decode to real name. */
482                 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
483                     strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
484                         SRP_PSEUDO_LEN) == 0 &&
485                     (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
486                     sizeof (secbuf)) {
487                         BZERO(&bs, sizeof (bs));
488                         plen = b64dec(&bs,
489                             esp->es_server.ea_peer + SRP_PSEUDO_LEN,
490                             esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
491                             secbuf);
492                         toffs = 0;
493                         for (i = 0; i < 5; i++) {
494                                 pncrypt_getkey(toffs, key, keylen);
495                                 toffs -= 86400;
496
497                                 if (!DesDecrypt(secbuf, key, clear)) {
498                                         dbglog("no DES here; cannot decode "
499                                                 "pseudonym");
500                                         return;
501                                 }
502                                 id = *(unsigned char *)clear;
503                                 if (id + 1 <= plen && id + 9 > plen)
504                                         break;
505                         }
506                         if (plen % 8 == 0 && i < 5) {
507                                 /*
508                                  * Note that this is always shorter than the
509                                  * original stored string, so there's no need
510                                  * to realloc.
511                                  */
512                                 if ((i = plen = *(unsigned char *)clear) > 7)
513                                         i = 7;
514                                 esp->es_server.ea_peerlen = plen;
515                                 dp = (unsigned char *)esp->es_server.ea_peer;
516                                 BCOPY(clear + 1, dp, i);
517                                 plen -= i;
518                                 dp += i;
519                                 sp = secbuf + 8;
520                                 while (plen > 0) {
521                                         DesDecrypt(sp, key, dp);
522                                         sp += 8;
523                                         dp += 8;
524                                         plen -= 8;
525                                 }
526                                 esp->es_server.ea_peer[
527                                         esp->es_server.ea_peerlen] = '\0';
528                                 dbglog("decoded pseudonym to \"%.*q\"",
529                                     esp->es_server.ea_peerlen,
530                                     esp->es_server.ea_peer);
531                         } else {
532                                 dbglog("failed to decode real name");
533                                 /* Stay in eapIdentfy state; requery */
534                                 break;
535                         }
536                 }
537                 /* Look up user in secrets database. */
538                 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
539                     esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
540                         /* Set up default in case SRP entry is bad */
541                         esp->es_server.ea_state = eapMD5Chall;
542                         /* Get t_confent based on index in srp-secrets */
543                         id = strtol((char *)secbuf, &cp, 10);
544                         if (*cp++ != ':' || id < 0)
545                                 break;
546                         if (id == 0) {
547                                 mytce.index = 0;
548                                 mytce.modulus.data = (u_char *)wkmodulus;
549                                 mytce.modulus.len = sizeof (wkmodulus);
550                                 mytce.generator.data = (u_char *)"\002";
551                                 mytce.generator.len = 1;
552                                 tce = &mytce;
553                         } else if ((tce = gettcid(id)) != NULL) {
554                                 /*
555                                  * Client will have to verify this modulus/
556                                  * generator combination, and that will take
557                                  * a while.  Lengthen the timeout here.
558                                  */
559                                 if (esp->es_server.ea_timeout > 0 &&
560                                     esp->es_server.ea_timeout < 30)
561                                         esp->es_server.ea_timeout = 30;
562                         } else {
563                                 break;
564                         }
565                         if ((cp2 = strchr(cp, ':')) == NULL)
566                                 break;
567                         *cp2++ = '\0';
568                         tpw.pebuf.name = esp->es_server.ea_peer;
569                         tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
570                             cp);
571                         tpw.pebuf.password.data = (char*) tpw.pwbuf;
572                         tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
573                             cp2);
574                         tpw.pebuf.salt.data = tpw.saltbuf;
575                         if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
576                                 break;
577                         esp->es_server.ea_session = (void *)ts;
578                         esp->es_server.ea_state = eapSRP1;
579                         vals[0] = esp->es_server.ea_id + 1;
580                         vals[1] = EAPT_SRP;
581                         t_serveraddexdata(ts, vals, 2);
582                         /* Generate B; must call before t_servergetkey() */
583                         t_servergenexp(ts);
584                         break;
585                 }
586 #endif /* PPP_WITH_SRP */
587 #ifdef PPP_WITH_EAPTLS
588                 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
589                     esp->es_server.ea_name, secret, &secret_len, 1)) {
590
591                         esp->es_server.ea_state = eapTlsStart;
592                         break;
593                 }
594 #endif /* PPP_WITH_EAPTLS */
595
596                 esp->es_server.ea_state = eapMD5Chall;
597                 break;
598
599 #ifdef PPP_WITH_EAPTLS
600         case eapTlsStart:
601                 /* Initialize ssl session */
602                 if(!eaptls_init_ssl_server(esp)) {
603                         esp->es_server.ea_state = eapBadAuth;
604                         break;
605                 }
606
607                 esp->es_server.ea_state = eapTlsRecv;
608                 break;
609
610         case eapTlsRecv:
611                 ets = (struct eaptls_session *) esp->es_server.ea_session;
612
613                 if(ets->alert_sent) {
614                         esp->es_server.ea_state = eapTlsSendAlert;
615                         break;
616                 }
617
618                 if (status) {
619                         esp->es_server.ea_state = eapBadAuth;
620                         break;
621                 }
622                 ets = (struct eaptls_session *) esp->es_server.ea_session;
623
624                 if(ets->frag)
625                         esp->es_server.ea_state = eapTlsSendAck;
626                 else
627                         esp->es_server.ea_state = eapTlsSend;
628                 break;
629
630         case eapTlsSend:
631                 ets = (struct eaptls_session *) esp->es_server.ea_session;
632
633                 if(ets->frag)
634                         esp->es_server.ea_state = eapTlsRecvAck;
635                 else
636                         if(SSL_is_init_finished(ets->ssl))
637                                 esp->es_server.ea_state = eapTlsRecvClient;
638                         else
639                                 /* JJK Add "TLS empty record" message here ??? */
640                                 esp->es_server.ea_state = eapTlsRecv;
641                 break;
642
643         case eapTlsSendAck:
644                 esp->es_server.ea_state = eapTlsRecv;
645                 break;
646
647         case eapTlsRecvAck:
648                 if (status)
649                 {
650                         esp->es_server.ea_state = eapBadAuth;
651                         break;
652                 }
653
654                 esp->es_server.ea_state = eapTlsSend;
655                 break;
656
657         case eapTlsSendAlert:
658                 esp->es_server.ea_state = eapTlsRecvAlertAck;
659                 break;
660 #endif /* PPP_WITH_EAPTLS */
661
662         case eapSRP1:
663 #ifdef PPP_WITH_SRP
664                 ts = (struct t_server *)esp->es_server.ea_session;
665                 if (ts != NULL && status != 0) {
666                         t_serverclose(ts);
667                         esp->es_server.ea_session = NULL;
668                         esp->es_server.ea_skey = NULL;
669                 }
670 #endif /* PPP_WITH_SRP */
671                 if (status == 1) {
672                         esp->es_server.ea_state = eapMD5Chall;
673                 } else if (status != 0 || esp->es_server.ea_session == NULL) {
674                         esp->es_server.ea_state = eapBadAuth;
675                 } else {
676                         esp->es_server.ea_state = eapSRP2;
677                 }
678                 break;
679
680         case eapSRP2:
681 #ifdef PPP_WITH_SRP
682                 ts = (struct t_server *)esp->es_server.ea_session;
683                 if (ts != NULL && status != 0) {
684                         t_serverclose(ts);
685                         esp->es_server.ea_session = NULL;
686                         esp->es_server.ea_skey = NULL;
687                 }
688 #endif /* PPP_WITH_SRP */
689                 if (status != 0 || esp->es_server.ea_session == NULL) {
690                         esp->es_server.ea_state = eapBadAuth;
691                 } else {
692                         esp->es_server.ea_state = eapSRP3;
693                 }
694                 break;
695
696         case eapSRP3:
697         case eapSRP4:
698 #ifdef PPP_WITH_SRP
699                 ts = (struct t_server *)esp->es_server.ea_session;
700                 if (ts != NULL && status != 0) {
701                         t_serverclose(ts);
702                         esp->es_server.ea_session = NULL;
703                         esp->es_server.ea_skey = NULL;
704                 }
705 #endif /* PPP_WITH_SRP */
706                 if (status != 0 || esp->es_server.ea_session == NULL) {
707                         esp->es_server.ea_state = eapBadAuth;
708                 } else {
709                         esp->es_server.ea_state = eapOpen;
710                 }
711                 break;
712
713 #ifdef PPP_WITH_CHAPMS
714         case eapMSCHAPv2Chall:
715 #endif
716         case eapMD5Chall:
717                 if (status != 0) {
718                         esp->es_server.ea_state = eapBadAuth;
719                 } else {
720                         esp->es_server.ea_state = eapOpen;
721                 }
722                 break;
723
724         default:
725                 esp->es_server.ea_state = eapBadAuth;
726                 break;
727         }
728         if (esp->es_server.ea_state == eapBadAuth)
729                 eap_send_failure(esp);
730
731 #ifdef PPP_WITH_EAPTLS
732         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));
733 #endif /* PPP_WITH_EAPTLS */
734 }
735
736 #if PPP_WITH_CHAPMS
737 /*
738  * eap_chap_verify_response - check whether the peer's response matches
739  * what we think it should be.  Returns 1 if it does (authentication
740  * succeeded), or 0 if it doesn't.
741  */
742 static int
743 eap_chap_verify_response(char *name, char *ourname, int id,
744                          struct chap_digest_type *digest,
745                          unsigned char *challenge, unsigned char *response,
746                          char *message, int message_space)
747 {
748         int ok;
749         unsigned char secret[MAXSECRETLEN];
750         int secret_len;
751
752         /* Get the secret that the peer is supposed to know */
753         if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
754                 error("No CHAP secret found for authenticating %q", name);
755                 return 0;
756         }
757
758         ok = digest->verify_response(id, name, secret, secret_len, challenge,
759                                      response, message, message_space);
760         memset(secret, 0, sizeof(secret));
761
762         return ok;
763 }
764
765 /*
766  * Format and send an CHAPV2-Success/Failure EAP Request message.
767  */
768 static void
769 eap_chapms2_send_request(eap_state *esp, u_char id,
770                          u_char opcode, u_char chapid,
771                          char *message, int message_len)
772 {
773         u_char *outp;
774         int msglen;
775
776         outp = outpacket_buf;
777
778         MAKEHEADER(outp, PPP_EAP);
779
780         msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
781         msglen += message_len;
782
783         PUTCHAR(EAP_REQUEST, outp);
784         PUTCHAR(id, outp);
785         PUTSHORT(msglen, outp);
786         PUTCHAR(EAPT_MSCHAPV2, outp);
787         PUTCHAR(opcode, outp);
788         PUTCHAR(chapid, outp);
789         /* MS len */
790         PUTSHORT(msglen - 5, outp);
791         BCOPY(message, outp, message_len);
792
793         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
794
795         if (opcode == CHAP_SUCCESS) {
796                 auth_peer_success(esp->es_unit, PPP_EAP, 0,
797                                 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
798         }
799         else {
800                 esp->es_server.ea_state = eapBadAuth;
801                 auth_peer_fail(esp->es_unit, PPP_EAP);
802         }
803 }
804 #endif /* PPP_WITH_CHAPMS */
805
806 /*
807  * Format an EAP Request message and send it to the peer.  Message
808  * type depends on current state.  (Server operation)
809  */
810 static void
811 eap_send_request(eap_state *esp)
812 {
813         u_char *outp;
814         u_char *lenloc;
815         u_char *ptr;
816         int outlen;
817         int challen;
818         char *str;
819 #ifdef PPP_WITH_SRP
820         struct t_server *ts;
821         u_char clear[8], cipher[8], dig[SHA_DIGEST_LENGTH], *optr, *cp, key[SHA_DIGEST_LENGTH];
822         int i, j, diglen, clen, keylen = sizeof(key);
823         struct b64state b64;
824         PPP_MD_CTX *ctxt;
825 #endif /* PPP_WITH_SRP */
826
827         /* Handle both initial auth and restart */
828         if (esp->es_server.ea_state < eapIdentify &&
829             esp->es_server.ea_state != eapInitial) {
830                 esp->es_server.ea_state = eapIdentify;
831                 if (explicit_remote) {
832                         /*
833                          * If we already know the peer's
834                          * unauthenticated name, then there's no
835                          * reason to ask.  Go to next state instead.
836                          */
837                         esp->es_server.ea_peer = remote_name;
838                         esp->es_server.ea_peerlen = strlen(remote_name);
839                         eap_figure_next_state(esp, 0);
840                 }
841         }
842
843         if (esp->es_server.ea_maxrequests > 0 &&
844             esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
845                 if (esp->es_server.ea_responses > 0)
846                         error("EAP: too many Requests sent");
847                 else
848                         error("EAP: no response to Requests");
849                 eap_send_failure(esp);
850                 return;
851         }
852
853         outp = outpacket_buf;
854     
855         MAKEHEADER(outp, PPP_EAP);
856
857         PUTCHAR(EAP_REQUEST, outp);
858         PUTCHAR(esp->es_server.ea_id, outp);
859         lenloc = outp;
860         INCPTR(2, outp);
861
862         switch (esp->es_server.ea_state) {
863         case eapIdentify:
864                 PUTCHAR(EAPT_IDENTITY, outp);
865                 str = "Name";
866                 challen = strlen(str);
867                 BCOPY(str, outp, challen);
868                 INCPTR(challen, outp);
869                 break;
870
871         case eapMD5Chall:
872                 PUTCHAR(EAPT_MD5CHAP, outp);
873                 /*
874                  * pick a random challenge length between
875                  * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
876                  */
877                 challen = (drand48() *
878                     (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
879                             MIN_CHALLENGE_LENGTH;
880                 PUTCHAR(challen, outp);
881                 esp->es_challen = challen;
882                 ptr = esp->es_challenge;
883                 while (--challen >= 0)
884                         *ptr++ = (u_char) (drand48() * 0x100);
885                 BCOPY(esp->es_challenge, outp, esp->es_challen);
886                 INCPTR(esp->es_challen, outp);
887                 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
888                 INCPTR(esp->es_server.ea_namelen, outp);
889                 break;
890
891 #ifdef PPP_WITH_CHAPMS
892         case eapMSCHAPv2Chall:
893                 esp->es_server.digest->generate_challenge(esp->es_challenge);
894                 challen = esp->es_challenge[0];
895                 esp->es_challen = challen;
896
897                 PUTCHAR(EAPT_MSCHAPV2, outp);
898                 PUTCHAR(CHAP_CHALLENGE, outp);
899                 PUTCHAR(esp->es_server.ea_id, outp);
900                 /* MS len */
901                 PUTSHORT(5 + challen +
902                                 esp->es_server.ea_namelen,
903                                 outp);
904                 /* challen + challenge */
905                 BCOPY(esp->es_challenge, outp, challen+1);
906                 INCPTR(challen+1, outp);
907                 BCOPY(esp->es_server.ea_name,
908                                 outp,
909                                 esp->es_server.ea_namelen);
910                 INCPTR(esp->es_server.ea_namelen, outp);
911                 break;
912 #endif /* PPP_WITH_CHAPMS */
913
914 #ifdef PPP_WITH_EAPTLS
915         case eapTlsStart:
916                 PUTCHAR(EAPT_TLS, outp);
917                 PUTCHAR(EAP_TLS_FLAGS_START, outp);
918                 eap_figure_next_state(esp, 0);
919                 break;
920
921         case eapTlsSend:
922                 eaptls_send(esp->es_server.ea_session, &outp);
923                 eap_figure_next_state(esp, 0);
924                 break;
925
926         case eapTlsSendAck:
927                 PUTCHAR(EAPT_TLS, outp);
928                 PUTCHAR(0, outp);
929                 eap_figure_next_state(esp, 0);
930                 break;
931
932         case eapTlsSendAlert:
933                 eaptls_send(esp->es_server.ea_session, &outp);
934                 eap_figure_next_state(esp, 0);
935                 break;
936 #endif /* PPP_WITH_EAPTLS */
937
938 #ifdef PPP_WITH_SRP
939         case eapSRP1:
940                 PUTCHAR(EAPT_SRP, outp);
941                 PUTCHAR(EAPSRP_CHALLENGE, outp);
942
943                 PUTCHAR(esp->es_server.ea_namelen, outp);
944                 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
945                 INCPTR(esp->es_server.ea_namelen, outp);
946
947                 ts = (struct t_server *)esp->es_server.ea_session;
948                 assert(ts != NULL);
949                 PUTCHAR(ts->s.len, outp);
950                 BCOPY(ts->s.data, outp, ts->s.len);
951                 INCPTR(ts->s.len, outp);
952
953                 if (ts->g.len == 1 && ts->g.data[0] == 2) {
954                         PUTCHAR(0, outp);
955                 } else {
956                         PUTCHAR(ts->g.len, outp);
957                         BCOPY(ts->g.data, outp, ts->g.len);
958                         INCPTR(ts->g.len, outp);
959                 }
960
961                 if (ts->n.len != sizeof (wkmodulus) ||
962                     BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
963                         BCOPY(ts->n.data, outp, ts->n.len);
964                         INCPTR(ts->n.len, outp);
965                 }
966                 break;
967
968         case eapSRP2:
969                 PUTCHAR(EAPT_SRP, outp);
970                 PUTCHAR(EAPSRP_SKEY, outp);
971
972                 ts = (struct t_server *)esp->es_server.ea_session;
973                 assert(ts != NULL);
974                 BCOPY(ts->B.data, outp, ts->B.len);
975                 INCPTR(ts->B.len, outp);
976                 break;
977
978         case eapSRP3:
979                 PUTCHAR(EAPT_SRP, outp);
980                 PUTCHAR(EAPSRP_SVALIDATOR, outp);
981                 PUTLONG(SRPVAL_EBIT, outp);
982                 ts = (struct t_server *)esp->es_server.ea_session;
983                 assert(ts != NULL);
984                 BCOPY(t_serverresponse(ts), outp, SHA_DIGEST_LENGTH);
985                 INCPTR(SHA_DIGEST_LENGTH, outp);
986
987                 if (pncrypt_getkey(0, key, keylen)) {
988                         /* Generate pseudonym */
989                         optr = outp;
990                         cp = (unsigned char *)esp->es_server.ea_peer;
991                         if ((j = i = esp->es_server.ea_peerlen) > 7)
992                                 j = 7;
993                         clear[0] = i;
994                         BCOPY(cp, clear + 1, j);
995                         i -= j;
996                         cp += j;
997
998                         if (!DesEncrypt(clear, key, cipher)) {
999                                 dbglog("no DES here; not generating pseudonym");
1000                                 break;
1001             }
1002
1003                         BZERO(&b64, sizeof (b64));
1004                         outp++;         /* space for pseudonym length */
1005                         outp += b64enc(&b64, cipher, 8, outp);
1006                         while (i >= 8) {
1007                                 DesEncrypt(cp, key, cipher);
1008                                 outp += b64enc(&b64, cipher, 8, outp);
1009                                 cp += 8;
1010                                 i -= 8;
1011                         }
1012                         if (i > 0) {
1013                                 BCOPY(cp, clear, i);
1014                                 cp += i;
1015                                 while (i < 8) {
1016                                         *cp++ = drand48() * 0x100;
1017                                         i++;
1018                                 }
1019
1020                                 DesEncrypt(clear, key, cipher);
1021                                 outp += b64enc(&b64, cipher, 8, outp);
1022                         }
1023                         outp += b64flush(&b64, outp);
1024
1025                         /* Set length and pad out to next 20 octet boundary */
1026                         i = outp - optr - 1;
1027                         *optr = i;
1028                         i %= SHA_DIGEST_LENGTH;
1029                         if (i != 0) {
1030                                 while (i < SHA_DIGEST_LENGTH) {
1031                                         *outp++ = drand48() * 0x100;
1032                                         i++;
1033                                 }
1034                         }
1035
1036                         /* Obscure the pseudonym with SHA1 hash */
1037                         ctxt = PPP_MD_CTX_new();
1038                         if (ctxt) {
1039
1040                                 PPP_DigestInit(ctxt, PPP_sha1());
1041                                 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1042                                 PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey,
1043                                         SESSION_KEY_LEN);
1044                                 PPP_DigestUpdate(ctxt,  esp->es_server.ea_peer,
1045                                         esp->es_server.ea_peerlen);
1046                                 while (optr < outp) {
1047                                         diglen = SHA_DIGEST_LENGTH;
1048                                         PPP_DigestFinal(ctxt, dig, &diglen);
1049                                         cp = dig;
1050                                         while (cp < dig + SHA_DIGEST_LENGTH)
1051                                                 *optr++ ^= *cp++;
1052
1053                                         PPP_DigestInit(ctxt, PPP_sha1());
1054                                         PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1055                                         PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
1056                                                 SESSION_KEY_LEN);
1057                                         PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH,
1058                                                 SHA_DIGEST_LENGTH);
1059                                 }
1060
1061                                 PPP_MD_CTX_free(ctxt);
1062                         }
1063                 }
1064                 break;
1065
1066         case eapSRP4:
1067                 PUTCHAR(EAPT_SRP, outp);
1068                 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1069                 challen = MIN_CHALLENGE_LENGTH +
1070                     ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1071                 esp->es_challen = challen;
1072                 ptr = esp->es_challenge;
1073                 while (--challen >= 0)
1074                         *ptr++ = drand48() * 0x100;
1075                 BCOPY(esp->es_challenge, outp, esp->es_challen);
1076                 INCPTR(esp->es_challen, outp);
1077                 break;
1078 #endif /* PPP_WITH_SRP */
1079
1080         default:
1081                 return;
1082         }
1083
1084         outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1085         PUTSHORT(outlen, lenloc);
1086
1087         output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1088
1089         esp->es_server.ea_requests++;
1090
1091         if (esp->es_server.ea_timeout > 0)
1092                 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1093 }
1094
1095 /*
1096  * eap_authpeer - Authenticate our peer (behave as server).
1097  *
1098  * Start server state and send first request.  This is called only
1099  * after eap_lowerup.
1100  */
1101 void
1102 eap_authpeer(int unit, char *localname)
1103 {
1104         eap_state *esp = &eap_states[unit];
1105
1106         /* Save the name we're given. */
1107         esp->es_server.ea_name = localname;
1108         esp->es_server.ea_namelen = strlen(localname);
1109
1110         esp->es_savedtime = esp->es_server.ea_timeout;
1111
1112         /* Lower layer up yet? */
1113         if (esp->es_server.ea_state == eapInitial ||
1114             esp->es_server.ea_state == eapPending) {
1115                 esp->es_server.ea_state = eapPending;
1116                 return;
1117         }
1118
1119         esp->es_server.ea_state = eapPending;
1120
1121         /* ID number not updated here intentionally; hashed into M1 */
1122         eap_send_request(esp);
1123 }
1124
1125 /*
1126  * eap_server_timeout - Retransmission timer for sending Requests
1127  * expired.
1128  */
1129 static void
1130 eap_server_timeout(void *arg)
1131 {
1132 #ifdef PPP_WITH_EAPTLS
1133         u_char *outp;
1134         u_char *lenloc;
1135         int outlen;
1136 #endif /* PPP_WITH_EAPTLS */
1137
1138         eap_state *esp = (eap_state *) arg;
1139
1140         if (!eap_server_active(esp))
1141                 return;
1142
1143 #ifdef PPP_WITH_EAPTLS
1144         switch(esp->es_server.ea_prev_state) {
1145
1146         /*
1147          *  In eap-tls the state changes after a request, so we return to
1148          *  previous state ...
1149          */
1150         case(eapTlsStart):
1151         case(eapTlsSendAck):
1152                 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1153                 break;
1154
1155         /*
1156          *  ... or resend the stored data
1157          */
1158         case(eapTlsSend):
1159         case(eapTlsSendAlert):
1160                 outp = outpacket_buf;
1161                 MAKEHEADER(outp, PPP_EAP);
1162                 PUTCHAR(EAP_REQUEST, outp);
1163                 PUTCHAR(esp->es_server.ea_id, outp);
1164                 lenloc = outp;
1165                 INCPTR(2, outp);
1166
1167                 eaptls_retransmit(esp->es_server.ea_session, &outp);
1168
1169                 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1170                 PUTSHORT(outlen, lenloc);
1171                 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1172                 esp->es_server.ea_requests++;
1173
1174                 if (esp->es_server.ea_timeout > 0)
1175                         TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1176
1177                 return;
1178         default:
1179                 break;
1180         }
1181 #endif /* PPP_WITH_EAPTLS */
1182
1183         /* EAP ID number must not change on timeout. */
1184         eap_send_request(esp);
1185 }
1186
1187 /*
1188  * When it's time to send rechallenge the peer, this timeout is
1189  * called.  Once the rechallenge is successful, the response handler
1190  * will restart the timer.  If it fails, then the link is dropped.
1191  */
1192 static void
1193 eap_rechallenge(void *arg)
1194 {
1195         eap_state *esp = (eap_state *)arg;
1196
1197         if (esp->es_server.ea_state != eapOpen &&
1198             esp->es_server.ea_state != eapSRP4)
1199                 return;
1200
1201         esp->es_server.ea_requests = 0;
1202         esp->es_server.ea_state = eapIdentify;
1203         eap_figure_next_state(esp, 0);
1204         esp->es_server.ea_id++;
1205         eap_send_request(esp);
1206 }
1207
1208 static void
1209 srp_lwrechallenge(void *arg)
1210 {
1211         eap_state *esp = (eap_state *)arg;
1212
1213         if (esp->es_server.ea_state != eapOpen ||
1214             esp->es_server.ea_type != EAPT_SRP)
1215                 return;
1216
1217         esp->es_server.ea_requests = 0;
1218         esp->es_server.ea_state = eapSRP4;
1219         esp->es_server.ea_id++;
1220         eap_send_request(esp);
1221 }
1222
1223 /*
1224  * eap_lowerup - The lower layer is now up.
1225  *
1226  * This is called before either eap_authpeer or eap_authwithpeer.  See
1227  * link_established() in auth.c.  All that's necessary here is to
1228  * return to closed state so that those two routines will do the right
1229  * thing.
1230  */
1231 static void
1232 eap_lowerup(int unit)
1233 {
1234         eap_state *esp = &eap_states[unit];
1235
1236         /* Discard any (possibly authenticated) peer name. */
1237         if (esp->es_server.ea_peer != NULL &&
1238             esp->es_server.ea_peer != remote_name)
1239                 free(esp->es_server.ea_peer);
1240         esp->es_server.ea_peer = NULL;
1241         if (esp->es_client.ea_peer != NULL)
1242                 free(esp->es_client.ea_peer);
1243         esp->es_client.ea_peer = NULL;
1244
1245         esp->es_client.ea_state = eapClosed;
1246         esp->es_server.ea_state = eapClosed;
1247 }
1248
1249 /*
1250  * eap_lowerdown - The lower layer is now down.
1251  *
1252  * Cancel all timeouts and return to initial state.
1253  */
1254 static void
1255 eap_lowerdown(int unit)
1256 {
1257         eap_state *esp = &eap_states[unit];
1258
1259         if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1260                 UNTIMEOUT(eap_client_timeout, (void *)esp);
1261         }
1262         if (eap_server_active(esp)) {
1263                 if (esp->es_server.ea_timeout > 0) {
1264                         UNTIMEOUT(eap_server_timeout, (void *)esp);
1265                 }
1266         } else {
1267                 if ((esp->es_server.ea_state == eapOpen ||
1268                     esp->es_server.ea_state == eapSRP4) &&
1269                     esp->es_rechallenge > 0) {
1270                         UNTIMEOUT(eap_rechallenge, (void *)esp);
1271                 }
1272                 if (esp->es_server.ea_state == eapOpen &&
1273                     esp->es_lwrechallenge > 0) {
1274                         UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1275                 }
1276         }
1277
1278         esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1279         esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1280 }
1281
1282 /*
1283  * eap_protrej - Peer doesn't speak this protocol.
1284  *
1285  * This shouldn't happen.  If it does, it represents authentication
1286  * failure.
1287  */
1288 static void
1289 eap_protrej(int unit)
1290 {
1291         eap_state *esp = &eap_states[unit];
1292
1293         if (eap_client_active(esp)) {
1294                 error("EAP authentication failed due to Protocol-Reject");
1295                 auth_withpeer_fail(unit, PPP_EAP);
1296         }
1297         if (eap_server_active(esp)) {
1298                 error("EAP authentication of peer failed on Protocol-Reject");
1299                 auth_peer_fail(unit, PPP_EAP);
1300         }
1301         eap_lowerdown(unit);
1302 }
1303
1304 /*
1305  * Format and send a regular EAP Response message.
1306  */
1307 static void
1308 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1309                   u_char *str, int lenstr)
1310 {
1311         u_char *outp;
1312         int msglen;
1313
1314         outp = outpacket_buf;
1315
1316         MAKEHEADER(outp, PPP_EAP);
1317
1318         PUTCHAR(EAP_RESPONSE, outp);
1319         PUTCHAR(id, outp);
1320         esp->es_client.ea_id = id;
1321         msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1322         PUTSHORT(msglen, outp);
1323         PUTCHAR(typenum, outp);
1324         if (lenstr > 0) {
1325                 BCOPY(str, outp, lenstr);
1326         }
1327
1328         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1329 }
1330
1331 /*
1332  * Format and send an MD5-Challenge EAP Response message.
1333  */
1334 static void
1335 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1336                   char *name, int namelen)
1337 {
1338         u_char *outp;
1339         int msglen;
1340
1341         outp = outpacket_buf;
1342
1343         MAKEHEADER(outp, PPP_EAP);
1344
1345         PUTCHAR(EAP_RESPONSE, outp);
1346         PUTCHAR(id, outp);
1347         esp->es_client.ea_id = id;
1348         msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_DIGEST_LENGTH +
1349             namelen;
1350         PUTSHORT(msglen, outp);
1351         PUTCHAR(EAPT_MD5CHAP, outp);
1352         PUTCHAR(MD5_DIGEST_LENGTH, outp);
1353         BCOPY(hash, outp, MD5_DIGEST_LENGTH);
1354         INCPTR(MD5_DIGEST_LENGTH, outp);
1355         if (namelen > 0) {
1356                 BCOPY(name, outp, namelen);
1357         }
1358
1359         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1360 }
1361
1362 #ifdef PPP_WITH_SRP
1363 /*
1364  * Format and send a SRP EAP Response message.
1365  */
1366 static void
1367 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1368                  u_char *str, int lenstr)
1369 {
1370         u_char *outp;
1371         int msglen;
1372
1373         outp = outpacket_buf;
1374     
1375         MAKEHEADER(outp, PPP_EAP);
1376
1377         PUTCHAR(EAP_RESPONSE, outp);
1378         PUTCHAR(id, outp);
1379         esp->es_client.ea_id = id;
1380         msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1381         PUTSHORT(msglen, outp);
1382         PUTCHAR(EAPT_SRP, outp);
1383         PUTCHAR(subtypenum, outp);
1384         if (lenstr > 0) {
1385                 BCOPY(str, outp, lenstr);
1386         }
1387
1388         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1389 }
1390
1391 /*
1392  * Format and send a SRP EAP Client Validator Response message.
1393  */
1394 static void
1395 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1396 {
1397         u_char *outp;
1398         int msglen;
1399
1400         outp = outpacket_buf;
1401     
1402         MAKEHEADER(outp, PPP_EAP);
1403
1404         PUTCHAR(EAP_RESPONSE, outp);
1405         PUTCHAR(id, outp);
1406         esp->es_client.ea_id = id;
1407         msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1408             SHA_DIGEST_LENGTH;
1409         PUTSHORT(msglen, outp);
1410         PUTCHAR(EAPT_SRP, outp);
1411         PUTCHAR(EAPSRP_CVALIDATOR, outp);
1412         PUTLONG(flags, outp);
1413         BCOPY(str, outp, SHA_DIGEST_LENGTH);
1414
1415         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1416 }
1417 #endif /* PPP_WITH_SRP */
1418
1419 #ifdef PPP_WITH_EAPTLS
1420 /*
1421  * Send an EAP-TLS response message with tls data
1422  */
1423 static void
1424 eap_tls_response(eap_state *esp, u_char id)
1425 {
1426         u_char *outp;
1427         int outlen;
1428         u_char *lenloc;
1429
1430         outp = outpacket_buf;
1431
1432         MAKEHEADER(outp, PPP_EAP);
1433
1434         PUTCHAR(EAP_RESPONSE, outp);
1435         PUTCHAR(id, outp);
1436
1437         lenloc = outp;
1438         INCPTR(2, outp);
1439
1440         /*
1441            If the id in the request is unchanged, we must retransmit
1442            the old data
1443         */
1444         if(id == esp->es_client.ea_id)
1445                 eaptls_retransmit(esp->es_client.ea_session, &outp);
1446         else
1447                 eaptls_send(esp->es_client.ea_session, &outp);
1448
1449         outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1450         PUTSHORT(outlen, lenloc);
1451
1452         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1453
1454         esp->es_client.ea_id = id;
1455 }
1456
1457 /*
1458  * Send an EAP-TLS ack
1459  */
1460 static void
1461 eap_tls_sendack(eap_state *esp, u_char id)
1462 {
1463         u_char *outp;
1464         int outlen;
1465         u_char *lenloc;
1466
1467         outp = outpacket_buf;
1468
1469         MAKEHEADER(outp, PPP_EAP);
1470
1471         PUTCHAR(EAP_RESPONSE, outp);
1472         PUTCHAR(id, outp);
1473         esp->es_client.ea_id = id;
1474
1475         lenloc = outp;
1476         INCPTR(2, outp);
1477
1478         PUTCHAR(EAPT_TLS, outp);
1479         PUTCHAR(0, outp);
1480
1481         outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1482         PUTSHORT(outlen, lenloc);
1483
1484         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1485 }
1486 #endif /* PPP_WITH_EAPTLS */
1487
1488 static void
1489 eap_send_nak(eap_state *esp, u_char id, u_char type)
1490 {
1491         u_char *outp;
1492         int msglen;
1493
1494         outp = outpacket_buf;
1495
1496         MAKEHEADER(outp, PPP_EAP);
1497
1498         PUTCHAR(EAP_RESPONSE, outp);
1499         PUTCHAR(id, outp);
1500         esp->es_client.ea_id = id;
1501         msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1502         PUTSHORT(msglen, outp);
1503         PUTCHAR(EAPT_NAK, outp);
1504         PUTCHAR(type, outp);
1505
1506         output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1507 }
1508
1509 #ifdef PPP_WITH_SRP
1510 static char *
1511 name_of_pn_file(void)
1512 {
1513         char *user, *path, *file;
1514         struct passwd *pw;
1515         size_t pl;
1516         static bool pnlogged = 0;
1517
1518         pw = getpwuid(getuid());
1519         if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1520                 errno = EINVAL;
1521                 return (NULL);
1522         }
1523         file = PPP_PATH_PSEUDONYM;
1524         pl = strlen(user) + strlen(file) + 2;
1525         path = malloc(pl);
1526         if (path == NULL)
1527                 return (NULL);
1528         (void) slprintf(path, pl, "%s/%s", user, file);
1529         if (!pnlogged) {
1530                 dbglog("pseudonym file: %s", path);
1531                 pnlogged = 1;
1532         }
1533         return (path);
1534 }
1535
1536 static int
1537 open_pn_file(mode_t modebits)
1538 {
1539         char *path;
1540         int fd, err;
1541
1542         if ((path = name_of_pn_file()) == NULL)
1543                 return (-1);
1544         fd = open(path, modebits, S_IRUSR | S_IWUSR);
1545         err = errno;
1546         free(path);
1547         errno = err;
1548         return (fd);
1549 }
1550
1551 static void
1552 remove_pn_file(void)
1553 {
1554         char *path;
1555
1556         if ((path = name_of_pn_file()) != NULL) {
1557                 (void) unlink(path);
1558                 (void) free(path);
1559         }
1560 }
1561
1562 static void
1563 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1564 {
1565         u_char val;
1566         u_char *datp, *digp;
1567         PPP_MD_CTX *ctxt;
1568         u_char dig[SHA_DIGEST_LENGTH];
1569         int dsize, fd, olen = len, diglen = sizeof(dig);
1570
1571         /*
1572          * Do the decoding by working backwards.  This eliminates the need
1573          * to save the decoded output in a separate buffer.
1574          */
1575         val = id;
1576         while (len > 0) {
1577                 if ((dsize = len % SHA_DIGEST_LENGTH) == 0)
1578                         dsize = SHA_DIGEST_LENGTH;
1579                 len -= dsize;
1580                 datp = inp + len;
1581                 ctxt = PPP_MD_CTX_new();
1582                 if (ctxt) {
1583
1584                         PPP_DigestInit(ctxt, PPP_sha1());
1585                         PPP_DigestUpdate(ctxt, &val, 1);
1586                         PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
1587                                         SESSION_KEY_LEN);
1588                         if (len > 0) {
1589                                 PPP_DigestUpdate(ctxt, datp, SHA_DIGEST_LENGTH);
1590                         } else {
1591                                 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
1592                                         esp->es_client.ea_namelen);
1593                         }
1594                         PPP_DigestFinal(ctxt, dig, &diglen);
1595
1596                         for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
1597                                 *datp++ ^= *digp;
1598
1599                         PPP_MD_CTX_free(ctxt);
1600                 }
1601         }
1602
1603         /* Now check that the result is sane */
1604         if (olen <= 0 || *inp + 1 > olen) {
1605                 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1606                 return;
1607         }
1608
1609         /* Save it away */
1610         fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1611         if (fd < 0) {
1612                 dbglog("EAP: error saving pseudonym: %m");
1613                 return;
1614         }
1615         len = write(fd, inp + 1, *inp);
1616         if (close(fd) != -1 && len == *inp) {
1617                 dbglog("EAP: saved pseudonym");
1618                 esp->es_usedpseudo = 0;
1619         } else {
1620                 dbglog("EAP: failed to save pseudonym");
1621                 remove_pn_file();
1622         }
1623 }
1624 #endif /* PPP_WITH_SRP */
1625
1626 #if PPP_WITH_CHAPMS
1627 /*
1628  * Format and send an CHAPV2-Challenge EAP Response message.
1629  */
1630 static void
1631 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1632 {
1633     u_char *outp;
1634     int msglen;
1635
1636     outp = outpacket_buf;
1637
1638     MAKEHEADER(outp, PPP_EAP);
1639
1640     PUTCHAR(EAP_RESPONSE, outp);
1641     PUTCHAR(id, outp);
1642     esp->es_client.ea_id = id;
1643     msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1644     PUTSHORT(msglen, outp);
1645     PUTCHAR(EAPT_MSCHAPV2, outp);
1646     PUTCHAR(CHAP_RESPONSE, outp);
1647     PUTCHAR(chapid, outp);
1648     PUTCHAR(0, outp);
1649     /* len */
1650     PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1651     BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1652     INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1653     BCOPY(user, outp, user_len);
1654
1655     output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1656 }
1657 #endif
1658
1659 /*
1660  * eap_request - Receive EAP Request message (client mode).
1661  */
1662 static void
1663 eap_request(eap_state *esp, u_char *inp, int id, int len)
1664 {
1665         u_char typenum;
1666         u_char vallen;
1667         int secret_len;
1668         char secret[MAXWORDLEN];
1669         char rhostname[256];
1670         PPP_MD_CTX *mdctx;
1671         u_char hash[MD5_DIGEST_LENGTH];
1672         int hashlen = MD5_DIGEST_LENGTH;
1673 #ifdef PPP_WITH_EAPTLS
1674         u_char flags;
1675         struct eaptls_session *ets = esp->es_client.ea_session;
1676 #endif /* PPP_WITH_EAPTLS */
1677
1678 #ifdef PPP_WITH_SRP
1679         struct t_client *tc;
1680         struct t_num sval, gval, Nval, *Ap, Bval;
1681         u_char vals[2];
1682         PPP_MD_CTX *ctxt;
1683         u_char dig[SHA_DIGEST_LENGTH];
1684         int diglen = sizeof(dig);
1685         int fd;
1686 #endif /* PPP_WITH_SRP */
1687
1688         /*
1689          * Ignore requests if we're not open
1690          */
1691         if (esp->es_client.ea_state <= eapClosed)
1692                 return;
1693
1694         /*
1695          * Note: we update es_client.ea_id *only if* a Response
1696          * message is being generated.  Otherwise, we leave it the
1697          * same for duplicate detection purposes.
1698          */
1699
1700         esp->es_client.ea_requests++;
1701         if (esp->es_client.ea_maxrequests != 0 &&
1702             esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1703                 info("EAP: received too many Request messages");
1704                 if (esp->es_client.ea_timeout > 0) {
1705                         UNTIMEOUT(eap_client_timeout, (void *)esp);
1706                 }
1707                 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1708                 return;
1709         }
1710
1711         if (len <= 0) {
1712                 error("EAP: empty Request message discarded");
1713                 return;
1714         }
1715
1716         GETCHAR(typenum, inp);
1717         len--;
1718
1719         switch (typenum) {
1720         case EAPT_IDENTITY:
1721                 if (len > 0)
1722                         info("EAP: Identity prompt \"%.*q\"", len, inp);
1723 #ifdef PPP_WITH_SRP
1724                 if (esp->es_usepseudo &&
1725                     (esp->es_usedpseudo == 0 ||
1726                         (esp->es_usedpseudo == 1 &&
1727                             id == esp->es_client.ea_id))) {
1728                         esp->es_usedpseudo = 1;
1729                         /* Try to get a pseudonym */
1730                         if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1731                                 strcpy(rhostname, SRP_PSEUDO_ID);
1732                                 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1733                                     sizeof (rhostname) - SRP_PSEUDO_LEN);
1734                                 /* XXX NAI unsupported */
1735                                 if (len > 0) {
1736                                         eap_send_response(esp, id, typenum,
1737                                             rhostname, len + SRP_PSEUDO_LEN);
1738                                 }
1739                                 (void) close(fd);
1740                                 if (len > 0)
1741                                         break;
1742                         }
1743                 }
1744                 /* Stop using pseudonym now. */
1745                 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1746                         remove_pn_file();
1747                         esp->es_usedpseudo = 2;
1748                 }
1749 #endif /* PPP_WITH_SRP */
1750                 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1751                     esp->es_client.ea_namelen);
1752                 break;
1753
1754         case EAPT_NOTIFICATION:
1755                 if (len > 0)
1756                         info("EAP: Notification \"%.*q\"", len, inp);
1757                 eap_send_response(esp, id, typenum, NULL, 0);
1758                 break;
1759
1760         case EAPT_NAK:
1761                 /*
1762                  * Avoid the temptation to send Response Nak in reply
1763                  * to Request Nak here.  It can only lead to trouble.
1764                  */
1765                 warn("EAP: unexpected Nak in Request; ignored");
1766                 /* Return because we're waiting for something real. */
1767                 return;
1768
1769         case EAPT_MD5CHAP:
1770                 if (len < 1) {
1771                         error("EAP: received MD5-Challenge with no data");
1772                         /* Bogus request; wait for something real. */
1773                         return;
1774                 }
1775                 GETCHAR(vallen, inp);
1776                 len--;
1777                 if (vallen < 8 || vallen > len) {
1778                         error("EAP: MD5-Challenge with bad length %d (8..%d)",
1779                             vallen, len);
1780                         /* Try something better. */
1781                         eap_send_nak(esp, id, EAPT_SRP);
1782                         break;
1783                 }
1784
1785                 /* Not so likely to happen. */
1786                 if (len - vallen >= sizeof (rhostname)) {
1787                         dbglog("EAP: trimming really long peer name down");
1788                         BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1789                         rhostname[sizeof (rhostname) - 1] = '\0';
1790                 } else {
1791                         BCOPY(inp + vallen, rhostname, len - vallen);
1792                         rhostname[len - vallen] = '\0';
1793                 }
1794
1795                 /* In case the remote doesn't give us his name. */
1796                 if (explicit_remote ||
1797                     (remote_name[0] != '\0' && vallen == len))
1798                         strlcpy(rhostname, remote_name, sizeof (rhostname));
1799
1800                 /*
1801                  * Get the secret for authenticating ourselves with
1802                  * the specified host.
1803                  */
1804                 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1805                     rhostname, secret, &secret_len, 0)) {
1806                         dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1807                         eap_send_nak(esp, id, EAPT_SRP);
1808                         break;
1809                 }
1810
1811                 mdctx = PPP_MD_CTX_new();
1812                 if (mdctx != NULL) {
1813                         if (PPP_DigestInit(mdctx, PPP_md5())) {
1814                                 typenum = id;
1815                                 if (PPP_DigestUpdate(mdctx, &typenum, 1)) {
1816                                         if (PPP_DigestUpdate(mdctx, secret, secret_len)) {
1817                                                 BZERO(secret, sizeof(secret));
1818                                                 if (PPP_DigestUpdate(mdctx, inp, vallen)) {
1819                                                         if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
1820                                                                 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1821                                                                                 esp->es_client.ea_namelen);
1822                                                                 PPP_MD_CTX_free(mdctx);
1823                                                                 break;
1824                                                         }
1825                                                 }
1826                                         }
1827                                 }
1828                         }
1829                         PPP_MD_CTX_free(mdctx);
1830                 }
1831                 dbglog("EAP: Invalid MD5 checksum");
1832         eap_send_nak(esp, id, EAPT_SRP);
1833                 break;
1834
1835 #ifdef PPP_WITH_EAPTLS
1836         case EAPT_TLS:
1837
1838                 switch(esp->es_client.ea_state) {
1839
1840                 case eapListen:
1841
1842                         if (len < 1) {
1843                                 error("EAP: received EAP-TLS Listen packet with no data");
1844                                 /* Bogus request; wait for something real. */
1845                                 return;
1846                         }
1847                         GETCHAR(flags, inp);
1848                         if(flags & EAP_TLS_FLAGS_START){
1849
1850                                 esp->es_client.ea_using_eaptls = 1;
1851
1852                                 if (explicit_remote){
1853                                         esp->es_client.ea_peer = strdup(remote_name);
1854                                         esp->es_client.ea_peerlen = strlen(remote_name);
1855                                 } else
1856                                         esp->es_client.ea_peer = NULL;
1857
1858                                 /* Init ssl session */
1859                                 if(!eaptls_init_ssl_client(esp)) {
1860                                         dbglog("cannot init ssl");
1861                                         eap_send_nak(esp, id, EAPT_MSCHAPV2);
1862                                         esp->es_client.ea_using_eaptls = 0;
1863                                         break;
1864                                 }
1865
1866                                 ets = esp->es_client.ea_session;
1867                                 eap_tls_response(esp, id);
1868                                 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1869                                 break;
1870                         }
1871
1872                         /* The server has sent a bad start packet. */
1873                         eap_send_nak(esp, id, EAPT_MSCHAPV2);
1874                         break;
1875
1876                 case eapTlsRecvAck:
1877                         eap_tls_response(esp, id);
1878                         esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1879                         break;
1880
1881                 case eapTlsRecv:
1882                         if (len < 1) {
1883                                 error("EAP: discarding EAP-TLS Receive packet with no data");
1884                                 /* Bogus request; wait for something real. */
1885                                 return;
1886                         }
1887                         eaptls_receive(ets, inp, len);
1888
1889                         if(ets->frag) {
1890                                 eap_tls_sendack(esp, id);
1891                                 esp->es_client.ea_state = eapTlsRecv;
1892                                 break;
1893                         }
1894
1895                         if(ets->alert_recv) {
1896                                 eap_tls_sendack(esp, id);
1897                                 esp->es_client.ea_state = eapTlsRecvFailure;
1898                                 break;
1899                         }
1900
1901                         /* Check if TLS handshake is finished */
1902                         if(eaptls_is_init_finished(ets)) {
1903 #ifdef PPP_WITH_MPPE
1904                                 eaptls_gen_mppe_keys(ets, 1);
1905 #endif
1906                                 eaptls_free_session(ets);
1907                                 eap_tls_sendack(esp, id);
1908                                 esp->es_client.ea_state = eapTlsRecvSuccess;
1909                                 break;
1910                         }
1911
1912                         eap_tls_response(esp,id);
1913                         esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1914                         break;
1915
1916                 default:
1917                         eap_send_nak(esp, id, EAPT_MSCHAPV2);
1918                         esp->es_client.ea_using_eaptls = 0;
1919                         break;
1920                 }
1921
1922                 break;
1923 #endif /* PPP_WITH_EAPTLS */
1924
1925 #ifdef PPP_WITH_SRP
1926         case EAPT_SRP:
1927                 if (len < 1) {
1928                         error("EAP: received empty SRP Request");
1929                         /* Bogus request; wait for something real. */
1930                         return;
1931                 }
1932
1933                 /* Get subtype */
1934                 GETCHAR(vallen, inp);
1935                 len--;
1936                 switch (vallen) {
1937                 case EAPSRP_CHALLENGE:
1938                         tc = NULL;
1939                         if (esp->es_client.ea_session != NULL) {
1940                                 tc = (struct t_client *)esp->es_client.
1941                                     ea_session;
1942                                 /*
1943                                  * If this is a new challenge, then start
1944                                  * over with a new client session context.
1945                                  * Otherwise, just resend last response.
1946                                  */
1947                                 if (id != esp->es_client.ea_id) {
1948                                         t_clientclose(tc);
1949                                         esp->es_client.ea_session = NULL;
1950                                         tc = NULL;
1951                                 }
1952                         }
1953                         /* No session key just yet */
1954                         esp->es_client.ea_skey = NULL;
1955                         if (tc == NULL) {
1956                                 GETCHAR(vallen, inp);
1957                                 len--;
1958                                 if (vallen >= len) {
1959                                         error("EAP: badly-formed SRP Challenge"
1960                                             " (name)");
1961                                         /* Ignore badly-formed messages */
1962                                         return;
1963                                 }
1964                                 BCOPY(inp, rhostname, vallen);
1965                                 rhostname[vallen] = '\0';
1966                                 INCPTR(vallen, inp);
1967                                 len -= vallen;
1968
1969                                 /*
1970                                  * In case the remote doesn't give us his name,
1971                                  * use configured name.
1972                                  */
1973                                 if (explicit_remote ||
1974                                     (remote_name[0] != '\0' && vallen == 0)) {
1975                                         strlcpy(rhostname, remote_name,
1976                                             sizeof (rhostname));
1977                                 }
1978
1979                                 if (esp->es_client.ea_peer != NULL)
1980                                         free(esp->es_client.ea_peer);
1981                                 esp->es_client.ea_peer = strdup(rhostname);
1982                                 esp->es_client.ea_peerlen = strlen(rhostname);
1983
1984                                 GETCHAR(vallen, inp);
1985                                 len--;
1986                                 if (vallen >= len) {
1987                                         error("EAP: badly-formed SRP Challenge"
1988                                             " (s)");
1989                                         /* Ignore badly-formed messages */
1990                                         return;
1991                                 }
1992                                 sval.data = inp;
1993                                 sval.len = vallen;
1994                                 INCPTR(vallen, inp);
1995                                 len -= vallen;
1996
1997                                 GETCHAR(vallen, inp);
1998                                 len--;
1999                                 if (vallen > len) {
2000                                         error("EAP: badly-formed SRP Challenge"
2001                                             " (g)");
2002                                         /* Ignore badly-formed messages */
2003                                         return;
2004                                 }
2005                                 /* If no generator present, then use value 2 */
2006                                 if (vallen == 0) {
2007                                         gval.data = (u_char *)"\002";
2008                                         gval.len = 1;
2009                                 } else {
2010                                         gval.data = inp;
2011                                         gval.len = vallen;
2012                                 }
2013                                 INCPTR(vallen, inp);
2014                                 len -= vallen;
2015
2016                                 /*
2017                                  * If no modulus present, then use well-known
2018                                  * value.
2019                                  */
2020                                 if (len == 0) {
2021                                         Nval.data = (u_char *)wkmodulus;
2022                                         Nval.len = sizeof (wkmodulus);
2023                                 } else {
2024                                         Nval.data = inp;
2025                                         Nval.len = len;
2026                                 }
2027                                 tc = t_clientopen(esp->es_client.ea_name,
2028                                     &Nval, &gval, &sval);
2029                                 if (tc == NULL) {
2030                                         eap_send_nak(esp, id, EAPT_MD5CHAP);
2031                                         break;
2032                                 }
2033                                 esp->es_client.ea_session = (void *)tc;
2034
2035                                 /* Add Challenge ID & type to verifier */
2036                                 vals[0] = id;
2037                                 vals[1] = EAPT_SRP;
2038                                 t_clientaddexdata(tc, vals, 2);
2039                         }
2040                         Ap = t_clientgenexp(tc);
2041                         eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2042                             Ap->len);
2043                         break;
2044
2045                 case EAPSRP_SKEY:
2046                         tc = (struct t_client *)esp->es_client.ea_session;
2047                         if (tc == NULL) {
2048                                 warn("EAP: peer sent Subtype 2 without 1");
2049                                 eap_send_nak(esp, id, EAPT_MD5CHAP);
2050                                 break;
2051                         }
2052                         if (esp->es_client.ea_skey != NULL) {
2053                                 /*
2054                                  * ID number should not change here.  Warn
2055                                  * if it does (but otherwise ignore).
2056                                  */
2057                                 if (id != esp->es_client.ea_id) {
2058                                         warn("EAP: ID changed from %d to %d "
2059                                             "in SRP Subtype 2 rexmit",
2060                                             esp->es_client.ea_id, id);
2061                                 }
2062                         } else {
2063                                 if (get_srp_secret(esp->es_unit,
2064                                     esp->es_client.ea_name,
2065                                     esp->es_client.ea_peer, secret, 0) == 0) {
2066                                         /*
2067                                          * Can't work with this peer because
2068                                          * the secret is missing.  Just give
2069                                          * up.
2070                                          */
2071                                         eap_send_nak(esp, id, EAPT_MD5CHAP);
2072                                         break;
2073                                 }
2074                                 Bval.data = inp;
2075                                 Bval.len = len;
2076                                 t_clientpasswd(tc, secret);
2077                                 BZERO(secret, sizeof (secret));
2078                                 esp->es_client.ea_skey =
2079                                     t_clientgetkey(tc, &Bval);
2080                                 if (esp->es_client.ea_skey == NULL) {
2081                                         /* Server is rogue; stop now */
2082                                         error("EAP: SRP server is rogue");
2083                                         goto client_failure;
2084                                 }
2085                         }
2086                         eap_srpval_response(esp, id, SRPVAL_EBIT,
2087                             t_clientresponse(tc));
2088                         break;
2089
2090                 case EAPSRP_SVALIDATOR:
2091                         tc = (struct t_client *)esp->es_client.ea_session;
2092                         if (tc == NULL || esp->es_client.ea_skey == NULL) {
2093                                 warn("EAP: peer sent Subtype 3 without 1/2");
2094                                 eap_send_nak(esp, id, EAPT_MD5CHAP);
2095                                 break;
2096                         }
2097                         /*
2098                          * If we're already open, then this ought to be a
2099                          * duplicate.  Otherwise, check that the server is
2100                          * who we think it is.
2101                          */
2102                         if (esp->es_client.ea_state == eapOpen) {
2103                                 if (id != esp->es_client.ea_id) {
2104                                         warn("EAP: ID changed from %d to %d "
2105                                             "in SRP Subtype 3 rexmit",
2106                                             esp->es_client.ea_id, id);
2107                                 }
2108                         } else {
2109                                 len -= sizeof (u_int32_t) + SHA_DIGEST_LENGTH;
2110                                 if (len < 0 || t_clientverify(tc, inp +
2111                                         sizeof (u_int32_t)) != 0) {
2112                                         error("EAP: SRP server verification "
2113                                             "failed");
2114                                         goto client_failure;
2115                                 }
2116                                 GETLONG(esp->es_client.ea_keyflags, inp);
2117                                 /* Save pseudonym if user wants it. */
2118                                 if (len > 0 && esp->es_usepseudo) {
2119                                         INCPTR(SHA_DIGEST_LENGTH, inp);
2120                                         write_pseudonym(esp, inp, len, id);
2121                                 }
2122                         }
2123                         /*
2124                          * We've verified our peer.  We're now mostly done,
2125                          * except for waiting on the regular EAP Success
2126                          * message.
2127                          */
2128                         eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2129                         break;
2130
2131                 case EAPSRP_LWRECHALLENGE:
2132                         if (len < 4) {
2133                                 warn("EAP: malformed Lightweight rechallenge");
2134                                 return;
2135                         }
2136                         ctxt = PPP_MD_CTX_new();
2137                         if (ctxt) {
2138
2139                                 vals[0] = id;
2140                                 PPP_DigestInit(ctxt, PPP_sha1());
2141                                 PPP_DigestUpdate(ctxt, vals, 1);
2142                                 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
2143                                         SESSION_KEY_LEN);
2144                                 PPP_DigestUpdate(ctxt, inp, len);
2145                                 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
2146                                         esp->es_client.ea_namelen);
2147                                 PPP_DigestFinal(ctxt, dig, &diglen);
2148
2149                                 PPP_MD_CTX_free(ctxt);
2150
2151                                 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2152                                         SHA_DIGEST_LENGTH);
2153                         }
2154                         break;
2155
2156                 default:
2157                         error("EAP: unknown SRP Subtype %d", vallen);
2158                         eap_send_nak(esp, id, EAPT_MD5CHAP);
2159                         break;
2160                 }
2161                 break;
2162 #endif /* PPP_WITH_SRP */
2163
2164 #ifdef PPP_WITH_CHAPMS
2165         case EAPT_MSCHAPV2:
2166             if (len < 4) {
2167                 error("EAP: received invalid MSCHAPv2 packet, too short");
2168                 return;
2169             }
2170             unsigned char opcode;
2171             GETCHAR(opcode, inp);
2172             unsigned char chapid; /* Chapv2-ID */
2173             GETCHAR(chapid, inp);
2174             short mssize;
2175             GETSHORT(mssize, inp);
2176
2177             /* Validate the mssize field */
2178             if (len != mssize) { 
2179                 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2180                 return;
2181             }
2182             len -= 4;
2183
2184             /* If MSCHAPv2 digest was not found, NAK the packet */
2185             if (!esp->es_client.digest) {
2186                 error("EAP MSCHAPv2 not supported");
2187                 eap_send_nak(esp, id, EAPT_SRP);
2188                 return;
2189             }
2190
2191             switch (opcode) {
2192             case CHAP_CHALLENGE: {
2193
2194                 /* make_response() expects: VLEN + VALUE */
2195                 u_char *challenge = inp;
2196
2197                 unsigned char vsize;
2198                 GETCHAR(vsize, inp);
2199                 len -= 1;
2200
2201                 /* Validate the VALUE field */
2202                 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2203                     error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2204                     return;
2205                 }
2206
2207                 /* Increment past the VALUE field */
2208                 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2209                 len -= MS_CHAP2_PEER_CHAL_LEN;
2210
2211                 /* Extract the hostname */
2212                 rhostname[0] = '\0';
2213                 if (len > 0) {
2214                     if (len >= sizeof (rhostname)) {
2215                         dbglog("EAP: trimming really long peer name down");
2216                         len = sizeof(rhostname) - 1;
2217                     }
2218                     BCOPY(inp, rhostname, len);
2219                     rhostname[len] = '\0';
2220                 }
2221
2222                 /* In case the remote doesn't give us his name. */
2223                 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2224                     strlcpy(rhostname, remote_name, sizeof(rhostname));
2225
2226                 /* Get the secret for authenticating ourselves with the specified host. */
2227                 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2228                     rhostname, secret, &secret_len, 0)) {
2229                     dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2230                     eap_send_nak(esp, id, EAPT_SRP);
2231                     break;
2232                 }
2233                 esp->es_client.ea_namelen = strlen(esp->es_client.ea_name);
2234
2235                 /* Create the MSCHAPv2 response (and add to cache) */
2236                 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2237                 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2238                         challenge, secret, secret_len, NULL);
2239
2240                 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2241                 break;
2242             }
2243             case CHAP_SUCCESS: {
2244
2245                 /* Check response for mutual authentication */
2246                 u_char status = CHAP_FAILURE;
2247                 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2248                      info("Chap authentication succeeded! %.*v", len, inp);
2249                      status = CHAP_SUCCESS;
2250                 }
2251                 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2252                 break;
2253             }
2254             case CHAP_FAILURE: {
2255
2256                 /* Process the failure string, and log appropriate information */
2257                 esp->es_client.digest->handle_failure(inp, len);
2258
2259                 u_char status = CHAP_FAILURE;
2260                 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2261                 goto client_failure; /* force termination */
2262             }
2263             default:
2264
2265                 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2266                 eap_send_nak(esp, id, EAPT_SRP);
2267             }
2268
2269             break;
2270 #endif /* PPP_WITH_CHAPMS */
2271 #ifdef PPP_WITH_PEAP
2272         case EAPT_PEAP:
2273
2274                 /* Initialize the PEAP context (if not already initialized) */
2275                 if (!esp->ea_peap) {
2276                         rhostname[0] = '\0';
2277                         if (explicit_remote || (remote_name[0] != '\0')) {
2278                                 strlcpy(rhostname, remote_name, sizeof (rhostname));
2279                         }
2280                         if (peap_init(&esp->ea_peap, rhostname)) {
2281                                 eap_send_nak(esp, id, EAPT_TLS);
2282                                 break;
2283                         }
2284                 }
2285
2286                 /* Process the PEAP packet */
2287                 if (peap_process(esp, id, inp, len)) {
2288                         eap_send_nak(esp, id, EAPT_TLS);
2289                 }
2290
2291                 break;
2292 #endif // PPP_WITH_PEAP
2293
2294         default:
2295                 info("EAP: unknown authentication type %d; Naking", typenum);
2296                 eap_send_nak(esp, id, EAPT_SRP);
2297                 break;
2298         }
2299
2300         if (esp->es_client.ea_timeout > 0) {
2301                 UNTIMEOUT(eap_client_timeout, (void *)esp);
2302                 TIMEOUT(eap_client_timeout, (void *)esp,
2303                     esp->es_client.ea_timeout);
2304         }
2305         return;
2306
2307 client_failure:
2308         esp->es_client.ea_state = eapBadAuth;
2309         if (esp->es_client.ea_timeout > 0) {
2310                 UNTIMEOUT(eap_client_timeout, (void *)esp);
2311         }
2312         esp->es_client.ea_session = NULL;
2313 #ifdef PPP_WITH_SRP
2314         t_clientclose(tc);
2315         auth_withpeer_fail(esp->es_unit, PPP_EAP);
2316 #endif /* PPP_WITH_SRP */
2317 }
2318
2319 /*
2320  * eap_response - Receive EAP Response message (server mode).
2321  */
2322 static void
2323 eap_response(eap_state *esp, u_char *inp, int id, int len)
2324 {
2325         u_char typenum;
2326         u_char vallen;
2327         int secret_len;
2328         char secret[MAXSECRETLEN];
2329         char rhostname[256];
2330         PPP_MD_CTX *mdctx;
2331         u_char hash[MD5_DIGEST_LENGTH];
2332         int hashlen = MD5_DIGEST_LENGTH;
2333 #ifdef PPP_WITH_SRP
2334         struct t_server *ts;
2335         struct t_num A;
2336         PPP_MD_CTX *ctxt;
2337         u_char dig[SHA_DIGEST_LENGTH];
2338         int diglen = sizeof(dig);
2339 #endif /* PPP_WITH_SRP */
2340
2341 #ifdef PPP_WITH_EAPTLS
2342         struct eaptls_session *ets;
2343         u_char flags;
2344 #endif /* PPP_WITH_EAPTLS */
2345 #ifdef PPP_WITH_CHAPMS
2346         u_char opcode;
2347         int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2348                 unsigned char *, unsigned char *, char *, int);
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                                 strcpy(rhostname, tmp);
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 }