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
56 #include <sys/types.h>
63 #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 */
226 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
231 * eap_client_timeout - Give up waiting for the peer to send any
235 eap_client_timeout(void *arg)
237 eap_state *esp = (eap_state *) arg;
239 if (!eap_client_active(esp))
242 error("EAP: timeout waiting for Request from peer");
243 auth_withpeer_fail(esp->es_unit, PPP_EAP);
244 esp->es_client.ea_state = eapBadAuth;
248 * eap_authwithpeer - Authenticate to our peer (behave as client).
250 * Start client state and wait for requests. This is called only
254 eap_authwithpeer(int unit, char *localname)
256 eap_state *esp = &eap_states[unit];
258 /* Save the peer name we're given */
259 esp->es_client.ea_name = localname;
260 esp->es_client.ea_namelen = strlen(localname);
262 esp->es_client.ea_state = eapListen;
265 * Start a timer so that if the other end just goes
266 * silent, we don't sit here waiting forever.
268 if (esp->es_client.ea_timeout > 0)
269 TIMEOUT(eap_client_timeout, (void *)esp,
270 esp->es_client.ea_timeout);
274 * Format a standard EAP Failure message and send it to the peer.
278 eap_send_failure(eap_state *esp)
282 outp = outpacket_buf;
284 MAKEHEADER(outp, PPP_EAP);
286 PUTCHAR(EAP_FAILURE, outp);
287 esp->es_server.ea_id++;
288 PUTCHAR(esp->es_server.ea_id, outp);
289 PUTSHORT(EAP_HEADERLEN, outp);
291 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
293 esp->es_server.ea_state = eapBadAuth;
294 auth_peer_fail(esp->es_unit, PPP_EAP);
298 * Format a standard EAP Success message and send it to the peer.
302 eap_send_success(eap_state *esp)
306 outp = outpacket_buf;
308 MAKEHEADER(outp, PPP_EAP);
310 PUTCHAR(EAP_SUCCESS, outp);
311 esp->es_server.ea_id++;
312 PUTCHAR(esp->es_server.ea_id, outp);
313 PUTSHORT(EAP_HEADERLEN, outp);
315 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
317 auth_peer_success(esp->es_unit, PPP_EAP, 0,
318 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
323 * Set DES key according to pseudonym-generating secret and current
327 pncrypt_setkey(int timeoffs)
332 u_char dig[SHA_DIGESTSIZE];
335 if (pn_secret == NULL)
337 reftime = time(NULL) + timeoffs;
338 tp = localtime(&reftime);
340 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
341 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
342 SHA1Update(&ctxt, tbuf, strlen(tbuf));
343 SHA1Final(dig, &ctxt);
344 return (DesSetkey(dig));
347 static char base64[] =
348 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
356 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
361 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
364 if (bs->bs_offs >= 24) {
365 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
366 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
367 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
368 *outp++ = base64[bs->bs_bits & 0x3F];
378 b64flush(struct b64state *bs, u_char *outp)
382 if (bs->bs_offs == 8) {
383 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
384 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
386 } else if (bs->bs_offs == 16) {
387 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
388 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
389 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
398 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
404 if ((cp = strchr(base64, *inp++)) == NULL)
406 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
409 if (bs->bs_offs >= 8) {
410 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
420 * Assume that current waiting server state is complete and figure
421 * next state to use based on available authentication data. 'status'
422 * indicates if there was an error in handling the last query. It is
423 * 0 for success and non-zero for failure.
426 eap_figure_next_state(eap_state *esp, int status)
429 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
431 struct t_confent *tce, mytce;
434 int id, i, plen, toffs;
439 struct eaptls_session *ets;
441 char secret[MAXWORDLEN];
442 #endif /* USE_EAPTLS */
444 esp->es_server.ea_timeout = esp->es_savedtime;
446 esp->es_server.ea_prev_state = esp->es_server.ea_state;
447 #endif /* USE_EAPTLS */
448 switch (esp->es_server.ea_state) {
454 /* Discard any previous session. */
455 ts = (struct t_server *)esp->es_server.ea_session;
458 esp->es_server.ea_session = NULL;
459 esp->es_server.ea_skey = NULL;
463 esp->es_server.ea_state = eapBadAuth;
467 /* If we've got a pseudonym, try to decode to real name. */
468 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
469 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
470 SRP_PSEUDO_LEN) == 0 &&
471 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
473 BZERO(&bs, sizeof (bs));
475 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
476 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
479 for (i = 0; i < 5; i++) {
480 pncrypt_setkey(toffs);
482 if (!DesDecrypt(secbuf, clear)) {
483 dbglog("no DES here; cannot decode "
487 id = *(unsigned char *)clear;
488 if (id + 1 <= plen && id + 9 > plen)
491 if (plen % 8 == 0 && i < 5) {
493 * Note that this is always shorter than the
494 * original stored string, so there's no need
497 if ((i = plen = *(unsigned char *)clear) > 7)
499 esp->es_server.ea_peerlen = plen;
500 dp = (unsigned char *)esp->es_server.ea_peer;
501 BCOPY(clear + 1, dp, i);
506 (void) DesDecrypt(sp, dp);
511 esp->es_server.ea_peer[
512 esp->es_server.ea_peerlen] = '\0';
513 dbglog("decoded pseudonym to \"%.*q\"",
514 esp->es_server.ea_peerlen,
515 esp->es_server.ea_peer);
517 dbglog("failed to decode real name");
518 /* Stay in eapIdentfy state; requery */
522 /* Look up user in secrets database. */
523 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
524 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
525 /* Set up default in case SRP entry is bad */
526 esp->es_server.ea_state = eapMD5Chall;
527 /* Get t_confent based on index in srp-secrets */
528 id = strtol((char *)secbuf, &cp, 10);
529 if (*cp++ != ':' || id < 0)
533 mytce.modulus.data = (u_char *)wkmodulus;
534 mytce.modulus.len = sizeof (wkmodulus);
535 mytce.generator.data = (u_char *)"\002";
536 mytce.generator.len = 1;
538 } else if ((tce = gettcid(id)) != NULL) {
540 * Client will have to verify this modulus/
541 * generator combination, and that will take
542 * a while. Lengthen the timeout here.
544 if (esp->es_server.ea_timeout > 0 &&
545 esp->es_server.ea_timeout < 30)
546 esp->es_server.ea_timeout = 30;
550 if ((cp2 = strchr(cp, ':')) == NULL)
553 tpw.pebuf.name = esp->es_server.ea_peer;
554 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
556 tpw.pebuf.password.data = tpw.pwbuf;
557 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
559 tpw.pebuf.salt.data = tpw.saltbuf;
560 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
562 esp->es_server.ea_session = (void *)ts;
563 esp->es_server.ea_state = eapSRP1;
564 vals[0] = esp->es_server.ea_id + 1;
566 t_serveraddexdata(ts, vals, 2);
567 /* Generate B; must call before t_servergetkey() */
573 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
574 esp->es_server.ea_name, secret, &secret_len, 1)) {
576 esp->es_server.ea_state = eapTlsStart;
579 #endif /* USE_EAPTLS */
581 esp->es_server.ea_state = eapMD5Chall;
586 /* Initialize ssl session */
587 if(!eaptls_init_ssl_server(esp)) {
588 esp->es_server.ea_state = eapBadAuth;
592 esp->es_server.ea_state = eapTlsRecv;
596 ets = (struct eaptls_session *) esp->es_server.ea_session;
598 if(ets->alert_sent) {
599 esp->es_server.ea_state = eapTlsSendAlert;
604 esp->es_server.ea_state = eapBadAuth;
607 ets = (struct eaptls_session *) esp->es_server.ea_session;
610 esp->es_server.ea_state = eapTlsSendAck;
612 esp->es_server.ea_state = eapTlsSend;
616 ets = (struct eaptls_session *) esp->es_server.ea_session;
619 esp->es_server.ea_state = eapTlsRecvAck;
621 if(SSL_is_init_finished(ets->ssl))
622 esp->es_server.ea_state = eapTlsRecvClient;
624 /* JJK Add "TLS empty record" message here ??? */
625 esp->es_server.ea_state = eapTlsRecv;
629 esp->es_server.ea_state = eapTlsRecv;
635 esp->es_server.ea_state = eapBadAuth;
639 esp->es_server.ea_state = eapTlsSend;
642 case eapTlsSendAlert:
643 esp->es_server.ea_state = eapTlsRecvAlertAck;
645 #endif /* USE_EAPTLS */
649 ts = (struct t_server *)esp->es_server.ea_session;
650 if (ts != NULL && status != 0) {
652 esp->es_server.ea_session = NULL;
653 esp->es_server.ea_skey = NULL;
657 esp->es_server.ea_state = eapMD5Chall;
658 } else if (status != 0 || esp->es_server.ea_session == NULL) {
659 esp->es_server.ea_state = eapBadAuth;
661 esp->es_server.ea_state = eapSRP2;
667 ts = (struct t_server *)esp->es_server.ea_session;
668 if (ts != NULL && status != 0) {
670 esp->es_server.ea_session = NULL;
671 esp->es_server.ea_skey = NULL;
674 if (status != 0 || esp->es_server.ea_session == NULL) {
675 esp->es_server.ea_state = eapBadAuth;
677 esp->es_server.ea_state = eapSRP3;
684 ts = (struct t_server *)esp->es_server.ea_session;
685 if (ts != NULL && status != 0) {
687 esp->es_server.ea_session = NULL;
688 esp->es_server.ea_skey = NULL;
691 if (status != 0 || esp->es_server.ea_session == NULL) {
692 esp->es_server.ea_state = eapBadAuth;
694 esp->es_server.ea_state = eapOpen;
699 case eapMSCHAPv2Chall:
703 esp->es_server.ea_state = eapBadAuth;
705 esp->es_server.ea_state = eapOpen;
710 esp->es_server.ea_state = eapBadAuth;
713 if (esp->es_server.ea_state == eapBadAuth)
714 eap_send_failure(esp);
717 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));
718 #endif /* USE_EAPTLS */
723 eap_chapms2_verify_response(int id, char *name,
724 unsigned char *secret, int secret_len,
725 unsigned char *challenge, unsigned char *response,
726 char *message, int message_space)
728 unsigned char md[MS_CHAP2_RESPONSE_LEN];
729 char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
730 int challenge_len, response_len;
732 challenge_len = *challenge++; /* skip length, is 16 */
733 response_len = *response++;
734 if (response_len != MS_CHAP2_RESPONSE_LEN)
735 goto bad; /* not even the right length */
737 /* Generate the expected response and our mutual auth. */
738 ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
739 (char *)secret, secret_len, md,
740 (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
742 /* compare MDs and send the appropriate status */
744 * Per RFC 2759, success message must be formatted as
745 * "S=<auth_string> M=<message>"
747 * <auth_string> is the Authenticator Response (mutual auth)
748 * <message> is a text message
750 * However, some versions of Windows (win98 tested) do not know
751 * about the M=<message> part (required per RFC 2759) and flag
752 * it as an error (reported incorrectly as an encryption error
753 * to the user). Since the RFC requires it, and it can be
754 * useful information, we supply it if the peer is a conforming
755 * system. Luckily (?), win98 sets the Flags field to 0x04
756 * (contrary to RFC requirements) so we can use that to
757 * distinguish between conforming and non-conforming systems.
759 * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
760 * help debugging this.
762 if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
763 MS_CHAP2_NTRESP_LEN) == 0) {
764 if (response[MS_CHAP2_FLAGS])
765 slprintf(message, message_space, "S=%s", saresponse);
767 slprintf(message, message_space, "S=%s M=%s",
768 saresponse, "Access granted");
774 * Failure message must be formatted as
775 * "E=e R=r C=c V=v M=m"
777 * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
778 * r = retry (we use 1, ok to retry)
779 * c = challenge to use for next response, we reuse previous
780 * v = Change Password version supported, we use 0
783 * The M=m part is only for MS-CHAPv2. Neither win2k nor
784 * win98 (others untested) display the message to the user anyway.
785 * They also both ignore the E=e code.
787 * Note that it's safe to reuse the same challenge as we don't
788 * actually accept another response based on the error message
789 * (and no clients try to resend a response anyway).
791 * Basically, this whole bit is useless code, even the small
792 * implementation here is only because of overspecification.
794 slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
795 challenge_len, challenge, "Access denied");
799 static struct chap_digest_type eap_chapms2_digest = {
800 CHAP_MICROSOFT_V2, /* code */
801 NULL, /* chapms2_generate_challenge, */
802 eap_chapms2_verify_response,
803 NULL, /* chapms2_make_response, */
804 NULL, /* chapms2_check_success, */
805 NULL, /* chapms_handle_failure, */
809 * eap_chap_verify_response - check whether the peer's response matches
810 * what we think it should be. Returns 1 if it does (authentication
811 * succeeded), or 0 if it doesn't.
814 eap_chap_verify_response(char *name, char *ourname, int id,
815 struct chap_digest_type *digest,
816 unsigned char *challenge, unsigned char *response,
817 char *message, int message_space)
820 unsigned char secret[MAXSECRETLEN];
823 /* Get the secret that the peer is supposed to know */
824 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
825 error("No CHAP secret found for authenticating %q", name);
829 ok = digest->verify_response(id, name, secret, secret_len, challenge,
830 response, message, message_space);
831 memset(secret, 0, sizeof(secret));
837 * Format and send an CHAPV2-Success/Failure EAP Request message.
840 eap_chapms2_send_request(eap_state *esp, u_char id,
841 u_char opcode, u_char chapid,
842 char *message, int message_len)
847 outp = outpacket_buf;
849 MAKEHEADER(outp, PPP_EAP);
851 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
852 msglen += message_len;
854 PUTCHAR(EAP_REQUEST, outp);
856 PUTSHORT(msglen, outp);
857 PUTCHAR(EAPT_MSCHAPV2, outp);
858 PUTCHAR(opcode, outp);
859 PUTCHAR(chapid, outp);
861 PUTSHORT(msglen - 5, outp);
862 BCOPY(message, outp, message_len);
864 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
866 if (opcode == CHAP_SUCCESS) {
867 auth_peer_success(esp->es_unit, PPP_EAP, 0,
868 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
871 esp->es_server.ea_state = eapBadAuth;
872 auth_peer_fail(esp->es_unit, PPP_EAP);
878 * Format an EAP Request message and send it to the peer. Message
879 * type depends on current state. (Server operation)
882 eap_send_request(eap_state *esp)
892 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
898 /* Handle both initial auth and restart */
899 if (esp->es_server.ea_state < eapIdentify &&
900 esp->es_server.ea_state != eapInitial) {
901 esp->es_server.ea_state = eapIdentify;
902 if (explicit_remote) {
904 * If we already know the peer's
905 * unauthenticated name, then there's no
906 * reason to ask. Go to next state instead.
908 esp->es_server.ea_peer = remote_name;
909 esp->es_server.ea_peerlen = strlen(remote_name);
910 eap_figure_next_state(esp, 0);
914 if (esp->es_server.ea_maxrequests > 0 &&
915 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
916 if (esp->es_server.ea_responses > 0)
917 error("EAP: too many Requests sent");
919 error("EAP: no response to Requests");
920 eap_send_failure(esp);
924 outp = outpacket_buf;
926 MAKEHEADER(outp, PPP_EAP);
928 PUTCHAR(EAP_REQUEST, outp);
929 PUTCHAR(esp->es_server.ea_id, outp);
933 switch (esp->es_server.ea_state) {
935 PUTCHAR(EAPT_IDENTITY, outp);
937 challen = strlen(str);
938 BCOPY(str, outp, challen);
939 INCPTR(challen, outp);
943 PUTCHAR(EAPT_MD5CHAP, outp);
945 * pick a random challenge length between
946 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
948 challen = (drand48() *
949 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
950 MIN_CHALLENGE_LENGTH;
951 PUTCHAR(challen, outp);
952 esp->es_challen = challen;
953 ptr = esp->es_challenge;
954 while (--challen >= 0)
955 *ptr++ = (u_char) (drand48() * 0x100);
956 BCOPY(esp->es_challenge, outp, esp->es_challen);
957 INCPTR(esp->es_challen, outp);
958 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
959 INCPTR(esp->es_server.ea_namelen, outp);
963 case eapMSCHAPv2Chall:
965 esp->es_challen = challen;
966 esp->es_challenge[0] = challen;
967 random_bytes(&esp->es_challenge[1], challen);
969 PUTCHAR(EAPT_MSCHAPV2, outp);
970 PUTCHAR(CHAP_CHALLENGE, outp);
971 PUTCHAR(esp->es_server.ea_id, outp);
973 PUTSHORT(5 + challen +
974 esp->es_server.ea_namelen,
976 /* challen + challenge */
977 BCOPY(esp->es_challenge, outp, challen+1);
978 INCPTR(challen+1, outp);
979 BCOPY(esp->es_server.ea_name,
981 esp->es_server.ea_namelen);
982 INCPTR(esp->es_server.ea_namelen, outp);
988 PUTCHAR(EAPT_TLS, outp);
989 PUTCHAR(EAP_TLS_FLAGS_START, outp);
990 eap_figure_next_state(esp, 0);
994 eaptls_send(esp->es_server.ea_session, &outp);
995 eap_figure_next_state(esp, 0);
999 PUTCHAR(EAPT_TLS, outp);
1001 eap_figure_next_state(esp, 0);
1004 case eapTlsSendAlert:
1005 eaptls_send(esp->es_server.ea_session, &outp);
1006 eap_figure_next_state(esp, 0);
1008 #endif /* USE_EAPTLS */
1012 PUTCHAR(EAPT_SRP, outp);
1013 PUTCHAR(EAPSRP_CHALLENGE, outp);
1015 PUTCHAR(esp->es_server.ea_namelen, outp);
1016 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
1017 INCPTR(esp->es_server.ea_namelen, outp);
1019 ts = (struct t_server *)esp->es_server.ea_session;
1021 PUTCHAR(ts->s.len, outp);
1022 BCOPY(ts->s.data, outp, ts->s.len);
1023 INCPTR(ts->s.len, outp);
1025 if (ts->g.len == 1 && ts->g.data[0] == 2) {
1028 PUTCHAR(ts->g.len, outp);
1029 BCOPY(ts->g.data, outp, ts->g.len);
1030 INCPTR(ts->g.len, outp);
1033 if (ts->n.len != sizeof (wkmodulus) ||
1034 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
1035 BCOPY(ts->n.data, outp, ts->n.len);
1036 INCPTR(ts->n.len, outp);
1041 PUTCHAR(EAPT_SRP, outp);
1042 PUTCHAR(EAPSRP_SKEY, outp);
1044 ts = (struct t_server *)esp->es_server.ea_session;
1046 BCOPY(ts->B.data, outp, ts->B.len);
1047 INCPTR(ts->B.len, outp);
1051 PUTCHAR(EAPT_SRP, outp);
1052 PUTCHAR(EAPSRP_SVALIDATOR, outp);
1053 PUTLONG(SRPVAL_EBIT, outp);
1054 ts = (struct t_server *)esp->es_server.ea_session;
1056 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
1057 INCPTR(SHA_DIGESTSIZE, outp);
1059 if (pncrypt_setkey(0)) {
1060 /* Generate pseudonym */
1062 cp = (unsigned char *)esp->es_server.ea_peer;
1063 if ((j = i = esp->es_server.ea_peerlen) > 7)
1066 BCOPY(cp, clear + 1, j);
1069 if (!DesEncrypt(clear, cipher)) {
1070 dbglog("no DES here; not generating pseudonym");
1073 BZERO(&b64, sizeof (b64));
1074 outp++; /* space for pseudonym length */
1075 outp += b64enc(&b64, cipher, 8, outp);
1077 (void) DesEncrypt(cp, cipher);
1078 outp += b64enc(&b64, cipher, 8, outp);
1083 BCOPY(cp, clear, i);
1086 *cp++ = drand48() * 0x100;
1089 (void) DesEncrypt(clear, cipher);
1090 outp += b64enc(&b64, cipher, 8, outp);
1092 outp += b64flush(&b64, outp);
1094 /* Set length and pad out to next 20 octet boundary */
1095 i = outp - optr - 1;
1097 i %= SHA_DIGESTSIZE;
1099 while (i < SHA_DIGESTSIZE) {
1100 *outp++ = drand48() * 0x100;
1105 /* Obscure the pseudonym with SHA1 hash */
1107 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1108 SHA1Update(&ctxt, esp->es_server.ea_skey,
1110 SHA1Update(&ctxt, esp->es_server.ea_peer,
1111 esp->es_server.ea_peerlen);
1112 while (optr < outp) {
1113 SHA1Final(dig, &ctxt);
1115 while (cp < dig + SHA_DIGESTSIZE)
1118 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1119 SHA1Update(&ctxt, esp->es_server.ea_skey,
1121 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1128 PUTCHAR(EAPT_SRP, outp);
1129 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1130 challen = MIN_CHALLENGE_LENGTH +
1131 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1132 esp->es_challen = challen;
1133 ptr = esp->es_challenge;
1134 while (--challen >= 0)
1135 *ptr++ = drand48() * 0x100;
1136 BCOPY(esp->es_challenge, outp, esp->es_challen);
1137 INCPTR(esp->es_challen, outp);
1139 #endif /* USE_SRP */
1145 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1146 PUTSHORT(outlen, lenloc);
1148 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1150 esp->es_server.ea_requests++;
1152 if (esp->es_server.ea_timeout > 0)
1153 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1157 * eap_authpeer - Authenticate our peer (behave as server).
1159 * Start server state and send first request. This is called only
1160 * after eap_lowerup.
1163 eap_authpeer(int unit, char *localname)
1165 eap_state *esp = &eap_states[unit];
1167 /* Save the name we're given. */
1168 esp->es_server.ea_name = localname;
1169 esp->es_server.ea_namelen = strlen(localname);
1171 esp->es_savedtime = esp->es_server.ea_timeout;
1173 /* Lower layer up yet? */
1174 if (esp->es_server.ea_state == eapInitial ||
1175 esp->es_server.ea_state == eapPending) {
1176 esp->es_server.ea_state = eapPending;
1180 esp->es_server.ea_state = eapPending;
1182 /* ID number not updated here intentionally; hashed into M1 */
1183 eap_send_request(esp);
1187 * eap_server_timeout - Retransmission timer for sending Requests
1191 eap_server_timeout(void *arg)
1197 #endif /* USE_EAPTLS */
1199 eap_state *esp = (eap_state *) arg;
1201 if (!eap_server_active(esp))
1205 switch(esp->es_server.ea_prev_state) {
1208 * In eap-tls the state changes after a request, so we return to
1209 * previous state ...
1212 case(eapTlsSendAck):
1213 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1217 * ... or resend the stored data
1220 case(eapTlsSendAlert):
1221 outp = outpacket_buf;
1222 MAKEHEADER(outp, PPP_EAP);
1223 PUTCHAR(EAP_REQUEST, outp);
1224 PUTCHAR(esp->es_server.ea_id, outp);
1228 eaptls_retransmit(esp->es_server.ea_session, &outp);
1230 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1231 PUTSHORT(outlen, lenloc);
1232 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1233 esp->es_server.ea_requests++;
1235 if (esp->es_server.ea_timeout > 0)
1236 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1242 #endif /* USE_EAPTLS */
1244 /* EAP ID number must not change on timeout. */
1245 eap_send_request(esp);
1249 * When it's time to send rechallenge the peer, this timeout is
1250 * called. Once the rechallenge is successful, the response handler
1251 * will restart the timer. If it fails, then the link is dropped.
1254 eap_rechallenge(void *arg)
1256 eap_state *esp = (eap_state *)arg;
1258 if (esp->es_server.ea_state != eapOpen &&
1259 esp->es_server.ea_state != eapSRP4)
1262 esp->es_server.ea_requests = 0;
1263 esp->es_server.ea_state = eapIdentify;
1264 eap_figure_next_state(esp, 0);
1265 esp->es_server.ea_id++;
1266 eap_send_request(esp);
1270 srp_lwrechallenge(void *arg)
1272 eap_state *esp = (eap_state *)arg;
1274 if (esp->es_server.ea_state != eapOpen ||
1275 esp->es_server.ea_type != EAPT_SRP)
1278 esp->es_server.ea_requests = 0;
1279 esp->es_server.ea_state = eapSRP4;
1280 esp->es_server.ea_id++;
1281 eap_send_request(esp);
1285 * eap_lowerup - The lower layer is now up.
1287 * This is called before either eap_authpeer or eap_authwithpeer. See
1288 * link_established() in auth.c. All that's necessary here is to
1289 * return to closed state so that those two routines will do the right
1293 eap_lowerup(int unit)
1295 eap_state *esp = &eap_states[unit];
1297 /* Discard any (possibly authenticated) peer name. */
1298 if (esp->es_server.ea_peer != NULL &&
1299 esp->es_server.ea_peer != remote_name)
1300 free(esp->es_server.ea_peer);
1301 esp->es_server.ea_peer = NULL;
1302 if (esp->es_client.ea_peer != NULL)
1303 free(esp->es_client.ea_peer);
1304 esp->es_client.ea_peer = NULL;
1306 esp->es_client.ea_state = eapClosed;
1307 esp->es_server.ea_state = eapClosed;
1311 * eap_lowerdown - The lower layer is now down.
1313 * Cancel all timeouts and return to initial state.
1316 eap_lowerdown(int unit)
1318 eap_state *esp = &eap_states[unit];
1320 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1321 UNTIMEOUT(eap_client_timeout, (void *)esp);
1323 if (eap_server_active(esp)) {
1324 if (esp->es_server.ea_timeout > 0) {
1325 UNTIMEOUT(eap_server_timeout, (void *)esp);
1328 if ((esp->es_server.ea_state == eapOpen ||
1329 esp->es_server.ea_state == eapSRP4) &&
1330 esp->es_rechallenge > 0) {
1331 UNTIMEOUT(eap_rechallenge, (void *)esp);
1333 if (esp->es_server.ea_state == eapOpen &&
1334 esp->es_lwrechallenge > 0) {
1335 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1339 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1340 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1344 * eap_protrej - Peer doesn't speak this protocol.
1346 * This shouldn't happen. If it does, it represents authentication
1350 eap_protrej(int unit)
1352 eap_state *esp = &eap_states[unit];
1354 if (eap_client_active(esp)) {
1355 error("EAP authentication failed due to Protocol-Reject");
1356 auth_withpeer_fail(unit, PPP_EAP);
1358 if (eap_server_active(esp)) {
1359 error("EAP authentication of peer failed on Protocol-Reject");
1360 auth_peer_fail(unit, PPP_EAP);
1362 eap_lowerdown(unit);
1366 * Format and send a regular EAP Response message.
1369 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1370 u_char *str, int lenstr)
1375 outp = outpacket_buf;
1377 MAKEHEADER(outp, PPP_EAP);
1379 PUTCHAR(EAP_RESPONSE, outp);
1381 esp->es_client.ea_id = id;
1382 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1383 PUTSHORT(msglen, outp);
1384 PUTCHAR(typenum, outp);
1386 BCOPY(str, outp, lenstr);
1389 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1393 * Format and send an MD5-Challenge EAP Response message.
1396 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1397 char *name, int namelen)
1402 outp = outpacket_buf;
1404 MAKEHEADER(outp, PPP_EAP);
1406 PUTCHAR(EAP_RESPONSE, outp);
1408 esp->es_client.ea_id = id;
1409 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1411 PUTSHORT(msglen, outp);
1412 PUTCHAR(EAPT_MD5CHAP, outp);
1413 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1414 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1415 INCPTR(MD5_SIGNATURE_SIZE, outp);
1417 BCOPY(name, outp, namelen);
1420 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1425 * Format and send a SRP EAP Response message.
1428 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1429 u_char *str, int lenstr)
1434 outp = outpacket_buf;
1436 MAKEHEADER(outp, PPP_EAP);
1438 PUTCHAR(EAP_RESPONSE, outp);
1440 esp->es_client.ea_id = id;
1441 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1442 PUTSHORT(msglen, outp);
1443 PUTCHAR(EAPT_SRP, outp);
1444 PUTCHAR(subtypenum, outp);
1446 BCOPY(str, outp, lenstr);
1449 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1453 * Format and send a SRP EAP Client Validator Response message.
1456 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1461 outp = outpacket_buf;
1463 MAKEHEADER(outp, PPP_EAP);
1465 PUTCHAR(EAP_RESPONSE, outp);
1467 esp->es_client.ea_id = id;
1468 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1470 PUTSHORT(msglen, outp);
1471 PUTCHAR(EAPT_SRP, outp);
1472 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1473 PUTLONG(flags, outp);
1474 BCOPY(str, outp, SHA_DIGESTSIZE);
1476 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1478 #endif /* USE_SRP */
1482 * Send an EAP-TLS response message with tls data
1485 eap_tls_response(eap_state *esp, u_char id)
1491 outp = outpacket_buf;
1493 MAKEHEADER(outp, PPP_EAP);
1495 PUTCHAR(EAP_RESPONSE, outp);
1502 If the id in the request is unchanged, we must retransmit
1505 if(id == esp->es_client.ea_id)
1506 eaptls_retransmit(esp->es_client.ea_session, &outp);
1508 eaptls_send(esp->es_client.ea_session, &outp);
1510 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1511 PUTSHORT(outlen, lenloc);
1513 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1515 esp->es_client.ea_id = id;
1519 * Send an EAP-TLS ack
1522 eap_tls_sendack(eap_state *esp, u_char id)
1528 outp = outpacket_buf;
1530 MAKEHEADER(outp, PPP_EAP);
1532 PUTCHAR(EAP_RESPONSE, outp);
1534 esp->es_client.ea_id = id;
1539 PUTCHAR(EAPT_TLS, outp);
1542 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1543 PUTSHORT(outlen, lenloc);
1545 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1547 #endif /* USE_EAPTLS */
1550 eap_send_nak(eap_state *esp, u_char id, u_char type)
1555 outp = outpacket_buf;
1557 MAKEHEADER(outp, PPP_EAP);
1559 PUTCHAR(EAP_RESPONSE, outp);
1561 esp->es_client.ea_id = id;
1562 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1563 PUTSHORT(msglen, outp);
1564 PUTCHAR(EAPT_NAK, outp);
1565 PUTCHAR(type, outp);
1567 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1572 name_of_pn_file(void)
1574 char *user, *path, *file;
1577 static bool pnlogged = 0;
1579 pw = getpwuid(getuid());
1580 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1584 file = _PATH_PSEUDONYM;
1585 pl = strlen(user) + strlen(file) + 2;
1589 (void) slprintf(path, pl, "%s/%s", user, file);
1591 dbglog("pseudonym file: %s", path);
1598 open_pn_file(mode_t modebits)
1603 if ((path = name_of_pn_file()) == NULL)
1605 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1613 remove_pn_file(void)
1617 if ((path = name_of_pn_file()) != NULL) {
1618 (void) unlink(path);
1624 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1627 u_char *datp, *digp;
1629 u_char dig[SHA_DIGESTSIZE];
1630 int dsize, fd, olen = len;
1633 * Do the decoding by working backwards. This eliminates the need
1634 * to save the decoded output in a separate buffer.
1638 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1639 dsize = SHA_DIGESTSIZE;
1643 SHA1Update(&ctxt, &val, 1);
1644 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1646 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1648 SHA1Update(&ctxt, esp->es_client.ea_name,
1649 esp->es_client.ea_namelen);
1651 SHA1Final(dig, &ctxt);
1652 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1656 /* Now check that the result is sane */
1657 if (olen <= 0 || *inp + 1 > olen) {
1658 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1663 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1665 dbglog("EAP: error saving pseudonym: %m");
1668 len = write(fd, inp + 1, *inp);
1669 if (close(fd) != -1 && len == *inp) {
1670 dbglog("EAP: saved pseudonym");
1671 esp->es_usedpseudo = 0;
1673 dbglog("EAP: failed to save pseudonym");
1677 #endif /* USE_SRP */
1681 * Format and send an CHAPV2-Challenge EAP Response message.
1684 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1689 outp = outpacket_buf;
1691 MAKEHEADER(outp, PPP_EAP);
1693 PUTCHAR(EAP_RESPONSE, outp);
1695 esp->es_client.ea_id = id;
1696 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1697 PUTSHORT(msglen, outp);
1698 PUTCHAR(EAPT_MSCHAPV2, outp);
1699 PUTCHAR(CHAP_RESPONSE, outp);
1700 PUTCHAR(chapid, outp);
1703 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1704 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1705 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1706 BCOPY(user, outp, user_len);
1708 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1713 * eap_request - Receive EAP Request message (client mode).
1716 eap_request(eap_state *esp, u_char *inp, int id, int len)
1721 char secret[MAXWORDLEN];
1722 char rhostname[256];
1724 u_char hash[MD5_SIGNATURE_SIZE];
1727 struct eaptls_session *ets = esp->es_client.ea_session;
1728 #endif /* USE_EAPTLS */
1731 struct t_client *tc;
1732 struct t_num sval, gval, Nval, *Ap, Bval;
1735 u_char dig[SHA_DIGESTSIZE];
1737 #endif /* USE_SRP */
1740 * Ignore requests if we're not open
1742 if (esp->es_client.ea_state <= eapClosed)
1746 * Note: we update es_client.ea_id *only if* a Response
1747 * message is being generated. Otherwise, we leave it the
1748 * same for duplicate detection purposes.
1751 esp->es_client.ea_requests++;
1752 if (esp->es_client.ea_maxrequests != 0 &&
1753 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1754 info("EAP: received too many Request messages");
1755 if (esp->es_client.ea_timeout > 0) {
1756 UNTIMEOUT(eap_client_timeout, (void *)esp);
1758 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1763 error("EAP: empty Request message discarded");
1767 GETCHAR(typenum, inp);
1773 info("EAP: Identity prompt \"%.*q\"", len, inp);
1775 if (esp->es_usepseudo &&
1776 (esp->es_usedpseudo == 0 ||
1777 (esp->es_usedpseudo == 1 &&
1778 id == esp->es_client.ea_id))) {
1779 esp->es_usedpseudo = 1;
1780 /* Try to get a pseudonym */
1781 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1782 strcpy(rhostname, SRP_PSEUDO_ID);
1783 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1784 sizeof (rhostname) - SRP_PSEUDO_LEN);
1785 /* XXX NAI unsupported */
1787 eap_send_response(esp, id, typenum,
1788 rhostname, len + SRP_PSEUDO_LEN);
1795 /* Stop using pseudonym now. */
1796 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1798 esp->es_usedpseudo = 2;
1800 #endif /* USE_SRP */
1801 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1802 esp->es_client.ea_namelen);
1805 case EAPT_NOTIFICATION:
1807 info("EAP: Notification \"%.*q\"", len, inp);
1808 eap_send_response(esp, id, typenum, NULL, 0);
1813 * Avoid the temptation to send Response Nak in reply
1814 * to Request Nak here. It can only lead to trouble.
1816 warn("EAP: unexpected Nak in Request; ignored");
1817 /* Return because we're waiting for something real. */
1822 error("EAP: received MD5-Challenge with no data");
1823 /* Bogus request; wait for something real. */
1826 GETCHAR(vallen, inp);
1828 if (vallen < 8 || vallen > len) {
1829 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1831 /* Try something better. */
1832 eap_send_nak(esp, id, EAPT_SRP);
1836 /* Not so likely to happen. */
1837 if (len - vallen >= sizeof (rhostname)) {
1838 dbglog("EAP: trimming really long peer name down");
1839 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1840 rhostname[sizeof (rhostname) - 1] = '\0';
1842 BCOPY(inp + vallen, rhostname, len - vallen);
1843 rhostname[len - vallen] = '\0';
1846 /* In case the remote doesn't give us his name. */
1847 if (explicit_remote ||
1848 (remote_name[0] != '\0' && vallen == len))
1849 strlcpy(rhostname, remote_name, sizeof (rhostname));
1852 * Get the secret for authenticating ourselves with
1853 * the specified host.
1855 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1856 rhostname, secret, &secret_len, 0)) {
1857 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1858 eap_send_nak(esp, id, EAPT_SRP);
1861 MD5_Init(&mdContext);
1863 MD5_Update(&mdContext, &typenum, 1);
1864 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1865 BZERO(secret, sizeof (secret));
1866 MD5_Update(&mdContext, inp, vallen);
1867 MD5_Final(hash, &mdContext);
1868 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1869 esp->es_client.ea_namelen);
1875 switch(esp->es_client.ea_state) {
1880 error("EAP: received EAP-TLS Listen packet with no data");
1881 /* Bogus request; wait for something real. */
1884 GETCHAR(flags, inp);
1885 if(flags & EAP_TLS_FLAGS_START){
1887 esp->es_client.ea_using_eaptls = 1;
1889 if (explicit_remote){
1890 esp->es_client.ea_peer = strdup(remote_name);
1891 esp->es_client.ea_peerlen = strlen(remote_name);
1893 esp->es_client.ea_peer = NULL;
1895 /* Init ssl session */
1896 if(!eaptls_init_ssl_client(esp)) {
1897 dbglog("cannot init ssl");
1898 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1899 esp->es_client.ea_using_eaptls = 0;
1903 ets = esp->es_client.ea_session;
1904 eap_tls_response(esp, id);
1905 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1909 /* The server has sent a bad start packet. */
1910 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1914 eap_tls_response(esp, id);
1915 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1920 error("EAP: discarding EAP-TLS Receive packet with no data");
1921 /* Bogus request; wait for something real. */
1924 eaptls_receive(ets, inp, len);
1927 eap_tls_sendack(esp, id);
1928 esp->es_client.ea_state = eapTlsRecv;
1932 if(ets->alert_recv) {
1933 eap_tls_sendack(esp, id);
1934 esp->es_client.ea_state = eapTlsRecvFailure;
1938 /* Check if TLS handshake is finished */
1939 if(eaptls_is_init_finished(ets)) {
1941 eaptls_gen_mppe_keys(ets, 1);
1943 eaptls_free_session(ets);
1944 eap_tls_sendack(esp, id);
1945 esp->es_client.ea_state = eapTlsRecvSuccess;
1949 eap_tls_response(esp,id);
1950 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1954 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1955 esp->es_client.ea_using_eaptls = 0;
1960 #endif /* USE_EAPTLS */
1965 error("EAP: received empty SRP Request");
1966 /* Bogus request; wait for something real. */
1971 GETCHAR(vallen, inp);
1974 case EAPSRP_CHALLENGE:
1976 if (esp->es_client.ea_session != NULL) {
1977 tc = (struct t_client *)esp->es_client.
1980 * If this is a new challenge, then start
1981 * over with a new client session context.
1982 * Otherwise, just resend last response.
1984 if (id != esp->es_client.ea_id) {
1986 esp->es_client.ea_session = NULL;
1990 /* No session key just yet */
1991 esp->es_client.ea_skey = NULL;
1993 GETCHAR(vallen, inp);
1995 if (vallen >= len) {
1996 error("EAP: badly-formed SRP Challenge"
1998 /* Ignore badly-formed messages */
2001 BCOPY(inp, rhostname, vallen);
2002 rhostname[vallen] = '\0';
2003 INCPTR(vallen, inp);
2007 * In case the remote doesn't give us his name,
2008 * use configured name.
2010 if (explicit_remote ||
2011 (remote_name[0] != '\0' && vallen == 0)) {
2012 strlcpy(rhostname, remote_name,
2013 sizeof (rhostname));
2016 if (esp->es_client.ea_peer != NULL)
2017 free(esp->es_client.ea_peer);
2018 esp->es_client.ea_peer = strdup(rhostname);
2019 esp->es_client.ea_peerlen = strlen(rhostname);
2021 GETCHAR(vallen, inp);
2023 if (vallen >= len) {
2024 error("EAP: badly-formed SRP Challenge"
2026 /* Ignore badly-formed messages */
2031 INCPTR(vallen, inp);
2034 GETCHAR(vallen, inp);
2037 error("EAP: badly-formed SRP Challenge"
2039 /* Ignore badly-formed messages */
2042 /* If no generator present, then use value 2 */
2044 gval.data = (u_char *)"\002";
2050 INCPTR(vallen, inp);
2054 * If no modulus present, then use well-known
2058 Nval.data = (u_char *)wkmodulus;
2059 Nval.len = sizeof (wkmodulus);
2064 tc = t_clientopen(esp->es_client.ea_name,
2065 &Nval, &gval, &sval);
2067 eap_send_nak(esp, id, EAPT_MD5CHAP);
2070 esp->es_client.ea_session = (void *)tc;
2072 /* Add Challenge ID & type to verifier */
2075 t_clientaddexdata(tc, vals, 2);
2077 Ap = t_clientgenexp(tc);
2078 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2083 tc = (struct t_client *)esp->es_client.ea_session;
2085 warn("EAP: peer sent Subtype 2 without 1");
2086 eap_send_nak(esp, id, EAPT_MD5CHAP);
2089 if (esp->es_client.ea_skey != NULL) {
2091 * ID number should not change here. Warn
2092 * if it does (but otherwise ignore).
2094 if (id != esp->es_client.ea_id) {
2095 warn("EAP: ID changed from %d to %d "
2096 "in SRP Subtype 2 rexmit",
2097 esp->es_client.ea_id, id);
2100 if (get_srp_secret(esp->es_unit,
2101 esp->es_client.ea_name,
2102 esp->es_client.ea_peer, secret, 0) == 0) {
2104 * Can't work with this peer because
2105 * the secret is missing. Just give
2108 eap_send_nak(esp, id, EAPT_MD5CHAP);
2113 t_clientpasswd(tc, secret);
2114 BZERO(secret, sizeof (secret));
2115 esp->es_client.ea_skey =
2116 t_clientgetkey(tc, &Bval);
2117 if (esp->es_client.ea_skey == NULL) {
2118 /* Server is rogue; stop now */
2119 error("EAP: SRP server is rogue");
2120 goto client_failure;
2123 eap_srpval_response(esp, id, SRPVAL_EBIT,
2124 t_clientresponse(tc));
2127 case EAPSRP_SVALIDATOR:
2128 tc = (struct t_client *)esp->es_client.ea_session;
2129 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2130 warn("EAP: peer sent Subtype 3 without 1/2");
2131 eap_send_nak(esp, id, EAPT_MD5CHAP);
2135 * If we're already open, then this ought to be a
2136 * duplicate. Otherwise, check that the server is
2137 * who we think it is.
2139 if (esp->es_client.ea_state == eapOpen) {
2140 if (id != esp->es_client.ea_id) {
2141 warn("EAP: ID changed from %d to %d "
2142 "in SRP Subtype 3 rexmit",
2143 esp->es_client.ea_id, id);
2146 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2147 if (len < 0 || t_clientverify(tc, inp +
2148 sizeof (u_int32_t)) != 0) {
2149 error("EAP: SRP server verification "
2151 goto client_failure;
2153 GETLONG(esp->es_client.ea_keyflags, inp);
2154 /* Save pseudonym if user wants it. */
2155 if (len > 0 && esp->es_usepseudo) {
2156 INCPTR(SHA_DIGESTSIZE, inp);
2157 write_pseudonym(esp, inp, len, id);
2161 * We've verified our peer. We're now mostly done,
2162 * except for waiting on the regular EAP Success
2165 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2168 case EAPSRP_LWRECHALLENGE:
2170 warn("EAP: malformed Lightweight rechallenge");
2175 SHA1Update(&ctxt, vals, 1);
2176 SHA1Update(&ctxt, esp->es_client.ea_skey,
2178 SHA1Update(&ctxt, inp, len);
2179 SHA1Update(&ctxt, esp->es_client.ea_name,
2180 esp->es_client.ea_namelen);
2181 SHA1Final(dig, &ctxt);
2182 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2187 error("EAP: unknown SRP Subtype %d", vallen);
2188 eap_send_nak(esp, id, EAPT_MD5CHAP);
2192 #endif /* USE_SRP */
2197 error("EAP: received invalid MSCHAPv2 packet, too short");
2200 unsigned char opcode;
2201 GETCHAR(opcode, inp);
2202 unsigned char chapid; /* Chapv2-ID */
2203 GETCHAR(chapid, inp);
2205 GETSHORT(mssize, inp);
2207 /* Validate the mssize field */
2208 if (len != mssize) {
2209 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2214 /* If MSCHAPv2 digest was not found, NAK the packet */
2215 if (!esp->es_client.digest) {
2216 error("EAP MSCHAPv2 not supported");
2217 eap_send_nak(esp, id, EAPT_SRP);
2222 case CHAP_CHALLENGE: {
2224 /* make_response() expects: VLEN + VALUE */
2225 u_char *challenge = inp;
2227 unsigned char vsize;
2228 GETCHAR(vsize, inp);
2231 /* Validate the VALUE field */
2232 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2233 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2237 /* Increment past the VALUE field */
2238 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2239 len -= MS_CHAP2_PEER_CHAL_LEN;
2241 /* Extract the hostname */
2242 rhostname[0] = '\0';
2244 if (len >= sizeof (rhostname)) {
2245 dbglog("EAP: trimming really long peer name down");
2246 len = sizeof(rhostname) - 1;
2248 BCOPY(inp, rhostname, len);
2249 rhostname[len] = '\0';
2252 /* In case the remote doesn't give us his name. */
2253 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2254 strlcpy(rhostname, remote_name, sizeof(rhostname));
2256 /* Get the secret for authenticating ourselves with the specified host. */
2257 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2258 rhostname, secret, &secret_len, 0)) {
2259 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2260 eap_send_nak(esp, id, EAPT_SRP);
2264 /* Create the MSCHAPv2 response (and add to cache) */
2265 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2266 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2267 challenge, secret, secret_len, NULL);
2269 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2272 case CHAP_SUCCESS: {
2274 /* Check response for mutual authentication */
2275 u_char status = CHAP_FAILURE;
2276 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2277 info("Chap authentication succeeded! %.*v", len, inp);
2278 status = CHAP_SUCCESS;
2280 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2283 case CHAP_FAILURE: {
2285 /* Process the failure string, and log appropriate information */
2286 esp->es_client.digest->handle_failure(inp, len);
2288 u_char status = CHAP_FAILURE;
2289 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2290 goto client_failure; /* force termination */
2294 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2295 eap_send_nak(esp, id, EAPT_SRP);
2302 info("EAP: unknown authentication type %d; Naking", typenum);
2303 eap_send_nak(esp, id, EAPT_SRP);
2307 if (esp->es_client.ea_timeout > 0) {
2308 UNTIMEOUT(eap_client_timeout, (void *)esp);
2309 TIMEOUT(eap_client_timeout, (void *)esp,
2310 esp->es_client.ea_timeout);
2315 esp->es_client.ea_state = eapBadAuth;
2316 if (esp->es_client.ea_timeout > 0) {
2317 UNTIMEOUT(eap_client_timeout, (void *)esp);
2319 esp->es_client.ea_session = NULL;
2322 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2323 #endif /* USE_SRP */
2327 * eap_response - Receive EAP Response message (server mode).
2330 eap_response(eap_state *esp, u_char *inp, int id, int len)
2335 char secret[MAXSECRETLEN];
2336 char rhostname[256];
2338 u_char hash[MD5_SIGNATURE_SIZE];
2340 struct t_server *ts;
2343 u_char dig[SHA_DIGESTSIZE];
2345 u_char dig[SHA_DIGESTSIZE];
2346 #endif /* USE_SRP */
2349 struct eaptls_session *ets;
2351 #endif /* USE_EAPTLS */
2354 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2355 unsigned char *, unsigned char *, char *, int);
2356 char response_message[256];
2360 * Ignore responses if we're not open
2362 if (esp->es_server.ea_state <= eapClosed)
2365 if (esp->es_server.ea_id != id) {
2366 dbglog("EAP: discarding Response %d; expected ID %d", id,
2367 esp->es_server.ea_id);
2371 esp->es_server.ea_responses++;
2374 error("EAP: empty Response message discarded");
2378 GETCHAR(typenum, inp);
2383 if (esp->es_server.ea_state != eapIdentify) {
2384 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2388 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2389 if (esp->es_server.ea_peer != NULL &&
2390 esp->es_server.ea_peer != remote_name)
2391 free(esp->es_server.ea_peer);
2392 esp->es_server.ea_peer = malloc(len + 1);
2393 if (esp->es_server.ea_peer == NULL) {
2394 esp->es_server.ea_peerlen = 0;
2395 eap_figure_next_state(esp, 1);
2398 BCOPY(inp, esp->es_server.ea_peer, len);
2399 esp->es_server.ea_peer[len] = '\0';
2400 esp->es_server.ea_peerlen = len;
2401 eap_figure_next_state(esp, 0);
2406 switch(esp->es_server.ea_state) {
2410 ets = (struct eaptls_session *) esp->es_server.ea_session;
2412 eap_figure_next_state(esp,
2413 eaptls_receive(esp->es_server.ea_session, inp, len));
2415 if(ets->alert_recv) {
2416 eap_send_failure(esp);
2423 dbglog("EAP-TLS ACK with extra data");
2425 eap_figure_next_state(esp, 0);
2428 case eapTlsRecvClient:
2429 /* Receive authentication response from client */
2431 GETCHAR(flags, inp);
2433 if(len == 1 && !flags) { /* Ack = ok */
2435 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2437 eap_send_success(esp);
2439 else { /* failure */
2440 warn("Server authentication failed");
2441 eap_send_failure(esp);
2445 warn("Bogus EAP-TLS packet received from client");
2447 eaptls_free_session(esp->es_server.ea_session);
2451 case eapTlsRecvAlertAck:
2452 eap_send_failure(esp);
2456 eap_figure_next_state(esp, 1);
2460 #endif /* USE_EAPTLS */
2462 case EAPT_NOTIFICATION:
2463 dbglog("EAP unexpected Notification; response discarded");
2468 info("EAP: Nak Response with no suggested protocol");
2469 eap_figure_next_state(esp, 1);
2473 GETCHAR(vallen, inp);
2476 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2477 /* Peer cannot Nak Identify Request */
2478 eap_figure_next_state(esp, 1);
2484 /* Run through SRP validator selection again. */
2485 esp->es_server.ea_state = eapIdentify;
2486 eap_figure_next_state(esp, 0);
2490 esp->es_server.ea_state = eapMD5Chall;
2494 /* Send EAP-TLS start packet */
2496 esp->es_server.ea_state = eapTlsStart;
2498 #endif /* USE_EAPTLS */
2502 info("EAP: peer proposes MSCHAPv2");
2503 esp->es_server.ea_state = eapMSCHAPv2Chall;
2508 dbglog("EAP: peer requesting unknown Type %d", vallen);
2509 switch (esp->es_server.ea_state) {
2513 esp->es_server.ea_state = eapMD5Chall;
2517 esp->es_server.ea_state = eapIdentify;
2518 eap_figure_next_state(esp, 0);
2528 if (esp->es_server.ea_state != eapMD5Chall) {
2529 error("EAP: unexpected MD5-Response");
2530 eap_figure_next_state(esp, 1);
2534 error("EAP: received MD5-Response with no data");
2535 eap_figure_next_state(esp, 1);
2538 GETCHAR(vallen, inp);
2540 if (vallen != 16 || vallen > len) {
2541 error("EAP: MD5-Response with bad length %d", vallen);
2542 eap_figure_next_state(esp, 1);
2546 /* Not so likely to happen. */
2547 if (len - vallen >= sizeof (rhostname)) {
2548 dbglog("EAP: trimming really long peer name down");
2549 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2550 rhostname[sizeof (rhostname) - 1] = '\0';
2552 BCOPY(inp + vallen, rhostname, len - vallen);
2553 rhostname[len - vallen] = '\0';
2556 /* In case the remote doesn't give us his name. */
2557 if (explicit_remote ||
2558 (remote_name[0] != '\0' && vallen == len))
2559 strlcpy(rhostname, remote_name, sizeof (rhostname));
2562 * Get the secret for authenticating the specified
2565 if (!get_secret(esp->es_unit, rhostname,
2566 esp->es_server.ea_name, secret, &secret_len, 1)) {
2567 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2568 eap_send_failure(esp);
2571 MD5_Init(&mdContext);
2572 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2573 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2574 BZERO(secret, sizeof (secret));
2575 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2576 MD5_Final(hash, &mdContext);
2577 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2578 eap_send_failure(esp);
2581 esp->es_server.ea_type = EAPT_MD5CHAP;
2582 eap_send_success(esp);
2583 eap_figure_next_state(esp, 0);
2584 if (esp->es_rechallenge != 0)
2585 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2591 error("EAP: received MSCHAPv2 with no data");
2592 eap_figure_next_state(esp, 1);
2595 GETCHAR(opcode, inp);
2600 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2601 error("EAP: unexpected MSCHAPv2-Response");
2602 eap_figure_next_state(esp, 1);
2605 /* skip MS ID + len */
2607 GETCHAR(vallen, inp);
2610 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2611 error("EAP: Invalid MSCHAPv2-Response "
2612 "length %d", vallen);
2613 eap_figure_next_state(esp, 1);
2617 /* Not so likely to happen. */
2618 if (len - vallen >= sizeof (rhostname)) {
2619 dbglog("EAP: trimming really long peer name down");
2620 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2621 rhostname[sizeof (rhostname) - 1] = '\0';
2623 BCOPY(inp + vallen, rhostname, len - vallen);
2624 rhostname[len - vallen] = '\0';
2627 /* In case the remote doesn't give us his name. */
2628 if (explicit_remote ||
2629 (remote_name[0] != '\0' && vallen == len))
2630 strlcpy(rhostname, remote_name, sizeof (rhostname));
2632 if (chap_verify_hook)
2633 chap_verifier = chap_verify_hook;
2635 chap_verifier = eap_chap_verify_response;
2637 esp->es_server.ea_id += 1;
2638 if ((*chap_verifier)(rhostname,
2639 esp->es_server.ea_name,
2641 &eap_chapms2_digest,
2645 sizeof(response_message)))
2647 info("EAP: MSCHAPv2 success for peer %q",
2649 esp->es_server.ea_type = EAPT_MSCHAPV2;
2650 eap_chapms2_send_request(esp,
2651 esp->es_server.ea_id,
2653 esp->es_server.ea_id,
2655 strlen(response_message));
2656 eap_figure_next_state(esp, 0);
2657 if (esp->es_rechallenge != 0)
2658 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2661 warn("EAP: MSCHAPv2 failure for peer %q",
2663 eap_chapms2_send_request(esp,
2664 esp->es_server.ea_id,
2666 esp->es_server.ea_id,
2668 strlen(response_message));
2672 info("EAP: MSCHAPv2 success confirmed");
2675 info("EAP: MSCHAPv2 failure confirmed");
2678 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2679 eap_send_nak(esp, id, EAPT_SRP);
2688 error("EAP: empty SRP Response");
2689 eap_figure_next_state(esp, 1);
2692 GETCHAR(typenum, inp);
2696 if (esp->es_server.ea_state != eapSRP1) {
2697 error("EAP: unexpected SRP Subtype 1 Response");
2698 eap_figure_next_state(esp, 1);
2703 ts = (struct t_server *)esp->es_server.ea_session;
2705 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2706 if (esp->es_server.ea_skey == NULL) {
2707 /* Client's A value is bogus; terminate now */
2708 error("EAP: bogus A value from client");
2709 eap_send_failure(esp);
2711 eap_figure_next_state(esp, 0);
2715 case EAPSRP_CVALIDATOR:
2716 if (esp->es_server.ea_state != eapSRP2) {
2717 error("EAP: unexpected SRP Subtype 2 Response");
2718 eap_figure_next_state(esp, 1);
2721 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2722 error("EAP: M1 length %d < %d", len,
2723 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2724 eap_figure_next_state(esp, 1);
2727 GETLONG(esp->es_server.ea_keyflags, inp);
2728 ts = (struct t_server *)esp->es_server.ea_session;
2730 if (t_serververify(ts, inp)) {
2731 info("EAP: unable to validate client identity");
2732 eap_send_failure(esp);
2735 eap_figure_next_state(esp, 0);
2739 if (esp->es_server.ea_state != eapSRP3) {
2740 error("EAP: unexpected SRP Subtype 3 Response");
2741 eap_send_failure(esp);
2744 esp->es_server.ea_type = EAPT_SRP;
2745 eap_send_success(esp);
2746 eap_figure_next_state(esp, 0);
2747 if (esp->es_rechallenge != 0)
2748 TIMEOUT(eap_rechallenge, esp,
2749 esp->es_rechallenge);
2750 if (esp->es_lwrechallenge != 0)
2751 TIMEOUT(srp_lwrechallenge, esp,
2752 esp->es_lwrechallenge);
2755 case EAPSRP_LWRECHALLENGE:
2756 if (esp->es_server.ea_state != eapSRP4) {
2757 info("EAP: unexpected SRP Subtype 4 Response");
2760 if (len != SHA_DIGESTSIZE) {
2761 error("EAP: bad Lightweight rechallenge "
2767 SHA1Update(&ctxt, &vallen, 1);
2768 SHA1Update(&ctxt, esp->es_server.ea_skey,
2770 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2771 SHA1Update(&ctxt, esp->es_server.ea_peer,
2772 esp->es_server.ea_peerlen);
2773 SHA1Final(dig, &ctxt);
2774 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2775 error("EAP: failed Lightweight rechallenge");
2776 eap_send_failure(esp);
2779 esp->es_server.ea_state = eapOpen;
2780 if (esp->es_lwrechallenge != 0)
2781 TIMEOUT(srp_lwrechallenge, esp,
2782 esp->es_lwrechallenge);
2786 #endif /* USE_SRP */
2789 /* This can't happen. */
2790 error("EAP: unknown Response type %d; ignored", typenum);
2794 if (esp->es_server.ea_timeout > 0) {
2795 UNTIMEOUT(eap_server_timeout, (void *)esp);
2798 if (esp->es_server.ea_state != eapBadAuth &&
2799 esp->es_server.ea_state != eapOpen) {
2800 esp->es_server.ea_id++;
2801 eap_send_request(esp);
2806 * eap_success - Receive EAP Success message (client mode).
2809 eap_success(eap_state *esp, u_char *inp, int id, int len)
2811 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2813 && esp->es_client.ea_state != eapTlsRecvSuccess
2814 #endif /* USE_EAPTLS */
2816 dbglog("EAP unexpected success message in state %s (%d)",
2817 eap_state_name(esp->es_client.ea_state),
2818 esp->es_client.ea_state);
2823 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2824 eapTlsRecvSuccess) {
2825 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2826 eap_state_name(esp->es_client.ea_state),
2827 esp->es_client.ea_state);
2830 #endif /* USE_EAPTLS */
2832 if (esp->es_client.ea_timeout > 0) {
2833 UNTIMEOUT(eap_client_timeout, (void *)esp);
2837 /* This is odd. The spec doesn't allow for this. */
2841 esp->es_client.ea_state = eapOpen;
2842 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2846 * eap_failure - Receive EAP Failure message (client mode).
2849 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2852 * Ignore failure messages if we're not open
2854 if (esp->es_client.ea_state <= eapClosed)
2857 if (!eap_client_active(esp)) {
2858 dbglog("EAP unexpected failure message in state %s (%d)",
2859 eap_state_name(esp->es_client.ea_state),
2860 esp->es_client.ea_state);
2863 if (esp->es_client.ea_timeout > 0) {
2864 UNTIMEOUT(eap_client_timeout, (void *)esp);
2868 /* This is odd. The spec doesn't allow for this. */
2872 esp->es_client.ea_state = eapBadAuth;
2874 error("EAP: peer reports authentication failure");
2875 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2879 * eap_input - Handle received EAP message.
2882 eap_input(int unit, u_char *inp, int inlen)
2884 eap_state *esp = &eap_states[unit];
2889 * Parse header (code, id and length). If packet too short,
2892 if (inlen < EAP_HEADERLEN) {
2893 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2899 if (len < EAP_HEADERLEN || len > inlen) {
2900 error("EAP: packet has illegal length field %d (%d..%d)", len,
2901 EAP_HEADERLEN, inlen);
2904 len -= EAP_HEADERLEN;
2906 /* Dispatch based on message code */
2909 eap_request(esp, inp, id, len);
2913 eap_response(esp, inp, id, len);
2917 eap_success(esp, inp, id, len);
2921 eap_failure(esp, inp, id, len);
2924 default: /* XXX Need code reject */
2925 /* Note: it's not legal to send EAP Nak here. */
2926 warn("EAP: unknown code %d received", code);
2932 * eap_printpkt - print the contents of an EAP packet.
2934 static char *eap_codenames[] = {
2935 "Request", "Response", "Success", "Failure"
2938 static char *eap_typenames[] = {
2939 "Identity", "Notification", "Nak", "MD5-Challenge",
2940 "OTP", "Generic-Token", NULL, NULL,
2941 "RSA", "DSS", "KEA", "KEA-Validate",
2942 "TLS", "Defender", "Windows 2000", "Arcot",
2943 "Cisco", "Nokia", "SRP", NULL,
2944 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2949 eap_printpkt(u_char *inp, int inlen,
2950 void (*printer) (void *, char *, ...), void *arg)
2952 int code, id, len, rtype, vallen;
2957 #endif /* USE_EAPTLS */
2962 if (inlen < EAP_HEADERLEN)
2968 if (len < EAP_HEADERLEN || len > inlen)
2971 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2972 printer(arg, " %s", eap_codenames[code-1]);
2974 printer(arg, " code=0x%x", code);
2975 printer(arg, " id=0x%x", id);
2976 len -= EAP_HEADERLEN;
2980 printer(arg, " <missing type>");
2983 GETCHAR(rtype, inp);
2986 rtype <= sizeof (eap_typenames) / sizeof (char *))
2987 printer(arg, " %s", eap_typenames[rtype-1]);
2989 printer(arg, " type=0x%x", rtype);
2992 case EAPT_NOTIFICATION:
2994 printer(arg, " <Message ");
2995 print_string((char *)inp, len, printer, arg);
3000 printer(arg, " <No message>");
3007 GETCHAR(vallen, inp);
3011 printer(arg, " <Value%.*B>", vallen, inp);
3012 INCPTR(vallen, inp);
3015 printer(arg, " <Name ");
3016 print_string((char *)inp, len, printer, arg);
3021 printer(arg, " <No name>");
3029 GETCHAR(opcode, inp);
3032 case CHAP_CHALLENGE:
3035 GETCHAR(vallen, inp);
3040 printer(arg, " Challenge <");
3041 for (; vallen > 0; --vallen) {
3044 printer(arg, "%.2x", val);
3048 printer(arg, ", <Name ");
3049 print_string((char *)inp, len, printer, arg);
3054 printer(arg, ", <No name>");
3060 printer(arg, " Success <Message ");
3061 print_string((char *)inp, len, printer, arg);
3067 printer(arg, " Failure <Message ");
3068 print_string((char *)inp, len, printer, arg);
3074 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3084 GETCHAR(flags, inp);
3087 if(flags == 0 && len == 0){
3088 printer(arg, " Ack");
3092 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3093 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3094 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3096 #endif /* USE_EAPTLS */
3101 GETCHAR(vallen, inp);
3103 printer(arg, "-%d", vallen);
3105 case EAPSRP_CHALLENGE:
3106 GETCHAR(vallen, inp);
3111 printer(arg, " <Name ");
3112 print_string((char *)inp, vallen, printer,
3116 printer(arg, " <No name>");
3118 INCPTR(vallen, inp);
3120 GETCHAR(vallen, inp);
3124 printer(arg, " <s%.*B>", vallen, inp);
3125 INCPTR(vallen, inp);
3127 GETCHAR(vallen, inp);
3132 printer(arg, " <Default g=2>");
3134 printer(arg, " <g%.*B>", vallen, inp);
3136 INCPTR(vallen, inp);
3139 printer(arg, " <Default N>");
3141 printer(arg, " <N%.*B>", len, inp);
3148 printer(arg, " <B%.*B>", len, inp);
3153 case EAPSRP_SVALIDATOR:
3154 if (len < sizeof (u_int32_t))
3157 len -= sizeof (u_int32_t);
3158 if (uval & SRPVAL_EBIT) {
3160 uval &= ~SRPVAL_EBIT;
3163 printer(arg, " f<%X>", uval);
3165 if ((vallen = len) > SHA_DIGESTSIZE)
3166 vallen = SHA_DIGESTSIZE;
3167 printer(arg, " <M2%.*B%s>", len, inp,
3168 len < SHA_DIGESTSIZE ? "?" : "");
3169 INCPTR(vallen, inp);
3172 printer(arg, " <PN%.*B>", len, inp);
3178 case EAPSRP_LWRECHALLENGE:
3179 printer(arg, " <Challenge%.*B>", len, inp);
3191 GETCHAR(rtype, inp);
3194 rtype <= sizeof (eap_typenames) / sizeof (char *))
3195 printer(arg, " %s", eap_typenames[rtype-1]);
3197 printer(arg, " type=0x%x", rtype);
3201 printer(arg, " <Name ");
3202 print_string((char *)inp, len, printer, arg);
3213 GETCHAR(flags, inp);
3216 if(flags == 0 && len == 0){
3217 printer(arg, " Ack");
3221 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3222 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3223 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3226 #endif /* USE_EAPTLS */
3230 printer(arg, " <missing hint>");
3233 GETCHAR(rtype, inp);
3235 printer(arg, " <Suggested-type %02X", rtype);
3237 rtype <= sizeof (eap_typenames) / sizeof (char *))
3238 printer(arg, " (%s)", eap_typenames[rtype-1]);
3244 printer(arg, " <missing length>");
3247 GETCHAR(vallen, inp);
3251 printer(arg, " <Value%.*B>", vallen, inp);
3252 INCPTR(vallen, inp);
3255 printer(arg, " <Name ");
3256 print_string((char *)inp, len, printer, arg);
3261 printer(arg, " <No name>");
3269 GETCHAR(opcode, inp);
3275 GETCHAR(vallen, inp);
3280 printer(arg, " Response <");
3281 for (; vallen > 0; --vallen) {
3284 printer(arg, "%.2x", val);
3288 printer(arg, ", <Name ");
3289 print_string((char *)inp, len, printer, arg);
3294 printer(arg, ", <No name>");
3298 printer(arg, " Success");
3301 printer(arg, " Failure");
3304 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3313 GETCHAR(vallen, inp);
3315 printer(arg, "-%d", vallen);
3318 printer(arg, " <A%.*B>", len, inp);
3323 case EAPSRP_CVALIDATOR:
3324 if (len < sizeof (u_int32_t))
3327 len -= sizeof (u_int32_t);
3328 if (uval & SRPVAL_EBIT) {
3330 uval &= ~SRPVAL_EBIT;
3333 printer(arg, " f<%X>", uval);
3335 printer(arg, " <M1%.*B%s>", len, inp,
3336 len == SHA_DIGESTSIZE ? "" : "?");
3344 case EAPSRP_LWRECHALLENGE:
3345 printer(arg, " <Response%.*B%s>", len, inp,
3346 len == SHA_DIGESTSIZE ? "" : "?");
3347 if ((vallen = len) > SHA_DIGESTSIZE)
3348 vallen = SHA_DIGESTSIZE;
3349 INCPTR(vallen, inp);
3357 case EAP_SUCCESS: /* No payload expected for these! */
3362 printer(arg, " <truncated>");
3367 printer(arg, "%8B...", inp);
3369 printer(arg, "%.*B", len, inp);
3372 return (inp - pstart);