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
56 #include <sys/types.h>
63 #include "pathnames.h"
74 #ifndef SHA_DIGESTSIZE
75 #define SHA_DIGESTSIZE 20
80 #endif /* USE_EAPTLS */
86 extern int chapms_strip_domain;
89 eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
91 static char *pn_secret = NULL; /* Pseudonym generating secret */
95 * Command-line options.
97 static option_t eap_option_list[] = {
98 { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
99 "Set retransmit timeout for EAP Requests (server)" },
100 { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
101 "Set max number of EAP Requests sent (server)" },
102 { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
103 "Set time limit for peer EAP authentication" },
104 { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
105 "Set max number of EAP Requests allows (client)" },
106 { "eap-interval", o_int, &eap_states[0].es_rechallenge,
107 "Set interval for EAP rechallenge" },
109 { "srp-interval", o_int, &eap_states[0].es_lwrechallenge,
110 "Set interval for SRP lightweight rechallenge" },
111 { "srp-pn-secret", o_string, &pn_secret,
112 "Long term pseudonym generation secret" },
113 { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
114 "Use pseudonym if offered one by server", 1 },
120 * Protocol entry points.
122 static void eap_init (int unit);
123 static void eap_input (int unit, u_char *inp, int inlen);
124 static void eap_protrej (int unit);
125 static void eap_lowerup (int unit);
126 static void eap_lowerdown (int unit);
127 static int eap_printpkt (u_char *inp, int inlen,
128 void (*)(void *arg, char *fmt, ...), void *arg);
130 struct protent eap_protent = {
131 PPP_EAP, /* protocol number */
132 eap_init, /* initialization procedure */
133 eap_input, /* process a received packet */
134 eap_protrej, /* process a received protocol-reject */
135 eap_lowerup, /* lower layer has gone up */
136 eap_lowerdown, /* lower layer has gone down */
137 NULL, /* open the protocol */
138 NULL, /* close the protocol */
139 eap_printpkt, /* print a packet in readable form */
140 NULL, /* process a received data packet */
141 1, /* protocol enabled */
142 "EAP", /* text name of protocol */
143 NULL, /* text name of corresponding data protocol */
144 eap_option_list, /* list of command-line options */
145 NULL, /* check requested options; assign defaults */
146 NULL, /* configure interface for demand-dial */
147 NULL /* say whether to bring up link for this pkt */
152 * A well-known 2048 bit modulus.
154 static const u_char wkmodulus[] = {
155 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
156 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
157 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
158 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
159 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
160 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
161 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
162 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
163 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
164 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
165 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
166 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
167 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
168 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
169 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
170 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
171 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
172 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
173 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
174 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
175 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
176 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
177 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
178 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
179 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
180 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
181 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
182 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
183 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
184 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
185 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
186 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
190 /* Local forward declarations. */
191 static void eap_server_timeout (void *arg);
194 * Convert EAP state code to printable string for debug.
197 eap_state_name(enum eap_state_code esc)
199 static const char *state_names[] = { EAP_STATES };
201 return (state_names[(int)esc]);
205 * eap_init - Initialize state for an EAP user. This is currently
206 * called once by main() during start-up.
211 eap_state *esp = &eap_states[unit];
213 BZERO(esp, sizeof (*esp));
215 esp->es_server.ea_timeout = EAP_DEFTIMEOUT;
216 esp->es_server.ea_maxrequests = EAP_DEFTRANSMITS;
217 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
218 esp->es_client.ea_timeout = EAP_DEFREQTIME;
219 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
221 esp->es_client.ea_using_eaptls = 0;
222 #endif /* USE_EAPTLS */
224 esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
225 esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
230 * eap_client_timeout - Give up waiting for the peer to send any
234 eap_client_timeout(void *arg)
236 eap_state *esp = (eap_state *) arg;
238 if (!eap_client_active(esp))
241 error("EAP: timeout waiting for Request from peer");
242 auth_withpeer_fail(esp->es_unit, PPP_EAP);
243 esp->es_client.ea_state = eapBadAuth;
247 * eap_authwithpeer - Authenticate to our peer (behave as client).
249 * Start client state and wait for requests. This is called only
253 eap_authwithpeer(int unit, char *localname)
255 eap_state *esp = &eap_states[unit];
257 /* Save the peer name we're given */
258 esp->es_client.ea_name = localname;
259 esp->es_client.ea_namelen = strlen(localname);
261 esp->es_client.ea_state = eapListen;
264 * Start a timer so that if the other end just goes
265 * silent, we don't sit here waiting forever.
267 if (esp->es_client.ea_timeout > 0)
268 TIMEOUT(eap_client_timeout, (void *)esp,
269 esp->es_client.ea_timeout);
273 * Format a standard EAP Failure message and send it to the peer.
277 eap_send_failure(eap_state *esp)
281 outp = outpacket_buf;
283 MAKEHEADER(outp, PPP_EAP);
285 PUTCHAR(EAP_FAILURE, outp);
286 esp->es_server.ea_id++;
287 PUTCHAR(esp->es_server.ea_id, outp);
288 PUTSHORT(EAP_HEADERLEN, outp);
290 output(esp->es_unit, outpacket_buf, EAP_HEADERLEN + PPP_HDRLEN);
292 esp->es_server.ea_state = eapBadAuth;
293 auth_peer_fail(esp->es_unit, PPP_EAP);
297 * Format a standard EAP Success message and send it to the peer.
301 eap_send_success(eap_state *esp)
305 outp = outpacket_buf;
307 MAKEHEADER(outp, PPP_EAP);
309 PUTCHAR(EAP_SUCCESS, outp);
310 esp->es_server.ea_id++;
311 PUTCHAR(esp->es_server.ea_id, outp);
312 PUTSHORT(EAP_HEADERLEN, outp);
314 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + EAP_HEADERLEN);
316 auth_peer_success(esp->es_unit, PPP_EAP, 0,
317 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
322 * Set DES key according to pseudonym-generating secret and current
326 pncrypt_setkey(int timeoffs)
331 u_char dig[SHA_DIGESTSIZE];
334 if (pn_secret == NULL)
336 reftime = time(NULL) + timeoffs;
337 tp = localtime(&reftime);
339 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
340 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
341 SHA1Update(&ctxt, tbuf, strlen(tbuf));
342 SHA1Final(dig, &ctxt);
343 return (DesSetkey(dig));
346 static char base64[] =
347 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
355 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
360 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
363 if (bs->bs_offs >= 24) {
364 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
365 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
366 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
367 *outp++ = base64[bs->bs_bits & 0x3F];
377 b64flush(struct b64state *bs, u_char *outp)
381 if (bs->bs_offs == 8) {
382 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
383 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
385 } else if (bs->bs_offs == 16) {
386 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
387 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
388 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
397 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
403 if ((cp = strchr(base64, *inp++)) == NULL)
405 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
408 if (bs->bs_offs >= 8) {
409 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
419 * Assume that current waiting server state is complete and figure
420 * next state to use based on available authentication data. 'status'
421 * indicates if there was an error in handling the last query. It is
422 * 0 for success and non-zero for failure.
425 eap_figure_next_state(eap_state *esp, int status)
428 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
430 struct t_confent *tce, mytce;
433 int id, i, plen, toffs;
438 struct eaptls_session *ets;
440 char secret[MAXWORDLEN];
441 #endif /* USE_EAPTLS */
443 esp->es_server.ea_timeout = esp->es_savedtime;
445 esp->es_server.ea_prev_state = esp->es_server.ea_state;
446 #endif /* USE_EAPTLS */
447 switch (esp->es_server.ea_state) {
453 /* Discard any previous session. */
454 ts = (struct t_server *)esp->es_server.ea_session;
457 esp->es_server.ea_session = NULL;
458 esp->es_server.ea_skey = NULL;
462 esp->es_server.ea_state = eapBadAuth;
466 /* If we've got a pseudonym, try to decode to real name. */
467 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
468 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
469 SRP_PSEUDO_LEN) == 0 &&
470 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
472 BZERO(&bs, sizeof (bs));
474 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
475 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
478 for (i = 0; i < 5; i++) {
479 pncrypt_setkey(toffs);
481 if (!DesDecrypt(secbuf, clear)) {
482 dbglog("no DES here; cannot decode "
486 id = *(unsigned char *)clear;
487 if (id + 1 <= plen && id + 9 > plen)
490 if (plen % 8 == 0 && i < 5) {
492 * Note that this is always shorter than the
493 * original stored string, so there's no need
496 if ((i = plen = *(unsigned char *)clear) > 7)
498 esp->es_server.ea_peerlen = plen;
499 dp = (unsigned char *)esp->es_server.ea_peer;
500 BCOPY(clear + 1, dp, i);
505 (void) DesDecrypt(sp, dp);
510 esp->es_server.ea_peer[
511 esp->es_server.ea_peerlen] = '\0';
512 dbglog("decoded pseudonym to \"%.*q\"",
513 esp->es_server.ea_peerlen,
514 esp->es_server.ea_peer);
516 dbglog("failed to decode real name");
517 /* Stay in eapIdentfy state; requery */
521 /* Look up user in secrets database. */
522 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
523 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
524 /* Set up default in case SRP entry is bad */
525 esp->es_server.ea_state = eapMD5Chall;
526 /* Get t_confent based on index in srp-secrets */
527 id = strtol((char *)secbuf, &cp, 10);
528 if (*cp++ != ':' || id < 0)
532 mytce.modulus.data = (u_char *)wkmodulus;
533 mytce.modulus.len = sizeof (wkmodulus);
534 mytce.generator.data = (u_char *)"\002";
535 mytce.generator.len = 1;
537 } else if ((tce = gettcid(id)) != NULL) {
539 * Client will have to verify this modulus/
540 * generator combination, and that will take
541 * a while. Lengthen the timeout here.
543 if (esp->es_server.ea_timeout > 0 &&
544 esp->es_server.ea_timeout < 30)
545 esp->es_server.ea_timeout = 30;
549 if ((cp2 = strchr(cp, ':')) == NULL)
552 tpw.pebuf.name = esp->es_server.ea_peer;
553 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
555 tpw.pebuf.password.data = tpw.pwbuf;
556 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
558 tpw.pebuf.salt.data = tpw.saltbuf;
559 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
561 esp->es_server.ea_session = (void *)ts;
562 esp->es_server.ea_state = eapSRP1;
563 vals[0] = esp->es_server.ea_id + 1;
565 t_serveraddexdata(ts, vals, 2);
566 /* Generate B; must call before t_servergetkey() */
572 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
573 esp->es_server.ea_name, secret, &secret_len, 1)) {
575 esp->es_server.ea_state = eapTlsStart;
578 #endif /* USE_EAPTLS */
580 esp->es_server.ea_state = eapMD5Chall;
585 /* Initialize ssl session */
586 if(!eaptls_init_ssl_server(esp)) {
587 esp->es_server.ea_state = eapBadAuth;
591 esp->es_server.ea_state = eapTlsRecv;
595 ets = (struct eaptls_session *) esp->es_server.ea_session;
597 if(ets->alert_sent) {
598 esp->es_server.ea_state = eapTlsSendAlert;
603 esp->es_server.ea_state = eapBadAuth;
606 ets = (struct eaptls_session *) esp->es_server.ea_session;
609 esp->es_server.ea_state = eapTlsSendAck;
611 esp->es_server.ea_state = eapTlsSend;
615 ets = (struct eaptls_session *) esp->es_server.ea_session;
618 esp->es_server.ea_state = eapTlsRecvAck;
620 if(SSL_is_init_finished(ets->ssl))
621 esp->es_server.ea_state = eapTlsRecvClient;
623 /* JJK Add "TLS empty record" message here ??? */
624 esp->es_server.ea_state = eapTlsRecv;
628 esp->es_server.ea_state = eapTlsRecv;
634 esp->es_server.ea_state = eapBadAuth;
638 esp->es_server.ea_state = eapTlsSend;
641 case eapTlsSendAlert:
642 esp->es_server.ea_state = eapTlsRecvAlertAck;
644 #endif /* USE_EAPTLS */
648 ts = (struct t_server *)esp->es_server.ea_session;
649 if (ts != NULL && status != 0) {
651 esp->es_server.ea_session = NULL;
652 esp->es_server.ea_skey = NULL;
656 esp->es_server.ea_state = eapMD5Chall;
657 } else if (status != 0 || esp->es_server.ea_session == NULL) {
658 esp->es_server.ea_state = eapBadAuth;
660 esp->es_server.ea_state = eapSRP2;
666 ts = (struct t_server *)esp->es_server.ea_session;
667 if (ts != NULL && status != 0) {
669 esp->es_server.ea_session = NULL;
670 esp->es_server.ea_skey = NULL;
673 if (status != 0 || esp->es_server.ea_session == NULL) {
674 esp->es_server.ea_state = eapBadAuth;
676 esp->es_server.ea_state = eapSRP3;
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;
690 if (status != 0 || esp->es_server.ea_session == NULL) {
691 esp->es_server.ea_state = eapBadAuth;
693 esp->es_server.ea_state = eapOpen;
698 case eapMSCHAPv2Chall:
702 esp->es_server.ea_state = eapBadAuth;
704 esp->es_server.ea_state = eapOpen;
709 esp->es_server.ea_state = eapBadAuth;
712 if (esp->es_server.ea_state == eapBadAuth)
713 eap_send_failure(esp);
716 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));
717 #endif /* USE_EAPTLS */
722 * eap_chap_verify_response - check whether the peer's response matches
723 * what we think it should be. Returns 1 if it does (authentication
724 * succeeded), or 0 if it doesn't.
727 eap_chap_verify_response(char *name, char *ourname, int id,
728 struct chap_digest_type *digest,
729 unsigned char *challenge, unsigned char *response,
730 char *message, int message_space)
733 unsigned char secret[MAXSECRETLEN];
736 /* Get the secret that the peer is supposed to know */
737 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
738 error("No CHAP secret found for authenticating %q", name);
742 ok = digest->verify_response(id, name, secret, secret_len, challenge,
743 response, message, message_space);
744 memset(secret, 0, sizeof(secret));
750 * Format and send an CHAPV2-Success/Failure EAP Request message.
753 eap_chapms2_send_request(eap_state *esp, u_char id,
754 u_char opcode, u_char chapid,
755 char *message, int message_len)
760 outp = outpacket_buf;
762 MAKEHEADER(outp, PPP_EAP);
764 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
765 msglen += message_len;
767 PUTCHAR(EAP_REQUEST, outp);
769 PUTSHORT(msglen, outp);
770 PUTCHAR(EAPT_MSCHAPV2, outp);
771 PUTCHAR(opcode, outp);
772 PUTCHAR(chapid, outp);
774 PUTSHORT(msglen - 5, outp);
775 BCOPY(message, outp, message_len);
777 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
779 if (opcode == CHAP_SUCCESS) {
780 auth_peer_success(esp->es_unit, PPP_EAP, 0,
781 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
784 esp->es_server.ea_state = eapBadAuth;
785 auth_peer_fail(esp->es_unit, PPP_EAP);
791 * Format an EAP Request message and send it to the peer. Message
792 * type depends on current state. (Server operation)
795 eap_send_request(eap_state *esp)
805 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
811 /* Handle both initial auth and restart */
812 if (esp->es_server.ea_state < eapIdentify &&
813 esp->es_server.ea_state != eapInitial) {
814 esp->es_server.ea_state = eapIdentify;
815 if (explicit_remote) {
817 * If we already know the peer's
818 * unauthenticated name, then there's no
819 * reason to ask. Go to next state instead.
821 esp->es_server.ea_peer = remote_name;
822 esp->es_server.ea_peerlen = strlen(remote_name);
823 eap_figure_next_state(esp, 0);
827 if (esp->es_server.ea_maxrequests > 0 &&
828 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
829 if (esp->es_server.ea_responses > 0)
830 error("EAP: too many Requests sent");
832 error("EAP: no response to Requests");
833 eap_send_failure(esp);
837 outp = outpacket_buf;
839 MAKEHEADER(outp, PPP_EAP);
841 PUTCHAR(EAP_REQUEST, outp);
842 PUTCHAR(esp->es_server.ea_id, outp);
846 switch (esp->es_server.ea_state) {
848 PUTCHAR(EAPT_IDENTITY, outp);
850 challen = strlen(str);
851 BCOPY(str, outp, challen);
852 INCPTR(challen, outp);
856 PUTCHAR(EAPT_MD5CHAP, outp);
858 * pick a random challenge length between
859 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
861 challen = (drand48() *
862 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
863 MIN_CHALLENGE_LENGTH;
864 PUTCHAR(challen, outp);
865 esp->es_challen = challen;
866 ptr = esp->es_challenge;
867 while (--challen >= 0)
868 *ptr++ = (u_char) (drand48() * 0x100);
869 BCOPY(esp->es_challenge, outp, esp->es_challen);
870 INCPTR(esp->es_challen, outp);
871 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
872 INCPTR(esp->es_server.ea_namelen, outp);
876 case eapMSCHAPv2Chall:
877 esp->es_server.digest->generate_challenge(esp->es_challenge);
878 challen = esp->es_challenge[0];
879 esp->es_challen = challen;
881 PUTCHAR(EAPT_MSCHAPV2, outp);
882 PUTCHAR(CHAP_CHALLENGE, outp);
883 PUTCHAR(esp->es_server.ea_id, outp);
885 PUTSHORT(5 + challen +
886 esp->es_server.ea_namelen,
888 /* challen + challenge */
889 BCOPY(esp->es_challenge, outp, challen+1);
890 INCPTR(challen+1, outp);
891 BCOPY(esp->es_server.ea_name,
893 esp->es_server.ea_namelen);
894 INCPTR(esp->es_server.ea_namelen, outp);
900 PUTCHAR(EAPT_TLS, outp);
901 PUTCHAR(EAP_TLS_FLAGS_START, outp);
902 eap_figure_next_state(esp, 0);
906 eaptls_send(esp->es_server.ea_session, &outp);
907 eap_figure_next_state(esp, 0);
911 PUTCHAR(EAPT_TLS, outp);
913 eap_figure_next_state(esp, 0);
916 case eapTlsSendAlert:
917 eaptls_send(esp->es_server.ea_session, &outp);
918 eap_figure_next_state(esp, 0);
920 #endif /* USE_EAPTLS */
924 PUTCHAR(EAPT_SRP, outp);
925 PUTCHAR(EAPSRP_CHALLENGE, outp);
927 PUTCHAR(esp->es_server.ea_namelen, outp);
928 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
929 INCPTR(esp->es_server.ea_namelen, outp);
931 ts = (struct t_server *)esp->es_server.ea_session;
933 PUTCHAR(ts->s.len, outp);
934 BCOPY(ts->s.data, outp, ts->s.len);
935 INCPTR(ts->s.len, outp);
937 if (ts->g.len == 1 && ts->g.data[0] == 2) {
940 PUTCHAR(ts->g.len, outp);
941 BCOPY(ts->g.data, outp, ts->g.len);
942 INCPTR(ts->g.len, outp);
945 if (ts->n.len != sizeof (wkmodulus) ||
946 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
947 BCOPY(ts->n.data, outp, ts->n.len);
948 INCPTR(ts->n.len, outp);
953 PUTCHAR(EAPT_SRP, outp);
954 PUTCHAR(EAPSRP_SKEY, outp);
956 ts = (struct t_server *)esp->es_server.ea_session;
958 BCOPY(ts->B.data, outp, ts->B.len);
959 INCPTR(ts->B.len, outp);
963 PUTCHAR(EAPT_SRP, outp);
964 PUTCHAR(EAPSRP_SVALIDATOR, outp);
965 PUTLONG(SRPVAL_EBIT, outp);
966 ts = (struct t_server *)esp->es_server.ea_session;
968 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
969 INCPTR(SHA_DIGESTSIZE, outp);
971 if (pncrypt_setkey(0)) {
972 /* Generate pseudonym */
974 cp = (unsigned char *)esp->es_server.ea_peer;
975 if ((j = i = esp->es_server.ea_peerlen) > 7)
978 BCOPY(cp, clear + 1, j);
981 if (!DesEncrypt(clear, cipher)) {
982 dbglog("no DES here; not generating pseudonym");
985 BZERO(&b64, sizeof (b64));
986 outp++; /* space for pseudonym length */
987 outp += b64enc(&b64, cipher, 8, outp);
989 (void) DesEncrypt(cp, cipher);
990 outp += b64enc(&b64, cipher, 8, outp);
998 *cp++ = drand48() * 0x100;
1001 (void) DesEncrypt(clear, cipher);
1002 outp += b64enc(&b64, cipher, 8, outp);
1004 outp += b64flush(&b64, outp);
1006 /* Set length and pad out to next 20 octet boundary */
1007 i = outp - optr - 1;
1009 i %= SHA_DIGESTSIZE;
1011 while (i < SHA_DIGESTSIZE) {
1012 *outp++ = drand48() * 0x100;
1017 /* Obscure the pseudonym with SHA1 hash */
1019 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1020 SHA1Update(&ctxt, esp->es_server.ea_skey,
1022 SHA1Update(&ctxt, esp->es_server.ea_peer,
1023 esp->es_server.ea_peerlen);
1024 while (optr < outp) {
1025 SHA1Final(dig, &ctxt);
1027 while (cp < dig + SHA_DIGESTSIZE)
1030 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1031 SHA1Update(&ctxt, esp->es_server.ea_skey,
1033 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1040 PUTCHAR(EAPT_SRP, outp);
1041 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1042 challen = MIN_CHALLENGE_LENGTH +
1043 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1044 esp->es_challen = challen;
1045 ptr = esp->es_challenge;
1046 while (--challen >= 0)
1047 *ptr++ = drand48() * 0x100;
1048 BCOPY(esp->es_challenge, outp, esp->es_challen);
1049 INCPTR(esp->es_challen, outp);
1051 #endif /* USE_SRP */
1057 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1058 PUTSHORT(outlen, lenloc);
1060 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1062 esp->es_server.ea_requests++;
1064 if (esp->es_server.ea_timeout > 0)
1065 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1069 * eap_authpeer - Authenticate our peer (behave as server).
1071 * Start server state and send first request. This is called only
1072 * after eap_lowerup.
1075 eap_authpeer(int unit, char *localname)
1077 eap_state *esp = &eap_states[unit];
1079 /* Save the name we're given. */
1080 esp->es_server.ea_name = localname;
1081 esp->es_server.ea_namelen = strlen(localname);
1083 esp->es_savedtime = esp->es_server.ea_timeout;
1085 /* Lower layer up yet? */
1086 if (esp->es_server.ea_state == eapInitial ||
1087 esp->es_server.ea_state == eapPending) {
1088 esp->es_server.ea_state = eapPending;
1092 esp->es_server.ea_state = eapPending;
1094 /* ID number not updated here intentionally; hashed into M1 */
1095 eap_send_request(esp);
1099 * eap_server_timeout - Retransmission timer for sending Requests
1103 eap_server_timeout(void *arg)
1109 #endif /* USE_EAPTLS */
1111 eap_state *esp = (eap_state *) arg;
1113 if (!eap_server_active(esp))
1117 switch(esp->es_server.ea_prev_state) {
1120 * In eap-tls the state changes after a request, so we return to
1121 * previous state ...
1124 case(eapTlsSendAck):
1125 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1129 * ... or resend the stored data
1132 case(eapTlsSendAlert):
1133 outp = outpacket_buf;
1134 MAKEHEADER(outp, PPP_EAP);
1135 PUTCHAR(EAP_REQUEST, outp);
1136 PUTCHAR(esp->es_server.ea_id, outp);
1140 eaptls_retransmit(esp->es_server.ea_session, &outp);
1142 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1143 PUTSHORT(outlen, lenloc);
1144 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1145 esp->es_server.ea_requests++;
1147 if (esp->es_server.ea_timeout > 0)
1148 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1154 #endif /* USE_EAPTLS */
1156 /* EAP ID number must not change on timeout. */
1157 eap_send_request(esp);
1161 * When it's time to send rechallenge the peer, this timeout is
1162 * called. Once the rechallenge is successful, the response handler
1163 * will restart the timer. If it fails, then the link is dropped.
1166 eap_rechallenge(void *arg)
1168 eap_state *esp = (eap_state *)arg;
1170 if (esp->es_server.ea_state != eapOpen &&
1171 esp->es_server.ea_state != eapSRP4)
1174 esp->es_server.ea_requests = 0;
1175 esp->es_server.ea_state = eapIdentify;
1176 eap_figure_next_state(esp, 0);
1177 esp->es_server.ea_id++;
1178 eap_send_request(esp);
1182 srp_lwrechallenge(void *arg)
1184 eap_state *esp = (eap_state *)arg;
1186 if (esp->es_server.ea_state != eapOpen ||
1187 esp->es_server.ea_type != EAPT_SRP)
1190 esp->es_server.ea_requests = 0;
1191 esp->es_server.ea_state = eapSRP4;
1192 esp->es_server.ea_id++;
1193 eap_send_request(esp);
1197 * eap_lowerup - The lower layer is now up.
1199 * This is called before either eap_authpeer or eap_authwithpeer. See
1200 * link_established() in auth.c. All that's necessary here is to
1201 * return to closed state so that those two routines will do the right
1205 eap_lowerup(int unit)
1207 eap_state *esp = &eap_states[unit];
1209 /* Discard any (possibly authenticated) peer name. */
1210 if (esp->es_server.ea_peer != NULL &&
1211 esp->es_server.ea_peer != remote_name)
1212 free(esp->es_server.ea_peer);
1213 esp->es_server.ea_peer = NULL;
1214 if (esp->es_client.ea_peer != NULL)
1215 free(esp->es_client.ea_peer);
1216 esp->es_client.ea_peer = NULL;
1218 esp->es_client.ea_state = eapClosed;
1219 esp->es_server.ea_state = eapClosed;
1223 * eap_lowerdown - The lower layer is now down.
1225 * Cancel all timeouts and return to initial state.
1228 eap_lowerdown(int unit)
1230 eap_state *esp = &eap_states[unit];
1232 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1233 UNTIMEOUT(eap_client_timeout, (void *)esp);
1235 if (eap_server_active(esp)) {
1236 if (esp->es_server.ea_timeout > 0) {
1237 UNTIMEOUT(eap_server_timeout, (void *)esp);
1240 if ((esp->es_server.ea_state == eapOpen ||
1241 esp->es_server.ea_state == eapSRP4) &&
1242 esp->es_rechallenge > 0) {
1243 UNTIMEOUT(eap_rechallenge, (void *)esp);
1245 if (esp->es_server.ea_state == eapOpen &&
1246 esp->es_lwrechallenge > 0) {
1247 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1251 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1252 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1256 * eap_protrej - Peer doesn't speak this protocol.
1258 * This shouldn't happen. If it does, it represents authentication
1262 eap_protrej(int unit)
1264 eap_state *esp = &eap_states[unit];
1266 if (eap_client_active(esp)) {
1267 error("EAP authentication failed due to Protocol-Reject");
1268 auth_withpeer_fail(unit, PPP_EAP);
1270 if (eap_server_active(esp)) {
1271 error("EAP authentication of peer failed on Protocol-Reject");
1272 auth_peer_fail(unit, PPP_EAP);
1274 eap_lowerdown(unit);
1278 * Format and send a regular EAP Response message.
1281 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1282 u_char *str, int lenstr)
1287 outp = outpacket_buf;
1289 MAKEHEADER(outp, PPP_EAP);
1291 PUTCHAR(EAP_RESPONSE, outp);
1293 esp->es_client.ea_id = id;
1294 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1295 PUTSHORT(msglen, outp);
1296 PUTCHAR(typenum, outp);
1298 BCOPY(str, outp, lenstr);
1301 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1305 * Format and send an MD5-Challenge EAP Response message.
1308 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1309 char *name, int namelen)
1314 outp = outpacket_buf;
1316 MAKEHEADER(outp, PPP_EAP);
1318 PUTCHAR(EAP_RESPONSE, outp);
1320 esp->es_client.ea_id = id;
1321 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1323 PUTSHORT(msglen, outp);
1324 PUTCHAR(EAPT_MD5CHAP, outp);
1325 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1326 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1327 INCPTR(MD5_SIGNATURE_SIZE, outp);
1329 BCOPY(name, outp, namelen);
1332 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1337 * Format and send a SRP EAP Response message.
1340 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1341 u_char *str, int lenstr)
1346 outp = outpacket_buf;
1348 MAKEHEADER(outp, PPP_EAP);
1350 PUTCHAR(EAP_RESPONSE, outp);
1352 esp->es_client.ea_id = id;
1353 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1354 PUTSHORT(msglen, outp);
1355 PUTCHAR(EAPT_SRP, outp);
1356 PUTCHAR(subtypenum, outp);
1358 BCOPY(str, outp, lenstr);
1361 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1365 * Format and send a SRP EAP Client Validator Response message.
1368 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1373 outp = outpacket_buf;
1375 MAKEHEADER(outp, PPP_EAP);
1377 PUTCHAR(EAP_RESPONSE, outp);
1379 esp->es_client.ea_id = id;
1380 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1382 PUTSHORT(msglen, outp);
1383 PUTCHAR(EAPT_SRP, outp);
1384 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1385 PUTLONG(flags, outp);
1386 BCOPY(str, outp, SHA_DIGESTSIZE);
1388 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1390 #endif /* USE_SRP */
1394 * Send an EAP-TLS response message with tls data
1397 eap_tls_response(eap_state *esp, u_char id)
1403 outp = outpacket_buf;
1405 MAKEHEADER(outp, PPP_EAP);
1407 PUTCHAR(EAP_RESPONSE, outp);
1414 If the id in the request is unchanged, we must retransmit
1417 if(id == esp->es_client.ea_id)
1418 eaptls_retransmit(esp->es_client.ea_session, &outp);
1420 eaptls_send(esp->es_client.ea_session, &outp);
1422 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1423 PUTSHORT(outlen, lenloc);
1425 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1427 esp->es_client.ea_id = id;
1431 * Send an EAP-TLS ack
1434 eap_tls_sendack(eap_state *esp, u_char id)
1440 outp = outpacket_buf;
1442 MAKEHEADER(outp, PPP_EAP);
1444 PUTCHAR(EAP_RESPONSE, outp);
1446 esp->es_client.ea_id = id;
1451 PUTCHAR(EAPT_TLS, outp);
1454 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1455 PUTSHORT(outlen, lenloc);
1457 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1459 #endif /* USE_EAPTLS */
1462 eap_send_nak(eap_state *esp, u_char id, u_char type)
1467 outp = outpacket_buf;
1469 MAKEHEADER(outp, PPP_EAP);
1471 PUTCHAR(EAP_RESPONSE, outp);
1473 esp->es_client.ea_id = id;
1474 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1475 PUTSHORT(msglen, outp);
1476 PUTCHAR(EAPT_NAK, outp);
1477 PUTCHAR(type, outp);
1479 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1484 name_of_pn_file(void)
1486 char *user, *path, *file;
1489 static bool pnlogged = 0;
1491 pw = getpwuid(getuid());
1492 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1496 file = _PATH_PSEUDONYM;
1497 pl = strlen(user) + strlen(file) + 2;
1501 (void) slprintf(path, pl, "%s/%s", user, file);
1503 dbglog("pseudonym file: %s", path);
1510 open_pn_file(mode_t modebits)
1515 if ((path = name_of_pn_file()) == NULL)
1517 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1525 remove_pn_file(void)
1529 if ((path = name_of_pn_file()) != NULL) {
1530 (void) unlink(path);
1536 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1539 u_char *datp, *digp;
1541 u_char dig[SHA_DIGESTSIZE];
1542 int dsize, fd, olen = len;
1545 * Do the decoding by working backwards. This eliminates the need
1546 * to save the decoded output in a separate buffer.
1550 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1551 dsize = SHA_DIGESTSIZE;
1555 SHA1Update(&ctxt, &val, 1);
1556 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1558 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1560 SHA1Update(&ctxt, esp->es_client.ea_name,
1561 esp->es_client.ea_namelen);
1563 SHA1Final(dig, &ctxt);
1564 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1568 /* Now check that the result is sane */
1569 if (olen <= 0 || *inp + 1 > olen) {
1570 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1575 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1577 dbglog("EAP: error saving pseudonym: %m");
1580 len = write(fd, inp + 1, *inp);
1581 if (close(fd) != -1 && len == *inp) {
1582 dbglog("EAP: saved pseudonym");
1583 esp->es_usedpseudo = 0;
1585 dbglog("EAP: failed to save pseudonym");
1589 #endif /* USE_SRP */
1593 * Format and send an CHAPV2-Challenge EAP Response message.
1596 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1601 outp = outpacket_buf;
1603 MAKEHEADER(outp, PPP_EAP);
1605 PUTCHAR(EAP_RESPONSE, outp);
1607 esp->es_client.ea_id = id;
1608 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1609 PUTSHORT(msglen, outp);
1610 PUTCHAR(EAPT_MSCHAPV2, outp);
1611 PUTCHAR(CHAP_RESPONSE, outp);
1612 PUTCHAR(chapid, outp);
1615 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1616 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1617 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1618 BCOPY(user, outp, user_len);
1620 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1625 * eap_request - Receive EAP Request message (client mode).
1628 eap_request(eap_state *esp, u_char *inp, int id, int len)
1633 char secret[MAXWORDLEN];
1634 char rhostname[256];
1636 u_char hash[MD5_SIGNATURE_SIZE];
1639 struct eaptls_session *ets = esp->es_client.ea_session;
1640 #endif /* USE_EAPTLS */
1643 struct t_client *tc;
1644 struct t_num sval, gval, Nval, *Ap, Bval;
1647 u_char dig[SHA_DIGESTSIZE];
1649 #endif /* USE_SRP */
1652 * Ignore requests if we're not open
1654 if (esp->es_client.ea_state <= eapClosed)
1658 * Note: we update es_client.ea_id *only if* a Response
1659 * message is being generated. Otherwise, we leave it the
1660 * same for duplicate detection purposes.
1663 esp->es_client.ea_requests++;
1664 if (esp->es_client.ea_maxrequests != 0 &&
1665 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1666 info("EAP: received too many Request messages");
1667 if (esp->es_client.ea_timeout > 0) {
1668 UNTIMEOUT(eap_client_timeout, (void *)esp);
1670 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1675 error("EAP: empty Request message discarded");
1679 GETCHAR(typenum, inp);
1685 info("EAP: Identity prompt \"%.*q\"", len, inp);
1687 if (esp->es_usepseudo &&
1688 (esp->es_usedpseudo == 0 ||
1689 (esp->es_usedpseudo == 1 &&
1690 id == esp->es_client.ea_id))) {
1691 esp->es_usedpseudo = 1;
1692 /* Try to get a pseudonym */
1693 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1694 strcpy(rhostname, SRP_PSEUDO_ID);
1695 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1696 sizeof (rhostname) - SRP_PSEUDO_LEN);
1697 /* XXX NAI unsupported */
1699 eap_send_response(esp, id, typenum,
1700 rhostname, len + SRP_PSEUDO_LEN);
1707 /* Stop using pseudonym now. */
1708 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1710 esp->es_usedpseudo = 2;
1712 #endif /* USE_SRP */
1713 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1714 esp->es_client.ea_namelen);
1717 case EAPT_NOTIFICATION:
1719 info("EAP: Notification \"%.*q\"", len, inp);
1720 eap_send_response(esp, id, typenum, NULL, 0);
1725 * Avoid the temptation to send Response Nak in reply
1726 * to Request Nak here. It can only lead to trouble.
1728 warn("EAP: unexpected Nak in Request; ignored");
1729 /* Return because we're waiting for something real. */
1734 error("EAP: received MD5-Challenge with no data");
1735 /* Bogus request; wait for something real. */
1738 GETCHAR(vallen, inp);
1740 if (vallen < 8 || vallen > len) {
1741 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1743 /* Try something better. */
1744 eap_send_nak(esp, id, EAPT_SRP);
1748 /* Not so likely to happen. */
1749 if (len - vallen >= sizeof (rhostname)) {
1750 dbglog("EAP: trimming really long peer name down");
1751 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1752 rhostname[sizeof (rhostname) - 1] = '\0';
1754 BCOPY(inp + vallen, rhostname, len - vallen);
1755 rhostname[len - vallen] = '\0';
1758 /* In case the remote doesn't give us his name. */
1759 if (explicit_remote ||
1760 (remote_name[0] != '\0' && vallen == len))
1761 strlcpy(rhostname, remote_name, sizeof (rhostname));
1764 * Get the secret for authenticating ourselves with
1765 * the specified host.
1767 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1768 rhostname, secret, &secret_len, 0)) {
1769 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1770 eap_send_nak(esp, id, EAPT_SRP);
1773 MD5_Init(&mdContext);
1775 MD5_Update(&mdContext, &typenum, 1);
1776 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1777 BZERO(secret, sizeof (secret));
1778 MD5_Update(&mdContext, inp, vallen);
1779 MD5_Final(hash, &mdContext);
1780 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1781 esp->es_client.ea_namelen);
1787 switch(esp->es_client.ea_state) {
1792 error("EAP: received EAP-TLS Listen packet with no data");
1793 /* Bogus request; wait for something real. */
1796 GETCHAR(flags, inp);
1797 if(flags & EAP_TLS_FLAGS_START){
1799 esp->es_client.ea_using_eaptls = 1;
1801 if (explicit_remote){
1802 esp->es_client.ea_peer = strdup(remote_name);
1803 esp->es_client.ea_peerlen = strlen(remote_name);
1805 esp->es_client.ea_peer = NULL;
1807 /* Init ssl session */
1808 if(!eaptls_init_ssl_client(esp)) {
1809 dbglog("cannot init ssl");
1810 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1811 esp->es_client.ea_using_eaptls = 0;
1815 ets = esp->es_client.ea_session;
1816 eap_tls_response(esp, id);
1817 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1821 /* The server has sent a bad start packet. */
1822 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1826 eap_tls_response(esp, id);
1827 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1832 error("EAP: discarding EAP-TLS Receive packet with no data");
1833 /* Bogus request; wait for something real. */
1836 eaptls_receive(ets, inp, len);
1839 eap_tls_sendack(esp, id);
1840 esp->es_client.ea_state = eapTlsRecv;
1844 if(ets->alert_recv) {
1845 eap_tls_sendack(esp, id);
1846 esp->es_client.ea_state = eapTlsRecvFailure;
1850 /* Check if TLS handshake is finished */
1851 if(eaptls_is_init_finished(ets)) {
1853 eaptls_gen_mppe_keys(ets, 1);
1855 eaptls_free_session(ets);
1856 eap_tls_sendack(esp, id);
1857 esp->es_client.ea_state = eapTlsRecvSuccess;
1861 eap_tls_response(esp,id);
1862 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1866 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1867 esp->es_client.ea_using_eaptls = 0;
1872 #endif /* USE_EAPTLS */
1877 error("EAP: received empty SRP Request");
1878 /* Bogus request; wait for something real. */
1883 GETCHAR(vallen, inp);
1886 case EAPSRP_CHALLENGE:
1888 if (esp->es_client.ea_session != NULL) {
1889 tc = (struct t_client *)esp->es_client.
1892 * If this is a new challenge, then start
1893 * over with a new client session context.
1894 * Otherwise, just resend last response.
1896 if (id != esp->es_client.ea_id) {
1898 esp->es_client.ea_session = NULL;
1902 /* No session key just yet */
1903 esp->es_client.ea_skey = NULL;
1905 GETCHAR(vallen, inp);
1907 if (vallen >= len) {
1908 error("EAP: badly-formed SRP Challenge"
1910 /* Ignore badly-formed messages */
1913 BCOPY(inp, rhostname, vallen);
1914 rhostname[vallen] = '\0';
1915 INCPTR(vallen, inp);
1919 * In case the remote doesn't give us his name,
1920 * use configured name.
1922 if (explicit_remote ||
1923 (remote_name[0] != '\0' && vallen == 0)) {
1924 strlcpy(rhostname, remote_name,
1925 sizeof (rhostname));
1928 if (esp->es_client.ea_peer != NULL)
1929 free(esp->es_client.ea_peer);
1930 esp->es_client.ea_peer = strdup(rhostname);
1931 esp->es_client.ea_peerlen = strlen(rhostname);
1933 GETCHAR(vallen, inp);
1935 if (vallen >= len) {
1936 error("EAP: badly-formed SRP Challenge"
1938 /* Ignore badly-formed messages */
1943 INCPTR(vallen, inp);
1946 GETCHAR(vallen, inp);
1949 error("EAP: badly-formed SRP Challenge"
1951 /* Ignore badly-formed messages */
1954 /* If no generator present, then use value 2 */
1956 gval.data = (u_char *)"\002";
1962 INCPTR(vallen, inp);
1966 * If no modulus present, then use well-known
1970 Nval.data = (u_char *)wkmodulus;
1971 Nval.len = sizeof (wkmodulus);
1976 tc = t_clientopen(esp->es_client.ea_name,
1977 &Nval, &gval, &sval);
1979 eap_send_nak(esp, id, EAPT_MD5CHAP);
1982 esp->es_client.ea_session = (void *)tc;
1984 /* Add Challenge ID & type to verifier */
1987 t_clientaddexdata(tc, vals, 2);
1989 Ap = t_clientgenexp(tc);
1990 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
1995 tc = (struct t_client *)esp->es_client.ea_session;
1997 warn("EAP: peer sent Subtype 2 without 1");
1998 eap_send_nak(esp, id, EAPT_MD5CHAP);
2001 if (esp->es_client.ea_skey != NULL) {
2003 * ID number should not change here. Warn
2004 * if it does (but otherwise ignore).
2006 if (id != esp->es_client.ea_id) {
2007 warn("EAP: ID changed from %d to %d "
2008 "in SRP Subtype 2 rexmit",
2009 esp->es_client.ea_id, id);
2012 if (get_srp_secret(esp->es_unit,
2013 esp->es_client.ea_name,
2014 esp->es_client.ea_peer, secret, 0) == 0) {
2016 * Can't work with this peer because
2017 * the secret is missing. Just give
2020 eap_send_nak(esp, id, EAPT_MD5CHAP);
2025 t_clientpasswd(tc, secret);
2026 BZERO(secret, sizeof (secret));
2027 esp->es_client.ea_skey =
2028 t_clientgetkey(tc, &Bval);
2029 if (esp->es_client.ea_skey == NULL) {
2030 /* Server is rogue; stop now */
2031 error("EAP: SRP server is rogue");
2032 goto client_failure;
2035 eap_srpval_response(esp, id, SRPVAL_EBIT,
2036 t_clientresponse(tc));
2039 case EAPSRP_SVALIDATOR:
2040 tc = (struct t_client *)esp->es_client.ea_session;
2041 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2042 warn("EAP: peer sent Subtype 3 without 1/2");
2043 eap_send_nak(esp, id, EAPT_MD5CHAP);
2047 * If we're already open, then this ought to be a
2048 * duplicate. Otherwise, check that the server is
2049 * who we think it is.
2051 if (esp->es_client.ea_state == eapOpen) {
2052 if (id != esp->es_client.ea_id) {
2053 warn("EAP: ID changed from %d to %d "
2054 "in SRP Subtype 3 rexmit",
2055 esp->es_client.ea_id, id);
2058 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2059 if (len < 0 || t_clientverify(tc, inp +
2060 sizeof (u_int32_t)) != 0) {
2061 error("EAP: SRP server verification "
2063 goto client_failure;
2065 GETLONG(esp->es_client.ea_keyflags, inp);
2066 /* Save pseudonym if user wants it. */
2067 if (len > 0 && esp->es_usepseudo) {
2068 INCPTR(SHA_DIGESTSIZE, inp);
2069 write_pseudonym(esp, inp, len, id);
2073 * We've verified our peer. We're now mostly done,
2074 * except for waiting on the regular EAP Success
2077 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2080 case EAPSRP_LWRECHALLENGE:
2082 warn("EAP: malformed Lightweight rechallenge");
2087 SHA1Update(&ctxt, vals, 1);
2088 SHA1Update(&ctxt, esp->es_client.ea_skey,
2090 SHA1Update(&ctxt, inp, len);
2091 SHA1Update(&ctxt, esp->es_client.ea_name,
2092 esp->es_client.ea_namelen);
2093 SHA1Final(dig, &ctxt);
2094 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2099 error("EAP: unknown SRP Subtype %d", vallen);
2100 eap_send_nak(esp, id, EAPT_MD5CHAP);
2104 #endif /* USE_SRP */
2109 error("EAP: received invalid MSCHAPv2 packet, too short");
2112 unsigned char opcode;
2113 GETCHAR(opcode, inp);
2114 unsigned char chapid; /* Chapv2-ID */
2115 GETCHAR(chapid, inp);
2117 GETSHORT(mssize, inp);
2119 /* Validate the mssize field */
2120 if (len != mssize) {
2121 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2126 /* If MSCHAPv2 digest was not found, NAK the packet */
2127 if (!esp->es_client.digest) {
2128 error("EAP MSCHAPv2 not supported");
2129 eap_send_nak(esp, id, EAPT_SRP);
2134 case CHAP_CHALLENGE: {
2136 /* make_response() expects: VLEN + VALUE */
2137 u_char *challenge = inp;
2139 unsigned char vsize;
2140 GETCHAR(vsize, inp);
2143 /* Validate the VALUE field */
2144 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2145 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2149 /* Increment past the VALUE field */
2150 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2151 len -= MS_CHAP2_PEER_CHAL_LEN;
2153 /* Extract the hostname */
2154 rhostname[0] = '\0';
2156 if (len >= sizeof (rhostname)) {
2157 dbglog("EAP: trimming really long peer name down");
2158 len = sizeof(rhostname) - 1;
2160 BCOPY(inp, rhostname, len);
2161 rhostname[len] = '\0';
2164 /* In case the remote doesn't give us his name. */
2165 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2166 strlcpy(rhostname, remote_name, sizeof(rhostname));
2168 /* Get the secret for authenticating ourselves with the specified host. */
2169 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2170 rhostname, secret, &secret_len, 0)) {
2171 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2172 eap_send_nak(esp, id, EAPT_SRP);
2176 /* Create the MSCHAPv2 response (and add to cache) */
2177 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2178 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2179 challenge, secret, secret_len, NULL);
2181 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2184 case CHAP_SUCCESS: {
2186 /* Check response for mutual authentication */
2187 u_char status = CHAP_FAILURE;
2188 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2189 info("Chap authentication succeeded! %.*v", len, inp);
2190 status = CHAP_SUCCESS;
2192 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2195 case CHAP_FAILURE: {
2197 /* Process the failure string, and log appropriate information */
2198 esp->es_client.digest->handle_failure(inp, len);
2200 u_char status = CHAP_FAILURE;
2201 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2202 goto client_failure; /* force termination */
2206 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2207 eap_send_nak(esp, id, EAPT_SRP);
2214 info("EAP: unknown authentication type %d; Naking", typenum);
2215 eap_send_nak(esp, id, EAPT_SRP);
2219 if (esp->es_client.ea_timeout > 0) {
2220 UNTIMEOUT(eap_client_timeout, (void *)esp);
2221 TIMEOUT(eap_client_timeout, (void *)esp,
2222 esp->es_client.ea_timeout);
2227 esp->es_client.ea_state = eapBadAuth;
2228 if (esp->es_client.ea_timeout > 0) {
2229 UNTIMEOUT(eap_client_timeout, (void *)esp);
2231 esp->es_client.ea_session = NULL;
2234 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2235 #endif /* USE_SRP */
2239 * eap_response - Receive EAP Response message (server mode).
2242 eap_response(eap_state *esp, u_char *inp, int id, int len)
2247 char secret[MAXSECRETLEN];
2248 char rhostname[256];
2250 u_char hash[MD5_SIGNATURE_SIZE];
2252 struct t_server *ts;
2255 u_char dig[SHA_DIGESTSIZE];
2257 u_char dig[SHA_DIGESTSIZE];
2258 #endif /* USE_SRP */
2261 struct eaptls_session *ets;
2263 #endif /* USE_EAPTLS */
2266 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2267 unsigned char *, unsigned char *, char *, int);
2268 char response_message[256];
2272 * Ignore responses if we're not open
2274 if (esp->es_server.ea_state <= eapClosed)
2277 if (esp->es_server.ea_id != id) {
2278 dbglog("EAP: discarding Response %d; expected ID %d", id,
2279 esp->es_server.ea_id);
2283 esp->es_server.ea_responses++;
2286 error("EAP: empty Response message discarded");
2290 GETCHAR(typenum, inp);
2295 if (esp->es_server.ea_state != eapIdentify) {
2296 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2300 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2301 if (esp->es_server.ea_peer != NULL &&
2302 esp->es_server.ea_peer != remote_name)
2303 free(esp->es_server.ea_peer);
2304 esp->es_server.ea_peer = malloc(len + 1);
2305 if (esp->es_server.ea_peer == NULL) {
2306 esp->es_server.ea_peerlen = 0;
2307 eap_figure_next_state(esp, 1);
2310 BCOPY(inp, esp->es_server.ea_peer, len);
2311 esp->es_server.ea_peer[len] = '\0';
2312 esp->es_server.ea_peerlen = len;
2313 eap_figure_next_state(esp, 0);
2318 switch(esp->es_server.ea_state) {
2322 ets = (struct eaptls_session *) esp->es_server.ea_session;
2324 eap_figure_next_state(esp,
2325 eaptls_receive(esp->es_server.ea_session, inp, len));
2327 if(ets->alert_recv) {
2328 eap_send_failure(esp);
2335 dbglog("EAP-TLS ACK with extra data");
2337 eap_figure_next_state(esp, 0);
2340 case eapTlsRecvClient:
2341 /* Receive authentication response from client */
2343 GETCHAR(flags, inp);
2345 if(len == 1 && !flags) { /* Ack = ok */
2347 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2349 eap_send_success(esp);
2351 else { /* failure */
2352 warn("Server authentication failed");
2353 eap_send_failure(esp);
2357 warn("Bogus EAP-TLS packet received from client");
2359 eaptls_free_session(esp->es_server.ea_session);
2363 case eapTlsRecvAlertAck:
2364 eap_send_failure(esp);
2368 eap_figure_next_state(esp, 1);
2372 #endif /* USE_EAPTLS */
2374 case EAPT_NOTIFICATION:
2375 dbglog("EAP unexpected Notification; response discarded");
2380 info("EAP: Nak Response with no suggested protocol");
2381 eap_figure_next_state(esp, 1);
2385 GETCHAR(vallen, inp);
2388 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2389 /* Peer cannot Nak Identify Request */
2390 eap_figure_next_state(esp, 1);
2396 /* Run through SRP validator selection again. */
2397 esp->es_server.ea_state = eapIdentify;
2398 eap_figure_next_state(esp, 0);
2402 esp->es_server.ea_state = eapMD5Chall;
2406 /* Send EAP-TLS start packet */
2408 esp->es_server.ea_state = eapTlsStart;
2410 #endif /* USE_EAPTLS */
2414 info("EAP: peer proposes MSCHAPv2");
2415 /* If MSCHAPv2 digest was not found, NAK the packet */
2416 if (!esp->es_server.digest) {
2417 error("EAP MSCHAPv2 not supported");
2418 eap_send_nak(esp, id, EAPT_SRP);
2421 esp->es_server.ea_state = eapMSCHAPv2Chall;
2426 dbglog("EAP: peer requesting unknown Type %d", vallen);
2427 switch (esp->es_server.ea_state) {
2431 esp->es_server.ea_state = eapMD5Chall;
2435 esp->es_server.ea_state = eapIdentify;
2436 eap_figure_next_state(esp, 0);
2446 if (esp->es_server.ea_state != eapMD5Chall) {
2447 error("EAP: unexpected MD5-Response");
2448 eap_figure_next_state(esp, 1);
2452 error("EAP: received MD5-Response with no data");
2453 eap_figure_next_state(esp, 1);
2456 GETCHAR(vallen, inp);
2458 if (vallen != 16 || vallen > len) {
2459 error("EAP: MD5-Response with bad length %d", vallen);
2460 eap_figure_next_state(esp, 1);
2464 /* Not so likely to happen. */
2465 if (len - vallen >= sizeof (rhostname)) {
2466 dbglog("EAP: trimming really long peer name down");
2467 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2468 rhostname[sizeof (rhostname) - 1] = '\0';
2470 BCOPY(inp + vallen, rhostname, len - vallen);
2471 rhostname[len - vallen] = '\0';
2474 /* In case the remote doesn't give us his name. */
2475 if (explicit_remote ||
2476 (remote_name[0] != '\0' && vallen == len))
2477 strlcpy(rhostname, remote_name, sizeof (rhostname));
2480 * Get the secret for authenticating the specified
2483 if (!get_secret(esp->es_unit, rhostname,
2484 esp->es_server.ea_name, secret, &secret_len, 1)) {
2485 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2486 eap_send_failure(esp);
2489 MD5_Init(&mdContext);
2490 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2491 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2492 BZERO(secret, sizeof (secret));
2493 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2494 MD5_Final(hash, &mdContext);
2495 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2496 eap_send_failure(esp);
2499 esp->es_server.ea_type = EAPT_MD5CHAP;
2500 eap_send_success(esp);
2501 eap_figure_next_state(esp, 0);
2502 if (esp->es_rechallenge != 0)
2503 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2509 error("EAP: received MSCHAPv2 with no data");
2510 eap_figure_next_state(esp, 1);
2513 GETCHAR(opcode, inp);
2518 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2519 error("EAP: unexpected MSCHAPv2-Response");
2520 eap_figure_next_state(esp, 1);
2523 /* skip MS ID + len */
2525 GETCHAR(vallen, inp);
2528 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2529 error("EAP: Invalid MSCHAPv2-Response "
2530 "length %d", vallen);
2531 eap_figure_next_state(esp, 1);
2535 /* Not so likely to happen. */
2536 if (len - vallen >= sizeof (rhostname)) {
2537 dbglog("EAP: trimming really long peer name down");
2538 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2539 rhostname[sizeof (rhostname) - 1] = '\0';
2541 BCOPY(inp + vallen, rhostname, len - vallen);
2542 rhostname[len - vallen] = '\0';
2545 /* In case the remote doesn't give us his name. */
2546 if (explicit_remote ||
2547 (remote_name[0] != '\0' && vallen == len))
2548 strlcpy(rhostname, remote_name, sizeof (rhostname));
2550 /* strip the MS domain name */
2551 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2552 char tmp[MAXNAMELEN+1];
2554 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2555 strcpy(rhostname, tmp);
2558 if (chap_verify_hook)
2559 chap_verifier = chap_verify_hook;
2561 chap_verifier = eap_chap_verify_response;
2563 esp->es_server.ea_id += 1;
2564 if ((*chap_verifier)(rhostname,
2565 esp->es_server.ea_name,
2567 esp->es_server.digest,
2571 sizeof(response_message)))
2573 info("EAP: MSCHAPv2 success for peer %q",
2575 esp->es_server.ea_type = EAPT_MSCHAPV2;
2576 eap_chapms2_send_request(esp,
2577 esp->es_server.ea_id,
2579 esp->es_server.ea_id,
2581 strlen(response_message));
2582 eap_figure_next_state(esp, 0);
2583 if (esp->es_rechallenge != 0)
2584 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2587 warn("EAP: MSCHAPv2 failure for peer %q",
2589 eap_chapms2_send_request(esp,
2590 esp->es_server.ea_id,
2592 esp->es_server.ea_id,
2594 strlen(response_message));
2598 info("EAP: MSCHAPv2 success confirmed");
2601 info("EAP: MSCHAPv2 failure confirmed");
2604 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2605 eap_send_nak(esp, id, EAPT_SRP);
2614 error("EAP: empty SRP Response");
2615 eap_figure_next_state(esp, 1);
2618 GETCHAR(typenum, inp);
2622 if (esp->es_server.ea_state != eapSRP1) {
2623 error("EAP: unexpected SRP Subtype 1 Response");
2624 eap_figure_next_state(esp, 1);
2629 ts = (struct t_server *)esp->es_server.ea_session;
2631 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2632 if (esp->es_server.ea_skey == NULL) {
2633 /* Client's A value is bogus; terminate now */
2634 error("EAP: bogus A value from client");
2635 eap_send_failure(esp);
2637 eap_figure_next_state(esp, 0);
2641 case EAPSRP_CVALIDATOR:
2642 if (esp->es_server.ea_state != eapSRP2) {
2643 error("EAP: unexpected SRP Subtype 2 Response");
2644 eap_figure_next_state(esp, 1);
2647 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2648 error("EAP: M1 length %d < %d", len,
2649 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2650 eap_figure_next_state(esp, 1);
2653 GETLONG(esp->es_server.ea_keyflags, inp);
2654 ts = (struct t_server *)esp->es_server.ea_session;
2656 if (t_serververify(ts, inp)) {
2657 info("EAP: unable to validate client identity");
2658 eap_send_failure(esp);
2661 eap_figure_next_state(esp, 0);
2665 if (esp->es_server.ea_state != eapSRP3) {
2666 error("EAP: unexpected SRP Subtype 3 Response");
2667 eap_send_failure(esp);
2670 esp->es_server.ea_type = EAPT_SRP;
2671 eap_send_success(esp);
2672 eap_figure_next_state(esp, 0);
2673 if (esp->es_rechallenge != 0)
2674 TIMEOUT(eap_rechallenge, esp,
2675 esp->es_rechallenge);
2676 if (esp->es_lwrechallenge != 0)
2677 TIMEOUT(srp_lwrechallenge, esp,
2678 esp->es_lwrechallenge);
2681 case EAPSRP_LWRECHALLENGE:
2682 if (esp->es_server.ea_state != eapSRP4) {
2683 info("EAP: unexpected SRP Subtype 4 Response");
2686 if (len != SHA_DIGESTSIZE) {
2687 error("EAP: bad Lightweight rechallenge "
2693 SHA1Update(&ctxt, &vallen, 1);
2694 SHA1Update(&ctxt, esp->es_server.ea_skey,
2696 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2697 SHA1Update(&ctxt, esp->es_server.ea_peer,
2698 esp->es_server.ea_peerlen);
2699 SHA1Final(dig, &ctxt);
2700 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2701 error("EAP: failed Lightweight rechallenge");
2702 eap_send_failure(esp);
2705 esp->es_server.ea_state = eapOpen;
2706 if (esp->es_lwrechallenge != 0)
2707 TIMEOUT(srp_lwrechallenge, esp,
2708 esp->es_lwrechallenge);
2712 #endif /* USE_SRP */
2715 /* This can't happen. */
2716 error("EAP: unknown Response type %d; ignored", typenum);
2720 if (esp->es_server.ea_timeout > 0) {
2721 UNTIMEOUT(eap_server_timeout, (void *)esp);
2724 if (esp->es_server.ea_state != eapBadAuth &&
2725 esp->es_server.ea_state != eapOpen) {
2726 esp->es_server.ea_id++;
2727 eap_send_request(esp);
2732 * eap_success - Receive EAP Success message (client mode).
2735 eap_success(eap_state *esp, u_char *inp, int id, int len)
2737 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2739 && esp->es_client.ea_state != eapTlsRecvSuccess
2740 #endif /* USE_EAPTLS */
2742 dbglog("EAP unexpected success message in state %s (%d)",
2743 eap_state_name(esp->es_client.ea_state),
2744 esp->es_client.ea_state);
2749 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2750 eapTlsRecvSuccess) {
2751 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2752 eap_state_name(esp->es_client.ea_state),
2753 esp->es_client.ea_state);
2756 #endif /* USE_EAPTLS */
2758 if (esp->es_client.ea_timeout > 0) {
2759 UNTIMEOUT(eap_client_timeout, (void *)esp);
2763 /* This is odd. The spec doesn't allow for this. */
2767 esp->es_client.ea_state = eapOpen;
2768 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2772 * eap_failure - Receive EAP Failure message (client mode).
2775 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2778 * Ignore failure messages if we're not open
2780 if (esp->es_client.ea_state <= eapClosed)
2783 if (!eap_client_active(esp)) {
2784 dbglog("EAP unexpected failure message in state %s (%d)",
2785 eap_state_name(esp->es_client.ea_state),
2786 esp->es_client.ea_state);
2789 if (esp->es_client.ea_timeout > 0) {
2790 UNTIMEOUT(eap_client_timeout, (void *)esp);
2794 /* This is odd. The spec doesn't allow for this. */
2798 esp->es_client.ea_state = eapBadAuth;
2800 error("EAP: peer reports authentication failure");
2801 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2805 * eap_input - Handle received EAP message.
2808 eap_input(int unit, u_char *inp, int inlen)
2810 eap_state *esp = &eap_states[unit];
2815 * Parse header (code, id and length). If packet too short,
2818 if (inlen < EAP_HEADERLEN) {
2819 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2825 if (len < EAP_HEADERLEN || len > inlen) {
2826 error("EAP: packet has illegal length field %d (%d..%d)", len,
2827 EAP_HEADERLEN, inlen);
2830 len -= EAP_HEADERLEN;
2832 /* Dispatch based on message code */
2835 eap_request(esp, inp, id, len);
2839 eap_response(esp, inp, id, len);
2843 eap_success(esp, inp, id, len);
2847 eap_failure(esp, inp, id, len);
2850 default: /* XXX Need code reject */
2851 /* Note: it's not legal to send EAP Nak here. */
2852 warn("EAP: unknown code %d received", code);
2858 * eap_printpkt - print the contents of an EAP packet.
2860 static char *eap_codenames[] = {
2861 "Request", "Response", "Success", "Failure"
2864 static char *eap_typenames[] = {
2865 "Identity", "Notification", "Nak", "MD5-Challenge",
2866 "OTP", "Generic-Token", NULL, NULL,
2867 "RSA", "DSS", "KEA", "KEA-Validate",
2868 "TLS", "Defender", "Windows 2000", "Arcot",
2869 "Cisco", "Nokia", "SRP", NULL,
2870 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2875 eap_printpkt(u_char *inp, int inlen,
2876 void (*printer) (void *, char *, ...), void *arg)
2878 int code, id, len, rtype, vallen;
2883 #endif /* USE_EAPTLS */
2888 if (inlen < EAP_HEADERLEN)
2894 if (len < EAP_HEADERLEN || len > inlen)
2897 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2898 printer(arg, " %s", eap_codenames[code-1]);
2900 printer(arg, " code=0x%x", code);
2901 printer(arg, " id=0x%x", id);
2902 len -= EAP_HEADERLEN;
2906 printer(arg, " <missing type>");
2909 GETCHAR(rtype, inp);
2912 rtype <= sizeof (eap_typenames) / sizeof (char *))
2913 printer(arg, " %s", eap_typenames[rtype-1]);
2915 printer(arg, " type=0x%x", rtype);
2918 case EAPT_NOTIFICATION:
2920 printer(arg, " <Message ");
2921 print_string((char *)inp, len, printer, arg);
2926 printer(arg, " <No message>");
2933 GETCHAR(vallen, inp);
2937 printer(arg, " <Value%.*B>", vallen, inp);
2938 INCPTR(vallen, inp);
2941 printer(arg, " <Name ");
2942 print_string((char *)inp, len, printer, arg);
2947 printer(arg, " <No name>");
2955 GETCHAR(opcode, inp);
2958 case CHAP_CHALLENGE:
2961 GETCHAR(vallen, inp);
2966 printer(arg, " Challenge <");
2967 for (; vallen > 0; --vallen) {
2970 printer(arg, "%.2x", val);
2974 printer(arg, ", <Name ");
2975 print_string((char *)inp, len, printer, arg);
2980 printer(arg, ", <No name>");
2986 printer(arg, " Success <Message ");
2987 print_string((char *)inp, len, printer, arg);
2993 printer(arg, " Failure <Message ");
2994 print_string((char *)inp, len, printer, arg);
3000 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3010 GETCHAR(flags, inp);
3013 if(flags == 0 && len == 0){
3014 printer(arg, " Ack");
3018 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3019 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3020 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3022 #endif /* USE_EAPTLS */
3027 GETCHAR(vallen, inp);
3029 printer(arg, "-%d", vallen);
3031 case EAPSRP_CHALLENGE:
3032 GETCHAR(vallen, inp);
3037 printer(arg, " <Name ");
3038 print_string((char *)inp, vallen, printer,
3042 printer(arg, " <No name>");
3044 INCPTR(vallen, inp);
3046 GETCHAR(vallen, inp);
3050 printer(arg, " <s%.*B>", vallen, inp);
3051 INCPTR(vallen, inp);
3053 GETCHAR(vallen, inp);
3058 printer(arg, " <Default g=2>");
3060 printer(arg, " <g%.*B>", vallen, inp);
3062 INCPTR(vallen, inp);
3065 printer(arg, " <Default N>");
3067 printer(arg, " <N%.*B>", len, inp);
3074 printer(arg, " <B%.*B>", len, inp);
3079 case EAPSRP_SVALIDATOR:
3080 if (len < sizeof (u_int32_t))
3083 len -= sizeof (u_int32_t);
3084 if (uval & SRPVAL_EBIT) {
3086 uval &= ~SRPVAL_EBIT;
3089 printer(arg, " f<%X>", uval);
3091 if ((vallen = len) > SHA_DIGESTSIZE)
3092 vallen = SHA_DIGESTSIZE;
3093 printer(arg, " <M2%.*B%s>", len, inp,
3094 len < SHA_DIGESTSIZE ? "?" : "");
3095 INCPTR(vallen, inp);
3098 printer(arg, " <PN%.*B>", len, inp);
3104 case EAPSRP_LWRECHALLENGE:
3105 printer(arg, " <Challenge%.*B>", len, inp);
3117 GETCHAR(rtype, inp);
3120 rtype <= sizeof (eap_typenames) / sizeof (char *))
3121 printer(arg, " %s", eap_typenames[rtype-1]);
3123 printer(arg, " type=0x%x", rtype);
3127 printer(arg, " <Name ");
3128 print_string((char *)inp, len, printer, arg);
3139 GETCHAR(flags, inp);
3142 if(flags == 0 && len == 0){
3143 printer(arg, " Ack");
3147 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3148 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3149 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3152 #endif /* USE_EAPTLS */
3156 printer(arg, " <missing hint>");
3159 GETCHAR(rtype, inp);
3161 printer(arg, " <Suggested-type %02X", rtype);
3163 rtype <= sizeof (eap_typenames) / sizeof (char *))
3164 printer(arg, " (%s)", eap_typenames[rtype-1]);
3170 printer(arg, " <missing length>");
3173 GETCHAR(vallen, inp);
3177 printer(arg, " <Value%.*B>", vallen, inp);
3178 INCPTR(vallen, inp);
3181 printer(arg, " <Name ");
3182 print_string((char *)inp, len, printer, arg);
3187 printer(arg, " <No name>");
3195 GETCHAR(opcode, inp);
3201 GETCHAR(vallen, inp);
3206 printer(arg, " Response <");
3207 for (; vallen > 0; --vallen) {
3210 printer(arg, "%.2x", val);
3214 printer(arg, ", <Name ");
3215 print_string((char *)inp, len, printer, arg);
3220 printer(arg, ", <No name>");
3224 printer(arg, " Success");
3227 printer(arg, " Failure");
3230 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3239 GETCHAR(vallen, inp);
3241 printer(arg, "-%d", vallen);
3244 printer(arg, " <A%.*B>", len, inp);
3249 case EAPSRP_CVALIDATOR:
3250 if (len < sizeof (u_int32_t))
3253 len -= sizeof (u_int32_t);
3254 if (uval & SRPVAL_EBIT) {
3256 uval &= ~SRPVAL_EBIT;
3259 printer(arg, " f<%X>", uval);
3261 printer(arg, " <M1%.*B%s>", len, inp,
3262 len == SHA_DIGESTSIZE ? "" : "?");
3270 case EAPSRP_LWRECHALLENGE:
3271 printer(arg, " <Response%.*B%s>", len, inp,
3272 len == SHA_DIGESTSIZE ? "" : "?");
3273 if ((vallen = len) > SHA_DIGESTSIZE)
3274 vallen = SHA_DIGESTSIZE;
3275 INCPTR(vallen, inp);
3283 case EAP_SUCCESS: /* No payload expected for these! */
3288 printer(arg, " <truncated>");
3293 printer(arg, "%8B...", inp);
3295 printer(arg, "%.*B", len, inp);
3298 return (inp - pstart);