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"
72 #endif /* PPP_WITH_PEAP */
81 #endif /* PPP_WITH_SRP */
83 #ifndef SHA_DIGESTSIZE
84 #define SHA_DIGESTSIZE 20
87 #ifdef PPP_WITH_EAPTLS
89 #endif /* PPP_WITH_EAPTLS */
91 #ifdef PPP_WITH_CHAPMS
95 extern int chapms_strip_domain;
96 #endif /* PPP_WITH_CHAPMS */
98 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
100 static char *pn_secret = NULL; /* Pseudonym generating secret */
104 * Command-line options.
106 static option_t eap_option_list[] = {
107 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
108 "Set retransmit timeout for EAP Requests (server)" },
109 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
110 "Set max number of EAP Requests sent (server)" },
111 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
112 "Set time limit for peer EAP authentication" },
113 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
114 "Set max number of EAP Requests allows (client)" },
115 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
116 "Set interval for EAP rechallenge" },
118 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
119 "Set interval for SRP lightweight rechallenge" },
120 { "srp-pn-secret", o_string, &pn_secret,
121 "Long term pseudonym generation secret" },
122 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
123 "Use pseudonym if offered one by server", 1 },
129 * Protocol entry points.
131 static void eap_init (int unit);
132 static void eap_input (int unit, u_char *inp, int inlen);
133 static void eap_protrej (int unit);
134 static void eap_lowerup (int unit);
135 static void eap_lowerdown (int unit);
136 static int eap_printpkt (u_char *inp, int inlen,
137 void (*)(void *arg, char *fmt, ...), void *arg);
139 struct protent eap_protent = {
140 PPP_EAP, /* protocol number */
141 eap_init, /* initialization procedure */
142 eap_input, /* process a received packet */
143 eap_protrej, /* process a received protocol-reject */
144 eap_lowerup, /* lower layer has gone up */
145 eap_lowerdown, /* lower layer has gone down */
146 NULL, /* open the protocol */
147 NULL, /* close the protocol */
148 eap_printpkt, /* print a packet in readable form */
149 NULL, /* process a received data packet */
150 1, /* protocol enabled */
151 "EAP", /* text name of protocol */
152 NULL, /* text name of corresponding data protocol */
153 eap_option_list, /* list of command-line options */
154 NULL, /* check requested options; assign defaults */
155 NULL, /* configure interface for demand-dial */
156 NULL /* say whether to bring up link for this pkt */
161 * A well-known 2048 bit modulus.
163 static const u_char wkmodulus[] = {
164 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
165 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
166 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
167 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
168 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
169 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
170 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
171 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
172 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
173 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
174 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
175 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
176 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
177 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
178 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
179 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
180 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
181 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
182 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
183 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
184 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
185 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
186 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
187 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
188 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
189 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
190 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
191 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
192 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
193 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
194 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
195 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
197 #endif /* PPP_WITH_SRP */
199 /* Local forward declarations. */
200 static void eap_server_timeout (void *arg);
203 * Convert EAP state code to printable string for debug.
206 eap_state_name(enum eap_state_code esc)
208 static const char *state_names[] = { EAP_STATES };
210 return (state_names[(int)esc]);
214 * eap_init - Initialize state for an EAP user. This is currently
215 * called once by main() during start-up.
220 eap_state *esp = &eap_states[unit];
222 BZERO(esp, sizeof (*esp));
224 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
225 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
226 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
227 esp->es_client.ea_timeout = EAP_DEFREQTIME;
228 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
229 #ifdef PPP_WITH_EAPTLS
230 esp->es_client.ea_using_eaptls = 0;
231 #endif /* PPP_WITH_EAPTLS */
232 #ifdef PPP_WITH_CHAPMS
233 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
234 esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
239 * eap_client_timeout - Give up waiting for the peer to send any
243 eap_client_timeout(void *arg)
245 eap_state *esp = (eap_state *) arg;
247 if (!eap_client_active(esp))
250 error("EAP: timeout waiting for Request from peer");
251 auth_withpeer_fail(esp->es_unit, PPP_EAP);
252 esp->es_client.ea_state = eapBadAuth;
256 * eap_authwithpeer - Authenticate to our peer (behave as client).
258 * Start client state and wait for requests. This is called only
262 eap_authwithpeer(int unit, char *localname)
264 eap_state *esp = &eap_states[unit];
266 /* Save the peer name we're given */
267 esp->es_client.ea_name = localname;
268 esp->es_client.ea_namelen = strlen(localname);
270 esp->es_client.ea_state = eapListen;
273 * Start a timer so that if the other end just goes
274 * silent, we don't sit here waiting forever.
276 if (esp->es_client.ea_timeout > 0)
277 TIMEOUT(eap_client_timeout, (void *)esp,
278 esp->es_client.ea_timeout);
282 * Format a standard EAP Failure message and send it to the peer.
286 eap_send_failure(eap_state *esp)
290 outp = outpacket_buf;
292 MAKEHEADER(outp, PPP_EAP);
294 PUTCHAR(EAP_FAILURE, outp);
295 esp->es_server.ea_id++;
296 PUTCHAR(esp->es_server.ea_id, outp);
297 PUTSHORT(EAP_HEADERLEN, outp);
299 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
301 esp->es_server.ea_state = eapBadAuth;
302 auth_peer_fail(esp->es_unit, PPP_EAP);
306 * Format a standard EAP Success message and send it to the peer.
310 eap_send_success(eap_state *esp)
314 outp = outpacket_buf;
316 MAKEHEADER(outp, PPP_EAP);
318 PUTCHAR(EAP_SUCCESS, outp);
319 esp->es_server.ea_id++;
320 PUTCHAR(esp->es_server.ea_id, outp);
321 PUTSHORT(EAP_HEADERLEN, outp);
323 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
325 auth_peer_success(esp->es_unit, PPP_EAP, 0,
326 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
331 * Set DES key according to pseudonym-generating secret and current
335 pncrypt_setkey(int timeoffs)
340 u_char dig[SHA_DIGESTSIZE];
341 int diglen = sizeof(dig);
344 if (pn_secret == NULL)
346 reftime = time(NULL) + timeoffs;
347 tp = localtime(&reftime);
348 ctxt = PPP_MD_CTX_new();
351 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
353 PPP_DigestInit(ctxt, PPP_sha1());
354 PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
355 PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
356 PPP_DigestFinal(ctxt, dig, &diglen);
358 PPP_MD_CTX_free(ctxt);
359 return (DesSetkey(dig));
365 static char base64[] =
366 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
374 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
379 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
382 if (bs->bs_offs >= 24) {
383 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
384 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
385 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
386 *outp++ = base64[bs->bs_bits & 0x3F];
396 b64flush(struct b64state *bs, u_char *outp)
400 if (bs->bs_offs == 8) {
401 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
402 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
404 } else if (bs->bs_offs == 16) {
405 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
406 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
407 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
416 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
422 if ((cp = strchr(base64, *inp++)) == NULL)
424 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
427 if (bs->bs_offs >= 8) {
428 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
435 #endif /* PPP_WITH_SRP */
438 * Assume that current waiting server state is complete and figure
439 * next state to use based on available authentication data. 'status'
440 * indicates if there was an error in handling the last query. It is
441 * 0 for success and non-zero for failure.
444 eap_figure_next_state(eap_state *esp, int status)
447 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
449 struct t_confent *tce, mytce;
452 int id, i, plen, toffs;
455 #endif /* PPP_WITH_SRP */
456 #ifdef PPP_WITH_EAPTLS
457 struct eaptls_session *ets;
459 char secret[MAXWORDLEN];
460 #endif /* PPP_WITH_EAPTLS */
462 esp->es_server.ea_timeout = esp->es_savedtime;
463 #ifdef PPP_WITH_EAPTLS
464 esp->es_server.ea_prev_state = esp->es_server.ea_state;
465 #endif /* PPP_WITH_EAPTLS */
466 switch (esp->es_server.ea_state) {
472 /* Discard any previous session. */
473 ts = (struct t_server *)esp->es_server.ea_session;
476 esp->es_server.ea_session = NULL;
477 esp->es_server.ea_skey = NULL;
479 #endif /* PPP_WITH_SRP */
481 esp->es_server.ea_state = eapBadAuth;
485 /* If we've got a pseudonym, try to decode to real name. */
486 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
487 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
488 SRP_PSEUDO_LEN) == 0 &&
489 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
491 BZERO(&bs, sizeof (bs));
493 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
494 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
497 for (i = 0; i < 5; i++) {
498 pncrypt_setkey(toffs);
500 if (!DesDecrypt(secbuf, clear)) {
501 dbglog("no DES here; cannot decode "
505 id = *(unsigned char *)clear;
506 if (id + 1 <= plen && id + 9 > plen)
509 if (plen % 8 == 0 && i < 5) {
511 * Note that this is always shorter than the
512 * original stored string, so there's no need
515 if ((i = plen = *(unsigned char *)clear) > 7)
517 esp->es_server.ea_peerlen = plen;
518 dp = (unsigned char *)esp->es_server.ea_peer;
519 BCOPY(clear + 1, dp, i);
524 (void) DesDecrypt(sp, dp);
529 esp->es_server.ea_peer[
530 esp->es_server.ea_peerlen] = '\0';
531 dbglog("decoded pseudonym to \"%.*q\"",
532 esp->es_server.ea_peerlen,
533 esp->es_server.ea_peer);
535 dbglog("failed to decode real name");
536 /* Stay in eapIdentfy state; requery */
540 /* Look up user in secrets database. */
541 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
542 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
543 /* Set up default in case SRP entry is bad */
544 esp->es_server.ea_state = eapMD5Chall;
545 /* Get t_confent based on index in srp-secrets */
546 id = strtol((char *)secbuf, &cp, 10);
547 if (*cp++ != ':' || id < 0)
551 mytce.modulus.data = (u_char *)wkmodulus;
552 mytce.modulus.len = sizeof (wkmodulus);
553 mytce.generator.data = (u_char *)"\002";
554 mytce.generator.len = 1;
556 } else if ((tce = gettcid(id)) != NULL) {
558 * Client will have to verify this modulus/
559 * generator combination, and that will take
560 * a while. Lengthen the timeout here.
562 if (esp->es_server.ea_timeout > 0 &&
563 esp->es_server.ea_timeout < 30)
564 esp->es_server.ea_timeout = 30;
568 if ((cp2 = strchr(cp, ':')) == NULL)
571 tpw.pebuf.name = esp->es_server.ea_peer;
572 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
574 tpw.pebuf.password.data = (char*) tpw.pwbuf;
575 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
577 tpw.pebuf.salt.data = tpw.saltbuf;
578 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
580 esp->es_server.ea_session = (void *)ts;
581 esp->es_server.ea_state = eapSRP1;
582 vals[0] = esp->es_server.ea_id + 1;
584 t_serveraddexdata(ts, vals, 2);
585 /* Generate B; must call before t_servergetkey() */
589 #endif /* PPP_WITH_SRP */
590 #ifdef PPP_WITH_EAPTLS
591 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
592 esp->es_server.ea_name, secret, &secret_len, 1)) {
594 esp->es_server.ea_state = eapTlsStart;
597 #endif /* PPP_WITH_EAPTLS */
599 esp->es_server.ea_state = eapMD5Chall;
602 #ifdef PPP_WITH_EAPTLS
604 /* Initialize ssl session */
605 if(!eaptls_init_ssl_server(esp)) {
606 esp->es_server.ea_state = eapBadAuth;
610 esp->es_server.ea_state = eapTlsRecv;
614 ets = (struct eaptls_session *) esp->es_server.ea_session;
616 if(ets->alert_sent) {
617 esp->es_server.ea_state = eapTlsSendAlert;
622 esp->es_server.ea_state = eapBadAuth;
625 ets = (struct eaptls_session *) esp->es_server.ea_session;
628 esp->es_server.ea_state = eapTlsSendAck;
630 esp->es_server.ea_state = eapTlsSend;
634 ets = (struct eaptls_session *) esp->es_server.ea_session;
637 esp->es_server.ea_state = eapTlsRecvAck;
639 if(SSL_is_init_finished(ets->ssl))
640 esp->es_server.ea_state = eapTlsRecvClient;
642 /* JJK Add "TLS empty record" message here ??? */
643 esp->es_server.ea_state = eapTlsRecv;
647 esp->es_server.ea_state = eapTlsRecv;
653 esp->es_server.ea_state = eapBadAuth;
657 esp->es_server.ea_state = eapTlsSend;
660 case eapTlsSendAlert:
661 esp->es_server.ea_state = eapTlsRecvAlertAck;
663 #endif /* PPP_WITH_EAPTLS */
667 ts = (struct t_server *)esp->es_server.ea_session;
668 if (ts != NULL && status != 0) {
670 esp->es_server.ea_session = NULL;
671 esp->es_server.ea_skey = NULL;
673 #endif /* PPP_WITH_SRP */
675 esp->es_server.ea_state = eapMD5Chall;
676 } else if (status != 0 || esp->es_server.ea_session == NULL) {
677 esp->es_server.ea_state = eapBadAuth;
679 esp->es_server.ea_state = eapSRP2;
685 ts = (struct t_server *)esp->es_server.ea_session;
686 if (ts != NULL && status != 0) {
688 esp->es_server.ea_session = NULL;
689 esp->es_server.ea_skey = NULL;
691 #endif /* PPP_WITH_SRP */
692 if (status != 0 || esp->es_server.ea_session == NULL) {
693 esp->es_server.ea_state = eapBadAuth;
695 esp->es_server.ea_state = eapSRP3;
702 ts = (struct t_server *)esp->es_server.ea_session;
703 if (ts != NULL && status != 0) {
705 esp->es_server.ea_session = NULL;
706 esp->es_server.ea_skey = NULL;
708 #endif /* PPP_WITH_SRP */
709 if (status != 0 || esp->es_server.ea_session == NULL) {
710 esp->es_server.ea_state = eapBadAuth;
712 esp->es_server.ea_state = eapOpen;
716 #ifdef PPP_WITH_CHAPMS
717 case eapMSCHAPv2Chall:
721 esp->es_server.ea_state = eapBadAuth;
723 esp->es_server.ea_state = eapOpen;
728 esp->es_server.ea_state = eapBadAuth;
731 if (esp->es_server.ea_state == eapBadAuth)
732 eap_send_failure(esp);
734 #ifdef PPP_WITH_EAPTLS
735 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));
736 #endif /* PPP_WITH_EAPTLS */
741 * eap_chap_verify_response - check whether the peer's response matches
742 * what we think it should be. Returns 1 if it does (authentication
743 * succeeded), or 0 if it doesn't.
746 eap_chap_verify_response(char *name, char *ourname, int id,
747 struct chap_digest_type *digest,
748 unsigned char *challenge, unsigned char *response,
749 char *message, int message_space)
752 unsigned char secret[MAXSECRETLEN];
755 /* Get the secret that the peer is supposed to know */
756 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
757 error("No CHAP secret found for authenticating %q", name);
761 ok = digest->verify_response(id, name, secret, secret_len, challenge,
762 response, message, message_space);
763 memset(secret, 0, sizeof(secret));
769 * Format and send an CHAPV2-Success/Failure EAP Request message.
772 eap_chapms2_send_request(eap_state *esp, u_char id,
773 u_char opcode, u_char chapid,
774 char *message, int message_len)
779 outp = outpacket_buf;
781 MAKEHEADER(outp, PPP_EAP);
783 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
784 msglen += message_len;
786 PUTCHAR(EAP_REQUEST, outp);
788 PUTSHORT(msglen, outp);
789 PUTCHAR(EAPT_MSCHAPV2, outp);
790 PUTCHAR(opcode, outp);
791 PUTCHAR(chapid, outp);
793 PUTSHORT(msglen - 5, outp);
794 BCOPY(message, outp, message_len);
796 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
798 if (opcode == CHAP_SUCCESS) {
799 auth_peer_success(esp->es_unit, PPP_EAP, 0,
800 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
803 esp->es_server.ea_state = eapBadAuth;
804 auth_peer_fail(esp->es_unit, PPP_EAP);
807 #endif /* PPP_WITH_CHAPMS */
810 * Format an EAP Request message and send it to the peer. Message
811 * type depends on current state. (Server operation)
814 eap_send_request(eap_state *esp)
824 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
828 #endif /* PPP_WITH_SRP */
830 /* Handle both initial auth and restart */
831 if (esp->es_server.ea_state < eapIdentify &&
832 esp->es_server.ea_state != eapInitial) {
833 esp->es_server.ea_state = eapIdentify;
834 if (explicit_remote) {
836 * If we already know the peer's
837 * unauthenticated name, then there's no
838 * reason to ask. Go to next state instead.
840 esp->es_server.ea_peer = remote_name;
841 esp->es_server.ea_peerlen = strlen(remote_name);
842 eap_figure_next_state(esp, 0);
846 if (esp->es_server.ea_maxrequests > 0 &&
847 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
848 if (esp->es_server.ea_responses > 0)
849 error("EAP: too many Requests sent");
851 error("EAP: no response to Requests");
852 eap_send_failure(esp);
856 outp = outpacket_buf;
858 MAKEHEADER(outp, PPP_EAP);
860 PUTCHAR(EAP_REQUEST, outp);
861 PUTCHAR(esp->es_server.ea_id, outp);
865 switch (esp->es_server.ea_state) {
867 PUTCHAR(EAPT_IDENTITY, outp);
869 challen = strlen(str);
870 BCOPY(str, outp, challen);
871 INCPTR(challen, outp);
875 PUTCHAR(EAPT_MD5CHAP, outp);
877 * pick a random challenge length between
878 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
880 challen = (drand48() *
881 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
882 MIN_CHALLENGE_LENGTH;
883 PUTCHAR(challen, outp);
884 esp->es_challen = challen;
885 ptr = esp->es_challenge;
886 while (--challen >= 0)
887 *ptr++ = (u_char) (drand48() * 0x100);
888 BCOPY(esp->es_challenge, outp, esp->es_challen);
889 INCPTR(esp->es_challen, outp);
890 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
891 INCPTR(esp->es_server.ea_namelen, outp);
894 #ifdef PPP_WITH_CHAPMS
895 case eapMSCHAPv2Chall:
896 esp->es_server.digest->generate_challenge(esp->es_challenge);
897 challen = esp->es_challenge[0];
898 esp->es_challen = challen;
900 PUTCHAR(EAPT_MSCHAPV2, outp);
901 PUTCHAR(CHAP_CHALLENGE, outp);
902 PUTCHAR(esp->es_server.ea_id, outp);
904 PUTSHORT(5 + challen +
905 esp->es_server.ea_namelen,
907 /* challen + challenge */
908 BCOPY(esp->es_challenge, outp, challen+1);
909 INCPTR(challen+1, outp);
910 BCOPY(esp->es_server.ea_name,
912 esp->es_server.ea_namelen);
913 INCPTR(esp->es_server.ea_namelen, outp);
915 #endif /* PPP_WITH_CHAPMS */
917 #ifdef PPP_WITH_EAPTLS
919 PUTCHAR(EAPT_TLS, outp);
920 PUTCHAR(EAP_TLS_FLAGS_START, outp);
921 eap_figure_next_state(esp, 0);
925 eaptls_send(esp->es_server.ea_session, &outp);
926 eap_figure_next_state(esp, 0);
930 PUTCHAR(EAPT_TLS, outp);
932 eap_figure_next_state(esp, 0);
935 case eapTlsSendAlert:
936 eaptls_send(esp->es_server.ea_session, &outp);
937 eap_figure_next_state(esp, 0);
939 #endif /* PPP_WITH_EAPTLS */
943 PUTCHAR(EAPT_SRP, outp);
944 PUTCHAR(EAPSRP_CHALLENGE, outp);
946 PUTCHAR(esp->es_server.ea_namelen, outp);
947 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
948 INCPTR(esp->es_server.ea_namelen, outp);
950 ts = (struct t_server *)esp->es_server.ea_session;
952 PUTCHAR(ts->s.len, outp);
953 BCOPY(ts->s.data, outp, ts->s.len);
954 INCPTR(ts->s.len, outp);
956 if (ts->g.len == 1 && ts->g.data[0] == 2) {
959 PUTCHAR(ts->g.len, outp);
960 BCOPY(ts->g.data, outp, ts->g.len);
961 INCPTR(ts->g.len, outp);
964 if (ts->n.len != sizeof (wkmodulus) ||
965 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
966 BCOPY(ts->n.data, outp, ts->n.len);
967 INCPTR(ts->n.len, outp);
972 PUTCHAR(EAPT_SRP, outp);
973 PUTCHAR(EAPSRP_SKEY, outp);
975 ts = (struct t_server *)esp->es_server.ea_session;
977 BCOPY(ts->B.data, outp, ts->B.len);
978 INCPTR(ts->B.len, outp);
982 PUTCHAR(EAPT_SRP, outp);
983 PUTCHAR(EAPSRP_SVALIDATOR, outp);
984 PUTLONG(SRPVAL_EBIT, outp);
985 ts = (struct t_server *)esp->es_server.ea_session;
987 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
988 INCPTR(SHA_DIGESTSIZE, outp);
990 if (pncrypt_setkey(0)) {
991 /* Generate pseudonym */
993 cp = (unsigned char *)esp->es_server.ea_peer;
994 if ((j = i = esp->es_server.ea_peerlen) > 7)
997 BCOPY(cp, clear + 1, j);
1000 if (!DesEncrypt(clear, cipher)) {
1001 dbglog("no DES here; not generating pseudonym");
1004 BZERO(&b64, sizeof (b64));
1005 outp++; /* space for pseudonym length */
1006 outp += b64enc(&b64, cipher, 8, outp);
1008 (void) DesEncrypt(cp, cipher);
1009 outp += b64enc(&b64, cipher, 8, outp);
1014 BCOPY(cp, clear, i);
1017 *cp++ = drand48() * 0x100;
1020 (void) DesEncrypt(clear, 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_DIGESTSIZE;
1030 while (i < SHA_DIGESTSIZE) {
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);
1047 while (optr < outp) {
1048 diglen = SHA_DIGEST_LENGTH;
1049 PPP_DigestFinal(ctxt, dig, &diglen);
1051 while (cp < dig + SHA_DIGEST_LENGTH)
1054 PPP_DigestInit(ctxt, PPP_sha1());
1055 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1056 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
1058 PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH,
1062 PPP_MD_CTX_free(ctxt);
1068 PUTCHAR(EAPT_SRP, outp);
1069 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1070 challen = MIN_CHALLENGE_LENGTH +
1071 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1072 esp->es_challen = challen;
1073 ptr = esp->es_challenge;
1074 while (--challen >= 0)
1075 *ptr++ = drand48() * 0x100;
1076 BCOPY(esp->es_challenge, outp, esp->es_challen);
1077 INCPTR(esp->es_challen, outp);
1079 #endif /* PPP_WITH_SRP */
1085 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1086 PUTSHORT(outlen, lenloc);
1088 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1090 esp->es_server.ea_requests++;
1092 if (esp->es_server.ea_timeout > 0)
1093 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1097 * eap_authpeer - Authenticate our peer (behave as server).
1099 * Start server state and send first request. This is called only
1100 * after eap_lowerup.
1103 eap_authpeer(int unit, char *localname)
1105 eap_state *esp = &eap_states[unit];
1107 /* Save the name we're given. */
1108 esp->es_server.ea_name = localname;
1109 esp->es_server.ea_namelen = strlen(localname);
1111 esp->es_savedtime = esp->es_server.ea_timeout;
1113 /* Lower layer up yet? */
1114 if (esp->es_server.ea_state == eapInitial ||
1115 esp->es_server.ea_state == eapPending) {
1116 esp->es_server.ea_state = eapPending;
1120 esp->es_server.ea_state = eapPending;
1122 /* ID number not updated here intentionally; hashed into M1 */
1123 eap_send_request(esp);
1127 * eap_server_timeout - Retransmission timer for sending Requests
1131 eap_server_timeout(void *arg)
1133 #ifdef PPP_WITH_EAPTLS
1137 #endif /* PPP_WITH_EAPTLS */
1139 eap_state *esp = (eap_state *) arg;
1141 if (!eap_server_active(esp))
1144 #ifdef PPP_WITH_EAPTLS
1145 switch(esp->es_server.ea_prev_state) {
1148 * In eap-tls the state changes after a request, so we return to
1149 * previous state ...
1152 case(eapTlsSendAck):
1153 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1157 * ... or resend the stored data
1160 case(eapTlsSendAlert):
1161 outp = outpacket_buf;
1162 MAKEHEADER(outp, PPP_EAP);
1163 PUTCHAR(EAP_REQUEST, outp);
1164 PUTCHAR(esp->es_server.ea_id, outp);
1168 eaptls_retransmit(esp->es_server.ea_session, &outp);
1170 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1171 PUTSHORT(outlen, lenloc);
1172 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1173 esp->es_server.ea_requests++;
1175 if (esp->es_server.ea_timeout > 0)
1176 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1182 #endif /* PPP_WITH_EAPTLS */
1184 /* EAP ID number must not change on timeout. */
1185 eap_send_request(esp);
1189 * When it's time to send rechallenge the peer, this timeout is
1190 * called. Once the rechallenge is successful, the response handler
1191 * will restart the timer. If it fails, then the link is dropped.
1194 eap_rechallenge(void *arg)
1196 eap_state *esp = (eap_state *)arg;
1198 if (esp->es_server.ea_state != eapOpen &&
1199 esp->es_server.ea_state != eapSRP4)
1202 esp->es_server.ea_requests = 0;
1203 esp->es_server.ea_state = eapIdentify;
1204 eap_figure_next_state(esp, 0);
1205 esp->es_server.ea_id++;
1206 eap_send_request(esp);
1210 srp_lwrechallenge(void *arg)
1212 eap_state *esp = (eap_state *)arg;
1214 if (esp->es_server.ea_state != eapOpen ||
1215 esp->es_server.ea_type != EAPT_SRP)
1218 esp->es_server.ea_requests = 0;
1219 esp->es_server.ea_state = eapSRP4;
1220 esp->es_server.ea_id++;
1221 eap_send_request(esp);
1225 * eap_lowerup - The lower layer is now up.
1227 * This is called before either eap_authpeer or eap_authwithpeer. See
1228 * link_established() in auth.c. All that's necessary here is to
1229 * return to closed state so that those two routines will do the right
1233 eap_lowerup(int unit)
1235 eap_state *esp = &eap_states[unit];
1237 /* Discard any (possibly authenticated) peer name. */
1238 if (esp->es_server.ea_peer != NULL &&
1239 esp->es_server.ea_peer != remote_name)
1240 free(esp->es_server.ea_peer);
1241 esp->es_server.ea_peer = NULL;
1242 if (esp->es_client.ea_peer != NULL)
1243 free(esp->es_client.ea_peer);
1244 esp->es_client.ea_peer = NULL;
1246 esp->es_client.ea_state = eapClosed;
1247 esp->es_server.ea_state = eapClosed;
1251 * eap_lowerdown - The lower layer is now down.
1253 * Cancel all timeouts and return to initial state.
1256 eap_lowerdown(int unit)
1258 eap_state *esp = &eap_states[unit];
1260 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1261 UNTIMEOUT(eap_client_timeout, (void *)esp);
1263 if (eap_server_active(esp)) {
1264 if (esp->es_server.ea_timeout > 0) {
1265 UNTIMEOUT(eap_server_timeout, (void *)esp);
1268 if ((esp->es_server.ea_state == eapOpen ||
1269 esp->es_server.ea_state == eapSRP4) &&
1270 esp->es_rechallenge > 0) {
1271 UNTIMEOUT(eap_rechallenge, (void *)esp);
1273 if (esp->es_server.ea_state == eapOpen &&
1274 esp->es_lwrechallenge > 0) {
1275 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1279 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1280 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1284 * eap_protrej - Peer doesn't speak this protocol.
1286 * This shouldn't happen. If it does, it represents authentication
1290 eap_protrej(int unit)
1292 eap_state *esp = &eap_states[unit];
1294 if (eap_client_active(esp)) {
1295 error("EAP authentication failed due to Protocol-Reject");
1296 auth_withpeer_fail(unit, PPP_EAP);
1298 if (eap_server_active(esp)) {
1299 error("EAP authentication of peer failed on Protocol-Reject");
1300 auth_peer_fail(unit, PPP_EAP);
1302 eap_lowerdown(unit);
1306 * Format and send a regular EAP Response message.
1309 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1310 u_char *str, int lenstr)
1315 outp = outpacket_buf;
1317 MAKEHEADER(outp, PPP_EAP);
1319 PUTCHAR(EAP_RESPONSE, outp);
1321 esp->es_client.ea_id = id;
1322 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1323 PUTSHORT(msglen, outp);
1324 PUTCHAR(typenum, outp);
1326 BCOPY(str, outp, lenstr);
1329 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1333 * Format and send an MD5-Challenge EAP Response message.
1336 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1337 char *name, int namelen)
1342 outp = outpacket_buf;
1344 MAKEHEADER(outp, PPP_EAP);
1346 PUTCHAR(EAP_RESPONSE, outp);
1348 esp->es_client.ea_id = id;
1349 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1351 PUTSHORT(msglen, outp);
1352 PUTCHAR(EAPT_MD5CHAP, outp);
1353 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1354 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1355 INCPTR(MD5_SIGNATURE_SIZE, outp);
1357 BCOPY(name, outp, namelen);
1360 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1365 * Format and send a SRP EAP Response message.
1368 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1369 u_char *str, int lenstr)
1374 outp = outpacket_buf;
1376 MAKEHEADER(outp, PPP_EAP);
1378 PUTCHAR(EAP_RESPONSE, outp);
1380 esp->es_client.ea_id = id;
1381 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1382 PUTSHORT(msglen, outp);
1383 PUTCHAR(EAPT_SRP, outp);
1384 PUTCHAR(subtypenum, outp);
1386 BCOPY(str, outp, lenstr);
1389 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1393 * Format and send a SRP EAP Client Validator Response message.
1396 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1401 outp = outpacket_buf;
1403 MAKEHEADER(outp, PPP_EAP);
1405 PUTCHAR(EAP_RESPONSE, outp);
1407 esp->es_client.ea_id = id;
1408 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1410 PUTSHORT(msglen, outp);
1411 PUTCHAR(EAPT_SRP, outp);
1412 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1413 PUTLONG(flags, outp);
1414 BCOPY(str, outp, SHA_DIGESTSIZE);
1416 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1418 #endif /* PPP_WITH_SRP */
1420 #ifdef PPP_WITH_EAPTLS
1422 * Send an EAP-TLS response message with tls data
1425 eap_tls_response(eap_state *esp, u_char id)
1431 outp = outpacket_buf;
1433 MAKEHEADER(outp, PPP_EAP);
1435 PUTCHAR(EAP_RESPONSE, outp);
1442 If the id in the request is unchanged, we must retransmit
1445 if(id == esp->es_client.ea_id)
1446 eaptls_retransmit(esp->es_client.ea_session, &outp);
1448 eaptls_send(esp->es_client.ea_session, &outp);
1450 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1451 PUTSHORT(outlen, lenloc);
1453 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1455 esp->es_client.ea_id = id;
1459 * Send an EAP-TLS ack
1462 eap_tls_sendack(eap_state *esp, u_char id)
1468 outp = outpacket_buf;
1470 MAKEHEADER(outp, PPP_EAP);
1472 PUTCHAR(EAP_RESPONSE, outp);
1474 esp->es_client.ea_id = id;
1479 PUTCHAR(EAPT_TLS, outp);
1482 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1483 PUTSHORT(outlen, lenloc);
1485 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1487 #endif /* PPP_WITH_EAPTLS */
1490 eap_send_nak(eap_state *esp, u_char id, u_char type)
1495 outp = outpacket_buf;
1497 MAKEHEADER(outp, PPP_EAP);
1499 PUTCHAR(EAP_RESPONSE, outp);
1501 esp->es_client.ea_id = id;
1502 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1503 PUTSHORT(msglen, outp);
1504 PUTCHAR(EAPT_NAK, outp);
1505 PUTCHAR(type, outp);
1507 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1512 name_of_pn_file(void)
1514 char *user, *path, *file;
1517 static bool pnlogged = 0;
1519 pw = getpwuid(getuid());
1520 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1524 file = PPP_PATH_PSEUDONYM;
1525 pl = strlen(user) + strlen(file) + 2;
1529 (void) slprintf(path, pl, "%s/%s", user, file);
1531 dbglog("pseudonym file: %s", path);
1538 open_pn_file(mode_t modebits)
1543 if ((path = name_of_pn_file()) == NULL)
1545 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1553 remove_pn_file(void)
1557 if ((path = name_of_pn_file()) != NULL) {
1558 (void) unlink(path);
1564 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1567 u_char *datp, *digp;
1569 u_char dig[SHA_DIGESTSIZE];
1570 int dsize, fd, olen = len, diglen = sizeof(dig);
1573 * Do the decoding by working backwards. This eliminates the need
1574 * to save the decoded output in a separate buffer.
1578 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1579 dsize = SHA_DIGESTSIZE;
1582 ctxt = PPP_MD_CTX_new();
1585 PPP_DigestInit(ctxt, PPP_sha1());
1586 PPP_DigestUpdate(ctxt, &val, 1);
1587 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
1590 PPP_DigestUpdate(ctxt, datp, SHA_DIGESTSIZE);
1592 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
1593 esp->es_client.ea_namelen);
1595 PPP_DigestFinal(ctxt, dig, &diglen);
1597 for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
1600 PPP_MD_CTX_free(ctxt);
1604 /* Now check that the result is sane */
1605 if (olen <= 0 || *inp + 1 > olen) {
1606 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1611 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1613 dbglog("EAP: error saving pseudonym: %m");
1616 len = write(fd, inp + 1, *inp);
1617 if (close(fd) != -1 && len == *inp) {
1618 dbglog("EAP: saved pseudonym");
1619 esp->es_usedpseudo = 0;
1621 dbglog("EAP: failed to save pseudonym");
1625 #endif /* PPP_WITH_SRP */
1629 * Format and send an CHAPV2-Challenge EAP Response message.
1632 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1637 outp = outpacket_buf;
1639 MAKEHEADER(outp, PPP_EAP);
1641 PUTCHAR(EAP_RESPONSE, outp);
1643 esp->es_client.ea_id = id;
1644 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1645 PUTSHORT(msglen, outp);
1646 PUTCHAR(EAPT_MSCHAPV2, outp);
1647 PUTCHAR(CHAP_RESPONSE, outp);
1648 PUTCHAR(chapid, outp);
1651 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1652 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1653 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1654 BCOPY(user, outp, user_len);
1656 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1661 * eap_request - Receive EAP Request message (client mode).
1664 eap_request(eap_state *esp, u_char *inp, int id, int len)
1669 char secret[MAXWORDLEN];
1670 char rhostname[256];
1672 u_char hash[MD5_SIGNATURE_SIZE];
1673 int hashlen = MD5_SIGNATURE_SIZE;
1674 #ifdef PPP_WITH_EAPTLS
1676 struct eaptls_session *ets = esp->es_client.ea_session;
1677 #endif /* PPP_WITH_EAPTLS */
1680 struct t_client *tc;
1681 struct t_num sval, gval, Nval, *Ap, Bval;
1684 u_char dig[SHA_DIGESTSIZE];
1685 int diglen = sizeof(dig);
1687 #endif /* PPP_WITH_SRP */
1690 * Ignore requests if we're not open
1692 if (esp->es_client.ea_state <= eapClosed)
1696 * Note: we update es_client.ea_id *only if* a Response
1697 * message is being generated. Otherwise, we leave it the
1698 * same for duplicate detection purposes.
1701 esp->es_client.ea_requests++;
1702 if (esp->es_client.ea_maxrequests != 0 &&
1703 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1704 info("EAP: received too many Request messages");
1705 if (esp->es_client.ea_timeout > 0) {
1706 UNTIMEOUT(eap_client_timeout, (void *)esp);
1708 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1713 error("EAP: empty Request message discarded");
1717 GETCHAR(typenum, inp);
1723 info("EAP: Identity prompt \"%.*q\"", len, inp);
1725 if (esp->es_usepseudo &&
1726 (esp->es_usedpseudo == 0 ||
1727 (esp->es_usedpseudo == 1 &&
1728 id == esp->es_client.ea_id))) {
1729 esp->es_usedpseudo = 1;
1730 /* Try to get a pseudonym */
1731 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1732 strcpy(rhostname, SRP_PSEUDO_ID);
1733 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1734 sizeof (rhostname) - SRP_PSEUDO_LEN);
1735 /* XXX NAI unsupported */
1737 eap_send_response(esp, id, typenum,
1738 rhostname, len + SRP_PSEUDO_LEN);
1745 /* Stop using pseudonym now. */
1746 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1748 esp->es_usedpseudo = 2;
1750 #endif /* PPP_WITH_SRP */
1751 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1752 esp->es_client.ea_namelen);
1755 case EAPT_NOTIFICATION:
1757 info("EAP: Notification \"%.*q\"", len, inp);
1758 eap_send_response(esp, id, typenum, NULL, 0);
1763 * Avoid the temptation to send Response Nak in reply
1764 * to Request Nak here. It can only lead to trouble.
1766 warn("EAP: unexpected Nak in Request; ignored");
1767 /* Return because we're waiting for something real. */
1772 error("EAP: received MD5-Challenge with no data");
1773 /* Bogus request; wait for something real. */
1776 GETCHAR(vallen, inp);
1778 if (vallen < 8 || vallen > len) {
1779 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1781 /* Try something better. */
1782 eap_send_nak(esp, id, EAPT_SRP);
1786 /* Not so likely to happen. */
1787 if (len - vallen >= sizeof (rhostname)) {
1788 dbglog("EAP: trimming really long peer name down");
1789 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1790 rhostname[sizeof (rhostname) - 1] = '\0';
1792 BCOPY(inp + vallen, rhostname, len - vallen);
1793 rhostname[len - vallen] = '\0';
1796 /* In case the remote doesn't give us his name. */
1797 if (explicit_remote ||
1798 (remote_name[0] != '\0' && vallen == len))
1799 strlcpy(rhostname, remote_name, sizeof (rhostname));
1802 * Get the secret for authenticating ourselves with
1803 * the specified host.
1805 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1806 rhostname, secret, &secret_len, 0)) {
1807 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1808 eap_send_nak(esp, id, EAPT_SRP);
1812 mdctx = PPP_MD_CTX_new();
1813 if (mdctx != NULL) {
1814 if (PPP_DigestInit(mdctx, PPP_md5())) {
1816 if (PPP_DigestUpdate(mdctx, &typenum, 1)) {
1817 if (PPP_DigestUpdate(mdctx, secret, secret_len)) {
1818 BZERO(secret, sizeof(secret));
1819 if (PPP_DigestUpdate(mdctx, inp, vallen)) {
1820 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
1821 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1822 esp->es_client.ea_namelen);
1823 PPP_MD_CTX_free(mdctx);
1830 PPP_MD_CTX_free(mdctx);
1832 dbglog("EAP: Invalid MD5 checksum");
1833 eap_send_nak(esp, id, EAPT_SRP);
1836 #ifdef PPP_WITH_EAPTLS
1839 switch(esp->es_client.ea_state) {
1844 error("EAP: received EAP-TLS Listen packet with no data");
1845 /* Bogus request; wait for something real. */
1848 GETCHAR(flags, inp);
1849 if(flags & EAP_TLS_FLAGS_START){
1851 esp->es_client.ea_using_eaptls = 1;
1853 if (explicit_remote){
1854 esp->es_client.ea_peer = strdup(remote_name);
1855 esp->es_client.ea_peerlen = strlen(remote_name);
1857 esp->es_client.ea_peer = NULL;
1859 /* Init ssl session */
1860 if(!eaptls_init_ssl_client(esp)) {
1861 dbglog("cannot init ssl");
1862 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1863 esp->es_client.ea_using_eaptls = 0;
1867 ets = esp->es_client.ea_session;
1868 eap_tls_response(esp, id);
1869 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1873 /* The server has sent a bad start packet. */
1874 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1878 eap_tls_response(esp, id);
1879 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1884 error("EAP: discarding EAP-TLS Receive packet with no data");
1885 /* Bogus request; wait for something real. */
1888 eaptls_receive(ets, inp, len);
1891 eap_tls_sendack(esp, id);
1892 esp->es_client.ea_state = eapTlsRecv;
1896 if(ets->alert_recv) {
1897 eap_tls_sendack(esp, id);
1898 esp->es_client.ea_state = eapTlsRecvFailure;
1902 /* Check if TLS handshake is finished */
1903 if(eaptls_is_init_finished(ets)) {
1904 #ifdef PPP_WITH_MPPE
1905 eaptls_gen_mppe_keys(ets, 1);
1907 eaptls_free_session(ets);
1908 eap_tls_sendack(esp, id);
1909 esp->es_client.ea_state = eapTlsRecvSuccess;
1913 eap_tls_response(esp,id);
1914 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1918 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1919 esp->es_client.ea_using_eaptls = 0;
1924 #endif /* PPP_WITH_EAPTLS */
1929 error("EAP: received empty SRP Request");
1930 /* Bogus request; wait for something real. */
1935 GETCHAR(vallen, inp);
1938 case EAPSRP_CHALLENGE:
1940 if (esp->es_client.ea_session != NULL) {
1941 tc = (struct t_client *)esp->es_client.
1944 * If this is a new challenge, then start
1945 * over with a new client session context.
1946 * Otherwise, just resend last response.
1948 if (id != esp->es_client.ea_id) {
1950 esp->es_client.ea_session = NULL;
1954 /* No session key just yet */
1955 esp->es_client.ea_skey = NULL;
1957 GETCHAR(vallen, inp);
1959 if (vallen >= len) {
1960 error("EAP: badly-formed SRP Challenge"
1962 /* Ignore badly-formed messages */
1965 BCOPY(inp, rhostname, vallen);
1966 rhostname[vallen] = '\0';
1967 INCPTR(vallen, inp);
1971 * In case the remote doesn't give us his name,
1972 * use configured name.
1974 if (explicit_remote ||
1975 (remote_name[0] != '\0' && vallen == 0)) {
1976 strlcpy(rhostname, remote_name,
1977 sizeof (rhostname));
1980 if (esp->es_client.ea_peer != NULL)
1981 free(esp->es_client.ea_peer);
1982 esp->es_client.ea_peer = strdup(rhostname);
1983 esp->es_client.ea_peerlen = strlen(rhostname);
1985 GETCHAR(vallen, inp);
1987 if (vallen >= len) {
1988 error("EAP: badly-formed SRP Challenge"
1990 /* Ignore badly-formed messages */
1995 INCPTR(vallen, inp);
1998 GETCHAR(vallen, inp);
2001 error("EAP: badly-formed SRP Challenge"
2003 /* Ignore badly-formed messages */
2006 /* If no generator present, then use value 2 */
2008 gval.data = (u_char *)"\002";
2014 INCPTR(vallen, inp);
2018 * If no modulus present, then use well-known
2022 Nval.data = (u_char *)wkmodulus;
2023 Nval.len = sizeof (wkmodulus);
2028 tc = t_clientopen(esp->es_client.ea_name,
2029 &Nval, &gval, &sval);
2031 eap_send_nak(esp, id, EAPT_MD5CHAP);
2034 esp->es_client.ea_session = (void *)tc;
2036 /* Add Challenge ID & type to verifier */
2039 t_clientaddexdata(tc, vals, 2);
2041 Ap = t_clientgenexp(tc);
2042 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2047 tc = (struct t_client *)esp->es_client.ea_session;
2049 warn("EAP: peer sent Subtype 2 without 1");
2050 eap_send_nak(esp, id, EAPT_MD5CHAP);
2053 if (esp->es_client.ea_skey != NULL) {
2055 * ID number should not change here. Warn
2056 * if it does (but otherwise ignore).
2058 if (id != esp->es_client.ea_id) {
2059 warn("EAP: ID changed from %d to %d "
2060 "in SRP Subtype 2 rexmit",
2061 esp->es_client.ea_id, id);
2064 if (get_srp_secret(esp->es_unit,
2065 esp->es_client.ea_name,
2066 esp->es_client.ea_peer, secret, 0) == 0) {
2068 * Can't work with this peer because
2069 * the secret is missing. Just give
2072 eap_send_nak(esp, id, EAPT_MD5CHAP);
2077 t_clientpasswd(tc, secret);
2078 BZERO(secret, sizeof (secret));
2079 esp->es_client.ea_skey =
2080 t_clientgetkey(tc, &Bval);
2081 if (esp->es_client.ea_skey == NULL) {
2082 /* Server is rogue; stop now */
2083 error("EAP: SRP server is rogue");
2084 goto client_failure;
2087 eap_srpval_response(esp, id, SRPVAL_EBIT,
2088 t_clientresponse(tc));
2091 case EAPSRP_SVALIDATOR:
2092 tc = (struct t_client *)esp->es_client.ea_session;
2093 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2094 warn("EAP: peer sent Subtype 3 without 1/2");
2095 eap_send_nak(esp, id, EAPT_MD5CHAP);
2099 * If we're already open, then this ought to be a
2100 * duplicate. Otherwise, check that the server is
2101 * who we think it is.
2103 if (esp->es_client.ea_state == eapOpen) {
2104 if (id != esp->es_client.ea_id) {
2105 warn("EAP: ID changed from %d to %d "
2106 "in SRP Subtype 3 rexmit",
2107 esp->es_client.ea_id, id);
2110 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2111 if (len < 0 || t_clientverify(tc, inp +
2112 sizeof (u_int32_t)) != 0) {
2113 error("EAP: SRP server verification "
2115 goto client_failure;
2117 GETLONG(esp->es_client.ea_keyflags, inp);
2118 /* Save pseudonym if user wants it. */
2119 if (len > 0 && esp->es_usepseudo) {
2120 INCPTR(SHA_DIGESTSIZE, inp);
2121 write_pseudonym(esp, inp, len, id);
2125 * We've verified our peer. We're now mostly done,
2126 * except for waiting on the regular EAP Success
2129 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2132 case EAPSRP_LWRECHALLENGE:
2134 warn("EAP: malformed Lightweight rechallenge");
2137 ctxt = PPP_MD_CTX_new();
2141 PPP_DigestInit(ctxt, PPP_sha1());
2142 PPP_DigestUpdate(ctxt, vals, 1);
2143 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
2145 PPP_DigestUpdate(ctxt, inp, len);
2146 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
2147 esp->es_client.ea_namelen);
2148 PPP_DigestFinal(ctxt, dig, &diglen);
2150 PPP_MD_CTX_free(ctxt);
2152 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2158 error("EAP: unknown SRP Subtype %d", vallen);
2159 eap_send_nak(esp, id, EAPT_MD5CHAP);
2163 #endif /* PPP_WITH_SRP */
2165 #ifdef PPP_WITH_CHAPMS
2168 error("EAP: received invalid MSCHAPv2 packet, too short");
2171 unsigned char opcode;
2172 GETCHAR(opcode, inp);
2173 unsigned char chapid; /* Chapv2-ID */
2174 GETCHAR(chapid, inp);
2176 GETSHORT(mssize, inp);
2178 /* Validate the mssize field */
2179 if (len != mssize) {
2180 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2185 /* If MSCHAPv2 digest was not found, NAK the packet */
2186 if (!esp->es_client.digest) {
2187 error("EAP MSCHAPv2 not supported");
2188 eap_send_nak(esp, id, EAPT_SRP);
2193 case CHAP_CHALLENGE: {
2195 /* make_response() expects: VLEN + VALUE */
2196 u_char *challenge = inp;
2198 unsigned char vsize;
2199 GETCHAR(vsize, inp);
2202 /* Validate the VALUE field */
2203 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2204 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2208 /* Increment past the VALUE field */
2209 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2210 len -= MS_CHAP2_PEER_CHAL_LEN;
2212 /* Extract the hostname */
2213 rhostname[0] = '\0';
2215 if (len >= sizeof (rhostname)) {
2216 dbglog("EAP: trimming really long peer name down");
2217 len = sizeof(rhostname) - 1;
2219 BCOPY(inp, rhostname, len);
2220 rhostname[len] = '\0';
2223 /* In case the remote doesn't give us his name. */
2224 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2225 strlcpy(rhostname, remote_name, sizeof(rhostname));
2227 /* Get the secret for authenticating ourselves with the specified host. */
2228 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2229 rhostname, secret, &secret_len, 0)) {
2230 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2231 eap_send_nak(esp, id, EAPT_SRP);
2234 esp->es_client.ea_namelen = strlen(esp->es_client.ea_name);
2236 /* Create the MSCHAPv2 response (and add to cache) */
2237 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2238 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2239 challenge, secret, secret_len, NULL);
2241 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2244 case CHAP_SUCCESS: {
2246 /* Check response for mutual authentication */
2247 u_char status = CHAP_FAILURE;
2248 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2249 info("Chap authentication succeeded! %.*v", len, inp);
2250 status = CHAP_SUCCESS;
2252 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2255 case CHAP_FAILURE: {
2257 /* Process the failure string, and log appropriate information */
2258 esp->es_client.digest->handle_failure(inp, len);
2260 u_char status = CHAP_FAILURE;
2261 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2262 goto client_failure; /* force termination */
2266 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2267 eap_send_nak(esp, id, EAPT_SRP);
2271 #endif /* PPP_WITH_CHAPMS */
2272 #ifdef PPP_WITH_PEAP
2275 /* Initialize the PEAP context (if not already initialized) */
2276 if (!esp->ea_peap) {
2277 rhostname[0] = '\0';
2278 if (explicit_remote || (remote_name[0] != '\0')) {
2279 strlcpy(rhostname, remote_name, sizeof (rhostname));
2281 if (peap_init(&esp->ea_peap, rhostname)) {
2282 eap_send_nak(esp, id, EAPT_TLS);
2287 /* Process the PEAP packet */
2288 if (peap_process(esp, id, inp, len)) {
2289 eap_send_nak(esp, id, EAPT_TLS);
2293 #endif // PPP_WITH_PEAP
2296 info("EAP: unknown authentication type %d; Naking", typenum);
2297 eap_send_nak(esp, id, EAPT_SRP);
2301 if (esp->es_client.ea_timeout > 0) {
2302 UNTIMEOUT(eap_client_timeout, (void *)esp);
2303 TIMEOUT(eap_client_timeout, (void *)esp,
2304 esp->es_client.ea_timeout);
2309 esp->es_client.ea_state = eapBadAuth;
2310 if (esp->es_client.ea_timeout > 0) {
2311 UNTIMEOUT(eap_client_timeout, (void *)esp);
2313 esp->es_client.ea_session = NULL;
2316 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2317 #endif /* PPP_WITH_SRP */
2321 * eap_response - Receive EAP Response message (server mode).
2324 eap_response(eap_state *esp, u_char *inp, int id, int len)
2329 char secret[MAXSECRETLEN];
2330 char rhostname[256];
2332 u_char hash[MD5_SIGNATURE_SIZE];
2333 int hashlen = MD5_SIGNATURE_SIZE;
2335 struct t_server *ts;
2338 u_char dig[SHA_DIGESTSIZE];
2339 int diglen = sizeof(dig);
2340 #endif /* PPP_WITH_SRP */
2342 #ifdef PPP_WITH_EAPTLS
2343 struct eaptls_session *ets;
2345 #endif /* PPP_WITH_EAPTLS */
2346 #ifdef PPP_WITH_CHAPMS
2348 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2349 unsigned char *, unsigned char *, char *, int);
2350 char response_message[256];
2351 #endif /* PPP_WITH_CHAPMS */
2354 * Ignore responses if we're not open
2356 if (esp->es_server.ea_state <= eapClosed)
2359 if (esp->es_server.ea_id != id) {
2360 dbglog("EAP: discarding Response %d; expected ID %d", id,
2361 esp->es_server.ea_id);
2365 esp->es_server.ea_responses++;
2368 error("EAP: empty Response message discarded");
2372 GETCHAR(typenum, inp);
2377 if (esp->es_server.ea_state != eapIdentify) {
2378 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2382 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2383 if (esp->es_server.ea_peer != NULL &&
2384 esp->es_server.ea_peer != remote_name)
2385 free(esp->es_server.ea_peer);
2386 esp->es_server.ea_peer = malloc(len + 1);
2387 if (esp->es_server.ea_peer == NULL) {
2388 esp->es_server.ea_peerlen = 0;
2389 eap_figure_next_state(esp, 1);
2392 BCOPY(inp, esp->es_server.ea_peer, len);
2393 esp->es_server.ea_peer[len] = '\0';
2394 esp->es_server.ea_peerlen = len;
2395 eap_figure_next_state(esp, 0);
2398 #ifdef PPP_WITH_EAPTLS
2400 switch(esp->es_server.ea_state) {
2404 ets = (struct eaptls_session *) esp->es_server.ea_session;
2406 eap_figure_next_state(esp,
2407 eaptls_receive(esp->es_server.ea_session, inp, len));
2409 if(ets->alert_recv) {
2410 eap_send_failure(esp);
2417 dbglog("EAP-TLS ACK with extra data");
2419 eap_figure_next_state(esp, 0);
2422 case eapTlsRecvClient:
2423 /* Receive authentication response from client */
2425 GETCHAR(flags, inp);
2427 if(len == 1 && !flags) { /* Ack = ok */
2428 #ifdef PPP_WITH_MPPE
2429 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2431 eap_send_success(esp);
2433 else { /* failure */
2434 warn("Server authentication failed");
2435 eap_send_failure(esp);
2439 warn("Bogus EAP-TLS packet received from client");
2441 eaptls_free_session(esp->es_server.ea_session);
2445 case eapTlsRecvAlertAck:
2446 eap_send_failure(esp);
2450 eap_figure_next_state(esp, 1);
2454 #endif /* PPP_WITH_EAPTLS */
2456 case EAPT_NOTIFICATION:
2457 dbglog("EAP unexpected Notification; response discarded");
2462 info("EAP: Nak Response with no suggested protocol");
2463 eap_figure_next_state(esp, 1);
2467 GETCHAR(vallen, inp);
2470 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2471 /* Peer cannot Nak Identify Request */
2472 eap_figure_next_state(esp, 1);
2478 /* Run through SRP validator selection again. */
2479 esp->es_server.ea_state = eapIdentify;
2480 eap_figure_next_state(esp, 0);
2484 esp->es_server.ea_state = eapMD5Chall;
2487 #ifdef PPP_WITH_EAPTLS
2488 /* Send EAP-TLS start packet */
2490 esp->es_server.ea_state = eapTlsStart;
2492 #endif /* PPP_WITH_EAPTLS */
2494 #ifdef PPP_WITH_CHAPMS
2496 info("EAP: peer proposes MSCHAPv2");
2497 /* If MSCHAPv2 digest was not found, NAK the packet */
2498 if (!esp->es_server.digest) {
2499 error("EAP MSCHAPv2 not supported");
2500 eap_send_nak(esp, id, EAPT_SRP);
2503 esp->es_server.ea_state = eapMSCHAPv2Chall;
2505 #endif /* PPP_WITH_CHAPMS */
2508 dbglog("EAP: peer requesting unknown Type %d", vallen);
2509 switch (esp->es_server.ea_state) {
2513 esp->es_server.ea_state = eapMD5Chall;
2517 esp->es_server.ea_state = eapIdentify;
2518 eap_figure_next_state(esp, 0);
2528 if (esp->es_server.ea_state != eapMD5Chall) {
2529 error("EAP: unexpected MD5-Response");
2530 eap_figure_next_state(esp, 1);
2534 error("EAP: received MD5-Response with no data");
2535 eap_figure_next_state(esp, 1);
2538 GETCHAR(vallen, inp);
2540 if (vallen != 16 || vallen > len) {
2541 error("EAP: MD5-Response with bad length %d", vallen);
2542 eap_figure_next_state(esp, 1);
2546 /* Not so likely to happen. */
2547 if (len - vallen >= sizeof (rhostname)) {
2548 dbglog("EAP: trimming really long peer name down");
2549 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2550 rhostname[sizeof (rhostname) - 1] = '\0';
2552 BCOPY(inp + vallen, rhostname, len - vallen);
2553 rhostname[len - vallen] = '\0';
2556 /* In case the remote doesn't give us his name. */
2557 if (explicit_remote ||
2558 (remote_name[0] != '\0' && vallen == len))
2559 strlcpy(rhostname, remote_name, sizeof (rhostname));
2562 * Get the secret for authenticating the specified
2565 if (!get_secret(esp->es_unit, rhostname,
2566 esp->es_server.ea_name, secret, &secret_len, 1)) {
2567 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2568 eap_send_failure(esp);
2572 mdctx = PPP_MD_CTX_new();
2573 if (mdctx != NULL) {
2575 if (PPP_DigestInit(mdctx, PPP_md5())) {
2577 if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
2579 if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
2581 BZERO(secret, sizeof(secret));
2582 if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
2584 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
2586 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) == 0) {
2588 esp->es_server.ea_type = EAPT_MD5CHAP;
2589 eap_send_success(esp);
2590 eap_figure_next_state(esp, 0);
2592 if (esp->es_rechallenge != 0) {
2593 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2595 PPP_MD_CTX_free(mdctx);
2604 PPP_MD_CTX_free(mdctx);
2607 eap_send_failure(esp);
2610 #ifdef PPP_WITH_CHAPMS
2613 error("EAP: received MSCHAPv2 with no data");
2614 eap_figure_next_state(esp, 1);
2617 GETCHAR(opcode, inp);
2622 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2623 error("EAP: unexpected MSCHAPv2-Response");
2624 eap_figure_next_state(esp, 1);
2627 /* skip MS ID + len */
2629 GETCHAR(vallen, inp);
2632 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2633 error("EAP: Invalid MSCHAPv2-Response "
2634 "length %d", vallen);
2635 eap_figure_next_state(esp, 1);
2639 /* Not so likely to happen. */
2640 if (len - vallen >= sizeof (rhostname)) {
2641 dbglog("EAP: trimming really long peer name down");
2642 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2643 rhostname[sizeof (rhostname) - 1] = '\0';
2645 BCOPY(inp + vallen, rhostname, len - vallen);
2646 rhostname[len - vallen] = '\0';
2649 /* In case the remote doesn't give us his name. */
2650 if (explicit_remote ||
2651 (remote_name[0] != '\0' && vallen == len))
2652 strlcpy(rhostname, remote_name, sizeof (rhostname));
2654 /* strip the MS domain name */
2655 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2656 char tmp[MAXNAMELEN+1];
2658 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2659 strcpy(rhostname, tmp);
2662 if (chap_verify_hook)
2663 chap_verifier = chap_verify_hook;
2665 chap_verifier = eap_chap_verify_response;
2667 esp->es_server.ea_id += 1;
2668 if ((*chap_verifier)(rhostname,
2669 esp->es_server.ea_name,
2671 esp->es_server.digest,
2675 sizeof(response_message)))
2677 info("EAP: MSCHAPv2 success for peer %q",
2679 esp->es_server.ea_type = EAPT_MSCHAPV2;
2680 eap_chapms2_send_request(esp,
2681 esp->es_server.ea_id,
2683 esp->es_server.ea_id,
2685 strlen(response_message));
2686 eap_figure_next_state(esp, 0);
2687 if (esp->es_rechallenge != 0)
2688 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2691 warn("EAP: MSCHAPv2 failure for peer %q",
2693 eap_chapms2_send_request(esp,
2694 esp->es_server.ea_id,
2696 esp->es_server.ea_id,
2698 strlen(response_message));
2702 info("EAP: MSCHAPv2 success confirmed");
2705 info("EAP: MSCHAPv2 failure confirmed");
2708 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2709 eap_send_nak(esp, id, EAPT_SRP);
2713 #endif /* PPP_WITH_CHAPMS */
2718 error("EAP: empty SRP Response");
2719 eap_figure_next_state(esp, 1);
2722 GETCHAR(typenum, inp);
2726 if (esp->es_server.ea_state != eapSRP1) {
2727 error("EAP: unexpected SRP Subtype 1 Response");
2728 eap_figure_next_state(esp, 1);
2733 ts = (struct t_server *)esp->es_server.ea_session;
2735 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2736 if (esp->es_server.ea_skey == NULL) {
2737 /* Client's A value is bogus; terminate now */
2738 error("EAP: bogus A value from client");
2739 eap_send_failure(esp);
2741 eap_figure_next_state(esp, 0);
2745 case EAPSRP_CVALIDATOR:
2746 if (esp->es_server.ea_state != eapSRP2) {
2747 error("EAP: unexpected SRP Subtype 2 Response");
2748 eap_figure_next_state(esp, 1);
2751 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2752 error("EAP: M1 length %d < %d", len,
2753 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2754 eap_figure_next_state(esp, 1);
2757 GETLONG(esp->es_server.ea_keyflags, inp);
2758 ts = (struct t_server *)esp->es_server.ea_session;
2760 if (t_serververify(ts, inp)) {
2761 info("EAP: unable to validate client identity");
2762 eap_send_failure(esp);
2765 eap_figure_next_state(esp, 0);
2769 if (esp->es_server.ea_state != eapSRP3) {
2770 error("EAP: unexpected SRP Subtype 3 Response");
2771 eap_send_failure(esp);
2774 esp->es_server.ea_type = EAPT_SRP;
2775 eap_send_success(esp);
2776 eap_figure_next_state(esp, 0);
2777 if (esp->es_rechallenge != 0)
2778 TIMEOUT(eap_rechallenge, esp,
2779 esp->es_rechallenge);
2780 if (esp->es_lwrechallenge != 0)
2781 TIMEOUT(srp_lwrechallenge, esp,
2782 esp->es_lwrechallenge);
2785 case EAPSRP_LWRECHALLENGE:
2786 if (esp->es_server.ea_state != eapSRP4) {
2787 info("EAP: unexpected SRP Subtype 4 Response");
2790 if (len != SHA_DIGESTSIZE) {
2791 error("EAP: bad Lightweight rechallenge "
2795 ctxt = PPP_MD_CTX_new();
2799 PPP_DigestInit(ctxt, PPP_sha1());
2800 PPP_DigestUpdate(ctxt, &vallen, 1);
2801 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
2803 PPP_DigestUpdate(ctxt, esp->es_challenge, esp->es_challen);
2804 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
2805 esp->es_server.ea_peerlen);
2806 PPP_DigestFinal(ctxt, dig, &diglen);
2808 PPP_MD_CTX_free(ctxt);
2810 if (BCMP(dig, inp, SHA_DIGEST_LENGTH) != 0) {
2811 error("EAP: failed Lightweight rechallenge");
2812 eap_send_failure(esp);
2816 esp->es_server.ea_state = eapOpen;
2817 if (esp->es_lwrechallenge != 0)
2818 TIMEOUT(srp_lwrechallenge, esp,
2819 esp->es_lwrechallenge);
2824 #endif /* PPP_WITH_SRP */
2827 /* This can't happen. */
2828 error("EAP: unknown Response type %d; ignored", typenum);
2832 if (esp->es_server.ea_timeout > 0) {
2833 UNTIMEOUT(eap_server_timeout, (void *)esp);
2836 if (esp->es_server.ea_state != eapBadAuth &&
2837 esp->es_server.ea_state != eapOpen) {
2838 esp->es_server.ea_id++;
2839 eap_send_request(esp);
2844 * eap_success - Receive EAP Success message (client mode).
2847 eap_success(eap_state *esp, u_char *inp, int id, int len)
2849 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2850 #ifdef PPP_WITH_EAPTLS
2851 && esp->es_client.ea_state != eapTlsRecvSuccess
2852 #endif /* PPP_WITH_EAPTLS */
2854 dbglog("EAP unexpected success message in state %s (%d)",
2855 eap_state_name(esp->es_client.ea_state),
2856 esp->es_client.ea_state);
2860 #ifdef PPP_WITH_EAPTLS
2861 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2862 eapTlsRecvSuccess) {
2863 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2864 eap_state_name(esp->es_client.ea_state),
2865 esp->es_client.ea_state);
2868 #endif /* PPP_WITH_EAPTLS */
2870 if (esp->es_client.ea_timeout > 0) {
2871 UNTIMEOUT(eap_client_timeout, (void *)esp);
2875 /* This is odd. The spec doesn't allow for this. */
2879 #ifdef PPP_WITH_PEAP
2880 peap_finish(&esp->ea_peap);
2883 esp->es_client.ea_state = eapOpen;
2884 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2888 * eap_failure - Receive EAP Failure message (client mode).
2891 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2894 * Ignore failure messages if we're not open
2896 if (esp->es_client.ea_state <= eapClosed)
2899 if (!eap_client_active(esp)) {
2900 dbglog("EAP unexpected failure message in state %s (%d)",
2901 eap_state_name(esp->es_client.ea_state),
2902 esp->es_client.ea_state);
2905 if (esp->es_client.ea_timeout > 0) {
2906 UNTIMEOUT(eap_client_timeout, (void *)esp);
2910 /* This is odd. The spec doesn't allow for this. */
2914 esp->es_client.ea_state = eapBadAuth;
2916 error("EAP: peer reports authentication failure");
2918 #ifdef PPP_WITH_PEAP
2919 peap_finish(&esp->ea_peap);
2922 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2926 * eap_input - Handle received EAP message.
2929 eap_input(int unit, u_char *inp, int inlen)
2931 eap_state *esp = &eap_states[unit];
2936 * Parse header (code, id and length). If packet too short,
2939 if (inlen < EAP_HEADERLEN) {
2940 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2946 if (len < EAP_HEADERLEN || len > inlen) {
2947 error("EAP: packet has illegal length field %d (%d..%d)", len,
2948 EAP_HEADERLEN, inlen);
2951 len -= EAP_HEADERLEN;
2953 /* Dispatch based on message code */
2956 eap_request(esp, inp, id, len);
2960 eap_response(esp, inp, id, len);
2964 eap_success(esp, inp, id, len);
2968 eap_failure(esp, inp, id, len);
2971 default: /* XXX Need code reject */
2972 /* Note: it's not legal to send EAP Nak here. */
2973 warn("EAP: unknown code %d received", code);
2979 * eap_printpkt - print the contents of an EAP packet.
2981 static char *eap_codenames[] = {
2982 "Request", "Response", "Success", "Failure"
2985 static char *eap_typenames[] = {
2986 "Identity", "Notification", "Nak", "MD5-Challenge",
2987 "OTP", "Generic-Token", NULL, NULL,
2988 "RSA", "DSS", "KEA", "KEA-Validate",
2989 "TLS", "Defender", "Windows 2000", "Arcot",
2990 "Cisco", "Nokia", "SRP", NULL,
2991 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2996 eap_printpkt(u_char *inp, int inlen,
2997 void (*printer) (void *, char *, ...), void *arg)
2999 int code, id, len, rtype, vallen;
3002 #ifdef PPP_WITH_EAPTLS
3004 #endif /* PPP_WITH_EAPTLS */
3005 #ifdef PPP_WITH_CHAPMS
3007 #endif /* PPP_WITH_CHAPMS */
3009 if (inlen < EAP_HEADERLEN)
3015 if (len < EAP_HEADERLEN || len > inlen)
3018 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
3019 printer(arg, " %s", eap_codenames[code-1]);
3021 printer(arg, " code=0x%x", code);
3022 printer(arg, " id=0x%x", id);
3023 len -= EAP_HEADERLEN;
3027 printer(arg, " <missing type>");
3030 GETCHAR(rtype, inp);
3033 rtype <= sizeof (eap_typenames) / sizeof (char *))
3034 printer(arg, " %s", eap_typenames[rtype-1]);
3036 printer(arg, " type=0x%x", rtype);
3039 case EAPT_NOTIFICATION:
3041 printer(arg, " <Message ");
3042 print_string((char *)inp, len, printer, arg);
3047 printer(arg, " <No message>");
3054 GETCHAR(vallen, inp);
3058 printer(arg, " <Value%.*B>", vallen, inp);
3059 INCPTR(vallen, inp);
3062 printer(arg, " <Name ");
3063 print_string((char *)inp, len, printer, arg);
3068 printer(arg, " <No name>");
3072 #ifdef PPP_WITH_CHAPMS
3076 GETCHAR(opcode, inp);
3079 case CHAP_CHALLENGE:
3082 GETCHAR(vallen, inp);
3087 printer(arg, " Challenge <");
3088 for (; vallen > 0; --vallen) {
3091 printer(arg, "%.2x", val);
3095 printer(arg, ", <Name ");
3096 print_string((char *)inp, len, printer, arg);
3101 printer(arg, ", <No name>");
3107 printer(arg, " Success <Message ");
3108 print_string((char *)inp, len, printer, arg);
3114 printer(arg, " Failure <Message ");
3115 print_string((char *)inp, len, printer, arg);
3121 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3125 #endif /* PPP_WITH_CHAPMS */
3127 #ifdef PPP_WITH_EAPTLS
3131 GETCHAR(flags, inp);
3134 if(flags == 0 && len == 0){
3135 printer(arg, " Ack");
3139 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3140 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3141 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3143 #endif /* PPP_WITH_EAPTLS */
3149 GETCHAR(vallen, inp);
3151 printer(arg, "-%d", vallen);
3153 case EAPSRP_CHALLENGE:
3154 GETCHAR(vallen, inp);
3159 printer(arg, " <Name ");
3160 print_string((char *)inp, vallen, printer,
3164 printer(arg, " <No name>");
3166 INCPTR(vallen, inp);
3168 GETCHAR(vallen, inp);
3172 printer(arg, " <s%.*B>", vallen, inp);
3173 INCPTR(vallen, inp);
3175 GETCHAR(vallen, inp);
3180 printer(arg, " <Default g=2>");
3182 printer(arg, " <g%.*B>", vallen, inp);
3184 INCPTR(vallen, inp);
3187 printer(arg, " <Default N>");
3189 printer(arg, " <N%.*B>", len, inp);
3196 printer(arg, " <B%.*B>", len, inp);
3201 case EAPSRP_SVALIDATOR:
3202 if (len < sizeof (u_int32_t))
3205 len -= sizeof (u_int32_t);
3206 if (uval & SRPVAL_EBIT) {
3208 uval &= ~SRPVAL_EBIT;
3211 printer(arg, " f<%X>", uval);
3213 if ((vallen = len) > SHA_DIGESTSIZE)
3214 vallen = SHA_DIGESTSIZE;
3215 printer(arg, " <M2%.*B%s>", len, inp,
3216 len < SHA_DIGESTSIZE ? "?" : "");
3217 INCPTR(vallen, inp);
3220 printer(arg, " <PN%.*B>", len, inp);
3226 case EAPSRP_LWRECHALLENGE:
3227 printer(arg, " <Challenge%.*B>", len, inp);
3233 #endif /* PPP_WITH_SRP */
3240 GETCHAR(rtype, inp);
3243 rtype <= sizeof (eap_typenames) / sizeof (char *))
3244 printer(arg, " %s", eap_typenames[rtype-1]);
3246 printer(arg, " type=0x%x", rtype);
3250 printer(arg, " <Name ");
3251 print_string((char *)inp, len, printer, arg);
3258 #ifdef PPP_WITH_EAPTLS
3262 GETCHAR(flags, inp);
3265 if(flags == 0 && len == 0){
3266 printer(arg, " Ack");
3270 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3271 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3272 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3275 #endif /* PPP_WITH_EAPTLS */
3279 printer(arg, " <missing hint>");
3282 GETCHAR(rtype, inp);
3284 printer(arg, " <Suggested-type %02X", rtype);
3286 rtype <= sizeof (eap_typenames) / sizeof (char *))
3287 printer(arg, " (%s)", eap_typenames[rtype-1]);
3293 printer(arg, " <missing length>");
3296 GETCHAR(vallen, inp);
3300 printer(arg, " <Value%.*B>", vallen, inp);
3301 INCPTR(vallen, inp);
3304 printer(arg, " <Name ");
3305 print_string((char *)inp, len, printer, arg);
3310 printer(arg, " <No name>");
3314 #ifdef PPP_WITH_CHAPMS
3318 GETCHAR(opcode, inp);
3324 GETCHAR(vallen, inp);
3329 printer(arg, " Response <");
3330 for (; vallen > 0; --vallen) {
3333 printer(arg, "%.2x", val);
3337 printer(arg, ", <Name ");
3338 print_string((char *)inp, len, printer, arg);
3343 printer(arg, ", <No name>");
3347 printer(arg, " Success");
3350 printer(arg, " Failure");
3353 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3357 #endif /* PPP_WITH_CHAPMS */
3363 GETCHAR(vallen, inp);
3365 printer(arg, "-%d", vallen);
3368 printer(arg, " <A%.*B>", len, inp);
3373 case EAPSRP_CVALIDATOR:
3374 if (len < sizeof (u_int32_t))
3377 len -= sizeof (u_int32_t);
3378 if (uval & SRPVAL_EBIT) {
3380 uval &= ~SRPVAL_EBIT;
3383 printer(arg, " f<%X>", uval);
3385 printer(arg, " <M1%.*B%s>", len, inp,
3386 len == SHA_DIGESTSIZE ? "" : "?");
3394 case EAPSRP_LWRECHALLENGE:
3395 printer(arg, " <Response%.*B%s>", len, inp,
3396 len == SHA_DIGESTSIZE ? "" : "?");
3397 if ((vallen = len) > SHA_DIGESTSIZE)
3398 vallen = SHA_DIGESTSIZE;
3399 INCPTR(vallen, inp);
3404 #endif /* PPP_WITH_SRP */
3408 case EAP_SUCCESS: /* No payload expected for these! */
3413 printer(arg, " <truncated>");
3418 printer(arg, "%8B...", inp);
3420 printer(arg, "%.*B", len, inp);
3423 return (inp - pstart);