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