47 #if PPP_SUPPORT && EAP_SUPPORT 51 #if LWIP_INCLUDED_POLARSSL_MD5 67 #ifndef SHA_DIGESTSIZE 68 #define SHA_DIGESTSIZE 20 72 static char *pn_secret =
NULL;
79 static option_t eap_option_list[] = {
80 {
"eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
81 "Set retransmit timeout for EAP Requests (server)" },
82 {
"eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
83 "Set max number of EAP Requests sent (server)" },
84 {
"eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
85 "Set time limit for peer EAP authentication" },
86 {
"eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
87 "Set max number of EAP Requests allows (client)" },
88 {
"eap-interval", o_int, &eap_states[0].es_rechallenge,
89 "Set interval for EAP rechallenge" },
91 {
"srp-interval", o_int, &eap_states[0].es_lwrechallenge,
92 "Set interval for SRP lightweight rechallenge" },
93 {
"srp-pn-secret", o_string, &pn_secret,
94 "Long term pseudonym generation secret" },
95 {
"srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
96 "Use pseudonym if offered one by server", 1 },
105 static void eap_init(ppp_pcb *pcb);
106 static void eap_input(ppp_pcb *pcb, u_char *inp,
int inlen);
107 static void eap_protrej(ppp_pcb *pcb);
108 static void eap_lowerup(ppp_pcb *pcb);
109 static void eap_lowerdown(ppp_pcb *pcb);
111 static int eap_printpkt(
const u_char *inp,
int inlen,
112 void (*)(
void *arg,
const char *fmt, ...),
void *arg);
115 const struct protent eap_protent = {
148 static const u_char wkmodulus[] = {
149 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
150 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
151 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
152 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
153 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
154 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
155 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
156 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
157 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
158 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
159 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
160 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
161 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
162 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
163 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
164 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
165 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
166 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
167 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
168 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
169 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
170 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
171 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
172 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
173 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
174 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
175 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
176 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
177 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
178 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
179 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
180 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
186 static void eap_server_timeout(
void *arg);
192 static const char * eap_state_name(
enum eap_state_code esc)
194 static const char *state_names[] = { EAP_STATES };
196 return (state_names[(
int)esc]);
203 static void eap_init(ppp_pcb *pcb) {
205 BZERO(&pcb->eap,
sizeof(eap_state));
207 pcb->eap.es_server.ea_id = magic();
215 static void eap_client_timeout(
void *arg) {
216 ppp_pcb *pcb = (ppp_pcb*)arg;
218 if (!eap_client_active(pcb))
221 ppp_error(
"EAP: timeout waiting for Request from peer");
222 auth_withpeer_fail(pcb, PPP_EAP);
223 pcb->eap.es_client.ea_state = eapBadAuth;
232 void eap_authwithpeer(ppp_pcb *pcb,
const char *localname) {
234 if(NULL == localname)
238 pcb->eap.es_client.ea_name = localname;
239 pcb->eap.es_client.ea_namelen = strlen(localname);
241 pcb->eap.es_client.ea_state = eapListen;
247 if (pcb->settings.eap_req_time > 0)
248 TIMEOUT(eap_client_timeout, pcb,
249 pcb->settings.eap_req_time);
257 static void eap_send_failure(ppp_pcb *pcb) {
271 MAKEHEADER(outp, PPP_EAP);
273 PUTCHAR(EAP_FAILURE, outp);
274 pcb->eap.es_server.ea_id++;
275 PUTCHAR(pcb->eap.es_server.ea_id, outp);
276 PUTSHORT(EAP_HEADERLEN, outp);
280 pcb->eap.es_server.ea_state = eapBadAuth;
281 auth_peer_fail(pcb, PPP_EAP);
288 static void eap_send_success(ppp_pcb *pcb) {
302 MAKEHEADER(outp, PPP_EAP);
304 PUTCHAR(EAP_SUCCESS, outp);
305 pcb->eap.es_server.ea_id++;
306 PUTCHAR(pcb->eap.es_server.ea_id, outp);
307 PUTSHORT(EAP_HEADERLEN, outp);
311 auth_peer_success(pcb, PPP_EAP, 0,
312 pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen);
322 pncrypt_setkey(
int timeoffs)
327 u_char dig[SHA_DIGESTSIZE];
330 if (pn_secret == NULL)
332 reftime = time(NULL) + timeoffs;
333 tp = localtime(&reftime);
335 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
336 strftime(tbuf,
sizeof (tbuf),
"%Y%m%d", tp);
337 SHA1Update(&ctxt, tbuf, strlen(tbuf));
338 SHA1Final(dig, &ctxt);
340 return (DesSetkey(dig));
343 static char base64[] =
344 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
352 b64enc(bs, inp, inlen, outp)
361 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
364 if (bs->bs_offs >= 24) {
365 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
366 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
367 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
368 *outp++ = base64[bs->bs_bits & 0x3F];
384 if (bs->bs_offs == 8) {
385 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
386 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
388 }
else if (bs->bs_offs == 16) {
389 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
390 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
391 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
400 b64dec(bs, inp, inlen, 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);
432 static void eap_figure_next_state(ppp_pcb *pcb,
int status) {
434 unsigned char secbuf[MAXSECRETLEN], clear[8], *sp, *dp;
436 struct t_confent *tce, mytce;
439 int id, i, plen, toffs;
444 pcb->settings.eap_timeout_time = pcb->eap.es_savedtime;
445 switch (pcb->eap.es_server.ea_state) {
452 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
455 pcb->eap.es_server.ea_session =
NULL;
456 pcb->eap.es_server.ea_skey =
NULL;
460 pcb->eap.es_server.ea_state = eapBadAuth;
465 if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN &&
466 strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID,
467 SRP_PSEUDO_LEN) == 0 &&
468 (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
470 BZERO(&bs,
sizeof (bs));
472 pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN,
473 pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN,
476 for (i = 0; i < 5; i++) {
477 pncrypt_setkey(toffs);
480 if (!DesDecrypt(secbuf, clear)) {
481 ppp_dbglog(
"no DES here; cannot decode " 485 id = *(
unsigned char *)clear;
486 if (
id + 1 <= plen &&
id + 9 > plen)
489 if (plen % 8 == 0 && i < 5) {
495 if ((i = plen = *(
unsigned char *)clear) > 7)
497 pcb->eap.es_server.ea_peerlen = plen;
498 dp = (
unsigned char *)pcb->eap.es_server.ea_peer;
505 (void) DesDecrypt(sp, dp);
510 pcb->eap.es_server.ea_peer[
511 pcb->eap.es_server.ea_peerlen] =
'\0';
512 ppp_dbglog(
"decoded pseudonym to \"%.*q\"",
513 pcb->eap.es_server.ea_peerlen,
514 pcb->eap.es_server.ea_peer);
516 ppp_dbglog(
"failed to decode real name");
522 if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer,
523 pcb->eap.es_server.ea_name, (
char *)secbuf, 1) != 0) {
525 pcb->eap.es_server.ea_state = eapMD5Chall;
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) {
543 if (pcb->settings.eap_timeout_time > 0 &&
544 pcb->settings.eap_timeout_time < 30)
545 pcb->settings.eap_timeout_time = 30;
549 if ((cp2 = strchr(cp,
':')) == NULL)
552 tpw.pebuf.name = pcb->eap.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 pcb->eap.es_server.ea_session = (
void *)ts;
562 pcb->eap.es_server.ea_state = eapSRP1;
563 vals[0] = pcb->eap.es_server.ea_id + 1;
565 t_serveraddexdata(ts, vals, 2);
571 pcb->eap.es_server.ea_state = eapMD5Chall;
576 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
577 if (ts != NULL && status != 0) {
579 pcb->eap.es_server.ea_session =
NULL;
580 pcb->eap.es_server.ea_skey =
NULL;
584 pcb->eap.es_server.ea_state = eapMD5Chall;
585 }
else if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
586 pcb->eap.es_server.ea_state = eapBadAuth;
588 pcb->eap.es_server.ea_state = eapSRP2;
594 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
595 if (ts != NULL && status != 0) {
597 pcb->eap.es_server.ea_session =
NULL;
598 pcb->eap.es_server.ea_skey =
NULL;
601 if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
602 pcb->eap.es_server.ea_state = eapBadAuth;
604 pcb->eap.es_server.ea_state = eapSRP3;
611 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
612 if (ts != NULL && status != 0) {
614 pcb->eap.es_server.ea_session =
NULL;
615 pcb->eap.es_server.ea_skey =
NULL;
618 if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
619 pcb->eap.es_server.ea_state = eapBadAuth;
621 pcb->eap.es_server.ea_state = eapOpen;
627 pcb->eap.es_server.ea_state = eapBadAuth;
629 pcb->eap.es_server.ea_state = eapOpen;
634 pcb->eap.es_server.ea_state = eapBadAuth;
637 if (pcb->eap.es_server.ea_state == eapBadAuth)
638 eap_send_failure(pcb);
645 static void eap_send_request(ppp_pcb *pcb) {
654 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
661 if (pcb->eap.es_server.ea_state < eapIdentify &&
662 pcb->eap.es_server.ea_state != eapInitial) {
663 pcb->eap.es_server.ea_state = eapIdentify;
665 if (pcb->settings.explicit_remote && pcb->remote_name) {
671 int len = (int)strlen(pcb->remote_name);
672 if (len > MAXNAMELEN) {
675 MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name, len);
676 pcb->eap.es_server.ea_peer[len] =
'\0';
677 pcb->eap.es_server.ea_peerlen = len;
678 eap_figure_next_state(pcb, 0);
683 if (pcb->settings.eap_max_transmits > 0 &&
684 pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) {
685 if (pcb->eap.es_server.ea_responses > 0)
686 ppp_error(
"EAP: too many Requests sent");
688 ppp_error(
"EAP: no response to Requests");
689 eap_send_failure(pcb);
703 MAKEHEADER(outp, PPP_EAP);
705 PUTCHAR(EAP_REQUEST, outp);
706 PUTCHAR(pcb->eap.es_server.ea_id, outp);
710 switch (pcb->eap.es_server.ea_state) {
712 PUTCHAR(EAPT_IDENTITY, outp);
720 PUTCHAR(EAPT_MD5CHAP, outp);
725 pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
726 magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
727 PUTCHAR(pcb->eap.es_challen, outp);
728 magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
729 MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
730 INCPTR(pcb->eap.es_challen, outp);
731 MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
732 INCPTR(pcb->eap.es_server.ea_namelen, outp);
737 PUTCHAR(EAPT_SRP, outp);
738 PUTCHAR(EAPSRP_CHALLENGE, outp);
740 PUTCHAR(pcb->eap.es_server.ea_namelen, outp);
741 MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
742 INCPTR(pcb->eap.es_server.ea_namelen, outp);
744 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
746 PUTCHAR(ts->s.len, outp);
747 MEMCPY(outp, ts->s.data, ts->s.len);
748 INCPTR(ts->s.len, outp);
750 if (ts->g.len == 1 && ts->g.data[0] == 2) {
753 PUTCHAR(ts->g.len, outp);
754 MEMCPY(outp, ts->g.data, ts->g.len);
755 INCPTR(ts->g.len, outp);
758 if (ts->n.len != sizeof (wkmodulus) ||
759 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
760 MEMCPY(outp, ts->n.data, ts->n.len);
761 INCPTR(ts->n.len, outp);
766 PUTCHAR(EAPT_SRP, outp);
767 PUTCHAR(EAPSRP_SKEY, outp);
769 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
771 MEMCPY(outp, ts->B.data, ts->B.len);
772 INCPTR(ts->B.len, outp);
776 PUTCHAR(EAPT_SRP, outp);
777 PUTCHAR(EAPSRP_SVALIDATOR, outp);
778 PUTLONG(SRPVAL_EBIT, outp);
779 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
781 MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE);
782 INCPTR(SHA_DIGESTSIZE, outp);
784 if (pncrypt_setkey(0)) {
787 cp = (
unsigned char *)pcb->eap.es_server.ea_peer;
788 if ((j = i = pcb->eap.es_server.ea_peerlen) > 7)
795 if (!DesEncrypt(clear, cipher)) {
796 ppp_dbglog(
"no DES here; not generating pseudonym");
799 BZERO(&b64,
sizeof (b64));
801 outp += b64enc(&b64, cipher, 8, outp);
804 (void) DesEncrypt(cp, cipher);
805 outp += b64enc(&b64, cipher, 8, outp);
812 magic_random_bytes(cp, 8-i);
814 (void) DesEncrypt(clear, cipher);
815 outp += b64enc(&b64, cipher, 8, outp);
817 outp += b64flush(&b64, outp);
824 magic_random_bytes(outp, SHA_DIGESTSIZE-i);
825 INCPTR(SHA_DIGESTSIZE-i, outp);
830 SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
831 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
833 SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
834 pcb->eap.es_server.ea_peerlen);
835 while (optr < outp) {
836 SHA1Final(dig, &ctxt);
838 while (cp < dig + SHA_DIGESTSIZE)
841 SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
842 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
844 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
851 PUTCHAR(EAPT_SRP, outp);
852 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
853 pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
854 magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
855 magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
856 MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
857 INCPTR(pcb->eap.es_challen, outp);
865 outlen = (outp - (
unsigned char*)p->
payload) - PPP_HDRLEN;
866 PUTSHORT(outlen, lenloc);
871 pcb->eap.es_server.ea_requests++;
873 if (pcb->settings.eap_timeout_time > 0)
874 TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time);
883 void eap_authpeer(ppp_pcb *pcb,
const char *localname) {
886 pcb->eap.es_server.ea_name = localname;
887 pcb->eap.es_server.ea_namelen = strlen(localname);
889 pcb->eap.es_savedtime = pcb->settings.eap_timeout_time;
892 if (pcb->eap.es_server.ea_state == eapInitial ||
893 pcb->eap.es_server.ea_state == eapPending) {
894 pcb->eap.es_server.ea_state = eapPending;
898 pcb->eap.es_server.ea_state = eapPending;
901 eap_send_request(pcb);
908 static void eap_server_timeout(
void *arg) {
909 ppp_pcb *pcb = (ppp_pcb*)arg;
911 if (!eap_server_active(pcb))
915 eap_send_request(pcb);
923 static void eap_rechallenge(
void *arg) {
924 ppp_pcb *pcb = (ppp_pcb*)arg;
926 if (pcb->eap.es_server.ea_state != eapOpen &&
927 pcb->eap.es_server.ea_state != eapSRP4)
930 pcb->eap.es_server.ea_requests = 0;
931 pcb->eap.es_server.ea_state = eapIdentify;
932 eap_figure_next_state(pcb, 0);
933 pcb->eap.es_server.ea_id++;
934 eap_send_request(pcb);
937 static void srp_lwrechallenge(
void *arg) {
938 ppp_pcb *pcb = (ppp_pcb*)arg;
940 if (pcb->eap.es_server.ea_state != eapOpen ||
941 pcb->eap.es_server.ea_type != EAPT_SRP)
944 pcb->eap.es_server.ea_requests = 0;
945 pcb->eap.es_server.ea_state = eapSRP4;
946 pcb->eap.es_server.ea_id++;
947 eap_send_request(pcb);
959 static void eap_lowerup(ppp_pcb *pcb) {
960 pcb->eap.es_client.ea_state = eapClosed;
962 pcb->eap.es_server.ea_state = eapClosed;
971 static void eap_lowerdown(ppp_pcb *pcb) {
973 if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) {
974 UNTIMEOUT(eap_client_timeout, pcb);
977 if (eap_server_active(pcb)) {
978 if (pcb->settings.eap_timeout_time > 0) {
979 UNTIMEOUT(eap_server_timeout, pcb);
982 if ((pcb->eap.es_server.ea_state == eapOpen ||
983 pcb->eap.es_server.ea_state == eapSRP4) &&
984 pcb->eap.es_rechallenge > 0) {
985 UNTIMEOUT(eap_rechallenge, (
void *)pcb);
987 if (pcb->eap.es_server.ea_state == eapOpen &&
988 pcb->eap.es_lwrechallenge > 0) {
989 UNTIMEOUT(srp_lwrechallenge, (
void *)pcb);
993 pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial;
994 pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0;
1004 static void eap_protrej(ppp_pcb *pcb) {
1006 if (eap_client_active(pcb)) {
1007 ppp_error(
"EAP authentication failed due to Protocol-Reject");
1008 auth_withpeer_fail(pcb, PPP_EAP);
1011 if (eap_server_active(pcb)) {
1012 ppp_error(
"EAP authentication of peer failed on Protocol-Reject");
1013 auth_peer_fail(pcb, PPP_EAP);
1022 static void eap_send_response(ppp_pcb *pcb, u_char
id, u_char typenum,
const u_char *str,
int lenstr) {
1027 msglen = EAP_HEADERLEN +
sizeof (u_char) + lenstr;
1038 MAKEHEADER(outp, PPP_EAP);
1040 PUTCHAR(EAP_RESPONSE, outp);
1042 pcb->eap.es_client.ea_id = id;
1043 PUTSHORT(msglen, outp);
1044 PUTCHAR(typenum, outp);
1046 MEMCPY(outp, str, lenstr);
1055 static void eap_chap_response(ppp_pcb *pcb, u_char
id, u_char *hash,
const char *name,
int namelen) {
1060 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char) + MD5_SIGNATURE_SIZE +
1072 MAKEHEADER(outp, PPP_EAP);
1074 PUTCHAR(EAP_RESPONSE, outp);
1076 pcb->eap.es_client.ea_id = id;
1077 PUTSHORT(msglen, outp);
1078 PUTCHAR(EAPT_MD5CHAP, outp);
1079 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1080 MEMCPY(outp, hash, MD5_SIGNATURE_SIZE);
1081 INCPTR(MD5_SIGNATURE_SIZE, outp);
1083 MEMCPY(outp, name, namelen);
1094 eap_srp_response(esp,
id, subtypenum, str, lenstr)
1101 ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1106 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char) + lenstr;
1117 MAKEHEADER(outp, PPP_EAP);
1119 PUTCHAR(EAP_RESPONSE, outp);
1121 pcb->eap.es_client.ea_id = id;
1122 PUTSHORT(msglen, outp);
1123 PUTCHAR(EAPT_SRP, outp);
1124 PUTCHAR(subtypenum, outp);
1126 MEMCPY(outp, str, lenstr);
1136 eap_srpval_response(esp,
id,
flags, str)
1142 ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1147 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char) +
sizeof (
u32_t) +
1159 MAKEHEADER(outp, PPP_EAP);
1161 PUTCHAR(EAP_RESPONSE, outp);
1163 pcb->eap.es_client.ea_id = id;
1164 PUTSHORT(msglen, outp);
1165 PUTCHAR(EAPT_SRP, outp);
1166 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1167 PUTLONG(flags, outp);
1168 MEMCPY(outp, str, SHA_DIGESTSIZE);
1174 static void eap_send_nak(ppp_pcb *pcb, u_char
id, u_char
type) {
1179 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char);
1190 MAKEHEADER(outp, PPP_EAP);
1192 PUTCHAR(EAP_RESPONSE, outp);
1194 pcb->eap.es_client.ea_id = id;
1195 PUTSHORT(msglen, outp);
1196 PUTCHAR(EAPT_NAK, outp);
1197 PUTCHAR(type, outp);
1206 char *user, *path, *file;
1209 static bool pnlogged = 0;
1211 pw = getpwuid(getuid());
1212 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1216 file = _PATH_PSEUDONYM;
1217 pl = strlen(user) + strlen(file) + 2;
1221 (void) slprintf(path, pl,
"%s/%s", user, file);
1223 ppp_dbglog(
"pseudonym file: %s", path);
1230 open_pn_file(modebits)
1236 if ((path = name_of_pn_file()) == NULL)
1238 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1250 if ((path = name_of_pn_file()) != NULL) {
1251 (void) unlink(path);
1257 write_pseudonym(esp, inp, len,
id)
1263 u_char *datp, *digp;
1265 u_char dig[SHA_DIGESTSIZE];
1266 int dsize, fd, olen = len;
1274 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1275 dsize = SHA_DIGESTSIZE;
1279 SHA1Update(&ctxt, &val, 1);
1280 SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN);
1282 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1284 SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1285 pcb->eap.es_client.ea_namelen);
1287 SHA1Final(dig, &ctxt);
1288 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1293 if (olen <= 0 || *inp + 1 > olen) {
1294 ppp_dbglog(
"EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1299 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1301 ppp_dbglog(
"EAP: error saving pseudonym: %m");
1304 len = write(fd, inp + 1, *inp);
1305 if (close(fd) != -1 && len == *inp) {
1306 ppp_dbglog(
"EAP: saved pseudonym");
1307 pcb->eap.es_usedpseudo = 0;
1309 ppp_dbglog(
"EAP: failed to save pseudonym");
1318 static void eap_request(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
1322 char secret[MAXSECRETLEN];
1323 char rhostname[MAXNAMELEN];
1324 md5_context mdContext;
1325 u_char hash[MD5_SIGNATURE_SIZE];
1327 struct t_client *tc;
1328 struct t_num sval, gval, Nval, *Ap, Bval;
1331 u_char dig[SHA_DIGESTSIZE];
1341 pcb->eap.es_client.ea_requests++;
1342 if (pcb->settings.eap_allow_req != 0 &&
1343 pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) {
1344 ppp_info(
"EAP: received too many Request messages");
1345 if (pcb->settings.eap_req_time > 0) {
1346 UNTIMEOUT(eap_client_timeout, pcb);
1348 auth_withpeer_fail(pcb, PPP_EAP);
1353 ppp_error(
"EAP: empty Request message discarded");
1357 GETCHAR(typenum, inp);
1363 ppp_info(
"EAP: Identity prompt \"%.*q\"", len, inp);
1365 if (pcb->eap.es_usepseudo &&
1366 (pcb->eap.es_usedpseudo == 0 ||
1367 (pcb->eap.es_usedpseudo == 1 &&
1368 id == pcb->eap.es_client.ea_id))) {
1369 pcb->eap.es_usedpseudo = 1;
1371 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1372 strcpy(rhostname, SRP_PSEUDO_ID);
1373 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1374 sizeof (rhostname) - SRP_PSEUDO_LEN);
1377 eap_send_response(pcb,
id, typenum,
1378 rhostname, len + SRP_PSEUDO_LEN);
1386 if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) {
1388 pcb->eap.es_usedpseudo = 2;
1391 eap_send_response(pcb,
id, typenum, (
const u_char*)pcb->eap.es_client.ea_name,
1392 pcb->eap.es_client.ea_namelen);
1395 case EAPT_NOTIFICATION:
1397 ppp_info(
"EAP: Notification \"%.*q\"", len, inp);
1398 eap_send_response(pcb,
id, typenum, NULL, 0);
1406 ppp_warn(
"EAP: unexpected Nak in Request; ignored");
1412 ppp_error(
"EAP: received MD5-Challenge with no data");
1416 GETCHAR(vallen, inp);
1418 if (vallen < 8 || vallen > len) {
1419 ppp_error(
"EAP: MD5-Challenge with bad length %d (8..%d)",
1422 eap_send_nak(pcb,
id, EAPT_SRP);
1427 if (vallen >= len +
sizeof (rhostname)) {
1428 ppp_dbglog(
"EAP: trimming really long peer name down");
1429 MEMCPY(rhostname, inp + vallen,
sizeof (rhostname) - 1);
1430 rhostname[
sizeof (rhostname) - 1] =
'\0';
1432 MEMCPY(rhostname, inp + vallen, len - vallen);
1433 rhostname[len - vallen] =
'\0';
1438 if (pcb->settings.explicit_remote ||
1439 (pcb->settings.remote_name[0] !=
'\0' && vallen == len))
1440 strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname));
1447 if (!get_secret(pcb, pcb->eap.es_client.ea_name,
1448 rhostname, secret, &secret_len, 0)) {
1449 ppp_dbglog(
"EAP: no MD5 secret for auth to %q", rhostname);
1450 eap_send_nak(pcb,
id, EAPT_SRP);
1453 md5_starts(&mdContext);
1455 md5_update(&mdContext, &typenum, 1);
1456 md5_update(&mdContext, (u_char *)secret, secret_len);
1457 BZERO(secret,
sizeof (secret));
1458 md5_update(&mdContext, inp, vallen);
1459 md5_finish(&mdContext, hash);
1460 eap_chap_response(pcb,
id, hash, pcb->eap.es_client.ea_name,
1461 pcb->eap.es_client.ea_namelen);
1467 ppp_error(
"EAP: received empty SRP Request");
1473 GETCHAR(vallen, inp);
1476 case EAPSRP_CHALLENGE:
1478 if (pcb->eap.es_client.ea_session != NULL) {
1479 tc = (
struct t_client *)pcb->eap.es_client.
1486 if (
id != pcb->eap.es_client.ea_id) {
1488 pcb->eap.es_client.ea_session =
NULL;
1493 pcb->eap.es_client.ea_skey =
NULL;
1497 GETCHAR(vallen, inp);
1499 if (vallen >= len) {
1500 ppp_error(
"EAP: badly-formed SRP Challenge" 1505 MEMCPY(rhostname, inp, vallen);
1506 rhostname[vallen] =
'\0';
1507 INCPTR(vallen, inp);
1514 if (explicit_remote ||
1515 (remote_name[0] !=
'\0' && vallen == 0)) {
1516 strlcpy(rhostname, remote_name,
1517 sizeof (rhostname));
1520 rhostnamelen = (int)strlen(rhostname);
1521 if (rhostnamelen > MAXNAMELEN) {
1522 rhostnamelen = MAXNAMELEN;
1524 MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen);
1525 pcb->eap.es_client.ea_peer[rhostnamelen] =
'\0';
1526 pcb->eap.es_client.ea_peerlen = rhostnamelen;
1528 GETCHAR(vallen, inp);
1530 if (vallen >= len) {
1531 ppp_error(
"EAP: badly-formed SRP Challenge" 1538 INCPTR(vallen, inp);
1541 GETCHAR(vallen, inp);
1544 ppp_error(
"EAP: badly-formed SRP Challenge" 1551 gval.data = (u_char *)
"\002";
1557 INCPTR(vallen, inp);
1565 Nval.data = (u_char *)wkmodulus;
1566 Nval.len =
sizeof (wkmodulus);
1571 tc = t_clientopen(pcb->eap.es_client.ea_name,
1572 &Nval, &gval, &sval);
1574 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1577 pcb->eap.es_client.ea_session = (
void *)tc;
1582 t_clientaddexdata(tc, vals, 2);
1584 Ap = t_clientgenexp(tc);
1585 eap_srp_response(esp,
id, EAPSRP_CKEY, Ap->data,
1590 tc = (
struct t_client *)pcb->eap.es_client.ea_session;
1592 ppp_warn(
"EAP: peer sent Subtype 2 without 1");
1593 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1596 if (pcb->eap.es_client.ea_skey != NULL) {
1601 if (
id != pcb->eap.es_client.ea_id) {
1602 ppp_warn(
"EAP: ID changed from %d to %d " 1603 "in SRP Subtype 2 rexmit",
1604 pcb->eap.es_client.ea_id,
id);
1607 if (get_srp_secret(pcb->eap.es_unit,
1608 pcb->eap.es_client.ea_name,
1609 pcb->eap.es_client.ea_peer, secret, 0) == 0) {
1615 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1620 t_clientpasswd(tc, secret);
1621 BZERO(secret,
sizeof (secret));
1622 pcb->eap.es_client.ea_skey =
1623 t_clientgetkey(tc, &Bval);
1624 if (pcb->eap.es_client.ea_skey == NULL) {
1626 ppp_error(
"EAP: SRP server is rogue");
1627 goto client_failure;
1630 eap_srpval_response(esp,
id, SRPVAL_EBIT,
1631 t_clientresponse(tc));
1634 case EAPSRP_SVALIDATOR:
1635 tc = (
struct t_client *)pcb->eap.es_client.ea_session;
1636 if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) {
1637 ppp_warn(
"EAP: peer sent Subtype 3 without 1/2");
1638 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1646 if (pcb->eap.es_client.ea_state == eapOpen) {
1647 if (
id != pcb->eap.es_client.ea_id) {
1648 ppp_warn(
"EAP: ID changed from %d to %d " 1649 "in SRP Subtype 3 rexmit",
1650 pcb->eap.es_client.ea_id,
id);
1653 len -=
sizeof (
u32_t) + SHA_DIGESTSIZE;
1654 if (len < 0 || t_clientverify(tc, inp +
1655 sizeof (
u32_t)) != 0) {
1656 ppp_error(
"EAP: SRP server verification " 1658 goto client_failure;
1660 GETLONG(pcb->eap.es_client.ea_keyflags, inp);
1662 if (len > 0 && pcb->eap.es_usepseudo) {
1663 INCPTR(SHA_DIGESTSIZE, inp);
1664 write_pseudonym(esp, inp, len,
id);
1672 eap_srp_response(esp,
id, EAPSRP_ACK, NULL, 0);
1675 case EAPSRP_LWRECHALLENGE:
1677 ppp_warn(
"EAP: malformed Lightweight rechallenge");
1682 SHA1Update(&ctxt, vals, 1);
1683 SHA1Update(&ctxt, pcb->eap.es_client.ea_skey,
1685 SHA1Update(&ctxt, inp, len);
1686 SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1687 pcb->eap.es_client.ea_namelen);
1688 SHA1Final(dig, &ctxt);
1689 eap_srp_response(esp,
id, EAPSRP_LWRECHALLENGE, dig,
1694 ppp_error(
"EAP: unknown SRP Subtype %d", vallen);
1695 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1702 ppp_info(
"EAP: unknown authentication type %d; Naking", typenum);
1703 eap_send_nak(pcb,
id, EAPT_SRP);
1707 if (pcb->settings.eap_req_time > 0) {
1708 UNTIMEOUT(eap_client_timeout, pcb);
1709 TIMEOUT(eap_client_timeout, pcb,
1710 pcb->settings.eap_req_time);
1716 pcb->eap.es_client.ea_state = eapBadAuth;
1717 if (pcb->settings.eap_req_time > 0) {
1718 UNTIMEOUT(eap_client_timeout, (
void *)esp);
1720 pcb->eap.es_client.ea_session =
NULL;
1722 auth_withpeer_fail(pcb, PPP_EAP);
1730 static void eap_response(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
1734 char secret[MAXSECRETLEN];
1735 char rhostname[MAXNAMELEN];
1736 md5_context mdContext;
1737 u_char hash[MD5_SIGNATURE_SIZE];
1739 struct t_server *ts;
1742 u_char dig[SHA_DIGESTSIZE];
1745 if (pcb->eap.es_server.ea_id !=
id) {
1746 ppp_dbglog(
"EAP: discarding Response %d; expected ID %d",
id,
1747 pcb->eap.es_server.ea_id);
1751 pcb->eap.es_server.ea_responses++;
1754 ppp_error(
"EAP: empty Response message discarded");
1758 GETCHAR(typenum, inp);
1763 if (pcb->eap.es_server.ea_state != eapIdentify) {
1764 ppp_dbglog(
"EAP discarding unwanted Identify \"%.q\"", len,
1768 ppp_info(
"EAP: unauthenticated peer name \"%.*q\"", len, inp);
1769 if (len > MAXNAMELEN) {
1772 MEMCPY(pcb->eap.es_server.ea_peer, inp, len);
1773 pcb->eap.es_server.ea_peer[len] =
'\0';
1774 pcb->eap.es_server.ea_peerlen = len;
1775 eap_figure_next_state(pcb, 0);
1778 case EAPT_NOTIFICATION:
1779 ppp_dbglog(
"EAP unexpected Notification; response discarded");
1784 ppp_info(
"EAP: Nak Response with no suggested protocol");
1785 eap_figure_next_state(pcb, 1);
1789 GETCHAR(vallen, inp);
1794 !pcb->explicit_remote &&
1796 pcb->eap.es_server.ea_state == eapIdentify){
1798 eap_figure_next_state(pcb, 1);
1805 pcb->eap.es_server.ea_state = eapIdentify;
1806 eap_figure_next_state(pcb, 0);
1810 pcb->eap.es_server.ea_state = eapMD5Chall;
1814 ppp_dbglog(
"EAP: peer requesting unknown Type %d", vallen);
1815 switch (pcb->eap.es_server.ea_state) {
1819 pcb->eap.es_server.ea_state = eapMD5Chall;
1823 pcb->eap.es_server.ea_state = eapIdentify;
1824 eap_figure_next_state(pcb, 0);
1834 if (pcb->eap.es_server.ea_state != eapMD5Chall) {
1835 ppp_error(
"EAP: unexpected MD5-Response");
1836 eap_figure_next_state(pcb, 1);
1840 ppp_error(
"EAP: received MD5-Response with no data");
1841 eap_figure_next_state(pcb, 1);
1844 GETCHAR(vallen, inp);
1846 if (vallen != 16 || vallen > len) {
1847 ppp_error(
"EAP: MD5-Response with bad length %d", vallen);
1848 eap_figure_next_state(pcb, 1);
1853 if (vallen >= len +
sizeof (rhostname)) {
1854 ppp_dbglog(
"EAP: trimming really long peer name down");
1855 MEMCPY(rhostname, inp + vallen,
sizeof (rhostname) - 1);
1856 rhostname[
sizeof (rhostname) - 1] =
'\0';
1858 MEMCPY(rhostname, inp + vallen, len - vallen);
1859 rhostname[len - vallen] =
'\0';
1864 if (explicit_remote ||
1865 (remote_name[0] !=
'\0' && vallen == len))
1866 strlcpy(rhostname, remote_name,
sizeof (rhostname));
1873 if (!get_secret(pcb, rhostname,
1874 pcb->eap.es_server.ea_name, secret, &secret_len, 1)) {
1875 ppp_dbglog(
"EAP: no MD5 secret for auth of %q", rhostname);
1876 eap_send_failure(pcb);
1879 md5_starts(&mdContext);
1880 md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1);
1881 md5_update(&mdContext, (u_char *)secret, secret_len);
1882 BZERO(secret,
sizeof (secret));
1883 md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen);
1884 md5_finish(&mdContext, hash);
1885 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
1886 eap_send_failure(pcb);
1889 pcb->eap.es_server.ea_type = EAPT_MD5CHAP;
1890 eap_send_success(pcb);
1891 eap_figure_next_state(pcb, 0);
1892 if (pcb->eap.es_rechallenge != 0)
1893 TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge);
1899 ppp_error(
"EAP: empty SRP Response");
1900 eap_figure_next_state(pcb, 1);
1903 GETCHAR(typenum, inp);
1907 if (pcb->eap.es_server.ea_state != eapSRP1) {
1908 ppp_error(
"EAP: unexpected SRP Subtype 1 Response");
1909 eap_figure_next_state(pcb, 1);
1914 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
1916 pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A);
1917 if (pcb->eap.es_server.ea_skey == NULL) {
1919 ppp_error(
"EAP: bogus A value from client");
1920 eap_send_failure(pcb);
1922 eap_figure_next_state(pcb, 0);
1926 case EAPSRP_CVALIDATOR:
1927 if (pcb->eap.es_server.ea_state != eapSRP2) {
1928 ppp_error(
"EAP: unexpected SRP Subtype 2 Response");
1929 eap_figure_next_state(pcb, 1);
1932 if (len <
sizeof (
u32_t) + SHA_DIGESTSIZE) {
1933 ppp_error(
"EAP: M1 length %d < %d", len,
1934 sizeof (
u32_t) + SHA_DIGESTSIZE);
1935 eap_figure_next_state(pcb, 1);
1938 GETLONG(pcb->eap.es_server.ea_keyflags, inp);
1939 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
1941 if (t_serververify(ts, inp)) {
1942 ppp_info(
"EAP: unable to validate client identity");
1943 eap_send_failure(pcb);
1946 eap_figure_next_state(pcb, 0);
1950 if (pcb->eap.es_server.ea_state != eapSRP3) {
1951 ppp_error(
"EAP: unexpected SRP Subtype 3 Response");
1952 eap_send_failure(esp);
1955 pcb->eap.es_server.ea_type = EAPT_SRP;
1956 eap_send_success(pcb, esp);
1957 eap_figure_next_state(pcb, 0);
1958 if (pcb->eap.es_rechallenge != 0)
1959 TIMEOUT(eap_rechallenge, pcb,
1960 pcb->eap.es_rechallenge);
1961 if (pcb->eap.es_lwrechallenge != 0)
1962 TIMEOUT(srp_lwrechallenge, pcb,
1963 pcb->eap.es_lwrechallenge);
1966 case EAPSRP_LWRECHALLENGE:
1967 if (pcb->eap.es_server.ea_state != eapSRP4) {
1968 ppp_info(
"EAP: unexpected SRP Subtype 4 Response");
1971 if (len != SHA_DIGESTSIZE) {
1972 ppp_error(
"EAP: bad Lightweight rechallenge " 1978 SHA1Update(&ctxt, &vallen, 1);
1979 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
1981 SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen);
1982 SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
1983 pcb->eap.es_server.ea_peerlen);
1984 SHA1Final(dig, &ctxt);
1985 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
1986 ppp_error(
"EAP: failed Lightweight rechallenge");
1987 eap_send_failure(pcb);
1990 pcb->eap.es_server.ea_state = eapOpen;
1991 if (pcb->eap.es_lwrechallenge != 0)
1992 TIMEOUT(srp_lwrechallenge, esp,
1993 pcb->eap.es_lwrechallenge);
2001 ppp_error(
"EAP: unknown Response type %d; ignored", typenum);
2005 if (pcb->settings.eap_timeout_time > 0) {
2006 UNTIMEOUT(eap_server_timeout, pcb);
2009 if (pcb->eap.es_server.ea_state != eapBadAuth &&
2010 pcb->eap.es_server.ea_state != eapOpen) {
2011 pcb->eap.es_server.ea_id++;
2012 eap_send_request(pcb);
2020 static void eap_success(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
2023 if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) {
2024 ppp_dbglog(
"EAP unexpected success message in state %s (%d)",
2025 eap_state_name(pcb->eap.es_client.ea_state),
2026 pcb->eap.es_client.ea_state);
2030 if (pcb->settings.eap_req_time > 0) {
2031 UNTIMEOUT(eap_client_timeout, pcb);
2039 pcb->eap.es_client.ea_state = eapOpen;
2040 auth_withpeer_success(pcb, PPP_EAP, 0);
2046 static void eap_failure(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
2049 if (!eap_client_active(pcb)) {
2050 ppp_dbglog(
"EAP unexpected failure message in state %s (%d)",
2051 eap_state_name(pcb->eap.es_client.ea_state),
2052 pcb->eap.es_client.ea_state);
2055 if (pcb->settings.eap_req_time > 0) {
2056 UNTIMEOUT(eap_client_timeout, pcb);
2064 pcb->eap.es_client.ea_state = eapBadAuth;
2066 ppp_error(
"EAP: peer reports authentication failure");
2067 auth_withpeer_fail(pcb, PPP_EAP);
2073 static void eap_input(ppp_pcb *pcb, u_char *inp,
int inlen) {
2081 if (inlen < EAP_HEADERLEN) {
2082 ppp_error(
"EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2088 if (len < EAP_HEADERLEN || len > inlen) {
2089 ppp_error(
"EAP: packet has illegal length field %d (%d..%d)", len,
2090 EAP_HEADERLEN, inlen);
2093 len -= EAP_HEADERLEN;
2098 eap_request(pcb, inp,
id, len);
2103 eap_response(pcb, inp,
id, len);
2108 eap_success(pcb, inp,
id, len);
2112 eap_failure(pcb, inp,
id, len);
2117 ppp_warn(
"EAP: unknown code %d received", code);
2122 #if PRINTPKT_SUPPORT 2126 static const char*
const eap_codenames[] = {
2127 "Request",
"Response",
"Success",
"Failure" 2130 static const char*
const eap_typenames[] = {
2131 "Identity",
"Notification",
"Nak",
"MD5-Challenge",
2132 "OTP",
"Generic-Token",
NULL,
NULL,
2133 "RSA",
"DSS",
"KEA",
"KEA-Validate",
2134 "TLS",
"Defender",
"Windows 2000",
"Arcot",
2135 "Cisco",
"Nokia",
"SRP" 2138 static int eap_printpkt(
const u_char *inp,
int inlen,
void (*printer) (
void *,
const char *, ...),
void *arg) {
2139 int code, id, len, rtype, vallen;
2140 const u_char *pstart;
2143 if (inlen < EAP_HEADERLEN)
2149 if (len < EAP_HEADERLEN || len > inlen)
2152 if (code >= 1 && code <= (
int)
sizeof(eap_codenames) / (
int)
sizeof(
char *))
2153 printer(arg,
" %s", eap_codenames[code-1]);
2155 printer(arg,
" code=0x%x", code);
2156 printer(arg,
" id=0x%x",
id);
2157 len -= EAP_HEADERLEN;
2161 printer(arg,
" <missing type>");
2164 GETCHAR(rtype, inp);
2167 rtype <= (
int)
sizeof (eap_typenames) / (
int)
sizeof (
char *))
2168 printer(arg,
" %s", eap_typenames[rtype-1]);
2170 printer(arg,
" type=0x%x", rtype);
2173 case EAPT_NOTIFICATION:
2175 printer(arg,
" <Message ");
2176 ppp_print_string(inp, len, printer, arg);
2181 printer(arg,
" <No message>");
2188 GETCHAR(vallen, inp);
2192 printer(arg,
" <Value%.*B>", vallen, inp);
2193 INCPTR(vallen, inp);
2196 printer(arg,
" <Name ");
2197 ppp_print_string(inp, len, printer, arg);
2202 printer(arg,
" <No name>");
2209 GETCHAR(vallen, inp);
2211 printer(arg,
"-%d", vallen);
2213 case EAPSRP_CHALLENGE:
2214 GETCHAR(vallen, inp);
2219 printer(arg,
" <Name ");
2220 ppp_print_string(inp, vallen, printer,
2224 printer(arg,
" <No name>");
2226 INCPTR(vallen, inp);
2228 GETCHAR(vallen, inp);
2232 printer(arg,
" <s%.*B>", vallen, inp);
2233 INCPTR(vallen, inp);
2235 GETCHAR(vallen, inp);
2240 printer(arg,
" <Default g=2>");
2242 printer(arg,
" <g%.*B>", vallen, inp);
2244 INCPTR(vallen, inp);
2247 printer(arg,
" <Default N>");
2249 printer(arg,
" <N%.*B>", len, inp);
2256 printer(arg,
" <B%.*B>", len, inp);
2261 case EAPSRP_SVALIDATOR:
2262 if (len < (
int)
sizeof (
u32_t))
2265 len -=
sizeof (
u32_t);
2266 if (uval & SRPVAL_EBIT) {
2268 uval &= ~SRPVAL_EBIT;
2271 printer(arg,
" f<%X>", uval);
2273 if ((vallen = len) > SHA_DIGESTSIZE)
2274 vallen = SHA_DIGESTSIZE;
2275 printer(arg,
" <M2%.*B%s>", len, inp,
2276 len < SHA_DIGESTSIZE ?
"?" :
"");
2277 INCPTR(vallen, inp);
2280 printer(arg,
" <PN%.*B>", len, inp);
2286 case EAPSRP_LWRECHALLENGE:
2287 printer(arg,
" <Challenge%.*B>", len, inp);
2303 GETCHAR(rtype, inp);
2306 rtype <= (
int)
sizeof (eap_typenames) / (
int)
sizeof (
char *))
2307 printer(arg,
" %s", eap_typenames[rtype-1]);
2309 printer(arg,
" type=0x%x", rtype);
2313 printer(arg,
" <Name ");
2314 ppp_print_string(inp, len, printer, arg);
2323 printer(arg,
" <missing hint>");
2326 GETCHAR(rtype, inp);
2328 printer(arg,
" <Suggested-type %02X", rtype);
2330 rtype < (
int)
sizeof (eap_typenames) / (
int)
sizeof (
char *))
2331 printer(arg,
" (%s)", eap_typenames[rtype-1]);
2337 printer(arg,
" <missing length>");
2340 GETCHAR(vallen, inp);
2344 printer(arg,
" <Value%.*B>", vallen, inp);
2345 INCPTR(vallen, inp);
2348 printer(arg,
" <Name ");
2349 ppp_print_string(inp, len, printer, arg);
2354 printer(arg,
" <No name>");
2361 GETCHAR(vallen, inp);
2363 printer(arg,
"-%d", vallen);
2366 printer(arg,
" <A%.*B>", len, inp);
2371 case EAPSRP_CVALIDATOR:
2372 if (len < (
int)
sizeof (
u32_t))
2375 len -=
sizeof (
u32_t);
2376 if (uval & SRPVAL_EBIT) {
2378 uval &= ~SRPVAL_EBIT;
2381 printer(arg,
" f<%X>", uval);
2383 printer(arg,
" <M1%.*B%s>", len, inp,
2384 len == SHA_DIGESTSIZE ?
"" :
"?");
2392 case EAPSRP_LWRECHALLENGE:
2393 printer(arg,
" <Response%.*B%s>", len, inp,
2394 len == SHA_DIGESTSIZE ?
"" :
"?");
2395 if ((vallen = len) > SHA_DIGESTSIZE)
2396 vallen = SHA_DIGESTSIZE;
2397 INCPTR(vallen, inp);
2415 printer(arg,
" <truncated>");
2420 printer(arg,
"%8B...", inp);
2422 printer(arg,
"%.*B", len, inp);
2425 return (inp - pstart);
void pbuf_realloc(struct pbuf *p, u16_t new_len)
#define MEMCPY(dst, src, len)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
#define LWIP_UNUSED_ARG(x)