2 * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
4 * Copyright (c) 2001 by Sun Microsystems, Inc.
7 * Non-exclusive rights to redistribute, modify, translate, and use
8 * this software in source and binary forms, in whole or in part, is
9 * hereby granted, provided that the above copyright notice is
10 * duplicated in any source form, and that neither the name of the
11 * copyright holder nor the author is used to endorse or promote
12 * products derived from this software.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 * Original version by James Carlson
20 * This implementation of EAP supports MD5-Challenge and SRP-SHA1
21 * authentication styles. Note that support of MD5-Challenge is a
22 * requirement of RFC 2284, and that it's essentially just a
23 * reimplementation of regular RFC 1994 CHAP using EAP messages.
25 * As an authenticator ("server"), there are multiple phases for each
26 * style. In the first phase of each style, the unauthenticated peer
27 * name is queried using the EAP Identity request type. If the
28 * "remotename" option is used, then this phase is skipped, because
29 * the peer's name is presumed to be known.
31 * For MD5-Challenge, there are two phases, and the second phase
32 * consists of sending the challenge itself and handling the
33 * associated response.
35 * For SRP-SHA1, there are four phases. The second sends 's', 'N',
36 * and 'g'. The reply contains 'A'. The third sends 'B', and the
37 * reply contains 'M1'. The forth sends the 'M2' value.
39 * As an authenticatee ("client"), there's just a single phase --
40 * responding to the queries generated by the peer. EAP is an
41 * authenticator-driven protocol.
43 * Based on draft-ietf-pppext-eap-srp-03.txt.
47 * Modification by Beniamino Galvani, Mar 2005
48 * Implemented EAP-TLS authentication
60 #include <sys/types.h>
67 #include "pathnames.h"
84 #ifndef SHA_DIGESTSIZE
85 #define SHA_DIGESTSIZE 20
90 #endif /* USE_EAPTLS */
96 extern int chapms_strip_domain;
99 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
101 static char *pn_secret = NULL; /* Pseudonym generating secret */
105 * Command-line options.
107 static option_t eap_option_list[] = {
108 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
109 "Set retransmit timeout for EAP Requests (server)" },
110 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
111 "Set max number of EAP Requests sent (server)" },
112 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
113 "Set time limit for peer EAP authentication" },
114 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
115 "Set max number of EAP Requests allows (client)" },
116 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
117 "Set interval for EAP rechallenge" },
119 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
120 "Set interval for SRP lightweight rechallenge" },
121 { "srp-pn-secret", o_string, &pn_secret,
122 "Long term pseudonym generation secret" },
123 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
124 "Use pseudonym if offered one by server", 1 },
130 * Protocol entry points.
132 static void eap_init (int unit);
133 static void eap_input (int unit, u_char *inp, int inlen);
134 static void eap_protrej (int unit);
135 static void eap_lowerup (int unit);
136 static void eap_lowerdown (int unit);
137 static int eap_printpkt (u_char *inp, int inlen,
138 void (*)(void *arg, char *fmt, ...), void *arg);
140 struct protent eap_protent = {
141 PPP_EAP, /* protocol number */
142 eap_init, /* initialization procedure */
143 eap_input, /* process a received packet */
144 eap_protrej, /* process a received protocol-reject */
145 eap_lowerup, /* lower layer has gone up */
146 eap_lowerdown, /* lower layer has gone down */
147 NULL, /* open the protocol */
148 NULL, /* close the protocol */
149 eap_printpkt, /* print a packet in readable form */
150 NULL, /* process a received data packet */
151 1, /* protocol enabled */
152 "EAP", /* text name of protocol */
153 NULL, /* text name of corresponding data protocol */
154 eap_option_list, /* list of command-line options */
155 NULL, /* check requested options; assign defaults */
156 NULL, /* configure interface for demand-dial */
157 NULL /* say whether to bring up link for this pkt */
162 * A well-known 2048 bit modulus.
164 static const u_char wkmodulus[] = {
165 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
166 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
167 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
168 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
169 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
170 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
171 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
172 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
173 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
174 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
175 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
176 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
177 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
178 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
179 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
180 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
181 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
182 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
183 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
184 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
185 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
186 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
187 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
188 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
189 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
190 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
191 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
192 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
193 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
194 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
195 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
196 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
200 /* Local forward declarations. */
201 static void eap_server_timeout (void *arg);
204 * Convert EAP state code to printable string for debug.
207 eap_state_name(enum eap_state_code esc)
209 static const char *state_names[] = { EAP_STATES };
211 return (state_names[(int)esc]);
215 * eap_init - Initialize state for an EAP user. This is currently
216 * called once by main() during start-up.
221 eap_state *esp = &eap_states[unit];
223 BZERO(esp, sizeof (*esp));
225 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
226 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
227 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
228 esp->es_client.ea_timeout = EAP_DEFREQTIME;
229 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
231 esp->es_client.ea_using_eaptls = 0;
232 #endif /* USE_EAPTLS */
234 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
235 esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
240 * eap_client_timeout - Give up waiting for the peer to send any
244 eap_client_timeout(void *arg)
246 eap_state *esp = (eap_state *) arg;
248 if (!eap_client_active(esp))
251 error("EAP: timeout waiting for Request from peer");
252 auth_withpeer_fail(esp->es_unit, PPP_EAP);
253 esp->es_client.ea_state = eapBadAuth;
257 * eap_authwithpeer - Authenticate to our peer (behave as client).
259 * Start client state and wait for requests. This is called only
263 eap_authwithpeer(int unit, char *localname)
265 eap_state *esp = &eap_states[unit];
267 /* Save the peer name we're given */
268 esp->es_client.ea_name = localname;
269 esp->es_client.ea_namelen = strlen(localname);
271 esp->es_client.ea_state = eapListen;
274 * Start a timer so that if the other end just goes
275 * silent, we don't sit here waiting forever.
277 if (esp->es_client.ea_timeout > 0)
278 TIMEOUT(eap_client_timeout, (void *)esp,
279 esp->es_client.ea_timeout);
283 * Format a standard EAP Failure message and send it to the peer.
287 eap_send_failure(eap_state *esp)
291 outp = outpacket_buf;
293 MAKEHEADER(outp, PPP_EAP);
295 PUTCHAR(EAP_FAILURE, outp);
296 esp->es_server.ea_id++;
297 PUTCHAR(esp->es_server.ea_id, outp);
298 PUTSHORT(EAP_HEADERLEN, outp);
300 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
302 esp->es_server.ea_state = eapBadAuth;
303 auth_peer_fail(esp->es_unit, PPP_EAP);
307 * Format a standard EAP Success message and send it to the peer.
311 eap_send_success(eap_state *esp)
315 outp = outpacket_buf;
317 MAKEHEADER(outp, PPP_EAP);
319 PUTCHAR(EAP_SUCCESS, outp);
320 esp->es_server.ea_id++;
321 PUTCHAR(esp->es_server.ea_id, outp);
322 PUTSHORT(EAP_HEADERLEN, outp);
324 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
326 auth_peer_success(esp->es_unit, PPP_EAP, 0,
327 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
332 * Set DES key according to pseudonym-generating secret and current
336 pncrypt_setkey(int timeoffs)
341 u_char dig[SHA_DIGESTSIZE];
344 if (pn_secret == NULL)
346 reftime = time(NULL) + timeoffs;
347 tp = localtime(&reftime);
349 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
350 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
351 SHA1Update(&ctxt, tbuf, strlen(tbuf));
352 SHA1Final(dig, &ctxt);
353 return (DesSetkey(dig));
356 static char base64[] =
357 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
365 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
370 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
373 if (bs->bs_offs >= 24) {
374 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
375 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
376 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
377 *outp++ = base64[bs->bs_bits & 0x3F];
387 b64flush(struct b64state *bs, u_char *outp)
391 if (bs->bs_offs == 8) {
392 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
393 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
395 } else if (bs->bs_offs == 16) {
396 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
397 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
398 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
407 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
413 if ((cp = strchr(base64, *inp++)) == NULL)
415 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
418 if (bs->bs_offs >= 8) {
419 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
429 * Assume that current waiting server state is complete and figure
430 * next state to use based on available authentication data. 'status'
431 * indicates if there was an error in handling the last query. It is
432 * 0 for success and non-zero for failure.
435 eap_figure_next_state(eap_state *esp, int status)
438 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
440 struct t_confent *tce, mytce;
443 int id, i, plen, toffs;
448 struct eaptls_session *ets;
450 char secret[MAXWORDLEN];
451 #endif /* USE_EAPTLS */
453 esp->es_server.ea_timeout = esp->es_savedtime;
455 esp->es_server.ea_prev_state = esp->es_server.ea_state;
456 #endif /* USE_EAPTLS */
457 switch (esp->es_server.ea_state) {
463 /* Discard any previous session. */
464 ts = (struct t_server *)esp->es_server.ea_session;
467 esp->es_server.ea_session = NULL;
468 esp->es_server.ea_skey = NULL;
472 esp->es_server.ea_state = eapBadAuth;
476 /* If we've got a pseudonym, try to decode to real name. */
477 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
478 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
479 SRP_PSEUDO_LEN) == 0 &&
480 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
482 BZERO(&bs, sizeof (bs));
484 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
485 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
488 for (i = 0; i < 5; i++) {
489 pncrypt_setkey(toffs);
491 if (!DesDecrypt(secbuf, clear)) {
492 dbglog("no DES here; cannot decode "
496 id = *(unsigned char *)clear;
497 if (id + 1 <= plen && id + 9 > plen)
500 if (plen % 8 == 0 && i < 5) {
502 * Note that this is always shorter than the
503 * original stored string, so there's no need
506 if ((i = plen = *(unsigned char *)clear) > 7)
508 esp->es_server.ea_peerlen = plen;
509 dp = (unsigned char *)esp->es_server.ea_peer;
510 BCOPY(clear + 1, dp, i);
515 (void) DesDecrypt(sp, dp);
520 esp->es_server.ea_peer[
521 esp->es_server.ea_peerlen] = '\0';
522 dbglog("decoded pseudonym to \"%.*q\"",
523 esp->es_server.ea_peerlen,
524 esp->es_server.ea_peer);
526 dbglog("failed to decode real name");
527 /* Stay in eapIdentfy state; requery */
531 /* Look up user in secrets database. */
532 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
533 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
534 /* Set up default in case SRP entry is bad */
535 esp->es_server.ea_state = eapMD5Chall;
536 /* Get t_confent based on index in srp-secrets */
537 id = strtol((char *)secbuf, &cp, 10);
538 if (*cp++ != ':' || id < 0)
542 mytce.modulus.data = (u_char *)wkmodulus;
543 mytce.modulus.len = sizeof (wkmodulus);
544 mytce.generator.data = (u_char *)"\002";
545 mytce.generator.len = 1;
547 } else if ((tce = gettcid(id)) != NULL) {
549 * Client will have to verify this modulus/
550 * generator combination, and that will take
551 * a while. Lengthen the timeout here.
553 if (esp->es_server.ea_timeout > 0 &&
554 esp->es_server.ea_timeout < 30)
555 esp->es_server.ea_timeout = 30;
559 if ((cp2 = strchr(cp, ':')) == NULL)
562 tpw.pebuf.name = esp->es_server.ea_peer;
563 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
565 tpw.pebuf.password.data = (char*) tpw.pwbuf;
566 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
568 tpw.pebuf.salt.data = tpw.saltbuf;
569 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
571 esp->es_server.ea_session = (void *)ts;
572 esp->es_server.ea_state = eapSRP1;
573 vals[0] = esp->es_server.ea_id + 1;
575 t_serveraddexdata(ts, vals, 2);
576 /* Generate B; must call before t_servergetkey() */
582 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
583 esp->es_server.ea_name, secret, &secret_len, 1)) {
585 esp->es_server.ea_state = eapTlsStart;
588 #endif /* USE_EAPTLS */
590 esp->es_server.ea_state = eapMD5Chall;
595 /* Initialize ssl session */
596 if(!eaptls_init_ssl_server(esp)) {
597 esp->es_server.ea_state = eapBadAuth;
601 esp->es_server.ea_state = eapTlsRecv;
605 ets = (struct eaptls_session *) esp->es_server.ea_session;
607 if(ets->alert_sent) {
608 esp->es_server.ea_state = eapTlsSendAlert;
613 esp->es_server.ea_state = eapBadAuth;
616 ets = (struct eaptls_session *) esp->es_server.ea_session;
619 esp->es_server.ea_state = eapTlsSendAck;
621 esp->es_server.ea_state = eapTlsSend;
625 ets = (struct eaptls_session *) esp->es_server.ea_session;
628 esp->es_server.ea_state = eapTlsRecvAck;
630 if(SSL_is_init_finished(ets->ssl))
631 esp->es_server.ea_state = eapTlsRecvClient;
633 /* JJK Add "TLS empty record" message here ??? */
634 esp->es_server.ea_state = eapTlsRecv;
638 esp->es_server.ea_state = eapTlsRecv;
644 esp->es_server.ea_state = eapBadAuth;
648 esp->es_server.ea_state = eapTlsSend;
651 case eapTlsSendAlert:
652 esp->es_server.ea_state = eapTlsRecvAlertAck;
654 #endif /* USE_EAPTLS */
658 ts = (struct t_server *)esp->es_server.ea_session;
659 if (ts != NULL && status != 0) {
661 esp->es_server.ea_session = NULL;
662 esp->es_server.ea_skey = NULL;
666 esp->es_server.ea_state = eapMD5Chall;
667 } else if (status != 0 || esp->es_server.ea_session == NULL) {
668 esp->es_server.ea_state = eapBadAuth;
670 esp->es_server.ea_state = eapSRP2;
676 ts = (struct t_server *)esp->es_server.ea_session;
677 if (ts != NULL && status != 0) {
679 esp->es_server.ea_session = NULL;
680 esp->es_server.ea_skey = NULL;
683 if (status != 0 || esp->es_server.ea_session == NULL) {
684 esp->es_server.ea_state = eapBadAuth;
686 esp->es_server.ea_state = eapSRP3;
693 ts = (struct t_server *)esp->es_server.ea_session;
694 if (ts != NULL && status != 0) {
696 esp->es_server.ea_session = NULL;
697 esp->es_server.ea_skey = NULL;
700 if (status != 0 || esp->es_server.ea_session == NULL) {
701 esp->es_server.ea_state = eapBadAuth;
703 esp->es_server.ea_state = eapOpen;
708 case eapMSCHAPv2Chall:
712 esp->es_server.ea_state = eapBadAuth;
714 esp->es_server.ea_state = eapOpen;
719 esp->es_server.ea_state = eapBadAuth;
722 if (esp->es_server.ea_state == eapBadAuth)
723 eap_send_failure(esp);
726 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));
727 #endif /* USE_EAPTLS */
732 * eap_chap_verify_response - check whether the peer's response matches
733 * what we think it should be. Returns 1 if it does (authentication
734 * succeeded), or 0 if it doesn't.
737 eap_chap_verify_response(char *name, char *ourname, int id,
738 struct chap_digest_type *digest,
739 unsigned char *challenge, unsigned char *response,
740 char *message, int message_space)
743 unsigned char secret[MAXSECRETLEN];
746 /* Get the secret that the peer is supposed to know */
747 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
748 error("No CHAP secret found for authenticating %q", name);
752 ok = digest->verify_response(id, name, secret, secret_len, challenge,
753 response, message, message_space);
754 memset(secret, 0, sizeof(secret));
760 * Format and send an CHAPV2-Success/Failure EAP Request message.
763 eap_chapms2_send_request(eap_state *esp, u_char id,
764 u_char opcode, u_char chapid,
765 char *message, int message_len)
770 outp = outpacket_buf;
772 MAKEHEADER(outp, PPP_EAP);
774 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
775 msglen += message_len;
777 PUTCHAR(EAP_REQUEST, outp);
779 PUTSHORT(msglen, outp);
780 PUTCHAR(EAPT_MSCHAPV2, outp);
781 PUTCHAR(opcode, outp);
782 PUTCHAR(chapid, outp);
784 PUTSHORT(msglen - 5, outp);
785 BCOPY(message, outp, message_len);
787 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
789 if (opcode == CHAP_SUCCESS) {
790 auth_peer_success(esp->es_unit, PPP_EAP, 0,
791 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
794 esp->es_server.ea_state = eapBadAuth;
795 auth_peer_fail(esp->es_unit, PPP_EAP);
801 * Format an EAP Request message and send it to the peer. Message
802 * type depends on current state. (Server operation)
805 eap_send_request(eap_state *esp)
815 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
821 /* Handle both initial auth and restart */
822 if (esp->es_server.ea_state < eapIdentify &&
823 esp->es_server.ea_state != eapInitial) {
824 esp->es_server.ea_state = eapIdentify;
825 if (explicit_remote) {
827 * If we already know the peer's
828 * unauthenticated name, then there's no
829 * reason to ask. Go to next state instead.
831 esp->es_server.ea_peer = remote_name;
832 esp->es_server.ea_peerlen = strlen(remote_name);
833 eap_figure_next_state(esp, 0);
837 if (esp->es_server.ea_maxrequests > 0 &&
838 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
839 if (esp->es_server.ea_responses > 0)
840 error("EAP: too many Requests sent");
842 error("EAP: no response to Requests");
843 eap_send_failure(esp);
847 outp = outpacket_buf;
849 MAKEHEADER(outp, PPP_EAP);
851 PUTCHAR(EAP_REQUEST, outp);
852 PUTCHAR(esp->es_server.ea_id, outp);
856 switch (esp->es_server.ea_state) {
858 PUTCHAR(EAPT_IDENTITY, outp);
860 challen = strlen(str);
861 BCOPY(str, outp, challen);
862 INCPTR(challen, outp);
866 PUTCHAR(EAPT_MD5CHAP, outp);
868 * pick a random challenge length between
869 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
871 challen = (drand48() *
872 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
873 MIN_CHALLENGE_LENGTH;
874 PUTCHAR(challen, outp);
875 esp->es_challen = challen;
876 ptr = esp->es_challenge;
877 while (--challen >= 0)
878 *ptr++ = (u_char) (drand48() * 0x100);
879 BCOPY(esp->es_challenge, outp, esp->es_challen);
880 INCPTR(esp->es_challen, outp);
881 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
882 INCPTR(esp->es_server.ea_namelen, outp);
886 case eapMSCHAPv2Chall:
887 esp->es_server.digest->generate_challenge(esp->es_challenge);
888 challen = esp->es_challenge[0];
889 esp->es_challen = challen;
891 PUTCHAR(EAPT_MSCHAPV2, outp);
892 PUTCHAR(CHAP_CHALLENGE, outp);
893 PUTCHAR(esp->es_server.ea_id, outp);
895 PUTSHORT(5 + challen +
896 esp->es_server.ea_namelen,
898 /* challen + challenge */
899 BCOPY(esp->es_challenge, outp, challen+1);
900 INCPTR(challen+1, outp);
901 BCOPY(esp->es_server.ea_name,
903 esp->es_server.ea_namelen);
904 INCPTR(esp->es_server.ea_namelen, outp);
910 PUTCHAR(EAPT_TLS, outp);
911 PUTCHAR(EAP_TLS_FLAGS_START, outp);
912 eap_figure_next_state(esp, 0);
916 eaptls_send(esp->es_server.ea_session, &outp);
917 eap_figure_next_state(esp, 0);
921 PUTCHAR(EAPT_TLS, outp);
923 eap_figure_next_state(esp, 0);
926 case eapTlsSendAlert:
927 eaptls_send(esp->es_server.ea_session, &outp);
928 eap_figure_next_state(esp, 0);
930 #endif /* USE_EAPTLS */
934 PUTCHAR(EAPT_SRP, outp);
935 PUTCHAR(EAPSRP_CHALLENGE, outp);
937 PUTCHAR(esp->es_server.ea_namelen, outp);
938 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
939 INCPTR(esp->es_server.ea_namelen, outp);
941 ts = (struct t_server *)esp->es_server.ea_session;
943 PUTCHAR(ts->s.len, outp);
944 BCOPY(ts->s.data, outp, ts->s.len);
945 INCPTR(ts->s.len, outp);
947 if (ts->g.len == 1 && ts->g.data[0] == 2) {
950 PUTCHAR(ts->g.len, outp);
951 BCOPY(ts->g.data, outp, ts->g.len);
952 INCPTR(ts->g.len, outp);
955 if (ts->n.len != sizeof (wkmodulus) ||
956 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
957 BCOPY(ts->n.data, outp, ts->n.len);
958 INCPTR(ts->n.len, outp);
963 PUTCHAR(EAPT_SRP, outp);
964 PUTCHAR(EAPSRP_SKEY, outp);
966 ts = (struct t_server *)esp->es_server.ea_session;
968 BCOPY(ts->B.data, outp, ts->B.len);
969 INCPTR(ts->B.len, outp);
973 PUTCHAR(EAPT_SRP, outp);
974 PUTCHAR(EAPSRP_SVALIDATOR, outp);
975 PUTLONG(SRPVAL_EBIT, outp);
976 ts = (struct t_server *)esp->es_server.ea_session;
978 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
979 INCPTR(SHA_DIGESTSIZE, outp);
981 if (pncrypt_setkey(0)) {
982 /* Generate pseudonym */
984 cp = (unsigned char *)esp->es_server.ea_peer;
985 if ((j = i = esp->es_server.ea_peerlen) > 7)
988 BCOPY(cp, clear + 1, j);
991 if (!DesEncrypt(clear, cipher)) {
992 dbglog("no DES here; not generating pseudonym");
995 BZERO(&b64, sizeof (b64));
996 outp++; /* space for pseudonym length */
997 outp += b64enc(&b64, cipher, 8, outp);
999 (void) DesEncrypt(cp, cipher);
1000 outp += b64enc(&b64, cipher, 8, outp);
1005 BCOPY(cp, clear, i);
1008 *cp++ = drand48() * 0x100;
1011 (void) DesEncrypt(clear, cipher);
1012 outp += b64enc(&b64, cipher, 8, outp);
1014 outp += b64flush(&b64, outp);
1016 /* Set length and pad out to next 20 octet boundary */
1017 i = outp - optr - 1;
1019 i %= SHA_DIGESTSIZE;
1021 while (i < SHA_DIGESTSIZE) {
1022 *outp++ = drand48() * 0x100;
1027 /* Obscure the pseudonym with SHA1 hash */
1029 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1030 SHA1Update(&ctxt, esp->es_server.ea_skey,
1032 SHA1Update(&ctxt, esp->es_server.ea_peer,
1033 esp->es_server.ea_peerlen);
1034 while (optr < outp) {
1035 SHA1Final(dig, &ctxt);
1037 while (cp < dig + SHA_DIGESTSIZE)
1040 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1041 SHA1Update(&ctxt, esp->es_server.ea_skey,
1043 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1050 PUTCHAR(EAPT_SRP, outp);
1051 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1052 challen = MIN_CHALLENGE_LENGTH +
1053 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1054 esp->es_challen = challen;
1055 ptr = esp->es_challenge;
1056 while (--challen >= 0)
1057 *ptr++ = drand48() * 0x100;
1058 BCOPY(esp->es_challenge, outp, esp->es_challen);
1059 INCPTR(esp->es_challen, outp);
1061 #endif /* USE_SRP */
1067 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1068 PUTSHORT(outlen, lenloc);
1070 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1072 esp->es_server.ea_requests++;
1074 if (esp->es_server.ea_timeout > 0)
1075 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1079 * eap_authpeer - Authenticate our peer (behave as server).
1081 * Start server state and send first request. This is called only
1082 * after eap_lowerup.
1085 eap_authpeer(int unit, char *localname)
1087 eap_state *esp = &eap_states[unit];
1089 /* Save the name we're given. */
1090 esp->es_server.ea_name = localname;
1091 esp->es_server.ea_namelen = strlen(localname);
1093 esp->es_savedtime = esp->es_server.ea_timeout;
1095 /* Lower layer up yet? */
1096 if (esp->es_server.ea_state == eapInitial ||
1097 esp->es_server.ea_state == eapPending) {
1098 esp->es_server.ea_state = eapPending;
1102 esp->es_server.ea_state = eapPending;
1104 /* ID number not updated here intentionally; hashed into M1 */
1105 eap_send_request(esp);
1109 * eap_server_timeout - Retransmission timer for sending Requests
1113 eap_server_timeout(void *arg)
1119 #endif /* USE_EAPTLS */
1121 eap_state *esp = (eap_state *) arg;
1123 if (!eap_server_active(esp))
1127 switch(esp->es_server.ea_prev_state) {
1130 * In eap-tls the state changes after a request, so we return to
1131 * previous state ...
1134 case(eapTlsSendAck):
1135 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1139 * ... or resend the stored data
1142 case(eapTlsSendAlert):
1143 outp = outpacket_buf;
1144 MAKEHEADER(outp, PPP_EAP);
1145 PUTCHAR(EAP_REQUEST, outp);
1146 PUTCHAR(esp->es_server.ea_id, outp);
1150 eaptls_retransmit(esp->es_server.ea_session, &outp);
1152 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1153 PUTSHORT(outlen, lenloc);
1154 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1155 esp->es_server.ea_requests++;
1157 if (esp->es_server.ea_timeout > 0)
1158 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1164 #endif /* USE_EAPTLS */
1166 /* EAP ID number must not change on timeout. */
1167 eap_send_request(esp);
1171 * When it's time to send rechallenge the peer, this timeout is
1172 * called. Once the rechallenge is successful, the response handler
1173 * will restart the timer. If it fails, then the link is dropped.
1176 eap_rechallenge(void *arg)
1178 eap_state *esp = (eap_state *)arg;
1180 if (esp->es_server.ea_state != eapOpen &&
1181 esp->es_server.ea_state != eapSRP4)
1184 esp->es_server.ea_requests = 0;
1185 esp->es_server.ea_state = eapIdentify;
1186 eap_figure_next_state(esp, 0);
1187 esp->es_server.ea_id++;
1188 eap_send_request(esp);
1192 srp_lwrechallenge(void *arg)
1194 eap_state *esp = (eap_state *)arg;
1196 if (esp->es_server.ea_state != eapOpen ||
1197 esp->es_server.ea_type != EAPT_SRP)
1200 esp->es_server.ea_requests = 0;
1201 esp->es_server.ea_state = eapSRP4;
1202 esp->es_server.ea_id++;
1203 eap_send_request(esp);
1207 * eap_lowerup - The lower layer is now up.
1209 * This is called before either eap_authpeer or eap_authwithpeer. See
1210 * link_established() in auth.c. All that's necessary here is to
1211 * return to closed state so that those two routines will do the right
1215 eap_lowerup(int unit)
1217 eap_state *esp = &eap_states[unit];
1219 /* Discard any (possibly authenticated) peer name. */
1220 if (esp->es_server.ea_peer != NULL &&
1221 esp->es_server.ea_peer != remote_name)
1222 free(esp->es_server.ea_peer);
1223 esp->es_server.ea_peer = NULL;
1224 if (esp->es_client.ea_peer != NULL)
1225 free(esp->es_client.ea_peer);
1226 esp->es_client.ea_peer = NULL;
1228 esp->es_client.ea_state = eapClosed;
1229 esp->es_server.ea_state = eapClosed;
1233 * eap_lowerdown - The lower layer is now down.
1235 * Cancel all timeouts and return to initial state.
1238 eap_lowerdown(int unit)
1240 eap_state *esp = &eap_states[unit];
1242 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1243 UNTIMEOUT(eap_client_timeout, (void *)esp);
1245 if (eap_server_active(esp)) {
1246 if (esp->es_server.ea_timeout > 0) {
1247 UNTIMEOUT(eap_server_timeout, (void *)esp);
1250 if ((esp->es_server.ea_state == eapOpen ||
1251 esp->es_server.ea_state == eapSRP4) &&
1252 esp->es_rechallenge > 0) {
1253 UNTIMEOUT(eap_rechallenge, (void *)esp);
1255 if (esp->es_server.ea_state == eapOpen &&
1256 esp->es_lwrechallenge > 0) {
1257 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1261 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1262 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1266 * eap_protrej - Peer doesn't speak this protocol.
1268 * This shouldn't happen. If it does, it represents authentication
1272 eap_protrej(int unit)
1274 eap_state *esp = &eap_states[unit];
1276 if (eap_client_active(esp)) {
1277 error("EAP authentication failed due to Protocol-Reject");
1278 auth_withpeer_fail(unit, PPP_EAP);
1280 if (eap_server_active(esp)) {
1281 error("EAP authentication of peer failed on Protocol-Reject");
1282 auth_peer_fail(unit, PPP_EAP);
1284 eap_lowerdown(unit);
1288 * Format and send a regular EAP Response message.
1291 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1292 u_char *str, int lenstr)
1297 outp = outpacket_buf;
1299 MAKEHEADER(outp, PPP_EAP);
1301 PUTCHAR(EAP_RESPONSE, outp);
1303 esp->es_client.ea_id = id;
1304 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1305 PUTSHORT(msglen, outp);
1306 PUTCHAR(typenum, outp);
1308 BCOPY(str, outp, lenstr);
1311 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1315 * Format and send an MD5-Challenge EAP Response message.
1318 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1319 char *name, int namelen)
1324 outp = outpacket_buf;
1326 MAKEHEADER(outp, PPP_EAP);
1328 PUTCHAR(EAP_RESPONSE, outp);
1330 esp->es_client.ea_id = id;
1331 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1333 PUTSHORT(msglen, outp);
1334 PUTCHAR(EAPT_MD5CHAP, outp);
1335 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1336 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1337 INCPTR(MD5_SIGNATURE_SIZE, outp);
1339 BCOPY(name, outp, namelen);
1342 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1347 * Format and send a SRP EAP Response message.
1350 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1351 u_char *str, int lenstr)
1356 outp = outpacket_buf;
1358 MAKEHEADER(outp, PPP_EAP);
1360 PUTCHAR(EAP_RESPONSE, outp);
1362 esp->es_client.ea_id = id;
1363 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1364 PUTSHORT(msglen, outp);
1365 PUTCHAR(EAPT_SRP, outp);
1366 PUTCHAR(subtypenum, outp);
1368 BCOPY(str, outp, lenstr);
1371 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1375 * Format and send a SRP EAP Client Validator Response message.
1378 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1383 outp = outpacket_buf;
1385 MAKEHEADER(outp, PPP_EAP);
1387 PUTCHAR(EAP_RESPONSE, outp);
1389 esp->es_client.ea_id = id;
1390 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1392 PUTSHORT(msglen, outp);
1393 PUTCHAR(EAPT_SRP, outp);
1394 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1395 PUTLONG(flags, outp);
1396 BCOPY(str, outp, SHA_DIGESTSIZE);
1398 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1400 #endif /* USE_SRP */
1404 * Send an EAP-TLS response message with tls data
1407 eap_tls_response(eap_state *esp, u_char id)
1413 outp = outpacket_buf;
1415 MAKEHEADER(outp, PPP_EAP);
1417 PUTCHAR(EAP_RESPONSE, outp);
1424 If the id in the request is unchanged, we must retransmit
1427 if(id == esp->es_client.ea_id)
1428 eaptls_retransmit(esp->es_client.ea_session, &outp);
1430 eaptls_send(esp->es_client.ea_session, &outp);
1432 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1433 PUTSHORT(outlen, lenloc);
1435 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1437 esp->es_client.ea_id = id;
1441 * Send an EAP-TLS ack
1444 eap_tls_sendack(eap_state *esp, u_char id)
1450 outp = outpacket_buf;
1452 MAKEHEADER(outp, PPP_EAP);
1454 PUTCHAR(EAP_RESPONSE, outp);
1456 esp->es_client.ea_id = id;
1461 PUTCHAR(EAPT_TLS, outp);
1464 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1465 PUTSHORT(outlen, lenloc);
1467 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1469 #endif /* USE_EAPTLS */
1472 eap_send_nak(eap_state *esp, u_char id, u_char type)
1477 outp = outpacket_buf;
1479 MAKEHEADER(outp, PPP_EAP);
1481 PUTCHAR(EAP_RESPONSE, outp);
1483 esp->es_client.ea_id = id;
1484 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1485 PUTSHORT(msglen, outp);
1486 PUTCHAR(EAPT_NAK, outp);
1487 PUTCHAR(type, outp);
1489 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1494 name_of_pn_file(void)
1496 char *user, *path, *file;
1499 static bool pnlogged = 0;
1501 pw = getpwuid(getuid());
1502 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1506 file = _PATH_PSEUDONYM;
1507 pl = strlen(user) + strlen(file) + 2;
1511 (void) slprintf(path, pl, "%s/%s", user, file);
1513 dbglog("pseudonym file: %s", path);
1520 open_pn_file(mode_t modebits)
1525 if ((path = name_of_pn_file()) == NULL)
1527 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1535 remove_pn_file(void)
1539 if ((path = name_of_pn_file()) != NULL) {
1540 (void) unlink(path);
1546 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1549 u_char *datp, *digp;
1551 u_char dig[SHA_DIGESTSIZE];
1552 int dsize, fd, olen = len;
1555 * Do the decoding by working backwards. This eliminates the need
1556 * to save the decoded output in a separate buffer.
1560 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1561 dsize = SHA_DIGESTSIZE;
1565 SHA1Update(&ctxt, &val, 1);
1566 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1568 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1570 SHA1Update(&ctxt, esp->es_client.ea_name,
1571 esp->es_client.ea_namelen);
1573 SHA1Final(dig, &ctxt);
1574 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1578 /* Now check that the result is sane */
1579 if (olen <= 0 || *inp + 1 > olen) {
1580 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1585 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1587 dbglog("EAP: error saving pseudonym: %m");
1590 len = write(fd, inp + 1, *inp);
1591 if (close(fd) != -1 && len == *inp) {
1592 dbglog("EAP: saved pseudonym");
1593 esp->es_usedpseudo = 0;
1595 dbglog("EAP: failed to save pseudonym");
1599 #endif /* USE_SRP */
1603 * Format and send an CHAPV2-Challenge EAP Response message.
1606 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1611 outp = outpacket_buf;
1613 MAKEHEADER(outp, PPP_EAP);
1615 PUTCHAR(EAP_RESPONSE, outp);
1617 esp->es_client.ea_id = id;
1618 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1619 PUTSHORT(msglen, outp);
1620 PUTCHAR(EAPT_MSCHAPV2, outp);
1621 PUTCHAR(CHAP_RESPONSE, outp);
1622 PUTCHAR(chapid, outp);
1625 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1626 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1627 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1628 BCOPY(user, outp, user_len);
1630 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1635 * eap_request - Receive EAP Request message (client mode).
1638 eap_request(eap_state *esp, u_char *inp, int id, int len)
1643 char secret[MAXWORDLEN];
1644 char rhostname[256];
1646 u_char hash[MD5_SIGNATURE_SIZE];
1649 struct eaptls_session *ets = esp->es_client.ea_session;
1650 #endif /* USE_EAPTLS */
1653 struct t_client *tc;
1654 struct t_num sval, gval, Nval, *Ap, Bval;
1657 u_char dig[SHA_DIGESTSIZE];
1659 #endif /* USE_SRP */
1662 * Ignore requests if we're not open
1664 if (esp->es_client.ea_state <= eapClosed)
1668 * Note: we update es_client.ea_id *only if* a Response
1669 * message is being generated. Otherwise, we leave it the
1670 * same for duplicate detection purposes.
1673 esp->es_client.ea_requests++;
1674 if (esp->es_client.ea_maxrequests != 0 &&
1675 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1676 info("EAP: received too many Request messages");
1677 if (esp->es_client.ea_timeout > 0) {
1678 UNTIMEOUT(eap_client_timeout, (void *)esp);
1680 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1685 error("EAP: empty Request message discarded");
1689 GETCHAR(typenum, inp);
1695 info("EAP: Identity prompt \"%.*q\"", len, inp);
1697 if (esp->es_usepseudo &&
1698 (esp->es_usedpseudo == 0 ||
1699 (esp->es_usedpseudo == 1 &&
1700 id == esp->es_client.ea_id))) {
1701 esp->es_usedpseudo = 1;
1702 /* Try to get a pseudonym */
1703 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1704 strcpy(rhostname, SRP_PSEUDO_ID);
1705 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1706 sizeof (rhostname) - SRP_PSEUDO_LEN);
1707 /* XXX NAI unsupported */
1709 eap_send_response(esp, id, typenum,
1710 rhostname, len + SRP_PSEUDO_LEN);
1717 /* Stop using pseudonym now. */
1718 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1720 esp->es_usedpseudo = 2;
1722 #endif /* USE_SRP */
1723 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1724 esp->es_client.ea_namelen);
1727 case EAPT_NOTIFICATION:
1729 info("EAP: Notification \"%.*q\"", len, inp);
1730 eap_send_response(esp, id, typenum, NULL, 0);
1735 * Avoid the temptation to send Response Nak in reply
1736 * to Request Nak here. It can only lead to trouble.
1738 warn("EAP: unexpected Nak in Request; ignored");
1739 /* Return because we're waiting for something real. */
1744 error("EAP: received MD5-Challenge with no data");
1745 /* Bogus request; wait for something real. */
1748 GETCHAR(vallen, inp);
1750 if (vallen < 8 || vallen > len) {
1751 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1753 /* Try something better. */
1754 eap_send_nak(esp, id, EAPT_SRP);
1758 /* Not so likely to happen. */
1759 if (len - vallen >= sizeof (rhostname)) {
1760 dbglog("EAP: trimming really long peer name down");
1761 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1762 rhostname[sizeof (rhostname) - 1] = '\0';
1764 BCOPY(inp + vallen, rhostname, len - vallen);
1765 rhostname[len - vallen] = '\0';
1768 /* In case the remote doesn't give us his name. */
1769 if (explicit_remote ||
1770 (remote_name[0] != '\0' && vallen == len))
1771 strlcpy(rhostname, remote_name, sizeof (rhostname));
1774 * Get the secret for authenticating ourselves with
1775 * the specified host.
1777 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1778 rhostname, secret, &secret_len, 0)) {
1779 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1780 eap_send_nak(esp, id, EAPT_SRP);
1783 MD5_Init(&mdContext);
1785 MD5_Update(&mdContext, &typenum, 1);
1786 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1787 BZERO(secret, sizeof (secret));
1788 MD5_Update(&mdContext, inp, vallen);
1789 MD5_Final(hash, &mdContext);
1790 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1791 esp->es_client.ea_namelen);
1797 switch(esp->es_client.ea_state) {
1802 error("EAP: received EAP-TLS Listen packet with no data");
1803 /* Bogus request; wait for something real. */
1806 GETCHAR(flags, inp);
1807 if(flags & EAP_TLS_FLAGS_START){
1809 esp->es_client.ea_using_eaptls = 1;
1811 if (explicit_remote){
1812 esp->es_client.ea_peer = strdup(remote_name);
1813 esp->es_client.ea_peerlen = strlen(remote_name);
1815 esp->es_client.ea_peer = NULL;
1817 /* Init ssl session */
1818 if(!eaptls_init_ssl_client(esp)) {
1819 dbglog("cannot init ssl");
1820 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1821 esp->es_client.ea_using_eaptls = 0;
1825 ets = esp->es_client.ea_session;
1826 eap_tls_response(esp, id);
1827 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1831 /* The server has sent a bad start packet. */
1832 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1836 eap_tls_response(esp, id);
1837 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1842 error("EAP: discarding EAP-TLS Receive packet with no data");
1843 /* Bogus request; wait for something real. */
1846 eaptls_receive(ets, inp, len);
1849 eap_tls_sendack(esp, id);
1850 esp->es_client.ea_state = eapTlsRecv;
1854 if(ets->alert_recv) {
1855 eap_tls_sendack(esp, id);
1856 esp->es_client.ea_state = eapTlsRecvFailure;
1860 /* Check if TLS handshake is finished */
1861 if(eaptls_is_init_finished(ets)) {
1863 eaptls_gen_mppe_keys(ets, 1);
1865 eaptls_free_session(ets);
1866 eap_tls_sendack(esp, id);
1867 esp->es_client.ea_state = eapTlsRecvSuccess;
1871 eap_tls_response(esp,id);
1872 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1876 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1877 esp->es_client.ea_using_eaptls = 0;
1882 #endif /* USE_EAPTLS */
1887 error("EAP: received empty SRP Request");
1888 /* Bogus request; wait for something real. */
1893 GETCHAR(vallen, inp);
1896 case EAPSRP_CHALLENGE:
1898 if (esp->es_client.ea_session != NULL) {
1899 tc = (struct t_client *)esp->es_client.
1902 * If this is a new challenge, then start
1903 * over with a new client session context.
1904 * Otherwise, just resend last response.
1906 if (id != esp->es_client.ea_id) {
1908 esp->es_client.ea_session = NULL;
1912 /* No session key just yet */
1913 esp->es_client.ea_skey = NULL;
1915 GETCHAR(vallen, inp);
1917 if (vallen >= len) {
1918 error("EAP: badly-formed SRP Challenge"
1920 /* Ignore badly-formed messages */
1923 BCOPY(inp, rhostname, vallen);
1924 rhostname[vallen] = '\0';
1925 INCPTR(vallen, inp);
1929 * In case the remote doesn't give us his name,
1930 * use configured name.
1932 if (explicit_remote ||
1933 (remote_name[0] != '\0' && vallen == 0)) {
1934 strlcpy(rhostname, remote_name,
1935 sizeof (rhostname));
1938 if (esp->es_client.ea_peer != NULL)
1939 free(esp->es_client.ea_peer);
1940 esp->es_client.ea_peer = strdup(rhostname);
1941 esp->es_client.ea_peerlen = strlen(rhostname);
1943 GETCHAR(vallen, inp);
1945 if (vallen >= len) {
1946 error("EAP: badly-formed SRP Challenge"
1948 /* Ignore badly-formed messages */
1953 INCPTR(vallen, inp);
1956 GETCHAR(vallen, inp);
1959 error("EAP: badly-formed SRP Challenge"
1961 /* Ignore badly-formed messages */
1964 /* If no generator present, then use value 2 */
1966 gval.data = (u_char *)"\002";
1972 INCPTR(vallen, inp);
1976 * If no modulus present, then use well-known
1980 Nval.data = (u_char *)wkmodulus;
1981 Nval.len = sizeof (wkmodulus);
1986 tc = t_clientopen(esp->es_client.ea_name,
1987 &Nval, &gval, &sval);
1989 eap_send_nak(esp, id, EAPT_MD5CHAP);
1992 esp->es_client.ea_session = (void *)tc;
1994 /* Add Challenge ID & type to verifier */
1997 t_clientaddexdata(tc, vals, 2);
1999 Ap = t_clientgenexp(tc);
2000 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2005 tc = (struct t_client *)esp->es_client.ea_session;
2007 warn("EAP: peer sent Subtype 2 without 1");
2008 eap_send_nak(esp, id, EAPT_MD5CHAP);
2011 if (esp->es_client.ea_skey != NULL) {
2013 * ID number should not change here. Warn
2014 * if it does (but otherwise ignore).
2016 if (id != esp->es_client.ea_id) {
2017 warn("EAP: ID changed from %d to %d "
2018 "in SRP Subtype 2 rexmit",
2019 esp->es_client.ea_id, id);
2022 if (get_srp_secret(esp->es_unit,
2023 esp->es_client.ea_name,
2024 esp->es_client.ea_peer, secret, 0) == 0) {
2026 * Can't work with this peer because
2027 * the secret is missing. Just give
2030 eap_send_nak(esp, id, EAPT_MD5CHAP);
2035 t_clientpasswd(tc, secret);
2036 BZERO(secret, sizeof (secret));
2037 esp->es_client.ea_skey =
2038 t_clientgetkey(tc, &Bval);
2039 if (esp->es_client.ea_skey == NULL) {
2040 /* Server is rogue; stop now */
2041 error("EAP: SRP server is rogue");
2042 goto client_failure;
2045 eap_srpval_response(esp, id, SRPVAL_EBIT,
2046 t_clientresponse(tc));
2049 case EAPSRP_SVALIDATOR:
2050 tc = (struct t_client *)esp->es_client.ea_session;
2051 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2052 warn("EAP: peer sent Subtype 3 without 1/2");
2053 eap_send_nak(esp, id, EAPT_MD5CHAP);
2057 * If we're already open, then this ought to be a
2058 * duplicate. Otherwise, check that the server is
2059 * who we think it is.
2061 if (esp->es_client.ea_state == eapOpen) {
2062 if (id != esp->es_client.ea_id) {
2063 warn("EAP: ID changed from %d to %d "
2064 "in SRP Subtype 3 rexmit",
2065 esp->es_client.ea_id, id);
2068 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2069 if (len < 0 || t_clientverify(tc, inp +
2070 sizeof (u_int32_t)) != 0) {
2071 error("EAP: SRP server verification "
2073 goto client_failure;
2075 GETLONG(esp->es_client.ea_keyflags, inp);
2076 /* Save pseudonym if user wants it. */
2077 if (len > 0 && esp->es_usepseudo) {
2078 INCPTR(SHA_DIGESTSIZE, inp);
2079 write_pseudonym(esp, inp, len, id);
2083 * We've verified our peer. We're now mostly done,
2084 * except for waiting on the regular EAP Success
2087 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2090 case EAPSRP_LWRECHALLENGE:
2092 warn("EAP: malformed Lightweight rechallenge");
2097 SHA1Update(&ctxt, vals, 1);
2098 SHA1Update(&ctxt, esp->es_client.ea_skey,
2100 SHA1Update(&ctxt, inp, len);
2101 SHA1Update(&ctxt, esp->es_client.ea_name,
2102 esp->es_client.ea_namelen);
2103 SHA1Final(dig, &ctxt);
2104 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2109 error("EAP: unknown SRP Subtype %d", vallen);
2110 eap_send_nak(esp, id, EAPT_MD5CHAP);
2114 #endif /* USE_SRP */
2119 error("EAP: received invalid MSCHAPv2 packet, too short");
2122 unsigned char opcode;
2123 GETCHAR(opcode, inp);
2124 unsigned char chapid; /* Chapv2-ID */
2125 GETCHAR(chapid, inp);
2127 GETSHORT(mssize, inp);
2129 /* Validate the mssize field */
2130 if (len != mssize) {
2131 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2136 /* If MSCHAPv2 digest was not found, NAK the packet */
2137 if (!esp->es_client.digest) {
2138 error("EAP MSCHAPv2 not supported");
2139 eap_send_nak(esp, id, EAPT_SRP);
2144 case CHAP_CHALLENGE: {
2146 /* make_response() expects: VLEN + VALUE */
2147 u_char *challenge = inp;
2149 unsigned char vsize;
2150 GETCHAR(vsize, inp);
2153 /* Validate the VALUE field */
2154 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2155 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2159 /* Increment past the VALUE field */
2160 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2161 len -= MS_CHAP2_PEER_CHAL_LEN;
2163 /* Extract the hostname */
2164 rhostname[0] = '\0';
2166 if (len >= sizeof (rhostname)) {
2167 dbglog("EAP: trimming really long peer name down");
2168 len = sizeof(rhostname) - 1;
2170 BCOPY(inp, rhostname, len);
2171 rhostname[len] = '\0';
2174 /* In case the remote doesn't give us his name. */
2175 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2176 strlcpy(rhostname, remote_name, sizeof(rhostname));
2178 /* Get the secret for authenticating ourselves with the specified host. */
2179 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2180 rhostname, secret, &secret_len, 0)) {
2181 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2182 eap_send_nak(esp, id, EAPT_SRP);
2186 /* Create the MSCHAPv2 response (and add to cache) */
2187 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2188 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2189 challenge, secret, secret_len, NULL);
2191 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2194 case CHAP_SUCCESS: {
2196 /* Check response for mutual authentication */
2197 u_char status = CHAP_FAILURE;
2198 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2199 info("Chap authentication succeeded! %.*v", len, inp);
2200 status = CHAP_SUCCESS;
2202 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2205 case CHAP_FAILURE: {
2207 /* Process the failure string, and log appropriate information */
2208 esp->es_client.digest->handle_failure(inp, len);
2210 u_char status = CHAP_FAILURE;
2211 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2212 goto client_failure; /* force termination */
2216 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2217 eap_send_nak(esp, id, EAPT_SRP);
2225 /* Initialize the PEAP context (if not already initialized) */
2226 if (!esp->ea_peap) {
2227 rhostname[0] = '\0';
2228 if (explicit_remote || (remote_name[0] != '\0')) {
2229 strlcpy(rhostname, remote_name, sizeof (rhostname));
2231 if (peap_init(&esp->ea_peap, rhostname)) {
2232 eap_send_nak(esp, id, EAPT_TLS);
2237 /* Process the PEAP packet */
2238 if (peap_process(esp, id, inp, len)) {
2239 eap_send_nak(esp, id, EAPT_TLS);
2243 #endif /* USE_PEAP */
2246 info("EAP: unknown authentication type %d; Naking", typenum);
2247 eap_send_nak(esp, id, EAPT_SRP);
2251 if (esp->es_client.ea_timeout > 0) {
2252 UNTIMEOUT(eap_client_timeout, (void *)esp);
2253 TIMEOUT(eap_client_timeout, (void *)esp,
2254 esp->es_client.ea_timeout);
2259 esp->es_client.ea_state = eapBadAuth;
2260 if (esp->es_client.ea_timeout > 0) {
2261 UNTIMEOUT(eap_client_timeout, (void *)esp);
2263 esp->es_client.ea_session = NULL;
2266 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2267 #endif /* USE_SRP */
2271 * eap_response - Receive EAP Response message (server mode).
2274 eap_response(eap_state *esp, u_char *inp, int id, int len)
2279 char secret[MAXSECRETLEN];
2280 char rhostname[256];
2282 u_char hash[MD5_SIGNATURE_SIZE];
2284 struct t_server *ts;
2287 u_char dig[SHA_DIGESTSIZE];
2288 #endif /* USE_SRP */
2291 struct eaptls_session *ets;
2293 #endif /* USE_EAPTLS */
2296 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2297 unsigned char *, unsigned char *, char *, int);
2298 char response_message[256];
2302 * Ignore responses if we're not open
2304 if (esp->es_server.ea_state <= eapClosed)
2307 if (esp->es_server.ea_id != id) {
2308 dbglog("EAP: discarding Response %d; expected ID %d", id,
2309 esp->es_server.ea_id);
2313 esp->es_server.ea_responses++;
2316 error("EAP: empty Response message discarded");
2320 GETCHAR(typenum, inp);
2325 if (esp->es_server.ea_state != eapIdentify) {
2326 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2330 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2331 if (esp->es_server.ea_peer != NULL &&
2332 esp->es_server.ea_peer != remote_name)
2333 free(esp->es_server.ea_peer);
2334 esp->es_server.ea_peer = malloc(len + 1);
2335 if (esp->es_server.ea_peer == NULL) {
2336 esp->es_server.ea_peerlen = 0;
2337 eap_figure_next_state(esp, 1);
2340 BCOPY(inp, esp->es_server.ea_peer, len);
2341 esp->es_server.ea_peer[len] = '\0';
2342 esp->es_server.ea_peerlen = len;
2343 eap_figure_next_state(esp, 0);
2348 switch(esp->es_server.ea_state) {
2352 ets = (struct eaptls_session *) esp->es_server.ea_session;
2354 eap_figure_next_state(esp,
2355 eaptls_receive(esp->es_server.ea_session, inp, len));
2357 if(ets->alert_recv) {
2358 eap_send_failure(esp);
2365 dbglog("EAP-TLS ACK with extra data");
2367 eap_figure_next_state(esp, 0);
2370 case eapTlsRecvClient:
2371 /* Receive authentication response from client */
2373 GETCHAR(flags, inp);
2375 if(len == 1 && !flags) { /* Ack = ok */
2377 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2379 eap_send_success(esp);
2381 else { /* failure */
2382 warn("Server authentication failed");
2383 eap_send_failure(esp);
2387 warn("Bogus EAP-TLS packet received from client");
2389 eaptls_free_session(esp->es_server.ea_session);
2393 case eapTlsRecvAlertAck:
2394 eap_send_failure(esp);
2398 eap_figure_next_state(esp, 1);
2402 #endif /* USE_EAPTLS */
2404 case EAPT_NOTIFICATION:
2405 dbglog("EAP unexpected Notification; response discarded");
2410 info("EAP: Nak Response with no suggested protocol");
2411 eap_figure_next_state(esp, 1);
2415 GETCHAR(vallen, inp);
2418 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2419 /* Peer cannot Nak Identify Request */
2420 eap_figure_next_state(esp, 1);
2426 /* Run through SRP validator selection again. */
2427 esp->es_server.ea_state = eapIdentify;
2428 eap_figure_next_state(esp, 0);
2432 esp->es_server.ea_state = eapMD5Chall;
2436 /* Send EAP-TLS start packet */
2438 esp->es_server.ea_state = eapTlsStart;
2440 #endif /* USE_EAPTLS */
2444 info("EAP: peer proposes MSCHAPv2");
2445 /* If MSCHAPv2 digest was not found, NAK the packet */
2446 if (!esp->es_server.digest) {
2447 error("EAP MSCHAPv2 not supported");
2448 eap_send_nak(esp, id, EAPT_SRP);
2451 esp->es_server.ea_state = eapMSCHAPv2Chall;
2456 dbglog("EAP: peer requesting unknown Type %d", vallen);
2457 switch (esp->es_server.ea_state) {
2461 esp->es_server.ea_state = eapMD5Chall;
2465 esp->es_server.ea_state = eapIdentify;
2466 eap_figure_next_state(esp, 0);
2476 if (esp->es_server.ea_state != eapMD5Chall) {
2477 error("EAP: unexpected MD5-Response");
2478 eap_figure_next_state(esp, 1);
2482 error("EAP: received MD5-Response with no data");
2483 eap_figure_next_state(esp, 1);
2486 GETCHAR(vallen, inp);
2488 if (vallen != 16 || vallen > len) {
2489 error("EAP: MD5-Response with bad length %d", vallen);
2490 eap_figure_next_state(esp, 1);
2494 /* Not so likely to happen. */
2495 if (len - vallen >= sizeof (rhostname)) {
2496 dbglog("EAP: trimming really long peer name down");
2497 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2498 rhostname[sizeof (rhostname) - 1] = '\0';
2500 BCOPY(inp + vallen, rhostname, len - vallen);
2501 rhostname[len - vallen] = '\0';
2504 /* In case the remote doesn't give us his name. */
2505 if (explicit_remote ||
2506 (remote_name[0] != '\0' && vallen == len))
2507 strlcpy(rhostname, remote_name, sizeof (rhostname));
2510 * Get the secret for authenticating the specified
2513 if (!get_secret(esp->es_unit, rhostname,
2514 esp->es_server.ea_name, secret, &secret_len, 1)) {
2515 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2516 eap_send_failure(esp);
2519 MD5_Init(&mdContext);
2520 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2521 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2522 BZERO(secret, sizeof (secret));
2523 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2524 MD5_Final(hash, &mdContext);
2525 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2526 eap_send_failure(esp);
2529 esp->es_server.ea_type = EAPT_MD5CHAP;
2530 eap_send_success(esp);
2531 eap_figure_next_state(esp, 0);
2532 if (esp->es_rechallenge != 0)
2533 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2539 error("EAP: received MSCHAPv2 with no data");
2540 eap_figure_next_state(esp, 1);
2543 GETCHAR(opcode, inp);
2548 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2549 error("EAP: unexpected MSCHAPv2-Response");
2550 eap_figure_next_state(esp, 1);
2553 /* skip MS ID + len */
2555 GETCHAR(vallen, inp);
2558 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2559 error("EAP: Invalid MSCHAPv2-Response "
2560 "length %d", vallen);
2561 eap_figure_next_state(esp, 1);
2565 /* Not so likely to happen. */
2566 if (len - vallen >= sizeof (rhostname)) {
2567 dbglog("EAP: trimming really long peer name down");
2568 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2569 rhostname[sizeof (rhostname) - 1] = '\0';
2571 BCOPY(inp + vallen, rhostname, len - vallen);
2572 rhostname[len - vallen] = '\0';
2575 /* In case the remote doesn't give us his name. */
2576 if (explicit_remote ||
2577 (remote_name[0] != '\0' && vallen == len))
2578 strlcpy(rhostname, remote_name, sizeof (rhostname));
2580 /* strip the MS domain name */
2581 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2582 char tmp[MAXNAMELEN+1];
2584 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2585 strcpy(rhostname, tmp);
2588 if (chap_verify_hook)
2589 chap_verifier = chap_verify_hook;
2591 chap_verifier = eap_chap_verify_response;
2593 esp->es_server.ea_id += 1;
2594 if ((*chap_verifier)(rhostname,
2595 esp->es_server.ea_name,
2597 esp->es_server.digest,
2601 sizeof(response_message)))
2603 info("EAP: MSCHAPv2 success for peer %q",
2605 esp->es_server.ea_type = EAPT_MSCHAPV2;
2606 eap_chapms2_send_request(esp,
2607 esp->es_server.ea_id,
2609 esp->es_server.ea_id,
2611 strlen(response_message));
2612 eap_figure_next_state(esp, 0);
2613 if (esp->es_rechallenge != 0)
2614 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2617 warn("EAP: MSCHAPv2 failure for peer %q",
2619 eap_chapms2_send_request(esp,
2620 esp->es_server.ea_id,
2622 esp->es_server.ea_id,
2624 strlen(response_message));
2628 info("EAP: MSCHAPv2 success confirmed");
2631 info("EAP: MSCHAPv2 failure confirmed");
2634 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2635 eap_send_nak(esp, id, EAPT_SRP);
2644 error("EAP: empty SRP Response");
2645 eap_figure_next_state(esp, 1);
2648 GETCHAR(typenum, inp);
2652 if (esp->es_server.ea_state != eapSRP1) {
2653 error("EAP: unexpected SRP Subtype 1 Response");
2654 eap_figure_next_state(esp, 1);
2659 ts = (struct t_server *)esp->es_server.ea_session;
2661 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2662 if (esp->es_server.ea_skey == NULL) {
2663 /* Client's A value is bogus; terminate now */
2664 error("EAP: bogus A value from client");
2665 eap_send_failure(esp);
2667 eap_figure_next_state(esp, 0);
2671 case EAPSRP_CVALIDATOR:
2672 if (esp->es_server.ea_state != eapSRP2) {
2673 error("EAP: unexpected SRP Subtype 2 Response");
2674 eap_figure_next_state(esp, 1);
2677 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2678 error("EAP: M1 length %d < %d", len,
2679 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2680 eap_figure_next_state(esp, 1);
2683 GETLONG(esp->es_server.ea_keyflags, inp);
2684 ts = (struct t_server *)esp->es_server.ea_session;
2686 if (t_serververify(ts, inp)) {
2687 info("EAP: unable to validate client identity");
2688 eap_send_failure(esp);
2691 eap_figure_next_state(esp, 0);
2695 if (esp->es_server.ea_state != eapSRP3) {
2696 error("EAP: unexpected SRP Subtype 3 Response");
2697 eap_send_failure(esp);
2700 esp->es_server.ea_type = EAPT_SRP;
2701 eap_send_success(esp);
2702 eap_figure_next_state(esp, 0);
2703 if (esp->es_rechallenge != 0)
2704 TIMEOUT(eap_rechallenge, esp,
2705 esp->es_rechallenge);
2706 if (esp->es_lwrechallenge != 0)
2707 TIMEOUT(srp_lwrechallenge, esp,
2708 esp->es_lwrechallenge);
2711 case EAPSRP_LWRECHALLENGE:
2712 if (esp->es_server.ea_state != eapSRP4) {
2713 info("EAP: unexpected SRP Subtype 4 Response");
2716 if (len != SHA_DIGESTSIZE) {
2717 error("EAP: bad Lightweight rechallenge "
2723 SHA1Update(&ctxt, &vallen, 1);
2724 SHA1Update(&ctxt, esp->es_server.ea_skey,
2726 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2727 SHA1Update(&ctxt, esp->es_server.ea_peer,
2728 esp->es_server.ea_peerlen);
2729 SHA1Final(dig, &ctxt);
2730 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2731 error("EAP: failed Lightweight rechallenge");
2732 eap_send_failure(esp);
2735 esp->es_server.ea_state = eapOpen;
2736 if (esp->es_lwrechallenge != 0)
2737 TIMEOUT(srp_lwrechallenge, esp,
2738 esp->es_lwrechallenge);
2742 #endif /* USE_SRP */
2745 /* This can't happen. */
2746 error("EAP: unknown Response type %d; ignored", typenum);
2750 if (esp->es_server.ea_timeout > 0) {
2751 UNTIMEOUT(eap_server_timeout, (void *)esp);
2754 if (esp->es_server.ea_state != eapBadAuth &&
2755 esp->es_server.ea_state != eapOpen) {
2756 esp->es_server.ea_id++;
2757 eap_send_request(esp);
2762 * eap_success - Receive EAP Success message (client mode).
2765 eap_success(eap_state *esp, u_char *inp, int id, int len)
2767 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2769 && esp->es_client.ea_state != eapTlsRecvSuccess
2770 #endif /* USE_EAPTLS */
2772 dbglog("EAP unexpected success message in state %s (%d)",
2773 eap_state_name(esp->es_client.ea_state),
2774 esp->es_client.ea_state);
2779 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2780 eapTlsRecvSuccess) {
2781 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2782 eap_state_name(esp->es_client.ea_state),
2783 esp->es_client.ea_state);
2786 #endif /* USE_EAPTLS */
2788 if (esp->es_client.ea_timeout > 0) {
2789 UNTIMEOUT(eap_client_timeout, (void *)esp);
2793 /* This is odd. The spec doesn't allow for this. */
2798 peap_finish(&esp->ea_peap);
2801 esp->es_client.ea_state = eapOpen;
2802 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2806 * eap_failure - Receive EAP Failure message (client mode).
2809 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2812 * Ignore failure messages if we're not open
2814 if (esp->es_client.ea_state <= eapClosed)
2817 if (!eap_client_active(esp)) {
2818 dbglog("EAP unexpected failure message in state %s (%d)",
2819 eap_state_name(esp->es_client.ea_state),
2820 esp->es_client.ea_state);
2823 if (esp->es_client.ea_timeout > 0) {
2824 UNTIMEOUT(eap_client_timeout, (void *)esp);
2828 /* This is odd. The spec doesn't allow for this. */
2832 esp->es_client.ea_state = eapBadAuth;
2834 error("EAP: peer reports authentication failure");
2837 peap_finish(&esp->ea_peap);
2840 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2844 * eap_input - Handle received EAP message.
2847 eap_input(int unit, u_char *inp, int inlen)
2849 eap_state *esp = &eap_states[unit];
2854 * Parse header (code, id and length). If packet too short,
2857 if (inlen < EAP_HEADERLEN) {
2858 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2864 if (len < EAP_HEADERLEN || len > inlen) {
2865 error("EAP: packet has illegal length field %d (%d..%d)", len,
2866 EAP_HEADERLEN, inlen);
2869 len -= EAP_HEADERLEN;
2871 /* Dispatch based on message code */
2874 eap_request(esp, inp, id, len);
2878 eap_response(esp, inp, id, len);
2882 eap_success(esp, inp, id, len);
2886 eap_failure(esp, inp, id, len);
2889 default: /* XXX Need code reject */
2890 /* Note: it's not legal to send EAP Nak here. */
2891 warn("EAP: unknown code %d received", code);
2897 * eap_printpkt - print the contents of an EAP packet.
2899 static char *eap_codenames[] = {
2900 "Request", "Response", "Success", "Failure"
2903 static char *eap_typenames[] = {
2904 "Identity", "Notification", "Nak", "MD5-Challenge",
2905 "OTP", "Generic-Token", NULL, NULL,
2906 "RSA", "DSS", "KEA", "KEA-Validate",
2907 "TLS", "Defender", "Windows 2000", "Arcot",
2908 "Cisco", "Nokia", "SRP", NULL,
2909 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2914 eap_printpkt(u_char *inp, int inlen,
2915 void (*printer) (void *, char *, ...), void *arg)
2917 int code, id, len, rtype, vallen;
2922 #endif /* USE_EAPTLS */
2927 if (inlen < EAP_HEADERLEN)
2933 if (len < EAP_HEADERLEN || len > inlen)
2936 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2937 printer(arg, " %s", eap_codenames[code-1]);
2939 printer(arg, " code=0x%x", code);
2940 printer(arg, " id=0x%x", id);
2941 len -= EAP_HEADERLEN;
2945 printer(arg, " <missing type>");
2948 GETCHAR(rtype, inp);
2951 rtype <= sizeof (eap_typenames) / sizeof (char *))
2952 printer(arg, " %s", eap_typenames[rtype-1]);
2954 printer(arg, " type=0x%x", rtype);
2957 case EAPT_NOTIFICATION:
2959 printer(arg, " <Message ");
2960 print_string((char *)inp, len, printer, arg);
2965 printer(arg, " <No message>");
2972 GETCHAR(vallen, inp);
2976 printer(arg, " <Value%.*B>", vallen, inp);
2977 INCPTR(vallen, inp);
2980 printer(arg, " <Name ");
2981 print_string((char *)inp, len, printer, arg);
2986 printer(arg, " <No name>");
2994 GETCHAR(opcode, inp);
2997 case CHAP_CHALLENGE:
3000 GETCHAR(vallen, inp);
3005 printer(arg, " Challenge <");
3006 for (; vallen > 0; --vallen) {
3009 printer(arg, "%.2x", val);
3013 printer(arg, ", <Name ");
3014 print_string((char *)inp, len, printer, arg);
3019 printer(arg, ", <No name>");
3025 printer(arg, " Success <Message ");
3026 print_string((char *)inp, len, printer, arg);
3032 printer(arg, " Failure <Message ");
3033 print_string((char *)inp, len, printer, arg);
3039 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3049 GETCHAR(flags, inp);
3052 if(flags == 0 && len == 0){
3053 printer(arg, " Ack");
3057 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3058 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3059 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3061 #endif /* USE_EAPTLS */
3067 GETCHAR(vallen, inp);
3069 printer(arg, "-%d", vallen);
3071 case EAPSRP_CHALLENGE:
3072 GETCHAR(vallen, inp);
3077 printer(arg, " <Name ");
3078 print_string((char *)inp, vallen, printer,
3082 printer(arg, " <No name>");
3084 INCPTR(vallen, inp);
3086 GETCHAR(vallen, inp);
3090 printer(arg, " <s%.*B>", vallen, inp);
3091 INCPTR(vallen, inp);
3093 GETCHAR(vallen, inp);
3098 printer(arg, " <Default g=2>");
3100 printer(arg, " <g%.*B>", vallen, inp);
3102 INCPTR(vallen, inp);
3105 printer(arg, " <Default N>");
3107 printer(arg, " <N%.*B>", len, inp);
3114 printer(arg, " <B%.*B>", len, inp);
3119 case EAPSRP_SVALIDATOR:
3120 if (len < sizeof (u_int32_t))
3123 len -= sizeof (u_int32_t);
3124 if (uval & SRPVAL_EBIT) {
3126 uval &= ~SRPVAL_EBIT;
3129 printer(arg, " f<%X>", uval);
3131 if ((vallen = len) > SHA_DIGESTSIZE)
3132 vallen = SHA_DIGESTSIZE;
3133 printer(arg, " <M2%.*B%s>", len, inp,
3134 len < SHA_DIGESTSIZE ? "?" : "");
3135 INCPTR(vallen, inp);
3138 printer(arg, " <PN%.*B>", len, inp);
3144 case EAPSRP_LWRECHALLENGE:
3145 printer(arg, " <Challenge%.*B>", len, inp);
3151 #endif /* USE_SRP */
3158 GETCHAR(rtype, inp);
3161 rtype <= sizeof (eap_typenames) / sizeof (char *))
3162 printer(arg, " %s", eap_typenames[rtype-1]);
3164 printer(arg, " type=0x%x", rtype);
3168 printer(arg, " <Name ");
3169 print_string((char *)inp, len, printer, arg);
3180 GETCHAR(flags, inp);
3183 if(flags == 0 && len == 0){
3184 printer(arg, " Ack");
3188 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3189 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3190 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3193 #endif /* USE_EAPTLS */
3197 printer(arg, " <missing hint>");
3200 GETCHAR(rtype, inp);
3202 printer(arg, " <Suggested-type %02X", rtype);
3204 rtype <= sizeof (eap_typenames) / sizeof (char *))
3205 printer(arg, " (%s)", eap_typenames[rtype-1]);
3211 printer(arg, " <missing length>");
3214 GETCHAR(vallen, inp);
3218 printer(arg, " <Value%.*B>", vallen, inp);
3219 INCPTR(vallen, inp);
3222 printer(arg, " <Name ");
3223 print_string((char *)inp, len, printer, arg);
3228 printer(arg, " <No name>");
3236 GETCHAR(opcode, inp);
3242 GETCHAR(vallen, inp);
3247 printer(arg, " Response <");
3248 for (; vallen > 0; --vallen) {
3251 printer(arg, "%.2x", val);
3255 printer(arg, ", <Name ");
3256 print_string((char *)inp, len, printer, arg);
3261 printer(arg, ", <No name>");
3265 printer(arg, " Success");
3268 printer(arg, " Failure");
3271 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3281 GETCHAR(vallen, inp);
3283 printer(arg, "-%d", vallen);
3286 printer(arg, " <A%.*B>", len, inp);
3291 case EAPSRP_CVALIDATOR:
3292 if (len < sizeof (u_int32_t))
3295 len -= sizeof (u_int32_t);
3296 if (uval & SRPVAL_EBIT) {
3298 uval &= ~SRPVAL_EBIT;
3301 printer(arg, " f<%X>", uval);
3303 printer(arg, " <M1%.*B%s>", len, inp,
3304 len == SHA_DIGESTSIZE ? "" : "?");
3312 case EAPSRP_LWRECHALLENGE:
3313 printer(arg, " <Response%.*B%s>", len, inp,
3314 len == SHA_DIGESTSIZE ? "" : "?");
3315 if ((vallen = len) > SHA_DIGESTSIZE)
3316 vallen = SHA_DIGESTSIZE;
3317 INCPTR(vallen, inp);
3322 #endif /* USE_SRP */
3326 case EAP_SUCCESS: /* No payload expected for these! */
3331 printer(arg, " <truncated>");
3336 printer(arg, "%8B...", inp);
3338 printer(arg, "%.*B", len, inp);
3341 return (inp - pstart);