2 * eap.c - Extensible Authentication Protocol for PPP (RFC 2284)
4 * Copyright (c) 2001 by Sun Microsystems, Inc.
7 * Non-exclusive rights to redistribute, modify, translate, and use
8 * this software in source and binary forms, in whole or in part, is
9 * hereby granted, provided that the above copyright notice is
10 * duplicated in any source form, and that neither the name of the
11 * copyright holder nor the author is used to endorse or promote
12 * products derived from this software.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 * Original version by James Carlson
20 * This implementation of EAP supports MD5-Challenge and SRP-SHA1
21 * authentication styles. Note that support of MD5-Challenge is a
22 * requirement of RFC 2284, and that it's essentially just a
23 * reimplementation of regular RFC 1994 CHAP using EAP messages.
25 * As an authenticator ("server"), there are multiple phases for each
26 * style. In the first phase of each style, the unauthenticated peer
27 * name is queried using the EAP Identity request type. If the
28 * "remotename" option is used, then this phase is skipped, because
29 * the peer's name is presumed to be known.
31 * For MD5-Challenge, there are two phases, and the second phase
32 * consists of sending the challenge itself and handling the
33 * associated response.
35 * For SRP-SHA1, there are four phases. The second sends 's', 'N',
36 * and 'g'. The reply contains 'A'. The third sends 'B', and the
37 * reply contains 'M1'. The forth sends the 'M2' value.
39 * As an authenticatee ("client"), there's just a single phase --
40 * responding to the queries generated by the peer. EAP is an
41 * authenticator-driven protocol.
43 * Based on draft-ietf-pppext-eap-srp-03.txt.
47 * Modification by Beniamino Galvani, Mar 2005
48 * Implemented EAP-TLS authentication
60 #include <sys/types.h>
67 #include "pathnames.h"
81 #ifndef SHA_DIGESTSIZE
82 #define SHA_DIGESTSIZE 20
87 #endif /* USE_EAPTLS */
93 extern int chapms_strip_domain;
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 option_t 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
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;
228 esp->es_client.ea_using_eaptls = 0;
229 #endif /* USE_EAPTLS */
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_setkey(int timeoffs)
338 u_char dig[SHA_DIGESTSIZE];
341 if (pn_secret == NULL)
343 reftime = time(NULL) + timeoffs;
344 tp = localtime(&reftime);
346 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
347 strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp);
348 SHA1Update(&ctxt, tbuf, strlen(tbuf));
349 SHA1Final(dig, &ctxt);
350 return (DesSetkey(dig));
353 static char base64[] =
354 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
362 b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
367 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
370 if (bs->bs_offs >= 24) {
371 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
372 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
373 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
374 *outp++ = base64[bs->bs_bits & 0x3F];
384 b64flush(struct b64state *bs, u_char *outp)
388 if (bs->bs_offs == 8) {
389 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
390 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
392 } else if (bs->bs_offs == 16) {
393 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
394 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
395 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
404 b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
410 if ((cp = strchr(base64, *inp++)) == NULL)
412 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
415 if (bs->bs_offs >= 8) {
416 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
426 * Assume that current waiting server state is complete and figure
427 * next state to use based on available authentication data. 'status'
428 * indicates if there was an error in handling the last query. It is
429 * 0 for success and non-zero for failure.
432 eap_figure_next_state(eap_state *esp, int status)
435 unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
437 struct t_confent *tce, mytce;
440 int id, i, plen, toffs;
445 struct eaptls_session *ets;
447 char secret[MAXWORDLEN];
448 #endif /* USE_EAPTLS */
450 esp->es_server.ea_timeout = esp->es_savedtime;
452 esp->es_server.ea_prev_state = esp->es_server.ea_state;
453 #endif /* USE_EAPTLS */
454 switch (esp->es_server.ea_state) {
460 /* Discard any previous session. */
461 ts = (struct t_server *)esp->es_server.ea_session;
464 esp->es_server.ea_session = NULL;
465 esp->es_server.ea_skey = NULL;
469 esp->es_server.ea_state = eapBadAuth;
473 /* If we've got a pseudonym, try to decode to real name. */
474 if (esp->es_server.ea_peerlen > SRP_PSEUDO_LEN &&
475 strncmp(esp->es_server.ea_peer, SRP_PSEUDO_ID,
476 SRP_PSEUDO_LEN) == 0 &&
477 (esp->es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
479 BZERO(&bs, sizeof (bs));
481 esp->es_server.ea_peer + SRP_PSEUDO_LEN,
482 esp->es_server.ea_peerlen - SRP_PSEUDO_LEN,
485 for (i = 0; i < 5; i++) {
486 pncrypt_setkey(toffs);
488 if (!DesDecrypt(secbuf, clear)) {
489 dbglog("no DES here; cannot decode "
493 id = *(unsigned char *)clear;
494 if (id + 1 <= plen && id + 9 > plen)
497 if (plen % 8 == 0 && i < 5) {
499 * Note that this is always shorter than the
500 * original stored string, so there's no need
503 if ((i = plen = *(unsigned char *)clear) > 7)
505 esp->es_server.ea_peerlen = plen;
506 dp = (unsigned char *)esp->es_server.ea_peer;
507 BCOPY(clear + 1, dp, i);
512 (void) DesDecrypt(sp, dp);
517 esp->es_server.ea_peer[
518 esp->es_server.ea_peerlen] = '\0';
519 dbglog("decoded pseudonym to \"%.*q\"",
520 esp->es_server.ea_peerlen,
521 esp->es_server.ea_peer);
523 dbglog("failed to decode real name");
524 /* Stay in eapIdentfy state; requery */
528 /* Look up user in secrets database. */
529 if (get_srp_secret(esp->es_unit, esp->es_server.ea_peer,
530 esp->es_server.ea_name, (char *)secbuf, 1) != 0) {
531 /* Set up default in case SRP entry is bad */
532 esp->es_server.ea_state = eapMD5Chall;
533 /* Get t_confent based on index in srp-secrets */
534 id = strtol((char *)secbuf, &cp, 10);
535 if (*cp++ != ':' || id < 0)
539 mytce.modulus.data = (u_char *)wkmodulus;
540 mytce.modulus.len = sizeof (wkmodulus);
541 mytce.generator.data = (u_char *)"\002";
542 mytce.generator.len = 1;
544 } else if ((tce = gettcid(id)) != NULL) {
546 * Client will have to verify this modulus/
547 * generator combination, and that will take
548 * a while. Lengthen the timeout here.
550 if (esp->es_server.ea_timeout > 0 &&
551 esp->es_server.ea_timeout < 30)
552 esp->es_server.ea_timeout = 30;
556 if ((cp2 = strchr(cp, ':')) == NULL)
559 tpw.pebuf.name = esp->es_server.ea_peer;
560 tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
562 tpw.pebuf.password.data = (char*) tpw.pwbuf;
563 tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
565 tpw.pebuf.salt.data = tpw.saltbuf;
566 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
568 esp->es_server.ea_session = (void *)ts;
569 esp->es_server.ea_state = eapSRP1;
570 vals[0] = esp->es_server.ea_id + 1;
572 t_serveraddexdata(ts, vals, 2);
573 /* Generate B; must call before t_servergetkey() */
579 if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
580 esp->es_server.ea_name, secret, &secret_len, 1)) {
582 esp->es_server.ea_state = eapTlsStart;
585 #endif /* USE_EAPTLS */
587 esp->es_server.ea_state = eapMD5Chall;
592 /* Initialize ssl session */
593 if(!eaptls_init_ssl_server(esp)) {
594 esp->es_server.ea_state = eapBadAuth;
598 esp->es_server.ea_state = eapTlsRecv;
602 ets = (struct eaptls_session *) esp->es_server.ea_session;
604 if(ets->alert_sent) {
605 esp->es_server.ea_state = eapTlsSendAlert;
610 esp->es_server.ea_state = eapBadAuth;
613 ets = (struct eaptls_session *) esp->es_server.ea_session;
616 esp->es_server.ea_state = eapTlsSendAck;
618 esp->es_server.ea_state = eapTlsSend;
622 ets = (struct eaptls_session *) esp->es_server.ea_session;
625 esp->es_server.ea_state = eapTlsRecvAck;
627 if(SSL_is_init_finished(ets->ssl))
628 esp->es_server.ea_state = eapTlsRecvClient;
630 /* JJK Add "TLS empty record" message here ??? */
631 esp->es_server.ea_state = eapTlsRecv;
635 esp->es_server.ea_state = eapTlsRecv;
641 esp->es_server.ea_state = eapBadAuth;
645 esp->es_server.ea_state = eapTlsSend;
648 case eapTlsSendAlert:
649 esp->es_server.ea_state = eapTlsRecvAlertAck;
651 #endif /* USE_EAPTLS */
655 ts = (struct t_server *)esp->es_server.ea_session;
656 if (ts != NULL && status != 0) {
658 esp->es_server.ea_session = NULL;
659 esp->es_server.ea_skey = NULL;
663 esp->es_server.ea_state = eapMD5Chall;
664 } else if (status != 0 || esp->es_server.ea_session == NULL) {
665 esp->es_server.ea_state = eapBadAuth;
667 esp->es_server.ea_state = eapSRP2;
673 ts = (struct t_server *)esp->es_server.ea_session;
674 if (ts != NULL && status != 0) {
676 esp->es_server.ea_session = NULL;
677 esp->es_server.ea_skey = NULL;
680 if (status != 0 || esp->es_server.ea_session == NULL) {
681 esp->es_server.ea_state = eapBadAuth;
683 esp->es_server.ea_state = eapSRP3;
690 ts = (struct t_server *)esp->es_server.ea_session;
691 if (ts != NULL && status != 0) {
693 esp->es_server.ea_session = NULL;
694 esp->es_server.ea_skey = NULL;
697 if (status != 0 || esp->es_server.ea_session == NULL) {
698 esp->es_server.ea_state = eapBadAuth;
700 esp->es_server.ea_state = eapOpen;
705 case eapMSCHAPv2Chall:
709 esp->es_server.ea_state = eapBadAuth;
711 esp->es_server.ea_state = eapOpen;
716 esp->es_server.ea_state = eapBadAuth;
719 if (esp->es_server.ea_state == eapBadAuth)
720 eap_send_failure(esp);
723 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));
724 #endif /* USE_EAPTLS */
729 * eap_chap_verify_response - check whether the peer's response matches
730 * what we think it should be. Returns 1 if it does (authentication
731 * succeeded), or 0 if it doesn't.
734 eap_chap_verify_response(char *name, char *ourname, int id,
735 struct chap_digest_type *digest,
736 unsigned char *challenge, unsigned char *response,
737 char *message, int message_space)
740 unsigned char secret[MAXSECRETLEN];
743 /* Get the secret that the peer is supposed to know */
744 if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
745 error("No CHAP secret found for authenticating %q", name);
749 ok = digest->verify_response(id, name, secret, secret_len, challenge,
750 response, message, message_space);
751 memset(secret, 0, sizeof(secret));
757 * Format and send an CHAPV2-Success/Failure EAP Request message.
760 eap_chapms2_send_request(eap_state *esp, u_char id,
761 u_char opcode, u_char chapid,
762 char *message, int message_len)
767 outp = outpacket_buf;
769 MAKEHEADER(outp, PPP_EAP);
771 msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
772 msglen += message_len;
774 PUTCHAR(EAP_REQUEST, outp);
776 PUTSHORT(msglen, outp);
777 PUTCHAR(EAPT_MSCHAPV2, outp);
778 PUTCHAR(opcode, outp);
779 PUTCHAR(chapid, outp);
781 PUTSHORT(msglen - 5, outp);
782 BCOPY(message, outp, message_len);
784 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
786 if (opcode == CHAP_SUCCESS) {
787 auth_peer_success(esp->es_unit, PPP_EAP, 0,
788 esp->es_server.ea_peer, esp->es_server.ea_peerlen);
791 esp->es_server.ea_state = eapBadAuth;
792 auth_peer_fail(esp->es_unit, PPP_EAP);
798 * Format an EAP Request message and send it to the peer. Message
799 * type depends on current state. (Server operation)
802 eap_send_request(eap_state *esp)
812 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
818 /* Handle both initial auth and restart */
819 if (esp->es_server.ea_state < eapIdentify &&
820 esp->es_server.ea_state != eapInitial) {
821 esp->es_server.ea_state = eapIdentify;
822 if (explicit_remote) {
824 * If we already know the peer's
825 * unauthenticated name, then there's no
826 * reason to ask. Go to next state instead.
828 esp->es_server.ea_peer = remote_name;
829 esp->es_server.ea_peerlen = strlen(remote_name);
830 eap_figure_next_state(esp, 0);
834 if (esp->es_server.ea_maxrequests > 0 &&
835 esp->es_server.ea_requests >= esp->es_server.ea_maxrequests) {
836 if (esp->es_server.ea_responses > 0)
837 error("EAP: too many Requests sent");
839 error("EAP: no response to Requests");
840 eap_send_failure(esp);
844 outp = outpacket_buf;
846 MAKEHEADER(outp, PPP_EAP);
848 PUTCHAR(EAP_REQUEST, outp);
849 PUTCHAR(esp->es_server.ea_id, outp);
853 switch (esp->es_server.ea_state) {
855 PUTCHAR(EAPT_IDENTITY, outp);
857 challen = strlen(str);
858 BCOPY(str, outp, challen);
859 INCPTR(challen, outp);
863 PUTCHAR(EAPT_MD5CHAP, outp);
865 * pick a random challenge length between
866 * MIN_CHALLENGE_LENGTH and MAX_CHALLENGE_LENGTH
868 challen = (drand48() *
869 (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
870 MIN_CHALLENGE_LENGTH;
871 PUTCHAR(challen, outp);
872 esp->es_challen = challen;
873 ptr = esp->es_challenge;
874 while (--challen >= 0)
875 *ptr++ = (u_char) (drand48() * 0x100);
876 BCOPY(esp->es_challenge, outp, esp->es_challen);
877 INCPTR(esp->es_challen, outp);
878 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
879 INCPTR(esp->es_server.ea_namelen, outp);
883 case eapMSCHAPv2Chall:
884 esp->es_server.digest->generate_challenge(esp->es_challenge);
885 challen = esp->es_challenge[0];
886 esp->es_challen = challen;
888 PUTCHAR(EAPT_MSCHAPV2, outp);
889 PUTCHAR(CHAP_CHALLENGE, outp);
890 PUTCHAR(esp->es_server.ea_id, outp);
892 PUTSHORT(5 + challen +
893 esp->es_server.ea_namelen,
895 /* challen + challenge */
896 BCOPY(esp->es_challenge, outp, challen+1);
897 INCPTR(challen+1, outp);
898 BCOPY(esp->es_server.ea_name,
900 esp->es_server.ea_namelen);
901 INCPTR(esp->es_server.ea_namelen, outp);
907 PUTCHAR(EAPT_TLS, outp);
908 PUTCHAR(EAP_TLS_FLAGS_START, outp);
909 eap_figure_next_state(esp, 0);
913 eaptls_send(esp->es_server.ea_session, &outp);
914 eap_figure_next_state(esp, 0);
918 PUTCHAR(EAPT_TLS, outp);
920 eap_figure_next_state(esp, 0);
923 case eapTlsSendAlert:
924 eaptls_send(esp->es_server.ea_session, &outp);
925 eap_figure_next_state(esp, 0);
927 #endif /* USE_EAPTLS */
931 PUTCHAR(EAPT_SRP, outp);
932 PUTCHAR(EAPSRP_CHALLENGE, outp);
934 PUTCHAR(esp->es_server.ea_namelen, outp);
935 BCOPY(esp->es_server.ea_name, outp, esp->es_server.ea_namelen);
936 INCPTR(esp->es_server.ea_namelen, outp);
938 ts = (struct t_server *)esp->es_server.ea_session;
940 PUTCHAR(ts->s.len, outp);
941 BCOPY(ts->s.data, outp, ts->s.len);
942 INCPTR(ts->s.len, outp);
944 if (ts->g.len == 1 && ts->g.data[0] == 2) {
947 PUTCHAR(ts->g.len, outp);
948 BCOPY(ts->g.data, outp, ts->g.len);
949 INCPTR(ts->g.len, outp);
952 if (ts->n.len != sizeof (wkmodulus) ||
953 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
954 BCOPY(ts->n.data, outp, ts->n.len);
955 INCPTR(ts->n.len, outp);
960 PUTCHAR(EAPT_SRP, outp);
961 PUTCHAR(EAPSRP_SKEY, outp);
963 ts = (struct t_server *)esp->es_server.ea_session;
965 BCOPY(ts->B.data, outp, ts->B.len);
966 INCPTR(ts->B.len, outp);
970 PUTCHAR(EAPT_SRP, outp);
971 PUTCHAR(EAPSRP_SVALIDATOR, outp);
972 PUTLONG(SRPVAL_EBIT, outp);
973 ts = (struct t_server *)esp->es_server.ea_session;
975 BCOPY(t_serverresponse(ts), outp, SHA_DIGESTSIZE);
976 INCPTR(SHA_DIGESTSIZE, outp);
978 if (pncrypt_setkey(0)) {
979 /* Generate pseudonym */
981 cp = (unsigned char *)esp->es_server.ea_peer;
982 if ((j = i = esp->es_server.ea_peerlen) > 7)
985 BCOPY(cp, clear + 1, j);
988 if (!DesEncrypt(clear, cipher)) {
989 dbglog("no DES here; not generating pseudonym");
992 BZERO(&b64, sizeof (b64));
993 outp++; /* space for pseudonym length */
994 outp += b64enc(&b64, cipher, 8, outp);
996 (void) DesEncrypt(cp, cipher);
997 outp += b64enc(&b64, cipher, 8, outp);
1002 BCOPY(cp, clear, i);
1005 *cp++ = drand48() * 0x100;
1008 (void) DesEncrypt(clear, cipher);
1009 outp += b64enc(&b64, cipher, 8, outp);
1011 outp += b64flush(&b64, outp);
1013 /* Set length and pad out to next 20 octet boundary */
1014 i = outp - optr - 1;
1016 i %= SHA_DIGESTSIZE;
1018 while (i < SHA_DIGESTSIZE) {
1019 *outp++ = drand48() * 0x100;
1024 /* Obscure the pseudonym with SHA1 hash */
1026 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1027 SHA1Update(&ctxt, esp->es_server.ea_skey,
1029 SHA1Update(&ctxt, esp->es_server.ea_peer,
1030 esp->es_server.ea_peerlen);
1031 while (optr < outp) {
1032 SHA1Final(dig, &ctxt);
1034 while (cp < dig + SHA_DIGESTSIZE)
1037 SHA1Update(&ctxt, &esp->es_server.ea_id, 1);
1038 SHA1Update(&ctxt, esp->es_server.ea_skey,
1040 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
1047 PUTCHAR(EAPT_SRP, outp);
1048 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
1049 challen = MIN_CHALLENGE_LENGTH +
1050 ((MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH) * drand48());
1051 esp->es_challen = challen;
1052 ptr = esp->es_challenge;
1053 while (--challen >= 0)
1054 *ptr++ = drand48() * 0x100;
1055 BCOPY(esp->es_challenge, outp, esp->es_challen);
1056 INCPTR(esp->es_challen, outp);
1058 #endif /* USE_SRP */
1064 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1065 PUTSHORT(outlen, lenloc);
1067 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1069 esp->es_server.ea_requests++;
1071 if (esp->es_server.ea_timeout > 0)
1072 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1076 * eap_authpeer - Authenticate our peer (behave as server).
1078 * Start server state and send first request. This is called only
1079 * after eap_lowerup.
1082 eap_authpeer(int unit, char *localname)
1084 eap_state *esp = &eap_states[unit];
1086 /* Save the name we're given. */
1087 esp->es_server.ea_name = localname;
1088 esp->es_server.ea_namelen = strlen(localname);
1090 esp->es_savedtime = esp->es_server.ea_timeout;
1092 /* Lower layer up yet? */
1093 if (esp->es_server.ea_state == eapInitial ||
1094 esp->es_server.ea_state == eapPending) {
1095 esp->es_server.ea_state = eapPending;
1099 esp->es_server.ea_state = eapPending;
1101 /* ID number not updated here intentionally; hashed into M1 */
1102 eap_send_request(esp);
1106 * eap_server_timeout - Retransmission timer for sending Requests
1110 eap_server_timeout(void *arg)
1116 #endif /* USE_EAPTLS */
1118 eap_state *esp = (eap_state *) arg;
1120 if (!eap_server_active(esp))
1124 switch(esp->es_server.ea_prev_state) {
1127 * In eap-tls the state changes after a request, so we return to
1128 * previous state ...
1131 case(eapTlsSendAck):
1132 esp->es_server.ea_state = esp->es_server.ea_prev_state;
1136 * ... or resend the stored data
1139 case(eapTlsSendAlert):
1140 outp = outpacket_buf;
1141 MAKEHEADER(outp, PPP_EAP);
1142 PUTCHAR(EAP_REQUEST, outp);
1143 PUTCHAR(esp->es_server.ea_id, outp);
1147 eaptls_retransmit(esp->es_server.ea_session, &outp);
1149 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1150 PUTSHORT(outlen, lenloc);
1151 output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1152 esp->es_server.ea_requests++;
1154 if (esp->es_server.ea_timeout > 0)
1155 TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1161 #endif /* USE_EAPTLS */
1163 /* EAP ID number must not change on timeout. */
1164 eap_send_request(esp);
1168 * When it's time to send rechallenge the peer, this timeout is
1169 * called. Once the rechallenge is successful, the response handler
1170 * will restart the timer. If it fails, then the link is dropped.
1173 eap_rechallenge(void *arg)
1175 eap_state *esp = (eap_state *)arg;
1177 if (esp->es_server.ea_state != eapOpen &&
1178 esp->es_server.ea_state != eapSRP4)
1181 esp->es_server.ea_requests = 0;
1182 esp->es_server.ea_state = eapIdentify;
1183 eap_figure_next_state(esp, 0);
1184 esp->es_server.ea_id++;
1185 eap_send_request(esp);
1189 srp_lwrechallenge(void *arg)
1191 eap_state *esp = (eap_state *)arg;
1193 if (esp->es_server.ea_state != eapOpen ||
1194 esp->es_server.ea_type != EAPT_SRP)
1197 esp->es_server.ea_requests = 0;
1198 esp->es_server.ea_state = eapSRP4;
1199 esp->es_server.ea_id++;
1200 eap_send_request(esp);
1204 * eap_lowerup - The lower layer is now up.
1206 * This is called before either eap_authpeer or eap_authwithpeer. See
1207 * link_established() in auth.c. All that's necessary here is to
1208 * return to closed state so that those two routines will do the right
1212 eap_lowerup(int unit)
1214 eap_state *esp = &eap_states[unit];
1216 /* Discard any (possibly authenticated) peer name. */
1217 if (esp->es_server.ea_peer != NULL &&
1218 esp->es_server.ea_peer != remote_name)
1219 free(esp->es_server.ea_peer);
1220 esp->es_server.ea_peer = NULL;
1221 if (esp->es_client.ea_peer != NULL)
1222 free(esp->es_client.ea_peer);
1223 esp->es_client.ea_peer = NULL;
1225 esp->es_client.ea_state = eapClosed;
1226 esp->es_server.ea_state = eapClosed;
1230 * eap_lowerdown - The lower layer is now down.
1232 * Cancel all timeouts and return to initial state.
1235 eap_lowerdown(int unit)
1237 eap_state *esp = &eap_states[unit];
1239 if (eap_client_active(esp) && esp->es_client.ea_timeout > 0) {
1240 UNTIMEOUT(eap_client_timeout, (void *)esp);
1242 if (eap_server_active(esp)) {
1243 if (esp->es_server.ea_timeout > 0) {
1244 UNTIMEOUT(eap_server_timeout, (void *)esp);
1247 if ((esp->es_server.ea_state == eapOpen ||
1248 esp->es_server.ea_state == eapSRP4) &&
1249 esp->es_rechallenge > 0) {
1250 UNTIMEOUT(eap_rechallenge, (void *)esp);
1252 if (esp->es_server.ea_state == eapOpen &&
1253 esp->es_lwrechallenge > 0) {
1254 UNTIMEOUT(srp_lwrechallenge, (void *)esp);
1258 esp->es_client.ea_state = esp->es_server.ea_state = eapInitial;
1259 esp->es_client.ea_requests = esp->es_server.ea_requests = 0;
1263 * eap_protrej - Peer doesn't speak this protocol.
1265 * This shouldn't happen. If it does, it represents authentication
1269 eap_protrej(int unit)
1271 eap_state *esp = &eap_states[unit];
1273 if (eap_client_active(esp)) {
1274 error("EAP authentication failed due to Protocol-Reject");
1275 auth_withpeer_fail(unit, PPP_EAP);
1277 if (eap_server_active(esp)) {
1278 error("EAP authentication of peer failed on Protocol-Reject");
1279 auth_peer_fail(unit, PPP_EAP);
1281 eap_lowerdown(unit);
1285 * Format and send a regular EAP Response message.
1288 eap_send_response(eap_state *esp, u_char id, u_char typenum,
1289 u_char *str, int lenstr)
1294 outp = outpacket_buf;
1296 MAKEHEADER(outp, PPP_EAP);
1298 PUTCHAR(EAP_RESPONSE, outp);
1300 esp->es_client.ea_id = id;
1301 msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr;
1302 PUTSHORT(msglen, outp);
1303 PUTCHAR(typenum, outp);
1305 BCOPY(str, outp, lenstr);
1308 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1312 * Format and send an MD5-Challenge EAP Response message.
1315 eap_chap_response(eap_state *esp, u_char id, u_char *hash,
1316 char *name, int namelen)
1321 outp = outpacket_buf;
1323 MAKEHEADER(outp, PPP_EAP);
1325 PUTCHAR(EAP_RESPONSE, outp);
1327 esp->es_client.ea_id = id;
1328 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE +
1330 PUTSHORT(msglen, outp);
1331 PUTCHAR(EAPT_MD5CHAP, outp);
1332 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1333 BCOPY(hash, outp, MD5_SIGNATURE_SIZE);
1334 INCPTR(MD5_SIGNATURE_SIZE, outp);
1336 BCOPY(name, outp, namelen);
1339 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1344 * Format and send a SRP EAP Response message.
1347 eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
1348 u_char *str, int lenstr)
1353 outp = outpacket_buf;
1355 MAKEHEADER(outp, PPP_EAP);
1357 PUTCHAR(EAP_RESPONSE, outp);
1359 esp->es_client.ea_id = id;
1360 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr;
1361 PUTSHORT(msglen, outp);
1362 PUTCHAR(EAPT_SRP, outp);
1363 PUTCHAR(subtypenum, outp);
1365 BCOPY(str, outp, lenstr);
1368 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1372 * Format and send a SRP EAP Client Validator Response message.
1375 eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
1380 outp = outpacket_buf;
1382 MAKEHEADER(outp, PPP_EAP);
1384 PUTCHAR(EAP_RESPONSE, outp);
1386 esp->es_client.ea_id = id;
1387 msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u_int32_t) +
1389 PUTSHORT(msglen, outp);
1390 PUTCHAR(EAPT_SRP, outp);
1391 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1392 PUTLONG(flags, outp);
1393 BCOPY(str, outp, SHA_DIGESTSIZE);
1395 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1397 #endif /* USE_SRP */
1401 * Send an EAP-TLS response message with tls data
1404 eap_tls_response(eap_state *esp, u_char id)
1410 outp = outpacket_buf;
1412 MAKEHEADER(outp, PPP_EAP);
1414 PUTCHAR(EAP_RESPONSE, outp);
1421 If the id in the request is unchanged, we must retransmit
1424 if(id == esp->es_client.ea_id)
1425 eaptls_retransmit(esp->es_client.ea_session, &outp);
1427 eaptls_send(esp->es_client.ea_session, &outp);
1429 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1430 PUTSHORT(outlen, lenloc);
1432 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1434 esp->es_client.ea_id = id;
1438 * Send an EAP-TLS ack
1441 eap_tls_sendack(eap_state *esp, u_char id)
1447 outp = outpacket_buf;
1449 MAKEHEADER(outp, PPP_EAP);
1451 PUTCHAR(EAP_RESPONSE, outp);
1453 esp->es_client.ea_id = id;
1458 PUTCHAR(EAPT_TLS, outp);
1461 outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1462 PUTSHORT(outlen, lenloc);
1464 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1466 #endif /* USE_EAPTLS */
1469 eap_send_nak(eap_state *esp, u_char id, u_char type)
1474 outp = outpacket_buf;
1476 MAKEHEADER(outp, PPP_EAP);
1478 PUTCHAR(EAP_RESPONSE, outp);
1480 esp->es_client.ea_id = id;
1481 msglen = EAP_HEADERLEN + 2 * sizeof (u_char);
1482 PUTSHORT(msglen, outp);
1483 PUTCHAR(EAPT_NAK, outp);
1484 PUTCHAR(type, outp);
1486 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1491 name_of_pn_file(void)
1493 char *user, *path, *file;
1496 static bool pnlogged = 0;
1498 pw = getpwuid(getuid());
1499 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1503 file = _PATH_PSEUDONYM;
1504 pl = strlen(user) + strlen(file) + 2;
1508 (void) slprintf(path, pl, "%s/%s", user, file);
1510 dbglog("pseudonym file: %s", path);
1517 open_pn_file(mode_t modebits)
1522 if ((path = name_of_pn_file()) == NULL)
1524 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1532 remove_pn_file(void)
1536 if ((path = name_of_pn_file()) != NULL) {
1537 (void) unlink(path);
1543 write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
1546 u_char *datp, *digp;
1548 u_char dig[SHA_DIGESTSIZE];
1549 int dsize, fd, olen = len;
1552 * Do the decoding by working backwards. This eliminates the need
1553 * to save the decoded output in a separate buffer.
1557 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1558 dsize = SHA_DIGESTSIZE;
1562 SHA1Update(&ctxt, &val, 1);
1563 SHA1Update(&ctxt, esp->es_client.ea_skey, SESSION_KEY_LEN);
1565 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1567 SHA1Update(&ctxt, esp->es_client.ea_name,
1568 esp->es_client.ea_namelen);
1570 SHA1Final(dig, &ctxt);
1571 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1575 /* Now check that the result is sane */
1576 if (olen <= 0 || *inp + 1 > olen) {
1577 dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1582 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1584 dbglog("EAP: error saving pseudonym: %m");
1587 len = write(fd, inp + 1, *inp);
1588 if (close(fd) != -1 && len == *inp) {
1589 dbglog("EAP: saved pseudonym");
1590 esp->es_usedpseudo = 0;
1592 dbglog("EAP: failed to save pseudonym");
1596 #endif /* USE_SRP */
1600 * Format and send an CHAPV2-Challenge EAP Response message.
1603 eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len)
1608 outp = outpacket_buf;
1610 MAKEHEADER(outp, PPP_EAP);
1612 PUTCHAR(EAP_RESPONSE, outp);
1614 esp->es_client.ea_id = id;
1615 msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len;
1616 PUTSHORT(msglen, outp);
1617 PUTCHAR(EAPT_MSCHAPV2, outp);
1618 PUTCHAR(CHAP_RESPONSE, outp);
1619 PUTCHAR(chapid, outp);
1622 PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
1623 BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
1624 INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
1625 BCOPY(user, outp, user_len);
1627 output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
1632 * eap_request - Receive EAP Request message (client mode).
1635 eap_request(eap_state *esp, u_char *inp, int id, int len)
1640 char secret[MAXWORDLEN];
1641 char rhostname[256];
1643 u_char hash[MD5_SIGNATURE_SIZE];
1646 struct eaptls_session *ets = esp->es_client.ea_session;
1647 #endif /* USE_EAPTLS */
1650 struct t_client *tc;
1651 struct t_num sval, gval, Nval, *Ap, Bval;
1654 u_char dig[SHA_DIGESTSIZE];
1656 #endif /* USE_SRP */
1659 * Ignore requests if we're not open
1661 if (esp->es_client.ea_state <= eapClosed)
1665 * Note: we update es_client.ea_id *only if* a Response
1666 * message is being generated. Otherwise, we leave it the
1667 * same for duplicate detection purposes.
1670 esp->es_client.ea_requests++;
1671 if (esp->es_client.ea_maxrequests != 0 &&
1672 esp->es_client.ea_requests > esp->es_client.ea_maxrequests) {
1673 info("EAP: received too many Request messages");
1674 if (esp->es_client.ea_timeout > 0) {
1675 UNTIMEOUT(eap_client_timeout, (void *)esp);
1677 auth_withpeer_fail(esp->es_unit, PPP_EAP);
1682 error("EAP: empty Request message discarded");
1686 GETCHAR(typenum, inp);
1692 info("EAP: Identity prompt \"%.*q\"", len, inp);
1694 if (esp->es_usepseudo &&
1695 (esp->es_usedpseudo == 0 ||
1696 (esp->es_usedpseudo == 1 &&
1697 id == esp->es_client.ea_id))) {
1698 esp->es_usedpseudo = 1;
1699 /* Try to get a pseudonym */
1700 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1701 strcpy(rhostname, SRP_PSEUDO_ID);
1702 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1703 sizeof (rhostname) - SRP_PSEUDO_LEN);
1704 /* XXX NAI unsupported */
1706 eap_send_response(esp, id, typenum,
1707 rhostname, len + SRP_PSEUDO_LEN);
1714 /* Stop using pseudonym now. */
1715 if (esp->es_usepseudo && esp->es_usedpseudo != 2) {
1717 esp->es_usedpseudo = 2;
1719 #endif /* USE_SRP */
1720 eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
1721 esp->es_client.ea_namelen);
1724 case EAPT_NOTIFICATION:
1726 info("EAP: Notification \"%.*q\"", len, inp);
1727 eap_send_response(esp, id, typenum, NULL, 0);
1732 * Avoid the temptation to send Response Nak in reply
1733 * to Request Nak here. It can only lead to trouble.
1735 warn("EAP: unexpected Nak in Request; ignored");
1736 /* Return because we're waiting for something real. */
1741 error("EAP: received MD5-Challenge with no data");
1742 /* Bogus request; wait for something real. */
1745 GETCHAR(vallen, inp);
1747 if (vallen < 8 || vallen > len) {
1748 error("EAP: MD5-Challenge with bad length %d (8..%d)",
1750 /* Try something better. */
1751 eap_send_nak(esp, id, EAPT_SRP);
1755 /* Not so likely to happen. */
1756 if (len - vallen >= sizeof (rhostname)) {
1757 dbglog("EAP: trimming really long peer name down");
1758 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
1759 rhostname[sizeof (rhostname) - 1] = '\0';
1761 BCOPY(inp + vallen, rhostname, len - vallen);
1762 rhostname[len - vallen] = '\0';
1765 /* In case the remote doesn't give us his name. */
1766 if (explicit_remote ||
1767 (remote_name[0] != '\0' && vallen == len))
1768 strlcpy(rhostname, remote_name, sizeof (rhostname));
1771 * Get the secret for authenticating ourselves with
1772 * the specified host.
1774 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
1775 rhostname, secret, &secret_len, 0)) {
1776 dbglog("EAP: no MD5 secret for auth to %q", rhostname);
1777 eap_send_nak(esp, id, EAPT_SRP);
1780 MD5_Init(&mdContext);
1782 MD5_Update(&mdContext, &typenum, 1);
1783 MD5_Update(&mdContext, (u_char *)secret, secret_len);
1784 BZERO(secret, sizeof (secret));
1785 MD5_Update(&mdContext, inp, vallen);
1786 MD5_Final(hash, &mdContext);
1787 eap_chap_response(esp, id, hash, esp->es_client.ea_name,
1788 esp->es_client.ea_namelen);
1794 switch(esp->es_client.ea_state) {
1799 error("EAP: received EAP-TLS Listen packet with no data");
1800 /* Bogus request; wait for something real. */
1803 GETCHAR(flags, inp);
1804 if(flags & EAP_TLS_FLAGS_START){
1806 esp->es_client.ea_using_eaptls = 1;
1808 if (explicit_remote){
1809 esp->es_client.ea_peer = strdup(remote_name);
1810 esp->es_client.ea_peerlen = strlen(remote_name);
1812 esp->es_client.ea_peer = NULL;
1814 /* Init ssl session */
1815 if(!eaptls_init_ssl_client(esp)) {
1816 dbglog("cannot init ssl");
1817 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1818 esp->es_client.ea_using_eaptls = 0;
1822 ets = esp->es_client.ea_session;
1823 eap_tls_response(esp, id);
1824 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1828 /* The server has sent a bad start packet. */
1829 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1833 eap_tls_response(esp, id);
1834 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1839 error("EAP: discarding EAP-TLS Receive packet with no data");
1840 /* Bogus request; wait for something real. */
1843 eaptls_receive(ets, inp, len);
1846 eap_tls_sendack(esp, id);
1847 esp->es_client.ea_state = eapTlsRecv;
1851 if(ets->alert_recv) {
1852 eap_tls_sendack(esp, id);
1853 esp->es_client.ea_state = eapTlsRecvFailure;
1857 /* Check if TLS handshake is finished */
1858 if(eaptls_is_init_finished(ets)) {
1860 eaptls_gen_mppe_keys(ets, 1);
1862 eaptls_free_session(ets);
1863 eap_tls_sendack(esp, id);
1864 esp->es_client.ea_state = eapTlsRecvSuccess;
1868 eap_tls_response(esp,id);
1869 esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
1873 eap_send_nak(esp, id, EAPT_MSCHAPV2);
1874 esp->es_client.ea_using_eaptls = 0;
1879 #endif /* USE_EAPTLS */
1884 error("EAP: received empty SRP Request");
1885 /* Bogus request; wait for something real. */
1890 GETCHAR(vallen, inp);
1893 case EAPSRP_CHALLENGE:
1895 if (esp->es_client.ea_session != NULL) {
1896 tc = (struct t_client *)esp->es_client.
1899 * If this is a new challenge, then start
1900 * over with a new client session context.
1901 * Otherwise, just resend last response.
1903 if (id != esp->es_client.ea_id) {
1905 esp->es_client.ea_session = NULL;
1909 /* No session key just yet */
1910 esp->es_client.ea_skey = NULL;
1912 GETCHAR(vallen, inp);
1914 if (vallen >= len) {
1915 error("EAP: badly-formed SRP Challenge"
1917 /* Ignore badly-formed messages */
1920 BCOPY(inp, rhostname, vallen);
1921 rhostname[vallen] = '\0';
1922 INCPTR(vallen, inp);
1926 * In case the remote doesn't give us his name,
1927 * use configured name.
1929 if (explicit_remote ||
1930 (remote_name[0] != '\0' && vallen == 0)) {
1931 strlcpy(rhostname, remote_name,
1932 sizeof (rhostname));
1935 if (esp->es_client.ea_peer != NULL)
1936 free(esp->es_client.ea_peer);
1937 esp->es_client.ea_peer = strdup(rhostname);
1938 esp->es_client.ea_peerlen = strlen(rhostname);
1940 GETCHAR(vallen, inp);
1942 if (vallen >= len) {
1943 error("EAP: badly-formed SRP Challenge"
1945 /* Ignore badly-formed messages */
1950 INCPTR(vallen, inp);
1953 GETCHAR(vallen, inp);
1956 error("EAP: badly-formed SRP Challenge"
1958 /* Ignore badly-formed messages */
1961 /* If no generator present, then use value 2 */
1963 gval.data = (u_char *)"\002";
1969 INCPTR(vallen, inp);
1973 * If no modulus present, then use well-known
1977 Nval.data = (u_char *)wkmodulus;
1978 Nval.len = sizeof (wkmodulus);
1983 tc = t_clientopen(esp->es_client.ea_name,
1984 &Nval, &gval, &sval);
1986 eap_send_nak(esp, id, EAPT_MD5CHAP);
1989 esp->es_client.ea_session = (void *)tc;
1991 /* Add Challenge ID & type to verifier */
1994 t_clientaddexdata(tc, vals, 2);
1996 Ap = t_clientgenexp(tc);
1997 eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data,
2002 tc = (struct t_client *)esp->es_client.ea_session;
2004 warn("EAP: peer sent Subtype 2 without 1");
2005 eap_send_nak(esp, id, EAPT_MD5CHAP);
2008 if (esp->es_client.ea_skey != NULL) {
2010 * ID number should not change here. Warn
2011 * if it does (but otherwise ignore).
2013 if (id != esp->es_client.ea_id) {
2014 warn("EAP: ID changed from %d to %d "
2015 "in SRP Subtype 2 rexmit",
2016 esp->es_client.ea_id, id);
2019 if (get_srp_secret(esp->es_unit,
2020 esp->es_client.ea_name,
2021 esp->es_client.ea_peer, secret, 0) == 0) {
2023 * Can't work with this peer because
2024 * the secret is missing. Just give
2027 eap_send_nak(esp, id, EAPT_MD5CHAP);
2032 t_clientpasswd(tc, secret);
2033 BZERO(secret, sizeof (secret));
2034 esp->es_client.ea_skey =
2035 t_clientgetkey(tc, &Bval);
2036 if (esp->es_client.ea_skey == NULL) {
2037 /* Server is rogue; stop now */
2038 error("EAP: SRP server is rogue");
2039 goto client_failure;
2042 eap_srpval_response(esp, id, SRPVAL_EBIT,
2043 t_clientresponse(tc));
2046 case EAPSRP_SVALIDATOR:
2047 tc = (struct t_client *)esp->es_client.ea_session;
2048 if (tc == NULL || esp->es_client.ea_skey == NULL) {
2049 warn("EAP: peer sent Subtype 3 without 1/2");
2050 eap_send_nak(esp, id, EAPT_MD5CHAP);
2054 * If we're already open, then this ought to be a
2055 * duplicate. Otherwise, check that the server is
2056 * who we think it is.
2058 if (esp->es_client.ea_state == eapOpen) {
2059 if (id != esp->es_client.ea_id) {
2060 warn("EAP: ID changed from %d to %d "
2061 "in SRP Subtype 3 rexmit",
2062 esp->es_client.ea_id, id);
2065 len -= sizeof (u_int32_t) + SHA_DIGESTSIZE;
2066 if (len < 0 || t_clientverify(tc, inp +
2067 sizeof (u_int32_t)) != 0) {
2068 error("EAP: SRP server verification "
2070 goto client_failure;
2072 GETLONG(esp->es_client.ea_keyflags, inp);
2073 /* Save pseudonym if user wants it. */
2074 if (len > 0 && esp->es_usepseudo) {
2075 INCPTR(SHA_DIGESTSIZE, inp);
2076 write_pseudonym(esp, inp, len, id);
2080 * We've verified our peer. We're now mostly done,
2081 * except for waiting on the regular EAP Success
2084 eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0);
2087 case EAPSRP_LWRECHALLENGE:
2089 warn("EAP: malformed Lightweight rechallenge");
2094 SHA1Update(&ctxt, vals, 1);
2095 SHA1Update(&ctxt, esp->es_client.ea_skey,
2097 SHA1Update(&ctxt, inp, len);
2098 SHA1Update(&ctxt, esp->es_client.ea_name,
2099 esp->es_client.ea_namelen);
2100 SHA1Final(dig, &ctxt);
2101 eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig,
2106 error("EAP: unknown SRP Subtype %d", vallen);
2107 eap_send_nak(esp, id, EAPT_MD5CHAP);
2111 #endif /* USE_SRP */
2116 error("EAP: received invalid MSCHAPv2 packet, too short");
2119 unsigned char opcode;
2120 GETCHAR(opcode, inp);
2121 unsigned char chapid; /* Chapv2-ID */
2122 GETCHAR(chapid, inp);
2124 GETSHORT(mssize, inp);
2126 /* Validate the mssize field */
2127 if (len != mssize) {
2128 error("EAP: received invalid MSCHAPv2 packet, invalid length");
2133 /* If MSCHAPv2 digest was not found, NAK the packet */
2134 if (!esp->es_client.digest) {
2135 error("EAP MSCHAPv2 not supported");
2136 eap_send_nak(esp, id, EAPT_SRP);
2141 case CHAP_CHALLENGE: {
2143 /* make_response() expects: VLEN + VALUE */
2144 u_char *challenge = inp;
2146 unsigned char vsize;
2147 GETCHAR(vsize, inp);
2150 /* Validate the VALUE field */
2151 if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) {
2152 error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
2156 /* Increment past the VALUE field */
2157 INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp);
2158 len -= MS_CHAP2_PEER_CHAL_LEN;
2160 /* Extract the hostname */
2161 rhostname[0] = '\0';
2163 if (len >= sizeof (rhostname)) {
2164 dbglog("EAP: trimming really long peer name down");
2165 len = sizeof(rhostname) - 1;
2167 BCOPY(inp, rhostname, len);
2168 rhostname[len] = '\0';
2171 /* In case the remote doesn't give us his name. */
2172 if (explicit_remote || (remote_name[0] != '\0' && len == 0))
2173 strlcpy(rhostname, remote_name, sizeof(rhostname));
2175 /* Get the secret for authenticating ourselves with the specified host. */
2176 if (!get_secret(esp->es_unit, esp->es_client.ea_name,
2177 rhostname, secret, &secret_len, 0)) {
2178 dbglog("EAP: no CHAP secret for auth to %q", rhostname);
2179 eap_send_nak(esp, id, EAPT_SRP);
2183 /* Create the MSCHAPv2 response (and add to cache) */
2184 unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE
2185 esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name,
2186 challenge, secret, secret_len, NULL);
2188 eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen);
2191 case CHAP_SUCCESS: {
2193 /* Check response for mutual authentication */
2194 u_char status = CHAP_FAILURE;
2195 if (esp->es_client.digest->check_success(chapid, inp, len) == 1) {
2196 info("Chap authentication succeeded! %.*v", len, inp);
2197 status = CHAP_SUCCESS;
2199 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2202 case CHAP_FAILURE: {
2204 /* Process the failure string, and log appropriate information */
2205 esp->es_client.digest->handle_failure(inp, len);
2207 u_char status = CHAP_FAILURE;
2208 eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status));
2209 goto client_failure; /* force termination */
2213 error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode);
2214 eap_send_nak(esp, id, EAPT_SRP);
2221 info("EAP: unknown authentication type %d; Naking", typenum);
2222 eap_send_nak(esp, id, EAPT_SRP);
2226 if (esp->es_client.ea_timeout > 0) {
2227 UNTIMEOUT(eap_client_timeout, (void *)esp);
2228 TIMEOUT(eap_client_timeout, (void *)esp,
2229 esp->es_client.ea_timeout);
2234 esp->es_client.ea_state = eapBadAuth;
2235 if (esp->es_client.ea_timeout > 0) {
2236 UNTIMEOUT(eap_client_timeout, (void *)esp);
2238 esp->es_client.ea_session = NULL;
2241 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2242 #endif /* USE_SRP */
2246 * eap_response - Receive EAP Response message (server mode).
2249 eap_response(eap_state *esp, u_char *inp, int id, int len)
2254 char secret[MAXSECRETLEN];
2255 char rhostname[256];
2257 u_char hash[MD5_SIGNATURE_SIZE];
2259 struct t_server *ts;
2262 u_char dig[SHA_DIGESTSIZE];
2263 #endif /* USE_SRP */
2266 struct eaptls_session *ets;
2268 #endif /* USE_EAPTLS */
2271 int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
2272 unsigned char *, unsigned char *, char *, int);
2273 char response_message[256];
2277 * Ignore responses if we're not open
2279 if (esp->es_server.ea_state <= eapClosed)
2282 if (esp->es_server.ea_id != id) {
2283 dbglog("EAP: discarding Response %d; expected ID %d", id,
2284 esp->es_server.ea_id);
2288 esp->es_server.ea_responses++;
2291 error("EAP: empty Response message discarded");
2295 GETCHAR(typenum, inp);
2300 if (esp->es_server.ea_state != eapIdentify) {
2301 dbglog("EAP discarding unwanted Identify \"%.q\"", len,
2305 info("EAP: unauthenticated peer name \"%.*q\"", len, inp);
2306 if (esp->es_server.ea_peer != NULL &&
2307 esp->es_server.ea_peer != remote_name)
2308 free(esp->es_server.ea_peer);
2309 esp->es_server.ea_peer = malloc(len + 1);
2310 if (esp->es_server.ea_peer == NULL) {
2311 esp->es_server.ea_peerlen = 0;
2312 eap_figure_next_state(esp, 1);
2315 BCOPY(inp, esp->es_server.ea_peer, len);
2316 esp->es_server.ea_peer[len] = '\0';
2317 esp->es_server.ea_peerlen = len;
2318 eap_figure_next_state(esp, 0);
2323 switch(esp->es_server.ea_state) {
2327 ets = (struct eaptls_session *) esp->es_server.ea_session;
2329 eap_figure_next_state(esp,
2330 eaptls_receive(esp->es_server.ea_session, inp, len));
2332 if(ets->alert_recv) {
2333 eap_send_failure(esp);
2340 dbglog("EAP-TLS ACK with extra data");
2342 eap_figure_next_state(esp, 0);
2345 case eapTlsRecvClient:
2346 /* Receive authentication response from client */
2348 GETCHAR(flags, inp);
2350 if(len == 1 && !flags) { /* Ack = ok */
2352 eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
2354 eap_send_success(esp);
2356 else { /* failure */
2357 warn("Server authentication failed");
2358 eap_send_failure(esp);
2362 warn("Bogus EAP-TLS packet received from client");
2364 eaptls_free_session(esp->es_server.ea_session);
2368 case eapTlsRecvAlertAck:
2369 eap_send_failure(esp);
2373 eap_figure_next_state(esp, 1);
2377 #endif /* USE_EAPTLS */
2379 case EAPT_NOTIFICATION:
2380 dbglog("EAP unexpected Notification; response discarded");
2385 info("EAP: Nak Response with no suggested protocol");
2386 eap_figure_next_state(esp, 1);
2390 GETCHAR(vallen, inp);
2393 if (!explicit_remote && esp->es_server.ea_state == eapIdentify){
2394 /* Peer cannot Nak Identify Request */
2395 eap_figure_next_state(esp, 1);
2401 /* Run through SRP validator selection again. */
2402 esp->es_server.ea_state = eapIdentify;
2403 eap_figure_next_state(esp, 0);
2407 esp->es_server.ea_state = eapMD5Chall;
2411 /* Send EAP-TLS start packet */
2413 esp->es_server.ea_state = eapTlsStart;
2415 #endif /* USE_EAPTLS */
2419 info("EAP: peer proposes MSCHAPv2");
2420 /* If MSCHAPv2 digest was not found, NAK the packet */
2421 if (!esp->es_server.digest) {
2422 error("EAP MSCHAPv2 not supported");
2423 eap_send_nak(esp, id, EAPT_SRP);
2426 esp->es_server.ea_state = eapMSCHAPv2Chall;
2431 dbglog("EAP: peer requesting unknown Type %d", vallen);
2432 switch (esp->es_server.ea_state) {
2436 esp->es_server.ea_state = eapMD5Chall;
2440 esp->es_server.ea_state = eapIdentify;
2441 eap_figure_next_state(esp, 0);
2451 if (esp->es_server.ea_state != eapMD5Chall) {
2452 error("EAP: unexpected MD5-Response");
2453 eap_figure_next_state(esp, 1);
2457 error("EAP: received MD5-Response with no data");
2458 eap_figure_next_state(esp, 1);
2461 GETCHAR(vallen, inp);
2463 if (vallen != 16 || vallen > len) {
2464 error("EAP: MD5-Response with bad length %d", vallen);
2465 eap_figure_next_state(esp, 1);
2469 /* Not so likely to happen. */
2470 if (len - vallen >= sizeof (rhostname)) {
2471 dbglog("EAP: trimming really long peer name down");
2472 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2473 rhostname[sizeof (rhostname) - 1] = '\0';
2475 BCOPY(inp + vallen, rhostname, len - vallen);
2476 rhostname[len - vallen] = '\0';
2479 /* In case the remote doesn't give us his name. */
2480 if (explicit_remote ||
2481 (remote_name[0] != '\0' && vallen == len))
2482 strlcpy(rhostname, remote_name, sizeof (rhostname));
2485 * Get the secret for authenticating the specified
2488 if (!get_secret(esp->es_unit, rhostname,
2489 esp->es_server.ea_name, secret, &secret_len, 1)) {
2490 dbglog("EAP: no MD5 secret for auth of %q", rhostname);
2491 eap_send_failure(esp);
2494 MD5_Init(&mdContext);
2495 MD5_Update(&mdContext, &esp->es_server.ea_id, 1);
2496 MD5_Update(&mdContext, (u_char *)secret, secret_len);
2497 BZERO(secret, sizeof (secret));
2498 MD5_Update(&mdContext, esp->es_challenge, esp->es_challen);
2499 MD5_Final(hash, &mdContext);
2500 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
2501 eap_send_failure(esp);
2504 esp->es_server.ea_type = EAPT_MD5CHAP;
2505 eap_send_success(esp);
2506 eap_figure_next_state(esp, 0);
2507 if (esp->es_rechallenge != 0)
2508 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2514 error("EAP: received MSCHAPv2 with no data");
2515 eap_figure_next_state(esp, 1);
2518 GETCHAR(opcode, inp);
2523 if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
2524 error("EAP: unexpected MSCHAPv2-Response");
2525 eap_figure_next_state(esp, 1);
2528 /* skip MS ID + len */
2530 GETCHAR(vallen, inp);
2533 if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
2534 error("EAP: Invalid MSCHAPv2-Response "
2535 "length %d", vallen);
2536 eap_figure_next_state(esp, 1);
2540 /* Not so likely to happen. */
2541 if (len - vallen >= sizeof (rhostname)) {
2542 dbglog("EAP: trimming really long peer name down");
2543 BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
2544 rhostname[sizeof (rhostname) - 1] = '\0';
2546 BCOPY(inp + vallen, rhostname, len - vallen);
2547 rhostname[len - vallen] = '\0';
2550 /* In case the remote doesn't give us his name. */
2551 if (explicit_remote ||
2552 (remote_name[0] != '\0' && vallen == len))
2553 strlcpy(rhostname, remote_name, sizeof (rhostname));
2555 /* strip the MS domain name */
2556 if (chapms_strip_domain && strrchr(rhostname, '\\')) {
2557 char tmp[MAXNAMELEN+1];
2559 strcpy(tmp, strrchr(rhostname, '\\') + 1);
2560 strcpy(rhostname, tmp);
2563 if (chap_verify_hook)
2564 chap_verifier = chap_verify_hook;
2566 chap_verifier = eap_chap_verify_response;
2568 esp->es_server.ea_id += 1;
2569 if ((*chap_verifier)(rhostname,
2570 esp->es_server.ea_name,
2572 esp->es_server.digest,
2576 sizeof(response_message)))
2578 info("EAP: MSCHAPv2 success for peer %q",
2580 esp->es_server.ea_type = EAPT_MSCHAPV2;
2581 eap_chapms2_send_request(esp,
2582 esp->es_server.ea_id,
2584 esp->es_server.ea_id,
2586 strlen(response_message));
2587 eap_figure_next_state(esp, 0);
2588 if (esp->es_rechallenge != 0)
2589 TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
2592 warn("EAP: MSCHAPv2 failure for peer %q",
2594 eap_chapms2_send_request(esp,
2595 esp->es_server.ea_id,
2597 esp->es_server.ea_id,
2599 strlen(response_message));
2603 info("EAP: MSCHAPv2 success confirmed");
2606 info("EAP: MSCHAPv2 failure confirmed");
2609 error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
2610 eap_send_nak(esp, id, EAPT_SRP);
2619 error("EAP: empty SRP Response");
2620 eap_figure_next_state(esp, 1);
2623 GETCHAR(typenum, inp);
2627 if (esp->es_server.ea_state != eapSRP1) {
2628 error("EAP: unexpected SRP Subtype 1 Response");
2629 eap_figure_next_state(esp, 1);
2634 ts = (struct t_server *)esp->es_server.ea_session;
2636 esp->es_server.ea_skey = t_servergetkey(ts, &A);
2637 if (esp->es_server.ea_skey == NULL) {
2638 /* Client's A value is bogus; terminate now */
2639 error("EAP: bogus A value from client");
2640 eap_send_failure(esp);
2642 eap_figure_next_state(esp, 0);
2646 case EAPSRP_CVALIDATOR:
2647 if (esp->es_server.ea_state != eapSRP2) {
2648 error("EAP: unexpected SRP Subtype 2 Response");
2649 eap_figure_next_state(esp, 1);
2652 if (len < sizeof (u_int32_t) + SHA_DIGESTSIZE) {
2653 error("EAP: M1 length %d < %d", len,
2654 sizeof (u_int32_t) + SHA_DIGESTSIZE);
2655 eap_figure_next_state(esp, 1);
2658 GETLONG(esp->es_server.ea_keyflags, inp);
2659 ts = (struct t_server *)esp->es_server.ea_session;
2661 if (t_serververify(ts, inp)) {
2662 info("EAP: unable to validate client identity");
2663 eap_send_failure(esp);
2666 eap_figure_next_state(esp, 0);
2670 if (esp->es_server.ea_state != eapSRP3) {
2671 error("EAP: unexpected SRP Subtype 3 Response");
2672 eap_send_failure(esp);
2675 esp->es_server.ea_type = EAPT_SRP;
2676 eap_send_success(esp);
2677 eap_figure_next_state(esp, 0);
2678 if (esp->es_rechallenge != 0)
2679 TIMEOUT(eap_rechallenge, esp,
2680 esp->es_rechallenge);
2681 if (esp->es_lwrechallenge != 0)
2682 TIMEOUT(srp_lwrechallenge, esp,
2683 esp->es_lwrechallenge);
2686 case EAPSRP_LWRECHALLENGE:
2687 if (esp->es_server.ea_state != eapSRP4) {
2688 info("EAP: unexpected SRP Subtype 4 Response");
2691 if (len != SHA_DIGESTSIZE) {
2692 error("EAP: bad Lightweight rechallenge "
2698 SHA1Update(&ctxt, &vallen, 1);
2699 SHA1Update(&ctxt, esp->es_server.ea_skey,
2701 SHA1Update(&ctxt, esp->es_challenge, esp->es_challen);
2702 SHA1Update(&ctxt, esp->es_server.ea_peer,
2703 esp->es_server.ea_peerlen);
2704 SHA1Final(dig, &ctxt);
2705 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2706 error("EAP: failed Lightweight rechallenge");
2707 eap_send_failure(esp);
2710 esp->es_server.ea_state = eapOpen;
2711 if (esp->es_lwrechallenge != 0)
2712 TIMEOUT(srp_lwrechallenge, esp,
2713 esp->es_lwrechallenge);
2717 #endif /* USE_SRP */
2720 /* This can't happen. */
2721 error("EAP: unknown Response type %d; ignored", typenum);
2725 if (esp->es_server.ea_timeout > 0) {
2726 UNTIMEOUT(eap_server_timeout, (void *)esp);
2729 if (esp->es_server.ea_state != eapBadAuth &&
2730 esp->es_server.ea_state != eapOpen) {
2731 esp->es_server.ea_id++;
2732 eap_send_request(esp);
2737 * eap_success - Receive EAP Success message (client mode).
2740 eap_success(eap_state *esp, u_char *inp, int id, int len)
2742 if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2744 && esp->es_client.ea_state != eapTlsRecvSuccess
2745 #endif /* USE_EAPTLS */
2747 dbglog("EAP unexpected success message in state %s (%d)",
2748 eap_state_name(esp->es_client.ea_state),
2749 esp->es_client.ea_state);
2754 if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2755 eapTlsRecvSuccess) {
2756 dbglog("EAP-TLS unexpected success message in state %s (%d)",
2757 eap_state_name(esp->es_client.ea_state),
2758 esp->es_client.ea_state);
2761 #endif /* USE_EAPTLS */
2763 if (esp->es_client.ea_timeout > 0) {
2764 UNTIMEOUT(eap_client_timeout, (void *)esp);
2768 /* This is odd. The spec doesn't allow for this. */
2772 esp->es_client.ea_state = eapOpen;
2773 auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
2777 * eap_failure - Receive EAP Failure message (client mode).
2780 eap_failure(eap_state *esp, u_char *inp, int id, int len)
2783 * Ignore failure messages if we're not open
2785 if (esp->es_client.ea_state <= eapClosed)
2788 if (!eap_client_active(esp)) {
2789 dbglog("EAP unexpected failure message in state %s (%d)",
2790 eap_state_name(esp->es_client.ea_state),
2791 esp->es_client.ea_state);
2794 if (esp->es_client.ea_timeout > 0) {
2795 UNTIMEOUT(eap_client_timeout, (void *)esp);
2799 /* This is odd. The spec doesn't allow for this. */
2803 esp->es_client.ea_state = eapBadAuth;
2805 error("EAP: peer reports authentication failure");
2806 auth_withpeer_fail(esp->es_unit, PPP_EAP);
2810 * eap_input - Handle received EAP message.
2813 eap_input(int unit, u_char *inp, int inlen)
2815 eap_state *esp = &eap_states[unit];
2820 * Parse header (code, id and length). If packet too short,
2823 if (inlen < EAP_HEADERLEN) {
2824 error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2830 if (len < EAP_HEADERLEN || len > inlen) {
2831 error("EAP: packet has illegal length field %d (%d..%d)", len,
2832 EAP_HEADERLEN, inlen);
2835 len -= EAP_HEADERLEN;
2837 /* Dispatch based on message code */
2840 eap_request(esp, inp, id, len);
2844 eap_response(esp, inp, id, len);
2848 eap_success(esp, inp, id, len);
2852 eap_failure(esp, inp, id, len);
2855 default: /* XXX Need code reject */
2856 /* Note: it's not legal to send EAP Nak here. */
2857 warn("EAP: unknown code %d received", code);
2863 * eap_printpkt - print the contents of an EAP packet.
2865 static char *eap_codenames[] = {
2866 "Request", "Response", "Success", "Failure"
2869 static char *eap_typenames[] = {
2870 "Identity", "Notification", "Nak", "MD5-Challenge",
2871 "OTP", "Generic-Token", NULL, NULL,
2872 "RSA", "DSS", "KEA", "KEA-Validate",
2873 "TLS", "Defender", "Windows 2000", "Arcot",
2874 "Cisco", "Nokia", "SRP", NULL,
2875 "TTLS", "RAS", "AKA", "3COM", "PEAP",
2880 eap_printpkt(u_char *inp, int inlen,
2881 void (*printer) (void *, char *, ...), void *arg)
2883 int code, id, len, rtype, vallen;
2888 #endif /* USE_EAPTLS */
2893 if (inlen < EAP_HEADERLEN)
2899 if (len < EAP_HEADERLEN || len > inlen)
2902 if (code >= 1 && code <= sizeof(eap_codenames) / sizeof(char *))
2903 printer(arg, " %s", eap_codenames[code-1]);
2905 printer(arg, " code=0x%x", code);
2906 printer(arg, " id=0x%x", id);
2907 len -= EAP_HEADERLEN;
2911 printer(arg, " <missing type>");
2914 GETCHAR(rtype, inp);
2917 rtype <= sizeof (eap_typenames) / sizeof (char *))
2918 printer(arg, " %s", eap_typenames[rtype-1]);
2920 printer(arg, " type=0x%x", rtype);
2923 case EAPT_NOTIFICATION:
2925 printer(arg, " <Message ");
2926 print_string((char *)inp, len, printer, arg);
2931 printer(arg, " <No message>");
2938 GETCHAR(vallen, inp);
2942 printer(arg, " <Value%.*B>", vallen, inp);
2943 INCPTR(vallen, inp);
2946 printer(arg, " <Name ");
2947 print_string((char *)inp, len, printer, arg);
2952 printer(arg, " <No name>");
2960 GETCHAR(opcode, inp);
2963 case CHAP_CHALLENGE:
2966 GETCHAR(vallen, inp);
2971 printer(arg, " Challenge <");
2972 for (; vallen > 0; --vallen) {
2975 printer(arg, "%.2x", val);
2979 printer(arg, ", <Name ");
2980 print_string((char *)inp, len, printer, arg);
2985 printer(arg, ", <No name>");
2991 printer(arg, " Success <Message ");
2992 print_string((char *)inp, len, printer, arg);
2998 printer(arg, " Failure <Message ");
2999 print_string((char *)inp, len, printer, arg);
3005 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3015 GETCHAR(flags, inp);
3018 if(flags == 0 && len == 0){
3019 printer(arg, " Ack");
3023 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3024 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3025 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3027 #endif /* USE_EAPTLS */
3033 GETCHAR(vallen, inp);
3035 printer(arg, "-%d", vallen);
3037 case EAPSRP_CHALLENGE:
3038 GETCHAR(vallen, inp);
3043 printer(arg, " <Name ");
3044 print_string((char *)inp, vallen, printer,
3048 printer(arg, " <No name>");
3050 INCPTR(vallen, inp);
3052 GETCHAR(vallen, inp);
3056 printer(arg, " <s%.*B>", vallen, inp);
3057 INCPTR(vallen, inp);
3059 GETCHAR(vallen, inp);
3064 printer(arg, " <Default g=2>");
3066 printer(arg, " <g%.*B>", vallen, inp);
3068 INCPTR(vallen, inp);
3071 printer(arg, " <Default N>");
3073 printer(arg, " <N%.*B>", len, inp);
3080 printer(arg, " <B%.*B>", len, inp);
3085 case EAPSRP_SVALIDATOR:
3086 if (len < sizeof (u_int32_t))
3089 len -= sizeof (u_int32_t);
3090 if (uval & SRPVAL_EBIT) {
3092 uval &= ~SRPVAL_EBIT;
3095 printer(arg, " f<%X>", uval);
3097 if ((vallen = len) > SHA_DIGESTSIZE)
3098 vallen = SHA_DIGESTSIZE;
3099 printer(arg, " <M2%.*B%s>", len, inp,
3100 len < SHA_DIGESTSIZE ? "?" : "");
3101 INCPTR(vallen, inp);
3104 printer(arg, " <PN%.*B>", len, inp);
3110 case EAPSRP_LWRECHALLENGE:
3111 printer(arg, " <Challenge%.*B>", len, inp);
3117 #endif /* USE_SRP */
3124 GETCHAR(rtype, inp);
3127 rtype <= sizeof (eap_typenames) / sizeof (char *))
3128 printer(arg, " %s", eap_typenames[rtype-1]);
3130 printer(arg, " type=0x%x", rtype);
3134 printer(arg, " <Name ");
3135 print_string((char *)inp, len, printer, arg);
3146 GETCHAR(flags, inp);
3149 if(flags == 0 && len == 0){
3150 printer(arg, " Ack");
3154 printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
3155 printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
3156 printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
3159 #endif /* USE_EAPTLS */
3163 printer(arg, " <missing hint>");
3166 GETCHAR(rtype, inp);
3168 printer(arg, " <Suggested-type %02X", rtype);
3170 rtype <= sizeof (eap_typenames) / sizeof (char *))
3171 printer(arg, " (%s)", eap_typenames[rtype-1]);
3177 printer(arg, " <missing length>");
3180 GETCHAR(vallen, inp);
3184 printer(arg, " <Value%.*B>", vallen, inp);
3185 INCPTR(vallen, inp);
3188 printer(arg, " <Name ");
3189 print_string((char *)inp, len, printer, arg);
3194 printer(arg, " <No name>");
3202 GETCHAR(opcode, inp);
3208 GETCHAR(vallen, inp);
3213 printer(arg, " Response <");
3214 for (; vallen > 0; --vallen) {
3217 printer(arg, "%.2x", val);
3221 printer(arg, ", <Name ");
3222 print_string((char *)inp, len, printer, arg);
3227 printer(arg, ", <No name>");
3231 printer(arg, " Success");
3234 printer(arg, " Failure");
3237 printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
3247 GETCHAR(vallen, inp);
3249 printer(arg, "-%d", vallen);
3252 printer(arg, " <A%.*B>", len, inp);
3257 case EAPSRP_CVALIDATOR:
3258 if (len < sizeof (u_int32_t))
3261 len -= sizeof (u_int32_t);
3262 if (uval & SRPVAL_EBIT) {
3264 uval &= ~SRPVAL_EBIT;
3267 printer(arg, " f<%X>", uval);
3269 printer(arg, " <M1%.*B%s>", len, inp,
3270 len == SHA_DIGESTSIZE ? "" : "?");
3278 case EAPSRP_LWRECHALLENGE:
3279 printer(arg, " <Response%.*B%s>", len, inp,
3280 len == SHA_DIGESTSIZE ? "" : "?");
3281 if ((vallen = len) > SHA_DIGESTSIZE)
3282 vallen = SHA_DIGESTSIZE;
3283 INCPTR(vallen, inp);
3288 #endif /* USE_SRP */
3292 case EAP_SUCCESS: /* No payload expected for these! */
3297 printer(arg, " <truncated>");
3302 printer(arg, "%8B...", inp);
3304 printer(arg, "%.*B", len, inp);
3307 return (inp - pstart);