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