47#if PPP_SUPPORT && EAP_SUPPORT
61#define SHA_DIGESTSIZE 20
65static char *pn_secret =
NULL;
72static option_t eap_option_list[] = {
73 {
"eap-restart", o_int, &eap_states[0].es_server.ea_timeout,
74 "Set retransmit timeout for EAP Requests (server)" },
75 {
"eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests,
76 "Set max number of EAP Requests sent (server)" },
77 {
"eap-timeout", o_int, &eap_states[0].es_client.ea_timeout,
78 "Set time limit for peer EAP authentication" },
79 {
"eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests,
80 "Set max number of EAP Requests allows (client)" },
81 {
"eap-interval", o_int, &eap_states[0].es_rechallenge,
82 "Set interval for EAP rechallenge" },
84 {
"srp-interval", o_int, &eap_states[0].es_lwrechallenge,
85 "Set interval for SRP lightweight rechallenge" },
86 {
"srp-pn-secret", o_string, &pn_secret,
87 "Long term pseudonym generation secret" },
88 {
"srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo,
89 "Use pseudonym if offered one by server", 1 },
98static void eap_init(ppp_pcb *pcb);
99static void eap_input(ppp_pcb *pcb,
u_char *inp,
int inlen);
100static void eap_protrej(ppp_pcb *pcb);
101static void eap_lowerup(ppp_pcb *pcb);
102static void eap_lowerdown(ppp_pcb *pcb);
104static int eap_printpkt(
const u_char *inp,
int inlen,
105 void (*)(
void *
arg,
const char *
fmt, ...),
void *
arg);
108const struct protent eap_protent = {
141static const u_char wkmodulus[] = {
142 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
143 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
144 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
145 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
146 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
147 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
148 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
149 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
150 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
151 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
152 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
153 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
154 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
155 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
156 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
157 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
158 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
159 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
160 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
161 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
162 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
163 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
164 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
165 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
166 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
167 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
168 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
169 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
170 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
171 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
172 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
173 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
179static void eap_server_timeout(
void *
arg);
185static const char * eap_state_name(
enum eap_state_code esc)
187 static const char *state_names[] = { EAP_STATES };
189 return (state_names[(
int)esc]);
196static void eap_init(ppp_pcb *pcb) {
198 BZERO(&pcb->eap,
sizeof(eap_state));
200 pcb->eap.es_server.ea_id = magic();
208static void eap_client_timeout(
void *
arg) {
209 ppp_pcb *pcb = (ppp_pcb*)
arg;
211 if (!eap_client_active(pcb))
214 ppp_error((
"EAP: timeout waiting for Request from peer"));
215 auth_withpeer_fail(pcb, PPP_EAP);
216 pcb->eap.es_client.ea_state = eapBadAuth;
225void eap_authwithpeer(ppp_pcb *pcb,
const char *localname) {
227 if(
NULL == localname)
231 pcb->eap.es_client.ea_name = localname;
232 pcb->eap.es_client.ea_namelen =
strlen(localname);
234 pcb->eap.es_client.ea_state = eapListen;
240 if (pcb->settings.eap_req_time > 0)
241 TIMEOUT(eap_client_timeout, pcb,
242 pcb->settings.eap_req_time);
250static void eap_send_failure(ppp_pcb *pcb) {
257 if(
p->tot_len !=
p->len) {
264 MAKEHEADER(outp, PPP_EAP);
266 PUTCHAR(EAP_FAILURE, outp);
267 pcb->eap.es_server.ea_id++;
268 PUTCHAR(pcb->eap.es_server.ea_id, outp);
269 PUTSHORT(EAP_HEADERLEN, outp);
273 pcb->eap.es_server.ea_state = eapBadAuth;
274 auth_peer_fail(pcb, PPP_EAP);
281static void eap_send_success(ppp_pcb *pcb) {
288 if(
p->tot_len !=
p->len) {
295 MAKEHEADER(outp, PPP_EAP);
297 PUTCHAR(EAP_SUCCESS, outp);
298 pcb->eap.es_server.ea_id++;
299 PUTCHAR(pcb->eap.es_server.ea_id, outp);
300 PUTSHORT(EAP_HEADERLEN, outp);
304 auth_peer_success(pcb, PPP_EAP, 0,
305 pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen);
315pncrypt_setkey(
int timeoffs)
320 u_char dig[SHA_DIGESTSIZE];
323 if (pn_secret ==
NULL)
328 SHA1Update(&ctxt, pn_secret,
strlen(pn_secret));
330 SHA1Update(&ctxt, tbuf,
strlen(tbuf));
331 SHA1Final(dig, &ctxt);
333 return (DesSetkey(dig));
336static char base64[] =
337"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
345b64enc(
bs, inp, inlen, outp)
354 bs->bs_bits = (
bs->bs_bits << 8) | *inp++;
357 if (
bs->bs_offs >= 24) {
358 *outp++ = base64[(
bs->bs_bits >> 18) & 0x3F];
359 *outp++ = base64[(
bs->bs_bits >> 12) & 0x3F];
360 *outp++ = base64[(
bs->bs_bits >> 6) & 0x3F];
361 *outp++ = base64[
bs->bs_bits & 0x3F];
377 if (
bs->bs_offs == 8) {
378 *outp++ = base64[(
bs->bs_bits >> 2) & 0x3F];
379 *outp++ = base64[(
bs->bs_bits << 4) & 0x3F];
381 }
else if (
bs->bs_offs == 16) {
382 *outp++ = base64[(
bs->bs_bits >> 10) & 0x3F];
383 *outp++ = base64[(
bs->bs_bits >> 4) & 0x3F];
384 *outp++ = base64[(
bs->bs_bits << 2) & 0x3F];
393b64dec(
bs, inp, inlen, outp)
405 bs->bs_bits = (
bs->bs_bits << 6) | (
cp - base64);
408 if (
bs->bs_offs >= 8) {
409 *outp++ =
bs->bs_bits >> (
bs->bs_offs - 8);
425static void eap_figure_next_state(ppp_pcb *pcb,
int status) {
427 unsigned char secbuf[MAXSECRETLEN], clear[8], *
sp, *dp;
429 struct t_confent *tce, mytce;
432 int id,
i, plen, toffs;
437 pcb->settings.eap_timeout_time = pcb->eap.es_savedtime;
438 switch (pcb->eap.es_server.ea_state) {
445 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
448 pcb->eap.es_server.ea_session =
NULL;
449 pcb->eap.es_server.ea_skey =
NULL;
453 pcb->eap.es_server.ea_state = eapBadAuth;
458 if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN &&
459 strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID,
460 SRP_PSEUDO_LEN) == 0 &&
461 (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 <
463 BZERO(&
bs,
sizeof (
bs));
465 pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN,
466 pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN,
469 for (
i = 0;
i < 5;
i++) {
470 pncrypt_setkey(toffs);
473 if (!DesDecrypt(secbuf, clear)) {
474 ppp_dbglog((
"no DES here; cannot decode "
478 id = *(
unsigned char *)clear;
479 if (
id + 1 <= plen &&
id + 9 > plen)
482 if (plen % 8 == 0 &&
i < 5) {
488 if ((
i = plen = *(
unsigned char *)clear) > 7)
490 pcb->eap.es_server.ea_peerlen = plen;
491 dp = (
unsigned char *)pcb->eap.es_server.ea_peer;
498 (
void) DesDecrypt(
sp, dp);
503 pcb->eap.es_server.ea_peer[
504 pcb->eap.es_server.ea_peerlen] =
'\0';
505 ppp_dbglog((
"decoded pseudonym to \"%.*q\"",
506 pcb->eap.es_server.ea_peerlen,
507 pcb->eap.es_server.ea_peer));
509 ppp_dbglog((
"failed to decode real name"));
515 if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer,
516 pcb->eap.es_server.ea_name, (
char *)secbuf, 1) != 0) {
518 pcb->eap.es_server.ea_state = eapMD5Chall;
520 id =
strtol((
char *)secbuf, &
cp, 10);
521 if (*
cp++ !=
':' ||
id < 0)
525 mytce.modulus.data = (
u_char *)wkmodulus;
526 mytce.modulus.len =
sizeof (wkmodulus);
527 mytce.generator.data = (
u_char *)
"\002";
528 mytce.generator.len = 1;
530 }
else if ((tce = gettcid(
id)) !=
NULL) {
536 if (pcb->settings.eap_timeout_time > 0 &&
537 pcb->settings.eap_timeout_time < 30)
538 pcb->settings.eap_timeout_time = 30;
545 tpw.pebuf.name = pcb->eap.es_server.ea_peer;
546 tpw.pebuf.password.len = t_fromb64((
char *)tpw.pwbuf,
548 tpw.pebuf.password.data = tpw.pwbuf;
549 tpw.pebuf.salt.len = t_fromb64((
char *)tpw.saltbuf,
551 tpw.pebuf.salt.data = tpw.saltbuf;
552 if ((ts = t_serveropenraw(&tpw.pebuf, tce)) ==
NULL)
554 pcb->eap.es_server.ea_session = (
void *)ts;
555 pcb->eap.es_server.ea_state = eapSRP1;
556 vals[0] = pcb->eap.es_server.ea_id + 1;
558 t_serveraddexdata(ts, vals, 2);
564 pcb->eap.es_server.ea_state = eapMD5Chall;
569 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
572 pcb->eap.es_server.ea_session =
NULL;
573 pcb->eap.es_server.ea_skey =
NULL;
577 pcb->eap.es_server.ea_state = eapMD5Chall;
578 }
else if (
status != 0 || pcb->eap.es_server.ea_session ==
NULL) {
579 pcb->eap.es_server.ea_state = eapBadAuth;
581 pcb->eap.es_server.ea_state = eapSRP2;
587 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
590 pcb->eap.es_server.ea_session =
NULL;
591 pcb->eap.es_server.ea_skey =
NULL;
594 if (
status != 0 || pcb->eap.es_server.ea_session ==
NULL) {
595 pcb->eap.es_server.ea_state = eapBadAuth;
597 pcb->eap.es_server.ea_state = eapSRP3;
604 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
607 pcb->eap.es_server.ea_session =
NULL;
608 pcb->eap.es_server.ea_skey =
NULL;
611 if (
status != 0 || pcb->eap.es_server.ea_session ==
NULL) {
612 pcb->eap.es_server.ea_state = eapBadAuth;
614 pcb->eap.es_server.ea_state = eapOpen;
620 pcb->eap.es_server.ea_state = eapBadAuth;
622 pcb->eap.es_server.ea_state = eapOpen;
627 pcb->eap.es_server.ea_state = eapBadAuth;
630 if (pcb->eap.es_server.ea_state == eapBadAuth)
631 eap_send_failure(pcb);
638static void eap_send_request(ppp_pcb *pcb) {
654 if (pcb->eap.es_server.ea_state < eapIdentify &&
655 pcb->eap.es_server.ea_state != eapInitial) {
656 pcb->eap.es_server.ea_state = eapIdentify;
658 if (pcb->settings.explicit_remote && pcb->remote_name) {
668 MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name,
len);
669 pcb->eap.es_server.ea_peer[
len] =
'\0';
670 pcb->eap.es_server.ea_peerlen =
len;
671 eap_figure_next_state(pcb, 0);
676 if (pcb->settings.eap_max_transmits > 0 &&
677 pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) {
678 if (pcb->eap.es_server.ea_responses > 0)
679 ppp_error((
"EAP: too many Requests sent"));
681 ppp_error((
"EAP: no response to Requests"));
682 eap_send_failure(pcb);
689 if(
p->tot_len !=
p->len) {
696 MAKEHEADER(outp, PPP_EAP);
698 PUTCHAR(EAP_REQUEST, outp);
699 PUTCHAR(pcb->eap.es_server.ea_id, outp);
703 switch (pcb->eap.es_server.ea_state) {
705 PUTCHAR(EAPT_IDENTITY, outp);
713 PUTCHAR(EAPT_MD5CHAP, outp);
718 pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
719 magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
720 PUTCHAR(pcb->eap.es_challen, outp);
721 magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
722 MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
723 INCPTR(pcb->eap.es_challen, outp);
724 MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
725 INCPTR(pcb->eap.es_server.ea_namelen, outp);
730 PUTCHAR(EAPT_SRP, outp);
731 PUTCHAR(EAPSRP_CHALLENGE, outp);
733 PUTCHAR(pcb->eap.es_server.ea_namelen, outp);
734 MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen);
735 INCPTR(pcb->eap.es_server.ea_namelen, outp);
737 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
739 PUTCHAR(ts->s.len, outp);
740 MEMCPY(outp, ts->s.data, ts->s.len);
741 INCPTR(ts->s.len, outp);
743 if (ts->g.len == 1 && ts->g.data[0] == 2) {
746 PUTCHAR(ts->g.len, outp);
747 MEMCPY(outp, ts->g.data, ts->g.len);
748 INCPTR(ts->g.len, outp);
751 if (ts->n.len !=
sizeof (wkmodulus) ||
752 BCMP(ts->n.data, wkmodulus,
sizeof (wkmodulus)) != 0) {
753 MEMCPY(outp, ts->n.data, ts->n.len);
754 INCPTR(ts->n.len, outp);
759 PUTCHAR(EAPT_SRP, outp);
760 PUTCHAR(EAPSRP_SKEY, outp);
762 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
764 MEMCPY(outp, ts->B.data, ts->B.len);
765 INCPTR(ts->B.len, outp);
769 PUTCHAR(EAPT_SRP, outp);
770 PUTCHAR(EAPSRP_SVALIDATOR, outp);
771 PUTLONG(SRPVAL_EBIT, outp);
772 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
774 MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE);
775 INCPTR(SHA_DIGESTSIZE, outp);
777 if (pncrypt_setkey(0)) {
780 cp = (
unsigned char *)pcb->eap.es_server.ea_peer;
781 if ((
j =
i = pcb->eap.es_server.ea_peerlen) > 7)
788 if (!DesEncrypt(clear,
cipher)) {
789 ppp_dbglog((
"no DES here; not generating pseudonym"));
792 BZERO(&
b64,
sizeof (
b64));
805 magic_random_bytes(
cp, 8-
i);
810 outp += b64flush(&
b64, outp);
817 magic_random_bytes(outp, SHA_DIGESTSIZE-
i);
818 INCPTR(SHA_DIGESTSIZE-
i, outp);
823 SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
824 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
826 SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
827 pcb->eap.es_server.ea_peerlen);
828 while (optr < outp) {
829 SHA1Final(dig, &ctxt);
831 while (
cp < dig + SHA_DIGESTSIZE)
834 SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1);
835 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
837 SHA1Update(&ctxt, optr - SHA_DIGESTSIZE,
844 PUTCHAR(EAPT_SRP, outp);
845 PUTCHAR(EAPSRP_LWRECHALLENGE, outp);
846 pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH +
847 magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH);
848 magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen);
849 MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen);
850 INCPTR(pcb->eap.es_challen, outp);
858 outlen = (outp - (
unsigned char*)
p->payload) - PPP_HDRLEN;
859 PUTSHORT(outlen, lenloc);
864 pcb->eap.es_server.ea_requests++;
866 if (pcb->settings.eap_timeout_time > 0)
867 TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time);
876void eap_authpeer(ppp_pcb *pcb,
const char *localname) {
879 pcb->eap.es_server.ea_name = localname;
880 pcb->eap.es_server.ea_namelen =
strlen(localname);
882 pcb->eap.es_savedtime = pcb->settings.eap_timeout_time;
885 if (pcb->eap.es_server.ea_state == eapInitial ||
886 pcb->eap.es_server.ea_state == eapPending) {
887 pcb->eap.es_server.ea_state = eapPending;
891 pcb->eap.es_server.ea_state = eapPending;
894 eap_send_request(pcb);
901static void eap_server_timeout(
void *
arg) {
902 ppp_pcb *pcb = (ppp_pcb*)
arg;
904 if (!eap_server_active(pcb))
908 eap_send_request(pcb);
916static void eap_rechallenge(
void *
arg) {
917 ppp_pcb *pcb = (ppp_pcb*)
arg;
919 if (pcb->eap.es_server.ea_state != eapOpen &&
920 pcb->eap.es_server.ea_state != eapSRP4)
923 pcb->eap.es_server.ea_requests = 0;
924 pcb->eap.es_server.ea_state = eapIdentify;
925 eap_figure_next_state(pcb, 0);
926 pcb->eap.es_server.ea_id++;
927 eap_send_request(pcb);
930static void srp_lwrechallenge(
void *
arg) {
931 ppp_pcb *pcb = (ppp_pcb*)
arg;
933 if (pcb->eap.es_server.ea_state != eapOpen ||
934 pcb->eap.es_server.ea_type != EAPT_SRP)
937 pcb->eap.es_server.ea_requests = 0;
938 pcb->eap.es_server.ea_state = eapSRP4;
939 pcb->eap.es_server.ea_id++;
940 eap_send_request(pcb);
952static void eap_lowerup(ppp_pcb *pcb) {
953 pcb->eap.es_client.ea_state = eapClosed;
955 pcb->eap.es_server.ea_state = eapClosed;
964static void eap_lowerdown(ppp_pcb *pcb) {
966 if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) {
967 UNTIMEOUT(eap_client_timeout, pcb);
970 if (eap_server_active(pcb)) {
971 if (pcb->settings.eap_timeout_time > 0) {
972 UNTIMEOUT(eap_server_timeout, pcb);
975 if ((pcb->eap.es_server.ea_state == eapOpen ||
976 pcb->eap.es_server.ea_state == eapSRP4) &&
977 pcb->eap.es_rechallenge > 0) {
978 UNTIMEOUT(eap_rechallenge, (
void *)pcb);
980 if (pcb->eap.es_server.ea_state == eapOpen &&
981 pcb->eap.es_lwrechallenge > 0) {
982 UNTIMEOUT(srp_lwrechallenge, (
void *)pcb);
986 pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial;
987 pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0;
997static void eap_protrej(ppp_pcb *pcb) {
999 if (eap_client_active(pcb)) {
1000 ppp_error((
"EAP authentication failed due to Protocol-Reject"));
1001 auth_withpeer_fail(pcb, PPP_EAP);
1004 if (eap_server_active(pcb)) {
1005 ppp_error((
"EAP authentication of peer failed on Protocol-Reject"));
1006 auth_peer_fail(pcb, PPP_EAP);
1015static void eap_send_response(ppp_pcb *pcb,
u_char id,
u_char typenum,
const u_char *
str,
int lenstr) {
1020 msglen = EAP_HEADERLEN +
sizeof (
u_char) + lenstr;
1024 if(
p->tot_len !=
p->len) {
1031 MAKEHEADER(outp, PPP_EAP);
1033 PUTCHAR(EAP_RESPONSE, outp);
1035 pcb->eap.es_client.ea_id =
id;
1036 PUTSHORT(msglen, outp);
1037 PUTCHAR(typenum, outp);
1053 msglen = EAP_HEADERLEN + 2 *
sizeof (
u_char) + MD5_SIGNATURE_SIZE +
1058 if(
p->tot_len !=
p->len) {
1065 MAKEHEADER(outp, PPP_EAP);
1067 PUTCHAR(EAP_RESPONSE, outp);
1069 pcb->eap.es_client.ea_id =
id;
1070 PUTSHORT(msglen, outp);
1071 PUTCHAR(EAPT_MD5CHAP, outp);
1072 PUTCHAR(MD5_SIGNATURE_SIZE, outp);
1074 INCPTR(MD5_SIGNATURE_SIZE, outp);
1087eap_srp_response(esp,
id, subtypenum,
str, lenstr)
1094 ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1099 msglen = EAP_HEADERLEN + 2 *
sizeof (
u_char) + lenstr;
1103 if(
p->tot_len !=
p->len) {
1110 MAKEHEADER(outp, PPP_EAP);
1112 PUTCHAR(EAP_RESPONSE, outp);
1114 pcb->eap.es_client.ea_id =
id;
1115 PUTSHORT(msglen, outp);
1116 PUTCHAR(EAPT_SRP, outp);
1117 PUTCHAR(subtypenum, outp);
1129eap_srpval_response(esp,
id,
flags,
str)
1135 ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit];
1140 msglen = EAP_HEADERLEN + 2 *
sizeof (
u_char) +
sizeof (
u32_t) +
1145 if(
p->tot_len !=
p->len) {
1152 MAKEHEADER(outp, PPP_EAP);
1154 PUTCHAR(EAP_RESPONSE, outp);
1156 pcb->eap.es_client.ea_id =
id;
1157 PUTSHORT(msglen, outp);
1158 PUTCHAR(EAPT_SRP, outp);
1159 PUTCHAR(EAPSRP_CVALIDATOR, outp);
1160 PUTLONG(
flags, outp);
1172 msglen = EAP_HEADERLEN + 2 *
sizeof (
u_char);
1176 if(
p->tot_len !=
p->len) {
1183 MAKEHEADER(outp, PPP_EAP);
1185 PUTCHAR(EAP_RESPONSE, outp);
1187 pcb->eap.es_client.ea_id =
id;
1188 PUTSHORT(msglen, outp);
1189 PUTCHAR(EAPT_NAK, outp);
1190 PUTCHAR(
type, outp);
1202 static bool pnlogged = 0;
1209 file = _PATH_PSEUDONYM;
1216 ppp_dbglog((
"pseudonym file: %s",
path));
1223open_pn_file(modebits)
1229 if ((
path = name_of_pn_file()) ==
NULL)
1243 if ((
path = name_of_pn_file()) !=
NULL) {
1250write_pseudonym(esp, inp,
len,
id)
1258 u_char dig[SHA_DIGESTSIZE];
1259 int dsize,
fd, olen =
len;
1267 if ((dsize =
len % SHA_DIGESTSIZE) == 0)
1268 dsize = SHA_DIGESTSIZE;
1272 SHA1Update(&ctxt, &
val, 1);
1273 SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN);
1275 SHA1Update(&ctxt, datp, SHA_DIGESTSIZE);
1277 SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1278 pcb->eap.es_client.ea_namelen);
1280 SHA1Final(dig, &ctxt);
1281 for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++)
1286 if (olen <= 0 || *inp + 1 > olen) {
1287 ppp_dbglog((
"EAP: decoded pseudonym is unusable <%.*B>", olen, inp));
1294 ppp_dbglog((
"EAP: error saving pseudonym: %m"));
1299 ppp_dbglog((
"EAP: saved pseudonym"));
1300 pcb->eap.es_usedpseudo = 0;
1302 ppp_dbglog((
"EAP: failed to save pseudonym"));
1311static void eap_request(ppp_pcb *pcb,
u_char *inp,
int id,
int len) {
1315 char secret[MAXSECRETLEN];
1317 lwip_md5_context mdContext;
1320 struct t_client *
tc;
1321 struct t_num sval,
gval, Nval, *
Ap, Bval;
1324 u_char dig[SHA_DIGESTSIZE];
1331 if (pcb->eap.es_client.ea_state <= eapClosed)
1340 pcb->eap.es_client.ea_requests++;
1341 if (pcb->settings.eap_allow_req != 0 &&
1342 pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) {
1343 ppp_info((
"EAP: received too many Request messages"));
1344 if (pcb->settings.eap_req_time > 0) {
1345 UNTIMEOUT(eap_client_timeout, pcb);
1347 auth_withpeer_fail(pcb, PPP_EAP);
1352 ppp_error((
"EAP: empty Request message discarded"));
1356 GETCHAR(typenum, inp);
1362 ppp_info((
"EAP: Identity prompt \"%.*q\"",
len, inp));
1364 if (pcb->eap.es_usepseudo &&
1365 (pcb->eap.es_usedpseudo == 0 ||
1366 (pcb->eap.es_usedpseudo == 1 &&
1367 id == pcb->eap.es_client.ea_id))) {
1368 pcb->eap.es_usedpseudo = 1;
1371 strcpy(rhostname, SRP_PSEUDO_ID);
1372 len =
read(
fd, rhostname + SRP_PSEUDO_LEN,
1373 sizeof (rhostname) - SRP_PSEUDO_LEN);
1376 eap_send_response(pcb,
id, typenum,
1377 rhostname,
len + SRP_PSEUDO_LEN);
1385 if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) {
1387 pcb->eap.es_usedpseudo = 2;
1390 eap_send_response(pcb,
id, typenum, (
const u_char*)pcb->eap.es_client.ea_name,
1391 pcb->eap.es_client.ea_namelen);
1394 case EAPT_NOTIFICATION:
1396 ppp_info((
"EAP: Notification \"%.*q\"",
len, inp));
1397 eap_send_response(pcb,
id, typenum,
NULL, 0);
1405 ppp_warn((
"EAP: unexpected Nak in Request; ignored"));
1411 ppp_error((
"EAP: received MD5-Challenge with no data"));
1415 GETCHAR(vallen, inp);
1417 if (vallen < 8 || vallen >
len) {
1418 ppp_error((
"EAP: MD5-Challenge with bad length %d (8..%d)",
1421 eap_send_nak(pcb,
id, EAPT_SRP);
1426 if (
len - vallen >= (
int)
sizeof (rhostname)) {
1427 ppp_dbglog((
"EAP: trimming really long peer name down"));
1428 MEMCPY(rhostname, inp + vallen,
sizeof (rhostname) - 1);
1429 rhostname[
sizeof (rhostname) - 1] =
'\0';
1431 MEMCPY(rhostname, inp + vallen,
len - vallen);
1432 rhostname[
len - vallen] =
'\0';
1437 if (pcb->settings.explicit_remote ||
1438 (pcb->settings.remote_name[0] !=
'\0' && vallen ==
len))
1439 strlcpy(rhostname, pcb->settings.remote_name,
sizeof (rhostname));
1446 if (!get_secret(pcb, pcb->eap.es_client.ea_name,
1447 rhostname,
secret, &secret_len, 0)) {
1448 ppp_dbglog((
"EAP: no MD5 secret for auth to %q", rhostname));
1449 eap_send_nak(pcb,
id, EAPT_SRP);
1452 lwip_md5_init(&mdContext);
1453 lwip_md5_starts(&mdContext);
1455 lwip_md5_update(&mdContext, &typenum, 1);
1456 lwip_md5_update(&mdContext, (
u_char *)
secret, secret_len);
1458 lwip_md5_update(&mdContext, inp, vallen);
1459 lwip_md5_finish(&mdContext,
hash);
1460 lwip_md5_free(&mdContext);
1461 eap_chap_response(pcb,
id,
hash, pcb->eap.es_client.ea_name,
1462 pcb->eap.es_client.ea_namelen);
1468 ppp_error((
"EAP: received empty SRP Request"));
1474 GETCHAR(vallen, inp);
1477 case EAPSRP_CHALLENGE:
1479 if (pcb->eap.es_client.ea_session !=
NULL) {
1480 tc = (
struct t_client *)pcb->eap.es_client.
1487 if (
id != pcb->eap.es_client.ea_id) {
1489 pcb->eap.es_client.ea_session =
NULL;
1494 pcb->eap.es_client.ea_skey =
NULL;
1498 GETCHAR(vallen, inp);
1500 if (vallen >=
len) {
1501 ppp_error((
"EAP: badly-formed SRP Challenge"
1506 MEMCPY(rhostname, inp, vallen);
1507 rhostname[vallen] =
'\0';
1508 INCPTR(vallen, inp);
1515 if (explicit_remote ||
1516 (remote_name[0] !=
'\0' && vallen == 0)) {
1517 strlcpy(rhostname, remote_name,
1518 sizeof (rhostname));
1525 MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen);
1526 pcb->eap.es_client.ea_peer[rhostnamelen] =
'\0';
1527 pcb->eap.es_client.ea_peerlen = rhostnamelen;
1529 GETCHAR(vallen, inp);
1531 if (vallen >=
len) {
1532 ppp_error((
"EAP: badly-formed SRP Challenge"
1539 INCPTR(vallen, inp);
1542 GETCHAR(vallen, inp);
1545 ppp_error((
"EAP: badly-formed SRP Challenge"
1558 INCPTR(vallen, inp);
1566 Nval.data = (
u_char *)wkmodulus;
1567 Nval.len =
sizeof (wkmodulus);
1572 tc = t_clientopen(pcb->eap.es_client.ea_name,
1573 &Nval, &
gval, &sval);
1575 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1578 pcb->eap.es_client.ea_session = (
void *)
tc;
1583 t_clientaddexdata(
tc, vals, 2);
1585 Ap = t_clientgenexp(
tc);
1586 eap_srp_response(esp,
id, EAPSRP_CKEY,
Ap->data,
1591 tc = (
struct t_client *)pcb->eap.es_client.ea_session;
1593 ppp_warn((
"EAP: peer sent Subtype 2 without 1"));
1594 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1597 if (pcb->eap.es_client.ea_skey !=
NULL) {
1602 if (
id != pcb->eap.es_client.ea_id) {
1603 ppp_warn((
"EAP: ID changed from %d to %d "
1604 "in SRP Subtype 2 rexmit",
1605 pcb->eap.es_client.ea_id,
id));
1608 if (get_srp_secret(pcb->eap.es_unit,
1609 pcb->eap.es_client.ea_name,
1610 pcb->eap.es_client.ea_peer,
secret, 0) == 0) {
1616 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1623 pcb->eap.es_client.ea_skey =
1624 t_clientgetkey(
tc, &Bval);
1625 if (pcb->eap.es_client.ea_skey ==
NULL) {
1627 ppp_error((
"EAP: SRP server is rogue"));
1628 goto client_failure;
1631 eap_srpval_response(esp,
id, SRPVAL_EBIT,
1632 t_clientresponse(
tc));
1635 case EAPSRP_SVALIDATOR:
1636 tc = (
struct t_client *)pcb->eap.es_client.ea_session;
1637 if (
tc ==
NULL || pcb->eap.es_client.ea_skey ==
NULL) {
1638 ppp_warn((
"EAP: peer sent Subtype 3 without 1/2"));
1639 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1647 if (pcb->eap.es_client.ea_state == eapOpen) {
1648 if (
id != pcb->eap.es_client.ea_id) {
1649 ppp_warn((
"EAP: ID changed from %d to %d "
1650 "in SRP Subtype 3 rexmit",
1651 pcb->eap.es_client.ea_id,
id));
1654 len -=
sizeof (
u32_t) + SHA_DIGESTSIZE;
1655 if (
len < 0 || t_clientverify(
tc, inp +
1656 sizeof (
u32_t)) != 0) {
1657 ppp_error((
"EAP: SRP server verification "
1659 goto client_failure;
1661 GETLONG(pcb->eap.es_client.ea_keyflags, inp);
1663 if (
len > 0 && pcb->eap.es_usepseudo) {
1664 INCPTR(SHA_DIGESTSIZE, inp);
1665 write_pseudonym(esp, inp,
len,
id);
1673 eap_srp_response(esp,
id, EAPSRP_ACK,
NULL, 0);
1676 case EAPSRP_LWRECHALLENGE:
1678 ppp_warn((
"EAP: malformed Lightweight rechallenge"));
1683 SHA1Update(&ctxt, vals, 1);
1684 SHA1Update(&ctxt, pcb->eap.es_client.ea_skey,
1686 SHA1Update(&ctxt, inp,
len);
1687 SHA1Update(&ctxt, pcb->eap.es_client.ea_name,
1688 pcb->eap.es_client.ea_namelen);
1689 SHA1Final(dig, &ctxt);
1690 eap_srp_response(esp,
id, EAPSRP_LWRECHALLENGE, dig,
1695 ppp_error((
"EAP: unknown SRP Subtype %d", vallen));
1696 eap_send_nak(pcb,
id, EAPT_MD5CHAP);
1703 ppp_info((
"EAP: unknown authentication type %d; Naking", typenum));
1704 eap_send_nak(pcb,
id, EAPT_SRP);
1708 if (pcb->settings.eap_req_time > 0) {
1709 UNTIMEOUT(eap_client_timeout, pcb);
1710 TIMEOUT(eap_client_timeout, pcb,
1711 pcb->settings.eap_req_time);
1717 pcb->eap.es_client.ea_state = eapBadAuth;
1718 if (pcb->settings.eap_req_time > 0) {
1719 UNTIMEOUT(eap_client_timeout, (
void *)esp);
1721 pcb->eap.es_client.ea_session =
NULL;
1723 auth_withpeer_fail(pcb, PPP_EAP);
1731static void eap_response(ppp_pcb *pcb,
u_char *inp,
int id,
int len) {
1735 char secret[MAXSECRETLEN];
1737 lwip_md5_context mdContext;
1740 struct t_server *ts;
1743 u_char dig[SHA_DIGESTSIZE];
1749 if (pcb->eap.es_server.ea_state <= eapClosed)
1752 if (pcb->eap.es_server.ea_id !=
id) {
1753 ppp_dbglog((
"EAP: discarding Response %d; expected ID %d",
id,
1754 pcb->eap.es_server.ea_id));
1758 pcb->eap.es_server.ea_responses++;
1761 ppp_error((
"EAP: empty Response message discarded"));
1765 GETCHAR(typenum, inp);
1770 if (pcb->eap.es_server.ea_state != eapIdentify) {
1771 ppp_dbglog((
"EAP discarding unwanted Identify \"%.q\"",
len,
1775 ppp_info((
"EAP: unauthenticated peer name \"%.*q\"",
len, inp));
1779 MEMCPY(pcb->eap.es_server.ea_peer, inp,
len);
1780 pcb->eap.es_server.ea_peer[
len] =
'\0';
1781 pcb->eap.es_server.ea_peerlen =
len;
1782 eap_figure_next_state(pcb, 0);
1785 case EAPT_NOTIFICATION:
1786 ppp_dbglog((
"EAP unexpected Notification; response discarded"));
1791 ppp_info((
"EAP: Nak Response with no suggested protocol"));
1792 eap_figure_next_state(pcb, 1);
1796 GETCHAR(vallen, inp);
1801 !pcb->explicit_remote &&
1803 pcb->eap.es_server.ea_state == eapIdentify){
1805 eap_figure_next_state(pcb, 1);
1812 pcb->eap.es_server.ea_state = eapIdentify;
1813 eap_figure_next_state(pcb, 0);
1817 pcb->eap.es_server.ea_state = eapMD5Chall;
1821 ppp_dbglog((
"EAP: peer requesting unknown Type %d", vallen));
1822 switch (pcb->eap.es_server.ea_state) {
1826 pcb->eap.es_server.ea_state = eapMD5Chall;
1830 pcb->eap.es_server.ea_state = eapIdentify;
1831 eap_figure_next_state(pcb, 0);
1841 if (pcb->eap.es_server.ea_state != eapMD5Chall) {
1842 ppp_error((
"EAP: unexpected MD5-Response"));
1843 eap_figure_next_state(pcb, 1);
1847 ppp_error((
"EAP: received MD5-Response with no data"));
1848 eap_figure_next_state(pcb, 1);
1851 GETCHAR(vallen, inp);
1853 if (vallen != 16 || vallen >
len) {
1854 ppp_error((
"EAP: MD5-Response with bad length %d", vallen));
1855 eap_figure_next_state(pcb, 1);
1860 if (
len - vallen >= (
int)
sizeof (rhostname)) {
1861 ppp_dbglog((
"EAP: trimming really long peer name down"));
1862 MEMCPY(rhostname, inp + vallen,
sizeof (rhostname) - 1);
1863 rhostname[
sizeof (rhostname) - 1] =
'\0';
1865 MEMCPY(rhostname, inp + vallen,
len - vallen);
1866 rhostname[
len - vallen] =
'\0';
1871 if (explicit_remote ||
1872 (remote_name[0] !=
'\0' && vallen ==
len))
1873 strlcpy(rhostname, remote_name,
sizeof (rhostname));
1880 if (!get_secret(pcb, rhostname,
1881 pcb->eap.es_server.ea_name,
secret, &secret_len, 1)) {
1882 ppp_dbglog((
"EAP: no MD5 secret for auth of %q", rhostname));
1883 eap_send_failure(pcb);
1886 lwip_md5_init(&mdContext);
1887 lwip_md5_starts(&mdContext);
1888 lwip_md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1);
1889 lwip_md5_update(&mdContext, (
u_char *)
secret, secret_len);
1891 lwip_md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen);
1892 lwip_md5_finish(&mdContext,
hash);
1893 lwip_md5_free(&mdContext);
1894 if (BCMP(
hash, inp, MD5_SIGNATURE_SIZE) != 0) {
1895 eap_send_failure(pcb);
1898 pcb->eap.es_server.ea_type = EAPT_MD5CHAP;
1899 eap_send_success(pcb);
1900 eap_figure_next_state(pcb, 0);
1901 if (pcb->eap.es_rechallenge != 0)
1902 TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge);
1908 ppp_error((
"EAP: empty SRP Response"));
1909 eap_figure_next_state(pcb, 1);
1912 GETCHAR(typenum, inp);
1916 if (pcb->eap.es_server.ea_state != eapSRP1) {
1917 ppp_error((
"EAP: unexpected SRP Subtype 1 Response"));
1918 eap_figure_next_state(pcb, 1);
1923 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
1925 pcb->eap.es_server.ea_skey = t_servergetkey(ts, &
A);
1926 if (pcb->eap.es_server.ea_skey ==
NULL) {
1928 ppp_error((
"EAP: bogus A value from client"));
1929 eap_send_failure(pcb);
1931 eap_figure_next_state(pcb, 0);
1935 case EAPSRP_CVALIDATOR:
1936 if (pcb->eap.es_server.ea_state != eapSRP2) {
1937 ppp_error((
"EAP: unexpected SRP Subtype 2 Response"));
1938 eap_figure_next_state(pcb, 1);
1941 if (
len <
sizeof (
u32_t) + SHA_DIGESTSIZE) {
1942 ppp_error((
"EAP: M1 length %d < %d",
len,
1943 sizeof (
u32_t) + SHA_DIGESTSIZE));
1944 eap_figure_next_state(pcb, 1);
1947 GETLONG(pcb->eap.es_server.ea_keyflags, inp);
1948 ts = (
struct t_server *)pcb->eap.es_server.ea_session;
1950 if (t_serververify(ts, inp)) {
1951 ppp_info((
"EAP: unable to validate client identity"));
1952 eap_send_failure(pcb);
1955 eap_figure_next_state(pcb, 0);
1959 if (pcb->eap.es_server.ea_state != eapSRP3) {
1960 ppp_error((
"EAP: unexpected SRP Subtype 3 Response"));
1961 eap_send_failure(esp);
1964 pcb->eap.es_server.ea_type = EAPT_SRP;
1965 eap_send_success(pcb, esp);
1966 eap_figure_next_state(pcb, 0);
1967 if (pcb->eap.es_rechallenge != 0)
1969 pcb->eap.es_rechallenge);
1970 if (pcb->eap.es_lwrechallenge != 0)
1971 TIMEOUT(srp_lwrechallenge, pcb,
1972 pcb->eap.es_lwrechallenge);
1975 case EAPSRP_LWRECHALLENGE:
1976 if (pcb->eap.es_server.ea_state != eapSRP4) {
1977 ppp_info((
"EAP: unexpected SRP Subtype 4 Response"));
1980 if (
len != SHA_DIGESTSIZE) {
1981 ppp_error((
"EAP: bad Lightweight rechallenge "
1987 SHA1Update(&ctxt, &vallen, 1);
1988 SHA1Update(&ctxt, pcb->eap.es_server.ea_skey,
1990 SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen);
1991 SHA1Update(&ctxt, pcb->eap.es_server.ea_peer,
1992 pcb->eap.es_server.ea_peerlen);
1993 SHA1Final(dig, &ctxt);
1994 if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) {
1995 ppp_error((
"EAP: failed Lightweight rechallenge"));
1996 eap_send_failure(pcb);
1999 pcb->eap.es_server.ea_state = eapOpen;
2000 if (pcb->eap.es_lwrechallenge != 0)
2001 TIMEOUT(srp_lwrechallenge, esp,
2002 pcb->eap.es_lwrechallenge);
2010 ppp_error((
"EAP: unknown Response type %d; ignored", typenum));
2014 if (pcb->settings.eap_timeout_time > 0) {
2015 UNTIMEOUT(eap_server_timeout, pcb);
2018 if (pcb->eap.es_server.ea_state != eapBadAuth &&
2019 pcb->eap.es_server.ea_state != eapOpen) {
2020 pcb->eap.es_server.ea_id++;
2021 eap_send_request(pcb);
2029static void eap_success(ppp_pcb *pcb,
u_char *inp,
int id,
int len) {
2032 if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) {
2033 ppp_dbglog((
"EAP unexpected success message in state %s (%d)",
2034 eap_state_name(pcb->eap.es_client.ea_state),
2035 pcb->eap.es_client.ea_state));
2039 if (pcb->settings.eap_req_time > 0) {
2040 UNTIMEOUT(eap_client_timeout, pcb);
2048 pcb->eap.es_client.ea_state = eapOpen;
2049 auth_withpeer_success(pcb, PPP_EAP, 0);
2055static void eap_failure(ppp_pcb *pcb,
u_char *inp,
int id,
int len) {
2061 if (pcb->eap.es_client.ea_state <= eapClosed)
2064 if (!eap_client_active(pcb)) {
2065 ppp_dbglog((
"EAP unexpected failure message in state %s (%d)",
2066 eap_state_name(pcb->eap.es_client.ea_state),
2067 pcb->eap.es_client.ea_state));
2070 if (pcb->settings.eap_req_time > 0) {
2071 UNTIMEOUT(eap_client_timeout, pcb);
2079 pcb->eap.es_client.ea_state = eapBadAuth;
2081 ppp_error((
"EAP: peer reports authentication failure"));
2082 auth_withpeer_fail(pcb, PPP_EAP);
2088static void eap_input(ppp_pcb *pcb,
u_char *inp,
int inlen) {
2096 if (inlen < EAP_HEADERLEN) {
2097 ppp_error((
"EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN));
2103 if (len < EAP_HEADERLEN || len > inlen) {
2104 ppp_error((
"EAP: packet has illegal length field %d (%d..%d)",
len,
2105 EAP_HEADERLEN, inlen));
2108 len -= EAP_HEADERLEN;
2113 eap_request(pcb, inp,
id,
len);
2118 eap_response(pcb, inp,
id,
len);
2123 eap_success(pcb, inp,
id,
len);
2127 eap_failure(pcb, inp,
id,
len);
2132 ppp_warn((
"EAP: unknown code %d received",
code));
2141static const char*
const eap_codenames[] = {
2142 "Request",
"Response",
"Success",
"Failure"
2145static const char*
const eap_typenames[] = {
2146 "Identity",
"Notification",
"Nak",
"MD5-Challenge",
2147 "OTP",
"Generic-Token",
NULL,
NULL,
2148 "RSA",
"DSS",
"KEA",
"KEA-Validate",
2149 "TLS",
"Defender",
"Windows 2000",
"Arcot",
2150 "Cisco",
"Nokia",
"SRP"
2153static int eap_printpkt(
const u_char *inp,
int inlen,
void (*printer) (
void *,
const char *, ...),
void *
arg) {
2158 if (inlen < EAP_HEADERLEN)
2164 if (len < EAP_HEADERLEN || len > inlen)
2168 printer(
arg,
" %s", eap_codenames[
code-1]);
2170 printer(
arg,
" code=0x%x",
code);
2171 printer(
arg,
" id=0x%x",
id);
2172 len -= EAP_HEADERLEN;
2176 printer(
arg,
" <missing type>");
2179 GETCHAR(rtype, inp);
2182 printer(
arg,
" %s", eap_typenames[rtype-1]);
2184 printer(
arg,
" type=0x%x", rtype);
2187 case EAPT_NOTIFICATION:
2189 printer(
arg,
" <Message ");
2190 ppp_print_string(inp,
len, printer,
arg);
2195 printer(
arg,
" <No message>");
2202 GETCHAR(vallen, inp);
2206 printer(
arg,
" <Value%.*B>", vallen, inp);
2207 INCPTR(vallen, inp);
2210 printer(
arg,
" <Name ");
2211 ppp_print_string(inp,
len, printer,
arg);
2216 printer(
arg,
" <No name>");
2223 GETCHAR(vallen, inp);
2225 printer(
arg,
"-%d", vallen);
2227 case EAPSRP_CHALLENGE:
2228 GETCHAR(vallen, inp);
2233 printer(
arg,
" <Name ");
2234 ppp_print_string(inp, vallen, printer,
2238 printer(
arg,
" <No name>");
2240 INCPTR(vallen, inp);
2242 GETCHAR(vallen, inp);
2246 printer(
arg,
" <s%.*B>", vallen, inp);
2247 INCPTR(vallen, inp);
2249 GETCHAR(vallen, inp);
2254 printer(
arg,
" <Default g=2>");
2256 printer(
arg,
" <g%.*B>", vallen, inp);
2258 INCPTR(vallen, inp);
2261 printer(
arg,
" <Default N>");
2263 printer(
arg,
" <N%.*B>",
len, inp);
2270 printer(
arg,
" <B%.*B>",
len, inp);
2275 case EAPSRP_SVALIDATOR:
2280 if (uval & SRPVAL_EBIT) {
2282 uval &= ~SRPVAL_EBIT;
2285 printer(
arg,
" f<%X>", uval);
2287 if ((vallen =
len) > SHA_DIGESTSIZE)
2288 vallen = SHA_DIGESTSIZE;
2289 printer(
arg,
" <M2%.*B%s>",
len, inp,
2290 len < SHA_DIGESTSIZE ?
"?" :
"");
2291 INCPTR(vallen, inp);
2294 printer(
arg,
" <PN%.*B>",
len, inp);
2300 case EAPSRP_LWRECHALLENGE:
2301 printer(
arg,
" <Challenge%.*B>",
len, inp);
2317 GETCHAR(rtype, inp);
2320 printer(
arg,
" %s", eap_typenames[rtype-1]);
2322 printer(
arg,
" type=0x%x", rtype);
2326 printer(
arg,
" <Name ");
2327 ppp_print_string(inp,
len, printer,
arg);
2336 printer(
arg,
" <missing hint>");
2339 GETCHAR(rtype, inp);
2341 printer(
arg,
" <Suggested-type %02X", rtype);
2343 printer(
arg,
" (%s)", eap_typenames[rtype-1]);
2349 printer(
arg,
" <missing length>");
2352 GETCHAR(vallen, inp);
2356 printer(
arg,
" <Value%.*B>", vallen, inp);
2357 INCPTR(vallen, inp);
2360 printer(
arg,
" <Name ");
2361 ppp_print_string(inp,
len, printer,
arg);
2366 printer(
arg,
" <No name>");
2373 GETCHAR(vallen, inp);
2375 printer(
arg,
"-%d", vallen);
2378 printer(
arg,
" <A%.*B>",
len, inp);
2383 case EAPSRP_CVALIDATOR:
2388 if (uval & SRPVAL_EBIT) {
2390 uval &= ~SRPVAL_EBIT;
2393 printer(
arg,
" f<%X>", uval);
2395 printer(
arg,
" <M1%.*B%s>",
len, inp,
2396 len == SHA_DIGESTSIZE ?
"" :
"?");
2404 case EAPSRP_LWRECHALLENGE:
2405 printer(
arg,
" <Response%.*B%s>",
len, inp,
2406 len == SHA_DIGESTSIZE ?
"" :
"?");
2407 if ((vallen =
len) > SHA_DIGESTSIZE)
2408 vallen = SHA_DIGESTSIZE;
2409 INCPTR(vallen, inp);
2427 printer(
arg,
" <truncated>");
2432 printer(
arg,
"%8B...", inp);
2434 printer(
arg,
"%.*B",
len, inp);
2437 return (inp - pstart);
ACPI_SIZE strlen(const char *String)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
char * strchr(const char *String, int ch)
void user(int argc, const char *argv[])
size_t strlcpy(char *d, const char *s, size_t bufsize)
#define LWIP_ARRAYSIZE(x)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
GLuint GLuint GLsizei GLenum type
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
#define LWIP_UNUSED_ARG(x)
void pbuf_realloc(struct pbuf *p, u16_t new_len)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define MEMCPY(DST, SRC, BYTES)
static struct msdos_boot_sector bs
static DATA_BLOB CRYPTPROTECT_PROMPTSTRUCT DATA_BLOB *static LPWSTR DATA_BLOB CRYPTPROTECT_PROMPTSTRUCT DATA_BLOB *static char secret[]
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList