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_getkey(int timeoffs, unsigned char *key, int keylen)
342 if (pn_secret == NULL)
344 reftime = time(NULL) + timeoffs;
345 tp = localtime(&reftime);
347 ctxt = PPP_MD_CTX_new();
350 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
352 PPP_DigestInit(ctxt, PPP_sha1());
353 PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
354 PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
355 PPP_DigestFinal(ctxt, key, &keylen);
357 PPP_MD_CTX_free(ctxt);
364 static char base64[] =
365 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
373 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
378 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
381 if (bs->bs_offs >= 24) {
382 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
383 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
384 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
385 *outp++ = base64[bs->bs_bits & 0x3F];
395 b64flush(struct b64state *bs, u_char *outp)
399 if (bs->bs_offs == 8) {
400 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
401 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
403 } else if (bs->bs_offs == 16) {
404 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
405 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
406 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
415 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
421 if ((cp = strchr(base64, *inp++)) == NULL)
423 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
426 if (bs->bs_offs >= 8) {
427 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
434 #endif /* PPP_WITH_SRP */
437 * Assume that current waiting server state is complete and figure
438 * next state to use based on available authentication data. 'status'
439 * indicates if there was an error in handling the last query. It is
440 * 0 for success and non-zero for failure.
443 eap_figure_next_state(eap_state *esp, int status)
446 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp, key[SHA_DIGEST_LENGTH];
448 struct t_confent *tce, mytce;
451 int id, i, plen, clen, toffs, keylen;
454 PPP_CIPHER_CTX *cctx;
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,
498 cctx = PPP_CIPHER_CTX_new();
500 dbglog("no DES here; cannot decode "
505 if (!PPP_CipherInit(cctx, PPP_des_ecb(), NULL, NULL, 0)) {
506 dbglog("no DES here; cannot decode "
511 for (i = 0; i < 5; i++) {
512 pncrypt_getkey(toffs, key, keylen);
515 PPP_CIPHER_CTX_set_cipher_data(cctx, key);
517 if (!PPP_CipherUpdate(cctx, clear, &clen, secbuf, 8)) {
518 dbglog("no DES here; cannot decode "
522 id = *(unsigned char *)clear;
523 if (id + 1 <= plen && id + 9 > plen)
526 if (plen % 8 == 0 && i < 5) {
528 * Note that this is always shorter than the
529 * original stored string, so there's no need
532 if ((i = plen = *(unsigned char *)clear) > 7)
534 esp->es_server.ea_peerlen = plen;
535 dp = (unsigned char *)esp->es_server.ea_peer;
536 BCOPY(clear + 1, dp, i);
541 PPP_CipherUpdate(cctx, dp, &clen, sp, 8);
546 PPP_CIPHER_CTX_free(cctx);
547 esp->es_server.ea_peer[
548 esp->es_server.ea_peerlen] = '\0';
549 dbglog("decoded pseudonym to \"%.*q\"",
550 esp->es_server.ea_peerlen,
551 esp->es_server.ea_peer);
553 dbglog("failed to decode real name");
554 /* Stay in eapIdentfy state; requery */
558 /* Look up user in secrets database. */
559 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
560 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
561 /* Set up default in case SRP entry is bad */
562 esp->es_server.ea_state = eapMD5Chall;
563 /* Get t_confent based on index in srp-secrets */
564 id = strtol((char *)secbuf, &cp, 10);
565 if (*cp++ != ':' || id < 0)
569 mytce.modulus.data = (u_char *)wkmodulus;
570 mytce.modulus.len = sizeof (wkmodulus);
571 mytce.generator.data = (u_char *)"\002";
572 mytce.generator.len = 1;
574 } else if ((tce = gettcid(id)) != NULL) {
576 * Client will have to verify this modulus/
577 * generator combination, and that will take
578 * a while. Lengthen the timeout here.
580 if (esp->es_server.ea_timeout > 0 &&
581 esp->es_server.ea_timeout < 30)
582 esp->es_server.ea_timeout = 30;
586 if ((cp2 = strchr(cp, ':')) == NULL)
589 tpw.pebuf.name = esp->es_server.ea_peer;
590 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
592 tpw.pebuf.password.data = (char*) tpw.pwbuf;
593 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
595 tpw.pebuf.salt.data = tpw.saltbuf;
596 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
598 esp->es_server.ea_session = (void *)ts;
599 esp->es_server.ea_state = eapSRP1;
600 vals[0] = esp->es_server.ea_id + 1;
602 t_serveraddexdata(ts, vals, 2);
603 /* Generate B; must call before t_servergetkey() */
607 #endif /* PPP_WITH_SRP */
608 #ifdef PPP_WITH_EAPTLS
609 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
610 esp->es_server.ea_name, secret, &secret_len, 1)) {
612 esp->es_server.ea_state = eapTlsStart;
615 #endif /* PPP_WITH_EAPTLS */
617 esp->es_server.ea_state = eapMD5Chall;
620 #ifdef PPP_WITH_EAPTLS
622 /* Initialize ssl session */
623 if(!eaptls_init_ssl_server(esp)) {
624 esp->es_server.ea_state = eapBadAuth;
628 esp->es_server.ea_state = eapTlsRecv;
632 ets = (struct eaptls_session *) esp->es_server.ea_session;
634 if(ets->alert_sent) {
635 esp->es_server.ea_state = eapTlsSendAlert;
640 esp->es_server.ea_state = eapBadAuth;
643 ets = (struct eaptls_session *) esp->es_server.ea_session;
646 esp->es_server.ea_state = eapTlsSendAck;
648 esp->es_server.ea_state = eapTlsSend;
652 ets = (struct eaptls_session *) esp->es_server.ea_session;
655 esp->es_server.ea_state = eapTlsRecvAck;
657 if(SSL_is_init_finished(ets->ssl))
658 esp->es_server.ea_state = eapTlsRecvClient;
660 /* JJK Add "TLS empty record" message here ??? */
661 esp->es_server.ea_state = eapTlsRecv;
665 esp->es_server.ea_state = eapTlsRecv;
671 esp->es_server.ea_state = eapBadAuth;
675 esp->es_server.ea_state = eapTlsSend;
678 case eapTlsSendAlert:
679 esp->es_server.ea_state = eapTlsRecvAlertAck;
681 #endif /* PPP_WITH_EAPTLS */
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 */
693 esp->es_server.ea_state = eapMD5Chall;
694 } else if (status != 0 || esp->es_server.ea_session == NULL) {
695 esp->es_server.ea_state = eapBadAuth;
697 esp->es_server.ea_state = eapSRP2;
703 ts = (struct t_server *)esp->es_server.ea_session;
704 if (ts != NULL && status != 0) {
706 esp->es_server.ea_session = NULL;
707 esp->es_server.ea_skey = NULL;
709 #endif /* PPP_WITH_SRP */
710 if (status != 0 || esp->es_server.ea_session == NULL) {
711 esp->es_server.ea_state = eapBadAuth;
713 esp->es_server.ea_state = eapSRP3;
720 ts = (struct t_server *)esp->es_server.ea_session;
721 if (ts != NULL && status != 0) {
723 esp->es_server.ea_session = NULL;
724 esp->es_server.ea_skey = NULL;
726 #endif /* PPP_WITH_SRP */
727 if (status != 0 || esp->es_server.ea_session == NULL) {
728 esp->es_server.ea_state = eapBadAuth;
730 esp->es_server.ea_state = eapOpen;
734 #ifdef PPP_WITH_CHAPMS
735 case eapMSCHAPv2Chall:
739 esp->es_server.ea_state = eapBadAuth;
741 esp->es_server.ea_state = eapOpen;
746 esp->es_server.ea_state = eapBadAuth;
749 if (esp->es_server.ea_state == eapBadAuth)
750 eap_send_failure(esp);
752 #ifdef PPP_WITH_EAPTLS
753 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));
754 #endif /* PPP_WITH_EAPTLS */
759 * eap_chap_verify_response - check whether the peer's response matches
760 * what we think it should be. Returns 1 if it does (authentication
761 * succeeded), or 0 if it doesn't.
764 eap_chap_verify_response(char *name, char *ourname, int id,
765 struct chap_digest_type *digest,
766 unsigned char *challenge, unsigned char *response,
767 char *message, int message_space)
770 unsigned char secret[MAXSECRETLEN];
773 /* Get the secret that the peer is supposed to know */
774 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
775 error("No CHAP secret found for authenticating %q", name);
779 ok = digest->verify_response(id, name, secret, secret_len, challenge,
780 response, message, message_space);
781 memset(secret, 0, sizeof(secret));
787 * Format and send an CHAPV2-Success/Failure EAP Request message.
790 eap_chapms2_send_request(eap_state *esp, u_char id,
791 u_char opcode, u_char chapid,
792 char *message, int message_len)
797 outp = outpacket_buf;
799 MAKEHEADER(outp, PPP_EAP);
801 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
802 msglen += message_len;
804 PUTCHAR(EAP_REQUEST, outp);
806 PUTSHORT(msglen, outp);
807 PUTCHAR(EAPT_MSCHAPV2, outp);
808 PUTCHAR(opcode, outp);
809 PUTCHAR(chapid, outp);
811 PUTSHORT(msglen - 5, outp);
812 BCOPY(message, outp, message_len);
814 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
816 if (opcode == CHAP_SUCCESS) {
817 auth_peer_success(esp->es_unit, PPP_EAP, 0,
818 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
821 esp->es_server.ea_state = eapBadAuth;
822 auth_peer_fail(esp->es_unit, PPP_EAP);
825 #endif /* PPP_WITH_CHAPMS */
828 * Format an EAP Request message and send it to the peer. Message
829 * type depends on current state. (Server operation)
832 eap_send_request(eap_state *esp)
842 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp, key[SHA_DIGEST_LENGTH];
843 int i, j, diglen, clen, keylen = sizeof(key);
846 PPP_CIPHER_CTX *cctx;
847 #endif /* PPP_WITH_SRP */
849 /* Handle both initial auth and restart */
850 if (esp->es_server.ea_state < eapIdentify &&
851 esp->es_server.ea_state != eapInitial) {
852 esp->es_server.ea_state = eapIdentify;
853 if (explicit_remote) {
855 * If we already know the peer's
856 * unauthenticated name, then there's no
857 * reason to ask. Go to next state instead.
859 esp->es_server.ea_peer = remote_name;
860 esp->es_server.ea_peerlen = strlen(remote_name);
861 eap_figure_next_state(esp, 0);
865 if (esp->es_server.ea_maxrequests > 0 &&
866 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
867 if (esp->es_server.ea_responses > 0)
868 error("EAP: too many Requests sent");
870 error("EAP: no response to Requests");
871 eap_send_failure(esp);
875 outp = outpacket_buf;
877 MAKEHEADER(outp, PPP_EAP);
879 PUTCHAR(EAP_REQUEST, outp);
880 PUTCHAR(esp->es_server.ea_id, outp);
884 switch (esp->es_server.ea_state) {
886 PUTCHAR(EAPT_IDENTITY, outp);
888 challen = strlen(str);
889 BCOPY(str, outp, challen);
890 INCPTR(challen, outp);
894 PUTCHAR(EAPT_MD5CHAP, outp);
896 * pick a random challenge length between
897 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
899 challen = (drand48() *
900 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
901 MIN_CHALLENGE_LENGTH;
902 PUTCHAR(challen, outp);
903 esp->es_challen = challen;
904 ptr = esp->es_challenge;
905 while (--challen >= 0)
906 *ptr++ = (u_char) (drand48() * 0x100);
907 BCOPY(esp->es_challenge, outp, esp->es_challen);
908 INCPTR(esp->es_challen, outp);
909 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
910 INCPTR(esp->es_server.ea_namelen, outp);
913 #ifdef PPP_WITH_CHAPMS
914 case eapMSCHAPv2Chall:
915 esp->es_server.digest->generate_challenge(esp->es_challenge);
916 challen = esp->es_challenge[0];
917 esp->es_challen = challen;
919 PUTCHAR(EAPT_MSCHAPV2, outp);
920 PUTCHAR(CHAP_CHALLENGE, outp);
921 PUTCHAR(esp->es_server.ea_id, outp);
923 PUTSHORT(5 + challen +
924 esp->es_server.ea_namelen,
926 /* challen + challenge */
927 BCOPY(esp->es_challenge, outp, challen+1);
928 INCPTR(challen+1, outp);
929 BCOPY(esp->es_server.ea_name,
931 esp->es_server.ea_namelen);
932 INCPTR(esp->es_server.ea_namelen, outp);
934 #endif /* PPP_WITH_CHAPMS */
936 #ifdef PPP_WITH_EAPTLS
938 PUTCHAR(EAPT_TLS, outp);
939 PUTCHAR(EAP_TLS_FLAGS_START, outp);
940 eap_figure_next_state(esp, 0);
944 eaptls_send(esp->es_server.ea_session, &outp);
945 eap_figure_next_state(esp, 0);
949 PUTCHAR(EAPT_TLS, outp);
951 eap_figure_next_state(esp, 0);
954 case eapTlsSendAlert:
955 eaptls_send(esp->es_server.ea_session, &outp);
956 eap_figure_next_state(esp, 0);
958 #endif /* PPP_WITH_EAPTLS */
962 PUTCHAR(EAPT_SRP, outp);
963 PUTCHAR(EAPSRP_CHALLENGE, outp);
965 PUTCHAR(esp->es_server.ea_namelen, outp);
966 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
967 INCPTR(esp->es_server.ea_namelen, outp);
969 ts = (struct t_server *)esp->es_server.ea_session;
971 PUTCHAR(ts->s.len, outp);
972 BCOPY(ts->s.data, outp, ts->s.len);
973 INCPTR(ts->s.len, outp);
975 if (ts->g.len == 1 && ts->g.data[0] == 2) {
978 PUTCHAR(ts->g.len, outp);
979 BCOPY(ts->g.data, outp, ts->g.len);
980 INCPTR(ts->g.len, outp);
983 if (ts->n.len != sizeof (wkmodulus) ||
984 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
985 BCOPY(ts->n.data, outp, ts->n.len);
986 INCPTR(ts->n.len, outp);
991 PUTCHAR(EAPT_SRP, outp);
992 PUTCHAR(EAPSRP_SKEY, outp);
994 ts = (struct t_server *)esp->es_server.ea_session;
996 BCOPY(ts->B.data, outp, ts->B.len);
997 INCPTR(ts->B.len, outp);
1001 PUTCHAR(EAPT_SRP, outp);
1002 PUTCHAR(EAPSRP_SVALIDATOR, outp);
1003 PUTLONG(SRPVAL_EBIT, outp);
1004 ts = (struct t_server *)esp->es_server.ea_session;
1006 BCOPY(t_serverresponse(ts), outp, SHA_DIGEST_LENGTH);
1007 INCPTR(SHA_DIGEST_LENGTH, outp);
1009 if (pncrypt_getkey(0, key, keylen)) {
1010 /* Generate pseudonym */
1012 cp = (unsigned char *)esp->es_server.ea_peer;
1013 if ((j = i = esp->es_server.ea_peerlen) > 7)
1016 BCOPY(cp, clear + 1, j);
1020 cctx = PPP_CIPHER_CTX_new();
1022 dbglog("no DES here; not generating pseudonym");
1025 PPP_CipherInit(cctx, PPP_des_ecb(), key, NULL, 1);
1027 PPP_CipherUpdate(cctx, cipher, &clen, clear, sizeof(clear));
1029 BZERO(&b64, sizeof (b64));
1030 outp++; /* space for pseudonym length */
1031 outp += b64enc(&b64, cipher, 8, outp);
1033 PPP_CipherUpdate(cctx, cipher, &clen, cp, 8);
1034 outp += b64enc(&b64, cipher, 8, outp);
1039 BCOPY(cp, clear, i);
1042 *cp++ = drand48() * 0x100;
1046 PPP_CipherUpdate(cctx, cipher, &clen, clear, 8);
1047 outp += b64enc(&b64, cipher, 8, outp);
1049 outp += b64flush(&b64, outp);
1051 PPP_CIPHER_CTX_free(cctx);
1053 /* Set length and pad out to next 20 octet boundary */
1054 i = outp - optr - 1;
1056 i %= SHA_DIGEST_LENGTH;
1058 while (i < SHA_DIGEST_LENGTH) {
1059 *outp++ = drand48() * 0x100;
1064 /* Obscure the pseudonym with SHA1 hash */
1065 ctxt = PPP_MD_CTX_new();
1068 PPP_DigestInit(ctxt, PPP_sha1());
1069 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1070 PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey,
1072 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
1073 esp->es_server.ea_peerlen);
1075 while (optr < outp) {
1076 diglen = SHA_DIGEST_LENGTH;
1077 PPP_DigestFinal(ctxt, dig, &diglen);
1079 while (cp < dig + SHA_DIGEST_LENGTH)
1082 PPP_DigestInit(ctxt, PPP_sha1());
1083 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1084 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
1086 PPP_DigestUpdate(ctxt, optr - SHA_DIGEST_LENGTH,
1090 PPP_MD_CTX_free(ctxt);
1096 PUTCHAR(EAPT_SRP, outp);
1097 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1098 challen = MIN_CHALLENGE_LENGTH +
1099 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1100 esp->es_challen = challen;
1101 ptr = esp->es_challenge;
1102 while (--challen >= 0)
1103 *ptr++ = drand48() * 0x100;
1104 BCOPY(esp->es_challenge, outp, esp->es_challen);
1105 INCPTR(esp->es_challen, outp);
1107 #endif /* PPP_WITH_SRP */
1113 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1114 PUTSHORT(outlen, lenloc);
1116 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1118 esp->es_server.ea_requests++;
1120 if (esp->es_server.ea_timeout > 0)
1121 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1125 * eap_authpeer - Authenticate our peer (behave as server).
1127 * Start server state and send first request. This is called only
1128 * after eap_lowerup.
1131 eap_authpeer(int unit, char *localname)
1133 eap_state *esp = &eap_states[unit];
1135 /* Save the name we're given. */
1136 esp->es_server.ea_name = localname;
1137 esp->es_server.ea_namelen = strlen(localname);
1139 esp->es_savedtime = esp->es_server.ea_timeout;
1141 /* Lower layer up yet? */
1142 if (esp->es_server.ea_state == eapInitial ||
1143 esp->es_server.ea_state == eapPending) {
1144 esp->es_server.ea_state = eapPending;
1148 esp->es_server.ea_state = eapPending;
1150 /* ID number not updated here intentionally; hashed into M1 */
1151 eap_send_request(esp);
1155 * eap_server_timeout - Retransmission timer for sending Requests
1159 eap_server_timeout(void *arg)
1161 #ifdef PPP_WITH_EAPTLS
1165 #endif /* PPP_WITH_EAPTLS */
1167 eap_state *esp = (eap_state *) arg;
1169 if (!eap_server_active(esp))
1172 #ifdef PPP_WITH_EAPTLS
1173 switch(esp->es_server.ea_prev_state) {
1176 * In eap-tls the state changes after a request, so we return to
1177 * previous state ...
1180 case(eapTlsSendAck):
1181 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1185 * ... or resend the stored data
1188 case(eapTlsSendAlert):
1189 outp = outpacket_buf;
1190 MAKEHEADER(outp, PPP_EAP);
1191 PUTCHAR(EAP_REQUEST, outp);
1192 PUTCHAR(esp->es_server.ea_id, outp);
1196 eaptls_retransmit(esp->es_server.ea_session, &outp);
1198 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1199 PUTSHORT(outlen, lenloc);
1200 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1201 esp->es_server.ea_requests++;
1203 if (esp->es_server.ea_timeout > 0)
1204 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1210 #endif /* PPP_WITH_EAPTLS */
1212 /* EAP ID number must not change on timeout. */
1213 eap_send_request(esp);
1217 * When it's time to send rechallenge the peer, this timeout is
1218 * called. Once the rechallenge is successful, the response handler
1219 * will restart the timer. If it fails, then the link is dropped.
1222 eap_rechallenge(void *arg)
1224 eap_state *esp = (eap_state *)arg;
1226 if (esp->es_server.ea_state != eapOpen &&
1227 esp->es_server.ea_state != eapSRP4)
1230 esp->es_server.ea_requests = 0;
1231 esp->es_server.ea_state = eapIdentify;
1232 eap_figure_next_state(esp, 0);
1233 esp->es_server.ea_id++;
1234 eap_send_request(esp);
1238 srp_lwrechallenge(void *arg)
1240 eap_state *esp = (eap_state *)arg;
1242 if (esp->es_server.ea_state != eapOpen ||
1243 esp->es_server.ea_type != EAPT_SRP)
1246 esp->es_server.ea_requests = 0;
1247 esp->es_server.ea_state = eapSRP4;
1248 esp->es_server.ea_id++;
1249 eap_send_request(esp);
1253 * eap_lowerup - The lower layer is now up.
1255 * This is called before either eap_authpeer or eap_authwithpeer. See
1256 * link_established() in auth.c. All that's necessary here is to
1257 * return to closed state so that those two routines will do the right
1261 eap_lowerup(int unit)
1263 eap_state *esp = &eap_states[unit];
1265 /* Discard any (possibly authenticated) peer name. */
1266 if (esp->es_server.ea_peer != NULL &&
1267 esp->es_server.ea_peer != remote_name)
1268 free(esp->es_server.ea_peer);
1269 esp->es_server.ea_peer = NULL;
1270 if (esp->es_client.ea_peer != NULL)
1271 free(esp->es_client.ea_peer);
1272 esp->es_client.ea_peer = NULL;
1274 esp->es_client.ea_state = eapClosed;
1275 esp->es_server.ea_state = eapClosed;
1279 * eap_lowerdown - The lower layer is now down.
1281 * Cancel all timeouts and return to initial state.
1284 eap_lowerdown(int unit)
1286 eap_state *esp = &eap_states[unit];
1288 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1289 UNTIMEOUT(eap_client_timeout, (void *)esp);
1291 if (eap_server_active(esp)) {
1292 if (esp->es_server.ea_timeout > 0) {
1293 UNTIMEOUT(eap_server_timeout, (void *)esp);
1296 if ((esp->es_server.ea_state == eapOpen ||
1297 esp->es_server.ea_state == eapSRP4) &&
1298 esp->es_rechallenge > 0) {
1299 UNTIMEOUT(eap_rechallenge, (void *)esp);
1301 if (esp->es_server.ea_state == eapOpen &&
1302 esp->es_lwrechallenge > 0) {
1303 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1307 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1308 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1312 * eap_protrej - Peer doesn't speak this protocol.
1314 * This shouldn't happen. If it does, it represents authentication
1318 eap_protrej(int unit)
1320 eap_state *esp = &eap_states[unit];
1322 if (eap_client_active(esp)) {
1323 error("EAP authentication failed due to Protocol-Reject");
1324 auth_withpeer_fail(unit, PPP_EAP);
1326 if (eap_server_active(esp)) {
1327 error("EAP authentication of peer failed on Protocol-Reject");
1328 auth_peer_fail(unit, PPP_EAP);
1330 eap_lowerdown(unit);
1334 * Format and send a regular EAP Response message.
1337 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1338 u_char *str, int lenstr)
1343 outp = outpacket_buf;
1345 MAKEHEADER(outp, PPP_EAP);
1347 PUTCHAR(EAP_RESPONSE, outp);
1349 esp->es_client.ea_id = id;
1350 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1351 PUTSHORT(msglen, outp);
1352 PUTCHAR(typenum, outp);
1354 BCOPY(str, outp, lenstr);
1357 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1361 * Format and send an MD5-Challenge EAP Response message.
1364 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1365 char *name, int namelen)
1370 outp = outpacket_buf;
1372 MAKEHEADER(outp, PPP_EAP);
1374 PUTCHAR(EAP_RESPONSE, outp);
1376 esp->es_client.ea_id = id;
1377 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_DIGEST_LENGTH +
1379 PUTSHORT(msglen, outp);
1380 PUTCHAR(EAPT_MD5CHAP, outp);
1381 PUTCHAR(MD5_DIGEST_LENGTH, outp);
1382 BCOPY(hash, outp, MD5_DIGEST_LENGTH);
1383 INCPTR(MD5_DIGEST_LENGTH, outp);
1385 BCOPY(name, outp, namelen);
1388 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1393 * Format and send a SRP EAP Response message.
1396 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1397 u_char *str, int lenstr)
1402 outp = outpacket_buf;
1404 MAKEHEADER(outp, PPP_EAP);
1406 PUTCHAR(EAP_RESPONSE, outp);
1408 esp->es_client.ea_id = id;
1409 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1410 PUTSHORT(msglen, outp);
1411 PUTCHAR(EAPT_SRP, outp);
1412 PUTCHAR(subtypenum, outp);
1414 BCOPY(str, outp, lenstr);
1417 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1421 * Format and send a SRP EAP Client Validator Response message.
1424 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1429 outp = outpacket_buf;
1431 MAKEHEADER(outp, PPP_EAP);
1433 PUTCHAR(EAP_RESPONSE, outp);
1435 esp->es_client.ea_id = id;
1436 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1438 PUTSHORT(msglen, outp);
1439 PUTCHAR(EAPT_SRP, outp);
1440 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1441 PUTLONG(flags, outp);
1442 BCOPY(str, outp, SHA_DIGEST_LENGTH);
1444 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1446 #endif /* PPP_WITH_SRP */
1448 #ifdef PPP_WITH_EAPTLS
1450 * Send an EAP-TLS response message with tls data
1453 eap_tls_response(eap_state *esp, u_char id)
1459 outp = outpacket_buf;
1461 MAKEHEADER(outp, PPP_EAP);
1463 PUTCHAR(EAP_RESPONSE, outp);
1470 If the id in the request is unchanged, we must retransmit
1473 if(id == esp->es_client.ea_id)
1474 eaptls_retransmit(esp->es_client.ea_session, &outp);
1476 eaptls_send(esp->es_client.ea_session, &outp);
1478 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1479 PUTSHORT(outlen, lenloc);
1481 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1483 esp->es_client.ea_id = id;
1487 * Send an EAP-TLS ack
1490 eap_tls_sendack(eap_state *esp, u_char id)
1496 outp = outpacket_buf;
1498 MAKEHEADER(outp, PPP_EAP);
1500 PUTCHAR(EAP_RESPONSE, outp);
1502 esp->es_client.ea_id = id;
1507 PUTCHAR(EAPT_TLS, outp);
1510 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1511 PUTSHORT(outlen, lenloc);
1513 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1515 #endif /* PPP_WITH_EAPTLS */
1518 eap_send_nak(eap_state *esp, u_char id, u_char type)
1523 outp = outpacket_buf;
1525 MAKEHEADER(outp, PPP_EAP);
1527 PUTCHAR(EAP_RESPONSE, outp);
1529 esp->es_client.ea_id = id;
1530 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1531 PUTSHORT(msglen, outp);
1532 PUTCHAR(EAPT_NAK, outp);
1533 PUTCHAR(type, outp);
1535 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1540 name_of_pn_file(void)
1542 char *user, *path, *file;
1545 static bool pnlogged = 0;
1547 pw = getpwuid(getuid());
1548 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1552 file = PPP_PATH_PSEUDONYM;
1553 pl = strlen(user) + strlen(file) + 2;
1557 (void) slprintf(path, pl, "%s/%s", user, file);
1559 dbglog("pseudonym file: %s", path);
1566 open_pn_file(mode_t modebits)
1571 if ((path = name_of_pn_file()) == NULL)
1573 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1581 remove_pn_file(void)
1585 if ((path = name_of_pn_file()) != NULL) {
1586 (void) unlink(path);
1592 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1595 u_char *datp, *digp;
1597 u_char dig[SHA_DIGEST_LENGTH];
1598 int dsize, fd, olen = len, diglen = sizeof(dig);
1601 * Do the decoding by working backwards. This eliminates the need
1602 * to save the decoded output in a separate buffer.
1606 if ((dsize = len % SHA_DIGEST_LENGTH) == 0)
1607 dsize = SHA_DIGEST_LENGTH;
1610 ctxt = PPP_MD_CTX_new();
1613 PPP_DigestInit(ctxt, PPP_sha1());
1614 PPP_DigestUpdate(ctxt, &val, 1);
1615 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
1618 PPP_DigestUpdate(ctxt, datp, SHA_DIGESTSIZE);
1620 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
1621 esp->es_client.ea_namelen);
1623 PPP_DigestFinal(ctxt, dig, &diglen);
1625 for (digp = dig; digp < dig + SHA_DIGEST_LENGTH; digp++)
1628 PPP_MD_CTX_free(ctxt);
1632 /* Now check that the result is sane */
1633 if (olen <= 0 || *inp + 1 > olen) {
1634 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1639 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1641 dbglog("EAP: error saving pseudonym: %m");
1644 len = write(fd, inp + 1, *inp);
1645 if (close(fd) != -1 && len == *inp) {
1646 dbglog("EAP: saved pseudonym");
1647 esp->es_usedpseudo = 0;
1649 dbglog("EAP: failed to save pseudonym");
1653 #endif /* PPP_WITH_SRP */
1657 * Format and send an CHAPV2-Challenge EAP Response message.
1660 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1665 outp = outpacket_buf;
1667 MAKEHEADER(outp, PPP_EAP);
1669 PUTCHAR(EAP_RESPONSE, outp);
1671 esp->es_client.ea_id = id;
1672 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1673 PUTSHORT(msglen, outp);
1674 PUTCHAR(EAPT_MSCHAPV2, outp);
1675 PUTCHAR(CHAP_RESPONSE, outp);
1676 PUTCHAR(chapid, outp);
1679 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1680 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1681 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1682 BCOPY(user, outp, user_len);
1684 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1689 * eap_request - Receive EAP Request message (client mode).
1692 eap_request(eap_state *esp, u_char *inp, int id, int len)
1697 char secret[MAXWORDLEN];
1698 char rhostname[256];
1700 u_char hash[MD5_DIGEST_LENGTH];
1701 int hashlen = MD5_DIGEST_LENGTH;
1702 #ifdef PPP_WITH_EAPTLS
1704 struct eaptls_session *ets = esp->es_client.ea_session;
1705 #endif /* PPP_WITH_EAPTLS */
1708 struct t_client *tc;
1709 struct t_num sval, gval, Nval, *Ap, Bval;
1712 u_char dig[SHA_DIGESTSIZE];
1713 int diglen = sizeof(dig);
1715 #endif /* PPP_WITH_SRP */
1718 * Ignore requests if we're not open
1720 if (esp->es_client.ea_state <= eapClosed)
1724 * Note: we update es_client.ea_id *only if* a Response
1725 * message is being generated. Otherwise, we leave it the
1726 * same for duplicate detection purposes.
1729 esp->es_client.ea_requests++;
1730 if (esp->es_client.ea_maxrequests != 0 &&
1731 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1732 info("EAP: received too many Request messages");
1733 if (esp->es_client.ea_timeout > 0) {
1734 UNTIMEOUT(eap_client_timeout, (void *)esp);
1736 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1741 error("EAP: empty Request message discarded");
1745 GETCHAR(typenum, inp);
1751 info("EAP: Identity prompt \"%.*q\"", len, inp);
1753 if (esp->es_usepseudo &&
1754 (esp->es_usedpseudo == 0 ||
1755 (esp->es_usedpseudo == 1 &&
1756 id == esp->es_client.ea_id))) {
1757 esp->es_usedpseudo = 1;
1758 /* Try to get a pseudonym */
1759 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1760 strcpy(rhostname, SRP_PSEUDO_ID);
1761 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1762 sizeof (rhostname) - SRP_PSEUDO_LEN);
1763 /* XXX NAI unsupported */
1765 eap_send_response(esp, id, typenum,
1766 rhostname, len + SRP_PSEUDO_LEN);
1773 /* Stop using pseudonym now. */
1774 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1776 esp->es_usedpseudo = 2;
1778 #endif /* PPP_WITH_SRP */
1779 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1780 esp->es_client.ea_namelen);
1783 case EAPT_NOTIFICATION:
1785 info("EAP: Notification \"%.*q\"", len, inp);
1786 eap_send_response(esp, id, typenum, NULL, 0);
1791 * Avoid the temptation to send Response Nak in reply
1792 * to Request Nak here. It can only lead to trouble.
1794 warn("EAP: unexpected Nak in Request; ignored");
1795 /* Return because we're waiting for something real. */
1800 error("EAP: received MD5-Challenge with no data");
1801 /* Bogus request; wait for something real. */
1804 GETCHAR(vallen, inp);
1806 if (vallen < 8 || vallen > len) {
1807 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1809 /* Try something better. */
1810 eap_send_nak(esp, id, EAPT_SRP);
1814 /* Not so likely to happen. */
1815 if (len - vallen >= sizeof (rhostname)) {
1816 dbglog("EAP: trimming really long peer name down");
1817 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1818 rhostname[sizeof (rhostname) - 1] = '\0';
1820 BCOPY(inp + vallen, rhostname, len - vallen);
1821 rhostname[len - vallen] = '\0';
1824 /* In case the remote doesn't give us his name. */
1825 if (explicit_remote ||
1826 (remote_name[0] != '\0' && vallen == len))
1827 strlcpy(rhostname, remote_name, sizeof (rhostname));
1830 * Get the secret for authenticating ourselves with
1831 * the specified host.
1833 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1834 rhostname, secret, &secret_len, 0)) {
1835 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1836 eap_send_nak(esp, id, EAPT_SRP);
1840 mdctx = PPP_MD_CTX_new();
1841 if (mdctx != NULL) {
1842 if (PPP_DigestInit(mdctx, PPP_md5())) {
1844 if (PPP_DigestUpdate(mdctx, &typenum, 1)) {
1845 if (PPP_DigestUpdate(mdctx, secret, secret_len)) {
1846 BZERO(secret, sizeof(secret));
1847 if (PPP_DigestUpdate(mdctx, inp, vallen)) {
1848 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
1849 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1850 esp->es_client.ea_namelen);
1851 PPP_MD_CTX_free(mdctx);
1858 PPP_MD_CTX_free(mdctx);
1860 dbglog("EAP: Invalid MD5 checksum");
1861 eap_send_nak(esp, id, EAPT_SRP);
1864 #ifdef PPP_WITH_EAPTLS
1867 switch(esp->es_client.ea_state) {
1872 error("EAP: received EAP-TLS Listen packet with no data");
1873 /* Bogus request; wait for something real. */
1876 GETCHAR(flags, inp);
1877 if(flags & EAP_TLS_FLAGS_START){
1879 esp->es_client.ea_using_eaptls = 1;
1881 if (explicit_remote){
1882 esp->es_client.ea_peer = strdup(remote_name);
1883 esp->es_client.ea_peerlen = strlen(remote_name);
1885 esp->es_client.ea_peer = NULL;
1887 /* Init ssl session */
1888 if(!eaptls_init_ssl_client(esp)) {
1889 dbglog("cannot init ssl");
1890 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1891 esp->es_client.ea_using_eaptls = 0;
1895 ets = esp->es_client.ea_session;
1896 eap_tls_response(esp, id);
1897 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1901 /* The server has sent a bad start packet. */
1902 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1906 eap_tls_response(esp, id);
1907 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1912 error("EAP: discarding EAP-TLS Receive packet with no data");
1913 /* Bogus request; wait for something real. */
1916 eaptls_receive(ets, inp, len);
1919 eap_tls_sendack(esp, id);
1920 esp->es_client.ea_state = eapTlsRecv;
1924 if(ets->alert_recv) {
1925 eap_tls_sendack(esp, id);
1926 esp->es_client.ea_state = eapTlsRecvFailure;
1930 /* Check if TLS handshake is finished */
1931 if(eaptls_is_init_finished(ets)) {
1932 #ifdef PPP_WITH_MPPE
1933 eaptls_gen_mppe_keys(ets, 1);
1935 eaptls_free_session(ets);
1936 eap_tls_sendack(esp, id);
1937 esp->es_client.ea_state = eapTlsRecvSuccess;
1941 eap_tls_response(esp,id);
1942 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1946 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1947 esp->es_client.ea_using_eaptls = 0;
1952 #endif /* PPP_WITH_EAPTLS */
1957 error("EAP: received empty SRP Request");
1958 /* Bogus request; wait for something real. */
1963 GETCHAR(vallen, inp);
1966 case EAPSRP_CHALLENGE:
1968 if (esp->es_client.ea_session != NULL) {
1969 tc = (struct t_client *)esp->es_client.
1972 * If this is a new challenge, then start
1973 * over with a new client session context.
1974 * Otherwise, just resend last response.
1976 if (id != esp->es_client.ea_id) {
1978 esp->es_client.ea_session = NULL;
1982 /* No session key just yet */
1983 esp->es_client.ea_skey = NULL;
1985 GETCHAR(vallen, inp);
1987 if (vallen >= len) {
1988 error("EAP: badly-formed SRP Challenge"
1990 /* Ignore badly-formed messages */
1993 BCOPY(inp, rhostname, vallen);
1994 rhostname[vallen] = '\0';
1995 INCPTR(vallen, inp);
1999 * In case the remote doesn't give us his name,
2000 * use configured name.
2002 if (explicit_remote ||
2003 (remote_name[0] != '\0' && vallen == 0)) {
2004 strlcpy(rhostname, remote_name,
2005 sizeof (rhostname));
2008 if (esp->es_client.ea_peer != NULL)
2009 free(esp->es_client.ea_peer);
2010 esp->es_client.ea_peer = strdup(rhostname);
2011 esp->es_client.ea_peerlen = strlen(rhostname);
2013 GETCHAR(vallen, inp);
2015 if (vallen >= len) {
2016 error("EAP: badly-formed SRP Challenge"
2018 /* Ignore badly-formed messages */
2023 INCPTR(vallen, inp);
2026 GETCHAR(vallen, inp);
2029 error("EAP: badly-formed SRP Challenge"
2031 /* Ignore badly-formed messages */
2034 /* If no generator present, then use value 2 */
2036 gval.data = (u_char *)"\002";
2042 INCPTR(vallen, inp);
2046 * If no modulus present, then use well-known
2050 Nval.data = (u_char *)wkmodulus;
2051 Nval.len = sizeof (wkmodulus);
2056 tc = t_clientopen(esp->es_client.ea_name,
2057 &Nval, &gval, &sval);
2059 eap_send_nak(esp, id, EAPT_MD5CHAP);
2062 esp->es_client.ea_session = (void *)tc;
2064 /* Add Challenge ID & type to verifier */
2067 t_clientaddexdata(tc, vals, 2);
2069 Ap = t_clientgenexp(tc);
2070 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2075 tc = (struct t_client *)esp->es_client.ea_session;
2077 warn("EAP: peer sent Subtype 2 without 1");
2078 eap_send_nak(esp, id, EAPT_MD5CHAP);
2081 if (esp->es_client.ea_skey != NULL) {
2083 * ID number should not change here. Warn
2084 * if it does (but otherwise ignore).
2086 if (id != esp->es_client.ea_id) {
2087 warn("EAP: ID changed from %d to %d "
2088 "in SRP Subtype 2 rexmit",
2089 esp->es_client.ea_id, id);
2092 if (get_srp_secret(esp->es_unit,
2093 esp->es_client.ea_name,
2094 esp->es_client.ea_peer, secret, 0) == 0) {
2096 * Can't work with this peer because
2097 * the secret is missing. Just give
2100 eap_send_nak(esp, id, EAPT_MD5CHAP);
2105 t_clientpasswd(tc, secret);
2106 BZERO(secret, sizeof (secret));
2107 esp->es_client.ea_skey =
2108 t_clientgetkey(tc, &Bval);
2109 if (esp->es_client.ea_skey == NULL) {
2110 /* Server is rogue; stop now */
2111 error("EAP: SRP server is rogue");
2112 goto client_failure;
2115 eap_srpval_response(esp, id, SRPVAL_EBIT,
2116 t_clientresponse(tc));
2119 case EAPSRP_SVALIDATOR:
2120 tc = (struct t_client *)esp->es_client.ea_session;
2121 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2122 warn("EAP: peer sent Subtype 3 without 1/2");
2123 eap_send_nak(esp, id, EAPT_MD5CHAP);
2127 * If we're already open, then this ought to be a
2128 * duplicate. Otherwise, check that the server is
2129 * who we think it is.
2131 if (esp->es_client.ea_state == eapOpen) {
2132 if (id != esp->es_client.ea_id) {
2133 warn("EAP: ID changed from %d to %d "
2134 "in SRP Subtype 3 rexmit",
2135 esp->es_client.ea_id, id);
2138 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2139 if (len < 0 || t_clientverify(tc, inp +
2140 sizeof (u_int32_t)) != 0) {
2141 error("EAP: SRP server verification "
2143 goto client_failure;
2145 GETLONG(esp->es_client.ea_keyflags, inp);
2146 /* Save pseudonym if user wants it. */
2147 if (len > 0 && esp->es_usepseudo) {
2148 INCPTR(SHA_DIGESTSIZE, inp);
2149 write_pseudonym(esp, inp, len, id);
2153 * We've verified our peer. We're now mostly done,
2154 * except for waiting on the regular EAP Success
2157 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2160 case EAPSRP_LWRECHALLENGE:
2162 warn("EAP: malformed Lightweight rechallenge");
2165 ctxt = PPP_MD_CTX_new();
2169 PPP_DigestInit(ctxt, PPP_sha1());
2170 PPP_DigestUpdate(ctxt, vals, 1);
2171 PPP_DigestUpdate(ctxt, esp->es_client.ea_skey,
2173 PPP_DigestUpdate(ctxt, inp, len);
2174 PPP_DigestUpdate(ctxt, esp->es_client.ea_name,
2175 esp->es_client.ea_namelen);
2176 PPP_DigestFinal(ctxt, dig, &diglen);
2178 PPP_MD_CTX_free(ctxt);
2180 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2186 error("EAP: unknown SRP Subtype %d", vallen);
2187 eap_send_nak(esp, id, EAPT_MD5CHAP);
2191 #endif /* PPP_WITH_SRP */
2193 #ifdef PPP_WITH_CHAPMS
2196 error("EAP: received invalid MSCHAPv2 packet, too short");
2199 unsigned char opcode;
2200 GETCHAR(opcode, inp);
2201 unsigned char chapid; /* Chapv2-ID */
2202 GETCHAR(chapid, inp);
2204 GETSHORT(mssize, inp);
2206 /* Validate the mssize field */
2207 if (len != mssize) {
2208 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2213 /* If MSCHAPv2 digest was not found, NAK the packet */
2214 if (!esp->es_client.digest) {
2215 error("EAP MSCHAPv2 not supported");
2216 eap_send_nak(esp, id, EAPT_SRP);
2221 case CHAP_CHALLENGE: {
2223 /* make_response() expects: VLEN + VALUE */
2224 u_char *challenge = inp;
2226 unsigned char vsize;
2227 GETCHAR(vsize, inp);
2230 /* Validate the VALUE field */
2231 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2232 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2236 /* Increment past the VALUE field */
2237 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2238 len -= MS_CHAP2_PEER_CHAL_LEN;
2240 /* Extract the hostname */
2241 rhostname[0] = '\0';
2243 if (len >= sizeof (rhostname)) {
2244 dbglog("EAP: trimming really long peer name down");
2245 len = sizeof(rhostname) - 1;
2247 BCOPY(inp, rhostname, len);
2248 rhostname[len] = '\0';
2251 /* In case the remote doesn't give us his name. */
2252 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2253 strlcpy(rhostname, remote_name, sizeof(rhostname));
2255 /* Get the secret for authenticating ourselves with the specified host. */
2256 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2257 rhostname, secret, &secret_len, 0)) {
2258 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2259 eap_send_nak(esp, id, EAPT_SRP);
2262 esp->es_client.ea_namelen = strlen(esp->es_client.ea_name);
2264 /* Create the MSCHAPv2 response (and add to cache) */
2265 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2266 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2267 challenge, secret, secret_len, NULL);
2269 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2272 case CHAP_SUCCESS: {
2274 /* Check response for mutual authentication */
2275 u_char status = CHAP_FAILURE;
2276 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2277 info("Chap authentication succeeded! %.*v", len, inp);
2278 status = CHAP_SUCCESS;
2280 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2283 case CHAP_FAILURE: {
2285 /* Process the failure string, and log appropriate information */
2286 esp->es_client.digest->handle_failure(inp, len);
2288 u_char status = CHAP_FAILURE;
2289 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2290 goto client_failure; /* force termination */
2294 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2295 eap_send_nak(esp, id, EAPT_SRP);
2299 #endif /* PPP_WITH_CHAPMS */
2300 #ifdef PPP_WITH_PEAP
2303 /* Initialize the PEAP context (if not already initialized) */
2304 if (!esp->ea_peap) {
2305 rhostname[0] = '\0';
2306 if (explicit_remote || (remote_name[0] != '\0')) {
2307 strlcpy(rhostname, remote_name, sizeof (rhostname));
2309 if (peap_init(&esp->ea_peap, rhostname)) {
2310 eap_send_nak(esp, id, EAPT_TLS);
2315 /* Process the PEAP packet */
2316 if (peap_process(esp, id, inp, len)) {
2317 eap_send_nak(esp, id, EAPT_TLS);
2321 #endif // PPP_WITH_PEAP
2324 info("EAP: unknown authentication type %d; Naking", typenum);
2325 eap_send_nak(esp, id, EAPT_SRP);
2329 if (esp->es_client.ea_timeout > 0) {
2330 UNTIMEOUT(eap_client_timeout, (void *)esp);
2331 TIMEOUT(eap_client_timeout, (void *)esp,
2332 esp->es_client.ea_timeout);
2337 esp->es_client.ea_state = eapBadAuth;
2338 if (esp->es_client.ea_timeout > 0) {
2339 UNTIMEOUT(eap_client_timeout, (void *)esp);
2341 esp->es_client.ea_session = NULL;
2344 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2345 #endif /* PPP_WITH_SRP */
2349 * eap_response - Receive EAP Response message (server mode).
2352 eap_response(eap_state *esp, u_char *inp, int id, int len)
2357 char secret[MAXSECRETLEN];
2358 char rhostname[256];
2360 u_char hash[MD5_DIGEST_LENGTH];
2361 int hashlen = MD5_DIGEST_LENGTH;
2363 struct t_server *ts;
2366 u_char dig[SHA_DIGESTSIZE];
2367 int diglen = sizeof(dig);
2368 #endif /* PPP_WITH_SRP */
2370 #ifdef PPP_WITH_EAPTLS
2371 struct eaptls_session *ets;
2373 #endif /* PPP_WITH_EAPTLS */
2374 #ifdef PPP_WITH_CHAPMS
2376 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2377 unsigned char *, unsigned char *, char *, int);
2378 char response_message[256];
2379 #endif /* PPP_WITH_CHAPMS */
2382 * Ignore responses if we're not open
2384 if (esp->es_server.ea_state <= eapClosed)
2387 if (esp->es_server.ea_id != id) {
2388 dbglog("EAP: discarding Response %d; expected ID %d", id,
2389 esp->es_server.ea_id);
2393 esp->es_server.ea_responses++;
2396 error("EAP: empty Response message discarded");
2400 GETCHAR(typenum, inp);
2405 if (esp->es_server.ea_state != eapIdentify) {
2406 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2410 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2411 if (esp->es_server.ea_peer != NULL &&
2412 esp->es_server.ea_peer != remote_name)
2413 free(esp->es_server.ea_peer);
2414 esp->es_server.ea_peer = malloc(len + 1);
2415 if (esp->es_server.ea_peer == NULL) {
2416 esp->es_server.ea_peerlen = 0;
2417 eap_figure_next_state(esp, 1);
2420 BCOPY(inp, esp->es_server.ea_peer, len);
2421 esp->es_server.ea_peer[len] = '\0';
2422 esp->es_server.ea_peerlen = len;
2423 eap_figure_next_state(esp, 0);
2426 #ifdef PPP_WITH_EAPTLS
2428 switch(esp->es_server.ea_state) {
2432 ets = (struct eaptls_session *) esp->es_server.ea_session;
2434 eap_figure_next_state(esp,
2435 eaptls_receive(esp->es_server.ea_session, inp, len));
2437 if(ets->alert_recv) {
2438 eap_send_failure(esp);
2445 dbglog("EAP-TLS ACK with extra data");
2447 eap_figure_next_state(esp, 0);
2450 case eapTlsRecvClient:
2451 /* Receive authentication response from client */
2453 GETCHAR(flags, inp);
2455 if(len == 1 && !flags) { /* Ack = ok */
2456 #ifdef PPP_WITH_MPPE
2457 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2459 eap_send_success(esp);
2461 else { /* failure */
2462 warn("Server authentication failed");
2463 eap_send_failure(esp);
2467 warn("Bogus EAP-TLS packet received from client");
2469 eaptls_free_session(esp->es_server.ea_session);
2473 case eapTlsRecvAlertAck:
2474 eap_send_failure(esp);
2478 eap_figure_next_state(esp, 1);
2482 #endif /* PPP_WITH_EAPTLS */
2484 case EAPT_NOTIFICATION:
2485 dbglog("EAP unexpected Notification; response discarded");
2490 info("EAP: Nak Response with no suggested protocol");
2491 eap_figure_next_state(esp, 1);
2495 GETCHAR(vallen, inp);
2498 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2499 /* Peer cannot Nak Identify Request */
2500 eap_figure_next_state(esp, 1);
2506 /* Run through SRP validator selection again. */
2507 esp->es_server.ea_state = eapIdentify;
2508 eap_figure_next_state(esp, 0);
2512 esp->es_server.ea_state = eapMD5Chall;
2515 #ifdef PPP_WITH_EAPTLS
2516 /* Send EAP-TLS start packet */
2518 esp->es_server.ea_state = eapTlsStart;
2520 #endif /* PPP_WITH_EAPTLS */
2522 #ifdef PPP_WITH_CHAPMS
2524 info("EAP: peer proposes MSCHAPv2");
2525 /* If MSCHAPv2 digest was not found, NAK the packet */
2526 if (!esp->es_server.digest) {
2527 error("EAP MSCHAPv2 not supported");
2528 eap_send_nak(esp, id, EAPT_SRP);
2531 esp->es_server.ea_state = eapMSCHAPv2Chall;
2533 #endif /* PPP_WITH_CHAPMS */
2536 dbglog("EAP: peer requesting unknown Type %d", vallen);
2537 switch (esp->es_server.ea_state) {
2541 esp->es_server.ea_state = eapMD5Chall;
2545 esp->es_server.ea_state = eapIdentify;
2546 eap_figure_next_state(esp, 0);
2556 if (esp->es_server.ea_state != eapMD5Chall) {
2557 error("EAP: unexpected MD5-Response");
2558 eap_figure_next_state(esp, 1);
2562 error("EAP: received MD5-Response with no data");
2563 eap_figure_next_state(esp, 1);
2566 GETCHAR(vallen, inp);
2568 if (vallen != 16 || vallen > len) {
2569 error("EAP: MD5-Response with bad length %d", vallen);
2570 eap_figure_next_state(esp, 1);
2574 /* Not so likely to happen. */
2575 if (len - vallen >= sizeof (rhostname)) {
2576 dbglog("EAP: trimming really long peer name down");
2577 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2578 rhostname[sizeof (rhostname) - 1] = '\0';
2580 BCOPY(inp + vallen, rhostname, len - vallen);
2581 rhostname[len - vallen] = '\0';
2584 /* In case the remote doesn't give us his name. */
2585 if (explicit_remote ||
2586 (remote_name[0] != '\0' && vallen == len))
2587 strlcpy(rhostname, remote_name, sizeof (rhostname));
2590 * Get the secret for authenticating the specified
2593 if (!get_secret(esp->es_unit, rhostname,
2594 esp->es_server.ea_name, secret, &secret_len, 1)) {
2595 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2596 eap_send_failure(esp);
2600 mdctx = PPP_MD_CTX_new();
2601 if (mdctx != NULL) {
2603 if (PPP_DigestInit(mdctx, PPP_md5())) {
2605 if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
2607 if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
2609 BZERO(secret, sizeof(secret));
2610 if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
2612 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
2614 if (BCMP(hash, inp, MD5_DIGEST_LENGTH) == 0) {
2616 esp->es_server.ea_type = EAPT_MD5CHAP;
2617 eap_send_success(esp);
2618 eap_figure_next_state(esp, 0);
2620 if (esp->es_rechallenge != 0) {
2621 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2623 PPP_MD_CTX_free(mdctx);
2632 PPP_MD_CTX_free(mdctx);
2635 eap_send_failure(esp);
2638 #ifdef PPP_WITH_CHAPMS
2641 error("EAP: received MSCHAPv2 with no data");
2642 eap_figure_next_state(esp, 1);
2645 GETCHAR(opcode, inp);
2650 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2651 error("EAP: unexpected MSCHAPv2-Response");
2652 eap_figure_next_state(esp, 1);
2655 /* skip MS ID + len */
2657 GETCHAR(vallen, inp);
2660 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2661 error("EAP: Invalid MSCHAPv2-Response "
2662 "length %d", vallen);
2663 eap_figure_next_state(esp, 1);
2667 /* Not so likely to happen. */
2668 if (len - vallen >= sizeof (rhostname)) {
2669 dbglog("EAP: trimming really long peer name down");
2670 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2671 rhostname[sizeof (rhostname) - 1] = '\0';
2673 BCOPY(inp + vallen, rhostname, len - vallen);
2674 rhostname[len - vallen] = '\0';
2677 /* In case the remote doesn't give us his name. */
2678 if (explicit_remote ||
2679 (remote_name[0] != '\0' && vallen == len))
2680 strlcpy(rhostname, remote_name, sizeof (rhostname));
2682 /* strip the MS domain name */
2683 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2684 char tmp[MAXNAMELEN+1];
2686 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2687 strcpy(rhostname, tmp);
2690 if (chap_verify_hook)
2691 chap_verifier = chap_verify_hook;
2693 chap_verifier = eap_chap_verify_response;
2695 esp->es_server.ea_id += 1;
2696 if ((*chap_verifier)(rhostname,
2697 esp->es_server.ea_name,
2699 esp->es_server.digest,
2703 sizeof(response_message)))
2705 info("EAP: MSCHAPv2 success for peer %q",
2707 esp->es_server.ea_type = EAPT_MSCHAPV2;
2708 eap_chapms2_send_request(esp,
2709 esp->es_server.ea_id,
2711 esp->es_server.ea_id,
2713 strlen(response_message));
2714 eap_figure_next_state(esp, 0);
2715 if (esp->es_rechallenge != 0)
2716 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2719 warn("EAP: MSCHAPv2 failure for peer %q",
2721 eap_chapms2_send_request(esp,
2722 esp->es_server.ea_id,
2724 esp->es_server.ea_id,
2726 strlen(response_message));
2730 info("EAP: MSCHAPv2 success confirmed");
2733 info("EAP: MSCHAPv2 failure confirmed");
2736 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2737 eap_send_nak(esp, id, EAPT_SRP);
2741 #endif /* PPP_WITH_CHAPMS */
2746 error("EAP: empty SRP Response");
2747 eap_figure_next_state(esp, 1);
2750 GETCHAR(typenum, inp);
2754 if (esp->es_server.ea_state != eapSRP1) {
2755 error("EAP: unexpected SRP Subtype 1 Response");
2756 eap_figure_next_state(esp, 1);
2761 ts = (struct t_server *)esp->es_server.ea_session;
2763 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2764 if (esp->es_server.ea_skey == NULL) {
2765 /* Client's A value is bogus; terminate now */
2766 error("EAP: bogus A value from client");
2767 eap_send_failure(esp);
2769 eap_figure_next_state(esp, 0);
2773 case EAPSRP_CVALIDATOR:
2774 if (esp->es_server.ea_state != eapSRP2) {
2775 error("EAP: unexpected SRP Subtype 2 Response");
2776 eap_figure_next_state(esp, 1);
2779 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2780 error("EAP: M1 length %d < %d", len,
2781 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2782 eap_figure_next_state(esp, 1);
2785 GETLONG(esp->es_server.ea_keyflags, inp);
2786 ts = (struct t_server *)esp->es_server.ea_session;
2788 if (t_serververify(ts, inp)) {
2789 info("EAP: unable to validate client identity");
2790 eap_send_failure(esp);
2793 eap_figure_next_state(esp, 0);
2797 if (esp->es_server.ea_state != eapSRP3) {
2798 error("EAP: unexpected SRP Subtype 3 Response");
2799 eap_send_failure(esp);
2802 esp->es_server.ea_type = EAPT_SRP;
2803 eap_send_success(esp);
2804 eap_figure_next_state(esp, 0);
2805 if (esp->es_rechallenge != 0)
2806 TIMEOUT(eap_rechallenge, esp,
2807 esp->es_rechallenge);
2808 if (esp->es_lwrechallenge != 0)
2809 TIMEOUT(srp_lwrechallenge, esp,
2810 esp->es_lwrechallenge);
2813 case EAPSRP_LWRECHALLENGE:
2814 if (esp->es_server.ea_state != eapSRP4) {
2815 info("EAP: unexpected SRP Subtype 4 Response");
2818 if (len != SHA_DIGESTSIZE) {
2819 error("EAP: bad Lightweight rechallenge "
2823 ctxt = PPP_MD_CTX_new();
2827 PPP_DigestInit(ctxt, PPP_sha1());
2828 PPP_DigestUpdate(ctxt, &vallen, 1);
2829 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
2831 PPP_DigestUpdate(ctxt, esp->es_challenge, esp->es_challen);
2832 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
2833 esp->es_server.ea_peerlen);
2834 PPP_DigestFinal(ctxt, dig, &diglen);
2836 PPP_MD_CTX_free(ctxt);
2838 if (BCMP(dig, inp, SHA_DIGEST_LENGTH) != 0) {
2839 error("EAP: failed Lightweight rechallenge");
2840 eap_send_failure(esp);
2844 esp->es_server.ea_state = eapOpen;
2845 if (esp->es_lwrechallenge != 0)
2846 TIMEOUT(srp_lwrechallenge, esp,
2847 esp->es_lwrechallenge);
2852 #endif /* PPP_WITH_SRP */
2855 /* This can't happen. */
2856 error("EAP: unknown Response type %d; ignored", typenum);
2860 if (esp->es_server.ea_timeout > 0) {
2861 UNTIMEOUT(eap_server_timeout, (void *)esp);
2864 if (esp->es_server.ea_state != eapBadAuth &&
2865 esp->es_server.ea_state != eapOpen) {
2866 esp->es_server.ea_id++;
2867 eap_send_request(esp);
2872 * eap_success - Receive EAP Success message (client mode).
2875 eap_success(eap_state *esp, u_char *inp, int id, int len)
2877 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2878 #ifdef PPP_WITH_EAPTLS
2879 && esp->es_client.ea_state != eapTlsRecvSuccess
2880 #endif /* PPP_WITH_EAPTLS */
2882 dbglog("EAP unexpected success message in state %s (%d)",
2883 eap_state_name(esp->es_client.ea_state),
2884 esp->es_client.ea_state);
2888 #ifdef PPP_WITH_EAPTLS
2889 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2890 eapTlsRecvSuccess) {
2891 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2892 eap_state_name(esp->es_client.ea_state),
2893 esp->es_client.ea_state);
2896 #endif /* PPP_WITH_EAPTLS */
2898 if (esp->es_client.ea_timeout > 0) {
2899 UNTIMEOUT(eap_client_timeout, (void *)esp);
2903 /* This is odd. The spec doesn't allow for this. */
2907 #ifdef PPP_WITH_PEAP
2908 peap_finish(&esp->ea_peap);
2911 esp->es_client.ea_state = eapOpen;
2912 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2916 * eap_failure - Receive EAP Failure message (client mode).
2919 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2922 * Ignore failure messages if we're not open
2924 if (esp->es_client.ea_state <= eapClosed)
2927 if (!eap_client_active(esp)) {
2928 dbglog("EAP unexpected failure message in state %s (%d)",
2929 eap_state_name(esp->es_client.ea_state),
2930 esp->es_client.ea_state);
2933 if (esp->es_client.ea_timeout > 0) {
2934 UNTIMEOUT(eap_client_timeout, (void *)esp);
2938 /* This is odd. The spec doesn't allow for this. */
2942 esp->es_client.ea_state = eapBadAuth;
2944 error("EAP: peer reports authentication failure");
2946 #ifdef PPP_WITH_PEAP
2947 peap_finish(&esp->ea_peap);
2950 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2954 * eap_input - Handle received EAP message.
2957 eap_input(int unit, u_char *inp, int inlen)
2959 eap_state *esp = &eap_states[unit];
2964 * Parse header (code, id and length). If packet too short,
2967 if (inlen < EAP_HEADERLEN) {
2968 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2974 if (len < EAP_HEADERLEN || len > inlen) {
2975 error("EAP: packet has illegal length field %d (%d..%d)", len,
2976 EAP_HEADERLEN, inlen);
2979 len -= EAP_HEADERLEN;
2981 /* Dispatch based on message code */
2984 eap_request(esp, inp, id, len);
2988 eap_response(esp, inp, id, len);
2992 eap_success(esp, inp, id, len);
2996 eap_failure(esp, inp, id, len);
2999 default: /* XXX Need code reject */
3000 /* Note: it's not legal to send EAP Nak here. */
3001 warn("EAP: unknown code %d received", code);
3007 * eap_printpkt - print the contents of an EAP packet.
3009 static char *eap_codenames[] = {
3010 "Request", "Response", "Success", "Failure"
3013 static char *eap_typenames[] = {
3014 "Identity", "Notification", "Nak", "MD5-Challenge",
3015 "OTP", "Generic-Token", NULL, NULL,
3016 "RSA", "DSS", "KEA", "KEA-Validate",
3017 "TLS", "Defender", "Windows 2000", "Arcot",
3018 "Cisco", "Nokia", "SRP", NULL,
3019 "TTLS", "RAS", "AKA", "3COM", "PEAP",
3024 eap_printpkt(u_char *inp, int inlen,
3025 void (*printer) (void *, char *, ...), void *arg)
3027 int code, id, len, rtype, vallen;
3030 #ifdef PPP_WITH_EAPTLS
3032 #endif /* PPP_WITH_EAPTLS */
3033 #ifdef PPP_WITH_CHAPMS
3035 #endif /* PPP_WITH_CHAPMS */
3037 if (inlen < EAP_HEADERLEN)
3043 if (len < EAP_HEADERLEN || len > inlen)
3046 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
3047 printer(arg, " %s", eap_codenames[code-1]);
3049 printer(arg, " code=0x%x", code);
3050 printer(arg, " id=0x%x", id);
3051 len -= EAP_HEADERLEN;
3055 printer(arg, " <missing type>");
3058 GETCHAR(rtype, inp);
3061 rtype <= sizeof (eap_typenames) / sizeof (char *))
3062 printer(arg, " %s", eap_typenames[rtype-1]);
3064 printer(arg, " type=0x%x", rtype);
3067 case EAPT_NOTIFICATION:
3069 printer(arg, " <Message ");
3070 print_string((char *)inp, len, printer, arg);
3075 printer(arg, " <No message>");
3082 GETCHAR(vallen, inp);
3086 printer(arg, " <Value%.*B>", vallen, inp);
3087 INCPTR(vallen, inp);
3090 printer(arg, " <Name ");
3091 print_string((char *)inp, len, printer, arg);
3096 printer(arg, " <No name>");
3100 #ifdef PPP_WITH_CHAPMS
3104 GETCHAR(opcode, inp);
3107 case CHAP_CHALLENGE:
3110 GETCHAR(vallen, inp);
3115 printer(arg, " Challenge <");
3116 for (; vallen > 0; --vallen) {
3119 printer(arg, "%.2x", val);
3123 printer(arg, ", <Name ");
3124 print_string((char *)inp, len, printer, arg);
3129 printer(arg, ", <No name>");
3135 printer(arg, " Success <Message ");
3136 print_string((char *)inp, len, printer, arg);
3142 printer(arg, " Failure <Message ");
3143 print_string((char *)inp, len, printer, arg);
3149 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3153 #endif /* PPP_WITH_CHAPMS */
3155 #ifdef PPP_WITH_EAPTLS
3159 GETCHAR(flags, inp);
3162 if(flags == 0 && len == 0){
3163 printer(arg, " Ack");
3167 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3168 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3169 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3171 #endif /* PPP_WITH_EAPTLS */
3177 GETCHAR(vallen, inp);
3179 printer(arg, "-%d", vallen);
3181 case EAPSRP_CHALLENGE:
3182 GETCHAR(vallen, inp);
3187 printer(arg, " <Name ");
3188 print_string((char *)inp, vallen, printer,
3192 printer(arg, " <No name>");
3194 INCPTR(vallen, inp);
3196 GETCHAR(vallen, inp);
3200 printer(arg, " <s%.*B>", vallen, inp);
3201 INCPTR(vallen, inp);
3203 GETCHAR(vallen, inp);
3208 printer(arg, " <Default g=2>");
3210 printer(arg, " <g%.*B>", vallen, inp);
3212 INCPTR(vallen, inp);
3215 printer(arg, " <Default N>");
3217 printer(arg, " <N%.*B>", len, inp);
3224 printer(arg, " <B%.*B>", len, inp);
3229 case EAPSRP_SVALIDATOR:
3230 if (len < sizeof (u_int32_t))
3233 len -= sizeof (u_int32_t);
3234 if (uval & SRPVAL_EBIT) {
3236 uval &= ~SRPVAL_EBIT;
3239 printer(arg, " f<%X>", uval);
3241 if ((vallen = len) > SHA_DIGESTSIZE)
3242 vallen = SHA_DIGESTSIZE;
3243 printer(arg, " <M2%.*B%s>", len, inp,
3244 len < SHA_DIGESTSIZE ? "?" : "");
3245 INCPTR(vallen, inp);
3248 printer(arg, " <PN%.*B>", len, inp);
3254 case EAPSRP_LWRECHALLENGE:
3255 printer(arg, " <Challenge%.*B>", len, inp);
3261 #endif /* PPP_WITH_SRP */
3268 GETCHAR(rtype, inp);
3271 rtype <= sizeof (eap_typenames) / sizeof (char *))
3272 printer(arg, " %s", eap_typenames[rtype-1]);
3274 printer(arg, " type=0x%x", rtype);
3278 printer(arg, " <Name ");
3279 print_string((char *)inp, len, printer, arg);
3286 #ifdef PPP_WITH_EAPTLS
3290 GETCHAR(flags, inp);
3293 if(flags == 0 && len == 0){
3294 printer(arg, " Ack");
3298 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3299 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3300 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3303 #endif /* PPP_WITH_EAPTLS */
3307 printer(arg, " <missing hint>");
3310 GETCHAR(rtype, inp);
3312 printer(arg, " <Suggested-type %02X", rtype);
3314 rtype <= sizeof (eap_typenames) / sizeof (char *))
3315 printer(arg, " (%s)", eap_typenames[rtype-1]);
3321 printer(arg, " <missing length>");
3324 GETCHAR(vallen, inp);
3328 printer(arg, " <Value%.*B>", vallen, inp);
3329 INCPTR(vallen, inp);
3332 printer(arg, " <Name ");
3333 print_string((char *)inp, len, printer, arg);
3338 printer(arg, " <No name>");
3342 #ifdef PPP_WITH_CHAPMS
3346 GETCHAR(opcode, inp);
3352 GETCHAR(vallen, inp);
3357 printer(arg, " Response <");
3358 for (; vallen > 0; --vallen) {
3361 printer(arg, "%.2x", val);
3365 printer(arg, ", <Name ");
3366 print_string((char *)inp, len, printer, arg);
3371 printer(arg, ", <No name>");
3375 printer(arg, " Success");
3378 printer(arg, " Failure");
3381 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3385 #endif /* PPP_WITH_CHAPMS */
3391 GETCHAR(vallen, inp);
3393 printer(arg, "-%d", vallen);
3396 printer(arg, " <A%.*B>", len, inp);
3401 case EAPSRP_CVALIDATOR:
3402 if (len < sizeof (u_int32_t))
3405 len -= sizeof (u_int32_t);
3406 if (uval & SRPVAL_EBIT) {
3408 uval &= ~SRPVAL_EBIT;
3411 printer(arg, " f<%X>", uval);
3413 printer(arg, " <M1%.*B%s>", len, inp,
3414 len == SHA_DIGESTSIZE ? "" : "?");
3422 case EAPSRP_LWRECHALLENGE:
3423 printer(arg, " <Response%.*B%s>", len, inp,
3424 len == SHA_DIGESTSIZE ? "" : "?");
3425 if ((vallen = len) > SHA_DIGESTSIZE)
3426 vallen = SHA_DIGESTSIZE;
3427 INCPTR(vallen, inp);
3432 #endif /* PPP_WITH_SRP */
3436 case EAP_SUCCESS: /* No payload expected for these! */
3441 printer(arg, " <truncated>");
3446 printer(arg, "%8B...", inp);
3448 printer(arg, "%.*B", len, inp);
3451 return (inp - pstart);