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.
47 * Modification by Beniamino Galvani, Mar 2005
48 * Implemented EAP-TLS authentication
60 #include <sys/types.h>
67 #include "pathnames.h"
78 #ifndef SHA_DIGESTSIZE
79 #define SHA_DIGESTSIZE 20
84 #endif /* USE_EAPTLS */
91 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
93 static char *pn_secret = NULL; /* Pseudonym generating secret */
97 * Command-line options.
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" },
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 },
122 * Protocol entry points.
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);
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 */
154 * A well-known 2048 bit modulus.
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
192 /* Local forward declarations. */
193 static void eap_server_timeout (void *arg);
196 * Convert EAP state code to printable string for debug.
199 eap_state_name(enum eap_state_code esc)
201 static const char *state_names[] = { EAP_STATES };
203 return (state_names[(int)esc]);
207 * eap_init - Initialize state for an EAP user. This is currently
208 * called once by main() during start-up.
213 eap_state *esp = &eap_states[unit];
215 BZERO(esp, sizeof (*esp));
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;
223 esp->es_client.ea_using_eaptls = 0;
224 #endif /* USE_EAPTLS */
228 * eap_client_timeout - Give up waiting for the peer to send any
232 eap_client_timeout(void *arg)
234 eap_state *esp = (eap_state *) arg;
236 if (!eap_client_active(esp))
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;
245 * eap_authwithpeer - Authenticate to our peer (behave as client).
247 * Start client state and wait for requests. This is called only
251 eap_authwithpeer(int unit, char *localname)
253 eap_state *esp = &eap_states[unit];
255 /* Save the peer name we're given */
256 esp->es_client.ea_name = localname;
257 esp->es_client.ea_namelen = strlen(localname);
259 esp->es_client.ea_state = eapListen;
262 * Start a timer so that if the other end just goes
263 * silent, we don't sit here waiting forever.
265 if (esp->es_client.ea_timeout > 0)
266 TIMEOUT(eap_client_timeout, (void *)esp,
267 esp->es_client.ea_timeout);
271 * Format a standard EAP Failure message and send it to the peer.
275 eap_send_failure(eap_state *esp)
279 outp = outpacket_buf;
281 MAKEHEADER(outp, PPP_EAP);
283 PUTCHAR(EAP_FAILURE, outp);
284 esp->es_server.ea_id++;
285 PUTCHAR(esp->es_server.ea_id, outp);
286 PUTSHORT(EAP_HEADERLEN, outp);
288 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
290 esp->es_server.ea_state = eapBadAuth;
291 auth_peer_fail(esp->es_unit, PPP_EAP);
295 * Format a standard EAP Success message and send it to the peer.
299 eap_send_success(eap_state *esp)
303 outp = outpacket_buf;
305 MAKEHEADER(outp, PPP_EAP);
307 PUTCHAR(EAP_SUCCESS, outp);
308 esp->es_server.ea_id++;
309 PUTCHAR(esp->es_server.ea_id, outp);
310 PUTSHORT(EAP_HEADERLEN, outp);
312 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
314 auth_peer_success(esp->es_unit, PPP_EAP, 0,
315 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
320 * Set DES key according to pseudonym-generating secret and current
324 pncrypt_setkey(int timeoffs)
329 u_char dig[SHA_DIGESTSIZE];
332 if (pn_secret == NULL)
334 reftime = time(NULL) + timeoffs;
335 tp = localtime(&reftime);
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));
344 static char base64[] =
345 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
353 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
358 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
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];
375 b64flush(struct b64state *bs, u_char *outp)
379 if (bs->bs_offs == 8) {
380 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
381 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
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];
395 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
401 if ((cp = strchr(base64, *inp++)) == NULL)
403 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
406 if (bs->bs_offs >= 8) {
407 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
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.
423 eap_figure_next_state(eap_state *esp, int status)
426 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
428 struct t_confent *tce, mytce;
431 int id, i, plen, toffs;
436 struct eaptls_session *ets;
438 char secret[MAXWORDLEN];
439 #endif /* USE_EAPTLS */
441 esp->es_server.ea_timeout = esp->es_savedtime;
443 esp->es_server.ea_prev_state = esp->es_server.ea_state;
444 #endif /* USE_EAPTLS */
445 switch (esp->es_server.ea_state) {
451 /* Discard any previous session. */
452 ts = (struct t_server *)esp->es_server.ea_session;
455 esp->es_server.ea_session = NULL;
456 esp->es_server.ea_skey = NULL;
460 esp->es_server.ea_state = eapBadAuth;
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 <
470 BZERO(&bs, sizeof (bs));
472 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
473 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
476 for (i = 0; i < 5; i++) {
477 pncrypt_setkey(toffs);
479 if (!DesDecrypt(secbuf, clear)) {
480 dbglog("no DES here; cannot decode "
484 id = *(unsigned char *)clear;
485 if (id + 1 <= plen && id + 9 > plen)
488 if (plen % 8 == 0 && i < 5) {
490 * Note that this is always shorter than the
491 * original stored string, so there's no need
494 if ((i = plen = *(unsigned char *)clear) > 7)
496 esp->es_server.ea_peerlen = plen;
497 dp = (unsigned char *)esp->es_server.ea_peer;
498 BCOPY(clear + 1, dp, i);
503 (void) DesDecrypt(sp, dp);
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);
514 dbglog("failed to decode real name");
515 /* Stay in eapIdentfy state; requery */
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)
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;
535 } else if ((tce = gettcid(id)) != NULL) {
537 * Client will have to verify this modulus/
538 * generator combination, and that will take
539 * a while. Lengthen the timeout here.
541 if (esp->es_server.ea_timeout > 0 &&
542 esp->es_server.ea_timeout < 30)
543 esp->es_server.ea_timeout = 30;
547 if ((cp2 = strchr(cp, ':')) == NULL)
550 tpw.pebuf.name = esp->es_server.ea_peer;
551 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
553 tpw.pebuf.password.data = tpw.pwbuf;
554 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
556 tpw.pebuf.salt.data = tpw.saltbuf;
557 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
559 esp->es_server.ea_session = (void *)ts;
560 esp->es_server.ea_state = eapSRP1;
561 vals[0] = esp->es_server.ea_id + 1;
563 t_serveraddexdata(ts, vals, 2);
564 /* Generate B; must call before t_servergetkey() */
570 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
571 esp->es_server.ea_name, secret, &secret_len, 1)) {
573 esp->es_server.ea_state = eapTlsStart;
576 #endif /* USE_EAPTLS */
578 esp->es_server.ea_state = eapMD5Chall;
583 /* Initialize ssl session */
584 if(!eaptls_init_ssl_server(esp)) {
585 esp->es_server.ea_state = eapBadAuth;
589 esp->es_server.ea_state = eapTlsRecv;
593 ets = (struct eaptls_session *) esp->es_server.ea_session;
595 if(ets->alert_sent) {
596 esp->es_server.ea_state = eapTlsSendAlert;
601 esp->es_server.ea_state = eapBadAuth;
604 ets = (struct eaptls_session *) esp->es_server.ea_session;
607 esp->es_server.ea_state = eapTlsSendAck;
609 esp->es_server.ea_state = eapTlsSend;
613 ets = (struct eaptls_session *) esp->es_server.ea_session;
616 esp->es_server.ea_state = eapTlsRecvAck;
618 if(SSL_is_init_finished(ets->ssl))
619 esp->es_server.ea_state = eapTlsRecvClient;
621 /* JJK Add "TLS empty record" message here ??? */
622 esp->es_server.ea_state = eapTlsRecv;
626 esp->es_server.ea_state = eapTlsRecv;
632 esp->es_server.ea_state = eapBadAuth;
636 esp->es_server.ea_state = eapTlsSend;
639 case eapTlsSendAlert:
640 esp->es_server.ea_state = eapTlsRecvAlertAck;
642 #endif /* USE_EAPTLS */
646 ts = (struct t_server *)esp->es_server.ea_session;
647 if (ts != NULL && status != 0) {
649 esp->es_server.ea_session = NULL;
650 esp->es_server.ea_skey = NULL;
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;
658 esp->es_server.ea_state = eapSRP2;
664 ts = (struct t_server *)esp->es_server.ea_session;
665 if (ts != NULL && status != 0) {
667 esp->es_server.ea_session = NULL;
668 esp->es_server.ea_skey = NULL;
671 if (status != 0 || esp->es_server.ea_session == NULL) {
672 esp->es_server.ea_state = eapBadAuth;
674 esp->es_server.ea_state = eapSRP3;
681 ts = (struct t_server *)esp->es_server.ea_session;
682 if (ts != NULL && status != 0) {
684 esp->es_server.ea_session = NULL;
685 esp->es_server.ea_skey = NULL;
688 if (status != 0 || esp->es_server.ea_session == NULL) {
689 esp->es_server.ea_state = eapBadAuth;
691 esp->es_server.ea_state = eapOpen;
696 case eapMSCHAPv2Chall:
700 esp->es_server.ea_state = eapBadAuth;
702 esp->es_server.ea_state = eapOpen;
707 esp->es_server.ea_state = eapBadAuth;
710 if (esp->es_server.ea_state == eapBadAuth)
711 eap_send_failure(esp);
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 */
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)
725 unsigned char md[MS_CHAP2_RESPONSE_LEN];
726 char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
727 int challenge_len, response_len;
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 */
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);
739 /* compare MDs and send the appropriate status */
741 * Per RFC 2759, success message must be formatted as
742 * "S=<auth_string> M=<message>"
744 * <auth_string> is the Authenticator Response (mutual auth)
745 * <message> is a text message
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.
756 * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
757 * help debugging this.
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);
764 slprintf(message, message_space, "S=%s M=%s",
765 saresponse, "Access granted");
771 * Failure message must be formatted as
772 * "E=e R=r C=c V=v M=m"
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
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.
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).
788 * Basically, this whole bit is useless code, even the small
789 * implementation here is only because of overspecification.
791 slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
792 challenge_len, challenge, "Access denied");
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, */
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.
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)
817 unsigned char secret[MAXSECRETLEN];
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);
826 ok = digest->verify_response(id, name, secret, secret_len, challenge,
827 response, message, message_space);
828 memset(secret, 0, sizeof(secret));
834 * Format and send an CHAPV2-Success/Failure EAP Request message.
837 eap_chapms2_send_request(eap_state *esp, u_char id,
838 u_char opcode, u_char chapid,
839 char *message, int message_len)
844 outp = outpacket_buf;
846 MAKEHEADER(outp, PPP_EAP);
848 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
849 msglen += message_len;
851 PUTCHAR(EAP_REQUEST, outp);
853 PUTSHORT(msglen, outp);
854 PUTCHAR(EAPT_MSCHAPV2, outp);
855 PUTCHAR(opcode, outp);
856 PUTCHAR(chapid, outp);
858 PUTSHORT(msglen - 5, outp);
859 BCOPY(message, outp, message_len);
861 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
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);
868 esp->es_server.ea_state = eapBadAuth;
869 auth_peer_fail(esp->es_unit, PPP_EAP);
875 * Format an EAP Request message and send it to the peer. Message
876 * type depends on current state. (Server operation)
879 eap_send_request(eap_state *esp)
889 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
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) {
901 * If we already know the peer's
902 * unauthenticated name, then there's no
903 * reason to ask. Go to next state instead.
905 esp->es_server.ea_peer = remote_name;
906 esp->es_server.ea_peerlen = strlen(remote_name);
907 eap_figure_next_state(esp, 0);
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");
916 error("EAP: no response to Requests");
917 eap_send_failure(esp);
921 outp = outpacket_buf;
923 MAKEHEADER(outp, PPP_EAP);
925 PUTCHAR(EAP_REQUEST, outp);
926 PUTCHAR(esp->es_server.ea_id, outp);
930 switch (esp->es_server.ea_state) {
932 PUTCHAR(EAPT_IDENTITY, outp);
934 challen = strlen(str);
935 BCOPY(str, outp, challen);
936 INCPTR(challen, outp);
940 PUTCHAR(EAPT_MD5CHAP, outp);
942 * pick a random challenge length between
943 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
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);
960 case eapMSCHAPv2Chall:
962 esp->es_challen = challen;
963 esp->es_challenge[0] = challen;
964 random_bytes(&esp->es_challenge[1], challen);
966 PUTCHAR(EAPT_MSCHAPV2, outp);
967 PUTCHAR(CHAP_CHALLENGE, outp);
968 PUTCHAR(esp->es_server.ea_id, outp);
970 PUTSHORT(5 + challen +
971 esp->es_server.ea_namelen,
973 /* challen + challenge */
974 BCOPY(esp->es_challenge, outp, challen+1);
975 INCPTR(challen+1, outp);
976 BCOPY(esp->es_server.ea_name,
978 esp->es_server.ea_namelen);
979 INCPTR(esp->es_server.ea_namelen, outp);
985 PUTCHAR(EAPT_TLS, outp);
986 PUTCHAR(EAP_TLS_FLAGS_START, outp);
987 eap_figure_next_state(esp, 0);
991 eaptls_send(esp->es_server.ea_session, &outp);
992 eap_figure_next_state(esp, 0);
996 PUTCHAR(EAPT_TLS, outp);
998 eap_figure_next_state(esp, 0);
1001 case eapTlsSendAlert:
1002 eaptls_send(esp->es_server.ea_session, &outp);
1003 eap_figure_next_state(esp, 0);
1005 #endif /* USE_EAPTLS */
1009 PUTCHAR(EAPT_SRP, outp);
1010 PUTCHAR(EAPSRP_CHALLENGE, outp);
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);
1016 ts = (struct t_server *)esp->es_server.ea_session;
1018 PUTCHAR(ts->s.len, outp);
1019 BCOPY(ts->s.data, outp, ts->s.len);
1020 INCPTR(ts->s.len, outp);
1022 if (ts->g.len == 1 && ts->g.data[0] == 2) {
1025 PUTCHAR(ts->g.len, outp);
1026 BCOPY(ts->g.data, outp, ts->g.len);
1027 INCPTR(ts->g.len, outp);
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);
1038 PUTCHAR(EAPT_SRP, outp);
1039 PUTCHAR(EAPSRP_SKEY, outp);
1041 ts = (struct t_server *)esp->es_server.ea_session;
1043 BCOPY(ts->B.data, outp, ts->B.len);
1044 INCPTR(ts->B.len, outp);
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;
1053 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
1054 INCPTR(SHA_DIGESTSIZE, outp);
1056 if (pncrypt_setkey(0)) {
1057 /* Generate pseudonym */
1059 cp = (unsigned char *)esp->es_server.ea_peer;
1060 if ((j = i = esp->es_server.ea_peerlen) > 7)
1063 BCOPY(cp, clear + 1, j);
1066 if (!DesEncrypt(clear, cipher)) {
1067 dbglog("no DES here; not generating pseudonym");
1070 BZERO(&b64, sizeof (b64));
1071 outp++; /* space for pseudonym length */
1072 outp += b64enc(&b64, cipher, 8, outp);
1074 (void) DesEncrypt(cp, cipher);
1075 outp += b64enc(&b64, cipher, 8, outp);
1080 BCOPY(cp, clear, i);
1083 *cp++ = drand48() * 0x100;
1086 (void) DesEncrypt(clear, cipher);
1087 outp += b64enc(&b64, cipher, 8, outp);
1089 outp += b64flush(&b64, outp);
1091 /* Set length and pad out to next 20 octet boundary */
1092 i = outp - optr - 1;
1094 i %= SHA_DIGESTSIZE;
1096 while (i < SHA_DIGESTSIZE) {
1097 *outp++ = drand48() * 0x100;
1102 /* Obscure the pseudonym with SHA1 hash */
1104 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1105 SHA1Update(&ctxt, esp->es_server.ea_skey,
1107 SHA1Update(&ctxt, esp->es_server.ea_peer,
1108 esp->es_server.ea_peerlen);
1109 while (optr < outp) {
1110 SHA1Final(dig, &ctxt);
1112 while (cp < dig + SHA_DIGESTSIZE)
1115 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1116 SHA1Update(&ctxt, esp->es_server.ea_skey,
1118 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
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);
1136 #endif /* USE_SRP */
1142 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1143 PUTSHORT(outlen, lenloc);
1145 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1147 esp->es_server.ea_requests++;
1149 if (esp->es_server.ea_timeout > 0)
1150 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1154 * eap_authpeer - Authenticate our peer (behave as server).
1156 * Start server state and send first request. This is called only
1157 * after eap_lowerup.
1160 eap_authpeer(int unit, char *localname)
1162 eap_state *esp = &eap_states[unit];
1164 /* Save the name we're given. */
1165 esp->es_server.ea_name = localname;
1166 esp->es_server.ea_namelen = strlen(localname);
1168 esp->es_savedtime = esp->es_server.ea_timeout;
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;
1177 esp->es_server.ea_state = eapPending;
1179 /* ID number not updated here intentionally; hashed into M1 */
1180 eap_send_request(esp);
1184 * eap_server_timeout - Retransmission timer for sending Requests
1188 eap_server_timeout(void *arg)
1194 #endif /* USE_EAPTLS */
1196 eap_state *esp = (eap_state *) arg;
1198 if (!eap_server_active(esp))
1202 switch(esp->es_server.ea_prev_state) {
1205 * In eap-tls the state changes after a request, so we return to
1206 * previous state ...
1209 case(eapTlsSendAck):
1210 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1214 * ... or resend the stored data
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);
1225 eaptls_retransmit(esp->es_server.ea_session, &outp);
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++;
1232 if (esp->es_server.ea_timeout > 0)
1233 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1239 #endif /* USE_EAPTLS */
1241 /* EAP ID number must not change on timeout. */
1242 eap_send_request(esp);
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.
1251 eap_rechallenge(void *arg)
1253 eap_state *esp = (eap_state *)arg;
1255 if (esp->es_server.ea_state != eapOpen &&
1256 esp->es_server.ea_state != eapSRP4)
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);
1267 srp_lwrechallenge(void *arg)
1269 eap_state *esp = (eap_state *)arg;
1271 if (esp->es_server.ea_state != eapOpen ||
1272 esp->es_server.ea_type != EAPT_SRP)
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);
1282 * eap_lowerup - The lower layer is now up.
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
1290 eap_lowerup(int unit)
1292 eap_state *esp = &eap_states[unit];
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;
1303 esp->es_client.ea_state = eapClosed;
1304 esp->es_server.ea_state = eapClosed;
1308 * eap_lowerdown - The lower layer is now down.
1310 * Cancel all timeouts and return to initial state.
1313 eap_lowerdown(int unit)
1315 eap_state *esp = &eap_states[unit];
1317 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1318 UNTIMEOUT(eap_client_timeout, (void *)esp);
1320 if (eap_server_active(esp)) {
1321 if (esp->es_server.ea_timeout > 0) {
1322 UNTIMEOUT(eap_server_timeout, (void *)esp);
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);
1330 if (esp->es_server.ea_state == eapOpen &&
1331 esp->es_lwrechallenge > 0) {
1332 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1336 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1337 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1341 * eap_protrej - Peer doesn't speak this protocol.
1343 * This shouldn't happen. If it does, it represents authentication
1347 eap_protrej(int unit)
1349 eap_state *esp = &eap_states[unit];
1351 if (eap_client_active(esp)) {
1352 error("EAP authentication failed due to Protocol-Reject");
1353 auth_withpeer_fail(unit, PPP_EAP);
1355 if (eap_server_active(esp)) {
1356 error("EAP authentication of peer failed on Protocol-Reject");
1357 auth_peer_fail(unit, PPP_EAP);
1359 eap_lowerdown(unit);
1363 * Format and send a regular EAP Response message.
1366 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1367 u_char *str, int lenstr)
1372 outp = outpacket_buf;
1374 MAKEHEADER(outp, PPP_EAP);
1376 PUTCHAR(EAP_RESPONSE, outp);
1378 esp->es_client.ea_id = id;
1379 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1380 PUTSHORT(msglen, outp);
1381 PUTCHAR(typenum, outp);
1383 BCOPY(str, outp, lenstr);
1386 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1390 * Format and send an MD5-Challenge EAP Response message.
1393 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1394 char *name, int namelen)
1399 outp = outpacket_buf;
1401 MAKEHEADER(outp, PPP_EAP);
1403 PUTCHAR(EAP_RESPONSE, outp);
1405 esp->es_client.ea_id = id;
1406 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
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);
1414 BCOPY(name, outp, namelen);
1417 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1422 * Format and send a SRP EAP Response message.
1425 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1426 u_char *str, int lenstr)
1431 outp = outpacket_buf;
1433 MAKEHEADER(outp, PPP_EAP);
1435 PUTCHAR(EAP_RESPONSE, 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);
1443 BCOPY(str, outp, lenstr);
1446 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1450 * Format and send a SRP EAP Client Validator Response message.
1453 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1458 outp = outpacket_buf;
1460 MAKEHEADER(outp, PPP_EAP);
1462 PUTCHAR(EAP_RESPONSE, outp);
1464 esp->es_client.ea_id = id;
1465 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1467 PUTSHORT(msglen, outp);
1468 PUTCHAR(EAPT_SRP, outp);
1469 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1470 PUTLONG(flags, outp);
1471 BCOPY(str, outp, SHA_DIGESTSIZE);
1473 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1475 #endif /* USE_SRP */
1479 * Send an EAP-TLS response message with tls data
1482 eap_tls_response(eap_state *esp, u_char id)
1488 outp = outpacket_buf;
1490 MAKEHEADER(outp, PPP_EAP);
1492 PUTCHAR(EAP_RESPONSE, outp);
1499 If the id in the request is unchanged, we must retransmit
1502 if(id == esp->es_client.ea_id)
1503 eaptls_retransmit(esp->es_client.ea_session, &outp);
1505 eaptls_send(esp->es_client.ea_session, &outp);
1507 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1508 PUTSHORT(outlen, lenloc);
1510 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1512 esp->es_client.ea_id = id;
1516 * Send an EAP-TLS ack
1519 eap_tls_sendack(eap_state *esp, u_char id)
1525 outp = outpacket_buf;
1527 MAKEHEADER(outp, PPP_EAP);
1529 PUTCHAR(EAP_RESPONSE, outp);
1531 esp->es_client.ea_id = id;
1536 PUTCHAR(EAPT_TLS, outp);
1539 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1540 PUTSHORT(outlen, lenloc);
1542 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1544 #endif /* USE_EAPTLS */
1547 eap_send_nak(eap_state *esp, u_char id, u_char type)
1552 outp = outpacket_buf;
1554 MAKEHEADER(outp, PPP_EAP);
1556 PUTCHAR(EAP_RESPONSE, 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);
1564 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1569 name_of_pn_file(void)
1571 char *user, *path, *file;
1574 static bool pnlogged = 0;
1576 pw = getpwuid(getuid());
1577 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1581 file = _PATH_PSEUDONYM;
1582 pl = strlen(user) + strlen(file) + 2;
1586 (void) slprintf(path, pl, "%s/%s", user, file);
1588 dbglog("pseudonym file: %s", path);
1595 open_pn_file(mode_t modebits)
1600 if ((path = name_of_pn_file()) == NULL)
1602 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1610 remove_pn_file(void)
1614 if ((path = name_of_pn_file()) != NULL) {
1615 (void) unlink(path);
1621 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1624 u_char *datp, *digp;
1626 u_char dig[SHA_DIGESTSIZE];
1627 int dsize, fd, olen = len;
1630 * Do the decoding by working backwards. This eliminates the need
1631 * to save the decoded output in a separate buffer.
1635 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1636 dsize = SHA_DIGESTSIZE;
1640 SHA1Update(&ctxt, &val, 1);
1641 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1643 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1645 SHA1Update(&ctxt, esp->es_client.ea_name,
1646 esp->es_client.ea_namelen);
1648 SHA1Final(dig, &ctxt);
1649 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
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);
1660 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1662 dbglog("EAP: error saving pseudonym: %m");
1665 len = write(fd, inp + 1, *inp);
1666 if (close(fd) != -1 && len == *inp) {
1667 dbglog("EAP: saved pseudonym");
1668 esp->es_usedpseudo = 0;
1670 dbglog("EAP: failed to save pseudonym");
1674 #endif /* USE_SRP */
1677 * eap_request - Receive EAP Request message (client mode).
1680 eap_request(eap_state *esp, u_char *inp, int id, int len)
1685 char secret[MAXWORDLEN];
1686 char rhostname[256];
1688 u_char hash[MD5_SIGNATURE_SIZE];
1691 struct eaptls_session *ets = esp->es_client.ea_session;
1692 #endif /* USE_EAPTLS */
1695 struct t_client *tc;
1696 struct t_num sval, gval, Nval, *Ap, Bval;
1699 u_char dig[SHA_DIGESTSIZE];
1701 #endif /* USE_SRP */
1704 * Ignore requests if we're not open
1706 if (esp->es_client.ea_state <= eapClosed)
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.
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);
1722 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1727 error("EAP: empty Request message discarded");
1731 GETCHAR(typenum, inp);
1737 info("EAP: Identity prompt \"%.*q\"", len, inp);
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 */
1751 eap_send_response(esp, id, typenum,
1752 rhostname, len + SRP_PSEUDO_LEN);
1759 /* Stop using pseudonym now. */
1760 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1762 esp->es_usedpseudo = 2;
1764 #endif /* USE_SRP */
1765 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1766 esp->es_client.ea_namelen);
1769 case EAPT_NOTIFICATION:
1771 info("EAP: Notification \"%.*q\"", len, inp);
1772 eap_send_response(esp, id, typenum, NULL, 0);
1777 * Avoid the temptation to send Response Nak in reply
1778 * to Request Nak here. It can only lead to trouble.
1780 warn("EAP: unexpected Nak in Request; ignored");
1781 /* Return because we're waiting for something real. */
1786 error("EAP: received MD5-Challenge with no data");
1787 /* Bogus request; wait for something real. */
1790 GETCHAR(vallen, inp);
1792 if (vallen < 8 || vallen > len) {
1793 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1795 /* Try something better. */
1796 eap_send_nak(esp, id, EAPT_SRP);
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';
1806 BCOPY(inp + vallen, rhostname, len - vallen);
1807 rhostname[len - vallen] = '\0';
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));
1816 * Get the secret for authenticating ourselves with
1817 * the specified host.
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);
1825 MD5_Init(&mdContext);
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);
1839 switch(esp->es_client.ea_state) {
1844 error("EAP: received EAP-TLS Listen packet with no data");
1845 /* Bogus request; wait for something real. */
1848 GETCHAR(flags, inp);
1849 if(flags & EAP_TLS_FLAGS_START){
1851 esp->es_client.ea_using_eaptls = 1;
1853 if (explicit_remote){
1854 esp->es_client.ea_peer = strdup(remote_name);
1855 esp->es_client.ea_peerlen = strlen(remote_name);
1857 esp->es_client.ea_peer = NULL;
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;
1867 ets = esp->es_client.ea_session;
1868 eap_tls_response(esp, id);
1869 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1873 /* The server has sent a bad start packet. */
1874 eap_send_nak(esp, id, EAPT_TLS);
1878 eap_tls_response(esp, id);
1879 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1884 error("EAP: discarding EAP-TLS Receive packet with no data");
1885 /* Bogus request; wait for something real. */
1888 eaptls_receive(ets, inp, len);
1891 eap_tls_sendack(esp, id);
1892 esp->es_client.ea_state = eapTlsRecv;
1896 if(ets->alert_recv) {
1897 eap_tls_sendack(esp, id);
1898 esp->es_client.ea_state = eapTlsRecvFailure;
1902 /* Check if TLS handshake is finished */
1903 if(eaptls_is_init_finished(ets)) {
1905 eaptls_gen_mppe_keys(ets, 1);
1907 eaptls_free_session(ets);
1908 eap_tls_sendack(esp, id);
1909 esp->es_client.ea_state = eapTlsRecvSuccess;
1913 eap_tls_response(esp,id);
1914 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1918 eap_send_nak(esp, id, EAPT_TLS);
1919 esp->es_client.ea_using_eaptls = 0;
1924 #endif /* USE_EAPTLS */
1929 error("EAP: received empty SRP Request");
1930 /* Bogus request; wait for something real. */
1935 GETCHAR(vallen, inp);
1938 case EAPSRP_CHALLENGE:
1940 if (esp->es_client.ea_session != NULL) {
1941 tc = (struct t_client *)esp->es_client.
1944 * If this is a new challenge, then start
1945 * over with a new client session context.
1946 * Otherwise, just resend last response.
1948 if (id != esp->es_client.ea_id) {
1950 esp->es_client.ea_session = NULL;
1954 /* No session key just yet */
1955 esp->es_client.ea_skey = NULL;
1957 GETCHAR(vallen, inp);
1959 if (vallen >= len) {
1960 error("EAP: badly-formed SRP Challenge"
1962 /* Ignore badly-formed messages */
1965 BCOPY(inp, rhostname, vallen);
1966 rhostname[vallen] = '\0';
1967 INCPTR(vallen, inp);
1971 * In case the remote doesn't give us his name,
1972 * use configured name.
1974 if (explicit_remote ||
1975 (remote_name[0] != '\0' && vallen == 0)) {
1976 strlcpy(rhostname, remote_name,
1977 sizeof (rhostname));
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);
1985 GETCHAR(vallen, inp);
1987 if (vallen >= len) {
1988 error("EAP: badly-formed SRP Challenge"
1990 /* Ignore badly-formed messages */
1995 INCPTR(vallen, inp);
1998 GETCHAR(vallen, inp);
2001 error("EAP: badly-formed SRP Challenge"
2003 /* Ignore badly-formed messages */
2006 /* If no generator present, then use value 2 */
2008 gval.data = (u_char *)"\002";
2014 INCPTR(vallen, inp);
2018 * If no modulus present, then use well-known
2022 Nval.data = (u_char *)wkmodulus;
2023 Nval.len = sizeof (wkmodulus);
2028 tc = t_clientopen(esp->es_client.ea_name,
2029 &Nval, &gval, &sval);
2031 eap_send_nak(esp, id, EAPT_MD5CHAP);
2034 esp->es_client.ea_session = (void *)tc;
2036 /* Add Challenge ID & type to verifier */
2039 t_clientaddexdata(tc, vals, 2);
2041 Ap = t_clientgenexp(tc);
2042 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2047 tc = (struct t_client *)esp->es_client.ea_session;
2049 warn("EAP: peer sent Subtype 2 without 1");
2050 eap_send_nak(esp, id, EAPT_MD5CHAP);
2053 if (esp->es_client.ea_skey != NULL) {
2055 * ID number should not change here. Warn
2056 * if it does (but otherwise ignore).
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);
2064 if (get_srp_secret(esp->es_unit,
2065 esp->es_client.ea_name,
2066 esp->es_client.ea_peer, secret, 0) == 0) {
2068 * Can't work with this peer because
2069 * the secret is missing. Just give
2072 eap_send_nak(esp, id, EAPT_MD5CHAP);
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;
2087 eap_srpval_response(esp, id, SRPVAL_EBIT,
2088 t_clientresponse(tc));
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);
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.
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);
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 "
2115 goto client_failure;
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);
2125 * We've verified our peer. We're now mostly done,
2126 * except for waiting on the regular EAP Success
2129 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2132 case EAPSRP_LWRECHALLENGE:
2134 warn("EAP: malformed Lightweight rechallenge");
2139 SHA1Update(&ctxt, vals, 1);
2140 SHA1Update(&ctxt, esp->es_client.ea_skey,
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,
2151 error("EAP: unknown SRP Subtype %d", vallen);
2152 eap_send_nak(esp, id, EAPT_MD5CHAP);
2156 #endif /* USE_SRP */
2159 info("EAP: unknown authentication type %d; Naking", typenum);
2160 eap_send_nak(esp, id, EAPT_SRP);
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);
2173 esp->es_client.ea_state = eapBadAuth;
2174 if (esp->es_client.ea_timeout > 0) {
2175 UNTIMEOUT(eap_client_timeout, (void *)esp);
2177 esp->es_client.ea_session = NULL;
2179 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2180 #endif /* USE_SRP */
2184 * eap_response - Receive EAP Response message (server mode).
2187 eap_response(eap_state *esp, u_char *inp, int id, int len)
2192 char secret[MAXSECRETLEN];
2193 char rhostname[256];
2195 u_char hash[MD5_SIGNATURE_SIZE];
2197 struct t_server *ts;
2200 u_char dig[SHA_DIGESTSIZE];
2202 u_char dig[SHA_DIGESTSIZE];
2203 #endif /* USE_SRP */
2206 struct eaptls_session *ets;
2208 #endif /* USE_EAPTLS */
2211 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2212 unsigned char *, unsigned char *, char *, int);
2213 char response_message[256];
2217 * Ignore responses if we're not open
2219 if (esp->es_server.ea_state <= eapClosed)
2222 if (esp->es_server.ea_id != id) {
2223 dbglog("EAP: discarding Response %d; expected ID %d", id,
2224 esp->es_server.ea_id);
2228 esp->es_server.ea_responses++;
2231 error("EAP: empty Response message discarded");
2235 GETCHAR(typenum, inp);
2240 if (esp->es_server.ea_state != eapIdentify) {
2241 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
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);
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);
2263 switch(esp->es_server.ea_state) {
2267 ets = (struct eaptls_session *) esp->es_server.ea_session;
2269 eap_figure_next_state(esp,
2270 eaptls_receive(esp->es_server.ea_session, inp, len));
2272 if(ets->alert_recv) {
2273 eap_send_failure(esp);
2280 dbglog("EAP-TLS ACK with extra data");
2282 eap_figure_next_state(esp, 0);
2285 case eapTlsRecvClient:
2286 /* Receive authentication response from client */
2288 GETCHAR(flags, inp);
2290 if(len == 1 && !flags) { /* Ack = ok */
2292 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2294 eap_send_success(esp);
2296 else { /* failure */
2297 warn("Server authentication failed");
2298 eap_send_failure(esp);
2302 warn("Bogus EAP-TLS packet received from client");
2304 eaptls_free_session(esp->es_server.ea_session);
2308 case eapTlsRecvAlertAck:
2309 eap_send_failure(esp);
2313 eap_figure_next_state(esp, 1);
2317 #endif /* USE_EAPTLS */
2319 case EAPT_NOTIFICATION:
2320 dbglog("EAP unexpected Notification; response discarded");
2325 info("EAP: Nak Response with no suggested protocol");
2326 eap_figure_next_state(esp, 1);
2330 GETCHAR(vallen, inp);
2333 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2334 /* Peer cannot Nak Identify Request */
2335 eap_figure_next_state(esp, 1);
2341 /* Run through SRP validator selection again. */
2342 esp->es_server.ea_state = eapIdentify;
2343 eap_figure_next_state(esp, 0);
2347 esp->es_server.ea_state = eapMD5Chall;
2351 /* Send EAP-TLS start packet */
2353 esp->es_server.ea_state = eapTlsStart;
2355 #endif /* USE_EAPTLS */
2359 info("EAP: peer proposes MSCHAPv2");
2360 esp->es_server.ea_state = eapMSCHAPv2Chall;
2365 dbglog("EAP: peer requesting unknown Type %d", vallen);
2366 switch (esp->es_server.ea_state) {
2370 esp->es_server.ea_state = eapMD5Chall;
2374 esp->es_server.ea_state = eapIdentify;
2375 eap_figure_next_state(esp, 0);
2385 if (esp->es_server.ea_state != eapMD5Chall) {
2386 error("EAP: unexpected MD5-Response");
2387 eap_figure_next_state(esp, 1);
2391 error("EAP: received MD5-Response with no data");
2392 eap_figure_next_state(esp, 1);
2395 GETCHAR(vallen, inp);
2397 if (vallen != 16 || vallen > len) {
2398 error("EAP: MD5-Response with bad length %d", vallen);
2399 eap_figure_next_state(esp, 1);
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';
2409 BCOPY(inp + vallen, rhostname, len - vallen);
2410 rhostname[len - vallen] = '\0';
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));
2419 * Get the secret for authenticating the specified
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);
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);
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);
2448 error("EAP: received MSCHAPv2 with no data");
2449 eap_figure_next_state(esp, 1);
2452 GETCHAR(opcode, inp);
2457 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2458 error("EAP: unexpected MSCHAPv2-Response");
2459 eap_figure_next_state(esp, 1);
2462 /* skip MS ID + len */
2464 GETCHAR(vallen, inp);
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);
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';
2480 BCOPY(inp + vallen, rhostname, len - vallen);
2481 rhostname[len - vallen] = '\0';
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));
2489 if (chap_verify_hook)
2490 chap_verifier = chap_verify_hook;
2492 chap_verifier = eap_chap_verify_response;
2494 esp->es_server.ea_id += 1;
2495 if ((*chap_verifier)(rhostname,
2496 esp->es_server.ea_name,
2498 &eap_chapms2_digest,
2502 sizeof(response_message)))
2504 info("EAP: MSCHAPv2 success for peer %q",
2506 esp->es_server.ea_type = EAPT_MSCHAPV2;
2507 eap_chapms2_send_request(esp,
2508 esp->es_server.ea_id,
2510 esp->es_server.ea_id,
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);
2518 warn("EAP: MSCHAPv2 failure for peer %q",
2520 eap_chapms2_send_request(esp,
2521 esp->es_server.ea_id,
2523 esp->es_server.ea_id,
2525 strlen(response_message));
2529 info("EAP: MSCHAPv2 success confirmed");
2532 info("EAP: MSCHAPv2 failure confirmed");
2535 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2536 eap_send_nak(esp, id, EAPT_SRP);
2545 error("EAP: empty SRP Response");
2546 eap_figure_next_state(esp, 1);
2549 GETCHAR(typenum, inp);
2553 if (esp->es_server.ea_state != eapSRP1) {
2554 error("EAP: unexpected SRP Subtype 1 Response");
2555 eap_figure_next_state(esp, 1);
2560 ts = (struct t_server *)esp->es_server.ea_session;
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);
2568 eap_figure_next_state(esp, 0);
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);
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);
2584 GETLONG(esp->es_server.ea_keyflags, inp);
2585 ts = (struct t_server *)esp->es_server.ea_session;
2587 if (t_serververify(ts, inp)) {
2588 info("EAP: unable to validate client identity");
2589 eap_send_failure(esp);
2592 eap_figure_next_state(esp, 0);
2596 if (esp->es_server.ea_state != eapSRP3) {
2597 error("EAP: unexpected SRP Subtype 3 Response");
2598 eap_send_failure(esp);
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);
2612 case EAPSRP_LWRECHALLENGE:
2613 if (esp->es_server.ea_state != eapSRP4) {
2614 info("EAP: unexpected SRP Subtype 4 Response");
2617 if (len != SHA_DIGESTSIZE) {
2618 error("EAP: bad Lightweight rechallenge "
2624 SHA1Update(&ctxt, &vallen, 1);
2625 SHA1Update(&ctxt, esp->es_server.ea_skey,
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);
2636 esp->es_server.ea_state = eapOpen;
2637 if (esp->es_lwrechallenge != 0)
2638 TIMEOUT(srp_lwrechallenge, esp,
2639 esp->es_lwrechallenge);
2643 #endif /* USE_SRP */
2646 /* This can't happen. */
2647 error("EAP: unknown Response type %d; ignored", typenum);
2651 if (esp->es_server.ea_timeout > 0) {
2652 UNTIMEOUT(eap_server_timeout, (void *)esp);
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);
2663 * eap_success - Receive EAP Success message (client mode).
2666 eap_success(eap_state *esp, u_char *inp, int id, int len)
2668 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2670 && esp->es_client.ea_state != eapTlsRecvSuccess
2671 #endif /* USE_EAPTLS */
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);
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);
2687 #endif /* USE_EAPTLS */
2689 if (esp->es_client.ea_timeout > 0) {
2690 UNTIMEOUT(eap_client_timeout, (void *)esp);
2694 /* This is odd. The spec doesn't allow for this. */
2698 esp->es_client.ea_state = eapOpen;
2699 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2703 * eap_failure - Receive EAP Failure message (client mode).
2706 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2709 * Ignore failure messages if we're not open
2711 if (esp->es_client.ea_state <= eapClosed)
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);
2720 if (esp->es_client.ea_timeout > 0) {
2721 UNTIMEOUT(eap_client_timeout, (void *)esp);
2725 /* This is odd. The spec doesn't allow for this. */
2729 esp->es_client.ea_state = eapBadAuth;
2731 error("EAP: peer reports authentication failure");
2732 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2736 * eap_input - Handle received EAP message.
2739 eap_input(int unit, u_char *inp, int inlen)
2741 eap_state *esp = &eap_states[unit];
2746 * Parse header (code, id and length). If packet too short,
2749 if (inlen < EAP_HEADERLEN) {
2750 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2756 if (len < EAP_HEADERLEN || len > inlen) {
2757 error("EAP: packet has illegal length field %d (%d..%d)", len,
2758 EAP_HEADERLEN, inlen);
2761 len -= EAP_HEADERLEN;
2763 /* Dispatch based on message code */
2766 eap_request(esp, inp, id, len);
2770 eap_response(esp, inp, id, len);
2774 eap_success(esp, inp, id, len);
2778 eap_failure(esp, inp, id, len);
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);
2789 * eap_printpkt - print the contents of an EAP packet.
2791 static char *eap_codenames[] = {
2792 "Request", "Response", "Success", "Failure"
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",
2806 eap_printpkt(u_char *inp, int inlen,
2807 void (*printer) (void *, char *, ...), void *arg)
2809 int code, id, len, rtype, vallen;
2814 #endif /* USE_EAPTLS */
2819 if (inlen < EAP_HEADERLEN)
2825 if (len < EAP_HEADERLEN || len > inlen)
2828 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2829 printer(arg, " %s", eap_codenames[code-1]);
2831 printer(arg, " code=0x%x", code);
2832 printer(arg, " id=0x%x", id);
2833 len -= EAP_HEADERLEN;
2837 printer(arg, " <missing type>");
2840 GETCHAR(rtype, inp);
2843 rtype <= sizeof (eap_typenames) / sizeof (char *))
2844 printer(arg, " %s", eap_typenames[rtype-1]);
2846 printer(arg, " type=0x%x", rtype);
2849 case EAPT_NOTIFICATION:
2851 printer(arg, " <Message ");
2852 print_string((char *)inp, len, printer, arg);
2857 printer(arg, " <No message>");
2864 GETCHAR(vallen, inp);
2868 printer(arg, " <Value%.*B>", vallen, inp);
2869 INCPTR(vallen, inp);
2872 printer(arg, " <Name ");
2873 print_string((char *)inp, len, printer, arg);
2878 printer(arg, " <No name>");
2886 GETCHAR(opcode, inp);
2889 case CHAP_CHALLENGE:
2892 GETCHAR(vallen, inp);
2897 printer(arg, " Challenge <");
2898 for (; vallen > 0; --vallen) {
2901 printer(arg, "%.2x", val);
2905 printer(arg, ", <Name ");
2906 print_string((char *)inp, len, printer, arg);
2911 printer(arg, ", <No name>");
2917 printer(arg, " Success <Message ");
2918 print_string((char *)inp, len, printer, arg);
2924 printer(arg, " Failure <Message ");
2925 print_string((char *)inp, len, printer, arg);
2931 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
2941 GETCHAR(flags, inp);
2944 if(flags == 0 && len == 0){
2945 printer(arg, " Ack");
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":"- ");
2953 #endif /* USE_EAPTLS */
2958 GETCHAR(vallen, inp);
2960 printer(arg, "-%d", vallen);
2962 case EAPSRP_CHALLENGE:
2963 GETCHAR(vallen, inp);
2968 printer(arg, " <Name ");
2969 print_string((char *)inp, vallen, printer,
2973 printer(arg, " <No name>");
2975 INCPTR(vallen, inp);
2977 GETCHAR(vallen, inp);
2981 printer(arg, " <s%.*B>", vallen, inp);
2982 INCPTR(vallen, inp);
2984 GETCHAR(vallen, inp);
2989 printer(arg, " <Default g=2>");
2991 printer(arg, " <g%.*B>", vallen, inp);
2993 INCPTR(vallen, inp);
2996 printer(arg, " <Default N>");
2998 printer(arg, " <N%.*B>", len, inp);
3005 printer(arg, " <B%.*B>", len, inp);
3010 case EAPSRP_SVALIDATOR:
3011 if (len < sizeof (u_int32_t))
3014 len -= sizeof (u_int32_t);
3015 if (uval & SRPVAL_EBIT) {
3017 uval &= ~SRPVAL_EBIT;
3020 printer(arg, " f<%X>", uval);
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);
3029 printer(arg, " <PN%.*B>", len, inp);
3035 case EAPSRP_LWRECHALLENGE:
3036 printer(arg, " <Challenge%.*B>", len, inp);
3048 GETCHAR(rtype, inp);
3051 rtype <= sizeof (eap_typenames) / sizeof (char *))
3052 printer(arg, " %s", eap_typenames[rtype-1]);
3054 printer(arg, " type=0x%x", rtype);
3058 printer(arg, " <Name ");
3059 print_string((char *)inp, len, printer, arg);
3070 GETCHAR(flags, inp);
3073 if(flags == 0 && len == 0){
3074 printer(arg, " Ack");
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":"- ");
3083 #endif /* USE_EAPTLS */
3087 printer(arg, " <missing hint>");
3090 GETCHAR(rtype, inp);
3092 printer(arg, " <Suggested-type %02X", rtype);
3094 rtype < sizeof (eap_typenames) / sizeof (char *))
3095 printer(arg, " (%s)", eap_typenames[rtype-1]);
3101 printer(arg, " <missing length>");
3104 GETCHAR(vallen, inp);
3108 printer(arg, " <Value%.*B>", vallen, inp);
3109 INCPTR(vallen, inp);
3112 printer(arg, " <Name ");
3113 print_string((char *)inp, len, printer, arg);
3118 printer(arg, " <No name>");
3126 GETCHAR(opcode, inp);
3132 GETCHAR(vallen, inp);
3137 printer(arg, " Response <");
3138 for (; vallen > 0; --vallen) {
3141 printer(arg, "%.2x", val);
3145 printer(arg, ", <Name ");
3146 print_string((char *)inp, len, printer, arg);
3151 printer(arg, ", <No name>");
3155 printer(arg, " Success");
3158 printer(arg, " Failure");
3161 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3170 GETCHAR(vallen, inp);
3172 printer(arg, "-%d", vallen);
3175 printer(arg, " <A%.*B>", len, inp);
3180 case EAPSRP_CVALIDATOR:
3181 if (len < sizeof (u_int32_t))
3184 len -= sizeof (u_int32_t);
3185 if (uval & SRPVAL_EBIT) {
3187 uval &= ~SRPVAL_EBIT;
3190 printer(arg, " f<%X>", uval);
3192 printer(arg, " <M1%.*B%s>", len, inp,
3193 len == SHA_DIGESTSIZE ? "" : "?");
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);
3214 case EAP_SUCCESS: /* No payload expected for these! */
3219 printer(arg, " <truncated>");
3224 printer(arg, "%8B...", inp);
3226 printer(arg, "%.*B", len, inp);
3229 return (inp - pstart);