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
88 #ifdef PPP_WITH_EAPTLS
90 #endif /* PPP_WITH_EAPTLS */
92 #ifdef PPP_WITH_CHAPMS
96 extern int chapms_strip_domain;
97 #endif /* PPP_WITH_CHAPMS */
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;
230 #ifdef PPP_WITH_EAPTLS
231 esp->es_client.ea_using_eaptls = 0;
232 #endif /* PPP_WITH_EAPTLS */
233 #ifdef PPP_WITH_CHAPMS
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;
447 #ifdef PPP_WITH_EAPTLS
448 struct eaptls_session *ets;
450 char secret[MAXWORDLEN];
451 #endif /* PPP_WITH_EAPTLS */
453 esp->es_server.ea_timeout = esp->es_savedtime;
454 #ifdef PPP_WITH_EAPTLS
455 esp->es_server.ea_prev_state = esp->es_server.ea_state;
456 #endif /* PPP_WITH_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() */
581 #ifdef PPP_WITH_EAPTLS
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 /* PPP_WITH_EAPTLS */
590 esp->es_server.ea_state = eapMD5Chall;
593 #ifdef PPP_WITH_EAPTLS
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 /* PPP_WITH_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;
707 #ifdef PPP_WITH_CHAPMS
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);
725 #ifdef PPP_WITH_EAPTLS
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 /* PPP_WITH_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);
798 #endif /* PPP_WITH_CHAPMS */
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);
885 #ifdef PPP_WITH_CHAPMS
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);
906 #endif /* PPP_WITH_CHAPMS */
908 #ifdef PPP_WITH_EAPTLS
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 /* PPP_WITH_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)
1115 #ifdef PPP_WITH_EAPTLS
1119 #endif /* PPP_WITH_EAPTLS */
1121 eap_state *esp = (eap_state *) arg;
1123 if (!eap_server_active(esp))
1126 #ifdef PPP_WITH_EAPTLS
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 /* PPP_WITH_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 */
1402 #ifdef PPP_WITH_EAPTLS
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 /* PPP_WITH_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];
1647 #ifdef PPP_WITH_EAPTLS
1649 struct eaptls_session *ets = esp->es_client.ea_session;
1650 #endif /* PPP_WITH_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);
1794 #ifdef PPP_WITH_EAPTLS
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)) {
1862 #ifdef PPP_WITH_MPPE
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 /* PPP_WITH_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 */
2116 #ifdef PPP_WITH_CHAPMS
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);
2185 esp->es_client.ea_namelen = strlen(esp->es_client.ea_name);
2187 /* Create the MSCHAPv2 response (and add to cache) */
2188 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2189 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2190 challenge, secret, secret_len, NULL);
2192 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2195 case CHAP_SUCCESS: {
2197 /* Check response for mutual authentication */
2198 u_char status = CHAP_FAILURE;
2199 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2200 info("Chap authentication succeeded! %.*v", len, inp);
2201 status = CHAP_SUCCESS;
2203 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2206 case CHAP_FAILURE: {
2208 /* Process the failure string, and log appropriate information */
2209 esp->es_client.digest->handle_failure(inp, len);
2211 u_char status = CHAP_FAILURE;
2212 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2213 goto client_failure; /* force termination */
2217 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2218 eap_send_nak(esp, id, EAPT_SRP);
2222 #endif /* PPP_WITH_CHAPMS */
2226 /* Initialize the PEAP context (if not already initialized) */
2227 if (!esp->ea_peap) {
2228 rhostname[0] = '\0';
2229 if (explicit_remote || (remote_name[0] != '\0')) {
2230 strlcpy(rhostname, remote_name, sizeof (rhostname));
2232 if (peap_init(&esp->ea_peap, rhostname)) {
2233 eap_send_nak(esp, id, EAPT_TLS);
2238 /* Process the PEAP packet */
2239 if (peap_process(esp, id, inp, len)) {
2240 eap_send_nak(esp, id, EAPT_TLS);
2247 info("EAP: unknown authentication type %d; Naking", typenum);
2248 eap_send_nak(esp, id, EAPT_SRP);
2252 if (esp->es_client.ea_timeout > 0) {
2253 UNTIMEOUT(eap_client_timeout, (void *)esp);
2254 TIMEOUT(eap_client_timeout, (void *)esp,
2255 esp->es_client.ea_timeout);
2260 esp->es_client.ea_state = eapBadAuth;
2261 if (esp->es_client.ea_timeout > 0) {
2262 UNTIMEOUT(eap_client_timeout, (void *)esp);
2264 esp->es_client.ea_session = NULL;
2267 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2268 #endif /* USE_SRP */
2272 * eap_response - Receive EAP Response message (server mode).
2275 eap_response(eap_state *esp, u_char *inp, int id, int len)
2280 char secret[MAXSECRETLEN];
2281 char rhostname[256];
2283 u_char hash[MD5_SIGNATURE_SIZE];
2285 struct t_server *ts;
2288 u_char dig[SHA_DIGESTSIZE];
2289 #endif /* USE_SRP */
2291 #ifdef PPP_WITH_EAPTLS
2292 struct eaptls_session *ets;
2294 #endif /* PPP_WITH_EAPTLS */
2295 #ifdef PPP_WITH_CHAPMS
2297 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2298 unsigned char *, unsigned char *, char *, int);
2299 char response_message[256];
2300 #endif /* PPP_WITH_CHAPMS */
2303 * Ignore responses if we're not open
2305 if (esp->es_server.ea_state <= eapClosed)
2308 if (esp->es_server.ea_id != id) {
2309 dbglog("EAP: discarding Response %d; expected ID %d", id,
2310 esp->es_server.ea_id);
2314 esp->es_server.ea_responses++;
2317 error("EAP: empty Response message discarded");
2321 GETCHAR(typenum, inp);
2326 if (esp->es_server.ea_state != eapIdentify) {
2327 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2331 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2332 if (esp->es_server.ea_peer != NULL &&
2333 esp->es_server.ea_peer != remote_name)
2334 free(esp->es_server.ea_peer);
2335 esp->es_server.ea_peer = malloc(len + 1);
2336 if (esp->es_server.ea_peer == NULL) {
2337 esp->es_server.ea_peerlen = 0;
2338 eap_figure_next_state(esp, 1);
2341 BCOPY(inp, esp->es_server.ea_peer, len);
2342 esp->es_server.ea_peer[len] = '\0';
2343 esp->es_server.ea_peerlen = len;
2344 eap_figure_next_state(esp, 0);
2347 #ifdef PPP_WITH_EAPTLS
2349 switch(esp->es_server.ea_state) {
2353 ets = (struct eaptls_session *) esp->es_server.ea_session;
2355 eap_figure_next_state(esp,
2356 eaptls_receive(esp->es_server.ea_session, inp, len));
2358 if(ets->alert_recv) {
2359 eap_send_failure(esp);
2366 dbglog("EAP-TLS ACK with extra data");
2368 eap_figure_next_state(esp, 0);
2371 case eapTlsRecvClient:
2372 /* Receive authentication response from client */
2374 GETCHAR(flags, inp);
2376 if(len == 1 && !flags) { /* Ack = ok */
2377 #ifdef PPP_WITH_MPPE
2378 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2380 eap_send_success(esp);
2382 else { /* failure */
2383 warn("Server authentication failed");
2384 eap_send_failure(esp);
2388 warn("Bogus EAP-TLS packet received from client");
2390 eaptls_free_session(esp->es_server.ea_session);
2394 case eapTlsRecvAlertAck:
2395 eap_send_failure(esp);
2399 eap_figure_next_state(esp, 1);
2403 #endif /* PPP_WITH_EAPTLS */
2405 case EAPT_NOTIFICATION:
2406 dbglog("EAP unexpected Notification; response discarded");
2411 info("EAP: Nak Response with no suggested protocol");
2412 eap_figure_next_state(esp, 1);
2416 GETCHAR(vallen, inp);
2419 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2420 /* Peer cannot Nak Identify Request */
2421 eap_figure_next_state(esp, 1);
2427 /* Run through SRP validator selection again. */
2428 esp->es_server.ea_state = eapIdentify;
2429 eap_figure_next_state(esp, 0);
2433 esp->es_server.ea_state = eapMD5Chall;
2436 #ifdef PPP_WITH_EAPTLS
2437 /* Send EAP-TLS start packet */
2439 esp->es_server.ea_state = eapTlsStart;
2441 #endif /* PPP_WITH_EAPTLS */
2443 #ifdef PPP_WITH_CHAPMS
2445 info("EAP: peer proposes MSCHAPv2");
2446 /* If MSCHAPv2 digest was not found, NAK the packet */
2447 if (!esp->es_server.digest) {
2448 error("EAP MSCHAPv2 not supported");
2449 eap_send_nak(esp, id, EAPT_SRP);
2452 esp->es_server.ea_state = eapMSCHAPv2Chall;
2454 #endif /* PPP_WITH_CHAPMS */
2457 dbglog("EAP: peer requesting unknown Type %d", vallen);
2458 switch (esp->es_server.ea_state) {
2462 esp->es_server.ea_state = eapMD5Chall;
2466 esp->es_server.ea_state = eapIdentify;
2467 eap_figure_next_state(esp, 0);
2477 if (esp->es_server.ea_state != eapMD5Chall) {
2478 error("EAP: unexpected MD5-Response");
2479 eap_figure_next_state(esp, 1);
2483 error("EAP: received MD5-Response with no data");
2484 eap_figure_next_state(esp, 1);
2487 GETCHAR(vallen, inp);
2489 if (vallen != 16 || vallen > len) {
2490 error("EAP: MD5-Response with bad length %d", vallen);
2491 eap_figure_next_state(esp, 1);
2495 /* Not so likely to happen. */
2496 if (len - vallen >= sizeof (rhostname)) {
2497 dbglog("EAP: trimming really long peer name down");
2498 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2499 rhostname[sizeof (rhostname) - 1] = '\0';
2501 BCOPY(inp + vallen, rhostname, len - vallen);
2502 rhostname[len - vallen] = '\0';
2505 /* In case the remote doesn't give us his name. */
2506 if (explicit_remote ||
2507 (remote_name[0] != '\0' && vallen == len))
2508 strlcpy(rhostname, remote_name, sizeof (rhostname));
2511 * Get the secret for authenticating the specified
2514 if (!get_secret(esp->es_unit, rhostname,
2515 esp->es_server.ea_name, secret, &secret_len, 1)) {
2516 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2517 eap_send_failure(esp);
2520 MD5_Init(&mdContext);
2521 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2522 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2523 BZERO(secret, sizeof (secret));
2524 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2525 MD5_Final(hash, &mdContext);
2526 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2527 eap_send_failure(esp);
2530 esp->es_server.ea_type = EAPT_MD5CHAP;
2531 eap_send_success(esp);
2532 eap_figure_next_state(esp, 0);
2533 if (esp->es_rechallenge != 0)
2534 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2537 #ifdef PPP_WITH_CHAPMS
2540 error("EAP: received MSCHAPv2 with no data");
2541 eap_figure_next_state(esp, 1);
2544 GETCHAR(opcode, inp);
2549 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2550 error("EAP: unexpected MSCHAPv2-Response");
2551 eap_figure_next_state(esp, 1);
2554 /* skip MS ID + len */
2556 GETCHAR(vallen, inp);
2559 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2560 error("EAP: Invalid MSCHAPv2-Response "
2561 "length %d", vallen);
2562 eap_figure_next_state(esp, 1);
2566 /* Not so likely to happen. */
2567 if (len - vallen >= sizeof (rhostname)) {
2568 dbglog("EAP: trimming really long peer name down");
2569 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2570 rhostname[sizeof (rhostname) - 1] = '\0';
2572 BCOPY(inp + vallen, rhostname, len - vallen);
2573 rhostname[len - vallen] = '\0';
2576 /* In case the remote doesn't give us his name. */
2577 if (explicit_remote ||
2578 (remote_name[0] != '\0' && vallen == len))
2579 strlcpy(rhostname, remote_name, sizeof (rhostname));
2581 /* strip the MS domain name */
2582 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2583 char tmp[MAXNAMELEN+1];
2585 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2586 strcpy(rhostname, tmp);
2589 if (chap_verify_hook)
2590 chap_verifier = chap_verify_hook;
2592 chap_verifier = eap_chap_verify_response;
2594 esp->es_server.ea_id += 1;
2595 if ((*chap_verifier)(rhostname,
2596 esp->es_server.ea_name,
2598 esp->es_server.digest,
2602 sizeof(response_message)))
2604 info("EAP: MSCHAPv2 success for peer %q",
2606 esp->es_server.ea_type = EAPT_MSCHAPV2;
2607 eap_chapms2_send_request(esp,
2608 esp->es_server.ea_id,
2610 esp->es_server.ea_id,
2612 strlen(response_message));
2613 eap_figure_next_state(esp, 0);
2614 if (esp->es_rechallenge != 0)
2615 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2618 warn("EAP: MSCHAPv2 failure for peer %q",
2620 eap_chapms2_send_request(esp,
2621 esp->es_server.ea_id,
2623 esp->es_server.ea_id,
2625 strlen(response_message));
2629 info("EAP: MSCHAPv2 success confirmed");
2632 info("EAP: MSCHAPv2 failure confirmed");
2635 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2636 eap_send_nak(esp, id, EAPT_SRP);
2640 #endif /* PPP_WITH_CHAPMS */
2645 error("EAP: empty SRP Response");
2646 eap_figure_next_state(esp, 1);
2649 GETCHAR(typenum, inp);
2653 if (esp->es_server.ea_state != eapSRP1) {
2654 error("EAP: unexpected SRP Subtype 1 Response");
2655 eap_figure_next_state(esp, 1);
2660 ts = (struct t_server *)esp->es_server.ea_session;
2662 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2663 if (esp->es_server.ea_skey == NULL) {
2664 /* Client's A value is bogus; terminate now */
2665 error("EAP: bogus A value from client");
2666 eap_send_failure(esp);
2668 eap_figure_next_state(esp, 0);
2672 case EAPSRP_CVALIDATOR:
2673 if (esp->es_server.ea_state != eapSRP2) {
2674 error("EAP: unexpected SRP Subtype 2 Response");
2675 eap_figure_next_state(esp, 1);
2678 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2679 error("EAP: M1 length %d < %d", len,
2680 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2681 eap_figure_next_state(esp, 1);
2684 GETLONG(esp->es_server.ea_keyflags, inp);
2685 ts = (struct t_server *)esp->es_server.ea_session;
2687 if (t_serververify(ts, inp)) {
2688 info("EAP: unable to validate client identity");
2689 eap_send_failure(esp);
2692 eap_figure_next_state(esp, 0);
2696 if (esp->es_server.ea_state != eapSRP3) {
2697 error("EAP: unexpected SRP Subtype 3 Response");
2698 eap_send_failure(esp);
2701 esp->es_server.ea_type = EAPT_SRP;
2702 eap_send_success(esp);
2703 eap_figure_next_state(esp, 0);
2704 if (esp->es_rechallenge != 0)
2705 TIMEOUT(eap_rechallenge, esp,
2706 esp->es_rechallenge);
2707 if (esp->es_lwrechallenge != 0)
2708 TIMEOUT(srp_lwrechallenge, esp,
2709 esp->es_lwrechallenge);
2712 case EAPSRP_LWRECHALLENGE:
2713 if (esp->es_server.ea_state != eapSRP4) {
2714 info("EAP: unexpected SRP Subtype 4 Response");
2717 if (len != SHA_DIGESTSIZE) {
2718 error("EAP: bad Lightweight rechallenge "
2724 SHA1Update(&ctxt, &vallen, 1);
2725 SHA1Update(&ctxt, esp->es_server.ea_skey,
2727 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2728 SHA1Update(&ctxt, esp->es_server.ea_peer,
2729 esp->es_server.ea_peerlen);
2730 SHA1Final(dig, &ctxt);
2731 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2732 error("EAP: failed Lightweight rechallenge");
2733 eap_send_failure(esp);
2736 esp->es_server.ea_state = eapOpen;
2737 if (esp->es_lwrechallenge != 0)
2738 TIMEOUT(srp_lwrechallenge, esp,
2739 esp->es_lwrechallenge);
2743 #endif /* USE_SRP */
2746 /* This can't happen. */
2747 error("EAP: unknown Response type %d; ignored", typenum);
2751 if (esp->es_server.ea_timeout > 0) {
2752 UNTIMEOUT(eap_server_timeout, (void *)esp);
2755 if (esp->es_server.ea_state != eapBadAuth &&
2756 esp->es_server.ea_state != eapOpen) {
2757 esp->es_server.ea_id++;
2758 eap_send_request(esp);
2763 * eap_success - Receive EAP Success message (client mode).
2766 eap_success(eap_state *esp, u_char *inp, int id, int len)
2768 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2769 #ifdef PPP_WITH_EAPTLS
2770 && esp->es_client.ea_state != eapTlsRecvSuccess
2771 #endif /* PPP_WITH_EAPTLS */
2773 dbglog("EAP unexpected success message in state %s (%d)",
2774 eap_state_name(esp->es_client.ea_state),
2775 esp->es_client.ea_state);
2779 #ifdef PPP_WITH_EAPTLS
2780 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2781 eapTlsRecvSuccess) {
2782 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2783 eap_state_name(esp->es_client.ea_state),
2784 esp->es_client.ea_state);
2787 #endif /* PPP_WITH_EAPTLS */
2789 if (esp->es_client.ea_timeout > 0) {
2790 UNTIMEOUT(eap_client_timeout, (void *)esp);
2794 /* This is odd. The spec doesn't allow for this. */
2799 peap_finish(&esp->ea_peap);
2802 esp->es_client.ea_state = eapOpen;
2803 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2807 * eap_failure - Receive EAP Failure message (client mode).
2810 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2813 * Ignore failure messages if we're not open
2815 if (esp->es_client.ea_state <= eapClosed)
2818 if (!eap_client_active(esp)) {
2819 dbglog("EAP unexpected failure message in state %s (%d)",
2820 eap_state_name(esp->es_client.ea_state),
2821 esp->es_client.ea_state);
2824 if (esp->es_client.ea_timeout > 0) {
2825 UNTIMEOUT(eap_client_timeout, (void *)esp);
2829 /* This is odd. The spec doesn't allow for this. */
2833 esp->es_client.ea_state = eapBadAuth;
2835 error("EAP: peer reports authentication failure");
2838 peap_finish(&esp->ea_peap);
2841 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2845 * eap_input - Handle received EAP message.
2848 eap_input(int unit, u_char *inp, int inlen)
2850 eap_state *esp = &eap_states[unit];
2855 * Parse header (code, id and length). If packet too short,
2858 if (inlen < EAP_HEADERLEN) {
2859 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2865 if (len < EAP_HEADERLEN || len > inlen) {
2866 error("EAP: packet has illegal length field %d (%d..%d)", len,
2867 EAP_HEADERLEN, inlen);
2870 len -= EAP_HEADERLEN;
2872 /* Dispatch based on message code */
2875 eap_request(esp, inp, id, len);
2879 eap_response(esp, inp, id, len);
2883 eap_success(esp, inp, id, len);
2887 eap_failure(esp, inp, id, len);
2890 default: /* XXX Need code reject */
2891 /* Note: it's not legal to send EAP Nak here. */
2892 warn("EAP: unknown code %d received", code);
2898 * eap_printpkt - print the contents of an EAP packet.
2900 static char *eap_codenames[] = {
2901 "Request", "Response", "Success", "Failure"
2904 static char *eap_typenames[] = {
2905 "Identity", "Notification", "Nak", "MD5-Challenge",
2906 "OTP", "Generic-Token", NULL, NULL,
2907 "RSA", "DSS", "KEA", "KEA-Validate",
2908 "TLS", "Defender", "Windows 2000", "Arcot",
2909 "Cisco", "Nokia", "SRP", NULL,
2910 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2915 eap_printpkt(u_char *inp, int inlen,
2916 void (*printer) (void *, char *, ...), void *arg)
2918 int code, id, len, rtype, vallen;
2921 #ifdef PPP_WITH_EAPTLS
2923 #endif /* PPP_WITH_EAPTLS */
2924 #ifdef PPP_WITH_CHAPMS
2926 #endif /* PPP_WITH_CHAPMS */
2928 if (inlen < EAP_HEADERLEN)
2934 if (len < EAP_HEADERLEN || len > inlen)
2937 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2938 printer(arg, " %s", eap_codenames[code-1]);
2940 printer(arg, " code=0x%x", code);
2941 printer(arg, " id=0x%x", id);
2942 len -= EAP_HEADERLEN;
2946 printer(arg, " <missing type>");
2949 GETCHAR(rtype, inp);
2952 rtype <= sizeof (eap_typenames) / sizeof (char *))
2953 printer(arg, " %s", eap_typenames[rtype-1]);
2955 printer(arg, " type=0x%x", rtype);
2958 case EAPT_NOTIFICATION:
2960 printer(arg, " <Message ");
2961 print_string((char *)inp, len, printer, arg);
2966 printer(arg, " <No message>");
2973 GETCHAR(vallen, inp);
2977 printer(arg, " <Value%.*B>", vallen, inp);
2978 INCPTR(vallen, inp);
2981 printer(arg, " <Name ");
2982 print_string((char *)inp, len, printer, arg);
2987 printer(arg, " <No name>");
2991 #ifdef PPP_WITH_CHAPMS
2995 GETCHAR(opcode, inp);
2998 case CHAP_CHALLENGE:
3001 GETCHAR(vallen, inp);
3006 printer(arg, " Challenge <");
3007 for (; vallen > 0; --vallen) {
3010 printer(arg, "%.2x", val);
3014 printer(arg, ", <Name ");
3015 print_string((char *)inp, len, printer, arg);
3020 printer(arg, ", <No name>");
3026 printer(arg, " Success <Message ");
3027 print_string((char *)inp, len, printer, arg);
3033 printer(arg, " Failure <Message ");
3034 print_string((char *)inp, len, printer, arg);
3040 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3044 #endif /* PPP_WITH_CHAPMS */
3046 #ifdef PPP_WITH_EAPTLS
3050 GETCHAR(flags, inp);
3053 if(flags == 0 && len == 0){
3054 printer(arg, " Ack");
3058 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3059 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3060 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3062 #endif /* PPP_WITH_EAPTLS */
3068 GETCHAR(vallen, inp);
3070 printer(arg, "-%d", vallen);
3072 case EAPSRP_CHALLENGE:
3073 GETCHAR(vallen, inp);
3078 printer(arg, " <Name ");
3079 print_string((char *)inp, vallen, printer,
3083 printer(arg, " <No name>");
3085 INCPTR(vallen, inp);
3087 GETCHAR(vallen, inp);
3091 printer(arg, " <s%.*B>", vallen, inp);
3092 INCPTR(vallen, inp);
3094 GETCHAR(vallen, inp);
3099 printer(arg, " <Default g=2>");
3101 printer(arg, " <g%.*B>", vallen, inp);
3103 INCPTR(vallen, inp);
3106 printer(arg, " <Default N>");
3108 printer(arg, " <N%.*B>", len, inp);
3115 printer(arg, " <B%.*B>", len, inp);
3120 case EAPSRP_SVALIDATOR:
3121 if (len < sizeof (u_int32_t))
3124 len -= sizeof (u_int32_t);
3125 if (uval & SRPVAL_EBIT) {
3127 uval &= ~SRPVAL_EBIT;
3130 printer(arg, " f<%X>", uval);
3132 if ((vallen = len) > SHA_DIGESTSIZE)
3133 vallen = SHA_DIGESTSIZE;
3134 printer(arg, " <M2%.*B%s>", len, inp,
3135 len < SHA_DIGESTSIZE ? "?" : "");
3136 INCPTR(vallen, inp);
3139 printer(arg, " <PN%.*B>", len, inp);
3145 case EAPSRP_LWRECHALLENGE:
3146 printer(arg, " <Challenge%.*B>", len, inp);
3152 #endif /* USE_SRP */
3159 GETCHAR(rtype, inp);
3162 rtype <= sizeof (eap_typenames) / sizeof (char *))
3163 printer(arg, " %s", eap_typenames[rtype-1]);
3165 printer(arg, " type=0x%x", rtype);
3169 printer(arg, " <Name ");
3170 print_string((char *)inp, len, printer, arg);
3177 #ifdef PPP_WITH_EAPTLS
3181 GETCHAR(flags, inp);
3184 if(flags == 0 && len == 0){
3185 printer(arg, " Ack");
3189 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3190 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3191 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3194 #endif /* PPP_WITH_EAPTLS */
3198 printer(arg, " <missing hint>");
3201 GETCHAR(rtype, inp);
3203 printer(arg, " <Suggested-type %02X", rtype);
3205 rtype <= sizeof (eap_typenames) / sizeof (char *))
3206 printer(arg, " (%s)", eap_typenames[rtype-1]);
3212 printer(arg, " <missing length>");
3215 GETCHAR(vallen, inp);
3219 printer(arg, " <Value%.*B>", vallen, inp);
3220 INCPTR(vallen, inp);
3223 printer(arg, " <Name ");
3224 print_string((char *)inp, len, printer, arg);
3229 printer(arg, " <No name>");
3233 #ifdef PPP_WITH_CHAPMS
3237 GETCHAR(opcode, inp);
3243 GETCHAR(vallen, inp);
3248 printer(arg, " Response <");
3249 for (; vallen > 0; --vallen) {
3252 printer(arg, "%.2x", val);
3256 printer(arg, ", <Name ");
3257 print_string((char *)inp, len, printer, arg);
3262 printer(arg, ", <No name>");
3266 printer(arg, " Success");
3269 printer(arg, " Failure");
3272 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3276 #endif /* PPP_WITH_CHAPMS */
3282 GETCHAR(vallen, inp);
3284 printer(arg, "-%d", vallen);
3287 printer(arg, " <A%.*B>", len, inp);
3292 case EAPSRP_CVALIDATOR:
3293 if (len < sizeof (u_int32_t))
3296 len -= sizeof (u_int32_t);
3297 if (uval & SRPVAL_EBIT) {
3299 uval &= ~SRPVAL_EBIT;
3302 printer(arg, " f<%X>", uval);
3304 printer(arg, " <M1%.*B%s>", len, inp,
3305 len == SHA_DIGESTSIZE ? "" : "?");
3313 case EAPSRP_LWRECHALLENGE:
3314 printer(arg, " <Response%.*B%s>", len, inp,
3315 len == SHA_DIGESTSIZE ? "" : "?");
3316 if ((vallen = len) > SHA_DIGESTSIZE)
3317 vallen = SHA_DIGESTSIZE;
3318 INCPTR(vallen, inp);
3323 #endif /* USE_SRP */
3327 case EAP_SUCCESS: /* No payload expected for these! */
3332 printer(arg, " <truncated>");
3337 printer(arg, "%8B...", inp);
3339 printer(arg, "%.*B", len, inp);
3342 return (inp - pstart);