65 #include "netif/ppp/ppp_opts.h" 66 #if PPP_SUPPORT && EAP_SUPPORT 68 #include "netif/ppp/ppp_impl.h" 69 #include "netif/ppp/eap.h" 70 #include "netif/ppp/magic.h" 71 #include "netif/ppp/pppcrypt.h" 79 #ifndef SHA_DIGESTSIZE 80 #define SHA_DIGESTSIZE 20 84 static char *pn_secret = NULL;
91 static option_t eap_option_list[] = {
92 {
"eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
93 "Set retransmit timeout for EAP Requests (server)" },
94 {
"eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
95 "Set max number of EAP Requests sent (server)" },
96 {
"eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
97 "Set time limit for peer EAP authentication" },
98 {
"eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
99 "Set max number of EAP Requests allows (client)" },
100 {
"eap-interval", o_int, &eap_states[0].es_rechallenge,
101 "Set interval for EAP rechallenge" },
103 {
"srp-interval", o_int, &eap_states[0].es_lwrechallenge,
104 "Set interval for SRP lightweight rechallenge" },
105 {
"srp-pn-secret", o_string, &pn_secret,
106 "Long term pseudonym generation secret" },
107 {
"srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
108 "Use pseudonym if offered one by server", 1 },
117 static void eap_init(ppp_pcb *pcb);
118 static void eap_input(ppp_pcb *pcb, u_char *inp,
int inlen);
119 static void eap_protrej(ppp_pcb *pcb);
120 static void eap_lowerup(ppp_pcb *pcb);
121 static void eap_lowerdown(ppp_pcb *pcb);
123 static int eap_printpkt(
const u_char *inp,
int inlen,
124 void (*)(
void *arg,
const char *fmt, ...),
void *arg);
127 const struct protent eap_protent = {
160 static const u_char wkmodulus[] = {
161 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
162 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
163 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
164 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
165 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
166 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
167 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
168 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
169 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
170 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
171 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
172 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
173 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
174 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
175 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
176 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
177 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
178 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
179 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
180 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
181 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
182 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
183 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
184 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
185 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
186 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
187 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
188 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
189 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
190 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
191 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
192 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
198 static void eap_server_timeout(
void *arg);
204 static const char * eap_state_name(
enum eap_state_code esc)
206 static const char *state_names[] = { EAP_STATES };
208 return (state_names[(
int)esc]);
215 static void eap_init(ppp_pcb *pcb) {
217 BZERO(&pcb->eap,
sizeof(eap_state));
219 pcb->eap.es_server.ea_id = magic();
227 static void eap_client_timeout(
void *arg) {
228 ppp_pcb *pcb = (ppp_pcb*)arg;
230 if (!eap_client_active(pcb))
233 ppp_error(
"EAP: timeout waiting for Request from peer");
234 auth_withpeer_fail(pcb, PPP_EAP);
235 pcb->eap.es_client.ea_state = eapBadAuth;
244 void eap_authwithpeer(ppp_pcb *pcb,
const char *localname) {
246 if(NULL == localname)
250 pcb->eap.es_client.ea_name = localname;
251 pcb->eap.es_client.ea_namelen = strlen(localname);
253 pcb->eap.es_client.ea_state = eapListen;
259 if (pcb->settings.eap_req_time > 0)
260 TIMEOUT(eap_client_timeout, pcb,
261 pcb->settings.eap_req_time);
269 static void eap_send_failure(ppp_pcb *pcb) {
283 MAKEHEADER(outp, PPP_EAP);
285 PUTCHAR(EAP_FAILURE, outp);
286 pcb->eap.es_server.ea_id++;
287 PUTCHAR(pcb->eap.es_server.ea_id, outp);
288 PUTSHORT(EAP_HEADERLEN, outp);
292 pcb->eap.es_server.ea_state = eapBadAuth;
293 auth_peer_fail(pcb, PPP_EAP);
300 static void eap_send_success(ppp_pcb *pcb) {
314 MAKEHEADER(outp, PPP_EAP);
316 PUTCHAR(EAP_SUCCESS, outp);
317 pcb->eap.es_server.ea_id++;
318 PUTCHAR(pcb->eap.es_server.ea_id, outp);
319 PUTSHORT(EAP_HEADERLEN, outp);
323 auth_peer_success(pcb, PPP_EAP, 0,
324 pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen);
334 pncrypt_setkey(
int timeoffs)
339 u_char dig[SHA_DIGESTSIZE];
342 if (pn_secret == NULL)
344 reftime = time(NULL) + timeoffs;
345 tp = localtime(&reftime);
347 SHA1Update(&ctxt, pn_secret, strlen(pn_secret));
348 strftime(tbuf,
sizeof (tbuf),
"%Y%m%d", tp);
349 SHA1Update(&ctxt, tbuf, strlen(tbuf));
350 SHA1Final(dig, &ctxt);
352 return (DesSetkey(dig));
355 static char base64[] =
356 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
364 b64enc(bs, inp, inlen, outp)
373 bs->bs_bits = (bs->bs_bits << 8) | *inp++;
376 if (bs->bs_offs >= 24) {
377 *outp++ = base64[(bs->bs_bits >> 18) & 0x3F];
378 *outp++ = base64[(bs->bs_bits >> 12) & 0x3F];
379 *outp++ = base64[(bs->bs_bits >> 6) & 0x3F];
380 *outp++ = base64[bs->bs_bits & 0x3F];
396 if (bs->bs_offs == 8) {
397 *outp++ = base64[(bs->bs_bits >> 2) & 0x3F];
398 *outp++ = base64[(bs->bs_bits << 4) & 0x3F];
400 }
else if (bs->bs_offs == 16) {
401 *outp++ = base64[(bs->bs_bits >> 10) & 0x3F];
402 *outp++ = base64[(bs->bs_bits >> 4) & 0x3F];
403 *outp++ = base64[(bs->bs_bits << 2) & 0x3F];
412 b64dec(bs, inp, inlen, outp)
422 if ((cp = strchr(base64, *inp++)) == NULL)
424 bs->bs_bits = (bs->bs_bits << 6) | (cp - base64);
427 if (bs->bs_offs >= 8) {
428 *outp++ = bs->bs_bits >> (bs->bs_offs - 8);
444 static void eap_figure_next_state(ppp_pcb *pcb,
int status) {
446 unsigned char secbuf[MAXSECRETLEN], clear[8], *sp, *dp;
448 struct t_confent *tce, mytce;
451 int id, i, plen, toffs;
456 pcb->settings.eap_timeout_time = pcb->eap.es_savedtime;
457 switch (pcb->eap.es_server.ea_state) {
464 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
467 pcb->eap.es_server.ea_session = NULL;
468 pcb->eap.es_server.ea_skey = NULL;
472 pcb->eap.es_server.ea_state = eapBadAuth;
477 if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN &&
478 strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID,
479 SRP_PSEUDO_LEN) == 0 &&
480 (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
482 BZERO(&bs,
sizeof (bs));
484 pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN,
485 pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN,
488 for (i = 0; i < 5; i++) {
489 pncrypt_setkey(toffs);
492 if (!DesDecrypt(secbuf, clear)) {
493 ppp_dbglog(
"no DES here; cannot decode " 497 id = *(
unsigned char *)clear;
498 if (
id + 1 <= plen &&
id + 9 > plen)
501 if (plen % 8 == 0 && i < 5) {
507 if ((i = plen = *(
unsigned char *)clear) > 7)
509 pcb->eap.es_server.ea_peerlen = plen;
510 dp = (
unsigned char *)pcb->eap.es_server.ea_peer;
511 MEMCPY(dp, clear + 1, i);
517 (void) DesDecrypt(sp, dp);
522 pcb->eap.es_server.ea_peer[
523 pcb->eap.es_server.ea_peerlen] =
'\0';
524 ppp_dbglog(
"decoded pseudonym to \"%.*q\"",
525 pcb->eap.es_server.ea_peerlen,
526 pcb->eap.es_server.ea_peer);
528 ppp_dbglog(
"failed to decode real name");
534 if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer,
535 pcb->eap.es_server.ea_name, (
char *)secbuf, 1) != 0) {
537 pcb->eap.es_server.ea_state = eapMD5Chall;
539 id = strtol((
char *)secbuf, &cp, 10);
540 if (*cp++ !=
':' ||
id < 0)
544 mytce.modulus.data = (u_char *)wkmodulus;
545 mytce.modulus.len =
sizeof (wkmodulus);
546 mytce.generator.data = (u_char *)
"\002";
547 mytce.generator.len = 1;
549 }
else if ((tce = gettcid(
id)) != NULL) {
555 if (pcb->settings.eap_timeout_time > 0 &&
556 pcb->settings.eap_timeout_time < 30)
557 pcb->settings.eap_timeout_time = 30;
561 if ((cp2 = strchr(cp,
':')) == NULL)
564 tpw.pebuf.name = pcb->eap.es_server.ea_peer;
565 tpw.pebuf.password.len = t_fromb64((
char *)tpw.pwbuf,
567 tpw.pebuf.password.data = tpw.pwbuf;
568 tpw.pebuf.salt.len = t_fromb64((
char *)tpw.saltbuf,
570 tpw.pebuf.salt.data = tpw.saltbuf;
571 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL)
573 pcb->eap.es_server.ea_session = (
void *)ts;
574 pcb->eap.es_server.ea_state = eapSRP1;
575 vals[0] = pcb->eap.es_server.ea_id + 1;
577 t_serveraddexdata(ts, vals, 2);
583 pcb->eap.es_server.ea_state = eapMD5Chall;
588 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
589 if (ts != NULL && status != 0) {
591 pcb->eap.es_server.ea_session = NULL;
592 pcb->eap.es_server.ea_skey = NULL;
596 pcb->eap.es_server.ea_state = eapMD5Chall;
597 }
else if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
598 pcb->eap.es_server.ea_state = eapBadAuth;
600 pcb->eap.es_server.ea_state = eapSRP2;
606 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
607 if (ts != NULL && status != 0) {
609 pcb->eap.es_server.ea_session = NULL;
610 pcb->eap.es_server.ea_skey = NULL;
613 if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
614 pcb->eap.es_server.ea_state = eapBadAuth;
616 pcb->eap.es_server.ea_state = eapSRP3;
623 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
624 if (ts != NULL && status != 0) {
626 pcb->eap.es_server.ea_session = NULL;
627 pcb->eap.es_server.ea_skey = NULL;
630 if (status != 0 || pcb->eap.es_server.ea_session == NULL) {
631 pcb->eap.es_server.ea_state = eapBadAuth;
633 pcb->eap.es_server.ea_state = eapOpen;
639 pcb->eap.es_server.ea_state = eapBadAuth;
641 pcb->eap.es_server.ea_state = eapOpen;
646 pcb->eap.es_server.ea_state = eapBadAuth;
649 if (pcb->eap.es_server.ea_state == eapBadAuth)
650 eap_send_failure(pcb);
657 static void eap_send_request(ppp_pcb *pcb) {
666 u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp;
673 if (pcb->eap.es_server.ea_state < eapIdentify &&
674 pcb->eap.es_server.ea_state != eapInitial) {
675 pcb->eap.es_server.ea_state = eapIdentify;
677 if (pcb->settings.explicit_remote && pcb->remote_name) {
683 int len = (int)strlen(pcb->remote_name);
684 if (len > MAXNAMELEN) {
687 MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name, len);
688 pcb->eap.es_server.ea_peer[len] =
'\0';
689 pcb->eap.es_server.ea_peerlen = len;
690 eap_figure_next_state(pcb, 0);
695 if (pcb->settings.eap_max_transmits > 0 &&
696 pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) {
697 if (pcb->eap.es_server.ea_responses > 0)
698 ppp_error(
"EAP: too many Requests sent");
700 ppp_error(
"EAP: no response to Requests");
701 eap_send_failure(pcb);
715 MAKEHEADER(outp, PPP_EAP);
717 PUTCHAR(EAP_REQUEST, outp);
718 PUTCHAR(pcb->eap.es_server.ea_id, outp);
722 switch (pcb->eap.es_server.ea_state) {
724 PUTCHAR(EAPT_IDENTITY, outp);
727 MEMCPY(outp, str, len);
732 PUTCHAR(EAPT_MD5CHAP, outp);
737 pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
738 magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
739 PUTCHAR(pcb->eap.es_challen, outp);
740 magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
741 MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
742 INCPTR(pcb->eap.es_challen, outp);
743 MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
744 INCPTR(pcb->eap.es_server.ea_namelen, outp);
749 PUTCHAR(EAPT_SRP, outp);
750 PUTCHAR(EAPSRP_CHALLENGE, outp);
752 PUTCHAR(pcb->eap.es_server.ea_namelen, outp);
753 MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
754 INCPTR(pcb->eap.es_server.ea_namelen, outp);
756 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
758 PUTCHAR(ts->s.len, outp);
759 MEMCPY(outp, ts->s.data, ts->s.len);
760 INCPTR(ts->s.len, outp);
762 if (ts->g.len == 1 && ts->g.data[0] == 2) {
765 PUTCHAR(ts->g.len, outp);
766 MEMCPY(outp, ts->g.data, ts->g.len);
767 INCPTR(ts->g.len, outp);
770 if (ts->n.len != sizeof (wkmodulus) ||
771 BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) {
772 MEMCPY(outp, ts->n.data, ts->n.len);
773 INCPTR(ts->n.len, outp);
778 PUTCHAR(EAPT_SRP, outp);
779 PUTCHAR(EAPSRP_SKEY, outp);
781 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
783 MEMCPY(outp, ts->B.data, ts->B.len);
784 INCPTR(ts->B.len, outp);
788 PUTCHAR(EAPT_SRP, outp);
789 PUTCHAR(EAPSRP_SVALIDATOR, outp);
790 PUTLONG(SRPVAL_EBIT, outp);
791 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
793 MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE);
794 INCPTR(SHA_DIGESTSIZE, outp);
796 if (pncrypt_setkey(0)) {
799 cp = (
unsigned char *)pcb->eap.es_server.ea_peer;
800 if ((j = i = pcb->eap.es_server.ea_peerlen) > 7)
803 MEMCPY(clear + 1, cp, j);
807 if (!DesEncrypt(clear, cipher)) {
808 ppp_dbglog(
"no DES here; not generating pseudonym");
811 BZERO(&b64,
sizeof (b64));
813 outp += b64enc(&b64, cipher, 8, outp);
816 (void) DesEncrypt(cp, cipher);
817 outp += b64enc(&b64, cipher, 8, outp);
822 MEMCPY(clear, cp, i);
824 magic_random_bytes(cp, 8-i);
826 (void) DesEncrypt(clear, cipher);
827 outp += b64enc(&b64, cipher, 8, outp);
829 outp += b64flush(&b64, outp);
836 magic_random_bytes(outp, SHA_DIGESTSIZE-i);
837 INCPTR(SHA_DIGESTSIZE-i, outp);
842 SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
843 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
845 SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
846 pcb->eap.es_server.ea_peerlen);
847 while (optr < outp) {
848 SHA1Final(dig, &ctxt);
850 while (cp < dig + SHA_DIGESTSIZE)
853 SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
854 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
856 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
863 PUTCHAR(EAPT_SRP, outp);
864 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
865 pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
866 magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
867 magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
868 MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
869 INCPTR(pcb->eap.es_challen, outp);
877 outlen = (outp - (
unsigned char*)p->
payload) - PPP_HDRLEN;
878 PUTSHORT(outlen, lenloc);
883 pcb->eap.es_server.ea_requests++;
885 if (pcb->settings.eap_timeout_time > 0)
886 TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time);
895 void eap_authpeer(ppp_pcb *pcb,
const char *localname) {
898 pcb->eap.es_server.ea_name = localname;
899 pcb->eap.es_server.ea_namelen = strlen(localname);
901 pcb->eap.es_savedtime = pcb->settings.eap_timeout_time;
904 if (pcb->eap.es_server.ea_state == eapInitial ||
905 pcb->eap.es_server.ea_state == eapPending) {
906 pcb->eap.es_server.ea_state = eapPending;
910 pcb->eap.es_server.ea_state = eapPending;
913 eap_send_request(pcb);
920 static void eap_server_timeout(
void *arg) {
921 ppp_pcb *pcb = (ppp_pcb*)arg;
923 if (!eap_server_active(pcb))
927 eap_send_request(pcb);
935 static void eap_rechallenge(
void *arg) {
936 ppp_pcb *pcb = (ppp_pcb*)arg;
938 if (pcb->eap.es_server.ea_state != eapOpen &&
939 pcb->eap.es_server.ea_state != eapSRP4)
942 pcb->eap.es_server.ea_requests = 0;
943 pcb->eap.es_server.ea_state = eapIdentify;
944 eap_figure_next_state(pcb, 0);
945 pcb->eap.es_server.ea_id++;
946 eap_send_request(pcb);
949 static void srp_lwrechallenge(
void *arg) {
950 ppp_pcb *pcb = (ppp_pcb*)arg;
952 if (pcb->eap.es_server.ea_state != eapOpen ||
953 pcb->eap.es_server.ea_type != EAPT_SRP)
956 pcb->eap.es_server.ea_requests = 0;
957 pcb->eap.es_server.ea_state = eapSRP4;
958 pcb->eap.es_server.ea_id++;
959 eap_send_request(pcb);
971 static void eap_lowerup(ppp_pcb *pcb) {
972 pcb->eap.es_client.ea_state = eapClosed;
974 pcb->eap.es_server.ea_state = eapClosed;
983 static void eap_lowerdown(ppp_pcb *pcb) {
985 if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) {
986 UNTIMEOUT(eap_client_timeout, pcb);
989 if (eap_server_active(pcb)) {
990 if (pcb->settings.eap_timeout_time > 0) {
991 UNTIMEOUT(eap_server_timeout, pcb);
994 if ((pcb->eap.es_server.ea_state == eapOpen ||
995 pcb->eap.es_server.ea_state == eapSRP4) &&
996 pcb->eap.es_rechallenge > 0) {
997 UNTIMEOUT(eap_rechallenge, (
void *)pcb);
999 if (pcb->eap.es_server.ea_state == eapOpen &&
1000 pcb->eap.es_lwrechallenge > 0) {
1001 UNTIMEOUT(srp_lwrechallenge, (
void *)pcb);
1005 pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial;
1006 pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0;
1016 static void eap_protrej(ppp_pcb *pcb) {
1018 if (eap_client_active(pcb)) {
1019 ppp_error(
"EAP authentication failed due to Protocol-Reject");
1020 auth_withpeer_fail(pcb, PPP_EAP);
1023 if (eap_server_active(pcb)) {
1024 ppp_error(
"EAP authentication of peer failed on Protocol-Reject");
1025 auth_peer_fail(pcb, PPP_EAP);
1034 static void eap_send_response(ppp_pcb *pcb, u_char
id, u_char typenum,
const u_char *str,
int lenstr) {
1039 msglen = EAP_HEADERLEN +
sizeof (u_char) + lenstr;
1050 MAKEHEADER(outp, PPP_EAP);
1052 PUTCHAR(EAP_RESPONSE, outp);
1054 pcb->eap.es_client.ea_id = id;
1055 PUTSHORT(msglen, outp);
1056 PUTCHAR(typenum, outp);
1058 MEMCPY(outp, str, lenstr);
1067 static void eap_chap_response(ppp_pcb *pcb, u_char
id, u_char *hash,
const char *name,
int namelen) {
1072 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char) + MD5_SIGNATURE_SIZE +
1084 MAKEHEADER(outp, PPP_EAP);
1086 PUTCHAR(EAP_RESPONSE, outp);
1088 pcb->eap.es_client.ea_id = id;
1089 PUTSHORT(msglen, outp);
1090 PUTCHAR(EAPT_MD5CHAP, outp);
1091 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1092 MEMCPY(outp, hash, MD5_SIGNATURE_SIZE);
1093 INCPTR(MD5_SIGNATURE_SIZE, outp);
1095 MEMCPY(outp, name, namelen);
1106 eap_srp_response(esp,
id, subtypenum, str, lenstr)
1113 ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1118 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char) + lenstr;
1129 MAKEHEADER(outp, PPP_EAP);
1131 PUTCHAR(EAP_RESPONSE, outp);
1133 pcb->eap.es_client.ea_id = id;
1134 PUTSHORT(msglen, outp);
1135 PUTCHAR(EAPT_SRP, outp);
1136 PUTCHAR(subtypenum, outp);
1138 MEMCPY(outp, str, lenstr);
1148 eap_srpval_response(esp,
id,
flags, str)
1154 ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1159 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char) +
sizeof (u32_t) +
1171 MAKEHEADER(outp, PPP_EAP);
1173 PUTCHAR(EAP_RESPONSE, outp);
1175 pcb->eap.es_client.ea_id = id;
1176 PUTSHORT(msglen, outp);
1177 PUTCHAR(EAPT_SRP, outp);
1178 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1179 PUTLONG(flags, outp);
1180 MEMCPY(outp, str, SHA_DIGESTSIZE);
1186 static void eap_send_nak(ppp_pcb *pcb, u_char
id, u_char
type) {
1191 msglen = EAP_HEADERLEN + 2 *
sizeof (u_char);
1202 MAKEHEADER(outp, PPP_EAP);
1204 PUTCHAR(EAP_RESPONSE, outp);
1206 pcb->eap.es_client.ea_id = id;
1207 PUTSHORT(msglen, outp);
1208 PUTCHAR(EAPT_NAK, outp);
1209 PUTCHAR(type, outp);
1218 char *user, *path, *file;
1221 static bool pnlogged = 0;
1223 pw = getpwuid(getuid());
1224 if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) {
1228 file = _PATH_PSEUDONYM;
1229 pl = strlen(user) + strlen(file) + 2;
1233 (void) slprintf(path, pl,
"%s/%s", user, file);
1235 ppp_dbglog(
"pseudonym file: %s", path);
1242 open_pn_file(modebits)
1248 if ((path = name_of_pn_file()) == NULL)
1250 fd = open(path, modebits, S_IRUSR | S_IWUSR);
1262 if ((path = name_of_pn_file()) != NULL) {
1263 (void) unlink(path);
1269 write_pseudonym(esp, inp, len,
id)
1275 u_char *datp, *digp;
1277 u_char dig[SHA_DIGESTSIZE];
1278 int dsize, fd, olen = len;
1286 if ((dsize = len % SHA_DIGESTSIZE) == 0)
1287 dsize = SHA_DIGESTSIZE;
1291 SHA1Update(&ctxt, &val, 1);
1292 SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN);
1294 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1296 SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1297 pcb->eap.es_client.ea_namelen);
1299 SHA1Final(dig, &ctxt);
1300 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1305 if (olen <= 0 || *inp + 1 > olen) {
1306 ppp_dbglog(
"EAP: decoded pseudonym is unusable <%.*B>", olen, inp);
1311 fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC);
1313 ppp_dbglog(
"EAP: error saving pseudonym: %m");
1316 len = write(fd, inp + 1, *inp);
1317 if (close(fd) != -1 && len == *inp) {
1318 ppp_dbglog(
"EAP: saved pseudonym");
1319 pcb->eap.es_usedpseudo = 0;
1321 ppp_dbglog(
"EAP: failed to save pseudonym");
1330 static void eap_request(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
1334 char secret[MAXSECRETLEN];
1335 char rhostname[MAXNAMELEN];
1336 lwip_md5_context mdContext;
1337 u_char hash[MD5_SIGNATURE_SIZE];
1339 struct t_client *tc;
1340 struct t_num sval, gval, Nval, *Ap, Bval;
1343 u_char dig[SHA_DIGESTSIZE];
1353 pcb->eap.es_client.ea_requests++;
1354 if (pcb->settings.eap_allow_req != 0 &&
1355 pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) {
1356 ppp_info(
"EAP: received too many Request messages");
1357 if (pcb->settings.eap_req_time > 0) {
1358 UNTIMEOUT(eap_client_timeout, pcb);
1360 auth_withpeer_fail(pcb, PPP_EAP);
1365 ppp_error(
"EAP: empty Request message discarded");
1369 GETCHAR(typenum, inp);
1375 ppp_info(
"EAP: Identity prompt \"%.*q\"", len, inp);
1377 if (pcb->eap.es_usepseudo &&
1378 (pcb->eap.es_usedpseudo == 0 ||
1379 (pcb->eap.es_usedpseudo == 1 &&
1380 id == pcb->eap.es_client.ea_id))) {
1381 pcb->eap.es_usedpseudo = 1;
1383 if ((fd = open_pn_file(O_RDONLY)) >= 0) {
1384 strcpy(rhostname, SRP_PSEUDO_ID);
1385 len = read(fd, rhostname + SRP_PSEUDO_LEN,
1386 sizeof (rhostname) - SRP_PSEUDO_LEN);
1389 eap_send_response(pcb,
id, typenum,
1390 rhostname, len + SRP_PSEUDO_LEN);
1398 if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) {
1400 pcb->eap.es_usedpseudo = 2;
1403 eap_send_response(pcb,
id, typenum, (
const u_char*)pcb->eap.es_client.ea_name,
1404 pcb->eap.es_client.ea_namelen);
1407 case EAPT_NOTIFICATION:
1409 ppp_info(
"EAP: Notification \"%.*q\"", len, inp);
1410 eap_send_response(pcb,
id, typenum, NULL, 0);
1418 ppp_warn(
"EAP: unexpected Nak in Request; ignored");
1424 ppp_error(
"EAP: received MD5-Challenge with no data");
1428 GETCHAR(vallen, inp);
1430 if (vallen < 8 || vallen > len) {
1431 ppp_error(
"EAP: MD5-Challenge with bad length %d (8..%d)",
1434 eap_send_nak(pcb,
id, EAPT_SRP);
1439 if (vallen >= len +
sizeof (rhostname)) {
1440 ppp_dbglog(
"EAP: trimming really long peer name down");
1441 MEMCPY(rhostname, inp + vallen,
sizeof (rhostname) - 1);
1442 rhostname[
sizeof (rhostname) - 1] =
'\0';
1444 MEMCPY(rhostname, inp + vallen, len - vallen);
1445 rhostname[len - vallen] =
'\0';
1450 if (pcb->settings.explicit_remote ||
1451 (pcb->settings.remote_name[0] !=
'\0' && vallen == len))
1452 strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname));
1459 if (!get_secret(pcb, pcb->eap.es_client.ea_name,
1460 rhostname, secret, &secret_len, 0)) {
1461 ppp_dbglog(
"EAP: no MD5 secret for auth to %q", rhostname);
1462 eap_send_nak(pcb,
id, EAPT_SRP);
1465 lwip_md5_init(&mdContext);
1466 lwip_md5_starts(&mdContext);
1468 lwip_md5_update(&mdContext, &typenum, 1);
1469 lwip_md5_update(&mdContext, (u_char *)secret, secret_len);
1470 BZERO(secret,
sizeof (secret));
1471 lwip_md5_update(&mdContext, inp, vallen);
1472 lwip_md5_finish(&mdContext, hash);
1473 lwip_md5_free(&mdContext);
1474 eap_chap_response(pcb,
id, hash, pcb->eap.es_client.ea_name,
1475 pcb->eap.es_client.ea_namelen);
1481 ppp_error(
"EAP: received empty SRP Request");
1487 GETCHAR(vallen, inp);
1490 case EAPSRP_CHALLENGE:
1492 if (pcb->eap.es_client.ea_session != NULL) {
1493 tc = (
struct t_client *)pcb->eap.es_client.
1500 if (
id != pcb->eap.es_client.ea_id) {
1502 pcb->eap.es_client.ea_session = NULL;
1507 pcb->eap.es_client.ea_skey = NULL;
1511 GETCHAR(vallen, inp);
1513 if (vallen >= len) {
1514 ppp_error(
"EAP: badly-formed SRP Challenge" 1519 MEMCPY(rhostname, inp, vallen);
1520 rhostname[vallen] =
'\0';
1521 INCPTR(vallen, inp);
1528 if (explicit_remote ||
1529 (remote_name[0] !=
'\0' && vallen == 0)) {
1530 strlcpy(rhostname, remote_name,
1531 sizeof (rhostname));
1534 rhostnamelen = (int)strlen(rhostname);
1535 if (rhostnamelen > MAXNAMELEN) {
1536 rhostnamelen = MAXNAMELEN;
1538 MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen);
1539 pcb->eap.es_client.ea_peer[rhostnamelen] =
'\0';
1540 pcb->eap.es_client.ea_peerlen = rhostnamelen;
1542 GETCHAR(vallen, inp);
1544 if (vallen >= len) {
1545 ppp_error(
"EAP: badly-formed SRP Challenge" 1552 INCPTR(vallen, inp);
1555 GETCHAR(vallen, inp);
1558 ppp_error(
"EAP: badly-formed SRP Challenge" 1565 gval.data = (u_char *)
"\002";
1571 INCPTR(vallen, inp);
1579 Nval.data = (u_char *)wkmodulus;
1580 Nval.len =
sizeof (wkmodulus);
1585 tc = t_clientopen(pcb->eap.es_client.ea_name,
1586 &Nval, &gval, &sval);
1588 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1591 pcb->eap.es_client.ea_session = (
void *)tc;
1596 t_clientaddexdata(tc, vals, 2);
1598 Ap = t_clientgenexp(tc);
1599 eap_srp_response(esp,
id, EAPSRP_CKEY, Ap->data,
1604 tc = (
struct t_client *)pcb->eap.es_client.ea_session;
1606 ppp_warn(
"EAP: peer sent Subtype 2 without 1");
1607 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1610 if (pcb->eap.es_client.ea_skey != NULL) {
1615 if (
id != pcb->eap.es_client.ea_id) {
1616 ppp_warn(
"EAP: ID changed from %d to %d " 1617 "in SRP Subtype 2 rexmit",
1618 pcb->eap.es_client.ea_id,
id);
1621 if (get_srp_secret(pcb->eap.es_unit,
1622 pcb->eap.es_client.ea_name,
1623 pcb->eap.es_client.ea_peer, secret, 0) == 0) {
1629 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1634 t_clientpasswd(tc, secret);
1635 BZERO(secret,
sizeof (secret));
1636 pcb->eap.es_client.ea_skey =
1637 t_clientgetkey(tc, &Bval);
1638 if (pcb->eap.es_client.ea_skey == NULL) {
1640 ppp_error(
"EAP: SRP server is rogue");
1641 goto client_failure;
1644 eap_srpval_response(esp,
id, SRPVAL_EBIT,
1645 t_clientresponse(tc));
1648 case EAPSRP_SVALIDATOR:
1649 tc = (
struct t_client *)pcb->eap.es_client.ea_session;
1650 if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) {
1651 ppp_warn(
"EAP: peer sent Subtype 3 without 1/2");
1652 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1660 if (pcb->eap.es_client.ea_state == eapOpen) {
1661 if (
id != pcb->eap.es_client.ea_id) {
1662 ppp_warn(
"EAP: ID changed from %d to %d " 1663 "in SRP Subtype 3 rexmit",
1664 pcb->eap.es_client.ea_id,
id);
1667 len -=
sizeof (u32_t) + SHA_DIGESTSIZE;
1668 if (len < 0 || t_clientverify(tc, inp +
1669 sizeof (u32_t)) != 0) {
1670 ppp_error(
"EAP: SRP server verification " 1672 goto client_failure;
1674 GETLONG(pcb->eap.es_client.ea_keyflags, inp);
1676 if (len > 0 && pcb->eap.es_usepseudo) {
1677 INCPTR(SHA_DIGESTSIZE, inp);
1678 write_pseudonym(esp, inp, len,
id);
1686 eap_srp_response(esp,
id, EAPSRP_ACK, NULL, 0);
1689 case EAPSRP_LWRECHALLENGE:
1691 ppp_warn(
"EAP: malformed Lightweight rechallenge");
1696 SHA1Update(&ctxt, vals, 1);
1697 SHA1Update(&ctxt, pcb->eap.es_client.ea_skey,
1699 SHA1Update(&ctxt, inp, len);
1700 SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1701 pcb->eap.es_client.ea_namelen);
1702 SHA1Final(dig, &ctxt);
1703 eap_srp_response(esp,
id, EAPSRP_LWRECHALLENGE, dig,
1708 ppp_error(
"EAP: unknown SRP Subtype %d", vallen);
1709 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1716 ppp_info(
"EAP: unknown authentication type %d; Naking", typenum);
1717 eap_send_nak(pcb,
id, EAPT_SRP);
1721 if (pcb->settings.eap_req_time > 0) {
1722 UNTIMEOUT(eap_client_timeout, pcb);
1723 TIMEOUT(eap_client_timeout, pcb,
1724 pcb->settings.eap_req_time);
1730 pcb->eap.es_client.ea_state = eapBadAuth;
1731 if (pcb->settings.eap_req_time > 0) {
1732 UNTIMEOUT(eap_client_timeout, (
void *)esp);
1734 pcb->eap.es_client.ea_session = NULL;
1736 auth_withpeer_fail(pcb, PPP_EAP);
1744 static void eap_response(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
1748 char secret[MAXSECRETLEN];
1749 char rhostname[MAXNAMELEN];
1750 lwip_md5_context mdContext;
1751 u_char hash[MD5_SIGNATURE_SIZE];
1753 struct t_server *ts;
1756 u_char dig[SHA_DIGESTSIZE];
1759 if (pcb->eap.es_server.ea_id !=
id) {
1760 ppp_dbglog(
"EAP: discarding Response %d; expected ID %d",
id,
1761 pcb->eap.es_server.ea_id);
1765 pcb->eap.es_server.ea_responses++;
1768 ppp_error(
"EAP: empty Response message discarded");
1772 GETCHAR(typenum, inp);
1777 if (pcb->eap.es_server.ea_state != eapIdentify) {
1778 ppp_dbglog(
"EAP discarding unwanted Identify \"%.q\"", len,
1782 ppp_info(
"EAP: unauthenticated peer name \"%.*q\"", len, inp);
1783 if (len > MAXNAMELEN) {
1786 MEMCPY(pcb->eap.es_server.ea_peer, inp, len);
1787 pcb->eap.es_server.ea_peer[len] =
'\0';
1788 pcb->eap.es_server.ea_peerlen = len;
1789 eap_figure_next_state(pcb, 0);
1792 case EAPT_NOTIFICATION:
1793 ppp_dbglog(
"EAP unexpected Notification; response discarded");
1798 ppp_info(
"EAP: Nak Response with no suggested protocol");
1799 eap_figure_next_state(pcb, 1);
1803 GETCHAR(vallen, inp);
1808 !pcb->explicit_remote &&
1810 pcb->eap.es_server.ea_state == eapIdentify){
1812 eap_figure_next_state(pcb, 1);
1819 pcb->eap.es_server.ea_state = eapIdentify;
1820 eap_figure_next_state(pcb, 0);
1824 pcb->eap.es_server.ea_state = eapMD5Chall;
1828 ppp_dbglog(
"EAP: peer requesting unknown Type %d", vallen);
1829 switch (pcb->eap.es_server.ea_state) {
1833 pcb->eap.es_server.ea_state = eapMD5Chall;
1837 pcb->eap.es_server.ea_state = eapIdentify;
1838 eap_figure_next_state(pcb, 0);
1848 if (pcb->eap.es_server.ea_state != eapMD5Chall) {
1849 ppp_error(
"EAP: unexpected MD5-Response");
1850 eap_figure_next_state(pcb, 1);
1854 ppp_error(
"EAP: received MD5-Response with no data");
1855 eap_figure_next_state(pcb, 1);
1858 GETCHAR(vallen, inp);
1860 if (vallen != 16 || vallen > len) {
1861 ppp_error(
"EAP: MD5-Response with bad length %d", vallen);
1862 eap_figure_next_state(pcb, 1);
1867 if (vallen >= len +
sizeof (rhostname)) {
1868 ppp_dbglog(
"EAP: trimming really long peer name down");
1869 MEMCPY(rhostname, inp + vallen,
sizeof (rhostname) - 1);
1870 rhostname[
sizeof (rhostname) - 1] =
'\0';
1872 MEMCPY(rhostname, inp + vallen, len - vallen);
1873 rhostname[len - vallen] =
'\0';
1878 if (explicit_remote ||
1879 (remote_name[0] !=
'\0' && vallen == len))
1880 strlcpy(rhostname, remote_name,
sizeof (rhostname));
1887 if (!get_secret(pcb, rhostname,
1888 pcb->eap.es_server.ea_name, secret, &secret_len, 1)) {
1889 ppp_dbglog(
"EAP: no MD5 secret for auth of %q", rhostname);
1890 eap_send_failure(pcb);
1893 lwip_md5_init(&mdContext);
1894 lwip_md5_starts(&mdContext);
1895 lwip_md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1);
1896 lwip_md5_update(&mdContext, (u_char *)secret, secret_len);
1897 BZERO(secret,
sizeof (secret));
1898 lwip_md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen);
1899 lwip_md5_finish(&mdContext, hash);
1900 lwip_md5_free(&mdContext);
1901 if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) {
1902 eap_send_failure(pcb);
1905 pcb->eap.es_server.ea_type = EAPT_MD5CHAP;
1906 eap_send_success(pcb);
1907 eap_figure_next_state(pcb, 0);
1908 if (pcb->eap.es_rechallenge != 0)
1909 TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge);
1915 ppp_error(
"EAP: empty SRP Response");
1916 eap_figure_next_state(pcb, 1);
1919 GETCHAR(typenum, inp);
1923 if (pcb->eap.es_server.ea_state != eapSRP1) {
1924 ppp_error(
"EAP: unexpected SRP Subtype 1 Response");
1925 eap_figure_next_state(pcb, 1);
1930 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
1932 pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A);
1933 if (pcb->eap.es_server.ea_skey == NULL) {
1935 ppp_error(
"EAP: bogus A value from client");
1936 eap_send_failure(pcb);
1938 eap_figure_next_state(pcb, 0);
1942 case EAPSRP_CVALIDATOR:
1943 if (pcb->eap.es_server.ea_state != eapSRP2) {
1944 ppp_error(
"EAP: unexpected SRP Subtype 2 Response");
1945 eap_figure_next_state(pcb, 1);
1948 if (len <
sizeof (u32_t) + SHA_DIGESTSIZE) {
1949 ppp_error(
"EAP: M1 length %d < %d", len,
1950 sizeof (u32_t) + SHA_DIGESTSIZE);
1951 eap_figure_next_state(pcb, 1);
1954 GETLONG(pcb->eap.es_server.ea_keyflags, inp);
1955 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
1957 if (t_serververify(ts, inp)) {
1958 ppp_info(
"EAP: unable to validate client identity");
1959 eap_send_failure(pcb);
1962 eap_figure_next_state(pcb, 0);
1966 if (pcb->eap.es_server.ea_state != eapSRP3) {
1967 ppp_error(
"EAP: unexpected SRP Subtype 3 Response");
1968 eap_send_failure(esp);
1971 pcb->eap.es_server.ea_type = EAPT_SRP;
1972 eap_send_success(pcb, esp);
1973 eap_figure_next_state(pcb, 0);
1974 if (pcb->eap.es_rechallenge != 0)
1975 TIMEOUT(eap_rechallenge, pcb,
1976 pcb->eap.es_rechallenge);
1977 if (pcb->eap.es_lwrechallenge != 0)
1978 TIMEOUT(srp_lwrechallenge, pcb,
1979 pcb->eap.es_lwrechallenge);
1982 case EAPSRP_LWRECHALLENGE:
1983 if (pcb->eap.es_server.ea_state != eapSRP4) {
1984 ppp_info(
"EAP: unexpected SRP Subtype 4 Response");
1987 if (len != SHA_DIGESTSIZE) {
1988 ppp_error(
"EAP: bad Lightweight rechallenge " 1994 SHA1Update(&ctxt, &vallen, 1);
1995 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
1997 SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen);
1998 SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
1999 pcb->eap.es_server.ea_peerlen);
2000 SHA1Final(dig, &ctxt);
2001 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
2002 ppp_error(
"EAP: failed Lightweight rechallenge");
2003 eap_send_failure(pcb);
2006 pcb->eap.es_server.ea_state = eapOpen;
2007 if (pcb->eap.es_lwrechallenge != 0)
2008 TIMEOUT(srp_lwrechallenge, esp,
2009 pcb->eap.es_lwrechallenge);
2017 ppp_error(
"EAP: unknown Response type %d; ignored", typenum);
2021 if (pcb->settings.eap_timeout_time > 0) {
2022 UNTIMEOUT(eap_server_timeout, pcb);
2025 if (pcb->eap.es_server.ea_state != eapBadAuth &&
2026 pcb->eap.es_server.ea_state != eapOpen) {
2027 pcb->eap.es_server.ea_id++;
2028 eap_send_request(pcb);
2036 static void eap_success(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
2039 if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) {
2040 ppp_dbglog(
"EAP unexpected success message in state %s (%d)",
2041 eap_state_name(pcb->eap.es_client.ea_state),
2042 pcb->eap.es_client.ea_state);
2046 if (pcb->settings.eap_req_time > 0) {
2047 UNTIMEOUT(eap_client_timeout, pcb);
2055 pcb->eap.es_client.ea_state = eapOpen;
2056 auth_withpeer_success(pcb, PPP_EAP, 0);
2062 static void eap_failure(ppp_pcb *pcb, u_char *inp,
int id,
int len) {
2065 if (!eap_client_active(pcb)) {
2066 ppp_dbglog(
"EAP unexpected failure message in state %s (%d)",
2067 eap_state_name(pcb->eap.es_client.ea_state),
2068 pcb->eap.es_client.ea_state);
2071 if (pcb->settings.eap_req_time > 0) {
2072 UNTIMEOUT(eap_client_timeout, pcb);
2080 pcb->eap.es_client.ea_state = eapBadAuth;
2082 ppp_error(
"EAP: peer reports authentication failure");
2083 auth_withpeer_fail(pcb, PPP_EAP);
2089 static void eap_input(ppp_pcb *pcb, u_char *inp,
int inlen) {
2097 if (inlen < EAP_HEADERLEN) {
2098 ppp_error(
"EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN);
2104 if (len < EAP_HEADERLEN || len > inlen) {
2105 ppp_error(
"EAP: packet has illegal length field %d (%d..%d)", len,
2106 EAP_HEADERLEN, inlen);
2109 len -= EAP_HEADERLEN;
2114 eap_request(pcb, inp,
id, len);
2119 eap_response(pcb, inp,
id, len);
2124 eap_success(pcb, inp,
id, len);
2128 eap_failure(pcb, inp,
id, len);
2133 ppp_warn(
"EAP: unknown code %d received", code);
2138 #if PRINTPKT_SUPPORT 2142 static const char*
const eap_codenames[] = {
2143 "Request",
"Response",
"Success",
"Failure" 2146 static const char*
const eap_typenames[] = {
2147 "Identity",
"Notification",
"Nak",
"MD5-Challenge",
2148 "OTP",
"Generic-Token", NULL, NULL,
2149 "RSA",
"DSS",
"KEA",
"KEA-Validate",
2150 "TLS",
"Defender",
"Windows 2000",
"Arcot",
2151 "Cisco",
"Nokia",
"SRP" 2154 static int eap_printpkt(
const u_char *inp,
int inlen,
void (*printer) (
void *,
const char *, ...),
void *arg) {
2155 int code, id, len, rtype, vallen;
2156 const u_char *pstart;
2159 if (inlen < EAP_HEADERLEN)
2165 if (len < EAP_HEADERLEN || len > inlen)
2168 if (code >= 1 && code <= (
int)LWIP_ARRAYSIZE(eap_codenames))
2169 printer(arg,
" %s", eap_codenames[code-1]);
2171 printer(arg,
" code=0x%x", code);
2172 printer(arg,
" id=0x%x",
id);
2173 len -= EAP_HEADERLEN;
2177 printer(arg,
" <missing type>");
2180 GETCHAR(rtype, inp);
2182 if (rtype >= 1 && rtype <= (
int)LWIP_ARRAYSIZE(eap_typenames))
2183 printer(arg,
" %s", eap_typenames[rtype-1]);
2185 printer(arg,
" type=0x%x", rtype);
2188 case EAPT_NOTIFICATION:
2190 printer(arg,
" <Message ");
2191 ppp_print_string(inp, len, printer, arg);
2196 printer(arg,
" <No message>");
2203 GETCHAR(vallen, inp);
2207 printer(arg,
" <Value%.*B>", vallen, inp);
2208 INCPTR(vallen, inp);
2211 printer(arg,
" <Name ");
2212 ppp_print_string(inp, len, printer, arg);
2217 printer(arg,
" <No name>");
2224 GETCHAR(vallen, inp);
2226 printer(arg,
"-%d", vallen);
2228 case EAPSRP_CHALLENGE:
2229 GETCHAR(vallen, inp);
2234 printer(arg,
" <Name ");
2235 ppp_print_string(inp, vallen, printer,
2239 printer(arg,
" <No name>");
2241 INCPTR(vallen, inp);
2243 GETCHAR(vallen, inp);
2247 printer(arg,
" <s%.*B>", vallen, inp);
2248 INCPTR(vallen, inp);
2250 GETCHAR(vallen, inp);
2255 printer(arg,
" <Default g=2>");
2257 printer(arg,
" <g%.*B>", vallen, inp);
2259 INCPTR(vallen, inp);
2262 printer(arg,
" <Default N>");
2264 printer(arg,
" <N%.*B>", len, inp);
2271 printer(arg,
" <B%.*B>", len, inp);
2276 case EAPSRP_SVALIDATOR:
2277 if (len < (
int)
sizeof (u32_t))
2280 len -=
sizeof (u32_t);
2281 if (uval & SRPVAL_EBIT) {
2283 uval &= ~SRPVAL_EBIT;
2286 printer(arg,
" f<%X>", uval);
2288 if ((vallen = len) > SHA_DIGESTSIZE)
2289 vallen = SHA_DIGESTSIZE;
2290 printer(arg,
" <M2%.*B%s>", len, inp,
2291 len < SHA_DIGESTSIZE ?
"?" :
"");
2292 INCPTR(vallen, inp);
2295 printer(arg,
" <PN%.*B>", len, inp);
2301 case EAPSRP_LWRECHALLENGE:
2302 printer(arg,
" <Challenge%.*B>", len, inp);
2318 GETCHAR(rtype, inp);
2320 if (rtype >= 1 && rtype <= (
int)LWIP_ARRAYSIZE(eap_typenames))
2321 printer(arg,
" %s", eap_typenames[rtype-1]);
2323 printer(arg,
" type=0x%x", rtype);
2327 printer(arg,
" <Name ");
2328 ppp_print_string(inp, len, printer, arg);
2337 printer(arg,
" <missing hint>");
2340 GETCHAR(rtype, inp);
2342 printer(arg,
" <Suggested-type %02X", rtype);
2343 if (rtype >= 1 && rtype < (
int)LWIP_ARRAYSIZE(eap_typenames))
2344 printer(arg,
" (%s)", eap_typenames[rtype-1]);
2350 printer(arg,
" <missing length>");
2353 GETCHAR(vallen, inp);
2357 printer(arg,
" <Value%.*B>", vallen, inp);
2358 INCPTR(vallen, inp);
2361 printer(arg,
" <Name ");
2362 ppp_print_string(inp, len, printer, arg);
2367 printer(arg,
" <No name>");
2374 GETCHAR(vallen, inp);
2376 printer(arg,
"-%d", vallen);
2379 printer(arg,
" <A%.*B>", len, inp);
2384 case EAPSRP_CVALIDATOR:
2385 if (len < (
int)
sizeof (u32_t))
2388 len -=
sizeof (u32_t);
2389 if (uval & SRPVAL_EBIT) {
2391 uval &= ~SRPVAL_EBIT;
2394 printer(arg,
" f<%X>", uval);
2396 printer(arg,
" <M1%.*B%s>", len, inp,
2397 len == SHA_DIGESTSIZE ?
"" :
"?");
2405 case EAPSRP_LWRECHALLENGE:
2406 printer(arg,
" <Response%.*B%s>", len, inp,
2407 len == SHA_DIGESTSIZE ?
"" :
"?");
2408 if ((vallen = len) > SHA_DIGESTSIZE)
2409 vallen = SHA_DIGESTSIZE;
2410 INCPTR(vallen, inp);
2428 printer(arg,
" <truncated>");
2433 printer(arg,
"%8B...", inp);
2435 printer(arg,
"%.*B", len, inp);
2438 return (inp - pstart);
void pbuf_realloc(struct pbuf *p, u16_t new_len)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define LWIP_UNUSED_ARG(x)
u8_t pbuf_free(struct pbuf *p)