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
51 #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
62 #include <sys/types.h>
69 #include "pathnames.h"
80 #ifndef SHA_DIGESTSIZE
81 #define SHA_DIGESTSIZE 20
86 #endif /* USE_EAPTLS */
93 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
95 static char *pn_secret = NULL; /* Pseudonym generating secret */
99 * Command-line options.
101 static option_t eap_option_list[] = {
102 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
103 "Set retransmit timeout for EAP Requests (server)" },
104 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
105 "Set max number of EAP Requests sent (server)" },
106 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
107 "Set time limit for peer EAP authentication" },
108 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
109 "Set max number of EAP Requests allows (client)" },
110 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
111 "Set interval for EAP rechallenge" },
113 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
114 "Set interval for SRP lightweight rechallenge" },
115 { "srp-pn-secret", o_string, &pn_secret,
116 "Long term pseudonym generation secret" },
117 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
118 "Use pseudonym if offered one by server", 1 },
124 * Protocol entry points.
126 static void eap_init __P((int unit));
127 static void eap_input __P((int unit, u_char *inp, int inlen));
128 static void eap_protrej __P((int unit));
129 static void eap_lowerup __P((int unit));
130 static void eap_lowerdown __P((int unit));
131 static int eap_printpkt __P((u_char *inp, int inlen,
132 void (*)(void *arg, char *fmt, ...), void *arg));
134 struct protent eap_protent = {
135 PPP_EAP, /* protocol number */
136 eap_init, /* initialization procedure */
137 eap_input, /* process a received packet */
138 eap_protrej, /* process a received protocol-reject */
139 eap_lowerup, /* lower layer has gone up */
140 eap_lowerdown, /* lower layer has gone down */
141 NULL, /* open the protocol */
142 NULL, /* close the protocol */
143 eap_printpkt, /* print a packet in readable form */
144 NULL, /* process a received data packet */
145 1, /* protocol enabled */
146 "EAP", /* text name of protocol */
147 NULL, /* text name of corresponding data protocol */
148 eap_option_list, /* list of command-line options */
149 NULL, /* check requested options; assign defaults */
150 NULL, /* configure interface for demand-dial */
151 NULL /* say whether to bring up link for this pkt */
155 * A well-known 2048 bit modulus.
157 static const u_char wkmodulus[] = {
158 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
159 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
160 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
161 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
162 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
163 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
164 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
165 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
166 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
167 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
168 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
169 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
170 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
171 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
172 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
173 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
174 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
175 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
176 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
177 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
178 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
179 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
180 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
181 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
182 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
183 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
184 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
185 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
186 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
187 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
188 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
189 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
192 /* Local forward declarations. */
193 static void eap_server_timeout __P((void *arg));
196 * Convert EAP state code to printable string for debug.
200 enum eap_state_code esc;
202 static const char *state_names[] = { EAP_STATES };
204 return (state_names[(int)esc]);
208 * eap_init - Initialize state for an EAP user. This is currently
209 * called once by main() during start-up.
215 eap_state *esp = &eap_states[unit];
217 BZERO(esp, sizeof (*esp));
219 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
220 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
221 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
222 esp->es_client.ea_timeout = EAP_DEFREQTIME;
223 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
225 esp->es_client.ea_using_eaptls = 0;
226 #endif /* USE_EAPTLS */
230 * eap_client_timeout - Give up waiting for the peer to send any
234 eap_client_timeout(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(unit, localname)
258 eap_state *esp = &eap_states[unit];
260 /* Save the peer name we're given */
261 esp->es_client.ea_name = localname;
262 esp->es_client.ea_namelen = strlen(localname);
264 esp->es_client.ea_state = eapListen;
267 * Start a timer so that if the other end just goes
268 * silent, we don't sit here waiting forever.
270 if (esp->es_client.ea_timeout > 0)
271 TIMEOUT(eap_client_timeout, (void *)esp,
272 esp->es_client.ea_timeout);
276 * Format a standard EAP Failure message and send it to the peer.
280 eap_send_failure(esp)
285 outp = outpacket_buf;
287 MAKEHEADER(outp, PPP_EAP);
289 PUTCHAR(EAP_FAILURE, outp);
290 esp->es_server.ea_id++;
291 PUTCHAR(esp->es_server.ea_id, outp);
292 PUTSHORT(EAP_HEADERLEN, outp);
294 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
296 esp->es_server.ea_state = eapBadAuth;
297 auth_peer_fail(esp->es_unit, PPP_EAP);
301 * Format a standard EAP Success message and send it to the peer.
305 eap_send_success(esp)
310 outp = outpacket_buf;
312 MAKEHEADER(outp, PPP_EAP);
314 PUTCHAR(EAP_SUCCESS, outp);
315 esp->es_server.ea_id++;
316 PUTCHAR(esp->es_server.ea_id, outp);
317 PUTSHORT(EAP_HEADERLEN, outp);
319 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
321 auth_peer_success(esp->es_unit, PPP_EAP, 0,
322 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
327 * Set DES key according to pseudonym-generating secret and current
331 pncrypt_setkey(int timeoffs)
336 u_char dig[SHA_DIGESTSIZE];
339 if (pn_secret == NULL)
341 reftime = time(NULL) + timeoffs;
342 tp = localtime(&reftime);
344 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
345 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
346 SHA1Update(&ctxt, tbuf, strlen(tbuf));
347 SHA1Final(dig, &ctxt);
348 return (DesSetkey(dig));
351 static char base64[] =
352 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
360 b64enc(bs, inp, inlen, outp)
369 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
372 if (bs->bs_offs >= 24) {
373 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
374 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
375 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
376 *outp++ = base64[bs->bs_bits & 0x3F];
392 if (bs->bs_offs == 8) {
393 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
394 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
396 } else if (bs->bs_offs == 16) {
397 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
398 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
399 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
408 b64dec(bs, inp, inlen, outp)
418 if ((cp = strchr(base64, *inp++)) == NULL)
420 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
423 if (bs->bs_offs >= 8) {
424 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
434 * Assume that current waiting server state is complete and figure
435 * next state to use based on available authentication data. 'status'
436 * indicates if there was an error in handling the last query. It is
437 * 0 for success and non-zero for failure.
440 eap_figure_next_state(esp, status)
445 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
447 struct t_confent *tce, mytce;
450 int id, i, plen, toffs;
455 struct eaptls_session *ets;
457 char secret[MAXWORDLEN];
458 #endif /* USE_EAPTLS */
460 esp->es_server.ea_timeout = esp->es_savedtime;
462 esp->es_server.ea_prev_state = esp->es_server.ea_state;
463 #endif /* USE_EAPTLS */
464 switch (esp->es_server.ea_state) {
470 /* Discard any previous session. */
471 ts = (struct t_server *)esp->es_server.ea_session;
474 esp->es_server.ea_session = NULL;
475 esp->es_server.ea_skey = NULL;
479 esp->es_server.ea_state = eapBadAuth;
483 /* If we've got a pseudonym, try to decode to real name. */
484 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
485 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
486 SRP_PSEUDO_LEN) == 0 &&
487 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
489 BZERO(&bs, sizeof (bs));
491 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
492 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
495 for (i = 0; i < 5; i++) {
496 pncrypt_setkey(toffs);
498 if (!DesDecrypt(secbuf, clear)) {
499 dbglog("no DES here; cannot decode "
503 id = *(unsigned char *)clear;
504 if (id + 1 <= plen && id + 9 > plen)
507 if (plen % 8 == 0 && i < 5) {
509 * Note that this is always shorter than the
510 * original stored string, so there's no need
513 if ((i = plen = *(unsigned char *)clear) > 7)
515 esp->es_server.ea_peerlen = plen;
516 dp = (unsigned char *)esp->es_server.ea_peer;
517 BCOPY(clear + 1, dp, i);
522 (void) DesDecrypt(sp, dp);
527 esp->es_server.ea_peer[
528 esp->es_server.ea_peerlen] = '\0';
529 dbglog("decoded pseudonym to \"%.*q\"",
530 esp->es_server.ea_peerlen,
531 esp->es_server.ea_peer);
533 dbglog("failed to decode real name");
534 /* Stay in eapIdentfy state; requery */
538 /* Look up user in secrets database. */
539 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
540 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
541 /* Set up default in case SRP entry is bad */
542 esp->es_server.ea_state = eapMD5Chall;
543 /* Get t_confent based on index in srp-secrets */
544 id = strtol((char *)secbuf, &cp, 10);
545 if (*cp++ != ':' || id < 0)
549 mytce.modulus.data = (u_char *)wkmodulus;
550 mytce.modulus.len = sizeof (wkmodulus);
551 mytce.generator.data = (u_char *)"\002";
552 mytce.generator.len = 1;
554 } else if ((tce = gettcid(id)) != NULL) {
556 * Client will have to verify this modulus/
557 * generator combination, and that will take
558 * a while. Lengthen the timeout here.
560 if (esp->es_server.ea_timeout > 0 &&
561 esp->es_server.ea_timeout < 30)
562 esp->es_server.ea_timeout = 30;
566 if ((cp2 = strchr(cp, ':')) == NULL)
569 tpw.pebuf.name = esp->es_server.ea_peer;
570 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
572 tpw.pebuf.password.data = tpw.pwbuf;
573 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
575 tpw.pebuf.salt.data = tpw.saltbuf;
576 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
578 esp->es_server.ea_session = (void *)ts;
579 esp->es_server.ea_state = eapSRP1;
580 vals[0] = esp->es_server.ea_id + 1;
582 t_serveraddexdata(ts, vals, 2);
583 /* Generate B; must call before t_servergetkey() */
589 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
590 esp->es_server.ea_name, secret, &secret_len, 1)) {
592 esp->es_server.ea_state = eapTlsStart;
595 #endif /* USE_EAPTLS */
597 esp->es_server.ea_state = eapMD5Chall;
602 /* Initialize ssl session */
603 if(!eaptls_init_ssl_server(esp)) {
604 esp->es_server.ea_state = eapBadAuth;
608 esp->es_server.ea_state = eapTlsRecv;
612 ets = (struct eaptls_session *) esp->es_server.ea_session;
614 if(ets->alert_sent) {
615 esp->es_server.ea_state = eapTlsSendAlert;
620 esp->es_server.ea_state = eapBadAuth;
623 ets = (struct eaptls_session *) esp->es_server.ea_session;
626 esp->es_server.ea_state = eapTlsSendAck;
628 esp->es_server.ea_state = eapTlsSend;
632 ets = (struct eaptls_session *) esp->es_server.ea_session;
635 esp->es_server.ea_state = eapTlsRecvAck;
637 if(SSL_is_init_finished(ets->ssl))
638 esp->es_server.ea_state = eapTlsRecvClient;
640 /* JJK Add "TLS empty record" message here ??? */
641 esp->es_server.ea_state = eapTlsRecv;
645 esp->es_server.ea_state = eapTlsRecv;
651 esp->es_server.ea_state = eapBadAuth;
655 esp->es_server.ea_state = eapTlsSend;
658 case eapTlsSendAlert:
659 esp->es_server.ea_state = eapTlsRecvAlertAck;
661 #endif /* USE_EAPTLS */
665 ts = (struct t_server *)esp->es_server.ea_session;
666 if (ts != NULL && status != 0) {
668 esp->es_server.ea_session = NULL;
669 esp->es_server.ea_skey = NULL;
673 esp->es_server.ea_state = eapMD5Chall;
674 } else if (status != 0 || esp->es_server.ea_session == NULL) {
675 esp->es_server.ea_state = eapBadAuth;
677 esp->es_server.ea_state = eapSRP2;
683 ts = (struct t_server *)esp->es_server.ea_session;
684 if (ts != NULL && status != 0) {
686 esp->es_server.ea_session = NULL;
687 esp->es_server.ea_skey = NULL;
690 if (status != 0 || esp->es_server.ea_session == NULL) {
691 esp->es_server.ea_state = eapBadAuth;
693 esp->es_server.ea_state = eapSRP3;
700 ts = (struct t_server *)esp->es_server.ea_session;
701 if (ts != NULL && status != 0) {
703 esp->es_server.ea_session = NULL;
704 esp->es_server.ea_skey = NULL;
707 if (status != 0 || esp->es_server.ea_session == NULL) {
708 esp->es_server.ea_state = eapBadAuth;
710 esp->es_server.ea_state = eapOpen;
715 case eapMSCHAPv2Chall:
719 esp->es_server.ea_state = eapBadAuth;
721 esp->es_server.ea_state = eapOpen;
726 esp->es_server.ea_state = eapBadAuth;
729 if (esp->es_server.ea_state == eapBadAuth)
730 eap_send_failure(esp);
733 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));
734 #endif /* USE_EAPTLS */
739 eap_chapms2_verify_response(int id, char *name,
740 unsigned char *secret, int secret_len,
741 unsigned char *challenge, unsigned char *response,
742 char *message, int message_space)
744 unsigned char md[MS_CHAP2_RESPONSE_LEN];
745 char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
746 int challenge_len, response_len;
748 challenge_len = *challenge++; /* skip length, is 16 */
749 response_len = *response++;
750 if (response_len != MS_CHAP2_RESPONSE_LEN)
751 goto bad; /* not even the right length */
753 /* Generate the expected response and our mutual auth. */
754 ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
755 (char *)secret, secret_len, md,
756 (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
758 /* compare MDs and send the appropriate status */
760 * Per RFC 2759, success message must be formatted as
761 * "S=<auth_string> M=<message>"
763 * <auth_string> is the Authenticator Response (mutual auth)
764 * <message> is a text message
766 * However, some versions of Windows (win98 tested) do not know
767 * about the M=<message> part (required per RFC 2759) and flag
768 * it as an error (reported incorrectly as an encryption error
769 * to the user). Since the RFC requires it, and it can be
770 * useful information, we supply it if the peer is a conforming
771 * system. Luckily (?), win98 sets the Flags field to 0x04
772 * (contrary to RFC requirements) so we can use that to
773 * distinguish between conforming and non-conforming systems.
775 * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
776 * help debugging this.
778 if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
779 MS_CHAP2_NTRESP_LEN) == 0) {
780 if (response[MS_CHAP2_FLAGS])
781 slprintf(message, message_space, "S=%s", saresponse);
783 slprintf(message, message_space, "S=%s M=%s",
784 saresponse, "Access granted");
790 * Failure message must be formatted as
791 * "E=e R=r C=c V=v M=m"
793 * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
794 * r = retry (we use 1, ok to retry)
795 * c = challenge to use for next response, we reuse previous
796 * v = Change Password version supported, we use 0
799 * The M=m part is only for MS-CHAPv2. Neither win2k nor
800 * win98 (others untested) display the message to the user anyway.
801 * They also both ignore the E=e code.
803 * Note that it's safe to reuse the same challenge as we don't
804 * actually accept another response based on the error message
805 * (and no clients try to resend a response anyway).
807 * Basically, this whole bit is useless code, even the small
808 * implementation here is only because of overspecification.
810 slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
811 challenge_len, challenge, "Access denied");
815 static struct chap_digest_type eap_chapms2_digest = {
816 CHAP_MICROSOFT_V2, /* code */
817 NULL, /* chapms2_generate_challenge, */
818 eap_chapms2_verify_response,
819 NULL, /* chapms2_make_response, */
820 NULL, /* chapms2_check_success, */
821 NULL, /* chapms_handle_failure, */
825 * eap_chap_verify_response - check whether the peer's response matches
826 * what we think it should be. Returns 1 if it does (authentication
827 * succeeded), or 0 if it doesn't.
830 eap_chap_verify_response(char *name, char *ourname, int id,
831 struct chap_digest_type *digest,
832 unsigned char *challenge, unsigned char *response,
833 char *message, int message_space)
836 unsigned char secret[MAXSECRETLEN];
839 /* Get the secret that the peer is supposed to know */
840 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
841 error("No CHAP secret found for authenticating %q", name);
845 ok = digest->verify_response(id, name, secret, secret_len, challenge,
846 response, message, message_space);
847 memset(secret, 0, sizeof(secret));
853 * Format and send an CHAPV2-Success/Failure EAP Request message.
856 eap_chapms2_send_request(eap_state *esp, u_char id,
857 u_char opcode, u_char chapid,
858 char *message, int message_len)
863 outp = outpacket_buf;
865 MAKEHEADER(outp, PPP_EAP);
867 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
868 msglen += message_len;
870 PUTCHAR(EAP_REQUEST, outp);
872 PUTSHORT(msglen, outp);
873 PUTCHAR(EAPT_MSCHAPV2, outp);
874 PUTCHAR(opcode, outp);
875 PUTCHAR(chapid, outp);
877 PUTSHORT(msglen - 5, outp);
878 BCOPY(message, outp, message_len);
880 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
882 if (opcode == CHAP_SUCCESS) {
883 auth_peer_success(esp->es_unit, PPP_EAP, 0,
884 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
887 esp->es_server.ea_state = eapBadAuth;
888 auth_peer_fail(esp->es_unit, PPP_EAP);
894 * Format an EAP Request message and send it to the peer. Message
895 * type depends on current state. (Server operation)
898 eap_send_request(esp)
909 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
915 /* Handle both initial auth and restart */
916 if (esp->es_server.ea_state < eapIdentify &&
917 esp->es_server.ea_state != eapInitial) {
918 esp->es_server.ea_state = eapIdentify;
919 if (explicit_remote) {
921 * If we already know the peer's
922 * unauthenticated name, then there's no
923 * reason to ask. Go to next state instead.
925 esp->es_server.ea_peer = remote_name;
926 esp->es_server.ea_peerlen = strlen(remote_name);
927 eap_figure_next_state(esp, 0);
931 if (esp->es_server.ea_maxrequests > 0 &&
932 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
933 if (esp->es_server.ea_responses > 0)
934 error("EAP: too many Requests sent");
936 error("EAP: no response to Requests");
937 eap_send_failure(esp);
941 outp = outpacket_buf;
943 MAKEHEADER(outp, PPP_EAP);
945 PUTCHAR(EAP_REQUEST, outp);
946 PUTCHAR(esp->es_server.ea_id, outp);
950 switch (esp->es_server.ea_state) {
952 PUTCHAR(EAPT_IDENTITY, outp);
954 challen = strlen(str);
955 BCOPY(str, outp, challen);
956 INCPTR(challen, outp);
960 PUTCHAR(EAPT_MD5CHAP, outp);
962 * pick a random challenge length between
963 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
965 challen = (drand48() *
966 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
967 MIN_CHALLENGE_LENGTH;
968 PUTCHAR(challen, outp);
969 esp->es_challen = challen;
970 ptr = esp->es_challenge;
971 while (--challen >= 0)
972 *ptr++ = (u_char) (drand48() * 0x100);
973 BCOPY(esp->es_challenge, outp, esp->es_challen);
974 INCPTR(esp->es_challen, outp);
975 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
976 INCPTR(esp->es_server.ea_namelen, outp);
980 case eapMSCHAPv2Chall:
982 esp->es_challen = challen;
983 esp->es_challenge[0] = challen;
984 random_bytes(&esp->es_challenge[1], challen);
986 PUTCHAR(EAPT_MSCHAPV2, outp);
987 PUTCHAR(CHAP_CHALLENGE, outp);
988 PUTCHAR(esp->es_server.ea_id, outp);
990 PUTSHORT(5 + challen +
991 esp->es_server.ea_namelen,
993 /* challen + challenge */
994 BCOPY(esp->es_challenge, outp, challen+1);
995 INCPTR(challen+1, outp);
996 BCOPY(esp->es_server.ea_name,
998 esp->es_server.ea_namelen);
999 INCPTR(esp->es_server.ea_namelen, outp);
1005 PUTCHAR(EAPT_TLS, outp);
1006 PUTCHAR(EAP_TLS_FLAGS_START, outp);
1007 eap_figure_next_state(esp, 0);
1011 eaptls_send(esp->es_server.ea_session, &outp);
1012 eap_figure_next_state(esp, 0);
1016 PUTCHAR(EAPT_TLS, outp);
1018 eap_figure_next_state(esp, 0);
1021 case eapTlsSendAlert:
1022 eaptls_send(esp->es_server.ea_session, &outp);
1023 eap_figure_next_state(esp, 0);
1025 #endif /* USE_EAPTLS */
1029 PUTCHAR(EAPT_SRP, outp);
1030 PUTCHAR(EAPSRP_CHALLENGE, outp);
1032 PUTCHAR(esp->es_server.ea_namelen, outp);
1033 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
1034 INCPTR(esp->es_server.ea_namelen, outp);
1036 ts = (struct t_server *)esp->es_server.ea_session;
1038 PUTCHAR(ts->s.len, outp);
1039 BCOPY(ts->s.data, outp, ts->s.len);
1040 INCPTR(ts->s.len, outp);
1042 if (ts->g.len == 1 && ts->g.data[0] == 2) {
1045 PUTCHAR(ts->g.len, outp);
1046 BCOPY(ts->g.data, outp, ts->g.len);
1047 INCPTR(ts->g.len, outp);
1050 if (ts->n.len != sizeof (wkmodulus) ||
1051 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
1052 BCOPY(ts->n.data, outp, ts->n.len);
1053 INCPTR(ts->n.len, outp);
1058 PUTCHAR(EAPT_SRP, outp);
1059 PUTCHAR(EAPSRP_SKEY, outp);
1061 ts = (struct t_server *)esp->es_server.ea_session;
1063 BCOPY(ts->B.data, outp, ts->B.len);
1064 INCPTR(ts->B.len, outp);
1068 PUTCHAR(EAPT_SRP, outp);
1069 PUTCHAR(EAPSRP_SVALIDATOR, outp);
1070 PUTLONG(SRPVAL_EBIT, outp);
1071 ts = (struct t_server *)esp->es_server.ea_session;
1073 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
1074 INCPTR(SHA_DIGESTSIZE, outp);
1076 if (pncrypt_setkey(0)) {
1077 /* Generate pseudonym */
1079 cp = (unsigned char *)esp->es_server.ea_peer;
1080 if ((j = i = esp->es_server.ea_peerlen) > 7)
1083 BCOPY(cp, clear + 1, j);
1086 if (!DesEncrypt(clear, cipher)) {
1087 dbglog("no DES here; not generating pseudonym");
1090 BZERO(&b64, sizeof (b64));
1091 outp++; /* space for pseudonym length */
1092 outp += b64enc(&b64, cipher, 8, outp);
1094 (void) DesEncrypt(cp, cipher);
1095 outp += b64enc(&b64, cipher, 8, outp);
1100 BCOPY(cp, clear, i);
1103 *cp++ = drand48() * 0x100;
1106 (void) DesEncrypt(clear, cipher);
1107 outp += b64enc(&b64, cipher, 8, outp);
1109 outp += b64flush(&b64, outp);
1111 /* Set length and pad out to next 20 octet boundary */
1112 i = outp - optr - 1;
1114 i %= SHA_DIGESTSIZE;
1116 while (i < SHA_DIGESTSIZE) {
1117 *outp++ = drand48() * 0x100;
1122 /* Obscure the pseudonym with SHA1 hash */
1124 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1125 SHA1Update(&ctxt, esp->es_server.ea_skey,
1127 SHA1Update(&ctxt, esp->es_server.ea_peer,
1128 esp->es_server.ea_peerlen);
1129 while (optr < outp) {
1130 SHA1Final(dig, &ctxt);
1132 while (cp < dig + SHA_DIGESTSIZE)
1135 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1136 SHA1Update(&ctxt, esp->es_server.ea_skey,
1138 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1145 PUTCHAR(EAPT_SRP, outp);
1146 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1147 challen = MIN_CHALLENGE_LENGTH +
1148 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1149 esp->es_challen = challen;
1150 ptr = esp->es_challenge;
1151 while (--challen >= 0)
1152 *ptr++ = drand48() * 0x100;
1153 BCOPY(esp->es_challenge, outp, esp->es_challen);
1154 INCPTR(esp->es_challen, outp);
1156 #endif /* USE_SRP */
1162 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1163 PUTSHORT(outlen, lenloc);
1165 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1167 esp->es_server.ea_requests++;
1169 if (esp->es_server.ea_timeout > 0)
1170 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1174 * eap_authpeer - Authenticate our peer (behave as server).
1176 * Start server state and send first request. This is called only
1177 * after eap_lowerup.
1180 eap_authpeer(unit, localname)
1184 eap_state *esp = &eap_states[unit];
1186 /* Save the name we're given. */
1187 esp->es_server.ea_name = localname;
1188 esp->es_server.ea_namelen = strlen(localname);
1190 esp->es_savedtime = esp->es_server.ea_timeout;
1192 /* Lower layer up yet? */
1193 if (esp->es_server.ea_state == eapInitial ||
1194 esp->es_server.ea_state == eapPending) {
1195 esp->es_server.ea_state = eapPending;
1199 esp->es_server.ea_state = eapPending;
1201 /* ID number not updated here intentionally; hashed into M1 */
1202 eap_send_request(esp);
1206 * eap_server_timeout - Retransmission timer for sending Requests
1210 eap_server_timeout(arg)
1217 #endif /* USE_EAPTLS */
1219 eap_state *esp = (eap_state *) arg;
1221 if (!eap_server_active(esp))
1225 switch(esp->es_server.ea_prev_state) {
1228 * In eap-tls the state changes after a request, so we return to
1229 * previous state ...
1232 case(eapTlsSendAck):
1233 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1237 * ... or resend the stored data
1240 case(eapTlsSendAlert):
1241 outp = outpacket_buf;
1242 MAKEHEADER(outp, PPP_EAP);
1243 PUTCHAR(EAP_REQUEST, outp);
1244 PUTCHAR(esp->es_server.ea_id, outp);
1248 eaptls_retransmit(esp->es_server.ea_session, &outp);
1250 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1251 PUTSHORT(outlen, lenloc);
1252 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1253 esp->es_server.ea_requests++;
1255 if (esp->es_server.ea_timeout > 0)
1256 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1262 #endif /* USE_EAPTLS */
1264 /* EAP ID number must not change on timeout. */
1265 eap_send_request(esp);
1269 * When it's time to send rechallenge the peer, this timeout is
1270 * called. Once the rechallenge is successful, the response handler
1271 * will restart the timer. If it fails, then the link is dropped.
1274 eap_rechallenge(arg)
1277 eap_state *esp = (eap_state *)arg;
1279 if (esp->es_server.ea_state != eapOpen &&
1280 esp->es_server.ea_state != eapSRP4)
1283 esp->es_server.ea_requests = 0;
1284 esp->es_server.ea_state = eapIdentify;
1285 eap_figure_next_state(esp, 0);
1286 esp->es_server.ea_id++;
1287 eap_send_request(esp);
1291 srp_lwrechallenge(arg)
1294 eap_state *esp = (eap_state *)arg;
1296 if (esp->es_server.ea_state != eapOpen ||
1297 esp->es_server.ea_type != EAPT_SRP)
1300 esp->es_server.ea_requests = 0;
1301 esp->es_server.ea_state = eapSRP4;
1302 esp->es_server.ea_id++;
1303 eap_send_request(esp);
1307 * eap_lowerup - The lower layer is now up.
1309 * This is called before either eap_authpeer or eap_authwithpeer. See
1310 * link_established() in auth.c. All that's necessary here is to
1311 * return to closed state so that those two routines will do the right
1318 eap_state *esp = &eap_states[unit];
1320 /* Discard any (possibly authenticated) peer name. */
1321 if (esp->es_server.ea_peer != NULL &&
1322 esp->es_server.ea_peer != remote_name)
1323 free(esp->es_server.ea_peer);
1324 esp->es_server.ea_peer = NULL;
1325 if (esp->es_client.ea_peer != NULL)
1326 free(esp->es_client.ea_peer);
1327 esp->es_client.ea_peer = NULL;
1329 esp->es_client.ea_state = eapClosed;
1330 esp->es_server.ea_state = eapClosed;
1334 * eap_lowerdown - The lower layer is now down.
1336 * Cancel all timeouts and return to initial state.
1342 eap_state *esp = &eap_states[unit];
1344 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1345 UNTIMEOUT(eap_client_timeout, (void *)esp);
1347 if (eap_server_active(esp)) {
1348 if (esp->es_server.ea_timeout > 0) {
1349 UNTIMEOUT(eap_server_timeout, (void *)esp);
1352 if ((esp->es_server.ea_state == eapOpen ||
1353 esp->es_server.ea_state == eapSRP4) &&
1354 esp->es_rechallenge > 0) {
1355 UNTIMEOUT(eap_rechallenge, (void *)esp);
1357 if (esp->es_server.ea_state == eapOpen &&
1358 esp->es_lwrechallenge > 0) {
1359 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1363 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1364 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1368 * eap_protrej - Peer doesn't speak this protocol.
1370 * This shouldn't happen. If it does, it represents authentication
1377 eap_state *esp = &eap_states[unit];
1379 if (eap_client_active(esp)) {
1380 error("EAP authentication failed due to Protocol-Reject");
1381 auth_withpeer_fail(unit, PPP_EAP);
1383 if (eap_server_active(esp)) {
1384 error("EAP authentication of peer failed on Protocol-Reject");
1385 auth_peer_fail(unit, PPP_EAP);
1387 eap_lowerdown(unit);
1391 * Format and send a regular EAP Response message.
1394 eap_send_response(esp, id, typenum, str, lenstr)
1404 outp = outpacket_buf;
1406 MAKEHEADER(outp, PPP_EAP);
1408 PUTCHAR(EAP_RESPONSE, outp);
1410 esp->es_client.ea_id = id;
1411 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1412 PUTSHORT(msglen, outp);
1413 PUTCHAR(typenum, outp);
1415 BCOPY(str, outp, lenstr);
1418 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1422 * Format and send an MD5-Challenge EAP Response message.
1425 eap_chap_response(esp, id, hash, name, namelen)
1435 outp = outpacket_buf;
1437 MAKEHEADER(outp, PPP_EAP);
1439 PUTCHAR(EAP_RESPONSE, outp);
1441 esp->es_client.ea_id = id;
1442 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1444 PUTSHORT(msglen, outp);
1445 PUTCHAR(EAPT_MD5CHAP, outp);
1446 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1447 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1448 INCPTR(MD5_SIGNATURE_SIZE, outp);
1450 BCOPY(name, outp, namelen);
1453 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1458 * Format and send a SRP EAP Response message.
1461 eap_srp_response(esp, id, subtypenum, str, lenstr)
1471 outp = outpacket_buf;
1473 MAKEHEADER(outp, PPP_EAP);
1475 PUTCHAR(EAP_RESPONSE, outp);
1477 esp->es_client.ea_id = id;
1478 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1479 PUTSHORT(msglen, outp);
1480 PUTCHAR(EAPT_SRP, outp);
1481 PUTCHAR(subtypenum, outp);
1483 BCOPY(str, outp, lenstr);
1486 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1490 * Format and send a SRP EAP Client Validator Response message.
1493 eap_srpval_response(esp, id, flags, str)
1502 outp = outpacket_buf;
1504 MAKEHEADER(outp, PPP_EAP);
1506 PUTCHAR(EAP_RESPONSE, outp);
1508 esp->es_client.ea_id = id;
1509 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1511 PUTSHORT(msglen, outp);
1512 PUTCHAR(EAPT_SRP, outp);
1513 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1514 PUTLONG(flags, outp);
1515 BCOPY(str, outp, SHA_DIGESTSIZE);
1517 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1519 #endif /* USE_SRP */
1523 * Send an EAP-TLS response message with tls data
1526 eap_tls_response(esp, id)
1534 outp = outpacket_buf;
1536 MAKEHEADER(outp, PPP_EAP);
1538 PUTCHAR(EAP_RESPONSE, outp);
1545 If the id in the request is unchanged, we must retransmit
1548 if(id == esp->es_client.ea_id)
1549 eaptls_retransmit(esp->es_client.ea_session, &outp);
1551 eaptls_send(esp->es_client.ea_session, &outp);
1553 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1554 PUTSHORT(outlen, lenloc);
1556 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1558 esp->es_client.ea_id = id;
1562 * Send an EAP-TLS ack
1565 eap_tls_sendack(esp, id)
1573 outp = outpacket_buf;
1575 MAKEHEADER(outp, PPP_EAP);
1577 PUTCHAR(EAP_RESPONSE, outp);
1579 esp->es_client.ea_id = id;
1584 PUTCHAR(EAPT_TLS, outp);
1587 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1588 PUTSHORT(outlen, lenloc);
1590 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1592 #endif /* USE_EAPTLS */
1595 eap_send_nak(esp, id, type)
1603 outp = outpacket_buf;
1605 MAKEHEADER(outp, PPP_EAP);
1607 PUTCHAR(EAP_RESPONSE, outp);
1609 esp->es_client.ea_id = id;
1610 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1611 PUTSHORT(msglen, outp);
1612 PUTCHAR(EAPT_NAK, outp);
1613 PUTCHAR(type, outp);
1615 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1622 char *user, *path, *file;
1625 static bool pnlogged = 0;
1627 pw = getpwuid(getuid());
1628 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1632 file = _PATH_PSEUDONYM;
1633 pl = strlen(user) + strlen(file) + 2;
1637 (void) slprintf(path, pl, "%s/%s", user, file);
1639 dbglog("pseudonym file: %s", path);
1646 open_pn_file(modebits)
1652 if ((path = name_of_pn_file()) == NULL)
1654 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1666 if ((path = name_of_pn_file()) != NULL) {
1667 (void) unlink(path);
1673 write_pseudonym(esp, inp, len, id)
1679 u_char *datp, *digp;
1681 u_char dig[SHA_DIGESTSIZE];
1682 int dsize, fd, olen = len;
1685 * Do the decoding by working backwards. This eliminates the need
1686 * to save the decoded output in a separate buffer.
1690 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1691 dsize = SHA_DIGESTSIZE;
1695 SHA1Update(&ctxt, &val, 1);
1696 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1698 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1700 SHA1Update(&ctxt, esp->es_client.ea_name,
1701 esp->es_client.ea_namelen);
1703 SHA1Final(dig, &ctxt);
1704 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1708 /* Now check that the result is sane */
1709 if (olen <= 0 || *inp + 1 > olen) {
1710 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1715 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1717 dbglog("EAP: error saving pseudonym: %m");
1720 len = write(fd, inp + 1, *inp);
1721 if (close(fd) != -1 && len == *inp) {
1722 dbglog("EAP: saved pseudonym");
1723 esp->es_usedpseudo = 0;
1725 dbglog("EAP: failed to save pseudonym");
1729 #endif /* USE_SRP */
1732 * eap_request - Receive EAP Request message (client mode).
1735 eap_request(esp, inp, id, len)
1744 char secret[MAXWORDLEN];
1745 char rhostname[256];
1747 u_char hash[MD5_SIGNATURE_SIZE];
1750 struct eaptls_session *ets = esp->es_client.ea_session;
1751 #endif /* USE_EAPTLS */
1754 struct t_client *tc;
1755 struct t_num sval, gval, Nval, *Ap, Bval;
1758 u_char dig[SHA_DIGESTSIZE];
1760 #endif /* USE_SRP */
1763 * Ignore requests if we're not open
1765 if (esp->es_client.ea_state <= eapClosed)
1769 * Note: we update es_client.ea_id *only if* a Response
1770 * message is being generated. Otherwise, we leave it the
1771 * same for duplicate detection purposes.
1774 esp->es_client.ea_requests++;
1775 if (esp->es_client.ea_maxrequests != 0 &&
1776 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1777 info("EAP: received too many Request messages");
1778 if (esp->es_client.ea_timeout > 0) {
1779 UNTIMEOUT(eap_client_timeout, (void *)esp);
1781 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1786 error("EAP: empty Request message discarded");
1790 GETCHAR(typenum, inp);
1796 info("EAP: Identity prompt \"%.*q\"", len, inp);
1798 if (esp->es_usepseudo &&
1799 (esp->es_usedpseudo == 0 ||
1800 (esp->es_usedpseudo == 1 &&
1801 id == esp->es_client.ea_id))) {
1802 esp->es_usedpseudo = 1;
1803 /* Try to get a pseudonym */
1804 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1805 strcpy(rhostname, SRP_PSEUDO_ID);
1806 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1807 sizeof (rhostname) - SRP_PSEUDO_LEN);
1808 /* XXX NAI unsupported */
1810 eap_send_response(esp, id, typenum,
1811 rhostname, len + SRP_PSEUDO_LEN);
1818 /* Stop using pseudonym now. */
1819 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1821 esp->es_usedpseudo = 2;
1823 #endif /* USE_SRP */
1824 eap_send_response(esp, id, typenum, esp->es_client.ea_name,
1825 esp->es_client.ea_namelen);
1828 case EAPT_NOTIFICATION:
1830 info("EAP: Notification \"%.*q\"", len, inp);
1831 eap_send_response(esp, id, typenum, NULL, 0);
1836 * Avoid the temptation to send Response Nak in reply
1837 * to Request Nak here. It can only lead to trouble.
1839 warn("EAP: unexpected Nak in Request; ignored");
1840 /* Return because we're waiting for something real. */
1845 error("EAP: received MD5-Challenge with no data");
1846 /* Bogus request; wait for something real. */
1849 GETCHAR(vallen, inp);
1851 if (vallen < 8 || vallen > len) {
1852 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1854 /* Try something better. */
1855 eap_send_nak(esp, id, EAPT_SRP);
1859 /* Not so likely to happen. */
1860 if (len - vallen >= sizeof (rhostname)) {
1861 dbglog("EAP: trimming really long peer name down");
1862 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1863 rhostname[sizeof (rhostname) - 1] = '\0';
1865 BCOPY(inp + vallen, rhostname, len - vallen);
1866 rhostname[len - vallen] = '\0';
1869 /* In case the remote doesn't give us his name. */
1870 if (explicit_remote ||
1871 (remote_name[0] != '\0' && vallen == len))
1872 strlcpy(rhostname, remote_name, sizeof (rhostname));
1875 * Get the secret for authenticating ourselves with
1876 * the specified host.
1878 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1879 rhostname, secret, &secret_len, 0)) {
1880 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1881 eap_send_nak(esp, id, EAPT_SRP);
1884 MD5_Init(&mdContext);
1886 MD5_Update(&mdContext, &typenum, 1);
1887 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1888 BZERO(secret, sizeof (secret));
1889 MD5_Update(&mdContext, inp, vallen);
1890 MD5_Final(hash, &mdContext);
1891 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1892 esp->es_client.ea_namelen);
1898 switch(esp->es_client.ea_state) {
1903 error("EAP: received EAP-TLS Listen packet with no data");
1904 /* Bogus request; wait for something real. */
1907 GETCHAR(flags, inp);
1908 if(flags & EAP_TLS_FLAGS_START){
1910 esp->es_client.ea_using_eaptls = 1;
1912 if (explicit_remote){
1913 esp->es_client.ea_peer = strdup(remote_name);
1914 esp->es_client.ea_peerlen = strlen(remote_name);
1916 esp->es_client.ea_peer = NULL;
1918 /* Init ssl session */
1919 if(!eaptls_init_ssl_client(esp)) {
1920 dbglog("cannot init ssl");
1921 eap_send_nak(esp, id, EAPT_TLS);
1922 esp->es_client.ea_using_eaptls = 0;
1926 ets = esp->es_client.ea_session;
1927 eap_tls_response(esp, id);
1928 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1932 /* The server has sent a bad start packet. */
1933 eap_send_nak(esp, id, EAPT_TLS);
1937 eap_tls_response(esp, id);
1938 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1943 error("EAP: discarding EAP-TLS Receive packet with no data");
1944 /* Bogus request; wait for something real. */
1947 eaptls_receive(ets, inp, len);
1950 eap_tls_sendack(esp, id);
1951 esp->es_client.ea_state = eapTlsRecv;
1955 if(ets->alert_recv) {
1956 eap_tls_sendack(esp, id);
1957 esp->es_client.ea_state = eapTlsRecvFailure;
1961 /* Check if TLS handshake is finished */
1962 if(eaptls_is_init_finished(ets)) {
1964 eaptls_gen_mppe_keys(ets, 1);
1966 eaptls_free_session(ets);
1967 eap_tls_sendack(esp, id);
1968 esp->es_client.ea_state = eapTlsRecvSuccess;
1972 eap_tls_response(esp,id);
1973 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1977 eap_send_nak(esp, id, EAPT_TLS);
1978 esp->es_client.ea_using_eaptls = 0;
1983 #endif /* USE_EAPTLS */
1988 error("EAP: received empty SRP Request");
1989 /* Bogus request; wait for something real. */
1994 GETCHAR(vallen, inp);
1997 case EAPSRP_CHALLENGE:
1999 if (esp->es_client.ea_session != NULL) {
2000 tc = (struct t_client *)esp->es_client.
2003 * If this is a new challenge, then start
2004 * over with a new client session context.
2005 * Otherwise, just resend last response.
2007 if (id != esp->es_client.ea_id) {
2009 esp->es_client.ea_session = NULL;
2013 /* No session key just yet */
2014 esp->es_client.ea_skey = NULL;
2016 GETCHAR(vallen, inp);
2018 if (vallen >= len) {
2019 error("EAP: badly-formed SRP Challenge"
2021 /* Ignore badly-formed messages */
2024 BCOPY(inp, rhostname, vallen);
2025 rhostname[vallen] = '\0';
2026 INCPTR(vallen, inp);
2030 * In case the remote doesn't give us his name,
2031 * use configured name.
2033 if (explicit_remote ||
2034 (remote_name[0] != '\0' && vallen == 0)) {
2035 strlcpy(rhostname, remote_name,
2036 sizeof (rhostname));
2039 if (esp->es_client.ea_peer != NULL)
2040 free(esp->es_client.ea_peer);
2041 esp->es_client.ea_peer = strdup(rhostname);
2042 esp->es_client.ea_peerlen = strlen(rhostname);
2044 GETCHAR(vallen, inp);
2046 if (vallen >= len) {
2047 error("EAP: badly-formed SRP Challenge"
2049 /* Ignore badly-formed messages */
2054 INCPTR(vallen, inp);
2057 GETCHAR(vallen, inp);
2060 error("EAP: badly-formed SRP Challenge"
2062 /* Ignore badly-formed messages */
2065 /* If no generator present, then use value 2 */
2067 gval.data = (u_char *)"\002";
2073 INCPTR(vallen, inp);
2077 * If no modulus present, then use well-known
2081 Nval.data = (u_char *)wkmodulus;
2082 Nval.len = sizeof (wkmodulus);
2087 tc = t_clientopen(esp->es_client.ea_name,
2088 &Nval, &gval, &sval);
2090 eap_send_nak(esp, id, EAPT_MD5CHAP);
2093 esp->es_client.ea_session = (void *)tc;
2095 /* Add Challenge ID & type to verifier */
2098 t_clientaddexdata(tc, vals, 2);
2100 Ap = t_clientgenexp(tc);
2101 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2106 tc = (struct t_client *)esp->es_client.ea_session;
2108 warn("EAP: peer sent Subtype 2 without 1");
2109 eap_send_nak(esp, id, EAPT_MD5CHAP);
2112 if (esp->es_client.ea_skey != NULL) {
2114 * ID number should not change here. Warn
2115 * if it does (but otherwise ignore).
2117 if (id != esp->es_client.ea_id) {
2118 warn("EAP: ID changed from %d to %d "
2119 "in SRP Subtype 2 rexmit",
2120 esp->es_client.ea_id, id);
2123 if (get_srp_secret(esp->es_unit,
2124 esp->es_client.ea_name,
2125 esp->es_client.ea_peer, secret, 0) == 0) {
2127 * Can't work with this peer because
2128 * the secret is missing. Just give
2131 eap_send_nak(esp, id, EAPT_MD5CHAP);
2136 t_clientpasswd(tc, secret);
2137 BZERO(secret, sizeof (secret));
2138 esp->es_client.ea_skey =
2139 t_clientgetkey(tc, &Bval);
2140 if (esp->es_client.ea_skey == NULL) {
2141 /* Server is rogue; stop now */
2142 error("EAP: SRP server is rogue");
2143 goto client_failure;
2146 eap_srpval_response(esp, id, SRPVAL_EBIT,
2147 t_clientresponse(tc));
2150 case EAPSRP_SVALIDATOR:
2151 tc = (struct t_client *)esp->es_client.ea_session;
2152 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2153 warn("EAP: peer sent Subtype 3 without 1/2");
2154 eap_send_nak(esp, id, EAPT_MD5CHAP);
2158 * If we're already open, then this ought to be a
2159 * duplicate. Otherwise, check that the server is
2160 * who we think it is.
2162 if (esp->es_client.ea_state == eapOpen) {
2163 if (id != esp->es_client.ea_id) {
2164 warn("EAP: ID changed from %d to %d "
2165 "in SRP Subtype 3 rexmit",
2166 esp->es_client.ea_id, id);
2169 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2170 if (len < 0 || t_clientverify(tc, inp +
2171 sizeof (u_int32_t)) != 0) {
2172 error("EAP: SRP server verification "
2174 goto client_failure;
2176 GETLONG(esp->es_client.ea_keyflags, inp);
2177 /* Save pseudonym if user wants it. */
2178 if (len > 0 && esp->es_usepseudo) {
2179 INCPTR(SHA_DIGESTSIZE, inp);
2180 write_pseudonym(esp, inp, len, id);
2184 * We've verified our peer. We're now mostly done,
2185 * except for waiting on the regular EAP Success
2188 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2191 case EAPSRP_LWRECHALLENGE:
2193 warn("EAP: malformed Lightweight rechallenge");
2198 SHA1Update(&ctxt, vals, 1);
2199 SHA1Update(&ctxt, esp->es_client.ea_skey,
2201 SHA1Update(&ctxt, inp, len);
2202 SHA1Update(&ctxt, esp->es_client.ea_name,
2203 esp->es_client.ea_namelen);
2204 SHA1Final(dig, &ctxt);
2205 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2210 error("EAP: unknown SRP Subtype %d", vallen);
2211 eap_send_nak(esp, id, EAPT_MD5CHAP);
2215 #endif /* USE_SRP */
2218 info("EAP: unknown authentication type %d; Naking", typenum);
2219 eap_send_nak(esp, id, EAPT_SRP);
2223 if (esp->es_client.ea_timeout > 0) {
2224 UNTIMEOUT(eap_client_timeout, (void *)esp);
2225 TIMEOUT(eap_client_timeout, (void *)esp,
2226 esp->es_client.ea_timeout);
2232 esp->es_client.ea_state = eapBadAuth;
2233 if (esp->es_client.ea_timeout > 0) {
2234 UNTIMEOUT(eap_client_timeout, (void *)esp);
2236 esp->es_client.ea_session = NULL;
2238 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2239 #endif /* USE_SRP */
2243 * eap_response - Receive EAP Response message (server mode).
2246 eap_response(esp, inp, id, len)
2255 char secret[MAXSECRETLEN];
2256 char rhostname[256];
2258 u_char hash[MD5_SIGNATURE_SIZE];
2260 struct t_server *ts;
2263 u_char dig[SHA_DIGESTSIZE];
2265 u_char dig[SHA_DIGESTSIZE];
2266 #endif /* USE_SRP */
2269 struct eaptls_session *ets;
2271 #endif /* USE_EAPTLS */
2274 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2275 unsigned char *, unsigned char *, char *, int);
2276 char response_message[256];
2280 * Ignore responses if we're not open
2282 if (esp->es_server.ea_state <= eapClosed)
2285 if (esp->es_server.ea_id != id) {
2286 dbglog("EAP: discarding Response %d; expected ID %d", id,
2287 esp->es_server.ea_id);
2291 esp->es_server.ea_responses++;
2294 error("EAP: empty Response message discarded");
2298 GETCHAR(typenum, inp);
2303 if (esp->es_server.ea_state != eapIdentify) {
2304 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2308 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2309 if (esp->es_server.ea_peer != NULL &&
2310 esp->es_server.ea_peer != remote_name)
2311 free(esp->es_server.ea_peer);
2312 esp->es_server.ea_peer = malloc(len + 1);
2313 if (esp->es_server.ea_peer == NULL) {
2314 esp->es_server.ea_peerlen = 0;
2315 eap_figure_next_state(esp, 1);
2318 BCOPY(inp, esp->es_server.ea_peer, len);
2319 esp->es_server.ea_peer[len] = '\0';
2320 esp->es_server.ea_peerlen = len;
2321 eap_figure_next_state(esp, 0);
2326 switch(esp->es_server.ea_state) {
2330 ets = (struct eaptls_session *) esp->es_server.ea_session;
2332 eap_figure_next_state(esp,
2333 eaptls_receive(esp->es_server.ea_session, inp, len));
2335 if(ets->alert_recv) {
2336 eap_send_failure(esp);
2343 dbglog("EAP-TLS ACK with extra data");
2345 eap_figure_next_state(esp, 0);
2348 case eapTlsRecvClient:
2349 /* Receive authentication response from client */
2351 GETCHAR(flags, inp);
2353 if(len == 1 && !flags) { /* Ack = ok */
2355 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2357 eap_send_success(esp);
2359 else { /* failure */
2360 warn("Server authentication failed");
2361 eap_send_failure(esp);
2365 warn("Bogus EAP-TLS packet received from client");
2367 eaptls_free_session(esp->es_server.ea_session);
2371 case eapTlsRecvAlertAck:
2372 eap_send_failure(esp);
2376 eap_figure_next_state(esp, 1);
2380 #endif /* USE_EAPTLS */
2382 case EAPT_NOTIFICATION:
2383 dbglog("EAP unexpected Notification; response discarded");
2388 info("EAP: Nak Response with no suggested protocol");
2389 eap_figure_next_state(esp, 1);
2393 GETCHAR(vallen, inp);
2396 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2397 /* Peer cannot Nak Identify Request */
2398 eap_figure_next_state(esp, 1);
2404 /* Run through SRP validator selection again. */
2405 esp->es_server.ea_state = eapIdentify;
2406 eap_figure_next_state(esp, 0);
2410 esp->es_server.ea_state = eapMD5Chall;
2414 /* Send EAP-TLS start packet */
2416 esp->es_server.ea_state = eapTlsStart;
2418 #endif /* USE_EAPTLS */
2422 info("EAP: peer proposes MSCHAPv2");
2423 esp->es_server.ea_state = eapMSCHAPv2Chall;
2428 dbglog("EAP: peer requesting unknown Type %d", vallen);
2429 switch (esp->es_server.ea_state) {
2433 esp->es_server.ea_state = eapMD5Chall;
2437 esp->es_server.ea_state = eapIdentify;
2438 eap_figure_next_state(esp, 0);
2448 if (esp->es_server.ea_state != eapMD5Chall) {
2449 error("EAP: unexpected MD5-Response");
2450 eap_figure_next_state(esp, 1);
2454 error("EAP: received MD5-Response with no data");
2455 eap_figure_next_state(esp, 1);
2458 GETCHAR(vallen, inp);
2460 if (vallen != 16 || vallen > len) {
2461 error("EAP: MD5-Response with bad length %d", vallen);
2462 eap_figure_next_state(esp, 1);
2466 /* Not so likely to happen. */
2467 if (len - vallen >= sizeof (rhostname)) {
2468 dbglog("EAP: trimming really long peer name down");
2469 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2470 rhostname[sizeof (rhostname) - 1] = '\0';
2472 BCOPY(inp + vallen, rhostname, len - vallen);
2473 rhostname[len - vallen] = '\0';
2476 /* In case the remote doesn't give us his name. */
2477 if (explicit_remote ||
2478 (remote_name[0] != '\0' && vallen == len))
2479 strlcpy(rhostname, remote_name, sizeof (rhostname));
2482 * Get the secret for authenticating the specified
2485 if (!get_secret(esp->es_unit, rhostname,
2486 esp->es_server.ea_name, secret, &secret_len, 1)) {
2487 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2488 eap_send_failure(esp);
2491 MD5_Init(&mdContext);
2492 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2493 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2494 BZERO(secret, sizeof (secret));
2495 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2496 MD5_Final(hash, &mdContext);
2497 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2498 eap_send_failure(esp);
2501 esp->es_server.ea_type = EAPT_MD5CHAP;
2502 eap_send_success(esp);
2503 eap_figure_next_state(esp, 0);
2504 if (esp->es_rechallenge != 0)
2505 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2511 error("EAP: received MSCHAPv2 with no data");
2512 eap_figure_next_state(esp, 1);
2515 GETCHAR(opcode, inp);
2520 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2521 error("EAP: unexpected MSCHAPv2-Response");
2522 eap_figure_next_state(esp, 1);
2525 /* skip MS ID + len */
2527 GETCHAR(vallen, inp);
2530 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2531 error("EAP: Invalid MSCHAPv2-Response "
2532 "length %d", vallen);
2533 eap_figure_next_state(esp, 1);
2537 /* Not so likely to happen. */
2538 if (len - vallen >= sizeof (rhostname)) {
2539 dbglog("EAP: trimming really long peer name down");
2540 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2541 rhostname[sizeof (rhostname) - 1] = '\0';
2543 BCOPY(inp + vallen, rhostname, len - vallen);
2544 rhostname[len - vallen] = '\0';
2547 /* In case the remote doesn't give us his name. */
2548 if (explicit_remote ||
2549 (remote_name[0] != '\0' && vallen == len))
2550 strlcpy(rhostname, remote_name, sizeof (rhostname));
2552 if (chap_verify_hook)
2553 chap_verifier = chap_verify_hook;
2555 chap_verifier = eap_chap_verify_response;
2557 esp->es_server.ea_id += 1;
2558 if ((*chap_verifier)(rhostname,
2559 esp->es_server.ea_name,
2561 &eap_chapms2_digest,
2565 sizeof(response_message)))
2567 info("EAP: MSCHAPv2 success for peer %q",
2569 esp->es_server.ea_type = EAPT_MSCHAPV2;
2570 eap_chapms2_send_request(esp,
2571 esp->es_server.ea_id,
2573 esp->es_server.ea_id,
2575 strlen(response_message));
2576 eap_figure_next_state(esp, 0);
2577 if (esp->es_rechallenge != 0)
2578 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2581 warn("EAP: MSCHAPv2 failure for peer %q",
2583 eap_chapms2_send_request(esp,
2584 esp->es_server.ea_id,
2586 esp->es_server.ea_id,
2588 strlen(response_message));
2592 info("EAP: MSCHAPv2 success confirmed");
2595 info("EAP: MSCHAPv2 failure confirmed");
2598 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2599 eap_send_nak(esp, id, EAPT_SRP);
2608 error("EAP: empty SRP Response");
2609 eap_figure_next_state(esp, 1);
2612 GETCHAR(typenum, inp);
2616 if (esp->es_server.ea_state != eapSRP1) {
2617 error("EAP: unexpected SRP Subtype 1 Response");
2618 eap_figure_next_state(esp, 1);
2623 ts = (struct t_server *)esp->es_server.ea_session;
2625 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2626 if (esp->es_server.ea_skey == NULL) {
2627 /* Client's A value is bogus; terminate now */
2628 error("EAP: bogus A value from client");
2629 eap_send_failure(esp);
2631 eap_figure_next_state(esp, 0);
2635 case EAPSRP_CVALIDATOR:
2636 if (esp->es_server.ea_state != eapSRP2) {
2637 error("EAP: unexpected SRP Subtype 2 Response");
2638 eap_figure_next_state(esp, 1);
2641 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2642 error("EAP: M1 length %d < %d", len,
2643 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2644 eap_figure_next_state(esp, 1);
2647 GETLONG(esp->es_server.ea_keyflags, inp);
2648 ts = (struct t_server *)esp->es_server.ea_session;
2650 if (t_serververify(ts, inp)) {
2651 info("EAP: unable to validate client identity");
2652 eap_send_failure(esp);
2655 eap_figure_next_state(esp, 0);
2659 if (esp->es_server.ea_state != eapSRP3) {
2660 error("EAP: unexpected SRP Subtype 3 Response");
2661 eap_send_failure(esp);
2664 esp->es_server.ea_type = EAPT_SRP;
2665 eap_send_success(esp);
2666 eap_figure_next_state(esp, 0);
2667 if (esp->es_rechallenge != 0)
2668 TIMEOUT(eap_rechallenge, esp,
2669 esp->es_rechallenge);
2670 if (esp->es_lwrechallenge != 0)
2671 TIMEOUT(srp_lwrechallenge, esp,
2672 esp->es_lwrechallenge);
2675 case EAPSRP_LWRECHALLENGE:
2676 if (esp->es_server.ea_state != eapSRP4) {
2677 info("EAP: unexpected SRP Subtype 4 Response");
2680 if (len != SHA_DIGESTSIZE) {
2681 error("EAP: bad Lightweight rechallenge "
2687 SHA1Update(&ctxt, &vallen, 1);
2688 SHA1Update(&ctxt, esp->es_server.ea_skey,
2690 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2691 SHA1Update(&ctxt, esp->es_server.ea_peer,
2692 esp->es_server.ea_peerlen);
2693 SHA1Final(dig, &ctxt);
2694 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2695 error("EAP: failed Lightweight rechallenge");
2696 eap_send_failure(esp);
2699 esp->es_server.ea_state = eapOpen;
2700 if (esp->es_lwrechallenge != 0)
2701 TIMEOUT(srp_lwrechallenge, esp,
2702 esp->es_lwrechallenge);
2706 #endif /* USE_SRP */
2709 /* This can't happen. */
2710 error("EAP: unknown Response type %d; ignored", typenum);
2714 if (esp->es_server.ea_timeout > 0) {
2715 UNTIMEOUT(eap_server_timeout, (void *)esp);
2718 if (esp->es_server.ea_state != eapBadAuth &&
2719 esp->es_server.ea_state != eapOpen) {
2720 esp->es_server.ea_id++;
2721 eap_send_request(esp);
2726 * eap_success - Receive EAP Success message (client mode).
2729 eap_success(esp, inp, id, len)
2735 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2737 && esp->es_client.ea_state != eapTlsRecvSuccess
2738 #endif /* USE_EAPTLS */
2740 dbglog("EAP unexpected success message in state %s (%d)",
2741 eap_state_name(esp->es_client.ea_state),
2742 esp->es_client.ea_state);
2747 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2748 eapTlsRecvSuccess) {
2749 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2750 eap_state_name(esp->es_client.ea_state),
2751 esp->es_client.ea_state);
2754 #endif /* USE_EAPTLS */
2756 if (esp->es_client.ea_timeout > 0) {
2757 UNTIMEOUT(eap_client_timeout, (void *)esp);
2761 /* This is odd. The spec doesn't allow for this. */
2765 esp->es_client.ea_state = eapOpen;
2766 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2770 * eap_failure - Receive EAP Failure message (client mode).
2773 eap_failure(esp, inp, id, len)
2780 * Ignore failure messages if we're not open
2782 if (esp->es_client.ea_state <= eapClosed)
2785 if (!eap_client_active(esp)) {
2786 dbglog("EAP unexpected failure message in state %s (%d)",
2787 eap_state_name(esp->es_client.ea_state),
2788 esp->es_client.ea_state);
2791 if (esp->es_client.ea_timeout > 0) {
2792 UNTIMEOUT(eap_client_timeout, (void *)esp);
2796 /* This is odd. The spec doesn't allow for this. */
2800 esp->es_client.ea_state = eapBadAuth;
2802 error("EAP: peer reports authentication failure");
2803 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2807 * eap_input - Handle received EAP message.
2810 eap_input(unit, inp, inlen)
2815 eap_state *esp = &eap_states[unit];
2820 * Parse header (code, id and length). If packet too short,
2823 if (inlen < EAP_HEADERLEN) {
2824 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2830 if (len < EAP_HEADERLEN || len > inlen) {
2831 error("EAP: packet has illegal length field %d (%d..%d)", len,
2832 EAP_HEADERLEN, inlen);
2835 len -= EAP_HEADERLEN;
2837 /* Dispatch based on message code */
2840 eap_request(esp, inp, id, len);
2844 eap_response(esp, inp, id, len);
2848 eap_success(esp, inp, id, len);
2852 eap_failure(esp, inp, id, len);
2855 default: /* XXX Need code reject */
2856 /* Note: it's not legal to send EAP Nak here. */
2857 warn("EAP: unknown code %d received", code);
2863 * eap_printpkt - print the contents of an EAP packet.
2865 static char *eap_codenames[] = {
2866 "Request", "Response", "Success", "Failure"
2869 static char *eap_typenames[] = {
2870 "Identity", "Notification", "Nak", "MD5-Challenge",
2871 "OTP", "Generic-Token", NULL, NULL,
2872 "RSA", "DSS", "KEA", "KEA-Validate",
2873 "TLS", "Defender", "Windows 2000", "Arcot",
2874 "Cisco", "Nokia", "SRP", NULL,
2875 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2880 eap_printpkt(inp, inlen, printer, arg)
2883 void (*printer) __P((void *, char *, ...));
2886 int code, id, len, rtype, vallen;
2891 #endif /* USE_EAPTLS */
2896 if (inlen < EAP_HEADERLEN)
2902 if (len < EAP_HEADERLEN || len > inlen)
2905 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2906 printer(arg, " %s", eap_codenames[code-1]);
2908 printer(arg, " code=0x%x", code);
2909 printer(arg, " id=0x%x", id);
2910 len -= EAP_HEADERLEN;
2914 printer(arg, " <missing type>");
2917 GETCHAR(rtype, inp);
2920 rtype <= sizeof (eap_typenames) / sizeof (char *))
2921 printer(arg, " %s", eap_typenames[rtype-1]);
2923 printer(arg, " type=0x%x", rtype);
2926 case EAPT_NOTIFICATION:
2928 printer(arg, " <Message ");
2929 print_string((char *)inp, len, printer, arg);
2934 printer(arg, " <No message>");
2941 GETCHAR(vallen, inp);
2945 printer(arg, " <Value%.*B>", vallen, inp);
2946 INCPTR(vallen, inp);
2949 printer(arg, " <Name ");
2950 print_string((char *)inp, len, printer, arg);
2955 printer(arg, " <No name>");
2963 GETCHAR(opcode, inp);
2966 case CHAP_CHALLENGE:
2969 GETCHAR(vallen, inp);
2974 printer(arg, " Challenge <");
2975 for (; vallen > 0; --vallen) {
2978 printer(arg, "%.2x", val);
2982 printer(arg, ", <Name ");
2983 print_string((char *)inp, len, printer, arg);
2988 printer(arg, ", <No name>");
2994 printer(arg, " Success <Message ");
2995 print_string((char *)inp, len, printer, arg);
3001 printer(arg, " Failure <Message ");
3002 print_string((char *)inp, len, printer, arg);
3008 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3018 GETCHAR(flags, inp);
3021 if(flags == 0 && len == 0){
3022 printer(arg, " Ack");
3026 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3027 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3028 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3030 #endif /* USE_EAPTLS */
3035 GETCHAR(vallen, inp);
3037 printer(arg, "-%d", vallen);
3039 case EAPSRP_CHALLENGE:
3040 GETCHAR(vallen, inp);
3045 printer(arg, " <Name ");
3046 print_string((char *)inp, vallen, printer,
3050 printer(arg, " <No name>");
3052 INCPTR(vallen, inp);
3054 GETCHAR(vallen, inp);
3058 printer(arg, " <s%.*B>", vallen, inp);
3059 INCPTR(vallen, inp);
3061 GETCHAR(vallen, inp);
3066 printer(arg, " <Default g=2>");
3068 printer(arg, " <g%.*B>", vallen, inp);
3070 INCPTR(vallen, inp);
3073 printer(arg, " <Default N>");
3075 printer(arg, " <N%.*B>", len, inp);
3082 printer(arg, " <B%.*B>", len, inp);
3087 case EAPSRP_SVALIDATOR:
3088 if (len < sizeof (u_int32_t))
3091 len -= sizeof (u_int32_t);
3092 if (uval & SRPVAL_EBIT) {
3094 uval &= ~SRPVAL_EBIT;
3097 printer(arg, " f<%X>", uval);
3099 if ((vallen = len) > SHA_DIGESTSIZE)
3100 vallen = SHA_DIGESTSIZE;
3101 printer(arg, " <M2%.*B%s>", len, inp,
3102 len < SHA_DIGESTSIZE ? "?" : "");
3103 INCPTR(vallen, inp);
3106 printer(arg, " <PN%.*B>", len, inp);
3112 case EAPSRP_LWRECHALLENGE:
3113 printer(arg, " <Challenge%.*B>", len, inp);
3125 GETCHAR(rtype, inp);
3128 rtype <= sizeof (eap_typenames) / sizeof (char *))
3129 printer(arg, " %s", eap_typenames[rtype-1]);
3131 printer(arg, " type=0x%x", rtype);
3135 printer(arg, " <Name ");
3136 print_string((char *)inp, len, printer, arg);
3147 GETCHAR(flags, inp);
3150 if(flags == 0 && len == 0){
3151 printer(arg, " Ack");
3155 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3156 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3157 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3160 #endif /* USE_EAPTLS */
3164 printer(arg, " <missing hint>");
3167 GETCHAR(rtype, inp);
3169 printer(arg, " <Suggested-type %02X", rtype);
3171 rtype < sizeof (eap_typenames) / sizeof (char *))
3172 printer(arg, " (%s)", eap_typenames[rtype-1]);
3178 printer(arg, " <missing length>");
3181 GETCHAR(vallen, inp);
3185 printer(arg, " <Value%.*B>", vallen, inp);
3186 INCPTR(vallen, inp);
3189 printer(arg, " <Name ");
3190 print_string((char *)inp, len, printer, arg);
3195 printer(arg, " <No name>");
3203 GETCHAR(opcode, inp);
3209 GETCHAR(vallen, inp);
3214 printer(arg, " Response <");
3215 for (; vallen > 0; --vallen) {
3218 printer(arg, "%.2x", val);
3222 printer(arg, ", <Name ");
3223 print_string((char *)inp, len, printer, arg);
3228 printer(arg, ", <No name>");
3232 printer(arg, " Success");
3235 printer(arg, " Failure");
3238 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3247 GETCHAR(vallen, inp);
3249 printer(arg, "-%d", vallen);
3252 printer(arg, " <A%.*B>", len, inp);
3257 case EAPSRP_CVALIDATOR:
3258 if (len < sizeof (u_int32_t))
3261 len -= sizeof (u_int32_t);
3262 if (uval & SRPVAL_EBIT) {
3264 uval &= ~SRPVAL_EBIT;
3267 printer(arg, " f<%X>", uval);
3269 printer(arg, " <M1%.*B%s>", len, inp,
3270 len == SHA_DIGESTSIZE ? "" : "?");
3278 case EAPSRP_LWRECHALLENGE:
3279 printer(arg, " <Response%.*B%s>", len, inp,
3280 len == SHA_DIGESTSIZE ? "" : "?");
3281 if ((vallen = len) > SHA_DIGESTSIZE)
3282 vallen = SHA_DIGESTSIZE;
3283 INCPTR(vallen, inp);
3291 case EAP_SUCCESS: /* No payload expected for these! */
3296 printer(arg, " <truncated>");
3301 printer(arg, "%8B...", inp);
3303 printer(arg, "%.*B", len, inp);
3306 return (inp - pstart);