32#if PPP_SUPPORT && CHAP_SUPPORT
54int (*chap_verify_hook)(
const char *
name,
const char *ourname,
int id,
55 const struct chap_digest_type *digest,
56 const unsigned char *challenge,
const unsigned char *response,
64static option_t chap_option_list[] = {
65 {
"chap-restart", o_int, &chap_timeout_time,
66 "Set timeout for CHAP", OPT_PRIO },
67 {
"chap-max-challenge", o_int, &pcb->settings.chap_max_transmits,
68 "Set max #xmits for challenge", OPT_PRIO },
69 {
"chap-interval", o_int, &pcb->settings.chap_rechallenge_time,
70 "Set interval for rechallenge", OPT_PRIO },
81#define TIMEOUT_PENDING 0x10
82#define CHALLENGE_VALID 0x20
87static void chap_init(ppp_pcb *pcb);
88static void chap_lowerup(ppp_pcb *pcb);
89static void chap_lowerdown(ppp_pcb *pcb);
91static void chap_timeout(
void *
arg);
92static void chap_generate_challenge(ppp_pcb *pcb);
93static void chap_handle_response(ppp_pcb *pcb,
int code,
94 unsigned char *pkt,
int len);
95static int chap_verify_response(ppp_pcb *pcb,
const char *
name,
const char *ourname,
int id,
96 const struct chap_digest_type *digest,
97 const unsigned char *challenge,
const unsigned char *response,
98 char *
message,
int message_space);
100static void chap_respond(ppp_pcb *pcb,
int id,
101 unsigned char *pkt,
int len);
102static void chap_handle_status(ppp_pcb *pcb,
int code,
int id,
103 unsigned char *pkt,
int len);
104static void chap_protrej(ppp_pcb *pcb);
105static void chap_input(ppp_pcb *pcb,
unsigned char *pkt,
int pktlen);
107static int chap_print_pkt(
const unsigned char *
p,
int plen,
108 void (*printer) (
void *,
const char *, ...),
void *
arg);
112static const struct chap_digest_type*
const chap_digests[] = {
124static void chap_init(ppp_pcb *pcb) {
128 memset(&pcb->chap_client, 0,
sizeof(chap_client_state));
130 memset(&pcb->chap_server, 0,
sizeof(chap_server_state));
138static void chap_lowerup(ppp_pcb *pcb) {
140 pcb->chap_client.flags |= LOWERUP;
142 pcb->chap_server.flags |= LOWERUP;
143 if (pcb->chap_server.flags & AUTH_STARTED)
148static void chap_lowerdown(ppp_pcb *pcb) {
150 pcb->chap_client.flags = 0;
152 if (pcb->chap_server.flags & TIMEOUT_PENDING)
153 UNTIMEOUT(chap_timeout, pcb);
154 pcb->chap_server.flags = 0;
164void chap_auth_peer(ppp_pcb *pcb,
const char *our_name,
int digest_code) {
165 const struct chap_digest_type *dp;
168 if (pcb->chap_server.flags & AUTH_STARTED) {
169 ppp_error((
"CHAP: peer authentication already started!"));
172 for (
i = 0; (dp = chap_digests[
i]) !=
NULL; ++
i)
173 if (dp->code == digest_code)
176 ppp_fatal((
"CHAP digest 0x%x requested but not available",
179 pcb->chap_server.digest = dp;
180 pcb->chap_server.name = our_name;
182 pcb->chap_server.id = magic();
183 pcb->chap_server.flags |= AUTH_STARTED;
184 if (pcb->chap_server.flags & LOWERUP)
193void chap_auth_with_peer(ppp_pcb *pcb,
const char *our_name,
int digest_code) {
194 const struct chap_digest_type *dp;
200 if (pcb->chap_client.flags & AUTH_STARTED) {
201 ppp_error((
"CHAP: authentication with peer already started!"));
204 for (
i = 0; (dp = chap_digests[
i]) !=
NULL; ++
i)
205 if (dp->code == digest_code)
209 ppp_fatal((
"CHAP digest 0x%x requested but not available",
212 pcb->chap_client.digest = dp;
213 pcb->chap_client.name = our_name;
214 pcb->chap_client.flags |= AUTH_STARTED;
223static void chap_timeout(
void *
arg) {
224 ppp_pcb *pcb = (ppp_pcb*)
arg;
227 pcb->chap_server.flags &= ~TIMEOUT_PENDING;
228 if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) {
229 pcb->chap_server.challenge_xmits = 0;
230 chap_generate_challenge(pcb);
231 pcb->chap_server.flags |= CHALLENGE_VALID;
232 }
else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) {
233 pcb->chap_server.flags &= ~CHALLENGE_VALID;
235 auth_peer_fail(pcb, PPP_CHAP);
242 if(
p->tot_len !=
p->len) {
246 MEMCPY(
p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen);
248 ++pcb->chap_server.challenge_xmits;
249 pcb->chap_server.flags |= TIMEOUT_PENDING;
250 TIMEOUT(chap_timeout,
arg, pcb->settings.chap_timeout_time);
257static void chap_generate_challenge(ppp_pcb *pcb) {
258 int clen = 1, nlen,
len;
261 p = pcb->chap_server.challenge;
262 MAKEHEADER(
p, PPP_CHAP);
264 pcb->chap_server.digest->generate_challenge(pcb,
p);
266 nlen =
strlen(pcb->chap_server.name);
267 memcpy(
p + 1 + clen, pcb->chap_server.name, nlen);
269 len = CHAP_HDRLEN + 1 + clen + nlen;
270 pcb->chap_server.challenge_pktlen = PPP_HDRLEN +
len;
272 p = pcb->chap_server.challenge + PPP_HDRLEN;
273 p[0] = CHAP_CHALLENGE;
274 p[1] = ++pcb->chap_server.id;
282static void chap_handle_response(ppp_pcb *pcb,
int id,
283 unsigned char *pkt,
int len) {
284 int response_len,
ok, mlen;
285 const unsigned char *response;
290 int (*verifier)(
const char *,
const char *,
int,
const struct chap_digest_type *,
291 const unsigned char *,
const unsigned char *,
char *,
int);
296 if ((pcb->chap_server.flags & LOWERUP) == 0)
298 if (
id != pcb->chap_server.challenge[PPP_HDRLEN+1] ||
len < 2)
300 if (pcb->chap_server.flags & CHALLENGE_VALID) {
302 GETCHAR(response_len, pkt);
303 len -= response_len + 1;
304 name = (
char *)pkt + response_len;
308 if (pcb->chap_server.flags & TIMEOUT_PENDING) {
309 pcb->chap_server.flags &= ~TIMEOUT_PENDING;
310 UNTIMEOUT(chap_timeout, pcb);
313 if (pcb->settings.explicit_remote) {
314 name = pcb->remote_name;
319 ppp_slprintf(rname,
sizeof(rname),
"%.*v",
len,
name);
324 if (chap_verify_hook)
325 verifier = chap_verify_hook;
327 verifier = chap_verify_response;
328 ok = (*verifier)(
name, pcb->chap_server.
name,
id, pcb->chap_server.digest,
329 pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN,
330 response, pcb->chap_server.message,
sizeof(pcb->chap_server.message));
332 ok = chap_verify_response(pcb,
name, pcb->chap_server.
name,
id, pcb->chap_server.digest,
333 pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN,
336 if (!
ok || !auth_number()) {
340 ppp_warn((
"Peer %q failed CHAP authentication",
name));
342 }
else if ((pcb->chap_server.flags & AUTH_DONE) == 0)
347 len = CHAP_HDRLEN + mlen;
351 if(
p->tot_len !=
p->len) {
356 outp = (
unsigned char *)
p->payload;
357 MAKEHEADER(outp, PPP_CHAP);
359 outp[0] = (pcb->chap_server.flags &
AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS;
367 if (pcb->chap_server.flags & CHALLENGE_VALID) {
368 pcb->chap_server.flags &= ~CHALLENGE_VALID;
369 if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags &
AUTH_FAILED)) {
384 ppp_warn((
"Peer %q failed CHAP Session verification",
name));
390 auth_peer_fail(pcb, PPP_CHAP);
392 if ((pcb->chap_server.flags & AUTH_DONE) == 0)
393 auth_peer_success(pcb, PPP_CHAP,
394 pcb->chap_server.digest->code,
396 if (pcb->settings.chap_rechallenge_time) {
397 pcb->chap_server.flags |= TIMEOUT_PENDING;
399 pcb->settings.chap_rechallenge_time);
402 pcb->chap_server.flags |= AUTH_DONE;
411static int chap_verify_response(ppp_pcb *pcb,
const char *
name,
const char *ourname,
int id,
412 const struct chap_digest_type *digest,
413 const unsigned char *challenge,
const unsigned char *response,
414 char *
message,
int message_space) {
416 unsigned char secret[MAXSECRETLEN];
420 if (!get_secret(pcb,
name, ourname, (
char *)
secret, &secret_len, 1)) {
421 ppp_error((
"No CHAP secret found for authenticating %q",
name));
424 ok = digest->verify_response(pcb,
id,
name,
secret, secret_len, challenge,
425 response,
message, message_space);
435static void chap_respond(ppp_pcb *pcb,
int id,
436 unsigned char *pkt,
int len) {
442 char secret[MAXSECRETLEN+1];
447 if(
p->tot_len !=
p->len) {
452 if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED))
454 if (
len < 2 ||
len < pkt[0] + 1)
457 nlen =
len - (clen + 1);
460 ppp_slprintf(rname,
sizeof(rname),
"%.*v", nlen, pkt + clen + 1);
464 if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0))
465 strlcpy(rname, pcb->settings.remote_name,
sizeof(rname));
469 if (!get_secret(pcb, pcb->chap_client.name, rname,
secret, &secret_len, 0)) {
471 ppp_warn((
"No CHAP secret found for authenticating us to %q", rname));
475 MAKEHEADER(outp, PPP_CHAP);
478 pcb->chap_client.digest->make_response(pcb, outp,
id, pcb->chap_client.name, pkt,
479 secret, secret_len, pcb->chap_client.priv);
483 nlen =
strlen(pcb->chap_client.name);
484 memcpy(outp + clen + 1, pcb->chap_client.name, nlen);
486 outp = (
u_char*)
p->payload + PPP_HDRLEN;
487 len = CHAP_HDRLEN + clen + 1 + nlen;
488 outp[0] = CHAP_RESPONSE;
497static void chap_handle_status(ppp_pcb *pcb,
int code,
int id,
498 unsigned char *pkt,
int len) {
502 if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP))
503 != (AUTH_STARTED|LOWERUP))
505 pcb->chap_client.flags |= AUTH_DONE;
507 if (
code == CHAP_SUCCESS) {
509 if (pcb->chap_client.digest->check_success !=
NULL) {
510 if (!(*pcb->chap_client.digest->check_success)(pcb, pkt,
len, pcb->chap_client.priv))
513 msg =
"CHAP authentication succeeded";
515 if (pcb->chap_client.digest->handle_failure !=
NULL)
516 (*pcb->chap_client.digest->handle_failure)(pcb, pkt,
len);
518 msg =
"CHAP authentication failed";
522 ppp_info((
"%s: %.*v",
msg,
len, pkt));
524 ppp_info((
"%s",
msg));
526 if (
code == CHAP_SUCCESS)
527 auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code);
530 ppp_error((
"CHAP authentication failed"));
531 auth_withpeer_fail(pcb, PPP_CHAP);
535static void chap_input(ppp_pcb *pcb,
unsigned char *pkt,
int pktlen) {
539 if (pktlen < CHAP_HDRLEN)
544 if (len < CHAP_HDRLEN || len > pktlen)
550 chap_respond(pcb,
id, pkt,
len);
554 chap_handle_response(pcb,
id, pkt,
len);
559 chap_handle_status(pcb,
code,
id, pkt,
len);
566static void chap_protrej(ppp_pcb *pcb) {
569 if (pcb->chap_server.flags & TIMEOUT_PENDING) {
570 pcb->chap_server.flags &= ~TIMEOUT_PENDING;
571 UNTIMEOUT(chap_timeout, pcb);
573 if (pcb->chap_server.flags & AUTH_STARTED) {
574 pcb->chap_server.flags = 0;
575 auth_peer_fail(pcb, PPP_CHAP);
578 if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) {
579 pcb->chap_client.flags &= ~AUTH_STARTED;
580 ppp_error((
"CHAP authentication failed due to protocol-reject"));
581 auth_withpeer_fail(pcb, PPP_CHAP);
589static const char*
const chap_code_names[] = {
590 "Challenge",
"Response",
"Success",
"Failure"
593static int chap_print_pkt(
const unsigned char *
p,
int plen,
594 void (*printer) (
void *,
const char *, ...),
void *
arg) {
599 if (plen < CHAP_HDRLEN)
604 if (len < CHAP_HDRLEN || len > plen)
608 printer(
arg,
" %s", chap_code_names[
code-1]);
610 printer(
arg,
" code=0x%x",
code);
611 printer(
arg,
" id=0x%x",
id);
622 nlen =
len - clen - 1;
624 for (; clen > 0; --clen) {
626 printer(
arg,
"%.2x",
x);
628 printer(
arg,
">, name = ");
629 ppp_print_string(
p, nlen, printer,
arg);
634 ppp_print_string(
p,
len, printer,
arg);
637 for (clen =
len; clen > 0; --clen) {
639 printer(
arg,
" %.2x",
x);
644 return len + CHAP_HDRLEN;
648const struct protent chap_protent = {
ACPI_SIZE strlen(const char *String)
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 *
GLint GLint GLint GLint GLint x
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
#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)
#define MEMCPY(DST, SRC, BYTES)
#define memcpy(s1, s2, n)
static DATA_BLOB CRYPTPROTECT_PROMPTSTRUCT DATA_BLOB *static LPWSTR DATA_BLOB CRYPTPROTECT_PROMPTSTRUCT DATA_BLOB *static char secret[]