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"
68 #include "ppp-crypto.h"
73 #endif /* PPP_WITH_PEAP */
82 #endif /* PPP_WITH_SRP */
84 #ifdef PPP_WITH_EAPTLS
86 #endif /* PPP_WITH_EAPTLS */
88 #ifdef PPP_WITH_CHAPMS
92 extern int chapms_strip_domain;
93 #endif /* PPP_WITH_CHAPMS */
95 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
97 static char *pn_secret = NULL; /* Pseudonym generating secret */
101 * Command-line options.
103 static option_t eap_option_list[] = {
104 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
105 "Set retransmit timeout for EAP Requests (server)" },
106 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
107 "Set max number of EAP Requests sent (server)" },
108 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
109 "Set time limit for peer EAP authentication" },
110 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
111 "Set max number of EAP Requests allows (client)" },
112 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
113 "Set interval for EAP rechallenge" },
115 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
116 "Set interval for SRP lightweight rechallenge" },
117 { "srp-pn-secret", o_string, &pn_secret,
118 "Long term pseudonym generation secret" },
119 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
120 "Use pseudonym if offered one by server", 1 },
126 * Protocol entry points.
128 static void eap_init (int unit);
129 static void eap_input (int unit, u_char *inp, int inlen);
130 static void eap_protrej (int unit);
131 static void eap_lowerup (int unit);
132 static void eap_lowerdown (int unit);
133 static int eap_printpkt (u_char *inp, int inlen,
134 void (*)(void *arg, char *fmt, ...), void *arg);
136 struct protent eap_protent = {
137 PPP_EAP, /* protocol number */
138 eap_init, /* initialization procedure */
139 eap_input, /* process a received packet */
140 eap_protrej, /* process a received protocol-reject */
141 eap_lowerup, /* lower layer has gone up */
142 eap_lowerdown, /* lower layer has gone down */
143 NULL, /* open the protocol */
144 NULL, /* close the protocol */
145 eap_printpkt, /* print a packet in readable form */
146 NULL, /* process a received data packet */
147 1, /* protocol enabled */
148 "EAP", /* text name of protocol */
149 NULL, /* text name of corresponding data protocol */
150 eap_option_list, /* list of command-line options */
151 NULL, /* check requested options; assign defaults */
152 NULL, /* configure interface for demand-dial */
153 NULL /* say whether to bring up link for this pkt */
158 * A well-known 2048 bit modulus.
160 static const u_char wkmodulus[] = {
161 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
162 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
163 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
164 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
165 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
166 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
167 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
168 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
169 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
170 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
171 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
172 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
173 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
174 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
175 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
176 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
177 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
178 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
179 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
180 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
181 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
182 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
183 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
184 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
185 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
186 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
187 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
188 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
189 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
190 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
191 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
192 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
194 #endif /* PPP_WITH_SRP */
196 /* Local forward declarations. */
197 static void eap_server_timeout (void *arg);
200 * Convert EAP state code to printable string for debug.
203 eap_state_name(enum eap_state_code esc)
205 static const char *state_names[] = { EAP_STATES };
207 return (state_names[(int)esc]);
211 * eap_init - Initialize state for an EAP user. This is currently
212 * called once by main() during start-up.
217 eap_state *esp = &eap_states[unit];
219 BZERO(esp, sizeof (*esp));
221 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
222 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
223 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
224 esp->es_client.ea_timeout = EAP_DEFREQTIME;
225 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
226 #ifdef PPP_WITH_EAPTLS
227 esp->es_client.ea_using_eaptls = 0;
228 #endif /* PPP_WITH_EAPTLS */
229 #ifdef PPP_WITH_CHAPMS
230 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
231 esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
236 * eap_client_timeout - Give up waiting for the peer to send any
240 eap_client_timeout(void *arg)
242 eap_state *esp = (eap_state *) arg;
244 if (!eap_client_active(esp))
247 error("EAP: timeout waiting for Request from peer");
248 auth_withpeer_fail(esp->es_unit, PPP_EAP);
249 esp->es_client.ea_state = eapBadAuth;
253 * eap_authwithpeer - Authenticate to our peer (behave as client).
255 * Start client state and wait for requests. This is called only
259 eap_authwithpeer(int unit, char *localname)
261 eap_state *esp = &eap_states[unit];
263 /* Save the peer name we're given */
264 esp->es_client.ea_name = localname;
265 esp->es_client.ea_namelen = strlen(localname);
267 esp->es_client.ea_state = eapListen;
270 * Start a timer so that if the other end just goes
271 * silent, we don't sit here waiting forever.
273 if (esp->es_client.ea_timeout > 0)
274 TIMEOUT(eap_client_timeout, (void *)esp,
275 esp->es_client.ea_timeout);
279 * Format a standard EAP Failure message and send it to the peer.
283 eap_send_failure(eap_state *esp)
287 outp = outpacket_buf;
289 MAKEHEADER(outp, PPP_EAP);
291 PUTCHAR(EAP_FAILURE, outp);
292 esp->es_server.ea_id++;
293 PUTCHAR(esp->es_server.ea_id, outp);
294 PUTSHORT(EAP_HEADERLEN, outp);
296 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
298 esp->es_server.ea_state = eapBadAuth;
299 auth_peer_fail(esp->es_unit, PPP_EAP);
303 * Format a standard EAP Success message and send it to the peer.
307 eap_send_success(eap_state *esp)
311 outp = outpacket_buf;
313 MAKEHEADER(outp, PPP_EAP);
315 PUTCHAR(EAP_SUCCESS, outp);
316 esp->es_server.ea_id++;
317 PUTCHAR(esp->es_server.ea_id, outp);
318 PUTSHORT(EAP_HEADERLEN, outp);
320 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
322 auth_peer_success(esp->es_unit, PPP_EAP, 0,
323 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
328 * Set DES key according to pseudonym-generating secret and current
332 pncrypt_getkey(int timeoffs, unsigned char *key, int keylen)
339 if (pn_secret == NULL)
341 reftime = time(NULL) + timeoffs;
342 tp = localtime(&reftime);
344 ctxt = PPP_MD_CTX_new();
347 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
349 PPP_DigestInit(ctxt, PPP_sha1());
350 PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
351 PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
352 PPP_DigestFinal(ctxt, key, &keylen);
354 PPP_MD_CTX_free(ctxt);
361 static char base64[] =
362 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
370 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
375 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
378 if (bs->bs_offs >= 24) {
379 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
380 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
381 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
382 *outp++ = base64[bs->bs_bits & 0x3F];
392 b64flush(struct b64state *bs, u_char *outp)
396 if (bs->bs_offs == 8) {
397 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
398 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
400 } else if (bs->bs_offs == 16) {
401 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
402 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
403 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
412 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
418 if ((cp = strchr(base64, *inp++)) == NULL)
420 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
423 if (bs->bs_offs >= 8) {
424 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
431 #endif /* PPP_WITH_SRP */
434 * Assume that current waiting server state is complete and figure
435 * next state to use based on available authentication data. 'status'
436 * indicates if there was an error in handling the last query. It is
437 * 0 for success and non-zero for failure.
440 eap_figure_next_state(eap_state *esp, int status)
443 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp, key[SHA_DIGEST_LENGTH];
445 struct t_confent *tce, mytce;
448 int id, i, plen, clen, toffs, keylen;
451 #endif /* PPP_WITH_SRP */
452 #ifdef PPP_WITH_EAPTLS
453 struct eaptls_session *ets;
455 char secret[MAXWORDLEN];
456 #endif /* PPP_WITH_EAPTLS */
458 esp->es_server.ea_timeout = esp->es_savedtime;
459 #ifdef PPP_WITH_EAPTLS
460 esp->es_server.ea_prev_state = esp->es_server.ea_state;
461 #endif /* PPP_WITH_EAPTLS */
462 switch (esp->es_server.ea_state) {
468 /* Discard any previous session. */
469 ts = (struct t_server *)esp->es_server.ea_session;
472 esp->es_server.ea_session = NULL;
473 esp->es_server.ea_skey = NULL;
475 #endif /* PPP_WITH_SRP */
477 esp->es_server.ea_state = eapBadAuth;
481 /* If we've got a pseudonym, try to decode to real name. */
482 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
483 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
484 SRP_PSEUDO_LEN) == 0 &&
485 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
487 BZERO(&bs, sizeof (bs));
489 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
490 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
493 for (i = 0; i < 5; i++) {
494 pncrypt_getkey(toffs, key, keylen);
497 if (!DesDecrypt(secbuf, key, clear)) {
498 dbglog("no DES here; cannot decode "
502 id = *(unsigned char *)clear;
503 if (id + 1 <= plen && id + 9 > plen)
506 if (plen % 8 == 0 && i < 5) {
508 * Note that this is always shorter than the
509 * original stored string, so there's no need
512 if ((i = plen = *(unsigned char *)clear) > 7)
514 esp->es_server.ea_peerlen = plen;
515 dp = (unsigned char *)esp->es_server.ea_peer;
516 BCOPY(clear + 1, dp, i);
521 DesDecrypt(sp, key, dp);
526 esp->es_server.ea_peer[
527 esp->es_server.ea_peerlen] = '\0';
528 dbglog("decoded pseudonym to \"%.*q\"",
529 esp->es_server.ea_peerlen,
530 esp->es_server.ea_peer);
532 dbglog("failed to decode real name");
533 /* Stay in eapIdentfy state; requery */
537 /* Look up user in secrets database. */
538 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
539 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
540 /* Set up default in case SRP entry is bad */
541 esp->es_server.ea_state = eapMD5Chall;
542 /* Get t_confent based on index in srp-secrets */
543 id = strtol((char *)secbuf, &cp, 10);
544 if (*cp++ != ':' || id < 0)
548 mytce.modulus.data = (u_char *)wkmodulus;
549 mytce.modulus.len = sizeof (wkmodulus);
550 mytce.generator.data = (u_char *)"\002";
551 mytce.generator.len = 1;
553 } else if ((tce = gettcid(id)) != NULL) {
555 * Client will have to verify this modulus/
556 * generator combination, and that will take
557 * a while. Lengthen the timeout here.
559 if (esp->es_server.ea_timeout > 0 &&
560 esp->es_server.ea_timeout < 30)
561 esp->es_server.ea_timeout = 30;
565 if ((cp2 = strchr(cp, ':')) == NULL)
568 tpw.pebuf.name = esp->es_server.ea_peer;
569 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
571 tpw.pebuf.password.data = (char*) tpw.pwbuf;
572 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
574 tpw.pebuf.salt.data = tpw.saltbuf;
575 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
577 esp->es_server.ea_session = (void *)ts;
578 esp->es_server.ea_state = eapSRP1;
579 vals[0] = esp->es_server.ea_id + 1;
581 t_serveraddexdata(ts, vals, 2);
582 /* Generate B; must call before t_servergetkey() */
586 #endif /* PPP_WITH_SRP */
587 #ifdef PPP_WITH_EAPTLS
588 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
589 esp->es_server.ea_name, secret, &secret_len, 1)) {
591 esp->es_server.ea_state = eapTlsStart;
594 #endif /* PPP_WITH_EAPTLS */
596 esp->es_server.ea_state = eapMD5Chall;
599 #ifdef PPP_WITH_EAPTLS
601 /* Initialize ssl session */
602 if(!eaptls_init_ssl_server(esp)) {
603 esp->es_server.ea_state = eapBadAuth;
607 esp->es_server.ea_state = eapTlsRecv;
611 ets = (struct eaptls_session *) esp->es_server.ea_session;
613 if(ets->alert_sent) {
614 esp->es_server.ea_state = eapTlsSendAlert;
619 esp->es_server.ea_state = eapBadAuth;
622 ets = (struct eaptls_session *) esp->es_server.ea_session;
625 esp->es_server.ea_state = eapTlsSendAck;
627 esp->es_server.ea_state = eapTlsSend;
631 ets = (struct eaptls_session *) esp->es_server.ea_session;
634 esp->es_server.ea_state = eapTlsRecvAck;
636 if(SSL_is_init_finished(ets->ssl))
637 esp->es_server.ea_state = eapTlsRecvClient;
639 /* JJK Add "TLS empty record" message here ??? */
640 esp->es_server.ea_state = eapTlsRecv;
644 esp->es_server.ea_state = eapTlsRecv;
650 esp->es_server.ea_state = eapBadAuth;
654 esp->es_server.ea_state = eapTlsSend;
657 case eapTlsSendAlert:
658 esp->es_server.ea_state = eapTlsRecvAlertAck;
660 #endif /* PPP_WITH_EAPTLS */
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;
670 #endif /* PPP_WITH_SRP */
672 esp->es_server.ea_state = eapMD5Chall;
673 } else if (status != 0 || esp->es_server.ea_session == NULL) {
674 esp->es_server.ea_state = eapBadAuth;
676 esp->es_server.ea_state = eapSRP2;
682 ts = (struct t_server *)esp->es_server.ea_session;
683 if (ts != NULL && status != 0) {
685 esp->es_server.ea_session = NULL;
686 esp->es_server.ea_skey = NULL;
688 #endif /* PPP_WITH_SRP */
689 if (status != 0 || esp->es_server.ea_session == NULL) {
690 esp->es_server.ea_state = eapBadAuth;
692 esp->es_server.ea_state = eapSRP3;
699 ts = (struct t_server *)esp->es_server.ea_session;
700 if (ts != NULL && status != 0) {
702 esp->es_server.ea_session = NULL;
703 esp->es_server.ea_skey = NULL;
705 #endif /* PPP_WITH_SRP */
706 if (status != 0 || esp->es_server.ea_session == NULL) {
707 esp->es_server.ea_state = eapBadAuth;
709 esp->es_server.ea_state = eapOpen;
713 #ifdef PPP_WITH_CHAPMS
714 case eapMSCHAPv2Chall:
718 esp->es_server.ea_state = eapBadAuth;
720 esp->es_server.ea_state = eapOpen;
725 esp->es_server.ea_state = eapBadAuth;
728 if (esp->es_server.ea_state == eapBadAuth)
729 eap_send_failure(esp);
731 #ifdef PPP_WITH_EAPTLS
732 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));
733 #endif /* PPP_WITH_EAPTLS */
738 * eap_chap_verify_response - check whether the peer's response matches
739 * what we think it should be. Returns 1 if it does (authentication
740 * succeeded), or 0 if it doesn't.
743 eap_chap_verify_response(char *name, char *ourname, int id,
744 struct chap_digest_type *digest,
745 unsigned char *challenge, unsigned char *response,
746 char *message, int message_space)
749 unsigned char secret[MAXSECRETLEN];
752 /* Get the secret that the peer is supposed to know */
753 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
754 error("No CHAP secret found for authenticating %q", name);
758 ok = digest->verify_response(id, name, secret, secret_len, challenge,
759 response, message, message_space);
760 memset(secret, 0, sizeof(secret));
766 * Format and send an CHAPV2-Success/Failure EAP Request message.
769 eap_chapms2_send_request(eap_state *esp, u_char id,
770 u_char opcode, u_char chapid,
771 char *message, int message_len)
776 outp = outpacket_buf;
778 MAKEHEADER(outp, PPP_EAP);
780 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
781 msglen += message_len;
783 PUTCHAR(EAP_REQUEST, outp);
785 PUTSHORT(msglen, outp);
786 PUTCHAR(EAPT_MSCHAPV2, outp);
787 PUTCHAR(opcode, outp);
788 PUTCHAR(chapid, outp);
790 PUTSHORT(msglen - 5, outp);
791 BCOPY(message, outp, message_len);
793 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
795 if (opcode == CHAP_SUCCESS) {
796 auth_peer_success(esp->es_unit, PPP_EAP, 0,
797 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
800 esp->es_server.ea_state = eapBadAuth;
801 auth_peer_fail(esp->es_unit, PPP_EAP);
804 #endif /* PPP_WITH_CHAPMS */
807 * Format an EAP Request message and send it to the peer. Message
808 * type depends on current state. (Server operation)
811 eap_send_request(eap_state *esp)
821 u_char clear[8], cipher[8], dig[SHA_DIGEST_LENGTH], *optr, *cp, key[SHA_DIGEST_LENGTH];
822 int i, j, diglen, clen, keylen = sizeof(key);
825 #endif /* PPP_WITH_SRP */
827 /* Handle both initial auth and restart */
828 if (esp->es_server.ea_state < eapIdentify &&
829 esp->es_server.ea_state != eapInitial) {
830 esp->es_server.ea_state = eapIdentify;
831 if (explicit_remote) {
833 * If we already know the peer's
834 * unauthenticated name, then there's no
835 * reason to ask. Go to next state instead.
837 esp->es_server.ea_peer = remote_name;
838 esp->es_server.ea_peerlen = strlen(remote_name);
839 eap_figure_next_state(esp, 0);
843 if (esp->es_server.ea_maxrequests > 0 &&
844 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
845 if (esp->es_server.ea_responses > 0)
846 error("EAP: too many Requests sent");
848 error("EAP: no response to Requests");
849 eap_send_failure(esp);
853 outp = outpacket_buf;
855 MAKEHEADER(outp, PPP_EAP);
857 PUTCHAR(EAP_REQUEST, outp);
858 PUTCHAR(esp->es_server.ea_id, outp);
862 switch (esp->es_server.ea_state) {
864 PUTCHAR(EAPT_IDENTITY, outp);
866 challen = strlen(str);
867 BCOPY(str, outp, challen);
868 INCPTR(challen, outp);
872 PUTCHAR(EAPT_MD5CHAP, outp);
874 * pick a random challenge length between
875 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
877 challen = (drand48() *
878 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
879 MIN_CHALLENGE_LENGTH;
880 PUTCHAR(challen, outp);
881 esp->es_challen = challen;
882 ptr = esp->es_challenge;
883 while (--challen >= 0)
884 *ptr++ = (u_char) (drand48() * 0x100);
885 BCOPY(esp->es_challenge, outp, esp->es_challen);
886 INCPTR(esp->es_challen, outp);
887 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
888 INCPTR(esp->es_server.ea_namelen, outp);
891 #ifdef PPP_WITH_CHAPMS
892 case eapMSCHAPv2Chall:
893 esp->es_server.digest->generate_challenge(esp->es_challenge);
894 challen = esp->es_challenge[0];
895 esp->es_challen = challen;
897 PUTCHAR(EAPT_MSCHAPV2, outp);
898 PUTCHAR(CHAP_CHALLENGE, outp);
899 PUTCHAR(esp->es_server.ea_id, outp);
901 PUTSHORT(5 + challen +
902 esp->es_server.ea_namelen,
904 /* challen + challenge */
905 BCOPY(esp->es_challenge, outp, challen+1);
906 INCPTR(challen+1, outp);
907 BCOPY(esp->es_server.ea_name,
909 esp->es_server.ea_namelen);
910 INCPTR(esp->es_server.ea_namelen, outp);
912 #endif /* PPP_WITH_CHAPMS */
914 #ifdef PPP_WITH_EAPTLS
916 PUTCHAR(EAPT_TLS, outp);
917 PUTCHAR(EAP_TLS_FLAGS_START, outp);
918 eap_figure_next_state(esp, 0);
922 eaptls_send(esp->es_server.ea_session, &outp);
923 eap_figure_next_state(esp, 0);
927 PUTCHAR(EAPT_TLS, outp);
929 eap_figure_next_state(esp, 0);
932 case eapTlsSendAlert:
933 eaptls_send(esp->es_server.ea_session, &outp);
934 eap_figure_next_state(esp, 0);
936 #endif /* PPP_WITH_EAPTLS */
940 PUTCHAR(EAPT_SRP, outp);
941 PUTCHAR(EAPSRP_CHALLENGE, outp);
943 PUTCHAR(esp->es_server.ea_namelen, outp);
944 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
945 INCPTR(esp->es_server.ea_namelen, outp);
947 ts = (struct t_server *)esp->es_server.ea_session;
949 PUTCHAR(ts->s.len, outp);
950 BCOPY(ts->s.data, outp, ts->s.len);
951 INCPTR(ts->s.len, outp);
953 if (ts->g.len == 1 && ts->g.data[0] == 2) {
956 PUTCHAR(ts->g.len, outp);
957 BCOPY(ts->g.data, outp, ts->g.len);
958 INCPTR(ts->g.len, outp);
961 if (ts->n.len != sizeof (wkmodulus) ||
962 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
963 BCOPY(ts->n.data, outp, ts->n.len);
964 INCPTR(ts->n.len, outp);
969 PUTCHAR(EAPT_SRP, outp);
970 PUTCHAR(EAPSRP_SKEY, outp);
972 ts = (struct t_server *)esp->es_server.ea_session;
974 BCOPY(ts->B.data, outp, ts->B.len);
975 INCPTR(ts->B.len, outp);
979 PUTCHAR(EAPT_SRP, outp);
980 PUTCHAR(EAPSRP_SVALIDATOR, outp);
981 PUTLONG(SRPVAL_EBIT, outp);
982 ts = (struct t_server *)esp->es_server.ea_session;
984 BCOPY(t_serverresponse(ts), outp, SHA_DIGEST_LENGTH);
985 INCPTR(SHA_DIGEST_LENGTH, outp);
987 if (pncrypt_getkey(0, key, keylen)) {
988 /* Generate pseudonym */
990 cp = (unsigned char *)esp->es_server.ea_peer;
991 if ((j = i = esp->es_server.ea_peerlen) > 7)
994 BCOPY(cp, clear + 1, j);
998 if (!DesEncrypt(clear, key, cipher)) {
999 dbglog("no DES here; not generating pseudonym");
1003 BZERO(&b64, sizeof (b64));
1004 outp++; /* space for pseudonym length */
1005 outp += b64enc(&b64, cipher, 8, outp);
1007 DesEncrypt(cp, key, cipher);
1008 outp += b64enc(&b64, cipher, 8, outp);
1013 BCOPY(cp, clear, i);
1016 *cp++ = drand48() * 0x100;
1020 DesEncrypt(clear, key, cipher);
1021 outp += b64enc(&b64, cipher, 8, outp);
1023 outp += b64flush(&b64, outp);
1025 /* Set length and pad out to next 20 octet boundary */
1026 i = outp - optr - 1;
1028 i %= SHA_DIGEST_LENGTH;
1030 while (i < SHA_DIGEST_LENGTH) {
1031 *outp++ = drand48() * 0x100;
1036 /* Obscure the pseudonym with SHA1 hash */
1037 ctxt = PPP_MD_CTX_new();
1040 PPP_DigestInit(ctxt, PPP_sha1());
1041 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1042 PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey,
1044 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
1045 esp->es_server.ea_peerlen);
1046 while (optr < outp) {
1047 diglen = SHA_DIGEST_LENGTH;
1048 PPP_DigestFinal(ctxt, dig, &diglen);
1050 while (cp < dig + SHA_DIGEST_LENGTH)
1053 PPP_DigestInit(ctxt, PPP_sha1());
1054 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1055 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
1057 PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH,
1061 PPP_MD_CTX_free(ctxt);
1067 PUTCHAR(EAPT_SRP, outp);
1068 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1069 challen = MIN_CHALLENGE_LENGTH +
1070 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1071 esp->es_challen = challen;
1072 ptr = esp->es_challenge;
1073 while (--challen >= 0)
1074 *ptr++ = drand48() * 0x100;
1075 BCOPY(esp->es_challenge, outp, esp->es_challen);
1076 INCPTR(esp->es_challen, outp);
1078 #endif /* PPP_WITH_SRP */
1084 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1085 PUTSHORT(outlen, lenloc);
1087 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1089 esp->es_server.ea_requests++;
1091 if (esp->es_server.ea_timeout > 0)
1092 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1096 * eap_authpeer - Authenticate our peer (behave as server).
1098 * Start server state and send first request. This is called only
1099 * after eap_lowerup.
1102 eap_authpeer(int unit, char *localname)
1104 eap_state *esp = &eap_states[unit];
1106 /* Save the name we're given. */
1107 esp->es_server.ea_name = localname;
1108 esp->es_server.ea_namelen = strlen(localname);
1110 esp->es_savedtime = esp->es_server.ea_timeout;
1112 /* Lower layer up yet? */
1113 if (esp->es_server.ea_state == eapInitial ||
1114 esp->es_server.ea_state == eapPending) {
1115 esp->es_server.ea_state = eapPending;
1119 esp->es_server.ea_state = eapPending;
1121 /* ID number not updated here intentionally; hashed into M1 */
1122 eap_send_request(esp);
1126 * eap_server_timeout - Retransmission timer for sending Requests
1130 eap_server_timeout(void *arg)
1132 #ifdef PPP_WITH_EAPTLS
1136 #endif /* PPP_WITH_EAPTLS */
1138 eap_state *esp = (eap_state *) arg;
1140 if (!eap_server_active(esp))
1143 #ifdef PPP_WITH_EAPTLS
1144 switch(esp->es_server.ea_prev_state) {
1147 * In eap-tls the state changes after a request, so we return to
1148 * previous state ...
1151 case(eapTlsSendAck):
1152 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1156 * ... or resend the stored data
1159 case(eapTlsSendAlert):
1160 outp = outpacket_buf;
1161 MAKEHEADER(outp, PPP_EAP);
1162 PUTCHAR(EAP_REQUEST, outp);
1163 PUTCHAR(esp->es_server.ea_id, outp);
1167 eaptls_retransmit(esp->es_server.ea_session, &outp);
1169 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1170 PUTSHORT(outlen, lenloc);
1171 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1172 esp->es_server.ea_requests++;
1174 if (esp->es_server.ea_timeout > 0)
1175 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1181 #endif /* PPP_WITH_EAPTLS */
1183 /* EAP ID number must not change on timeout. */
1184 eap_send_request(esp);
1188 * When it's time to send rechallenge the peer, this timeout is
1189 * called. Once the rechallenge is successful, the response handler
1190 * will restart the timer. If it fails, then the link is dropped.
1193 eap_rechallenge(void *arg)
1195 eap_state *esp = (eap_state *)arg;
1197 if (esp->es_server.ea_state != eapOpen &&
1198 esp->es_server.ea_state != eapSRP4)
1201 esp->es_server.ea_requests = 0;
1202 esp->es_server.ea_state = eapIdentify;
1203 eap_figure_next_state(esp, 0);
1204 esp->es_server.ea_id++;
1205 eap_send_request(esp);
1209 srp_lwrechallenge(void *arg)
1211 eap_state *esp = (eap_state *)arg;
1213 if (esp->es_server.ea_state != eapOpen ||
1214 esp->es_server.ea_type != EAPT_SRP)
1217 esp->es_server.ea_requests = 0;
1218 esp->es_server.ea_state = eapSRP4;
1219 esp->es_server.ea_id++;
1220 eap_send_request(esp);
1224 * eap_lowerup - The lower layer is now up.
1226 * This is called before either eap_authpeer or eap_authwithpeer. See
1227 * link_established() in auth.c. All that's necessary here is to
1228 * return to closed state so that those two routines will do the right
1232 eap_lowerup(int unit)
1234 eap_state *esp = &eap_states[unit];
1236 /* Discard any (possibly authenticated) peer name. */
1237 if (esp->es_server.ea_peer != NULL &&
1238 esp->es_server.ea_peer != remote_name)
1239 free(esp->es_server.ea_peer);
1240 esp->es_server.ea_peer = NULL;
1241 if (esp->es_client.ea_peer != NULL)
1242 free(esp->es_client.ea_peer);
1243 esp->es_client.ea_peer = NULL;
1245 esp->es_client.ea_state = eapClosed;
1246 esp->es_server.ea_state = eapClosed;
1250 * eap_lowerdown - The lower layer is now down.
1252 * Cancel all timeouts and return to initial state.
1255 eap_lowerdown(int unit)
1257 eap_state *esp = &eap_states[unit];
1259 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1260 UNTIMEOUT(eap_client_timeout, (void *)esp);
1262 if (eap_server_active(esp)) {
1263 if (esp->es_server.ea_timeout > 0) {
1264 UNTIMEOUT(eap_server_timeout, (void *)esp);
1267 if ((esp->es_server.ea_state == eapOpen ||
1268 esp->es_server.ea_state == eapSRP4) &&
1269 esp->es_rechallenge > 0) {
1270 UNTIMEOUT(eap_rechallenge, (void *)esp);
1272 if (esp->es_server.ea_state == eapOpen &&
1273 esp->es_lwrechallenge > 0) {
1274 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1278 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1279 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1283 * eap_protrej - Peer doesn't speak this protocol.
1285 * This shouldn't happen. If it does, it represents authentication
1289 eap_protrej(int unit)
1291 eap_state *esp = &eap_states[unit];
1293 if (eap_client_active(esp)) {
1294 error("EAP authentication failed due to Protocol-Reject");
1295 auth_withpeer_fail(unit, PPP_EAP);
1297 if (eap_server_active(esp)) {
1298 error("EAP authentication of peer failed on Protocol-Reject");
1299 auth_peer_fail(unit, PPP_EAP);
1301 eap_lowerdown(unit);
1305 * Format and send a regular EAP Response message.
1308 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1309 u_char *str, int lenstr)
1314 outp = outpacket_buf;
1316 MAKEHEADER(outp, PPP_EAP);
1318 PUTCHAR(EAP_RESPONSE, outp);
1320 esp->es_client.ea_id = id;
1321 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1322 PUTSHORT(msglen, outp);
1323 PUTCHAR(typenum, outp);
1325 BCOPY(str, outp, lenstr);
1328 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1332 * Format and send an MD5-Challenge EAP Response message.
1335 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1336 char *name, int namelen)
1341 outp = outpacket_buf;
1343 MAKEHEADER(outp, PPP_EAP);
1345 PUTCHAR(EAP_RESPONSE, outp);
1347 esp->es_client.ea_id = id;
1348 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_DIGEST_LENGTH +
1350 PUTSHORT(msglen, outp);
1351 PUTCHAR(EAPT_MD5CHAP, outp);
1352 PUTCHAR(MD5_DIGEST_LENGTH, outp);
1353 BCOPY(hash, outp, MD5_DIGEST_LENGTH);
1354 INCPTR(MD5_DIGEST_LENGTH, outp);
1356 BCOPY(name, outp, namelen);
1359 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1364 * Format and send a SRP EAP Response message.
1367 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1368 u_char *str, int lenstr)
1373 outp = outpacket_buf;
1375 MAKEHEADER(outp, PPP_EAP);
1377 PUTCHAR(EAP_RESPONSE, outp);
1379 esp->es_client.ea_id = id;
1380 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1381 PUTSHORT(msglen, outp);
1382 PUTCHAR(EAPT_SRP, outp);
1383 PUTCHAR(subtypenum, outp);
1385 BCOPY(str, outp, lenstr);
1388 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1392 * Format and send a SRP EAP Client Validator Response message.
1395 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1400 outp = outpacket_buf;
1402 MAKEHEADER(outp, PPP_EAP);
1404 PUTCHAR(EAP_RESPONSE, outp);
1406 esp->es_client.ea_id = id;
1407 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1409 PUTSHORT(msglen, outp);
1410 PUTCHAR(EAPT_SRP, outp);
1411 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1412 PUTLONG(flags, outp);
1413 BCOPY(str, outp, SHA_DIGEST_LENGTH);
1415 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1417 #endif /* PPP_WITH_SRP */
1419 #ifdef PPP_WITH_EAPTLS
1421 * Send an EAP-TLS response message with tls data
1424 eap_tls_response(eap_state *esp, u_char id)
1430 outp = outpacket_buf;
1432 MAKEHEADER(outp, PPP_EAP);
1434 PUTCHAR(EAP_RESPONSE, outp);
1441 If the id in the request is unchanged, we must retransmit
1444 if(id == esp->es_client.ea_id)
1445 eaptls_retransmit(esp->es_client.ea_session, &outp);
1447 eaptls_send(esp->es_client.ea_session, &outp);
1449 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1450 PUTSHORT(outlen, lenloc);
1452 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1454 esp->es_client.ea_id = id;
1458 * Send an EAP-TLS ack
1461 eap_tls_sendack(eap_state *esp, u_char id)
1467 outp = outpacket_buf;
1469 MAKEHEADER(outp, PPP_EAP);
1471 PUTCHAR(EAP_RESPONSE, outp);
1473 esp->es_client.ea_id = id;
1478 PUTCHAR(EAPT_TLS, outp);
1481 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1482 PUTSHORT(outlen, lenloc);
1484 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1486 #endif /* PPP_WITH_EAPTLS */
1489 eap_send_nak(eap_state *esp, u_char id, u_char type)
1494 outp = outpacket_buf;
1496 MAKEHEADER(outp, PPP_EAP);
1498 PUTCHAR(EAP_RESPONSE, outp);
1500 esp->es_client.ea_id = id;
1501 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1502 PUTSHORT(msglen, outp);
1503 PUTCHAR(EAPT_NAK, outp);
1504 PUTCHAR(type, outp);
1506 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1511 name_of_pn_file(void)
1513 char *user, *path, *file;
1516 static bool pnlogged = 0;
1518 pw = getpwuid(getuid());
1519 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1523 file = PPP_PATH_PSEUDONYM;
1524 pl = strlen(user) + strlen(file) + 2;
1528 (void) slprintf(path, pl, "%s/%s", user, file);
1530 dbglog("pseudonym file: %s", path);
1537 open_pn_file(mode_t modebits)
1542 if ((path = name_of_pn_file()) == NULL)
1544 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1552 remove_pn_file(void)
1556 if ((path = name_of_pn_file()) != NULL) {
1557 (void) unlink(path);
1563 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1566 u_char *datp, *digp;
1568 u_char dig[SHA_DIGEST_LENGTH];
1569 int dsize, fd, olen = len, diglen = sizeof(dig);
1572 * Do the decoding by working backwards. This eliminates the need
1573 * to save the decoded output in a separate buffer.
1577 if ((dsize = len % SHA_DIGEST_LENGTH) == 0)
1578 dsize = SHA_DIGEST_LENGTH;
1581 ctxt = PPP_MD_CTX_new();
1584 PPP_DigestInit(ctxt, PPP_sha1());
1585 PPP_DigestUpdate(ctxt, &val, 1);
1586 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
1589 PPP_DigestUpdate(ctxt, datp, SHA_DIGEST_LENGTH);
1591 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
1592 esp->es_client.ea_namelen);
1594 PPP_DigestFinal(ctxt, dig, &diglen);
1596 for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
1599 PPP_MD_CTX_free(ctxt);
1603 /* Now check that the result is sane */
1604 if (olen <= 0 || *inp + 1 > olen) {
1605 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1610 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1612 dbglog("EAP: error saving pseudonym: %m");
1615 len = write(fd, inp + 1, *inp);
1616 if (close(fd) != -1 && len == *inp) {
1617 dbglog("EAP: saved pseudonym");
1618 esp->es_usedpseudo = 0;
1620 dbglog("EAP: failed to save pseudonym");
1624 #endif /* PPP_WITH_SRP */
1628 * Format and send an CHAPV2-Challenge EAP Response message.
1631 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1636 outp = outpacket_buf;
1638 MAKEHEADER(outp, PPP_EAP);
1640 PUTCHAR(EAP_RESPONSE, outp);
1642 esp->es_client.ea_id = id;
1643 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1644 PUTSHORT(msglen, outp);
1645 PUTCHAR(EAPT_MSCHAPV2, outp);
1646 PUTCHAR(CHAP_RESPONSE, outp);
1647 PUTCHAR(chapid, outp);
1650 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1651 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1652 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1653 BCOPY(user, outp, user_len);
1655 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1660 * eap_request - Receive EAP Request message (client mode).
1663 eap_request(eap_state *esp, u_char *inp, int id, int len)
1668 char secret[MAXWORDLEN];
1669 char rhostname[256];
1671 u_char hash[MD5_DIGEST_LENGTH];
1672 int hashlen = MD5_DIGEST_LENGTH;
1673 #ifdef PPP_WITH_EAPTLS
1675 struct eaptls_session *ets = esp->es_client.ea_session;
1676 #endif /* PPP_WITH_EAPTLS */
1679 struct t_client *tc;
1680 struct t_num sval, gval, Nval, *Ap, Bval;
1683 u_char dig[SHA_DIGEST_LENGTH];
1684 int diglen = sizeof(dig);
1686 #endif /* PPP_WITH_SRP */
1689 * Ignore requests if we're not open
1691 if (esp->es_client.ea_state <= eapClosed)
1695 * Note: we update es_client.ea_id *only if* a Response
1696 * message is being generated. Otherwise, we leave it the
1697 * same for duplicate detection purposes.
1700 esp->es_client.ea_requests++;
1701 if (esp->es_client.ea_maxrequests != 0 &&
1702 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1703 info("EAP: received too many Request messages");
1704 if (esp->es_client.ea_timeout > 0) {
1705 UNTIMEOUT(eap_client_timeout, (void *)esp);
1707 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1712 error("EAP: empty Request message discarded");
1716 GETCHAR(typenum, inp);
1722 info("EAP: Identity prompt \"%.*q\"", len, inp);
1724 if (esp->es_usepseudo &&
1725 (esp->es_usedpseudo == 0 ||
1726 (esp->es_usedpseudo == 1 &&
1727 id == esp->es_client.ea_id))) {
1728 esp->es_usedpseudo = 1;
1729 /* Try to get a pseudonym */
1730 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1731 strcpy(rhostname, SRP_PSEUDO_ID);
1732 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1733 sizeof (rhostname) - SRP_PSEUDO_LEN);
1734 /* XXX NAI unsupported */
1736 eap_send_response(esp, id, typenum,
1737 rhostname, len + SRP_PSEUDO_LEN);
1744 /* Stop using pseudonym now. */
1745 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1747 esp->es_usedpseudo = 2;
1749 #endif /* PPP_WITH_SRP */
1750 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1751 esp->es_client.ea_namelen);
1754 case EAPT_NOTIFICATION:
1756 info("EAP: Notification \"%.*q\"", len, inp);
1757 eap_send_response(esp, id, typenum, NULL, 0);
1762 * Avoid the temptation to send Response Nak in reply
1763 * to Request Nak here. It can only lead to trouble.
1765 warn("EAP: unexpected Nak in Request; ignored");
1766 /* Return because we're waiting for something real. */
1771 error("EAP: received MD5-Challenge with no data");
1772 /* Bogus request; wait for something real. */
1775 GETCHAR(vallen, inp);
1777 if (vallen < 8 || vallen > len) {
1778 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1780 /* Try something better. */
1781 eap_send_nak(esp, id, EAPT_SRP);
1785 /* Not so likely to happen. */
1786 if (len - vallen >= sizeof (rhostname)) {
1787 dbglog("EAP: trimming really long peer name down");
1788 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1789 rhostname[sizeof (rhostname) - 1] = '\0';
1791 BCOPY(inp + vallen, rhostname, len - vallen);
1792 rhostname[len - vallen] = '\0';
1795 /* In case the remote doesn't give us his name. */
1796 if (explicit_remote ||
1797 (remote_name[0] != '\0' && vallen == len))
1798 strlcpy(rhostname, remote_name, sizeof (rhostname));
1801 * Get the secret for authenticating ourselves with
1802 * the specified host.
1804 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1805 rhostname, secret, &secret_len, 0)) {
1806 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1807 eap_send_nak(esp, id, EAPT_SRP);
1811 mdctx = PPP_MD_CTX_new();
1812 if (mdctx != NULL) {
1813 if (PPP_DigestInit(mdctx, PPP_md5())) {
1815 if (PPP_DigestUpdate(mdctx, &typenum, 1)) {
1816 if (PPP_DigestUpdate(mdctx, secret, secret_len)) {
1817 BZERO(secret, sizeof(secret));
1818 if (PPP_DigestUpdate(mdctx, inp, vallen)) {
1819 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
1820 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1821 esp->es_client.ea_namelen);
1822 PPP_MD_CTX_free(mdctx);
1829 PPP_MD_CTX_free(mdctx);
1831 dbglog("EAP: Invalid MD5 checksum");
1832 eap_send_nak(esp, id, EAPT_SRP);
1835 #ifdef PPP_WITH_EAPTLS
1838 switch(esp->es_client.ea_state) {
1843 error("EAP: received EAP-TLS Listen packet with no data");
1844 /* Bogus request; wait for something real. */
1847 GETCHAR(flags, inp);
1848 if(flags & EAP_TLS_FLAGS_START){
1850 esp->es_client.ea_using_eaptls = 1;
1852 if (explicit_remote){
1853 esp->es_client.ea_peer = strdup(remote_name);
1854 esp->es_client.ea_peerlen = strlen(remote_name);
1856 esp->es_client.ea_peer = NULL;
1858 /* Init ssl session */
1859 if(!eaptls_init_ssl_client(esp)) {
1860 dbglog("cannot init ssl");
1861 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1862 esp->es_client.ea_using_eaptls = 0;
1866 ets = esp->es_client.ea_session;
1867 eap_tls_response(esp, id);
1868 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1872 /* The server has sent a bad start packet. */
1873 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1877 eap_tls_response(esp, id);
1878 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1883 error("EAP: discarding EAP-TLS Receive packet with no data");
1884 /* Bogus request; wait for something real. */
1887 eaptls_receive(ets, inp, len);
1890 eap_tls_sendack(esp, id);
1891 esp->es_client.ea_state = eapTlsRecv;
1895 if(ets->alert_recv) {
1896 eap_tls_sendack(esp, id);
1897 esp->es_client.ea_state = eapTlsRecvFailure;
1901 /* Check if TLS handshake is finished */
1902 if(eaptls_is_init_finished(ets)) {
1903 #ifdef PPP_WITH_MPPE
1904 eaptls_gen_mppe_keys(ets, 1);
1906 eaptls_free_session(ets);
1907 eap_tls_sendack(esp, id);
1908 esp->es_client.ea_state = eapTlsRecvSuccess;
1912 eap_tls_response(esp,id);
1913 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1917 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1918 esp->es_client.ea_using_eaptls = 0;
1923 #endif /* PPP_WITH_EAPTLS */
1928 error("EAP: received empty SRP Request");
1929 /* Bogus request; wait for something real. */
1934 GETCHAR(vallen, inp);
1937 case EAPSRP_CHALLENGE:
1939 if (esp->es_client.ea_session != NULL) {
1940 tc = (struct t_client *)esp->es_client.
1943 * If this is a new challenge, then start
1944 * over with a new client session context.
1945 * Otherwise, just resend last response.
1947 if (id != esp->es_client.ea_id) {
1949 esp->es_client.ea_session = NULL;
1953 /* No session key just yet */
1954 esp->es_client.ea_skey = NULL;
1956 GETCHAR(vallen, inp);
1958 if (vallen >= len) {
1959 error("EAP: badly-formed SRP Challenge"
1961 /* Ignore badly-formed messages */
1964 BCOPY(inp, rhostname, vallen);
1965 rhostname[vallen] = '\0';
1966 INCPTR(vallen, inp);
1970 * In case the remote doesn't give us his name,
1971 * use configured name.
1973 if (explicit_remote ||
1974 (remote_name[0] != '\0' && vallen == 0)) {
1975 strlcpy(rhostname, remote_name,
1976 sizeof (rhostname));
1979 if (esp->es_client.ea_peer != NULL)
1980 free(esp->es_client.ea_peer);
1981 esp->es_client.ea_peer = strdup(rhostname);
1982 esp->es_client.ea_peerlen = strlen(rhostname);
1984 GETCHAR(vallen, inp);
1986 if (vallen >= len) {
1987 error("EAP: badly-formed SRP Challenge"
1989 /* Ignore badly-formed messages */
1994 INCPTR(vallen, inp);
1997 GETCHAR(vallen, inp);
2000 error("EAP: badly-formed SRP Challenge"
2002 /* Ignore badly-formed messages */
2005 /* If no generator present, then use value 2 */
2007 gval.data = (u_char *)"\002";
2013 INCPTR(vallen, inp);
2017 * If no modulus present, then use well-known
2021 Nval.data = (u_char *)wkmodulus;
2022 Nval.len = sizeof (wkmodulus);
2027 tc = t_clientopen(esp->es_client.ea_name,
2028 &Nval, &gval, &sval);
2030 eap_send_nak(esp, id, EAPT_MD5CHAP);
2033 esp->es_client.ea_session = (void *)tc;
2035 /* Add Challenge ID & type to verifier */
2038 t_clientaddexdata(tc, vals, 2);
2040 Ap = t_clientgenexp(tc);
2041 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2046 tc = (struct t_client *)esp->es_client.ea_session;
2048 warn("EAP: peer sent Subtype 2 without 1");
2049 eap_send_nak(esp, id, EAPT_MD5CHAP);
2052 if (esp->es_client.ea_skey != NULL) {
2054 * ID number should not change here. Warn
2055 * if it does (but otherwise ignore).
2057 if (id != esp->es_client.ea_id) {
2058 warn("EAP: ID changed from %d to %d "
2059 "in SRP Subtype 2 rexmit",
2060 esp->es_client.ea_id, id);
2063 if (get_srp_secret(esp->es_unit,
2064 esp->es_client.ea_name,
2065 esp->es_client.ea_peer, secret, 0) == 0) {
2067 * Can't work with this peer because
2068 * the secret is missing. Just give
2071 eap_send_nak(esp, id, EAPT_MD5CHAP);
2076 t_clientpasswd(tc, secret);
2077 BZERO(secret, sizeof (secret));
2078 esp->es_client.ea_skey =
2079 t_clientgetkey(tc, &Bval);
2080 if (esp->es_client.ea_skey == NULL) {
2081 /* Server is rogue; stop now */
2082 error("EAP: SRP server is rogue");
2083 goto client_failure;
2086 eap_srpval_response(esp, id, SRPVAL_EBIT,
2087 t_clientresponse(tc));
2090 case EAPSRP_SVALIDATOR:
2091 tc = (struct t_client *)esp->es_client.ea_session;
2092 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2093 warn("EAP: peer sent Subtype 3 without 1/2");
2094 eap_send_nak(esp, id, EAPT_MD5CHAP);
2098 * If we're already open, then this ought to be a
2099 * duplicate. Otherwise, check that the server is
2100 * who we think it is.
2102 if (esp->es_client.ea_state == eapOpen) {
2103 if (id != esp->es_client.ea_id) {
2104 warn("EAP: ID changed from %d to %d "
2105 "in SRP Subtype 3 rexmit",
2106 esp->es_client.ea_id, id);
2109 len -= sizeof (u_int32_t) + SHA_DIGEST_LENGTH;
2110 if (len < 0 || t_clientverify(tc, inp +
2111 sizeof (u_int32_t)) != 0) {
2112 error("EAP: SRP server verification "
2114 goto client_failure;
2116 GETLONG(esp->es_client.ea_keyflags, inp);
2117 /* Save pseudonym if user wants it. */
2118 if (len > 0 && esp->es_usepseudo) {
2119 INCPTR(SHA_DIGEST_LENGTH, inp);
2120 write_pseudonym(esp, inp, len, id);
2124 * We've verified our peer. We're now mostly done,
2125 * except for waiting on the regular EAP Success
2128 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2131 case EAPSRP_LWRECHALLENGE:
2133 warn("EAP: malformed Lightweight rechallenge");
2136 ctxt = PPP_MD_CTX_new();
2140 PPP_DigestInit(ctxt, PPP_sha1());
2141 PPP_DigestUpdate(ctxt, vals, 1);
2142 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
2144 PPP_DigestUpdate(ctxt, inp, len);
2145 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
2146 esp->es_client.ea_namelen);
2147 PPP_DigestFinal(ctxt, dig, &diglen);
2149 PPP_MD_CTX_free(ctxt);
2151 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2157 error("EAP: unknown SRP Subtype %d", vallen);
2158 eap_send_nak(esp, id, EAPT_MD5CHAP);
2162 #endif /* PPP_WITH_SRP */
2164 #ifdef PPP_WITH_CHAPMS
2167 error("EAP: received invalid MSCHAPv2 packet, too short");
2170 unsigned char opcode;
2171 GETCHAR(opcode, inp);
2172 unsigned char chapid; /* Chapv2-ID */
2173 GETCHAR(chapid, inp);
2175 GETSHORT(mssize, inp);
2177 /* Validate the mssize field */
2178 if (len != mssize) {
2179 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2184 /* If MSCHAPv2 digest was not found, NAK the packet */
2185 if (!esp->es_client.digest) {
2186 error("EAP MSCHAPv2 not supported");
2187 eap_send_nak(esp, id, EAPT_SRP);
2192 case CHAP_CHALLENGE: {
2194 /* make_response() expects: VLEN + VALUE */
2195 u_char *challenge = inp;
2197 unsigned char vsize;
2198 GETCHAR(vsize, inp);
2201 /* Validate the VALUE field */
2202 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2203 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2207 /* Increment past the VALUE field */
2208 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2209 len -= MS_CHAP2_PEER_CHAL_LEN;
2211 /* Extract the hostname */
2212 rhostname[0] = '\0';
2214 if (len >= sizeof (rhostname)) {
2215 dbglog("EAP: trimming really long peer name down");
2216 len = sizeof(rhostname) - 1;
2218 BCOPY(inp, rhostname, len);
2219 rhostname[len] = '\0';
2222 /* In case the remote doesn't give us his name. */
2223 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2224 strlcpy(rhostname, remote_name, sizeof(rhostname));
2226 /* Get the secret for authenticating ourselves with the specified host. */
2227 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2228 rhostname, secret, &secret_len, 0)) {
2229 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2230 eap_send_nak(esp, id, EAPT_SRP);
2233 esp->es_client.ea_namelen = strlen(esp->es_client.ea_name);
2235 /* Create the MSCHAPv2 response (and add to cache) */
2236 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2237 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2238 challenge, secret, secret_len, NULL);
2240 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2243 case CHAP_SUCCESS: {
2245 /* Check response for mutual authentication */
2246 u_char status = CHAP_FAILURE;
2247 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2248 info("Chap authentication succeeded! %.*v", len, inp);
2249 status = CHAP_SUCCESS;
2251 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2254 case CHAP_FAILURE: {
2256 /* Process the failure string, and log appropriate information */
2257 esp->es_client.digest->handle_failure(inp, len);
2259 u_char status = CHAP_FAILURE;
2260 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2261 goto client_failure; /* force termination */
2265 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2266 eap_send_nak(esp, id, EAPT_SRP);
2270 #endif /* PPP_WITH_CHAPMS */
2271 #ifdef PPP_WITH_PEAP
2274 /* Initialize the PEAP context (if not already initialized) */
2275 if (!esp->ea_peap) {
2276 rhostname[0] = '\0';
2277 if (explicit_remote || (remote_name[0] != '\0')) {
2278 strlcpy(rhostname, remote_name, sizeof (rhostname));
2280 if (peap_init(&esp->ea_peap, rhostname)) {
2281 eap_send_nak(esp, id, EAPT_TLS);
2286 /* Process the PEAP packet */
2287 if (peap_process(esp, id, inp, len)) {
2288 eap_send_nak(esp, id, EAPT_TLS);
2292 #endif // PPP_WITH_PEAP
2295 info("EAP: unknown authentication type %d; Naking", typenum);
2296 eap_send_nak(esp, id, EAPT_SRP);
2300 if (esp->es_client.ea_timeout > 0) {
2301 UNTIMEOUT(eap_client_timeout, (void *)esp);
2302 TIMEOUT(eap_client_timeout, (void *)esp,
2303 esp->es_client.ea_timeout);
2308 esp->es_client.ea_state = eapBadAuth;
2309 if (esp->es_client.ea_timeout > 0) {
2310 UNTIMEOUT(eap_client_timeout, (void *)esp);
2312 esp->es_client.ea_session = NULL;
2315 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2316 #endif /* PPP_WITH_SRP */
2320 * eap_response - Receive EAP Response message (server mode).
2323 eap_response(eap_state *esp, u_char *inp, int id, int len)
2328 char secret[MAXSECRETLEN];
2329 char rhostname[256];
2331 u_char hash[MD5_DIGEST_LENGTH];
2332 int hashlen = MD5_DIGEST_LENGTH;
2334 struct t_server *ts;
2337 u_char dig[SHA_DIGEST_LENGTH];
2338 int diglen = sizeof(dig);
2339 #endif /* PPP_WITH_SRP */
2341 #ifdef PPP_WITH_EAPTLS
2342 struct eaptls_session *ets;
2344 #endif /* PPP_WITH_EAPTLS */
2345 #ifdef PPP_WITH_CHAPMS
2347 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2348 unsigned char *, unsigned char *, char *, int);
2349 char response_message[256];
2350 #endif /* PPP_WITH_CHAPMS */
2353 * Ignore responses if we're not open
2355 if (esp->es_server.ea_state <= eapClosed)
2358 if (esp->es_server.ea_id != id) {
2359 dbglog("EAP: discarding Response %d; expected ID %d", id,
2360 esp->es_server.ea_id);
2364 esp->es_server.ea_responses++;
2367 error("EAP: empty Response message discarded");
2371 GETCHAR(typenum, inp);
2376 if (esp->es_server.ea_state != eapIdentify) {
2377 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2381 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2382 if (esp->es_server.ea_peer != NULL &&
2383 esp->es_server.ea_peer != remote_name)
2384 free(esp->es_server.ea_peer);
2385 esp->es_server.ea_peer = malloc(len + 1);
2386 if (esp->es_server.ea_peer == NULL) {
2387 esp->es_server.ea_peerlen = 0;
2388 eap_figure_next_state(esp, 1);
2391 BCOPY(inp, esp->es_server.ea_peer, len);
2392 esp->es_server.ea_peer[len] = '\0';
2393 esp->es_server.ea_peerlen = len;
2394 eap_figure_next_state(esp, 0);
2397 #ifdef PPP_WITH_EAPTLS
2399 switch(esp->es_server.ea_state) {
2403 ets = (struct eaptls_session *) esp->es_server.ea_session;
2405 eap_figure_next_state(esp,
2406 eaptls_receive(esp->es_server.ea_session, inp, len));
2408 if(ets->alert_recv) {
2409 eap_send_failure(esp);
2416 dbglog("EAP-TLS ACK with extra data");
2418 eap_figure_next_state(esp, 0);
2421 case eapTlsRecvClient:
2422 /* Receive authentication response from client */
2424 GETCHAR(flags, inp);
2426 if(len == 1 && !flags) { /* Ack = ok */
2427 #ifdef PPP_WITH_MPPE
2428 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2430 eap_send_success(esp);
2432 else { /* failure */
2433 warn("Server authentication failed");
2434 eap_send_failure(esp);
2438 warn("Bogus EAP-TLS packet received from client");
2440 eaptls_free_session(esp->es_server.ea_session);
2444 case eapTlsRecvAlertAck:
2445 eap_send_failure(esp);
2449 eap_figure_next_state(esp, 1);
2453 #endif /* PPP_WITH_EAPTLS */
2455 case EAPT_NOTIFICATION:
2456 dbglog("EAP unexpected Notification; response discarded");
2461 info("EAP: Nak Response with no suggested protocol");
2462 eap_figure_next_state(esp, 1);
2466 GETCHAR(vallen, inp);
2469 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2470 /* Peer cannot Nak Identify Request */
2471 eap_figure_next_state(esp, 1);
2477 /* Run through SRP validator selection again. */
2478 esp->es_server.ea_state = eapIdentify;
2479 eap_figure_next_state(esp, 0);
2483 esp->es_server.ea_state = eapMD5Chall;
2486 #ifdef PPP_WITH_EAPTLS
2487 /* Send EAP-TLS start packet */
2489 esp->es_server.ea_state = eapTlsStart;
2491 #endif /* PPP_WITH_EAPTLS */
2493 #ifdef PPP_WITH_CHAPMS
2495 info("EAP: peer proposes MSCHAPv2");
2496 /* If MSCHAPv2 digest was not found, NAK the packet */
2497 if (!esp->es_server.digest) {
2498 error("EAP MSCHAPv2 not supported");
2499 eap_send_nak(esp, id, EAPT_SRP);
2502 esp->es_server.ea_state = eapMSCHAPv2Chall;
2504 #endif /* PPP_WITH_CHAPMS */
2507 dbglog("EAP: peer requesting unknown Type %d", vallen);
2508 switch (esp->es_server.ea_state) {
2512 esp->es_server.ea_state = eapMD5Chall;
2516 esp->es_server.ea_state = eapIdentify;
2517 eap_figure_next_state(esp, 0);
2527 if (esp->es_server.ea_state != eapMD5Chall) {
2528 error("EAP: unexpected MD5-Response");
2529 eap_figure_next_state(esp, 1);
2533 error("EAP: received MD5-Response with no data");
2534 eap_figure_next_state(esp, 1);
2537 GETCHAR(vallen, inp);
2539 if (vallen != 16 || vallen > len) {
2540 error("EAP: MD5-Response with bad length %d", vallen);
2541 eap_figure_next_state(esp, 1);
2545 /* Not so likely to happen. */
2546 if (len - vallen >= sizeof (rhostname)) {
2547 dbglog("EAP: trimming really long peer name down");
2548 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2549 rhostname[sizeof (rhostname) - 1] = '\0';
2551 BCOPY(inp + vallen, rhostname, len - vallen);
2552 rhostname[len - vallen] = '\0';
2555 /* In case the remote doesn't give us his name. */
2556 if (explicit_remote ||
2557 (remote_name[0] != '\0' && vallen == len))
2558 strlcpy(rhostname, remote_name, sizeof (rhostname));
2561 * Get the secret for authenticating the specified
2564 if (!get_secret(esp->es_unit, rhostname,
2565 esp->es_server.ea_name, secret, &secret_len, 1)) {
2566 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2567 eap_send_failure(esp);
2571 mdctx = PPP_MD_CTX_new();
2572 if (mdctx != NULL) {
2574 if (PPP_DigestInit(mdctx, PPP_md5())) {
2576 if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
2578 if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
2580 BZERO(secret, sizeof(secret));
2581 if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
2583 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
2585 if (BCMP(hash, inp, MD5_DIGEST_LENGTH) == 0) {
2586 esp->es_server.ea_type = EAPT_MD5CHAP;
2587 eap_send_success(esp);
2588 eap_figure_next_state(esp, 0);
2590 if (esp->es_rechallenge != 0) {
2591 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2593 PPP_MD_CTX_free(mdctx);
2602 PPP_MD_CTX_free(mdctx);
2605 eap_send_failure(esp);
2608 #ifdef PPP_WITH_CHAPMS
2611 error("EAP: received MSCHAPv2 with no data");
2612 eap_figure_next_state(esp, 1);
2615 GETCHAR(opcode, inp);
2620 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2621 error("EAP: unexpected MSCHAPv2-Response");
2622 eap_figure_next_state(esp, 1);
2625 /* skip MS ID + len */
2627 GETCHAR(vallen, inp);
2630 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2631 error("EAP: Invalid MSCHAPv2-Response "
2632 "length %d", vallen);
2633 eap_figure_next_state(esp, 1);
2637 /* Not so likely to happen. */
2638 if (len - vallen >= sizeof (rhostname)) {
2639 dbglog("EAP: trimming really long peer name down");
2640 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2641 rhostname[sizeof (rhostname) - 1] = '\0';
2643 BCOPY(inp + vallen, rhostname, len - vallen);
2644 rhostname[len - vallen] = '\0';
2647 /* In case the remote doesn't give us his name. */
2648 if (explicit_remote ||
2649 (remote_name[0] != '\0' && vallen == len))
2650 strlcpy(rhostname, remote_name, sizeof (rhostname));
2652 /* strip the MS domain name */
2653 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2654 char tmp[MAXNAMELEN+1];
2656 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2657 strcpy(rhostname, tmp);
2660 if (chap_verify_hook)
2661 chap_verifier = chap_verify_hook;
2663 chap_verifier = eap_chap_verify_response;
2665 esp->es_server.ea_id += 1;
2666 if ((*chap_verifier)(rhostname,
2667 esp->es_server.ea_name,
2669 esp->es_server.digest,
2673 sizeof(response_message)))
2675 info("EAP: MSCHAPv2 success for peer %q",
2677 esp->es_server.ea_type = EAPT_MSCHAPV2;
2678 eap_chapms2_send_request(esp,
2679 esp->es_server.ea_id,
2681 esp->es_server.ea_id,
2683 strlen(response_message));
2684 eap_figure_next_state(esp, 0);
2685 if (esp->es_rechallenge != 0)
2686 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2689 warn("EAP: MSCHAPv2 failure for peer %q",
2691 eap_chapms2_send_request(esp,
2692 esp->es_server.ea_id,
2694 esp->es_server.ea_id,
2696 strlen(response_message));
2700 info("EAP: MSCHAPv2 success confirmed");
2703 info("EAP: MSCHAPv2 failure confirmed");
2706 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2707 eap_send_nak(esp, id, EAPT_SRP);
2711 #endif /* PPP_WITH_CHAPMS */
2716 error("EAP: empty SRP Response");
2717 eap_figure_next_state(esp, 1);
2720 GETCHAR(typenum, inp);
2724 if (esp->es_server.ea_state != eapSRP1) {
2725 error("EAP: unexpected SRP Subtype 1 Response");
2726 eap_figure_next_state(esp, 1);
2731 ts = (struct t_server *)esp->es_server.ea_session;
2733 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2734 if (esp->es_server.ea_skey == NULL) {
2735 /* Client's A value is bogus; terminate now */
2736 error("EAP: bogus A value from client");
2737 eap_send_failure(esp);
2739 eap_figure_next_state(esp, 0);
2743 case EAPSRP_CVALIDATOR:
2744 if (esp->es_server.ea_state != eapSRP2) {
2745 error("EAP: unexpected SRP Subtype 2 Response");
2746 eap_figure_next_state(esp, 1);
2749 if (len < sizeof (u_int32_t) + SHA_DIGEST_LENGTH) {
2750 error("EAP: M1 length %d < %d", len,
2751 sizeof (u_int32_t) + SHA_DIGEST_LENGTH);
2752 eap_figure_next_state(esp, 1);
2755 GETLONG(esp->es_server.ea_keyflags, inp);
2756 ts = (struct t_server *)esp->es_server.ea_session;
2758 if (t_serververify(ts, inp)) {
2759 info("EAP: unable to validate client identity");
2760 eap_send_failure(esp);
2763 eap_figure_next_state(esp, 0);
2767 if (esp->es_server.ea_state != eapSRP3) {
2768 error("EAP: unexpected SRP Subtype 3 Response");
2769 eap_send_failure(esp);
2772 esp->es_server.ea_type = EAPT_SRP;
2773 eap_send_success(esp);
2774 eap_figure_next_state(esp, 0);
2775 if (esp->es_rechallenge != 0)
2776 TIMEOUT(eap_rechallenge, esp,
2777 esp->es_rechallenge);
2778 if (esp->es_lwrechallenge != 0)
2779 TIMEOUT(srp_lwrechallenge, esp,
2780 esp->es_lwrechallenge);
2783 case EAPSRP_LWRECHALLENGE:
2784 if (esp->es_server.ea_state != eapSRP4) {
2785 info("EAP: unexpected SRP Subtype 4 Response");
2788 if (len != SHA_DIGEST_LENGTH) {
2789 error("EAP: bad Lightweight rechallenge "
2793 ctxt = PPP_MD_CTX_new();
2797 PPP_DigestInit(ctxt, PPP_sha1());
2798 PPP_DigestUpdate(ctxt, &vallen, 1);
2799 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
2801 PPP_DigestUpdate(ctxt, esp->es_challenge, esp->es_challen);
2802 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
2803 esp->es_server.ea_peerlen);
2804 PPP_DigestFinal(ctxt, dig, &diglen);
2806 PPP_MD_CTX_free(ctxt);
2808 if (BCMP(dig, inp, SHA_DIGEST_LENGTH) != 0) {
2809 error("EAP: failed Lightweight rechallenge");
2810 eap_send_failure(esp);
2814 esp->es_server.ea_state = eapOpen;
2815 if (esp->es_lwrechallenge != 0)
2816 TIMEOUT(srp_lwrechallenge, esp,
2817 esp->es_lwrechallenge);
2822 #endif /* PPP_WITH_SRP */
2825 /* This can't happen. */
2826 error("EAP: unknown Response type %d; ignored", typenum);
2830 if (esp->es_server.ea_timeout > 0) {
2831 UNTIMEOUT(eap_server_timeout, (void *)esp);
2834 if (esp->es_server.ea_state != eapBadAuth &&
2835 esp->es_server.ea_state != eapOpen) {
2836 esp->es_server.ea_id++;
2837 eap_send_request(esp);
2842 * eap_success - Receive EAP Success message (client mode).
2845 eap_success(eap_state *esp, u_char *inp, int id, int len)
2847 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2848 #ifdef PPP_WITH_EAPTLS
2849 && esp->es_client.ea_state != eapTlsRecvSuccess
2850 #endif /* PPP_WITH_EAPTLS */
2852 dbglog("EAP unexpected success message in state %s (%d)",
2853 eap_state_name(esp->es_client.ea_state),
2854 esp->es_client.ea_state);
2858 #ifdef PPP_WITH_EAPTLS
2859 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2860 eapTlsRecvSuccess) {
2861 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2862 eap_state_name(esp->es_client.ea_state),
2863 esp->es_client.ea_state);
2866 #endif /* PPP_WITH_EAPTLS */
2868 if (esp->es_client.ea_timeout > 0) {
2869 UNTIMEOUT(eap_client_timeout, (void *)esp);
2873 /* This is odd. The spec doesn't allow for this. */
2877 #ifdef PPP_WITH_PEAP
2878 peap_finish(&esp->ea_peap);
2881 esp->es_client.ea_state = eapOpen;
2882 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2886 * eap_failure - Receive EAP Failure message (client mode).
2889 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2892 * Ignore failure messages if we're not open
2894 if (esp->es_client.ea_state <= eapClosed)
2897 if (!eap_client_active(esp)) {
2898 dbglog("EAP unexpected failure message in state %s (%d)",
2899 eap_state_name(esp->es_client.ea_state),
2900 esp->es_client.ea_state);
2903 if (esp->es_client.ea_timeout > 0) {
2904 UNTIMEOUT(eap_client_timeout, (void *)esp);
2908 /* This is odd. The spec doesn't allow for this. */
2912 esp->es_client.ea_state = eapBadAuth;
2914 error("EAP: peer reports authentication failure");
2916 #ifdef PPP_WITH_PEAP
2917 peap_finish(&esp->ea_peap);
2920 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2924 * eap_input - Handle received EAP message.
2927 eap_input(int unit, u_char *inp, int inlen)
2929 eap_state *esp = &eap_states[unit];
2934 * Parse header (code, id and length). If packet too short,
2937 if (inlen < EAP_HEADERLEN) {
2938 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2944 if (len < EAP_HEADERLEN || len > inlen) {
2945 error("EAP: packet has illegal length field %d (%d..%d)", len,
2946 EAP_HEADERLEN, inlen);
2949 len -= EAP_HEADERLEN;
2951 /* Dispatch based on message code */
2954 eap_request(esp, inp, id, len);
2958 eap_response(esp, inp, id, len);
2962 eap_success(esp, inp, id, len);
2966 eap_failure(esp, inp, id, len);
2969 default: /* XXX Need code reject */
2970 /* Note: it's not legal to send EAP Nak here. */
2971 warn("EAP: unknown code %d received", code);
2977 * eap_printpkt - print the contents of an EAP packet.
2979 static char *eap_codenames[] = {
2980 "Request", "Response", "Success", "Failure"
2983 static char *eap_typenames[] = {
2984 "Identity", "Notification", "Nak", "MD5-Challenge",
2985 "OTP", "Generic-Token", NULL, NULL,
2986 "RSA", "DSS", "KEA", "KEA-Validate",
2987 "TLS", "Defender", "Windows 2000", "Arcot",
2988 "Cisco", "Nokia", "SRP", NULL,
2989 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2994 eap_printpkt(u_char *inp, int inlen,
2995 void (*printer) (void *, char *, ...), void *arg)
2997 int code, id, len, rtype, vallen;
3000 #ifdef PPP_WITH_EAPTLS
3002 #endif /* PPP_WITH_EAPTLS */
3003 #ifdef PPP_WITH_CHAPMS
3005 #endif /* PPP_WITH_CHAPMS */
3007 if (inlen < EAP_HEADERLEN)
3013 if (len < EAP_HEADERLEN || len > inlen)
3016 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
3017 printer(arg, " %s", eap_codenames[code-1]);
3019 printer(arg, " code=0x%x", code);
3020 printer(arg, " id=0x%x", id);
3021 len -= EAP_HEADERLEN;
3025 printer(arg, " <missing type>");
3028 GETCHAR(rtype, inp);
3031 rtype <= sizeof (eap_typenames) / sizeof (char *))
3032 printer(arg, " %s", eap_typenames[rtype-1]);
3034 printer(arg, " type=0x%x", rtype);
3037 case EAPT_NOTIFICATION:
3039 printer(arg, " <Message ");
3040 print_string((char *)inp, len, printer, arg);
3045 printer(arg, " <No message>");
3052 GETCHAR(vallen, inp);
3056 printer(arg, " <Value%.*B>", vallen, inp);
3057 INCPTR(vallen, inp);
3060 printer(arg, " <Name ");
3061 print_string((char *)inp, len, printer, arg);
3066 printer(arg, " <No name>");
3070 #ifdef PPP_WITH_CHAPMS
3074 GETCHAR(opcode, inp);
3077 case CHAP_CHALLENGE:
3080 GETCHAR(vallen, inp);
3085 printer(arg, " Challenge <");
3086 for (; vallen > 0; --vallen) {
3089 printer(arg, "%.2x", val);
3093 printer(arg, ", <Name ");
3094 print_string((char *)inp, len, printer, arg);
3099 printer(arg, ", <No name>");
3105 printer(arg, " Success <Message ");
3106 print_string((char *)inp, len, printer, arg);
3112 printer(arg, " Failure <Message ");
3113 print_string((char *)inp, len, printer, arg);
3119 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3123 #endif /* PPP_WITH_CHAPMS */
3125 #ifdef PPP_WITH_EAPTLS
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":"- ");
3141 #endif /* PPP_WITH_EAPTLS */
3147 GETCHAR(vallen, inp);
3149 printer(arg, "-%d", vallen);
3151 case EAPSRP_CHALLENGE:
3152 GETCHAR(vallen, inp);
3157 printer(arg, " <Name ");
3158 print_string((char *)inp, vallen, printer,
3162 printer(arg, " <No name>");
3164 INCPTR(vallen, inp);
3166 GETCHAR(vallen, inp);
3170 printer(arg, " <s%.*B>", vallen, inp);
3171 INCPTR(vallen, inp);
3173 GETCHAR(vallen, inp);
3178 printer(arg, " <Default g=2>");
3180 printer(arg, " <g%.*B>", vallen, inp);
3182 INCPTR(vallen, inp);
3185 printer(arg, " <Default N>");
3187 printer(arg, " <N%.*B>", len, inp);
3194 printer(arg, " <B%.*B>", len, inp);
3199 case EAPSRP_SVALIDATOR:
3200 if (len < sizeof (u_int32_t))
3203 len -= sizeof (u_int32_t);
3204 if (uval & SRPVAL_EBIT) {
3206 uval &= ~SRPVAL_EBIT;
3209 printer(arg, " f<%X>", uval);
3211 if ((vallen = len) > SHA_DIGEST_LENGTH)
3212 vallen = SHA_DIGEST_LENGTH;
3213 printer(arg, " <M2%.*B%s>", len, inp,
3214 len < SHA_DIGEST_LENGTH ? "?" : "");
3215 INCPTR(vallen, inp);
3218 printer(arg, " <PN%.*B>", len, inp);
3224 case EAPSRP_LWRECHALLENGE:
3225 printer(arg, " <Challenge%.*B>", len, inp);
3231 #endif /* PPP_WITH_SRP */
3238 GETCHAR(rtype, inp);
3241 rtype <= sizeof (eap_typenames) / sizeof (char *))
3242 printer(arg, " %s", eap_typenames[rtype-1]);
3244 printer(arg, " type=0x%x", rtype);
3248 printer(arg, " <Name ");
3249 print_string((char *)inp, len, printer, arg);
3256 #ifdef PPP_WITH_EAPTLS
3260 GETCHAR(flags, inp);
3263 if(flags == 0 && len == 0){
3264 printer(arg, " Ack");
3268 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3269 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3270 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3273 #endif /* PPP_WITH_EAPTLS */
3277 printer(arg, " <missing hint>");
3280 GETCHAR(rtype, inp);
3282 printer(arg, " <Suggested-type %02X", rtype);
3284 rtype <= sizeof (eap_typenames) / sizeof (char *))
3285 printer(arg, " (%s)", eap_typenames[rtype-1]);
3291 printer(arg, " <missing length>");
3294 GETCHAR(vallen, inp);
3298 printer(arg, " <Value%.*B>", vallen, inp);
3299 INCPTR(vallen, inp);
3302 printer(arg, " <Name ");
3303 print_string((char *)inp, len, printer, arg);
3308 printer(arg, " <No name>");
3312 #ifdef PPP_WITH_CHAPMS
3316 GETCHAR(opcode, inp);
3322 GETCHAR(vallen, inp);
3327 printer(arg, " Response <");
3328 for (; vallen > 0; --vallen) {
3331 printer(arg, "%.2x", val);
3335 printer(arg, ", <Name ");
3336 print_string((char *)inp, len, printer, arg);
3341 printer(arg, ", <No name>");
3345 printer(arg, " Success");
3348 printer(arg, " Failure");
3351 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3355 #endif /* PPP_WITH_CHAPMS */
3361 GETCHAR(vallen, inp);
3363 printer(arg, "-%d", vallen);
3366 printer(arg, " <A%.*B>", len, inp);
3371 case EAPSRP_CVALIDATOR:
3372 if (len < sizeof (u_int32_t))
3375 len -= sizeof (u_int32_t);
3376 if (uval & SRPVAL_EBIT) {
3378 uval &= ~SRPVAL_EBIT;
3381 printer(arg, " f<%X>", uval);
3383 printer(arg, " <M1%.*B%s>", len, inp,
3384 len == SHA_DIGEST_LENGTH ? "" : "?");
3392 case EAPSRP_LWRECHALLENGE:
3393 printer(arg, " <Response%.*B%s>", len, inp,
3394 len == SHA_DIGEST_LENGTH ? "" : "?");
3395 if ((vallen = len) > SHA_DIGEST_LENGTH)
3396 vallen = SHA_DIGEST_LENGTH;
3397 INCPTR(vallen, inp);
3402 #endif /* PPP_WITH_SRP */
3406 case EAP_SUCCESS: /* No payload expected for these! */
3411 printer(arg, " <truncated>");
3416 printer(arg, "%8B...", inp);
3418 printer(arg, "%.*B", len, inp);
3421 return (inp - pstart);