2 * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
4 * Copyright (c) 2001 by Sun Microsystems, Inc.
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.
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.
18 * Original version by James Carlson
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.
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.
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.
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.
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.
43 * Based on draft-ietf-pppext-eap-srp-03.txt.
46 #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
57 #include <sys/types.h>
64 #include "pathnames.h"
75 #ifndef SHA_DIGESTSIZE
76 #define SHA_DIGESTSIZE 20
80 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
82 static char *pn_secret = NULL; /* Pseudonym generating secret */
86 * Command-line options.
88 static option_t eap_option_list[] = {
89 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
90 "Set retransmit timeout for EAP Requests (server)" },
91 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
92 "Set max number of EAP Requests sent (server)" },
93 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
94 "Set time limit for peer EAP authentication" },
95 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
96 "Set max number of EAP Requests allows (client)" },
97 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
98 "Set interval for EAP rechallenge" },
100 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
101 "Set interval for SRP lightweight rechallenge" },
102 { "srp-pn-secret", o_string, &pn_secret,
103 "Long term pseudonym generation secret" },
104 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
105 "Use pseudonym if offered one by server", 1 },
111 * Protocol entry points.
113 static void eap_init __P((int unit));
114 static void eap_input __P((int unit, u_char *inp, int inlen));
115 static void eap_protrej __P((int unit));
116 static void eap_lowerup __P((int unit));
117 static void eap_lowerdown __P((int unit));
118 static int eap_printpkt __P((u_char *inp, int inlen,
119 void (*)(void *arg, char *fmt, ...), void *arg));
121 struct protent eap_protent = {
122 PPP_EAP, /* protocol number */
123 eap_init, /* initialization procedure */
124 eap_input, /* process a received packet */
125 eap_protrej, /* process a received protocol-reject */
126 eap_lowerup, /* lower layer has gone up */
127 eap_lowerdown, /* lower layer has gone down */
128 NULL, /* open the protocol */
129 NULL, /* close the protocol */
130 eap_printpkt, /* print a packet in readable form */
131 NULL, /* process a received data packet */
132 1, /* protocol enabled */
133 "EAP", /* text name of protocol */
134 NULL, /* text name of corresponding data protocol */
135 eap_option_list, /* list of command-line options */
136 NULL, /* check requested options; assign defaults */
137 NULL, /* configure interface for demand-dial */
138 NULL /* say whether to bring up link for this pkt */
142 * A well-known 2048 bit modulus.
144 static const u_char wkmodulus[] = {
145 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
146 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
147 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
148 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
149 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
150 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
151 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
152 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
153 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
154 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
155 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
156 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
157 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
158 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
159 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
160 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
161 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
162 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
163 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
164 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
165 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
166 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
167 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
168 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
169 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
170 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
171 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
172 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
173 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
174 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
175 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
176 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
179 /* Local forward declarations. */
180 static void eap_server_timeout __P((void *arg));
183 * Convert EAP state code to printable string for debug.
187 enum eap_state_code esc;
189 static const char *state_names[] = { EAP_STATES };
191 return (state_names[(int)esc]);
195 * eap_init - Initialize state for an EAP user. This is currently
196 * called once by main() during start-up.
202 eap_state *esp = &eap_states[unit];
204 BZERO(esp, sizeof (*esp));
206 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
207 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
208 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
209 esp->es_client.ea_timeout = EAP_DEFREQTIME;
210 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
214 * eap_client_timeout - Give up waiting for the peer to send any
218 eap_client_timeout(arg)
221 eap_state *esp = (eap_state *) arg;
223 if (!eap_client_active(esp))
226 error("EAP: timeout waiting for Request from peer");
227 auth_withpeer_fail(esp->es_unit, PPP_EAP);
228 esp->es_client.ea_state = eapBadAuth;
232 * eap_authwithpeer - Authenticate to our peer (behave as client).
234 * Start client state and wait for requests. This is called only
238 eap_authwithpeer(unit, localname)
242 eap_state *esp = &eap_states[unit];
244 /* Save the peer name we're given */
245 esp->es_client.ea_name = localname;
246 esp->es_client.ea_namelen = strlen(localname);
248 esp->es_client.ea_state = eapListen;
251 * Start a timer so that if the other end just goes
252 * silent, we don't sit here waiting forever.
254 if (esp->es_client.ea_timeout > 0)
255 TIMEOUT(eap_client_timeout, (void *)esp,
256 esp->es_client.ea_timeout);
260 * Format a standard EAP Failure message and send it to the peer.
264 eap_send_failure(esp)
269 outp = outpacket_buf;
271 MAKEHEADER(outp, PPP_EAP);
273 PUTCHAR(EAP_FAILURE, outp);
274 esp->es_server.ea_id++;
275 PUTCHAR(esp->es_server.ea_id, outp);
276 PUTSHORT(EAP_HEADERLEN, outp);
278 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
280 esp->es_server.ea_state = eapBadAuth;
281 auth_peer_fail(esp->es_unit, PPP_EAP);
285 * Format a standard EAP Success message and send it to the peer.
289 eap_send_success(esp)
294 outp = outpacket_buf;
296 MAKEHEADER(outp, PPP_EAP);
298 PUTCHAR(EAP_SUCCESS, outp);
299 esp->es_server.ea_id++;
300 PUTCHAR(esp->es_server.ea_id, outp);
301 PUTSHORT(EAP_HEADERLEN, outp);
303 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
305 auth_peer_success(esp->es_unit, PPP_EAP, 0,
306 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
311 * Set DES key according to pseudonym-generating secret and current
315 pncrypt_setkey(int timeoffs)
320 u_char dig[SHA_DIGESTSIZE];
323 if (pn_secret == NULL)
325 reftime = time(NULL) + timeoffs;
326 tp = localtime(&reftime);
328 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
329 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
330 SHA1Update(&ctxt, tbuf, strlen(tbuf));
331 SHA1Final(dig, &ctxt);
332 return (DesSetkey(dig));
335 static char base64[] =
336 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
344 b64enc(bs, inp, inlen, outp)
353 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
356 if (bs->bs_offs >= 24) {
357 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
358 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
359 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
360 *outp++ = base64[bs->bs_bits & 0x3F];
376 if (bs->bs_offs == 8) {
377 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
378 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
380 } else if (bs->bs_offs == 16) {
381 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
382 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
383 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
392 b64dec(bs, inp, inlen, outp)
402 if ((cp = strchr(base64, *inp++)) == NULL)
404 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
407 if (bs->bs_offs >= 8) {
408 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
418 * Assume that current waiting server state is complete and figure
419 * next state to use based on available authentication data. 'status'
420 * indicates if there was an error in handling the last query. It is
421 * 0 for success and non-zero for failure.
424 eap_figure_next_state(esp, status)
429 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
431 struct t_confent *tce, mytce;
434 int id, i, plen, toffs;
439 esp->es_server.ea_timeout = esp->es_savedtime;
440 switch (esp->es_server.ea_state) {
446 /* Discard any previous session. */
447 ts = (struct t_server *)esp->es_server.ea_session;
450 esp->es_server.ea_session = NULL;
451 esp->es_server.ea_skey = NULL;
455 esp->es_server.ea_state = eapBadAuth;
459 /* If we've got a pseudonym, try to decode to real name. */
460 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
461 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
462 SRP_PSEUDO_LEN) == 0 &&
463 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
465 BZERO(&bs, sizeof (bs));
467 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
468 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
471 for (i = 0; i < 5; i++) {
472 pncrypt_setkey(toffs);
474 if (!DesDecrypt(secbuf, clear)) {
475 dbglog("no DES here; cannot decode "
479 id = *(unsigned char *)clear;
480 if (id + 1 <= plen && id + 9 > plen)
483 if (plen % 8 == 0 && i < 5) {
485 * Note that this is always shorter than the
486 * original stored string, so there's no need
489 if ((i = plen = *(unsigned char *)clear) > 7)
491 esp->es_server.ea_peerlen = plen;
492 dp = (unsigned char *)esp->es_server.ea_peer;
493 BCOPY(clear + 1, dp, i);
498 (void) DesDecrypt(sp, dp);
503 esp->es_server.ea_peer[
504 esp->es_server.ea_peerlen] = '\0';
505 dbglog("decoded pseudonym to \"%.*q\"",
506 esp->es_server.ea_peerlen,
507 esp->es_server.ea_peer);
509 dbglog("failed to decode real name");
510 /* Stay in eapIdentfy state; requery */
514 /* Look up user in secrets database. */
515 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
516 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
517 /* Set up default in case SRP entry is bad */
518 esp->es_server.ea_state = eapMD5Chall;
519 /* Get t_confent based on index in srp-secrets */
520 id = strtol((char *)secbuf, &cp, 10);
521 if (*cp++ != ':' || id < 0)
525 mytce.modulus.data = (u_char *)wkmodulus;
526 mytce.modulus.len = sizeof (wkmodulus);
527 mytce.generator.data = (u_char *)"\002";
528 mytce.generator.len = 1;
530 } else if ((tce = gettcid(id)) != NULL) {
532 * Client will have to verify this modulus/
533 * generator combination, and that will take
534 * a while. Lengthen the timeout here.
536 if (esp->es_server.ea_timeout > 0 &&
537 esp->es_server.ea_timeout < 30)
538 esp->es_server.ea_timeout = 30;
542 if ((cp2 = strchr(cp, ':')) == NULL)
545 tpw.pebuf.name = esp->es_server.ea_peer;
546 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
548 tpw.pebuf.password.data = tpw.pwbuf;
549 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
551 tpw.pebuf.salt.data = tpw.saltbuf;
552 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
554 esp->es_server.ea_session = (void *)ts;
555 esp->es_server.ea_state = eapSRP1;
556 vals[0] = esp->es_server.ea_id + 1;
558 t_serveraddexdata(ts, vals, 2);
559 /* Generate B; must call before t_servergetkey() */
564 esp->es_server.ea_state = eapMD5Chall;
569 ts = (struct t_server *)esp->es_server.ea_session;
570 if (ts != NULL && status != 0) {
572 esp->es_server.ea_session = NULL;
573 esp->es_server.ea_skey = NULL;
577 esp->es_server.ea_state = eapMD5Chall;
578 } else if (status != 0 || esp->es_server.ea_session == NULL) {
579 esp->es_server.ea_state = eapBadAuth;
581 esp->es_server.ea_state = eapSRP2;
587 ts = (struct t_server *)esp->es_server.ea_session;
588 if (ts != NULL && status != 0) {
590 esp->es_server.ea_session = NULL;
591 esp->es_server.ea_skey = NULL;
594 if (status != 0 || esp->es_server.ea_session == NULL) {
595 esp->es_server.ea_state = eapBadAuth;
597 esp->es_server.ea_state = eapSRP3;
604 ts = (struct t_server *)esp->es_server.ea_session;
605 if (ts != NULL && status != 0) {
607 esp->es_server.ea_session = NULL;
608 esp->es_server.ea_skey = NULL;
611 if (status != 0 || esp->es_server.ea_session == NULL) {
612 esp->es_server.ea_state = eapBadAuth;
614 esp->es_server.ea_state = eapOpen;
620 esp->es_server.ea_state = eapBadAuth;
622 esp->es_server.ea_state = eapOpen;
627 esp->es_server.ea_state = eapBadAuth;
630 if (esp->es_server.ea_state == eapBadAuth)
631 eap_send_failure(esp);
635 * Format an EAP Request message and send it to the peer. Message
636 * type depends on current state. (Server operation)
639 eap_send_request(esp)
650 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
656 /* Handle both initial auth and restart */
657 if (esp->es_server.ea_state < eapIdentify &&
658 esp->es_server.ea_state != eapInitial) {
659 esp->es_server.ea_state = eapIdentify;
660 if (explicit_remote) {
662 * If we already know the peer's
663 * unauthenticated name, then there's no
664 * reason to ask. Go to next state instead.
666 esp->es_server.ea_peer = remote_name;
667 esp->es_server.ea_peerlen = strlen(remote_name);
668 eap_figure_next_state(esp, 0);
672 if (esp->es_server.ea_maxrequests > 0 &&
673 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
674 if (esp->es_server.ea_responses > 0)
675 error("EAP: too many Requests sent");
677 error("EAP: no response to Requests");
678 eap_send_failure(esp);
682 outp = outpacket_buf;
684 MAKEHEADER(outp, PPP_EAP);
686 PUTCHAR(EAP_REQUEST, outp);
687 PUTCHAR(esp->es_server.ea_id, outp);
691 switch (esp->es_server.ea_state) {
693 PUTCHAR(EAPT_IDENTITY, outp);
695 challen = strlen(str);
696 BCOPY(str, outp, challen);
697 INCPTR(challen, outp);
701 PUTCHAR(EAPT_MD5CHAP, outp);
703 * pick a random challenge length between
704 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
706 challen = (drand48() *
707 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
708 MIN_CHALLENGE_LENGTH;
709 PUTCHAR(challen, outp);
710 esp->es_challen = challen;
711 ptr = esp->es_challenge;
712 while (--challen >= 0)
713 *ptr++ = (u_char) (drand48() * 0x100);
714 BCOPY(esp->es_challenge, outp, esp->es_challen);
715 INCPTR(esp->es_challen, outp);
716 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
717 INCPTR(esp->es_server.ea_namelen, outp);
722 PUTCHAR(EAPT_SRP, outp);
723 PUTCHAR(EAPSRP_CHALLENGE, outp);
725 PUTCHAR(esp->es_server.ea_namelen, outp);
726 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
727 INCPTR(esp->es_server.ea_namelen, outp);
729 ts = (struct t_server *)esp->es_server.ea_session;
731 PUTCHAR(ts->s.len, outp);
732 BCOPY(ts->s.data, outp, ts->s.len);
733 INCPTR(ts->s.len, outp);
735 if (ts->g.len == 1 && ts->g.data[0] == 2) {
738 PUTCHAR(ts->g.len, outp);
739 BCOPY(ts->g.data, outp, ts->g.len);
740 INCPTR(ts->g.len, outp);
743 if (ts->n.len != sizeof (wkmodulus) ||
744 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
745 BCOPY(ts->n.data, outp, ts->n.len);
746 INCPTR(ts->n.len, outp);
751 PUTCHAR(EAPT_SRP, outp);
752 PUTCHAR(EAPSRP_SKEY, outp);
754 ts = (struct t_server *)esp->es_server.ea_session;
756 BCOPY(ts->B.data, outp, ts->B.len);
757 INCPTR(ts->B.len, outp);
761 PUTCHAR(EAPT_SRP, outp);
762 PUTCHAR(EAPSRP_SVALIDATOR, outp);
763 PUTLONG(SRPVAL_EBIT, outp);
764 ts = (struct t_server *)esp->es_server.ea_session;
766 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
767 INCPTR(SHA_DIGESTSIZE, outp);
769 if (pncrypt_setkey(0)) {
770 /* Generate pseudonym */
772 cp = (unsigned char *)esp->es_server.ea_peer;
773 if ((j = i = esp->es_server.ea_peerlen) > 7)
776 BCOPY(cp, clear + 1, j);
779 if (!DesEncrypt(clear, cipher)) {
780 dbglog("no DES here; not generating pseudonym");
783 BZERO(&b64, sizeof (b64));
784 outp++; /* space for pseudonym length */
785 outp += b64enc(&b64, cipher, 8, outp);
787 (void) DesEncrypt(cp, cipher);
788 outp += b64enc(&b64, cipher, 8, outp);
796 *cp++ = drand48() * 0x100;
799 (void) DesEncrypt(clear, cipher);
800 outp += b64enc(&b64, cipher, 8, outp);
802 outp += b64flush(&b64, outp);
804 /* Set length and pad out to next 20 octet boundary */
809 while (i < SHA_DIGESTSIZE) {
810 *outp++ = drand48() * 0x100;
815 /* Obscure the pseudonym with SHA1 hash */
817 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
818 SHA1Update(&ctxt, esp->es_server.ea_skey,
820 SHA1Update(&ctxt, esp->es_server.ea_peer,
821 esp->es_server.ea_peerlen);
822 while (optr < outp) {
823 SHA1Final(dig, &ctxt);
825 while (cp < dig + SHA_DIGESTSIZE)
828 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
829 SHA1Update(&ctxt, esp->es_server.ea_skey,
831 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
838 PUTCHAR(EAPT_SRP, outp);
839 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
840 challen = MIN_CHALLENGE_LENGTH +
841 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
842 esp->es_challen = challen;
843 ptr = esp->es_challenge;
844 while (--challen >= 0)
845 *ptr++ = drand48() * 0x100;
846 BCOPY(esp->es_challenge, outp, esp->es_challen);
847 INCPTR(esp->es_challen, outp);
855 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
856 PUTSHORT(outlen, lenloc);
858 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
860 esp->es_server.ea_requests++;
862 if (esp->es_server.ea_timeout > 0)
863 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
867 * eap_authpeer - Authenticate our peer (behave as server).
869 * Start server state and send first request. This is called only
873 eap_authpeer(unit, localname)
877 eap_state *esp = &eap_states[unit];
879 /* Save the name we're given. */
880 esp->es_server.ea_name = localname;
881 esp->es_server.ea_namelen = strlen(localname);
883 esp->es_savedtime = esp->es_server.ea_timeout;
885 /* Lower layer up yet? */
886 if (esp->es_server.ea_state == eapInitial ||
887 esp->es_server.ea_state == eapPending) {
888 esp->es_server.ea_state = eapPending;
892 esp->es_server.ea_state = eapPending;
894 /* ID number not updated here intentionally; hashed into M1 */
895 eap_send_request(esp);
899 * eap_server_timeout - Retransmission timer for sending Requests
903 eap_server_timeout(arg)
906 eap_state *esp = (eap_state *) arg;
908 if (!eap_server_active(esp))
911 /* EAP ID number must not change on timeout. */
912 eap_send_request(esp);
916 * When it's time to send rechallenge the peer, this timeout is
917 * called. Once the rechallenge is successful, the response handler
918 * will restart the timer. If it fails, then the link is dropped.
924 eap_state *esp = (eap_state *)arg;
926 if (esp->es_server.ea_state != eapOpen &&
927 esp->es_server.ea_state != eapSRP4)
930 esp->es_server.ea_requests = 0;
931 esp->es_server.ea_state = eapIdentify;
932 eap_figure_next_state(esp, 0);
933 esp->es_server.ea_id++;
934 eap_send_request(esp);
938 srp_lwrechallenge(arg)
941 eap_state *esp = (eap_state *)arg;
943 if (esp->es_server.ea_state != eapOpen ||
944 esp->es_server.ea_type != EAPT_SRP)
947 esp->es_server.ea_requests = 0;
948 esp->es_server.ea_state = eapSRP4;
949 esp->es_server.ea_id++;
950 eap_send_request(esp);
954 * eap_lowerup - The lower layer is now up.
956 * This is called before either eap_authpeer or eap_authwithpeer. See
957 * link_established() in auth.c. All that's necessary here is to
958 * return to closed state so that those two routines will do the right
965 eap_state *esp = &eap_states[unit];
967 /* Discard any (possibly authenticated) peer name. */
968 if (esp->es_server.ea_peer != NULL &&
969 esp->es_server.ea_peer != remote_name)
970 free(esp->es_server.ea_peer);
971 esp->es_server.ea_peer = NULL;
972 if (esp->es_client.ea_peer != NULL)
973 free(esp->es_client.ea_peer);
974 esp->es_client.ea_peer = NULL;
976 esp->es_client.ea_state = eapClosed;
977 esp->es_server.ea_state = eapClosed;
981 * eap_lowerdown - The lower layer is now down.
983 * Cancel all timeouts and return to initial state.
989 eap_state *esp = &eap_states[unit];
991 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
992 UNTIMEOUT(eap_client_timeout, (void *)esp);
994 if (eap_server_active(esp)) {
995 if (esp->es_server.ea_timeout > 0) {
996 UNTIMEOUT(eap_server_timeout, (void *)esp);
999 if ((esp->es_server.ea_state == eapOpen ||
1000 esp->es_server.ea_state == eapSRP4) &&
1001 esp->es_rechallenge > 0) {
1002 UNTIMEOUT(eap_rechallenge, (void *)esp);
1004 if (esp->es_server.ea_state == eapOpen &&
1005 esp->es_lwrechallenge > 0) {
1006 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1010 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1011 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1015 * eap_protrej - Peer doesn't speak this protocol.
1017 * This shouldn't happen. If it does, it represents authentication
1024 eap_state *esp = &eap_states[unit];
1026 if (eap_client_active(esp)) {
1027 error("EAP authentication failed due to Protocol-Reject");
1028 auth_withpeer_fail(unit, PPP_EAP);
1030 if (eap_server_active(esp)) {
1031 error("EAP authentication of peer failed on Protocol-Reject");
1032 auth_peer_fail(unit, PPP_EAP);
1034 eap_lowerdown(unit);
1038 * Format and send a regular EAP Response message.
1041 eap_send_response(esp, id, typenum, str, lenstr)
1051 outp = outpacket_buf;
1053 MAKEHEADER(outp, PPP_EAP);
1055 PUTCHAR(EAP_RESPONSE, outp);
1057 esp->es_client.ea_id = id;
1058 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1059 PUTSHORT(msglen, outp);
1060 PUTCHAR(typenum, outp);
1062 BCOPY(str, outp, lenstr);
1065 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1069 * Format and send an MD5-Challenge EAP Response message.
1072 eap_chap_response(esp, id, hash, name, namelen)
1082 outp = outpacket_buf;
1084 MAKEHEADER(outp, PPP_EAP);
1086 PUTCHAR(EAP_RESPONSE, outp);
1088 esp->es_client.ea_id = id;
1089 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1091 PUTSHORT(msglen, outp);
1092 PUTCHAR(EAPT_MD5CHAP, outp);
1093 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1094 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1095 INCPTR(MD5_SIGNATURE_SIZE, outp);
1097 BCOPY(name, outp, namelen);
1100 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1105 * Format and send a SRP EAP Response message.
1108 eap_srp_response(esp, id, subtypenum, str, lenstr)
1118 outp = outpacket_buf;
1120 MAKEHEADER(outp, PPP_EAP);
1122 PUTCHAR(EAP_RESPONSE, outp);
1124 esp->es_client.ea_id = id;
1125 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1126 PUTSHORT(msglen, outp);
1127 PUTCHAR(EAPT_SRP, outp);
1128 PUTCHAR(subtypenum, outp);
1130 BCOPY(str, outp, lenstr);
1133 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1137 * Format and send a SRP EAP Client Validator Response message.
1140 eap_srpval_response(esp, id, flags, str)
1149 outp = outpacket_buf;
1151 MAKEHEADER(outp, PPP_EAP);
1153 PUTCHAR(EAP_RESPONSE, outp);
1155 esp->es_client.ea_id = id;
1156 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1158 PUTSHORT(msglen, outp);
1159 PUTCHAR(EAPT_SRP, outp);
1160 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1161 PUTLONG(flags, outp);
1162 BCOPY(str, outp, SHA_DIGESTSIZE);
1164 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1166 #endif /* USE_SRP */
1169 eap_send_nak(esp, id, type)
1177 outp = outpacket_buf;
1179 MAKEHEADER(outp, PPP_EAP);
1181 PUTCHAR(EAP_RESPONSE, outp);
1183 esp->es_client.ea_id = id;
1184 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1185 PUTSHORT(msglen, outp);
1186 PUTCHAR(EAPT_NAK, outp);
1187 PUTCHAR(type, outp);
1189 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1196 char *user, *path, *file;
1199 static bool pnlogged = 0;
1201 pw = getpwuid(getuid());
1202 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1206 file = _PATH_PSEUDONYM;
1207 pl = strlen(user) + strlen(file) + 2;
1211 (void) slprintf(path, pl, "%s/%s", user, file);
1213 dbglog("pseudonym file: %s", path);
1220 open_pn_file(modebits)
1226 if ((path = name_of_pn_file()) == NULL)
1228 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1240 if ((path = name_of_pn_file()) != NULL) {
1241 (void) unlink(path);
1247 write_pseudonym(esp, inp, len, id)
1253 u_char *datp, *digp;
1255 u_char dig[SHA_DIGESTSIZE];
1256 int dsize, fd, olen = len;
1259 * Do the decoding by working backwards. This eliminates the need
1260 * to save the decoded output in a separate buffer.
1264 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1265 dsize = SHA_DIGESTSIZE;
1269 SHA1Update(&ctxt, &val, 1);
1270 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1272 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1274 SHA1Update(&ctxt, esp->es_client.ea_name,
1275 esp->es_client.ea_namelen);
1277 SHA1Final(dig, &ctxt);
1278 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1282 /* Now check that the result is sane */
1283 if (olen <= 0 || *inp + 1 > olen) {
1284 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1289 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1291 dbglog("EAP: error saving pseudonym: %m");
1294 len = write(fd, inp + 1, *inp);
1295 if (close(fd) != -1 && len == *inp) {
1296 dbglog("EAP: saved pseudonym");
1297 esp->es_usedpseudo = 0;
1299 dbglog("EAP: failed to save pseudonym");
1303 #endif /* USE_SRP */
1306 * eap_request - Receive EAP Request message (client mode).
1309 eap_request(esp, inp, id, len)
1318 char secret[MAXWORDLEN];
1319 char rhostname[256];
1321 u_char hash[MD5_SIGNATURE_SIZE];
1323 struct t_client *tc;
1324 struct t_num sval, gval, Nval, *Ap, Bval;
1327 u_char dig[SHA_DIGESTSIZE];
1329 #endif /* USE_SRP */
1332 * Note: we update es_client.ea_id *only if* a Response
1333 * message is being generated. Otherwise, we leave it the
1334 * same for duplicate detection purposes.
1337 esp->es_client.ea_requests++;
1338 if (esp->es_client.ea_maxrequests != 0 &&
1339 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1340 info("EAP: received too many Request messages");
1341 if (esp->es_client.ea_timeout > 0) {
1342 UNTIMEOUT(eap_client_timeout, (void *)esp);
1344 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1349 error("EAP: empty Request message discarded");
1353 GETCHAR(typenum, inp);
1359 info("EAP: Identity prompt \"%.*q\"", len, inp);
1361 if (esp->es_usepseudo &&
1362 (esp->es_usedpseudo == 0 ||
1363 (esp->es_usedpseudo == 1 &&
1364 id == esp->es_client.ea_id))) {
1365 esp->es_usedpseudo = 1;
1366 /* Try to get a pseudonym */
1367 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1368 strcpy(rhostname, SRP_PSEUDO_ID);
1369 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1370 sizeof (rhostname) - SRP_PSEUDO_LEN);
1371 /* XXX NAI unsupported */
1373 eap_send_response(esp, id, typenum,
1374 rhostname, len + SRP_PSEUDO_LEN);
1381 /* Stop using pseudonym now. */
1382 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1384 esp->es_usedpseudo = 2;
1386 #endif /* USE_SRP */
1387 eap_send_response(esp, id, typenum, esp->es_client.ea_name,
1388 esp->es_client.ea_namelen);
1391 case EAPT_NOTIFICATION:
1393 info("EAP: Notification \"%.*q\"", len, inp);
1394 eap_send_response(esp, id, typenum, NULL, 0);
1399 * Avoid the temptation to send Response Nak in reply
1400 * to Request Nak here. It can only lead to trouble.
1402 warn("EAP: unexpected Nak in Request; ignored");
1403 /* Return because we're waiting for something real. */
1408 error("EAP: received MD5-Challenge with no data");
1409 /* Bogus request; wait for something real. */
1412 GETCHAR(vallen, inp);
1414 if (vallen < 8 || vallen > len) {
1415 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1417 /* Try something better. */
1418 eap_send_nak(esp, id, EAPT_SRP);
1422 /* Not so likely to happen. */
1423 if (len - vallen >= sizeof (rhostname)) {
1424 dbglog("EAP: trimming really long peer name down");
1425 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1426 rhostname[sizeof (rhostname) - 1] = '\0';
1428 BCOPY(inp + vallen, rhostname, len - vallen);
1429 rhostname[len - vallen] = '\0';
1432 /* In case the remote doesn't give us his name. */
1433 if (explicit_remote ||
1434 (remote_name[0] != '\0' && vallen == len))
1435 strlcpy(rhostname, remote_name, sizeof (rhostname));
1438 * Get the secret for authenticating ourselves with
1439 * the specified host.
1441 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1442 rhostname, secret, &secret_len, 0)) {
1443 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1444 eap_send_nak(esp, id, EAPT_SRP);
1447 MD5_Init(&mdContext);
1449 MD5_Update(&mdContext, &typenum, 1);
1450 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1451 BZERO(secret, sizeof (secret));
1452 MD5_Update(&mdContext, inp, vallen);
1453 MD5_Final(hash, &mdContext);
1454 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1455 esp->es_client.ea_namelen);
1461 error("EAP: received empty SRP Request");
1462 /* Bogus request; wait for something real. */
1467 GETCHAR(vallen, inp);
1470 case EAPSRP_CHALLENGE:
1472 if (esp->es_client.ea_session != NULL) {
1473 tc = (struct t_client *)esp->es_client.
1476 * If this is a new challenge, then start
1477 * over with a new client session context.
1478 * Otherwise, just resend last response.
1480 if (id != esp->es_client.ea_id) {
1482 esp->es_client.ea_session = NULL;
1486 /* No session key just yet */
1487 esp->es_client.ea_skey = NULL;
1489 GETCHAR(vallen, inp);
1491 if (vallen >= len) {
1492 error("EAP: badly-formed SRP Challenge"
1494 /* Ignore badly-formed messages */
1497 BCOPY(inp, rhostname, vallen);
1498 rhostname[vallen] = '\0';
1499 INCPTR(vallen, inp);
1503 * In case the remote doesn't give us his name,
1504 * use configured name.
1506 if (explicit_remote ||
1507 (remote_name[0] != '\0' && vallen == 0)) {
1508 strlcpy(rhostname, remote_name,
1509 sizeof (rhostname));
1512 if (esp->es_client.ea_peer != NULL)
1513 free(esp->es_client.ea_peer);
1514 esp->es_client.ea_peer = strdup(rhostname);
1515 esp->es_client.ea_peerlen = strlen(rhostname);
1517 GETCHAR(vallen, inp);
1519 if (vallen >= len) {
1520 error("EAP: badly-formed SRP Challenge"
1522 /* Ignore badly-formed messages */
1527 INCPTR(vallen, inp);
1530 GETCHAR(vallen, inp);
1533 error("EAP: badly-formed SRP Challenge"
1535 /* Ignore badly-formed messages */
1538 /* If no generator present, then use value 2 */
1540 gval.data = (u_char *)"\002";
1546 INCPTR(vallen, inp);
1550 * If no modulus present, then use well-known
1554 Nval.data = (u_char *)wkmodulus;
1555 Nval.len = sizeof (wkmodulus);
1560 tc = t_clientopen(esp->es_client.ea_name,
1561 &Nval, &gval, &sval);
1563 eap_send_nak(esp, id, EAPT_MD5CHAP);
1566 esp->es_client.ea_session = (void *)tc;
1568 /* Add Challenge ID & type to verifier */
1571 t_clientaddexdata(tc, vals, 2);
1573 Ap = t_clientgenexp(tc);
1574 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
1579 tc = (struct t_client *)esp->es_client.ea_session;
1581 warn("EAP: peer sent Subtype 2 without 1");
1582 eap_send_nak(esp, id, EAPT_MD5CHAP);
1585 if (esp->es_client.ea_skey != NULL) {
1587 * ID number should not change here. Warn
1588 * if it does (but otherwise ignore).
1590 if (id != esp->es_client.ea_id) {
1591 warn("EAP: ID changed from %d to %d "
1592 "in SRP Subtype 2 rexmit",
1593 esp->es_client.ea_id, id);
1596 if (get_srp_secret(esp->es_unit,
1597 esp->es_client.ea_name,
1598 esp->es_client.ea_peer, secret, 0) == 0) {
1600 * Can't work with this peer because
1601 * the secret is missing. Just give
1604 eap_send_nak(esp, id, EAPT_MD5CHAP);
1609 t_clientpasswd(tc, secret);
1610 BZERO(secret, sizeof (secret));
1611 esp->es_client.ea_skey =
1612 t_clientgetkey(tc, &Bval);
1613 if (esp->es_client.ea_skey == NULL) {
1614 /* Server is rogue; stop now */
1615 error("EAP: SRP server is rogue");
1616 goto client_failure;
1619 eap_srpval_response(esp, id, SRPVAL_EBIT,
1620 t_clientresponse(tc));
1623 case EAPSRP_SVALIDATOR:
1624 tc = (struct t_client *)esp->es_client.ea_session;
1625 if (tc == NULL || esp->es_client.ea_skey == NULL) {
1626 warn("EAP: peer sent Subtype 3 without 1/2");
1627 eap_send_nak(esp, id, EAPT_MD5CHAP);
1631 * If we're already open, then this ought to be a
1632 * duplicate. Otherwise, check that the server is
1633 * who we think it is.
1635 if (esp->es_client.ea_state == eapOpen) {
1636 if (id != esp->es_client.ea_id) {
1637 warn("EAP: ID changed from %d to %d "
1638 "in SRP Subtype 3 rexmit",
1639 esp->es_client.ea_id, id);
1642 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
1643 if (len < 0 || t_clientverify(tc, inp +
1644 sizeof (u_int32_t)) != 0) {
1645 error("EAP: SRP server verification "
1647 goto client_failure;
1649 GETLONG(esp->es_client.ea_keyflags, inp);
1650 /* Save pseudonym if user wants it. */
1651 if (len > 0 && esp->es_usepseudo) {
1652 INCPTR(SHA_DIGESTSIZE, inp);
1653 write_pseudonym(esp, inp, len, id);
1657 * We've verified our peer. We're now mostly done,
1658 * except for waiting on the regular EAP Success
1661 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
1664 case EAPSRP_LWRECHALLENGE:
1666 warn("EAP: malformed Lightweight rechallenge");
1671 SHA1Update(&ctxt, vals, 1);
1672 SHA1Update(&ctxt, esp->es_client.ea_skey,
1674 SHA1Update(&ctxt, inp, len);
1675 SHA1Update(&ctxt, esp->es_client.ea_name,
1676 esp->es_client.ea_namelen);
1677 SHA1Final(dig, &ctxt);
1678 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
1683 error("EAP: unknown SRP Subtype %d", vallen);
1684 eap_send_nak(esp, id, EAPT_MD5CHAP);
1688 #endif /* USE_SRP */
1691 info("EAP: unknown authentication type %d; Naking", typenum);
1692 eap_send_nak(esp, id, EAPT_SRP);
1696 if (esp->es_client.ea_timeout > 0) {
1697 UNTIMEOUT(eap_client_timeout, (void *)esp);
1698 TIMEOUT(eap_client_timeout, (void *)esp,
1699 esp->es_client.ea_timeout);
1705 esp->es_client.ea_state = eapBadAuth;
1706 if (esp->es_client.ea_timeout > 0) {
1707 UNTIMEOUT(eap_client_timeout, (void *)esp);
1709 esp->es_client.ea_session = NULL;
1711 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1712 #endif /* USE_SRP */
1716 * eap_response - Receive EAP Response message (server mode).
1719 eap_response(esp, inp, id, len)
1728 char secret[MAXSECRETLEN];
1729 char rhostname[256];
1731 u_char hash[MD5_SIGNATURE_SIZE];
1733 struct t_server *ts;
1736 u_char dig[SHA_DIGESTSIZE];
1737 #endif /* USE_SRP */
1739 if (esp->es_server.ea_id != id) {
1740 dbglog("EAP: discarding Response %d; expected ID %d", id,
1741 esp->es_server.ea_id);
1745 esp->es_server.ea_responses++;
1748 error("EAP: empty Response message discarded");
1752 GETCHAR(typenum, inp);
1757 if (esp->es_server.ea_state != eapIdentify) {
1758 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
1762 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
1763 if (esp->es_server.ea_peer != NULL &&
1764 esp->es_server.ea_peer != remote_name)
1765 free(esp->es_server.ea_peer);
1766 esp->es_server.ea_peer = malloc(len + 1);
1767 if (esp->es_server.ea_peer == NULL) {
1768 esp->es_server.ea_peerlen = 0;
1769 eap_figure_next_state(esp, 1);
1772 BCOPY(inp, esp->es_server.ea_peer, len);
1773 esp->es_server.ea_peer[len] = '\0';
1774 esp->es_server.ea_peerlen = len;
1775 eap_figure_next_state(esp, 0);
1778 case EAPT_NOTIFICATION:
1779 dbglog("EAP unexpected Notification; response discarded");
1784 info("EAP: Nak Response with no suggested protocol");
1785 eap_figure_next_state(esp, 1);
1789 GETCHAR(vallen, inp);
1792 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
1793 /* Peer cannot Nak Identify Request */
1794 eap_figure_next_state(esp, 1);
1800 /* Run through SRP validator selection again. */
1801 esp->es_server.ea_state = eapIdentify;
1802 eap_figure_next_state(esp, 0);
1806 esp->es_server.ea_state = eapMD5Chall;
1810 dbglog("EAP: peer requesting unknown Type %d", vallen);
1811 switch (esp->es_server.ea_state) {
1815 esp->es_server.ea_state = eapMD5Chall;
1819 esp->es_server.ea_state = eapIdentify;
1820 eap_figure_next_state(esp, 0);
1830 if (esp->es_server.ea_state != eapMD5Chall) {
1831 error("EAP: unexpected MD5-Response");
1832 eap_figure_next_state(esp, 1);
1836 error("EAP: received MD5-Response with no data");
1837 eap_figure_next_state(esp, 1);
1840 GETCHAR(vallen, inp);
1842 if (vallen != 16 || vallen > len) {
1843 error("EAP: MD5-Response with bad length %d", vallen);
1844 eap_figure_next_state(esp, 1);
1848 /* Not so likely to happen. */
1849 if (len - vallen >= sizeof (rhostname)) {
1850 dbglog("EAP: trimming really long peer name down");
1851 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1852 rhostname[sizeof (rhostname) - 1] = '\0';
1854 BCOPY(inp + vallen, rhostname, len - vallen);
1855 rhostname[len - vallen] = '\0';
1858 /* In case the remote doesn't give us his name. */
1859 if (explicit_remote ||
1860 (remote_name[0] != '\0' && vallen == len))
1861 strlcpy(rhostname, remote_name, sizeof (rhostname));
1864 * Get the secret for authenticating the specified
1867 if (!get_secret(esp->es_unit, rhostname,
1868 esp->es_server.ea_name, secret, &secret_len, 1)) {
1869 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
1870 eap_send_failure(esp);
1873 MD5_Init(&mdContext);
1874 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
1875 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1876 BZERO(secret, sizeof (secret));
1877 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
1878 MD5_Final(hash, &mdContext);
1879 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
1880 eap_send_failure(esp);
1883 esp->es_server.ea_type = EAPT_MD5CHAP;
1884 eap_send_success(esp);
1885 eap_figure_next_state(esp, 0);
1886 if (esp->es_rechallenge != 0)
1887 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
1893 error("EAP: empty SRP Response");
1894 eap_figure_next_state(esp, 1);
1897 GETCHAR(typenum, inp);
1901 if (esp->es_server.ea_state != eapSRP1) {
1902 error("EAP: unexpected SRP Subtype 1 Response");
1903 eap_figure_next_state(esp, 1);
1908 ts = (struct t_server *)esp->es_server.ea_session;
1910 esp->es_server.ea_skey = t_servergetkey(ts, &A);
1911 if (esp->es_server.ea_skey == NULL) {
1912 /* Client's A value is bogus; terminate now */
1913 error("EAP: bogus A value from client");
1914 eap_send_failure(esp);
1916 eap_figure_next_state(esp, 0);
1920 case EAPSRP_CVALIDATOR:
1921 if (esp->es_server.ea_state != eapSRP2) {
1922 error("EAP: unexpected SRP Subtype 2 Response");
1923 eap_figure_next_state(esp, 1);
1926 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
1927 error("EAP: M1 length %d < %d", len,
1928 sizeof (u_int32_t) + SHA_DIGESTSIZE);
1929 eap_figure_next_state(esp, 1);
1932 GETLONG(esp->es_server.ea_keyflags, inp);
1933 ts = (struct t_server *)esp->es_server.ea_session;
1935 if (t_serververify(ts, inp)) {
1936 info("EAP: unable to validate client identity");
1937 eap_send_failure(esp);
1940 eap_figure_next_state(esp, 0);
1944 if (esp->es_server.ea_state != eapSRP3) {
1945 error("EAP: unexpected SRP Subtype 3 Response");
1946 eap_send_failure(esp);
1949 esp->es_server.ea_type = EAPT_SRP;
1950 eap_send_success(esp);
1951 eap_figure_next_state(esp, 0);
1952 if (esp->es_rechallenge != 0)
1953 TIMEOUT(eap_rechallenge, esp,
1954 esp->es_rechallenge);
1955 if (esp->es_lwrechallenge != 0)
1956 TIMEOUT(srp_lwrechallenge, esp,
1957 esp->es_lwrechallenge);
1960 case EAPSRP_LWRECHALLENGE:
1961 if (esp->es_server.ea_state != eapSRP4) {
1962 info("EAP: unexpected SRP Subtype 4 Response");
1965 if (len != SHA_DIGESTSIZE) {
1966 error("EAP: bad Lightweight rechallenge "
1972 SHA1Update(&ctxt, &vallen, 1);
1973 SHA1Update(&ctxt, esp->es_server.ea_skey,
1975 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
1976 SHA1Update(&ctxt, esp->es_server.ea_peer,
1977 esp->es_server.ea_peerlen);
1978 SHA1Final(dig, &ctxt);
1979 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
1980 error("EAP: failed Lightweight rechallenge");
1981 eap_send_failure(esp);
1984 esp->es_server.ea_state = eapOpen;
1985 if (esp->es_lwrechallenge != 0)
1986 TIMEOUT(srp_lwrechallenge, esp,
1987 esp->es_lwrechallenge);
1991 #endif /* USE_SRP */
1994 /* This can't happen. */
1995 error("EAP: unknown Response type %d; ignored", typenum);
1999 if (esp->es_server.ea_timeout > 0) {
2000 UNTIMEOUT(eap_server_timeout, (void *)esp);
2003 if (esp->es_server.ea_state != eapBadAuth &&
2004 esp->es_server.ea_state != eapOpen) {
2005 esp->es_server.ea_id++;
2006 eap_send_request(esp);
2011 * eap_success - Receive EAP Success message (client mode).
2014 eap_success(esp, inp, id, len)
2020 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
2021 dbglog("EAP unexpected success message in state %s (%d)",
2022 eap_state_name(esp->es_client.ea_state),
2023 esp->es_client.ea_state);
2027 if (esp->es_client.ea_timeout > 0) {
2028 UNTIMEOUT(eap_client_timeout, (void *)esp);
2032 /* This is odd. The spec doesn't allow for this. */
2036 esp->es_client.ea_state = eapOpen;
2037 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2041 * eap_failure - Receive EAP Failure message (client mode).
2044 eap_failure(esp, inp, id, len)
2050 if (!eap_client_active(esp)) {
2051 dbglog("EAP unexpected failure message in state %s (%d)",
2052 eap_state_name(esp->es_client.ea_state),
2053 esp->es_client.ea_state);
2056 if (esp->es_client.ea_timeout > 0) {
2057 UNTIMEOUT(eap_client_timeout, (void *)esp);
2061 /* This is odd. The spec doesn't allow for this. */
2065 esp->es_client.ea_state = eapBadAuth;
2067 error("EAP: peer reports authentication failure");
2068 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2072 * eap_input - Handle received EAP message.
2075 eap_input(unit, inp, inlen)
2080 eap_state *esp = &eap_states[unit];
2085 * Parse header (code, id and length). If packet too short,
2088 if (inlen < EAP_HEADERLEN) {
2089 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2095 if (len < EAP_HEADERLEN || len > inlen) {
2096 error("EAP: packet has illegal length field %d (%d..%d)", len,
2097 EAP_HEADERLEN, inlen);
2100 len -= EAP_HEADERLEN;
2102 /* Dispatch based on message code */
2105 eap_request(esp, inp, id, len);
2109 eap_response(esp, inp, id, len);
2113 eap_success(esp, inp, id, len);
2117 eap_failure(esp, inp, id, len);
2120 default: /* XXX Need code reject */
2121 /* Note: it's not legal to send EAP Nak here. */
2122 warn("EAP: unknown code %d received", code);
2128 * eap_printpkt - print the contents of an EAP packet.
2130 static char *eap_codenames[] = {
2131 "Request", "Response", "Success", "Failure"
2134 static char *eap_typenames[] = {
2135 "Identity", "Notification", "Nak", "MD5-Challenge",
2136 "OTP", "Generic-Token", NULL, NULL,
2137 "RSA", "DSS", "KEA", "KEA-Validate",
2138 "TLS", "Defender", "Windows 2000", "Arcot",
2139 "Cisco", "Nokia", "SRP"
2143 eap_printpkt(inp, inlen, printer, arg)
2146 void (*printer) __P((void *, char *, ...));
2149 int code, id, len, rtype, vallen;
2153 if (inlen < EAP_HEADERLEN)
2159 if (len < EAP_HEADERLEN || len > inlen)
2162 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2163 printer(arg, " %s", eap_codenames[code-1]);
2165 printer(arg, " code=0x%x", code);
2166 printer(arg, " id=0x%x", id);
2167 len -= EAP_HEADERLEN;
2171 printer(arg, " <missing type>");
2174 GETCHAR(rtype, inp);
2177 rtype <= sizeof (eap_typenames) / sizeof (char *))
2178 printer(arg, " %s", eap_typenames[rtype-1]);
2180 printer(arg, " type=0x%x", rtype);
2183 case EAPT_NOTIFICATION:
2185 printer(arg, " <Message ");
2186 print_string((char *)inp, len, printer, arg);
2191 printer(arg, " <No message>");
2198 GETCHAR(vallen, inp);
2202 printer(arg, " <Value%.*B>", vallen, inp);
2203 INCPTR(vallen, inp);
2206 printer(arg, " <Name ");
2207 print_string((char *)inp, len, printer, arg);
2212 printer(arg, " <No name>");
2219 GETCHAR(vallen, inp);
2221 printer(arg, "-%d", vallen);
2223 case EAPSRP_CHALLENGE:
2224 GETCHAR(vallen, inp);
2229 printer(arg, " <Name ");
2230 print_string((char *)inp, vallen, printer,
2234 printer(arg, " <No name>");
2236 INCPTR(vallen, inp);
2238 GETCHAR(vallen, inp);
2242 printer(arg, " <s%.*B>", vallen, inp);
2243 INCPTR(vallen, inp);
2245 GETCHAR(vallen, inp);
2250 printer(arg, " <Default g=2>");
2252 printer(arg, " <g%.*B>", vallen, inp);
2254 INCPTR(vallen, inp);
2257 printer(arg, " <Default N>");
2259 printer(arg, " <N%.*B>", len, inp);
2266 printer(arg, " <B%.*B>", len, inp);
2271 case EAPSRP_SVALIDATOR:
2272 if (len < sizeof (u_int32_t))
2275 len -= sizeof (u_int32_t);
2276 if (uval & SRPVAL_EBIT) {
2278 uval &= ~SRPVAL_EBIT;
2281 printer(arg, " f<%X>", uval);
2283 if ((vallen = len) > SHA_DIGESTSIZE)
2284 vallen = SHA_DIGESTSIZE;
2285 printer(arg, " <M2%.*B%s>", len, inp,
2286 len < SHA_DIGESTSIZE ? "?" : "");
2287 INCPTR(vallen, inp);
2290 printer(arg, " <PN%.*B>", len, inp);
2296 case EAPSRP_LWRECHALLENGE:
2297 printer(arg, " <Challenge%.*B>", len, inp);
2309 GETCHAR(rtype, inp);
2312 rtype <= sizeof (eap_typenames) / sizeof (char *))
2313 printer(arg, " %s", eap_typenames[rtype-1]);
2315 printer(arg, " type=0x%x", rtype);
2319 printer(arg, " <Name ");
2320 print_string((char *)inp, len, printer, arg);
2329 printer(arg, " <missing hint>");
2332 GETCHAR(rtype, inp);
2334 printer(arg, " <Suggested-type %02X", rtype);
2336 rtype < sizeof (eap_typenames) / sizeof (char *))
2337 printer(arg, " (%s)", eap_typenames[rtype-1]);
2343 printer(arg, " <missing length>");
2346 GETCHAR(vallen, inp);
2350 printer(arg, " <Value%.*B>", vallen, inp);
2351 INCPTR(vallen, inp);
2354 printer(arg, " <Name ");
2355 print_string((char *)inp, len, printer, arg);
2360 printer(arg, " <No name>");
2367 GETCHAR(vallen, inp);
2369 printer(arg, "-%d", vallen);
2372 printer(arg, " <A%.*B>", len, inp);
2377 case EAPSRP_CVALIDATOR:
2378 if (len < sizeof (u_int32_t))
2381 len -= sizeof (u_int32_t);
2382 if (uval & SRPVAL_EBIT) {
2384 uval &= ~SRPVAL_EBIT;
2387 printer(arg, " f<%X>", uval);
2389 printer(arg, " <M1%.*B%s>", len, inp,
2390 len == SHA_DIGESTSIZE ? "" : "?");
2398 case EAPSRP_LWRECHALLENGE:
2399 printer(arg, " <Response%.*B%s>", len, inp,
2400 len == SHA_DIGESTSIZE ? "" : "?");
2401 if ((vallen = len) > SHA_DIGESTSIZE)
2402 vallen = SHA_DIGESTSIZE;
2403 INCPTR(vallen, inp);
2411 case EAP_SUCCESS: /* No payload expected for these! */
2416 printer(arg, " <truncated>");
2421 printer(arg, "%8B...", inp);
2423 printer(arg, "%.*B", len, inp);
2426 return (inp - pstart);