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>
66 #include "pppd-private.h"
68 #include "pathnames.h"
70 #include "crypto_ms.h"
74 #endif /* PPP_WITH_PEAP */
83 #endif /* PPP_WITH_SRP */
85 #ifdef PPP_WITH_EAPTLS
87 #endif /* PPP_WITH_EAPTLS */
89 #ifdef PPP_WITH_CHAPMS
93 extern int chapms_strip_domain;
94 #endif /* PPP_WITH_CHAPMS */
96 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
98 static char *pn_secret = NULL; /* Pseudonym generating secret */
102 * Command-line options.
104 static struct option eap_option_list[] = {
105 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
106 "Set retransmit timeout for EAP Requests (server)" },
107 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
108 "Set max number of EAP Requests sent (server)" },
109 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
110 "Set time limit for peer EAP authentication" },
111 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
112 "Set max number of EAP Requests allows (client)" },
113 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
114 "Set interval for EAP rechallenge" },
116 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
117 "Set interval for SRP lightweight rechallenge" },
118 { "srp-pn-secret", o_string, &pn_secret,
119 "Long term pseudonym generation secret" },
120 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
121 "Use pseudonym if offered one by server", 1 },
127 * Protocol entry points.
129 static void eap_init (int unit);
130 static void eap_input (int unit, u_char *inp, int inlen);
131 static void eap_protrej (int unit);
132 static void eap_lowerup (int unit);
133 static void eap_lowerdown (int unit);
134 static int eap_printpkt (u_char *inp, int inlen,
135 void (*)(void *arg, char *fmt, ...), void *arg);
137 struct protent eap_protent = {
138 PPP_EAP, /* protocol number */
139 eap_init, /* initialization procedure */
140 eap_input, /* process a received packet */
141 eap_protrej, /* process a received protocol-reject */
142 eap_lowerup, /* lower layer has gone up */
143 eap_lowerdown, /* lower layer has gone down */
144 NULL, /* open the protocol */
145 NULL, /* close the protocol */
146 eap_printpkt, /* print a packet in readable form */
147 NULL, /* process a received data packet */
148 1, /* protocol enabled */
149 "EAP", /* text name of protocol */
150 NULL, /* text name of corresponding data protocol */
151 eap_option_list, /* list of command-line options */
152 NULL, /* check requested options; assign defaults */
153 NULL, /* configure interface for demand-dial */
154 NULL /* say whether to bring up link for this pkt */
159 * A well-known 2048 bit modulus.
161 static const u_char wkmodulus[] = {
162 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
163 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
164 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
165 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
166 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
167 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
168 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
169 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
170 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
171 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
172 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
173 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
174 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
175 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
176 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
177 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
178 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
179 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
180 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
181 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
182 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
183 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
184 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
185 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
186 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
187 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
188 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
189 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
190 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
191 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
192 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
193 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
195 #endif /* PPP_WITH_SRP */
197 /* Local forward declarations. */
198 static void eap_server_timeout (void *arg);
201 * Convert EAP state code to printable string for debug.
204 eap_state_name(enum eap_state_code esc)
206 static const char *state_names[] = { EAP_STATES };
208 return (state_names[(int)esc]);
212 * eap_init - Initialize state for an EAP user. This is currently
213 * called once by main() during start-up.
218 eap_state *esp = &eap_states[unit];
220 BZERO(esp, sizeof (*esp));
222 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
223 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
224 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
225 esp->es_client.ea_timeout = EAP_DEFREQTIME;
226 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
227 #ifdef PPP_WITH_EAPTLS
228 esp->es_client.ea_using_eaptls = 0;
229 #endif /* PPP_WITH_EAPTLS */
230 #ifdef PPP_WITH_CHAPMS
231 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
232 esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
237 * eap_client_timeout - Give up waiting for the peer to send any
241 eap_client_timeout(void *arg)
243 eap_state *esp = (eap_state *) arg;
245 if (!eap_client_active(esp))
248 error("EAP: timeout waiting for Request from peer");
249 auth_withpeer_fail(esp->es_unit, PPP_EAP);
250 esp->es_client.ea_state = eapBadAuth;
254 * eap_authwithpeer - Authenticate to our peer (behave as client).
256 * Start client state and wait for requests. This is called only
260 eap_authwithpeer(int unit, char *localname)
262 eap_state *esp = &eap_states[unit];
264 /* Save the peer name we're given */
265 esp->es_client.ea_name = localname;
266 esp->es_client.ea_namelen = strlen(localname);
268 esp->es_client.ea_state = eapListen;
271 * Start a timer so that if the other end just goes
272 * silent, we don't sit here waiting forever.
274 if (esp->es_client.ea_timeout > 0)
275 TIMEOUT(eap_client_timeout, (void *)esp,
276 esp->es_client.ea_timeout);
280 * Format a standard EAP Failure message and send it to the peer.
284 eap_send_failure(eap_state *esp)
288 outp = outpacket_buf;
290 MAKEHEADER(outp, PPP_EAP);
292 PUTCHAR(EAP_FAILURE, outp);
293 esp->es_server.ea_id++;
294 PUTCHAR(esp->es_server.ea_id, outp);
295 PUTSHORT(EAP_HEADERLEN, outp);
297 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
299 esp->es_server.ea_state = eapBadAuth;
300 auth_peer_fail(esp->es_unit, PPP_EAP);
304 * Format a standard EAP Success message and send it to the peer.
308 eap_send_success(eap_state *esp)
312 outp = outpacket_buf;
314 MAKEHEADER(outp, PPP_EAP);
316 PUTCHAR(EAP_SUCCESS, outp);
317 esp->es_server.ea_id++;
318 PUTCHAR(esp->es_server.ea_id, outp);
319 PUTSHORT(EAP_HEADERLEN, outp);
321 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
323 auth_peer_success(esp->es_unit, PPP_EAP, 0,
324 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
329 * Set DES key according to pseudonym-generating secret and current
333 pncrypt_getkey(int timeoffs, unsigned char *key, int keylen)
340 if (pn_secret == NULL)
342 reftime = time(NULL) + timeoffs;
343 tp = localtime(&reftime);
345 ctxt = PPP_MD_CTX_new();
348 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
350 PPP_DigestInit(ctxt, PPP_sha1());
351 PPP_DigestUpdate(ctxt, pn_secret, strlen(pn_secret));
352 PPP_DigestUpdate(ctxt, tbuf, strlen(tbuf));
353 PPP_DigestFinal(ctxt, key, &keylen);
355 PPP_MD_CTX_free(ctxt);
362 static char base64[] =
363 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
371 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
376 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
379 if (bs->bs_offs >= 24) {
380 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
381 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
382 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
383 *outp++ = base64[bs->bs_bits & 0x3F];
393 b64flush(struct b64state *bs, u_char *outp)
397 if (bs->bs_offs == 8) {
398 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
399 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
401 } else if (bs->bs_offs == 16) {
402 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
403 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
404 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
413 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
419 if ((cp = strchr(base64, *inp++)) == NULL)
421 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
424 if (bs->bs_offs >= 8) {
425 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
432 #endif /* PPP_WITH_SRP */
435 * Assume that current waiting server state is complete and figure
436 * next state to use based on available authentication data. 'status'
437 * indicates if there was an error in handling the last query. It is
438 * 0 for success and non-zero for failure.
441 eap_figure_next_state(eap_state *esp, int status)
444 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp, key[SHA_DIGEST_LENGTH];
446 struct t_confent *tce, mytce;
449 int id, i, plen, clen, toffs, keylen;
452 #endif /* PPP_WITH_SRP */
453 #ifdef PPP_WITH_EAPTLS
454 struct eaptls_session *ets;
456 char secret[MAXWORDLEN];
457 #endif /* PPP_WITH_EAPTLS */
459 esp->es_server.ea_timeout = esp->es_savedtime;
460 #ifdef PPP_WITH_EAPTLS
461 esp->es_server.ea_prev_state = esp->es_server.ea_state;
462 #endif /* PPP_WITH_EAPTLS */
463 switch (esp->es_server.ea_state) {
469 /* Discard any previous session. */
470 ts = (struct t_server *)esp->es_server.ea_session;
473 esp->es_server.ea_session = NULL;
474 esp->es_server.ea_skey = NULL;
476 #endif /* PPP_WITH_SRP */
478 esp->es_server.ea_state = eapBadAuth;
482 /* If we've got a pseudonym, try to decode to real name. */
483 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
484 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
485 SRP_PSEUDO_LEN) == 0 &&
486 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
488 BZERO(&bs, sizeof (bs));
490 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
491 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
494 for (i = 0; i < 5; i++) {
495 pncrypt_getkey(toffs, key, keylen);
498 if (!DesDecrypt(secbuf, key, clear)) {
499 dbglog("no DES here; cannot decode "
503 id = *(unsigned char *)clear;
504 if (id + 1 <= plen && id + 9 > plen)
507 if (plen % 8 == 0 && i < 5) {
509 * Note that this is always shorter than the
510 * original stored string, so there's no need
513 if ((i = plen = *(unsigned char *)clear) > 7)
515 esp->es_server.ea_peerlen = plen;
516 dp = (unsigned char *)esp->es_server.ea_peer;
517 BCOPY(clear + 1, dp, i);
522 DesDecrypt(sp, key, dp);
527 esp->es_server.ea_peer[
528 esp->es_server.ea_peerlen] = '\0';
529 dbglog("decoded pseudonym to \"%.*q\"",
530 esp->es_server.ea_peerlen,
531 esp->es_server.ea_peer);
533 dbglog("failed to decode real name");
534 /* Stay in eapIdentfy state; requery */
538 /* Look up user in secrets database. */
539 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
540 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
541 /* Set up default in case SRP entry is bad */
542 esp->es_server.ea_state = eapMD5Chall;
543 /* Get t_confent based on index in srp-secrets */
544 id = strtol((char *)secbuf, &cp, 10);
545 if (*cp++ != ':' || id < 0)
549 mytce.modulus.data = (u_char *)wkmodulus;
550 mytce.modulus.len = sizeof (wkmodulus);
551 mytce.generator.data = (u_char *)"\002";
552 mytce.generator.len = 1;
554 } else if ((tce = gettcid(id)) != NULL) {
556 * Client will have to verify this modulus/
557 * generator combination, and that will take
558 * a while. Lengthen the timeout here.
560 if (esp->es_server.ea_timeout > 0 &&
561 esp->es_server.ea_timeout < 30)
562 esp->es_server.ea_timeout = 30;
566 if ((cp2 = strchr(cp, ':')) == NULL)
569 tpw.pebuf.name = esp->es_server.ea_peer;
570 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
572 tpw.pebuf.password.data = (char*) tpw.pwbuf;
573 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
575 tpw.pebuf.salt.data = tpw.saltbuf;
576 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
578 esp->es_server.ea_session = (void *)ts;
579 esp->es_server.ea_state = eapSRP1;
580 vals[0] = esp->es_server.ea_id + 1;
582 t_serveraddexdata(ts, vals, 2);
583 /* Generate B; must call before t_servergetkey() */
587 #endif /* PPP_WITH_SRP */
588 #ifdef PPP_WITH_EAPTLS
589 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
590 esp->es_server.ea_name, secret, &secret_len, 1)) {
592 esp->es_server.ea_state = eapTlsStart;
595 #endif /* PPP_WITH_EAPTLS */
597 esp->es_server.ea_state = eapMD5Chall;
600 #ifdef PPP_WITH_EAPTLS
602 /* Initialize ssl session */
603 if(!eaptls_init_ssl_server(esp)) {
604 esp->es_server.ea_state = eapBadAuth;
608 esp->es_server.ea_state = eapTlsRecv;
612 ets = (struct eaptls_session *) esp->es_server.ea_session;
614 if(ets->alert_sent) {
615 esp->es_server.ea_state = eapTlsSendAlert;
620 esp->es_server.ea_state = eapBadAuth;
623 ets = (struct eaptls_session *) esp->es_server.ea_session;
626 esp->es_server.ea_state = eapTlsSendAck;
628 esp->es_server.ea_state = eapTlsSend;
632 ets = (struct eaptls_session *) esp->es_server.ea_session;
635 esp->es_server.ea_state = eapTlsRecvAck;
637 if(SSL_is_init_finished(ets->ssl))
638 esp->es_server.ea_state = eapTlsRecvClient;
640 /* JJK Add "TLS empty record" message here ??? */
641 esp->es_server.ea_state = eapTlsRecv;
645 esp->es_server.ea_state = eapTlsRecv;
651 esp->es_server.ea_state = eapBadAuth;
655 esp->es_server.ea_state = eapTlsSend;
658 case eapTlsSendAlert:
659 esp->es_server.ea_state = eapTlsRecvAlertAck;
661 #endif /* PPP_WITH_EAPTLS */
665 ts = (struct t_server *)esp->es_server.ea_session;
666 if (ts != NULL && status != 0) {
668 esp->es_server.ea_session = NULL;
669 esp->es_server.ea_skey = NULL;
671 #endif /* PPP_WITH_SRP */
673 esp->es_server.ea_state = eapMD5Chall;
674 } else if (status != 0 || esp->es_server.ea_session == NULL) {
675 esp->es_server.ea_state = eapBadAuth;
677 esp->es_server.ea_state = eapSRP2;
683 ts = (struct t_server *)esp->es_server.ea_session;
684 if (ts != NULL && status != 0) {
686 esp->es_server.ea_session = NULL;
687 esp->es_server.ea_skey = NULL;
689 #endif /* PPP_WITH_SRP */
690 if (status != 0 || esp->es_server.ea_session == NULL) {
691 esp->es_server.ea_state = eapBadAuth;
693 esp->es_server.ea_state = eapSRP3;
700 ts = (struct t_server *)esp->es_server.ea_session;
701 if (ts != NULL && status != 0) {
703 esp->es_server.ea_session = NULL;
704 esp->es_server.ea_skey = NULL;
706 #endif /* PPP_WITH_SRP */
707 if (status != 0 || esp->es_server.ea_session == NULL) {
708 esp->es_server.ea_state = eapBadAuth;
710 esp->es_server.ea_state = eapOpen;
714 #ifdef PPP_WITH_CHAPMS
715 case eapMSCHAPv2Chall:
719 esp->es_server.ea_state = eapBadAuth;
721 esp->es_server.ea_state = eapOpen;
726 esp->es_server.ea_state = eapBadAuth;
729 if (esp->es_server.ea_state == eapBadAuth)
730 eap_send_failure(esp);
732 #ifdef PPP_WITH_EAPTLS
733 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));
734 #endif /* PPP_WITH_EAPTLS */
739 * eap_chap_verify_response - check whether the peer's response matches
740 * what we think it should be. Returns 1 if it does (authentication
741 * succeeded), or 0 if it doesn't.
744 eap_chap_verify_response(char *name, char *ourname, int id,
745 struct chap_digest_type *digest,
746 unsigned char *challenge, unsigned char *response,
747 char *message, int message_space)
750 unsigned char secret[MAXSECRETLEN];
753 /* Get the secret that the peer is supposed to know */
754 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
755 error("No CHAP secret found for authenticating %q", name);
759 ok = digest->verify_response(id, name, secret, secret_len, challenge,
760 response, message, message_space);
761 memset(secret, 0, sizeof(secret));
767 * Format and send an CHAPV2-Success/Failure EAP Request message.
770 eap_chapms2_send_request(eap_state *esp, u_char id,
771 u_char opcode, u_char chapid,
772 char *message, int message_len)
777 outp = outpacket_buf;
779 MAKEHEADER(outp, PPP_EAP);
781 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
782 msglen += message_len;
784 PUTCHAR(EAP_REQUEST, outp);
786 PUTSHORT(msglen, outp);
787 PUTCHAR(EAPT_MSCHAPV2, outp);
788 PUTCHAR(opcode, outp);
789 PUTCHAR(chapid, outp);
791 PUTSHORT(msglen - 5, outp);
792 BCOPY(message, outp, message_len);
794 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
796 if (opcode == CHAP_SUCCESS) {
797 auth_peer_success(esp->es_unit, PPP_EAP, 0,
798 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
801 esp->es_server.ea_state = eapBadAuth;
802 auth_peer_fail(esp->es_unit, PPP_EAP);
805 #endif /* PPP_WITH_CHAPMS */
808 * Format an EAP Request message and send it to the peer. Message
809 * type depends on current state. (Server operation)
812 eap_send_request(eap_state *esp)
822 u_char clear[8], cipher[8], dig[SHA_DIGEST_LENGTH], *optr, *cp, key[SHA_DIGEST_LENGTH];
823 int i, j, diglen, clen, keylen = sizeof(key);
826 #endif /* PPP_WITH_SRP */
828 /* Handle both initial auth and restart */
829 if (esp->es_server.ea_state < eapIdentify &&
830 esp->es_server.ea_state != eapInitial) {
831 esp->es_server.ea_state = eapIdentify;
832 if (explicit_remote) {
834 * If we already know the peer's
835 * unauthenticated name, then there's no
836 * reason to ask. Go to next state instead.
838 esp->es_server.ea_peer = remote_name;
839 esp->es_server.ea_peerlen = strlen(remote_name);
840 eap_figure_next_state(esp, 0);
844 if (esp->es_server.ea_maxrequests > 0 &&
845 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
846 if (esp->es_server.ea_responses > 0)
847 error("EAP: too many Requests sent");
849 error("EAP: no response to Requests");
850 eap_send_failure(esp);
854 outp = outpacket_buf;
856 MAKEHEADER(outp, PPP_EAP);
858 PUTCHAR(EAP_REQUEST, outp);
859 PUTCHAR(esp->es_server.ea_id, outp);
863 switch (esp->es_server.ea_state) {
865 PUTCHAR(EAPT_IDENTITY, outp);
867 challen = strlen(str);
868 BCOPY(str, outp, challen);
869 INCPTR(challen, outp);
873 PUTCHAR(EAPT_MD5CHAP, outp);
875 * pick a random challenge length between
876 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
878 challen = (drand48() *
879 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
880 MIN_CHALLENGE_LENGTH;
881 PUTCHAR(challen, outp);
882 esp->es_challen = challen;
883 ptr = esp->es_challenge;
884 while (--challen >= 0)
885 *ptr++ = (u_char) (drand48() * 0x100);
886 BCOPY(esp->es_challenge, outp, esp->es_challen);
887 INCPTR(esp->es_challen, outp);
888 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
889 INCPTR(esp->es_server.ea_namelen, outp);
892 #ifdef PPP_WITH_CHAPMS
893 case eapMSCHAPv2Chall:
894 esp->es_server.digest->generate_challenge(esp->es_challenge);
895 challen = esp->es_challenge[0];
896 esp->es_challen = challen;
898 PUTCHAR(EAPT_MSCHAPV2, outp);
899 PUTCHAR(CHAP_CHALLENGE, outp);
900 PUTCHAR(esp->es_server.ea_id, outp);
902 PUTSHORT(5 + challen +
903 esp->es_server.ea_namelen,
905 /* challen + challenge */
906 BCOPY(esp->es_challenge, outp, challen+1);
907 INCPTR(challen+1, outp);
908 BCOPY(esp->es_server.ea_name,
910 esp->es_server.ea_namelen);
911 INCPTR(esp->es_server.ea_namelen, outp);
913 #endif /* PPP_WITH_CHAPMS */
915 #ifdef PPP_WITH_EAPTLS
917 PUTCHAR(EAPT_TLS, outp);
918 PUTCHAR(EAP_TLS_FLAGS_START, outp);
919 eap_figure_next_state(esp, 0);
923 eaptls_send(esp->es_server.ea_session, &outp);
924 eap_figure_next_state(esp, 0);
928 PUTCHAR(EAPT_TLS, outp);
930 eap_figure_next_state(esp, 0);
933 case eapTlsSendAlert:
934 eaptls_send(esp->es_server.ea_session, &outp);
935 eap_figure_next_state(esp, 0);
937 #endif /* PPP_WITH_EAPTLS */
941 PUTCHAR(EAPT_SRP, outp);
942 PUTCHAR(EAPSRP_CHALLENGE, outp);
944 PUTCHAR(esp->es_server.ea_namelen, outp);
945 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
946 INCPTR(esp->es_server.ea_namelen, outp);
948 ts = (struct t_server *)esp->es_server.ea_session;
950 PUTCHAR(ts->s.len, outp);
951 BCOPY(ts->s.data, outp, ts->s.len);
952 INCPTR(ts->s.len, outp);
954 if (ts->g.len == 1 && ts->g.data[0] == 2) {
957 PUTCHAR(ts->g.len, outp);
958 BCOPY(ts->g.data, outp, ts->g.len);
959 INCPTR(ts->g.len, outp);
962 if (ts->n.len != sizeof (wkmodulus) ||
963 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
964 BCOPY(ts->n.data, outp, ts->n.len);
965 INCPTR(ts->n.len, outp);
970 PUTCHAR(EAPT_SRP, outp);
971 PUTCHAR(EAPSRP_SKEY, outp);
973 ts = (struct t_server *)esp->es_server.ea_session;
975 BCOPY(ts->B.data, outp, ts->B.len);
976 INCPTR(ts->B.len, outp);
980 PUTCHAR(EAPT_SRP, outp);
981 PUTCHAR(EAPSRP_SVALIDATOR, outp);
982 PUTLONG(SRPVAL_EBIT, outp);
983 ts = (struct t_server *)esp->es_server.ea_session;
985 BCOPY(t_serverresponse(ts), outp, SHA_DIGEST_LENGTH);
986 INCPTR(SHA_DIGEST_LENGTH, outp);
988 if (pncrypt_getkey(0, key, keylen)) {
989 /* Generate pseudonym */
991 cp = (unsigned char *)esp->es_server.ea_peer;
992 if ((j = i = esp->es_server.ea_peerlen) > 7)
995 BCOPY(cp, clear + 1, j);
999 if (!DesEncrypt(clear, key, cipher)) {
1000 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 DesEncrypt(cp, key, cipher);
1009 outp += b64enc(&b64, cipher, 8, outp);
1014 BCOPY(cp, clear, i);
1017 *cp++ = drand48() * 0x100;
1021 DesEncrypt(clear, key, cipher);
1022 outp += b64enc(&b64, cipher, 8, outp);
1024 outp += b64flush(&b64, outp);
1026 /* Set length and pad out to next 20 octet boundary */
1027 i = outp - optr - 1;
1029 i %= SHA_DIGEST_LENGTH;
1031 while (i < SHA_DIGEST_LENGTH) {
1032 *outp++ = drand48() * 0x100;
1037 /* Obscure the pseudonym with SHA1 hash */
1038 ctxt = PPP_MD_CTX_new();
1041 PPP_DigestInit(ctxt, PPP_sha1());
1042 PPP_DigestUpdate(ctxt, &esp->es_server.ea_id, 1);
1043 PPP_DigestUpdate(ctxt, &esp->es_server.ea_skey,
1045 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
1046 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_DIGEST_LENGTH +
1351 PUTSHORT(msglen, outp);
1352 PUTCHAR(EAPT_MD5CHAP, outp);
1353 PUTCHAR(MD5_DIGEST_LENGTH, outp);
1354 BCOPY(hash, outp, MD5_DIGEST_LENGTH);
1355 INCPTR(MD5_DIGEST_LENGTH, 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_DIGEST_LENGTH);
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_DIGEST_LENGTH];
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_DIGEST_LENGTH) == 0)
1579 dsize = SHA_DIGEST_LENGTH;
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_DIGEST_LENGTH);
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_DIGEST_LENGTH];
1673 int hashlen = MD5_DIGEST_LENGTH;
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_DIGEST_LENGTH];
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_DIGEST_LENGTH;
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_DIGEST_LENGTH, 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_DIGEST_LENGTH];
2333 int hashlen = MD5_DIGEST_LENGTH;
2335 struct t_server *ts;
2338 u_char dig[SHA_DIGEST_LENGTH];
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 chap_verify_hook_fn *chap_verifier;
2349 char response_message[256];
2350 #endif /* PPP_WITH_CHAPMS */
2353 * Ignore responses if we're not open
2355 if (esp->es_server.ea_state <= eapClosed)
2358 if (esp->es_server.ea_id != id) {
2359 dbglog("EAP: discarding Response %d; expected ID %d", id,
2360 esp->es_server.ea_id);
2364 esp->es_server.ea_responses++;
2367 error("EAP: empty Response message discarded");
2371 GETCHAR(typenum, inp);
2376 if (esp->es_server.ea_state != eapIdentify) {
2377 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2381 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2382 if (esp->es_server.ea_peer != NULL &&
2383 esp->es_server.ea_peer != remote_name)
2384 free(esp->es_server.ea_peer);
2385 esp->es_server.ea_peer = malloc(len + 1);
2386 if (esp->es_server.ea_peer == NULL) {
2387 esp->es_server.ea_peerlen = 0;
2388 eap_figure_next_state(esp, 1);
2391 BCOPY(inp, esp->es_server.ea_peer, len);
2392 esp->es_server.ea_peer[len] = '\0';
2393 esp->es_server.ea_peerlen = len;
2394 eap_figure_next_state(esp, 0);
2397 #ifdef PPP_WITH_EAPTLS
2399 switch(esp->es_server.ea_state) {
2403 ets = (struct eaptls_session *) esp->es_server.ea_session;
2405 eap_figure_next_state(esp,
2406 eaptls_receive(esp->es_server.ea_session, inp, len));
2408 if(ets->alert_recv) {
2409 eap_send_failure(esp);
2416 dbglog("EAP-TLS ACK with extra data");
2418 eap_figure_next_state(esp, 0);
2421 case eapTlsRecvClient:
2422 /* Receive authentication response from client */
2424 GETCHAR(flags, inp);
2426 if(len == 1 && !flags) { /* Ack = ok */
2427 #ifdef PPP_WITH_MPPE
2428 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2430 eap_send_success(esp);
2432 else { /* failure */
2433 warn("Server authentication failed");
2434 eap_send_failure(esp);
2438 warn("Bogus EAP-TLS packet received from client");
2440 eaptls_free_session(esp->es_server.ea_session);
2444 case eapTlsRecvAlertAck:
2445 eap_send_failure(esp);
2449 eap_figure_next_state(esp, 1);
2453 #endif /* PPP_WITH_EAPTLS */
2455 case EAPT_NOTIFICATION:
2456 dbglog("EAP unexpected Notification; response discarded");
2461 info("EAP: Nak Response with no suggested protocol");
2462 eap_figure_next_state(esp, 1);
2466 GETCHAR(vallen, inp);
2469 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2470 /* Peer cannot Nak Identify Request */
2471 eap_figure_next_state(esp, 1);
2477 /* Run through SRP validator selection again. */
2478 esp->es_server.ea_state = eapIdentify;
2479 eap_figure_next_state(esp, 0);
2483 esp->es_server.ea_state = eapMD5Chall;
2486 #ifdef PPP_WITH_EAPTLS
2487 /* Send EAP-TLS start packet */
2489 esp->es_server.ea_state = eapTlsStart;
2491 #endif /* PPP_WITH_EAPTLS */
2493 #ifdef PPP_WITH_CHAPMS
2495 info("EAP: peer proposes MSCHAPv2");
2496 /* If MSCHAPv2 digest was not found, NAK the packet */
2497 if (!esp->es_server.digest) {
2498 error("EAP MSCHAPv2 not supported");
2499 eap_send_nak(esp, id, EAPT_SRP);
2502 esp->es_server.ea_state = eapMSCHAPv2Chall;
2504 #endif /* PPP_WITH_CHAPMS */
2507 dbglog("EAP: peer requesting unknown Type %d", vallen);
2508 switch (esp->es_server.ea_state) {
2512 esp->es_server.ea_state = eapMD5Chall;
2516 esp->es_server.ea_state = eapIdentify;
2517 eap_figure_next_state(esp, 0);
2527 if (esp->es_server.ea_state != eapMD5Chall) {
2528 error("EAP: unexpected MD5-Response");
2529 eap_figure_next_state(esp, 1);
2533 error("EAP: received MD5-Response with no data");
2534 eap_figure_next_state(esp, 1);
2537 GETCHAR(vallen, inp);
2539 if (vallen != 16 || vallen > len) {
2540 error("EAP: MD5-Response with bad length %d", vallen);
2541 eap_figure_next_state(esp, 1);
2545 /* Not so likely to happen. */
2546 if (len - vallen >= sizeof (rhostname)) {
2547 dbglog("EAP: trimming really long peer name down");
2548 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2549 rhostname[sizeof (rhostname) - 1] = '\0';
2551 BCOPY(inp + vallen, rhostname, len - vallen);
2552 rhostname[len - vallen] = '\0';
2555 /* In case the remote doesn't give us his name. */
2556 if (explicit_remote ||
2557 (remote_name[0] != '\0' && vallen == len))
2558 strlcpy(rhostname, remote_name, sizeof (rhostname));
2561 * Get the secret for authenticating the specified
2564 if (!get_secret(esp->es_unit, rhostname,
2565 esp->es_server.ea_name, secret, &secret_len, 1)) {
2566 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2567 eap_send_failure(esp);
2571 mdctx = PPP_MD_CTX_new();
2572 if (mdctx != NULL) {
2574 if (PPP_DigestInit(mdctx, PPP_md5())) {
2576 if (PPP_DigestUpdate(mdctx, &esp->es_server.ea_id, 1)) {
2578 if (PPP_DigestUpdate(mdctx, &secret, secret_len)) {
2580 BZERO(secret, sizeof(secret));
2581 if (PPP_DigestUpdate(mdctx, esp->es_challenge, esp->es_challen)) {
2583 if (PPP_DigestFinal(mdctx, hash, &hashlen)) {
2585 if (BCMP(hash, inp, MD5_DIGEST_LENGTH) == 0) {
2586 esp->es_server.ea_type = EAPT_MD5CHAP;
2587 eap_send_success(esp);
2588 eap_figure_next_state(esp, 0);
2590 if (esp->es_rechallenge != 0) {
2591 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2593 PPP_MD_CTX_free(mdctx);
2602 PPP_MD_CTX_free(mdctx);
2605 eap_send_failure(esp);
2608 #ifdef PPP_WITH_CHAPMS
2611 error("EAP: received MSCHAPv2 with no data");
2612 eap_figure_next_state(esp, 1);
2615 GETCHAR(opcode, inp);
2620 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2621 error("EAP: unexpected MSCHAPv2-Response");
2622 eap_figure_next_state(esp, 1);
2625 /* skip MS ID + len */
2627 GETCHAR(vallen, inp);
2630 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2631 error("EAP: Invalid MSCHAPv2-Response "
2632 "length %d", vallen);
2633 eap_figure_next_state(esp, 1);
2637 /* Not so likely to happen. */
2638 if (len - vallen >= sizeof (rhostname)) {
2639 dbglog("EAP: trimming really long peer name down");
2640 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2641 rhostname[sizeof (rhostname) - 1] = '\0';
2643 BCOPY(inp + vallen, rhostname, len - vallen);
2644 rhostname[len - vallen] = '\0';
2647 /* In case the remote doesn't give us his name. */
2648 if (explicit_remote ||
2649 (remote_name[0] != '\0' && vallen == len))
2650 strlcpy(rhostname, remote_name, sizeof (rhostname));
2652 /* strip the MS domain name */
2653 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2654 char tmp[MAXNAMELEN+1];
2656 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2657 strlcpy(rhostname, tmp, sizeof(rhostname));
2660 if (chap_verify_hook)
2661 chap_verifier = chap_verify_hook;
2663 chap_verifier = eap_chap_verify_response;
2665 esp->es_server.ea_id += 1;
2666 if ((*chap_verifier)(rhostname,
2667 esp->es_server.ea_name,
2669 esp->es_server.digest,
2673 sizeof(response_message)))
2675 info("EAP: MSCHAPv2 success for peer %q",
2677 esp->es_server.ea_type = EAPT_MSCHAPV2;
2678 eap_chapms2_send_request(esp,
2679 esp->es_server.ea_id,
2681 esp->es_server.ea_id,
2683 strlen(response_message));
2684 eap_figure_next_state(esp, 0);
2685 if (esp->es_rechallenge != 0)
2686 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2689 warn("EAP: MSCHAPv2 failure for peer %q",
2691 eap_chapms2_send_request(esp,
2692 esp->es_server.ea_id,
2694 esp->es_server.ea_id,
2696 strlen(response_message));
2700 info("EAP: MSCHAPv2 success confirmed");
2703 info("EAP: MSCHAPv2 failure confirmed");
2706 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2707 eap_send_nak(esp, id, EAPT_SRP);
2711 #endif /* PPP_WITH_CHAPMS */
2716 error("EAP: empty SRP Response");
2717 eap_figure_next_state(esp, 1);
2720 GETCHAR(typenum, inp);
2724 if (esp->es_server.ea_state != eapSRP1) {
2725 error("EAP: unexpected SRP Subtype 1 Response");
2726 eap_figure_next_state(esp, 1);
2731 ts = (struct t_server *)esp->es_server.ea_session;
2733 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2734 if (esp->es_server.ea_skey == NULL) {
2735 /* Client's A value is bogus; terminate now */
2736 error("EAP: bogus A value from client");
2737 eap_send_failure(esp);
2739 eap_figure_next_state(esp, 0);
2743 case EAPSRP_CVALIDATOR:
2744 if (esp->es_server.ea_state != eapSRP2) {
2745 error("EAP: unexpected SRP Subtype 2 Response");
2746 eap_figure_next_state(esp, 1);
2749 if (len < sizeof (u_int32_t) + SHA_DIGEST_LENGTH) {
2750 error("EAP: M1 length %d < %d", len,
2751 sizeof (u_int32_t) + SHA_DIGEST_LENGTH);
2752 eap_figure_next_state(esp, 1);
2755 GETLONG(esp->es_server.ea_keyflags, inp);
2756 ts = (struct t_server *)esp->es_server.ea_session;
2758 if (t_serververify(ts, inp)) {
2759 info("EAP: unable to validate client identity");
2760 eap_send_failure(esp);
2763 eap_figure_next_state(esp, 0);
2767 if (esp->es_server.ea_state != eapSRP3) {
2768 error("EAP: unexpected SRP Subtype 3 Response");
2769 eap_send_failure(esp);
2772 esp->es_server.ea_type = EAPT_SRP;
2773 eap_send_success(esp);
2774 eap_figure_next_state(esp, 0);
2775 if (esp->es_rechallenge != 0)
2776 TIMEOUT(eap_rechallenge, esp,
2777 esp->es_rechallenge);
2778 if (esp->es_lwrechallenge != 0)
2779 TIMEOUT(srp_lwrechallenge, esp,
2780 esp->es_lwrechallenge);
2783 case EAPSRP_LWRECHALLENGE:
2784 if (esp->es_server.ea_state != eapSRP4) {
2785 info("EAP: unexpected SRP Subtype 4 Response");
2788 if (len != SHA_DIGEST_LENGTH) {
2789 error("EAP: bad Lightweight rechallenge "
2793 ctxt = PPP_MD_CTX_new();
2797 PPP_DigestInit(ctxt, PPP_sha1());
2798 PPP_DigestUpdate(ctxt, &vallen, 1);
2799 PPP_DigestUpdate(ctxt, esp->es_server.ea_skey,
2801 PPP_DigestUpdate(ctxt, esp->es_challenge, esp->es_challen);
2802 PPP_DigestUpdate(ctxt, esp->es_server.ea_peer,
2803 esp->es_server.ea_peerlen);
2804 PPP_DigestFinal(ctxt, dig, &diglen);
2806 PPP_MD_CTX_free(ctxt);
2808 if (BCMP(dig, inp, SHA_DIGEST_LENGTH) != 0) {
2809 error("EAP: failed Lightweight rechallenge");
2810 eap_send_failure(esp);
2814 esp->es_server.ea_state = eapOpen;
2815 if (esp->es_lwrechallenge != 0)
2816 TIMEOUT(srp_lwrechallenge, esp,
2817 esp->es_lwrechallenge);
2822 #endif /* PPP_WITH_SRP */
2825 /* This can't happen. */
2826 error("EAP: unknown Response type %d; ignored", typenum);
2830 if (esp->es_server.ea_timeout > 0) {
2831 UNTIMEOUT(eap_server_timeout, (void *)esp);
2834 if (esp->es_server.ea_state != eapBadAuth &&
2835 esp->es_server.ea_state != eapOpen) {
2836 esp->es_server.ea_id++;
2837 eap_send_request(esp);
2842 * eap_success - Receive EAP Success message (client mode).
2845 eap_success(eap_state *esp, u_char *inp, int id, int len)
2847 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2848 #ifdef PPP_WITH_EAPTLS
2849 && esp->es_client.ea_state != eapTlsRecvSuccess
2850 #endif /* PPP_WITH_EAPTLS */
2852 dbglog("EAP unexpected success message in state %s (%d)",
2853 eap_state_name(esp->es_client.ea_state),
2854 esp->es_client.ea_state);
2858 #ifdef PPP_WITH_EAPTLS
2859 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2860 eapTlsRecvSuccess) {
2861 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2862 eap_state_name(esp->es_client.ea_state),
2863 esp->es_client.ea_state);
2866 #endif /* PPP_WITH_EAPTLS */
2868 if (esp->es_client.ea_timeout > 0) {
2869 UNTIMEOUT(eap_client_timeout, (void *)esp);
2873 /* This is odd. The spec doesn't allow for this. */
2877 #ifdef PPP_WITH_PEAP
2878 peap_finish(&esp->ea_peap);
2881 esp->es_client.ea_state = eapOpen;
2882 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2886 * eap_failure - Receive EAP Failure message (client mode).
2889 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2892 * Ignore failure messages if we're not open
2894 if (esp->es_client.ea_state <= eapClosed)
2897 if (!eap_client_active(esp)) {
2898 dbglog("EAP unexpected failure message in state %s (%d)",
2899 eap_state_name(esp->es_client.ea_state),
2900 esp->es_client.ea_state);
2903 if (esp->es_client.ea_timeout > 0) {
2904 UNTIMEOUT(eap_client_timeout, (void *)esp);
2908 /* This is odd. The spec doesn't allow for this. */
2912 esp->es_client.ea_state = eapBadAuth;
2914 error("EAP: peer reports authentication failure");
2916 #ifdef PPP_WITH_PEAP
2917 peap_finish(&esp->ea_peap);
2920 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2924 * eap_input - Handle received EAP message.
2927 eap_input(int unit, u_char *inp, int inlen)
2929 eap_state *esp = &eap_states[unit];
2934 * Parse header (code, id and length). If packet too short,
2937 if (inlen < EAP_HEADERLEN) {
2938 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2944 if (len < EAP_HEADERLEN || len > inlen) {
2945 error("EAP: packet has illegal length field %d (%d..%d)", len,
2946 EAP_HEADERLEN, inlen);
2949 len -= EAP_HEADERLEN;
2951 /* Dispatch based on message code */
2954 eap_request(esp, inp, id, len);
2958 eap_response(esp, inp, id, len);
2962 eap_success(esp, inp, id, len);
2966 eap_failure(esp, inp, id, len);
2969 default: /* XXX Need code reject */
2970 /* Note: it's not legal to send EAP Nak here. */
2971 warn("EAP: unknown code %d received", code);
2977 * eap_printpkt - print the contents of an EAP packet.
2979 static char *eap_codenames[] = {
2980 "Request", "Response", "Success", "Failure"
2983 static char *eap_typenames[] = {
2984 "Identity", "Notification", "Nak", "MD5-Challenge",
2985 "OTP", "Generic-Token", NULL, NULL,
2986 "RSA", "DSS", "KEA", "KEA-Validate",
2987 "TLS", "Defender", "Windows 2000", "Arcot",
2988 "Cisco", "Nokia", "SRP", NULL,
2989 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2994 eap_printpkt(u_char *inp, int inlen,
2995 void (*printer) (void *, char *, ...), void *arg)
2997 int code, id, len, rtype, vallen;
3000 #ifdef PPP_WITH_EAPTLS
3002 #endif /* PPP_WITH_EAPTLS */
3003 #ifdef PPP_WITH_CHAPMS
3005 #endif /* PPP_WITH_CHAPMS */
3007 if (inlen < EAP_HEADERLEN)
3013 if (len < EAP_HEADERLEN || len > inlen)
3016 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
3017 printer(arg, " %s", eap_codenames[code-1]);
3019 printer(arg, " code=0x%x", code);
3020 printer(arg, " id=0x%x", id);
3021 len -= EAP_HEADERLEN;
3025 printer(arg, " <missing type>");
3028 GETCHAR(rtype, inp);
3031 rtype <= sizeof (eap_typenames) / sizeof (char *))
3032 printer(arg, " %s", eap_typenames[rtype-1]);
3034 printer(arg, " type=0x%x", rtype);
3037 case EAPT_NOTIFICATION:
3039 printer(arg, " <Message ");
3040 print_string((char *)inp, len, printer, arg);
3045 printer(arg, " <No message>");
3052 GETCHAR(vallen, inp);
3056 printer(arg, " <Value%.*B>", vallen, inp);
3057 INCPTR(vallen, inp);
3060 printer(arg, " <Name ");
3061 print_string((char *)inp, len, printer, arg);
3066 printer(arg, " <No name>");
3070 #ifdef PPP_WITH_CHAPMS
3074 GETCHAR(opcode, inp);
3077 case CHAP_CHALLENGE:
3080 GETCHAR(vallen, inp);
3085 printer(arg, " Challenge <");
3086 for (; vallen > 0; --vallen) {
3089 printer(arg, "%.2x", val);
3093 printer(arg, ", <Name ");
3094 print_string((char *)inp, len, printer, arg);
3099 printer(arg, ", <No name>");
3105 printer(arg, " Success <Message ");
3106 print_string((char *)inp, len, printer, arg);
3112 printer(arg, " Failure <Message ");
3113 print_string((char *)inp, len, printer, arg);
3119 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3123 #endif /* PPP_WITH_CHAPMS */
3125 #ifdef PPP_WITH_EAPTLS
3129 GETCHAR(flags, inp);
3132 if(flags == 0 && len == 0){
3133 printer(arg, " Ack");
3137 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3138 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3139 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3141 #endif /* PPP_WITH_EAPTLS */
3147 GETCHAR(vallen, inp);
3149 printer(arg, "-%d", vallen);
3151 case EAPSRP_CHALLENGE:
3152 GETCHAR(vallen, inp);
3157 printer(arg, " <Name ");
3158 print_string((char *)inp, vallen, printer,
3162 printer(arg, " <No name>");
3164 INCPTR(vallen, inp);
3166 GETCHAR(vallen, inp);
3170 printer(arg, " <s%.*B>", vallen, inp);
3171 INCPTR(vallen, inp);
3173 GETCHAR(vallen, inp);
3178 printer(arg, " <Default g=2>");
3180 printer(arg, " <g%.*B>", vallen, inp);
3182 INCPTR(vallen, inp);
3185 printer(arg, " <Default N>");
3187 printer(arg, " <N%.*B>", len, inp);
3194 printer(arg, " <B%.*B>", len, inp);
3199 case EAPSRP_SVALIDATOR:
3200 if (len < sizeof (u_int32_t))
3203 len -= sizeof (u_int32_t);
3204 if (uval & SRPVAL_EBIT) {
3206 uval &= ~SRPVAL_EBIT;
3209 printer(arg, " f<%X>", uval);
3211 if ((vallen = len) > SHA_DIGEST_LENGTH)
3212 vallen = SHA_DIGEST_LENGTH;
3213 printer(arg, " <M2%.*B%s>", len, inp,
3214 len < SHA_DIGEST_LENGTH ? "?" : "");
3215 INCPTR(vallen, inp);
3218 printer(arg, " <PN%.*B>", len, inp);
3224 case EAPSRP_LWRECHALLENGE:
3225 printer(arg, " <Challenge%.*B>", len, inp);
3231 #endif /* PPP_WITH_SRP */
3238 GETCHAR(rtype, inp);
3241 rtype <= sizeof (eap_typenames) / sizeof (char *))
3242 printer(arg, " %s", eap_typenames[rtype-1]);
3244 printer(arg, " type=0x%x", rtype);
3248 printer(arg, " <Name ");
3249 print_string((char *)inp, len, printer, arg);
3256 #ifdef PPP_WITH_EAPTLS
3260 GETCHAR(flags, inp);
3263 if(flags == 0 && len == 0){
3264 printer(arg, " Ack");
3268 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3269 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3270 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3273 #endif /* PPP_WITH_EAPTLS */
3277 printer(arg, " <missing hint>");
3280 GETCHAR(rtype, inp);
3282 printer(arg, " <Suggested-type %02X", rtype);
3284 rtype <= sizeof (eap_typenames) / sizeof (char *))
3285 printer(arg, " (%s)", eap_typenames[rtype-1]);
3291 printer(arg, " <missing length>");
3294 GETCHAR(vallen, inp);
3298 printer(arg, " <Value%.*B>", vallen, inp);
3299 INCPTR(vallen, inp);
3302 printer(arg, " <Name ");
3303 print_string((char *)inp, len, printer, arg);
3308 printer(arg, " <No name>");
3312 #ifdef PPP_WITH_CHAPMS
3316 GETCHAR(opcode, inp);
3322 GETCHAR(vallen, inp);
3327 printer(arg, " Response <");
3328 for (; vallen > 0; --vallen) {
3331 printer(arg, "%.2x", val);
3335 printer(arg, ", <Name ");
3336 print_string((char *)inp, len, printer, arg);
3341 printer(arg, ", <No name>");
3345 printer(arg, " Success");
3348 printer(arg, " Failure");
3351 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3355 #endif /* PPP_WITH_CHAPMS */
3361 GETCHAR(vallen, inp);
3363 printer(arg, "-%d", vallen);
3366 printer(arg, " <A%.*B>", len, inp);
3371 case EAPSRP_CVALIDATOR:
3372 if (len < sizeof (u_int32_t))
3375 len -= sizeof (u_int32_t);
3376 if (uval & SRPVAL_EBIT) {
3378 uval &= ~SRPVAL_EBIT;
3381 printer(arg, " f<%X>", uval);
3383 printer(arg, " <M1%.*B%s>", len, inp,
3384 len == SHA_DIGEST_LENGTH ? "" : "?");
3392 case EAPSRP_LWRECHALLENGE:
3393 printer(arg, " <Response%.*B%s>", len, inp,
3394 len == SHA_DIGEST_LENGTH ? "" : "?");
3395 if ((vallen = len) > SHA_DIGEST_LENGTH)
3396 vallen = SHA_DIGEST_LENGTH;
3397 INCPTR(vallen, inp);
3402 #endif /* PPP_WITH_SRP */
3406 case EAP_SUCCESS: /* No payload expected for these! */
3411 printer(arg, " <truncated>");
3416 printer(arg, "%8B...", inp);
3418 printer(arg, "%.*B", len, inp);
3421 return (inp - pstart);