2 * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
4 * Copyright (c) 2001 by Sun Microsystems, Inc.
7 * Non-exclusive rights to redistribute, modify, translate, and use
8 * this software in source and binary forms, in whole or in part, is
9 * hereby granted, provided that the above copyright notice is
10 * duplicated in any source form, and that neither the name of the
11 * copyright holder nor the author is used to endorse or promote
12 * products derived from this software.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 * Original version by James Carlson
20 * This implementation of EAP supports MD5-Challenge and SRP-SHA1
21 * authentication styles. Note that support of MD5-Challenge is a
22 * requirement of RFC 2284, and that it's essentially just a
23 * reimplementation of regular RFC 1994 CHAP using EAP messages.
25 * As an authenticator ("server"), there are multiple phases for each
26 * style. In the first phase of each style, the unauthenticated peer
27 * name is queried using the EAP Identity request type. If the
28 * "remotename" option is used, then this phase is skipped, because
29 * the peer's name is presumed to be known.
31 * For MD5-Challenge, there are two phases, and the second phase
32 * consists of sending the challenge itself and handling the
33 * associated response.
35 * For SRP-SHA1, there are four phases. The second sends 's', 'N',
36 * and 'g'. The reply contains 'A'. The third sends 'B', and the
37 * reply contains 'M1'. The forth sends the 'M2' value.
39 * As an authenticatee ("client"), there's just a single phase --
40 * responding to the queries generated by the peer. EAP is an
41 * authenticator-driven protocol.
43 * Based on draft-ietf-pppext-eap-srp-03.txt.
47 * Modification by Beniamino Galvani, Mar 2005
48 * Implemented EAP-TLS authentication
56 #include <sys/types.h>
63 #include "pathnames.h"
74 #ifndef SHA_DIGESTSIZE
75 #define SHA_DIGESTSIZE 20
80 #endif /* USE_EAPTLS */
87 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
89 static char *pn_secret = NULL; /* Pseudonym generating secret */
93 * Command-line options.
95 static option_t eap_option_list[] = {
96 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
97 "Set retransmit timeout for EAP Requests (server)" },
98 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
99 "Set max number of EAP Requests sent (server)" },
100 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
101 "Set time limit for peer EAP authentication" },
102 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
103 "Set max number of EAP Requests allows (client)" },
104 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
105 "Set interval for EAP rechallenge" },
107 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
108 "Set interval for SRP lightweight rechallenge" },
109 { "srp-pn-secret", o_string, &pn_secret,
110 "Long term pseudonym generation secret" },
111 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
112 "Use pseudonym if offered one by server", 1 },
118 * Protocol entry points.
120 static void eap_init (int unit);
121 static void eap_input (int unit, u_char *inp, int inlen);
122 static void eap_protrej (int unit);
123 static void eap_lowerup (int unit);
124 static void eap_lowerdown (int unit);
125 static int eap_printpkt (u_char *inp, int inlen,
126 void (*)(void *arg, char *fmt, ...), void *arg);
128 struct protent eap_protent = {
129 PPP_EAP, /* protocol number */
130 eap_init, /* initialization procedure */
131 eap_input, /* process a received packet */
132 eap_protrej, /* process a received protocol-reject */
133 eap_lowerup, /* lower layer has gone up */
134 eap_lowerdown, /* lower layer has gone down */
135 NULL, /* open the protocol */
136 NULL, /* close the protocol */
137 eap_printpkt, /* print a packet in readable form */
138 NULL, /* process a received data packet */
139 1, /* protocol enabled */
140 "EAP", /* text name of protocol */
141 NULL, /* text name of corresponding data protocol */
142 eap_option_list, /* list of command-line options */
143 NULL, /* check requested options; assign defaults */
144 NULL, /* configure interface for demand-dial */
145 NULL /* say whether to bring up link for this pkt */
150 * A well-known 2048 bit modulus.
152 static const u_char wkmodulus[] = {
153 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
154 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
155 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
156 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
157 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
158 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
159 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
160 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
161 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
162 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
163 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
164 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
165 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
166 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
167 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
168 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
169 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
170 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
171 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
172 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
173 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
174 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
175 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
176 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
177 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
178 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
179 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
180 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
181 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
182 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
183 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
184 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
188 /* Local forward declarations. */
189 static void eap_server_timeout (void *arg);
192 * Convert EAP state code to printable string for debug.
195 eap_state_name(enum eap_state_code esc)
197 static const char *state_names[] = { EAP_STATES };
199 return (state_names[(int)esc]);
203 * eap_init - Initialize state for an EAP user. This is currently
204 * called once by main() during start-up.
209 eap_state *esp = &eap_states[unit];
211 BZERO(esp, sizeof (*esp));
213 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
214 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
215 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
216 esp->es_client.ea_timeout = EAP_DEFREQTIME;
217 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
219 esp->es_client.ea_using_eaptls = 0;
220 #endif /* USE_EAPTLS */
222 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
223 esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
228 * eap_client_timeout - Give up waiting for the peer to send any
232 eap_client_timeout(void *arg)
234 eap_state *esp = (eap_state *) arg;
236 if (!eap_client_active(esp))
239 error("EAP: timeout waiting for Request from peer");
240 auth_withpeer_fail(esp->es_unit, PPP_EAP);
241 esp->es_client.ea_state = eapBadAuth;
245 * eap_authwithpeer - Authenticate to our peer (behave as client).
247 * Start client state and wait for requests. This is called only
251 eap_authwithpeer(int unit, char *localname)
253 eap_state *esp = &eap_states[unit];
255 /* Save the peer name we're given */
256 esp->es_client.ea_name = localname;
257 esp->es_client.ea_namelen = strlen(localname);
259 esp->es_client.ea_state = eapListen;
262 * Start a timer so that if the other end just goes
263 * silent, we don't sit here waiting forever.
265 if (esp->es_client.ea_timeout > 0)
266 TIMEOUT(eap_client_timeout, (void *)esp,
267 esp->es_client.ea_timeout);
271 * Format a standard EAP Failure message and send it to the peer.
275 eap_send_failure(eap_state *esp)
279 outp = outpacket_buf;
281 MAKEHEADER(outp, PPP_EAP);
283 PUTCHAR(EAP_FAILURE, outp);
284 esp->es_server.ea_id++;
285 PUTCHAR(esp->es_server.ea_id, outp);
286 PUTSHORT(EAP_HEADERLEN, outp);
288 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
290 esp->es_server.ea_state = eapBadAuth;
291 auth_peer_fail(esp->es_unit, PPP_EAP);
295 * Format a standard EAP Success message and send it to the peer.
299 eap_send_success(eap_state *esp)
303 outp = outpacket_buf;
305 MAKEHEADER(outp, PPP_EAP);
307 PUTCHAR(EAP_SUCCESS, outp);
308 esp->es_server.ea_id++;
309 PUTCHAR(esp->es_server.ea_id, outp);
310 PUTSHORT(EAP_HEADERLEN, outp);
312 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
314 auth_peer_success(esp->es_unit, PPP_EAP, 0,
315 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
320 * Set DES key according to pseudonym-generating secret and current
324 pncrypt_setkey(int timeoffs)
329 u_char dig[SHA_DIGESTSIZE];
332 if (pn_secret == NULL)
334 reftime = time(NULL) + timeoffs;
335 tp = localtime(&reftime);
337 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
338 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
339 SHA1Update(&ctxt, tbuf, strlen(tbuf));
340 SHA1Final(dig, &ctxt);
341 return (DesSetkey(dig));
344 static char base64[] =
345 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
353 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
358 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
361 if (bs->bs_offs >= 24) {
362 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
363 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
364 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
365 *outp++ = base64[bs->bs_bits & 0x3F];
375 b64flush(struct b64state *bs, u_char *outp)
379 if (bs->bs_offs == 8) {
380 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
381 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
383 } else if (bs->bs_offs == 16) {
384 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
385 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
386 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
395 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
401 if ((cp = strchr(base64, *inp++)) == NULL)
403 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
406 if (bs->bs_offs >= 8) {
407 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
417 * Assume that current waiting server state is complete and figure
418 * next state to use based on available authentication data. 'status'
419 * indicates if there was an error in handling the last query. It is
420 * 0 for success and non-zero for failure.
423 eap_figure_next_state(eap_state *esp, int status)
426 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
428 struct t_confent *tce, mytce;
431 int id, i, plen, toffs;
436 struct eaptls_session *ets;
438 char secret[MAXWORDLEN];
439 #endif /* USE_EAPTLS */
441 esp->es_server.ea_timeout = esp->es_savedtime;
443 esp->es_server.ea_prev_state = esp->es_server.ea_state;
444 #endif /* USE_EAPTLS */
445 switch (esp->es_server.ea_state) {
451 /* Discard any previous session. */
452 ts = (struct t_server *)esp->es_server.ea_session;
455 esp->es_server.ea_session = NULL;
456 esp->es_server.ea_skey = NULL;
460 esp->es_server.ea_state = eapBadAuth;
464 /* If we've got a pseudonym, try to decode to real name. */
465 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
466 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
467 SRP_PSEUDO_LEN) == 0 &&
468 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
470 BZERO(&bs, sizeof (bs));
472 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
473 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
476 for (i = 0; i < 5; i++) {
477 pncrypt_setkey(toffs);
479 if (!DesDecrypt(secbuf, clear)) {
480 dbglog("no DES here; cannot decode "
484 id = *(unsigned char *)clear;
485 if (id + 1 <= plen && id + 9 > plen)
488 if (plen % 8 == 0 && i < 5) {
490 * Note that this is always shorter than the
491 * original stored string, so there's no need
494 if ((i = plen = *(unsigned char *)clear) > 7)
496 esp->es_server.ea_peerlen = plen;
497 dp = (unsigned char *)esp->es_server.ea_peer;
498 BCOPY(clear + 1, dp, i);
503 (void) DesDecrypt(sp, dp);
508 esp->es_server.ea_peer[
509 esp->es_server.ea_peerlen] = '\0';
510 dbglog("decoded pseudonym to \"%.*q\"",
511 esp->es_server.ea_peerlen,
512 esp->es_server.ea_peer);
514 dbglog("failed to decode real name");
515 /* Stay in eapIdentfy state; requery */
519 /* Look up user in secrets database. */
520 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
521 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
522 /* Set up default in case SRP entry is bad */
523 esp->es_server.ea_state = eapMD5Chall;
524 /* Get t_confent based on index in srp-secrets */
525 id = strtol((char *)secbuf, &cp, 10);
526 if (*cp++ != ':' || id < 0)
530 mytce.modulus.data = (u_char *)wkmodulus;
531 mytce.modulus.len = sizeof (wkmodulus);
532 mytce.generator.data = (u_char *)"\002";
533 mytce.generator.len = 1;
535 } else if ((tce = gettcid(id)) != NULL) {
537 * Client will have to verify this modulus/
538 * generator combination, and that will take
539 * a while. Lengthen the timeout here.
541 if (esp->es_server.ea_timeout > 0 &&
542 esp->es_server.ea_timeout < 30)
543 esp->es_server.ea_timeout = 30;
547 if ((cp2 = strchr(cp, ':')) == NULL)
550 tpw.pebuf.name = esp->es_server.ea_peer;
551 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
553 tpw.pebuf.password.data = tpw.pwbuf;
554 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
556 tpw.pebuf.salt.data = tpw.saltbuf;
557 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
559 esp->es_server.ea_session = (void *)ts;
560 esp->es_server.ea_state = eapSRP1;
561 vals[0] = esp->es_server.ea_id + 1;
563 t_serveraddexdata(ts, vals, 2);
564 /* Generate B; must call before t_servergetkey() */
570 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
571 esp->es_server.ea_name, secret, &secret_len, 1)) {
573 esp->es_server.ea_state = eapTlsStart;
576 #endif /* USE_EAPTLS */
578 esp->es_server.ea_state = eapMD5Chall;
583 /* Initialize ssl session */
584 if(!eaptls_init_ssl_server(esp)) {
585 esp->es_server.ea_state = eapBadAuth;
589 esp->es_server.ea_state = eapTlsRecv;
593 ets = (struct eaptls_session *) esp->es_server.ea_session;
595 if(ets->alert_sent) {
596 esp->es_server.ea_state = eapTlsSendAlert;
601 esp->es_server.ea_state = eapBadAuth;
604 ets = (struct eaptls_session *) esp->es_server.ea_session;
607 esp->es_server.ea_state = eapTlsSendAck;
609 esp->es_server.ea_state = eapTlsSend;
613 ets = (struct eaptls_session *) esp->es_server.ea_session;
616 esp->es_server.ea_state = eapTlsRecvAck;
618 if(SSL_is_init_finished(ets->ssl))
619 esp->es_server.ea_state = eapTlsRecvClient;
621 /* JJK Add "TLS empty record" message here ??? */
622 esp->es_server.ea_state = eapTlsRecv;
626 esp->es_server.ea_state = eapTlsRecv;
632 esp->es_server.ea_state = eapBadAuth;
636 esp->es_server.ea_state = eapTlsSend;
639 case eapTlsSendAlert:
640 esp->es_server.ea_state = eapTlsRecvAlertAck;
642 #endif /* USE_EAPTLS */
646 ts = (struct t_server *)esp->es_server.ea_session;
647 if (ts != NULL && status != 0) {
649 esp->es_server.ea_session = NULL;
650 esp->es_server.ea_skey = NULL;
654 esp->es_server.ea_state = eapMD5Chall;
655 } else if (status != 0 || esp->es_server.ea_session == NULL) {
656 esp->es_server.ea_state = eapBadAuth;
658 esp->es_server.ea_state = eapSRP2;
664 ts = (struct t_server *)esp->es_server.ea_session;
665 if (ts != NULL && status != 0) {
667 esp->es_server.ea_session = NULL;
668 esp->es_server.ea_skey = NULL;
671 if (status != 0 || esp->es_server.ea_session == NULL) {
672 esp->es_server.ea_state = eapBadAuth;
674 esp->es_server.ea_state = eapSRP3;
681 ts = (struct t_server *)esp->es_server.ea_session;
682 if (ts != NULL && status != 0) {
684 esp->es_server.ea_session = NULL;
685 esp->es_server.ea_skey = NULL;
688 if (status != 0 || esp->es_server.ea_session == NULL) {
689 esp->es_server.ea_state = eapBadAuth;
691 esp->es_server.ea_state = eapOpen;
696 case eapMSCHAPv2Chall:
700 esp->es_server.ea_state = eapBadAuth;
702 esp->es_server.ea_state = eapOpen;
707 esp->es_server.ea_state = eapBadAuth;
710 if (esp->es_server.ea_state == eapBadAuth)
711 eap_send_failure(esp);
714 dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state));
715 #endif /* USE_EAPTLS */
720 * eap_chap_verify_response - check whether the peer's response matches
721 * what we think it should be. Returns 1 if it does (authentication
722 * succeeded), or 0 if it doesn't.
725 eap_chap_verify_response(char *name, char *ourname, int id,
726 struct chap_digest_type *digest,
727 unsigned char *challenge, unsigned char *response,
728 char *message, int message_space)
731 unsigned char secret[MAXSECRETLEN];
734 /* Get the secret that the peer is supposed to know */
735 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
736 error("No CHAP secret found for authenticating %q", name);
740 ok = digest->verify_response(id, name, secret, secret_len, challenge,
741 response, message, message_space);
742 memset(secret, 0, sizeof(secret));
748 * Format and send an CHAPV2-Success/Failure EAP Request message.
751 eap_chapms2_send_request(eap_state *esp, u_char id,
752 u_char opcode, u_char chapid,
753 char *message, int message_len)
758 outp = outpacket_buf;
760 MAKEHEADER(outp, PPP_EAP);
762 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
763 msglen += message_len;
765 PUTCHAR(EAP_REQUEST, outp);
767 PUTSHORT(msglen, outp);
768 PUTCHAR(EAPT_MSCHAPV2, outp);
769 PUTCHAR(opcode, outp);
770 PUTCHAR(chapid, outp);
772 PUTSHORT(msglen - 5, outp);
773 BCOPY(message, outp, message_len);
775 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
777 if (opcode == CHAP_SUCCESS) {
778 auth_peer_success(esp->es_unit, PPP_EAP, 0,
779 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
782 esp->es_server.ea_state = eapBadAuth;
783 auth_peer_fail(esp->es_unit, PPP_EAP);
789 * Format an EAP Request message and send it to the peer. Message
790 * type depends on current state. (Server operation)
793 eap_send_request(eap_state *esp)
803 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
809 /* Handle both initial auth and restart */
810 if (esp->es_server.ea_state < eapIdentify &&
811 esp->es_server.ea_state != eapInitial) {
812 esp->es_server.ea_state = eapIdentify;
813 if (explicit_remote) {
815 * If we already know the peer's
816 * unauthenticated name, then there's no
817 * reason to ask. Go to next state instead.
819 esp->es_server.ea_peer = remote_name;
820 esp->es_server.ea_peerlen = strlen(remote_name);
821 eap_figure_next_state(esp, 0);
825 if (esp->es_server.ea_maxrequests > 0 &&
826 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
827 if (esp->es_server.ea_responses > 0)
828 error("EAP: too many Requests sent");
830 error("EAP: no response to Requests");
831 eap_send_failure(esp);
835 outp = outpacket_buf;
837 MAKEHEADER(outp, PPP_EAP);
839 PUTCHAR(EAP_REQUEST, outp);
840 PUTCHAR(esp->es_server.ea_id, outp);
844 switch (esp->es_server.ea_state) {
846 PUTCHAR(EAPT_IDENTITY, outp);
848 challen = strlen(str);
849 BCOPY(str, outp, challen);
850 INCPTR(challen, outp);
854 PUTCHAR(EAPT_MD5CHAP, outp);
856 * pick a random challenge length between
857 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
859 challen = (drand48() *
860 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
861 MIN_CHALLENGE_LENGTH;
862 PUTCHAR(challen, outp);
863 esp->es_challen = challen;
864 ptr = esp->es_challenge;
865 while (--challen >= 0)
866 *ptr++ = (u_char) (drand48() * 0x100);
867 BCOPY(esp->es_challenge, outp, esp->es_challen);
868 INCPTR(esp->es_challen, outp);
869 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
870 INCPTR(esp->es_server.ea_namelen, outp);
874 case eapMSCHAPv2Chall:
875 esp->es_server.digest->generate_challenge(esp->es_challenge);
876 challen = esp->es_challenge[0];
877 esp->es_challen = challen;
879 PUTCHAR(EAPT_MSCHAPV2, outp);
880 PUTCHAR(CHAP_CHALLENGE, outp);
881 PUTCHAR(esp->es_server.ea_id, outp);
883 PUTSHORT(5 + challen +
884 esp->es_server.ea_namelen,
886 /* challen + challenge */
887 BCOPY(esp->es_challenge, outp, challen+1);
888 INCPTR(challen+1, outp);
889 BCOPY(esp->es_server.ea_name,
891 esp->es_server.ea_namelen);
892 INCPTR(esp->es_server.ea_namelen, outp);
898 PUTCHAR(EAPT_TLS, outp);
899 PUTCHAR(EAP_TLS_FLAGS_START, outp);
900 eap_figure_next_state(esp, 0);
904 eaptls_send(esp->es_server.ea_session, &outp);
905 eap_figure_next_state(esp, 0);
909 PUTCHAR(EAPT_TLS, outp);
911 eap_figure_next_state(esp, 0);
914 case eapTlsSendAlert:
915 eaptls_send(esp->es_server.ea_session, &outp);
916 eap_figure_next_state(esp, 0);
918 #endif /* USE_EAPTLS */
922 PUTCHAR(EAPT_SRP, outp);
923 PUTCHAR(EAPSRP_CHALLENGE, outp);
925 PUTCHAR(esp->es_server.ea_namelen, outp);
926 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
927 INCPTR(esp->es_server.ea_namelen, outp);
929 ts = (struct t_server *)esp->es_server.ea_session;
931 PUTCHAR(ts->s.len, outp);
932 BCOPY(ts->s.data, outp, ts->s.len);
933 INCPTR(ts->s.len, outp);
935 if (ts->g.len == 1 && ts->g.data[0] == 2) {
938 PUTCHAR(ts->g.len, outp);
939 BCOPY(ts->g.data, outp, ts->g.len);
940 INCPTR(ts->g.len, outp);
943 if (ts->n.len != sizeof (wkmodulus) ||
944 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
945 BCOPY(ts->n.data, outp, ts->n.len);
946 INCPTR(ts->n.len, outp);
951 PUTCHAR(EAPT_SRP, outp);
952 PUTCHAR(EAPSRP_SKEY, outp);
954 ts = (struct t_server *)esp->es_server.ea_session;
956 BCOPY(ts->B.data, outp, ts->B.len);
957 INCPTR(ts->B.len, outp);
961 PUTCHAR(EAPT_SRP, outp);
962 PUTCHAR(EAPSRP_SVALIDATOR, outp);
963 PUTLONG(SRPVAL_EBIT, outp);
964 ts = (struct t_server *)esp->es_server.ea_session;
966 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
967 INCPTR(SHA_DIGESTSIZE, outp);
969 if (pncrypt_setkey(0)) {
970 /* Generate pseudonym */
972 cp = (unsigned char *)esp->es_server.ea_peer;
973 if ((j = i = esp->es_server.ea_peerlen) > 7)
976 BCOPY(cp, clear + 1, j);
979 if (!DesEncrypt(clear, cipher)) {
980 dbglog("no DES here; not generating pseudonym");
983 BZERO(&b64, sizeof (b64));
984 outp++; /* space for pseudonym length */
985 outp += b64enc(&b64, cipher, 8, outp);
987 (void) DesEncrypt(cp, cipher);
988 outp += b64enc(&b64, cipher, 8, outp);
996 *cp++ = drand48() * 0x100;
999 (void) DesEncrypt(clear, cipher);
1000 outp += b64enc(&b64, cipher, 8, outp);
1002 outp += b64flush(&b64, outp);
1004 /* Set length and pad out to next 20 octet boundary */
1005 i = outp - optr - 1;
1007 i %= SHA_DIGESTSIZE;
1009 while (i < SHA_DIGESTSIZE) {
1010 *outp++ = drand48() * 0x100;
1015 /* Obscure the pseudonym with SHA1 hash */
1017 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1018 SHA1Update(&ctxt, esp->es_server.ea_skey,
1020 SHA1Update(&ctxt, esp->es_server.ea_peer,
1021 esp->es_server.ea_peerlen);
1022 while (optr < outp) {
1023 SHA1Final(dig, &ctxt);
1025 while (cp < dig + SHA_DIGESTSIZE)
1028 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1029 SHA1Update(&ctxt, esp->es_server.ea_skey,
1031 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1038 PUTCHAR(EAPT_SRP, outp);
1039 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1040 challen = MIN_CHALLENGE_LENGTH +
1041 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1042 esp->es_challen = challen;
1043 ptr = esp->es_challenge;
1044 while (--challen >= 0)
1045 *ptr++ = drand48() * 0x100;
1046 BCOPY(esp->es_challenge, outp, esp->es_challen);
1047 INCPTR(esp->es_challen, outp);
1049 #endif /* USE_SRP */
1055 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1056 PUTSHORT(outlen, lenloc);
1058 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1060 esp->es_server.ea_requests++;
1062 if (esp->es_server.ea_timeout > 0)
1063 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1067 * eap_authpeer - Authenticate our peer (behave as server).
1069 * Start server state and send first request. This is called only
1070 * after eap_lowerup.
1073 eap_authpeer(int unit, char *localname)
1075 eap_state *esp = &eap_states[unit];
1077 /* Save the name we're given. */
1078 esp->es_server.ea_name = localname;
1079 esp->es_server.ea_namelen = strlen(localname);
1081 esp->es_savedtime = esp->es_server.ea_timeout;
1083 /* Lower layer up yet? */
1084 if (esp->es_server.ea_state == eapInitial ||
1085 esp->es_server.ea_state == eapPending) {
1086 esp->es_server.ea_state = eapPending;
1090 esp->es_server.ea_state = eapPending;
1092 /* ID number not updated here intentionally; hashed into M1 */
1093 eap_send_request(esp);
1097 * eap_server_timeout - Retransmission timer for sending Requests
1101 eap_server_timeout(void *arg)
1107 #endif /* USE_EAPTLS */
1109 eap_state *esp = (eap_state *) arg;
1111 if (!eap_server_active(esp))
1115 switch(esp->es_server.ea_prev_state) {
1118 * In eap-tls the state changes after a request, so we return to
1119 * previous state ...
1122 case(eapTlsSendAck):
1123 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1127 * ... or resend the stored data
1130 case(eapTlsSendAlert):
1131 outp = outpacket_buf;
1132 MAKEHEADER(outp, PPP_EAP);
1133 PUTCHAR(EAP_REQUEST, outp);
1134 PUTCHAR(esp->es_server.ea_id, outp);
1138 eaptls_retransmit(esp->es_server.ea_session, &outp);
1140 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1141 PUTSHORT(outlen, lenloc);
1142 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1143 esp->es_server.ea_requests++;
1145 if (esp->es_server.ea_timeout > 0)
1146 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1152 #endif /* USE_EAPTLS */
1154 /* EAP ID number must not change on timeout. */
1155 eap_send_request(esp);
1159 * When it's time to send rechallenge the peer, this timeout is
1160 * called. Once the rechallenge is successful, the response handler
1161 * will restart the timer. If it fails, then the link is dropped.
1164 eap_rechallenge(void *arg)
1166 eap_state *esp = (eap_state *)arg;
1168 if (esp->es_server.ea_state != eapOpen &&
1169 esp->es_server.ea_state != eapSRP4)
1172 esp->es_server.ea_requests = 0;
1173 esp->es_server.ea_state = eapIdentify;
1174 eap_figure_next_state(esp, 0);
1175 esp->es_server.ea_id++;
1176 eap_send_request(esp);
1180 srp_lwrechallenge(void *arg)
1182 eap_state *esp = (eap_state *)arg;
1184 if (esp->es_server.ea_state != eapOpen ||
1185 esp->es_server.ea_type != EAPT_SRP)
1188 esp->es_server.ea_requests = 0;
1189 esp->es_server.ea_state = eapSRP4;
1190 esp->es_server.ea_id++;
1191 eap_send_request(esp);
1195 * eap_lowerup - The lower layer is now up.
1197 * This is called before either eap_authpeer or eap_authwithpeer. See
1198 * link_established() in auth.c. All that's necessary here is to
1199 * return to closed state so that those two routines will do the right
1203 eap_lowerup(int unit)
1205 eap_state *esp = &eap_states[unit];
1207 /* Discard any (possibly authenticated) peer name. */
1208 if (esp->es_server.ea_peer != NULL &&
1209 esp->es_server.ea_peer != remote_name)
1210 free(esp->es_server.ea_peer);
1211 esp->es_server.ea_peer = NULL;
1212 if (esp->es_client.ea_peer != NULL)
1213 free(esp->es_client.ea_peer);
1214 esp->es_client.ea_peer = NULL;
1216 esp->es_client.ea_state = eapClosed;
1217 esp->es_server.ea_state = eapClosed;
1221 * eap_lowerdown - The lower layer is now down.
1223 * Cancel all timeouts and return to initial state.
1226 eap_lowerdown(int unit)
1228 eap_state *esp = &eap_states[unit];
1230 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1231 UNTIMEOUT(eap_client_timeout, (void *)esp);
1233 if (eap_server_active(esp)) {
1234 if (esp->es_server.ea_timeout > 0) {
1235 UNTIMEOUT(eap_server_timeout, (void *)esp);
1238 if ((esp->es_server.ea_state == eapOpen ||
1239 esp->es_server.ea_state == eapSRP4) &&
1240 esp->es_rechallenge > 0) {
1241 UNTIMEOUT(eap_rechallenge, (void *)esp);
1243 if (esp->es_server.ea_state == eapOpen &&
1244 esp->es_lwrechallenge > 0) {
1245 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1249 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1250 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1254 * eap_protrej - Peer doesn't speak this protocol.
1256 * This shouldn't happen. If it does, it represents authentication
1260 eap_protrej(int unit)
1262 eap_state *esp = &eap_states[unit];
1264 if (eap_client_active(esp)) {
1265 error("EAP authentication failed due to Protocol-Reject");
1266 auth_withpeer_fail(unit, PPP_EAP);
1268 if (eap_server_active(esp)) {
1269 error("EAP authentication of peer failed on Protocol-Reject");
1270 auth_peer_fail(unit, PPP_EAP);
1272 eap_lowerdown(unit);
1276 * Format and send a regular EAP Response message.
1279 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1280 u_char *str, int lenstr)
1285 outp = outpacket_buf;
1287 MAKEHEADER(outp, PPP_EAP);
1289 PUTCHAR(EAP_RESPONSE, outp);
1291 esp->es_client.ea_id = id;
1292 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1293 PUTSHORT(msglen, outp);
1294 PUTCHAR(typenum, outp);
1296 BCOPY(str, outp, lenstr);
1299 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1303 * Format and send an MD5-Challenge EAP Response message.
1306 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1307 char *name, int namelen)
1312 outp = outpacket_buf;
1314 MAKEHEADER(outp, PPP_EAP);
1316 PUTCHAR(EAP_RESPONSE, outp);
1318 esp->es_client.ea_id = id;
1319 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1321 PUTSHORT(msglen, outp);
1322 PUTCHAR(EAPT_MD5CHAP, outp);
1323 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1324 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1325 INCPTR(MD5_SIGNATURE_SIZE, outp);
1327 BCOPY(name, outp, namelen);
1330 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1335 * Format and send a SRP EAP Response message.
1338 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1339 u_char *str, int lenstr)
1344 outp = outpacket_buf;
1346 MAKEHEADER(outp, PPP_EAP);
1348 PUTCHAR(EAP_RESPONSE, outp);
1350 esp->es_client.ea_id = id;
1351 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1352 PUTSHORT(msglen, outp);
1353 PUTCHAR(EAPT_SRP, outp);
1354 PUTCHAR(subtypenum, outp);
1356 BCOPY(str, outp, lenstr);
1359 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1363 * Format and send a SRP EAP Client Validator Response message.
1366 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1371 outp = outpacket_buf;
1373 MAKEHEADER(outp, PPP_EAP);
1375 PUTCHAR(EAP_RESPONSE, outp);
1377 esp->es_client.ea_id = id;
1378 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1380 PUTSHORT(msglen, outp);
1381 PUTCHAR(EAPT_SRP, outp);
1382 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1383 PUTLONG(flags, outp);
1384 BCOPY(str, outp, SHA_DIGESTSIZE);
1386 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1388 #endif /* USE_SRP */
1392 * Send an EAP-TLS response message with tls data
1395 eap_tls_response(eap_state *esp, u_char id)
1401 outp = outpacket_buf;
1403 MAKEHEADER(outp, PPP_EAP);
1405 PUTCHAR(EAP_RESPONSE, outp);
1412 If the id in the request is unchanged, we must retransmit
1415 if(id == esp->es_client.ea_id)
1416 eaptls_retransmit(esp->es_client.ea_session, &outp);
1418 eaptls_send(esp->es_client.ea_session, &outp);
1420 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1421 PUTSHORT(outlen, lenloc);
1423 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1425 esp->es_client.ea_id = id;
1429 * Send an EAP-TLS ack
1432 eap_tls_sendack(eap_state *esp, u_char id)
1438 outp = outpacket_buf;
1440 MAKEHEADER(outp, PPP_EAP);
1442 PUTCHAR(EAP_RESPONSE, outp);
1444 esp->es_client.ea_id = id;
1449 PUTCHAR(EAPT_TLS, outp);
1452 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1453 PUTSHORT(outlen, lenloc);
1455 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1457 #endif /* USE_EAPTLS */
1460 eap_send_nak(eap_state *esp, u_char id, u_char type)
1465 outp = outpacket_buf;
1467 MAKEHEADER(outp, PPP_EAP);
1469 PUTCHAR(EAP_RESPONSE, outp);
1471 esp->es_client.ea_id = id;
1472 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1473 PUTSHORT(msglen, outp);
1474 PUTCHAR(EAPT_NAK, outp);
1475 PUTCHAR(type, outp);
1477 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1482 name_of_pn_file(void)
1484 char *user, *path, *file;
1487 static bool pnlogged = 0;
1489 pw = getpwuid(getuid());
1490 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1494 file = _PATH_PSEUDONYM;
1495 pl = strlen(user) + strlen(file) + 2;
1499 (void) slprintf(path, pl, "%s/%s", user, file);
1501 dbglog("pseudonym file: %s", path);
1508 open_pn_file(mode_t modebits)
1513 if ((path = name_of_pn_file()) == NULL)
1515 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1523 remove_pn_file(void)
1527 if ((path = name_of_pn_file()) != NULL) {
1528 (void) unlink(path);
1534 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1537 u_char *datp, *digp;
1539 u_char dig[SHA_DIGESTSIZE];
1540 int dsize, fd, olen = len;
1543 * Do the decoding by working backwards. This eliminates the need
1544 * to save the decoded output in a separate buffer.
1548 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1549 dsize = SHA_DIGESTSIZE;
1553 SHA1Update(&ctxt, &val, 1);
1554 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1556 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1558 SHA1Update(&ctxt, esp->es_client.ea_name,
1559 esp->es_client.ea_namelen);
1561 SHA1Final(dig, &ctxt);
1562 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1566 /* Now check that the result is sane */
1567 if (olen <= 0 || *inp + 1 > olen) {
1568 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1573 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1575 dbglog("EAP: error saving pseudonym: %m");
1578 len = write(fd, inp + 1, *inp);
1579 if (close(fd) != -1 && len == *inp) {
1580 dbglog("EAP: saved pseudonym");
1581 esp->es_usedpseudo = 0;
1583 dbglog("EAP: failed to save pseudonym");
1587 #endif /* USE_SRP */
1591 * Format and send an CHAPV2-Challenge EAP Response message.
1594 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1599 outp = outpacket_buf;
1601 MAKEHEADER(outp, PPP_EAP);
1603 PUTCHAR(EAP_RESPONSE, outp);
1605 esp->es_client.ea_id = id;
1606 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1607 PUTSHORT(msglen, outp);
1608 PUTCHAR(EAPT_MSCHAPV2, outp);
1609 PUTCHAR(CHAP_RESPONSE, outp);
1610 PUTCHAR(chapid, outp);
1613 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1614 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1615 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1616 BCOPY(user, outp, user_len);
1618 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1623 * eap_request - Receive EAP Request message (client mode).
1626 eap_request(eap_state *esp, u_char *inp, int id, int len)
1631 char secret[MAXWORDLEN];
1632 char rhostname[256];
1634 u_char hash[MD5_SIGNATURE_SIZE];
1637 struct eaptls_session *ets = esp->es_client.ea_session;
1638 #endif /* USE_EAPTLS */
1641 struct t_client *tc;
1642 struct t_num sval, gval, Nval, *Ap, Bval;
1645 u_char dig[SHA_DIGESTSIZE];
1647 #endif /* USE_SRP */
1650 * Ignore requests if we're not open
1652 if (esp->es_client.ea_state <= eapClosed)
1656 * Note: we update es_client.ea_id *only if* a Response
1657 * message is being generated. Otherwise, we leave it the
1658 * same for duplicate detection purposes.
1661 esp->es_client.ea_requests++;
1662 if (esp->es_client.ea_maxrequests != 0 &&
1663 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1664 info("EAP: received too many Request messages");
1665 if (esp->es_client.ea_timeout > 0) {
1666 UNTIMEOUT(eap_client_timeout, (void *)esp);
1668 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1673 error("EAP: empty Request message discarded");
1677 GETCHAR(typenum, inp);
1683 info("EAP: Identity prompt \"%.*q\"", len, inp);
1685 if (esp->es_usepseudo &&
1686 (esp->es_usedpseudo == 0 ||
1687 (esp->es_usedpseudo == 1 &&
1688 id == esp->es_client.ea_id))) {
1689 esp->es_usedpseudo = 1;
1690 /* Try to get a pseudonym */
1691 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1692 strcpy(rhostname, SRP_PSEUDO_ID);
1693 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1694 sizeof (rhostname) - SRP_PSEUDO_LEN);
1695 /* XXX NAI unsupported */
1697 eap_send_response(esp, id, typenum,
1698 rhostname, len + SRP_PSEUDO_LEN);
1705 /* Stop using pseudonym now. */
1706 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1708 esp->es_usedpseudo = 2;
1710 #endif /* USE_SRP */
1711 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1712 esp->es_client.ea_namelen);
1715 case EAPT_NOTIFICATION:
1717 info("EAP: Notification \"%.*q\"", len, inp);
1718 eap_send_response(esp, id, typenum, NULL, 0);
1723 * Avoid the temptation to send Response Nak in reply
1724 * to Request Nak here. It can only lead to trouble.
1726 warn("EAP: unexpected Nak in Request; ignored");
1727 /* Return because we're waiting for something real. */
1732 error("EAP: received MD5-Challenge with no data");
1733 /* Bogus request; wait for something real. */
1736 GETCHAR(vallen, inp);
1738 if (vallen < 8 || vallen > len) {
1739 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1741 /* Try something better. */
1742 eap_send_nak(esp, id, EAPT_SRP);
1746 /* Not so likely to happen. */
1747 if (len - vallen >= sizeof (rhostname)) {
1748 dbglog("EAP: trimming really long peer name down");
1749 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1750 rhostname[sizeof (rhostname) - 1] = '\0';
1752 BCOPY(inp + vallen, rhostname, len - vallen);
1753 rhostname[len - vallen] = '\0';
1756 /* In case the remote doesn't give us his name. */
1757 if (explicit_remote ||
1758 (remote_name[0] != '\0' && vallen == len))
1759 strlcpy(rhostname, remote_name, sizeof (rhostname));
1762 * Get the secret for authenticating ourselves with
1763 * the specified host.
1765 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1766 rhostname, secret, &secret_len, 0)) {
1767 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1768 eap_send_nak(esp, id, EAPT_SRP);
1771 MD5_Init(&mdContext);
1773 MD5_Update(&mdContext, &typenum, 1);
1774 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1775 BZERO(secret, sizeof (secret));
1776 MD5_Update(&mdContext, inp, vallen);
1777 MD5_Final(hash, &mdContext);
1778 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1779 esp->es_client.ea_namelen);
1785 switch(esp->es_client.ea_state) {
1790 error("EAP: received EAP-TLS Listen packet with no data");
1791 /* Bogus request; wait for something real. */
1794 GETCHAR(flags, inp);
1795 if(flags & EAP_TLS_FLAGS_START){
1797 esp->es_client.ea_using_eaptls = 1;
1799 if (explicit_remote){
1800 esp->es_client.ea_peer = strdup(remote_name);
1801 esp->es_client.ea_peerlen = strlen(remote_name);
1803 esp->es_client.ea_peer = NULL;
1805 /* Init ssl session */
1806 if(!eaptls_init_ssl_client(esp)) {
1807 dbglog("cannot init ssl");
1808 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1809 esp->es_client.ea_using_eaptls = 0;
1813 ets = esp->es_client.ea_session;
1814 eap_tls_response(esp, id);
1815 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1819 /* The server has sent a bad start packet. */
1820 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1824 eap_tls_response(esp, id);
1825 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1830 error("EAP: discarding EAP-TLS Receive packet with no data");
1831 /* Bogus request; wait for something real. */
1834 eaptls_receive(ets, inp, len);
1837 eap_tls_sendack(esp, id);
1838 esp->es_client.ea_state = eapTlsRecv;
1842 if(ets->alert_recv) {
1843 eap_tls_sendack(esp, id);
1844 esp->es_client.ea_state = eapTlsRecvFailure;
1848 /* Check if TLS handshake is finished */
1849 if(eaptls_is_init_finished(ets)) {
1851 eaptls_gen_mppe_keys(ets, 1);
1853 eaptls_free_session(ets);
1854 eap_tls_sendack(esp, id);
1855 esp->es_client.ea_state = eapTlsRecvSuccess;
1859 eap_tls_response(esp,id);
1860 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1864 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1865 esp->es_client.ea_using_eaptls = 0;
1870 #endif /* USE_EAPTLS */
1875 error("EAP: received empty SRP Request");
1876 /* Bogus request; wait for something real. */
1881 GETCHAR(vallen, inp);
1884 case EAPSRP_CHALLENGE:
1886 if (esp->es_client.ea_session != NULL) {
1887 tc = (struct t_client *)esp->es_client.
1890 * If this is a new challenge, then start
1891 * over with a new client session context.
1892 * Otherwise, just resend last response.
1894 if (id != esp->es_client.ea_id) {
1896 esp->es_client.ea_session = NULL;
1900 /* No session key just yet */
1901 esp->es_client.ea_skey = NULL;
1903 GETCHAR(vallen, inp);
1905 if (vallen >= len) {
1906 error("EAP: badly-formed SRP Challenge"
1908 /* Ignore badly-formed messages */
1911 BCOPY(inp, rhostname, vallen);
1912 rhostname[vallen] = '\0';
1913 INCPTR(vallen, inp);
1917 * In case the remote doesn't give us his name,
1918 * use configured name.
1920 if (explicit_remote ||
1921 (remote_name[0] != '\0' && vallen == 0)) {
1922 strlcpy(rhostname, remote_name,
1923 sizeof (rhostname));
1926 if (esp->es_client.ea_peer != NULL)
1927 free(esp->es_client.ea_peer);
1928 esp->es_client.ea_peer = strdup(rhostname);
1929 esp->es_client.ea_peerlen = strlen(rhostname);
1931 GETCHAR(vallen, inp);
1933 if (vallen >= len) {
1934 error("EAP: badly-formed SRP Challenge"
1936 /* Ignore badly-formed messages */
1941 INCPTR(vallen, inp);
1944 GETCHAR(vallen, inp);
1947 error("EAP: badly-formed SRP Challenge"
1949 /* Ignore badly-formed messages */
1952 /* If no generator present, then use value 2 */
1954 gval.data = (u_char *)"\002";
1960 INCPTR(vallen, inp);
1964 * If no modulus present, then use well-known
1968 Nval.data = (u_char *)wkmodulus;
1969 Nval.len = sizeof (wkmodulus);
1974 tc = t_clientopen(esp->es_client.ea_name,
1975 &Nval, &gval, &sval);
1977 eap_send_nak(esp, id, EAPT_MD5CHAP);
1980 esp->es_client.ea_session = (void *)tc;
1982 /* Add Challenge ID & type to verifier */
1985 t_clientaddexdata(tc, vals, 2);
1987 Ap = t_clientgenexp(tc);
1988 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
1993 tc = (struct t_client *)esp->es_client.ea_session;
1995 warn("EAP: peer sent Subtype 2 without 1");
1996 eap_send_nak(esp, id, EAPT_MD5CHAP);
1999 if (esp->es_client.ea_skey != NULL) {
2001 * ID number should not change here. Warn
2002 * if it does (but otherwise ignore).
2004 if (id != esp->es_client.ea_id) {
2005 warn("EAP: ID changed from %d to %d "
2006 "in SRP Subtype 2 rexmit",
2007 esp->es_client.ea_id, id);
2010 if (get_srp_secret(esp->es_unit,
2011 esp->es_client.ea_name,
2012 esp->es_client.ea_peer, secret, 0) == 0) {
2014 * Can't work with this peer because
2015 * the secret is missing. Just give
2018 eap_send_nak(esp, id, EAPT_MD5CHAP);
2023 t_clientpasswd(tc, secret);
2024 BZERO(secret, sizeof (secret));
2025 esp->es_client.ea_skey =
2026 t_clientgetkey(tc, &Bval);
2027 if (esp->es_client.ea_skey == NULL) {
2028 /* Server is rogue; stop now */
2029 error("EAP: SRP server is rogue");
2030 goto client_failure;
2033 eap_srpval_response(esp, id, SRPVAL_EBIT,
2034 t_clientresponse(tc));
2037 case EAPSRP_SVALIDATOR:
2038 tc = (struct t_client *)esp->es_client.ea_session;
2039 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2040 warn("EAP: peer sent Subtype 3 without 1/2");
2041 eap_send_nak(esp, id, EAPT_MD5CHAP);
2045 * If we're already open, then this ought to be a
2046 * duplicate. Otherwise, check that the server is
2047 * who we think it is.
2049 if (esp->es_client.ea_state == eapOpen) {
2050 if (id != esp->es_client.ea_id) {
2051 warn("EAP: ID changed from %d to %d "
2052 "in SRP Subtype 3 rexmit",
2053 esp->es_client.ea_id, id);
2056 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2057 if (len < 0 || t_clientverify(tc, inp +
2058 sizeof (u_int32_t)) != 0) {
2059 error("EAP: SRP server verification "
2061 goto client_failure;
2063 GETLONG(esp->es_client.ea_keyflags, inp);
2064 /* Save pseudonym if user wants it. */
2065 if (len > 0 && esp->es_usepseudo) {
2066 INCPTR(SHA_DIGESTSIZE, inp);
2067 write_pseudonym(esp, inp, len, id);
2071 * We've verified our peer. We're now mostly done,
2072 * except for waiting on the regular EAP Success
2075 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2078 case EAPSRP_LWRECHALLENGE:
2080 warn("EAP: malformed Lightweight rechallenge");
2085 SHA1Update(&ctxt, vals, 1);
2086 SHA1Update(&ctxt, esp->es_client.ea_skey,
2088 SHA1Update(&ctxt, inp, len);
2089 SHA1Update(&ctxt, esp->es_client.ea_name,
2090 esp->es_client.ea_namelen);
2091 SHA1Final(dig, &ctxt);
2092 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2097 error("EAP: unknown SRP Subtype %d", vallen);
2098 eap_send_nak(esp, id, EAPT_MD5CHAP);
2102 #endif /* USE_SRP */
2107 error("EAP: received invalid MSCHAPv2 packet, too short");
2110 unsigned char opcode;
2111 GETCHAR(opcode, inp);
2112 unsigned char chapid; /* Chapv2-ID */
2113 GETCHAR(chapid, inp);
2115 GETSHORT(mssize, inp);
2117 /* Validate the mssize field */
2118 if (len != mssize) {
2119 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2124 /* If MSCHAPv2 digest was not found, NAK the packet */
2125 if (!esp->es_client.digest) {
2126 error("EAP MSCHAPv2 not supported");
2127 eap_send_nak(esp, id, EAPT_SRP);
2132 case CHAP_CHALLENGE: {
2134 /* make_response() expects: VLEN + VALUE */
2135 u_char *challenge = inp;
2137 unsigned char vsize;
2138 GETCHAR(vsize, inp);
2141 /* Validate the VALUE field */
2142 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2143 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2147 /* Increment past the VALUE field */
2148 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2149 len -= MS_CHAP2_PEER_CHAL_LEN;
2151 /* Extract the hostname */
2152 rhostname[0] = '\0';
2154 if (len >= sizeof (rhostname)) {
2155 dbglog("EAP: trimming really long peer name down");
2156 len = sizeof(rhostname) - 1;
2158 BCOPY(inp, rhostname, len);
2159 rhostname[len] = '\0';
2162 /* In case the remote doesn't give us his name. */
2163 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2164 strlcpy(rhostname, remote_name, sizeof(rhostname));
2166 /* Get the secret for authenticating ourselves with the specified host. */
2167 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2168 rhostname, secret, &secret_len, 0)) {
2169 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2170 eap_send_nak(esp, id, EAPT_SRP);
2174 /* Create the MSCHAPv2 response (and add to cache) */
2175 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2176 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2177 challenge, secret, secret_len, NULL);
2179 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2182 case CHAP_SUCCESS: {
2184 /* Check response for mutual authentication */
2185 u_char status = CHAP_FAILURE;
2186 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2187 info("Chap authentication succeeded! %.*v", len, inp);
2188 status = CHAP_SUCCESS;
2190 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2193 case CHAP_FAILURE: {
2195 /* Process the failure string, and log appropriate information */
2196 esp->es_client.digest->handle_failure(inp, len);
2198 u_char status = CHAP_FAILURE;
2199 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2200 goto client_failure; /* force termination */
2204 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2205 eap_send_nak(esp, id, EAPT_SRP);
2212 info("EAP: unknown authentication type %d; Naking", typenum);
2213 eap_send_nak(esp, id, EAPT_SRP);
2217 if (esp->es_client.ea_timeout > 0) {
2218 UNTIMEOUT(eap_client_timeout, (void *)esp);
2219 TIMEOUT(eap_client_timeout, (void *)esp,
2220 esp->es_client.ea_timeout);
2225 esp->es_client.ea_state = eapBadAuth;
2226 if (esp->es_client.ea_timeout > 0) {
2227 UNTIMEOUT(eap_client_timeout, (void *)esp);
2229 esp->es_client.ea_session = NULL;
2232 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2233 #endif /* USE_SRP */
2237 * eap_response - Receive EAP Response message (server mode).
2240 eap_response(eap_state *esp, u_char *inp, int id, int len)
2245 char secret[MAXSECRETLEN];
2246 char rhostname[256];
2248 u_char hash[MD5_SIGNATURE_SIZE];
2250 struct t_server *ts;
2253 u_char dig[SHA_DIGESTSIZE];
2255 u_char dig[SHA_DIGESTSIZE];
2256 #endif /* USE_SRP */
2259 struct eaptls_session *ets;
2261 #endif /* USE_EAPTLS */
2264 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2265 unsigned char *, unsigned char *, char *, int);
2266 char response_message[256];
2270 * Ignore responses if we're not open
2272 if (esp->es_server.ea_state <= eapClosed)
2275 if (esp->es_server.ea_id != id) {
2276 dbglog("EAP: discarding Response %d; expected ID %d", id,
2277 esp->es_server.ea_id);
2281 esp->es_server.ea_responses++;
2284 error("EAP: empty Response message discarded");
2288 GETCHAR(typenum, inp);
2293 if (esp->es_server.ea_state != eapIdentify) {
2294 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2298 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2299 if (esp->es_server.ea_peer != NULL &&
2300 esp->es_server.ea_peer != remote_name)
2301 free(esp->es_server.ea_peer);
2302 esp->es_server.ea_peer = malloc(len + 1);
2303 if (esp->es_server.ea_peer == NULL) {
2304 esp->es_server.ea_peerlen = 0;
2305 eap_figure_next_state(esp, 1);
2308 BCOPY(inp, esp->es_server.ea_peer, len);
2309 esp->es_server.ea_peer[len] = '\0';
2310 esp->es_server.ea_peerlen = len;
2311 eap_figure_next_state(esp, 0);
2316 switch(esp->es_server.ea_state) {
2320 ets = (struct eaptls_session *) esp->es_server.ea_session;
2322 eap_figure_next_state(esp,
2323 eaptls_receive(esp->es_server.ea_session, inp, len));
2325 if(ets->alert_recv) {
2326 eap_send_failure(esp);
2333 dbglog("EAP-TLS ACK with extra data");
2335 eap_figure_next_state(esp, 0);
2338 case eapTlsRecvClient:
2339 /* Receive authentication response from client */
2341 GETCHAR(flags, inp);
2343 if(len == 1 && !flags) { /* Ack = ok */
2345 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2347 eap_send_success(esp);
2349 else { /* failure */
2350 warn("Server authentication failed");
2351 eap_send_failure(esp);
2355 warn("Bogus EAP-TLS packet received from client");
2357 eaptls_free_session(esp->es_server.ea_session);
2361 case eapTlsRecvAlertAck:
2362 eap_send_failure(esp);
2366 eap_figure_next_state(esp, 1);
2370 #endif /* USE_EAPTLS */
2372 case EAPT_NOTIFICATION:
2373 dbglog("EAP unexpected Notification; response discarded");
2378 info("EAP: Nak Response with no suggested protocol");
2379 eap_figure_next_state(esp, 1);
2383 GETCHAR(vallen, inp);
2386 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2387 /* Peer cannot Nak Identify Request */
2388 eap_figure_next_state(esp, 1);
2394 /* Run through SRP validator selection again. */
2395 esp->es_server.ea_state = eapIdentify;
2396 eap_figure_next_state(esp, 0);
2400 esp->es_server.ea_state = eapMD5Chall;
2404 /* Send EAP-TLS start packet */
2406 esp->es_server.ea_state = eapTlsStart;
2408 #endif /* USE_EAPTLS */
2412 info("EAP: peer proposes MSCHAPv2");
2413 /* If MSCHAPv2 digest was not found, NAK the packet */
2414 if (!esp->es_server.digest) {
2415 error("EAP MSCHAPv2 not supported");
2416 eap_send_nak(esp, id, EAPT_SRP);
2419 esp->es_server.ea_state = eapMSCHAPv2Chall;
2424 dbglog("EAP: peer requesting unknown Type %d", vallen);
2425 switch (esp->es_server.ea_state) {
2429 esp->es_server.ea_state = eapMD5Chall;
2433 esp->es_server.ea_state = eapIdentify;
2434 eap_figure_next_state(esp, 0);
2444 if (esp->es_server.ea_state != eapMD5Chall) {
2445 error("EAP: unexpected MD5-Response");
2446 eap_figure_next_state(esp, 1);
2450 error("EAP: received MD5-Response with no data");
2451 eap_figure_next_state(esp, 1);
2454 GETCHAR(vallen, inp);
2456 if (vallen != 16 || vallen > len) {
2457 error("EAP: MD5-Response with bad length %d", vallen);
2458 eap_figure_next_state(esp, 1);
2462 /* Not so likely to happen. */
2463 if (len - vallen >= sizeof (rhostname)) {
2464 dbglog("EAP: trimming really long peer name down");
2465 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2466 rhostname[sizeof (rhostname) - 1] = '\0';
2468 BCOPY(inp + vallen, rhostname, len - vallen);
2469 rhostname[len - vallen] = '\0';
2472 /* In case the remote doesn't give us his name. */
2473 if (explicit_remote ||
2474 (remote_name[0] != '\0' && vallen == len))
2475 strlcpy(rhostname, remote_name, sizeof (rhostname));
2478 * Get the secret for authenticating the specified
2481 if (!get_secret(esp->es_unit, rhostname,
2482 esp->es_server.ea_name, secret, &secret_len, 1)) {
2483 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2484 eap_send_failure(esp);
2487 MD5_Init(&mdContext);
2488 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2489 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2490 BZERO(secret, sizeof (secret));
2491 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2492 MD5_Final(hash, &mdContext);
2493 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2494 eap_send_failure(esp);
2497 esp->es_server.ea_type = EAPT_MD5CHAP;
2498 eap_send_success(esp);
2499 eap_figure_next_state(esp, 0);
2500 if (esp->es_rechallenge != 0)
2501 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2507 error("EAP: received MSCHAPv2 with no data");
2508 eap_figure_next_state(esp, 1);
2511 GETCHAR(opcode, inp);
2516 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2517 error("EAP: unexpected MSCHAPv2-Response");
2518 eap_figure_next_state(esp, 1);
2521 /* skip MS ID + len */
2523 GETCHAR(vallen, inp);
2526 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2527 error("EAP: Invalid MSCHAPv2-Response "
2528 "length %d", vallen);
2529 eap_figure_next_state(esp, 1);
2533 /* Not so likely to happen. */
2534 if (len - vallen >= sizeof (rhostname)) {
2535 dbglog("EAP: trimming really long peer name down");
2536 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2537 rhostname[sizeof (rhostname) - 1] = '\0';
2539 BCOPY(inp + vallen, rhostname, len - vallen);
2540 rhostname[len - vallen] = '\0';
2543 /* In case the remote doesn't give us his name. */
2544 if (explicit_remote ||
2545 (remote_name[0] != '\0' && vallen == len))
2546 strlcpy(rhostname, remote_name, sizeof (rhostname));
2548 if (chap_verify_hook)
2549 chap_verifier = chap_verify_hook;
2551 chap_verifier = eap_chap_verify_response;
2553 esp->es_server.ea_id += 1;
2554 if ((*chap_verifier)(rhostname,
2555 esp->es_server.ea_name,
2557 esp->es_server.digest,
2561 sizeof(response_message)))
2563 info("EAP: MSCHAPv2 success for peer %q",
2565 esp->es_server.ea_type = EAPT_MSCHAPV2;
2566 eap_chapms2_send_request(esp,
2567 esp->es_server.ea_id,
2569 esp->es_server.ea_id,
2571 strlen(response_message));
2572 eap_figure_next_state(esp, 0);
2573 if (esp->es_rechallenge != 0)
2574 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2577 warn("EAP: MSCHAPv2 failure for peer %q",
2579 eap_chapms2_send_request(esp,
2580 esp->es_server.ea_id,
2582 esp->es_server.ea_id,
2584 strlen(response_message));
2588 info("EAP: MSCHAPv2 success confirmed");
2591 info("EAP: MSCHAPv2 failure confirmed");
2594 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2595 eap_send_nak(esp, id, EAPT_SRP);
2604 error("EAP: empty SRP Response");
2605 eap_figure_next_state(esp, 1);
2608 GETCHAR(typenum, inp);
2612 if (esp->es_server.ea_state != eapSRP1) {
2613 error("EAP: unexpected SRP Subtype 1 Response");
2614 eap_figure_next_state(esp, 1);
2619 ts = (struct t_server *)esp->es_server.ea_session;
2621 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2622 if (esp->es_server.ea_skey == NULL) {
2623 /* Client's A value is bogus; terminate now */
2624 error("EAP: bogus A value from client");
2625 eap_send_failure(esp);
2627 eap_figure_next_state(esp, 0);
2631 case EAPSRP_CVALIDATOR:
2632 if (esp->es_server.ea_state != eapSRP2) {
2633 error("EAP: unexpected SRP Subtype 2 Response");
2634 eap_figure_next_state(esp, 1);
2637 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2638 error("EAP: M1 length %d < %d", len,
2639 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2640 eap_figure_next_state(esp, 1);
2643 GETLONG(esp->es_server.ea_keyflags, inp);
2644 ts = (struct t_server *)esp->es_server.ea_session;
2646 if (t_serververify(ts, inp)) {
2647 info("EAP: unable to validate client identity");
2648 eap_send_failure(esp);
2651 eap_figure_next_state(esp, 0);
2655 if (esp->es_server.ea_state != eapSRP3) {
2656 error("EAP: unexpected SRP Subtype 3 Response");
2657 eap_send_failure(esp);
2660 esp->es_server.ea_type = EAPT_SRP;
2661 eap_send_success(esp);
2662 eap_figure_next_state(esp, 0);
2663 if (esp->es_rechallenge != 0)
2664 TIMEOUT(eap_rechallenge, esp,
2665 esp->es_rechallenge);
2666 if (esp->es_lwrechallenge != 0)
2667 TIMEOUT(srp_lwrechallenge, esp,
2668 esp->es_lwrechallenge);
2671 case EAPSRP_LWRECHALLENGE:
2672 if (esp->es_server.ea_state != eapSRP4) {
2673 info("EAP: unexpected SRP Subtype 4 Response");
2676 if (len != SHA_DIGESTSIZE) {
2677 error("EAP: bad Lightweight rechallenge "
2683 SHA1Update(&ctxt, &vallen, 1);
2684 SHA1Update(&ctxt, esp->es_server.ea_skey,
2686 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2687 SHA1Update(&ctxt, esp->es_server.ea_peer,
2688 esp->es_server.ea_peerlen);
2689 SHA1Final(dig, &ctxt);
2690 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2691 error("EAP: failed Lightweight rechallenge");
2692 eap_send_failure(esp);
2695 esp->es_server.ea_state = eapOpen;
2696 if (esp->es_lwrechallenge != 0)
2697 TIMEOUT(srp_lwrechallenge, esp,
2698 esp->es_lwrechallenge);
2702 #endif /* USE_SRP */
2705 /* This can't happen. */
2706 error("EAP: unknown Response type %d; ignored", typenum);
2710 if (esp->es_server.ea_timeout > 0) {
2711 UNTIMEOUT(eap_server_timeout, (void *)esp);
2714 if (esp->es_server.ea_state != eapBadAuth &&
2715 esp->es_server.ea_state != eapOpen) {
2716 esp->es_server.ea_id++;
2717 eap_send_request(esp);
2722 * eap_success - Receive EAP Success message (client mode).
2725 eap_success(eap_state *esp, u_char *inp, int id, int len)
2727 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2729 && esp->es_client.ea_state != eapTlsRecvSuccess
2730 #endif /* USE_EAPTLS */
2732 dbglog("EAP unexpected success message in state %s (%d)",
2733 eap_state_name(esp->es_client.ea_state),
2734 esp->es_client.ea_state);
2739 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2740 eapTlsRecvSuccess) {
2741 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2742 eap_state_name(esp->es_client.ea_state),
2743 esp->es_client.ea_state);
2746 #endif /* USE_EAPTLS */
2748 if (esp->es_client.ea_timeout > 0) {
2749 UNTIMEOUT(eap_client_timeout, (void *)esp);
2753 /* This is odd. The spec doesn't allow for this. */
2757 esp->es_client.ea_state = eapOpen;
2758 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2762 * eap_failure - Receive EAP Failure message (client mode).
2765 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2768 * Ignore failure messages if we're not open
2770 if (esp->es_client.ea_state <= eapClosed)
2773 if (!eap_client_active(esp)) {
2774 dbglog("EAP unexpected failure message in state %s (%d)",
2775 eap_state_name(esp->es_client.ea_state),
2776 esp->es_client.ea_state);
2779 if (esp->es_client.ea_timeout > 0) {
2780 UNTIMEOUT(eap_client_timeout, (void *)esp);
2784 /* This is odd. The spec doesn't allow for this. */
2788 esp->es_client.ea_state = eapBadAuth;
2790 error("EAP: peer reports authentication failure");
2791 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2795 * eap_input - Handle received EAP message.
2798 eap_input(int unit, u_char *inp, int inlen)
2800 eap_state *esp = &eap_states[unit];
2805 * Parse header (code, id and length). If packet too short,
2808 if (inlen < EAP_HEADERLEN) {
2809 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2815 if (len < EAP_HEADERLEN || len > inlen) {
2816 error("EAP: packet has illegal length field %d (%d..%d)", len,
2817 EAP_HEADERLEN, inlen);
2820 len -= EAP_HEADERLEN;
2822 /* Dispatch based on message code */
2825 eap_request(esp, inp, id, len);
2829 eap_response(esp, inp, id, len);
2833 eap_success(esp, inp, id, len);
2837 eap_failure(esp, inp, id, len);
2840 default: /* XXX Need code reject */
2841 /* Note: it's not legal to send EAP Nak here. */
2842 warn("EAP: unknown code %d received", code);
2848 * eap_printpkt - print the contents of an EAP packet.
2850 static char *eap_codenames[] = {
2851 "Request", "Response", "Success", "Failure"
2854 static char *eap_typenames[] = {
2855 "Identity", "Notification", "Nak", "MD5-Challenge",
2856 "OTP", "Generic-Token", NULL, NULL,
2857 "RSA", "DSS", "KEA", "KEA-Validate",
2858 "TLS", "Defender", "Windows 2000", "Arcot",
2859 "Cisco", "Nokia", "SRP", NULL,
2860 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2865 eap_printpkt(u_char *inp, int inlen,
2866 void (*printer) (void *, char *, ...), void *arg)
2868 int code, id, len, rtype, vallen;
2873 #endif /* USE_EAPTLS */
2878 if (inlen < EAP_HEADERLEN)
2884 if (len < EAP_HEADERLEN || len > inlen)
2887 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2888 printer(arg, " %s", eap_codenames[code-1]);
2890 printer(arg, " code=0x%x", code);
2891 printer(arg, " id=0x%x", id);
2892 len -= EAP_HEADERLEN;
2896 printer(arg, " <missing type>");
2899 GETCHAR(rtype, inp);
2902 rtype <= sizeof (eap_typenames) / sizeof (char *))
2903 printer(arg, " %s", eap_typenames[rtype-1]);
2905 printer(arg, " type=0x%x", rtype);
2908 case EAPT_NOTIFICATION:
2910 printer(arg, " <Message ");
2911 print_string((char *)inp, len, printer, arg);
2916 printer(arg, " <No message>");
2923 GETCHAR(vallen, inp);
2927 printer(arg, " <Value%.*B>", vallen, inp);
2928 INCPTR(vallen, inp);
2931 printer(arg, " <Name ");
2932 print_string((char *)inp, len, printer, arg);
2937 printer(arg, " <No name>");
2945 GETCHAR(opcode, inp);
2948 case CHAP_CHALLENGE:
2951 GETCHAR(vallen, inp);
2956 printer(arg, " Challenge <");
2957 for (; vallen > 0; --vallen) {
2960 printer(arg, "%.2x", val);
2964 printer(arg, ", <Name ");
2965 print_string((char *)inp, len, printer, arg);
2970 printer(arg, ", <No name>");
2976 printer(arg, " Success <Message ");
2977 print_string((char *)inp, len, printer, arg);
2983 printer(arg, " Failure <Message ");
2984 print_string((char *)inp, len, printer, arg);
2990 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3000 GETCHAR(flags, inp);
3003 if(flags == 0 && len == 0){
3004 printer(arg, " Ack");
3008 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3009 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3010 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3012 #endif /* USE_EAPTLS */
3017 GETCHAR(vallen, inp);
3019 printer(arg, "-%d", vallen);
3021 case EAPSRP_CHALLENGE:
3022 GETCHAR(vallen, inp);
3027 printer(arg, " <Name ");
3028 print_string((char *)inp, vallen, printer,
3032 printer(arg, " <No name>");
3034 INCPTR(vallen, inp);
3036 GETCHAR(vallen, inp);
3040 printer(arg, " <s%.*B>", vallen, inp);
3041 INCPTR(vallen, inp);
3043 GETCHAR(vallen, inp);
3048 printer(arg, " <Default g=2>");
3050 printer(arg, " <g%.*B>", vallen, inp);
3052 INCPTR(vallen, inp);
3055 printer(arg, " <Default N>");
3057 printer(arg, " <N%.*B>", len, inp);
3064 printer(arg, " <B%.*B>", len, inp);
3069 case EAPSRP_SVALIDATOR:
3070 if (len < sizeof (u_int32_t))
3073 len -= sizeof (u_int32_t);
3074 if (uval & SRPVAL_EBIT) {
3076 uval &= ~SRPVAL_EBIT;
3079 printer(arg, " f<%X>", uval);
3081 if ((vallen = len) > SHA_DIGESTSIZE)
3082 vallen = SHA_DIGESTSIZE;
3083 printer(arg, " <M2%.*B%s>", len, inp,
3084 len < SHA_DIGESTSIZE ? "?" : "");
3085 INCPTR(vallen, inp);
3088 printer(arg, " <PN%.*B>", len, inp);
3094 case EAPSRP_LWRECHALLENGE:
3095 printer(arg, " <Challenge%.*B>", len, inp);
3107 GETCHAR(rtype, inp);
3110 rtype <= sizeof (eap_typenames) / sizeof (char *))
3111 printer(arg, " %s", eap_typenames[rtype-1]);
3113 printer(arg, " type=0x%x", rtype);
3117 printer(arg, " <Name ");
3118 print_string((char *)inp, len, printer, arg);
3129 GETCHAR(flags, inp);
3132 if(flags == 0 && len == 0){
3133 printer(arg, " Ack");
3137 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3138 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3139 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3142 #endif /* USE_EAPTLS */
3146 printer(arg, " <missing hint>");
3149 GETCHAR(rtype, inp);
3151 printer(arg, " <Suggested-type %02X", rtype);
3153 rtype <= sizeof (eap_typenames) / sizeof (char *))
3154 printer(arg, " (%s)", eap_typenames[rtype-1]);
3160 printer(arg, " <missing length>");
3163 GETCHAR(vallen, inp);
3167 printer(arg, " <Value%.*B>", vallen, inp);
3168 INCPTR(vallen, inp);
3171 printer(arg, " <Name ");
3172 print_string((char *)inp, len, printer, arg);
3177 printer(arg, " <No name>");
3185 GETCHAR(opcode, inp);
3191 GETCHAR(vallen, inp);
3196 printer(arg, " Response <");
3197 for (; vallen > 0; --vallen) {
3200 printer(arg, "%.2x", val);
3204 printer(arg, ", <Name ");
3205 print_string((char *)inp, len, printer, arg);
3210 printer(arg, ", <No name>");
3214 printer(arg, " Success");
3217 printer(arg, " Failure");
3220 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3229 GETCHAR(vallen, inp);
3231 printer(arg, "-%d", vallen);
3234 printer(arg, " <A%.*B>", len, inp);
3239 case EAPSRP_CVALIDATOR:
3240 if (len < sizeof (u_int32_t))
3243 len -= sizeof (u_int32_t);
3244 if (uval & SRPVAL_EBIT) {
3246 uval &= ~SRPVAL_EBIT;
3249 printer(arg, " f<%X>", uval);
3251 printer(arg, " <M1%.*B%s>", len, inp,
3252 len == SHA_DIGESTSIZE ? "" : "?");
3260 case EAPSRP_LWRECHALLENGE:
3261 printer(arg, " <Response%.*B%s>", len, inp,
3262 len == SHA_DIGESTSIZE ? "" : "?");
3263 if ((vallen = len) > SHA_DIGESTSIZE)
3264 vallen = SHA_DIGESTSIZE;
3265 INCPTR(vallen, inp);
3273 case EAP_SUCCESS: /* No payload expected for these! */
3278 printer(arg, " <truncated>");
3283 printer(arg, "%8B...", inp);
3285 printer(arg, "%.*B", len, inp);
3288 return (inp - pstart);