ReactOS 0.4.16-dev-819-g75c0dc0
chap-new.c
Go to the documentation of this file.
1/*
2 * chap-new.c - New CHAP implementation.
3 *
4 * Copyright (c) 2003 Paul Mackerras. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. The name(s) of the authors of this software must not be used to
14 * endorse or promote products derived from this software without
15 * prior written permission.
16 *
17 * 3. Redistributions of any form whatsoever must retain the following
18 * acknowledgment:
19 * "This product includes software developed by Paul Mackerras
20 * <paulus@samba.org>".
21 *
22 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 */
30
31#include "netif/ppp/ppp_opts.h"
32#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
33
34#if 0 /* UNUSED */
35#include <stdlib.h>
36#include <string.h>
37#endif /* UNUSED */
38
39#include "netif/ppp/ppp_impl.h"
40
41#if 0 /* UNUSED */
42#include "session.h"
43#endif /* UNUSED */
44
45#include "netif/ppp/chap-new.h"
46#include "netif/ppp/chap-md5.h"
47#if MSCHAP_SUPPORT
48#include "netif/ppp/chap_ms.h"
49#endif
50#include "netif/ppp/magic.h"
51
52#if 0 /* UNUSED */
53/* Hook for a plugin to validate CHAP challenge */
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,
57 char *message, int message_space) = NULL;
58#endif /* UNUSED */
59
60#if PPP_OPTIONS
61/*
62 * Command-line options.
63 */
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 },
71 { NULL }
72};
73#endif /* PPP_OPTIONS */
74
75
76/* Values for flags in chap_client_state and chap_server_state */
77#define LOWERUP 1
78#define AUTH_STARTED 2
79#define AUTH_DONE 4
80#define AUTH_FAILED 8
81#define TIMEOUT_PENDING 0x10
82#define CHALLENGE_VALID 0x20
83
84/*
85 * Prototypes.
86 */
87static void chap_init(ppp_pcb *pcb);
88static void chap_lowerup(ppp_pcb *pcb);
89static void chap_lowerdown(ppp_pcb *pcb);
90#if PPP_SERVER
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);
99#endif /* PPP_SERVER */
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);
106#if PRINTPKT_SUPPORT
107static int chap_print_pkt(const unsigned char *p, int plen,
108 void (*printer) (void *, const char *, ...), void *arg);
109#endif /* PRINTPKT_SUPPORT */
110
111/* List of digest types that we know about */
112static const struct chap_digest_type* const chap_digests[] = {
113 &md5_digest,
114#if MSCHAP_SUPPORT
115 &chapms_digest,
116 &chapms2_digest,
117#endif /* MSCHAP_SUPPORT */
118 NULL
119};
120
121/*
122 * chap_init - reset to initial state.
123 */
124static void chap_init(ppp_pcb *pcb) {
125 LWIP_UNUSED_ARG(pcb);
126
127#if 0 /* Not necessary, everything is cleared in ppp_new() */
128 memset(&pcb->chap_client, 0, sizeof(chap_client_state));
129#if PPP_SERVER
130 memset(&pcb->chap_server, 0, sizeof(chap_server_state));
131#endif /* PPP_SERVER */
132#endif /* 0 */
133}
134
135/*
136 * chap_lowerup - we can start doing stuff now.
137 */
138static void chap_lowerup(ppp_pcb *pcb) {
139
140 pcb->chap_client.flags |= LOWERUP;
141#if PPP_SERVER
142 pcb->chap_server.flags |= LOWERUP;
143 if (pcb->chap_server.flags & AUTH_STARTED)
144 chap_timeout(pcb);
145#endif /* PPP_SERVER */
146}
147
148static void chap_lowerdown(ppp_pcb *pcb) {
149
150 pcb->chap_client.flags = 0;
151#if PPP_SERVER
152 if (pcb->chap_server.flags & TIMEOUT_PENDING)
153 UNTIMEOUT(chap_timeout, pcb);
154 pcb->chap_server.flags = 0;
155#endif /* PPP_SERVER */
156}
157
158#if PPP_SERVER
159/*
160 * chap_auth_peer - Start authenticating the peer.
161 * If the lower layer is already up, we start sending challenges,
162 * otherwise we wait for the lower layer to come up.
163 */
164void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) {
165 const struct chap_digest_type *dp;
166 int i;
167
168 if (pcb->chap_server.flags & AUTH_STARTED) {
169 ppp_error(("CHAP: peer authentication already started!"));
170 return;
171 }
172 for (i = 0; (dp = chap_digests[i]) != NULL; ++i)
173 if (dp->code == digest_code)
174 break;
175 if (dp == NULL)
176 ppp_fatal(("CHAP digest 0x%x requested but not available",
177 digest_code));
178
179 pcb->chap_server.digest = dp;
180 pcb->chap_server.name = our_name;
181 /* Start with a random ID value */
182 pcb->chap_server.id = magic();
183 pcb->chap_server.flags |= AUTH_STARTED;
184 if (pcb->chap_server.flags & LOWERUP)
185 chap_timeout(pcb);
186}
187#endif /* PPP_SERVER */
188
189/*
190 * chap_auth_with_peer - Prepare to authenticate ourselves to the peer.
191 * There isn't much to do until we receive a challenge.
192 */
193void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) {
194 const struct chap_digest_type *dp;
195 int i;
196
197 if(NULL == our_name)
198 return;
199
200 if (pcb->chap_client.flags & AUTH_STARTED) {
201 ppp_error(("CHAP: authentication with peer already started!"));
202 return;
203 }
204 for (i = 0; (dp = chap_digests[i]) != NULL; ++i)
205 if (dp->code == digest_code)
206 break;
207
208 if (dp == NULL)
209 ppp_fatal(("CHAP digest 0x%x requested but not available",
210 digest_code));
211
212 pcb->chap_client.digest = dp;
213 pcb->chap_client.name = our_name;
214 pcb->chap_client.flags |= AUTH_STARTED;
215}
216
217#if PPP_SERVER
218/*
219 * chap_timeout - It's time to send another challenge to the peer.
220 * This could be either a retransmission of a previous challenge,
221 * or a new challenge to start re-authentication.
222 */
223static void chap_timeout(void *arg) {
224 ppp_pcb *pcb = (ppp_pcb*)arg;
225 struct pbuf *p;
226
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;
234 pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED;
235 auth_peer_fail(pcb, PPP_CHAP);
236 return;
237 }
238
239 p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PBUF_RAM);
240 if(NULL == p)
241 return;
242 if(p->tot_len != p->len) {
243 pbuf_free(p);
244 return;
245 }
246 MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen);
247 ppp_write(pcb, p);
248 ++pcb->chap_server.challenge_xmits;
249 pcb->chap_server.flags |= TIMEOUT_PENDING;
250 TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time);
251}
252
253/*
254 * chap_generate_challenge - generate a challenge string and format
255 * the challenge packet in pcb->chap_server.challenge_pkt.
256 */
257static void chap_generate_challenge(ppp_pcb *pcb) {
258 int clen = 1, nlen, len;
259 unsigned char *p;
260
261 p = pcb->chap_server.challenge;
262 MAKEHEADER(p, PPP_CHAP);
263 p += CHAP_HDRLEN;
264 pcb->chap_server.digest->generate_challenge(pcb, p);
265 clen = *p;
266 nlen = strlen(pcb->chap_server.name);
267 memcpy(p + 1 + clen, pcb->chap_server.name, nlen);
268
269 len = CHAP_HDRLEN + 1 + clen + nlen;
270 pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len;
271
272 p = pcb->chap_server.challenge + PPP_HDRLEN;
273 p[0] = CHAP_CHALLENGE;
274 p[1] = ++pcb->chap_server.id;
275 p[2] = len >> 8;
276 p[3] = len;
277}
278
279/*
280 * chap_handle_response - check the response to our challenge.
281 */
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;
286 unsigned char *outp;
287 struct pbuf *p;
288 const char *name = NULL; /* initialized to shut gcc up */
289#if 0 /* UNUSED */
290 int (*verifier)(const char *, const char *, int, const struct chap_digest_type *,
291 const unsigned char *, const unsigned char *, char *, int);
292#endif /* UNUSED */
293 char rname[MAXNAMELEN+1];
294 char message[256];
295
296 if ((pcb->chap_server.flags & LOWERUP) == 0)
297 return;
298 if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2)
299 return;
300 if (pcb->chap_server.flags & CHALLENGE_VALID) {
301 response = pkt;
302 GETCHAR(response_len, pkt);
303 len -= response_len + 1; /* length of name */
304 name = (char *)pkt + response_len;
305 if (len < 0)
306 return;
307
308 if (pcb->chap_server.flags & TIMEOUT_PENDING) {
309 pcb->chap_server.flags &= ~TIMEOUT_PENDING;
310 UNTIMEOUT(chap_timeout, pcb);
311 }
312#if PPP_REMOTENAME
313 if (pcb->settings.explicit_remote) {
314 name = pcb->remote_name;
315 } else
316#endif /* PPP_REMOTENAME */
317 {
318 /* Null terminate and clean remote name. */
319 ppp_slprintf(rname, sizeof(rname), "%.*v", len, name);
320 name = rname;
321 }
322
323#if 0 /* UNUSED */
324 if (chap_verify_hook)
325 verifier = chap_verify_hook;
326 else
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));
331#endif /* UNUSED */
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,
334 response, message, sizeof(message));
335#if 0 /* UNUSED */
336 if (!ok || !auth_number()) {
337#endif /* UNUSED */
338 if (!ok) {
339 pcb->chap_server.flags |= AUTH_FAILED;
340 ppp_warn(("Peer %q failed CHAP authentication", name));
341 }
342 } else if ((pcb->chap_server.flags & AUTH_DONE) == 0)
343 return;
344
345 /* send the response */
346 mlen = strlen(message);
347 len = CHAP_HDRLEN + mlen;
348 p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PBUF_RAM);
349 if(NULL == p)
350 return;
351 if(p->tot_len != p->len) {
352 pbuf_free(p);
353 return;
354 }
355
356 outp = (unsigned char *)p->payload;
357 MAKEHEADER(outp, PPP_CHAP);
358
359 outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS;
360 outp[1] = id;
361 outp[2] = len >> 8;
362 outp[3] = len;
363 if (mlen > 0)
364 memcpy(outp + CHAP_HDRLEN, message, mlen);
365 ppp_write(pcb, p);
366
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)) {
370
371#if 0 /* UNUSED */
372 /*
373 * Auth is OK, so now we need to check session restrictions
374 * to ensure everything is OK, but only if we used a
375 * plugin, and only if we're configured to check. This
376 * allows us to do PAM checks on PPP servers that
377 * authenticate against ActiveDirectory, and use AD for
378 * account info (like when using Winbind integrated with
379 * PAM).
380 */
381 if (session_mgmt &&
382 session_check(name, NULL, devnam, NULL) == 0) {
383 pcb->chap_server.flags |= AUTH_FAILED;
384 ppp_warn(("Peer %q failed CHAP Session verification", name));
385 }
386#endif /* UNUSED */
387
388 }
389 if (pcb->chap_server.flags & AUTH_FAILED) {
390 auth_peer_fail(pcb, PPP_CHAP);
391 } else {
392 if ((pcb->chap_server.flags & AUTH_DONE) == 0)
393 auth_peer_success(pcb, PPP_CHAP,
394 pcb->chap_server.digest->code,
395 name, strlen(name));
396 if (pcb->settings.chap_rechallenge_time) {
397 pcb->chap_server.flags |= TIMEOUT_PENDING;
398 TIMEOUT(chap_timeout, pcb,
399 pcb->settings.chap_rechallenge_time);
400 }
401 }
402 pcb->chap_server.flags |= AUTH_DONE;
403 }
404}
405
406/*
407 * chap_verify_response - check whether the peer's response matches
408 * what we think it should be. Returns 1 if it does (authentication
409 * succeeded), or 0 if it doesn't.
410 */
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) {
415 int ok;
416 unsigned char secret[MAXSECRETLEN];
417 int secret_len;
418
419 /* Get the secret that the peer is supposed to know */
420 if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) {
421 ppp_error(("No CHAP secret found for authenticating %q", name));
422 return 0;
423 }
424 ok = digest->verify_response(pcb, id, name, secret, secret_len, challenge,
425 response, message, message_space);
426 memset(secret, 0, sizeof(secret));
427
428 return ok;
429}
430#endif /* PPP_SERVER */
431
432/*
433 * chap_respond - Generate and send a response to a challenge.
434 */
435static void chap_respond(ppp_pcb *pcb, int id,
436 unsigned char *pkt, int len) {
437 int clen, nlen;
438 int secret_len;
439 struct pbuf *p;
440 u_char *outp;
441 char rname[MAXNAMELEN+1];
442 char secret[MAXSECRETLEN+1];
443
444 p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PBUF_RAM);
445 if(NULL == p)
446 return;
447 if(p->tot_len != p->len) {
448 pbuf_free(p);
449 return;
450 }
451
452 if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED))
453 return; /* not ready */
454 if (len < 2 || len < pkt[0] + 1)
455 return; /* too short */
456 clen = pkt[0];
457 nlen = len - (clen + 1);
458
459 /* Null terminate and clean remote name. */
460 ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1);
461
462#if PPP_REMOTENAME
463 /* Microsoft doesn't send their name back in the PPP packet */
464 if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0))
465 strlcpy(rname, pcb->settings.remote_name, sizeof(rname));
466#endif /* PPP_REMOTENAME */
467
468 /* get secret for authenticating ourselves with the specified host */
469 if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) {
470 secret_len = 0; /* assume null secret if can't find one */
471 ppp_warn(("No CHAP secret found for authenticating us to %q", rname));
472 }
473
474 outp = (u_char*)p->payload;
475 MAKEHEADER(outp, PPP_CHAP);
476 outp += CHAP_HDRLEN;
477
478 pcb->chap_client.digest->make_response(pcb, outp, id, pcb->chap_client.name, pkt,
479 secret, secret_len, pcb->chap_client.priv);
480 memset(secret, 0, secret_len);
481
482 clen = *outp;
483 nlen = strlen(pcb->chap_client.name);
484 memcpy(outp + clen + 1, pcb->chap_client.name, nlen);
485
486 outp = (u_char*)p->payload + PPP_HDRLEN;
487 len = CHAP_HDRLEN + clen + 1 + nlen;
488 outp[0] = CHAP_RESPONSE;
489 outp[1] = id;
490 outp[2] = len >> 8;
491 outp[3] = len;
492
493 pbuf_realloc(p, PPP_HDRLEN + len);
494 ppp_write(pcb, p);
495}
496
497static void chap_handle_status(ppp_pcb *pcb, int code, int id,
498 unsigned char *pkt, int len) {
499 const char *msg = NULL;
500 LWIP_UNUSED_ARG(id);
501
502 if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP))
503 != (AUTH_STARTED|LOWERUP))
504 return;
505 pcb->chap_client.flags |= AUTH_DONE;
506
507 if (code == CHAP_SUCCESS) {
508 /* used for MS-CHAP v2 mutual auth, yuck */
509 if (pcb->chap_client.digest->check_success != NULL) {
510 if (!(*pcb->chap_client.digest->check_success)(pcb, pkt, len, pcb->chap_client.priv))
511 code = CHAP_FAILURE;
512 } else
513 msg = "CHAP authentication succeeded";
514 } else {
515 if (pcb->chap_client.digest->handle_failure != NULL)
516 (*pcb->chap_client.digest->handle_failure)(pcb, pkt, len);
517 else
518 msg = "CHAP authentication failed";
519 }
520 if (msg) {
521 if (len > 0)
522 ppp_info(("%s: %.*v", msg, len, pkt));
523 else
524 ppp_info(("%s", msg));
525 }
526 if (code == CHAP_SUCCESS)
527 auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code);
528 else {
529 pcb->chap_client.flags |= AUTH_FAILED;
530 ppp_error(("CHAP authentication failed"));
531 auth_withpeer_fail(pcb, PPP_CHAP);
532 }
533}
534
535static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) {
536 unsigned char code, id;
537 int len;
538
539 if (pktlen < CHAP_HDRLEN)
540 return;
541 GETCHAR(code, pkt);
542 GETCHAR(id, pkt);
543 GETSHORT(len, pkt);
544 if (len < CHAP_HDRLEN || len > pktlen)
545 return;
546 len -= CHAP_HDRLEN;
547
548 switch (code) {
549 case CHAP_CHALLENGE:
550 chap_respond(pcb, id, pkt, len);
551 break;
552#if PPP_SERVER
553 case CHAP_RESPONSE:
554 chap_handle_response(pcb, id, pkt, len);
555 break;
556#endif /* PPP_SERVER */
557 case CHAP_FAILURE:
558 case CHAP_SUCCESS:
559 chap_handle_status(pcb, code, id, pkt, len);
560 break;
561 default:
562 break;
563 }
564}
565
566static void chap_protrej(ppp_pcb *pcb) {
567
568#if PPP_SERVER
569 if (pcb->chap_server.flags & TIMEOUT_PENDING) {
570 pcb->chap_server.flags &= ~TIMEOUT_PENDING;
571 UNTIMEOUT(chap_timeout, pcb);
572 }
573 if (pcb->chap_server.flags & AUTH_STARTED) {
574 pcb->chap_server.flags = 0;
575 auth_peer_fail(pcb, PPP_CHAP);
576 }
577#endif /* PPP_SERVER */
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);
582 }
583}
584
585#if PRINTPKT_SUPPORT
586/*
587 * chap_print_pkt - print the contents of a CHAP packet.
588 */
589static const char* const chap_code_names[] = {
590 "Challenge", "Response", "Success", "Failure"
591};
592
593static int chap_print_pkt(const unsigned char *p, int plen,
594 void (*printer) (void *, const char *, ...), void *arg) {
595 int code, id, len;
596 int clen, nlen;
597 unsigned char x;
598
599 if (plen < CHAP_HDRLEN)
600 return 0;
601 GETCHAR(code, p);
602 GETCHAR(id, p);
603 GETSHORT(len, p);
604 if (len < CHAP_HDRLEN || len > plen)
605 return 0;
606
607 if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(chap_code_names))
608 printer(arg, " %s", chap_code_names[code-1]);
609 else
610 printer(arg, " code=0x%x", code);
611 printer(arg, " id=0x%x", id);
612 len -= CHAP_HDRLEN;
613 switch (code) {
614 case CHAP_CHALLENGE:
615 case CHAP_RESPONSE:
616 if (len < 1)
617 break;
618 clen = p[0];
619 if (len < clen + 1)
620 break;
621 ++p;
622 nlen = len - clen - 1;
623 printer(arg, " <");
624 for (; clen > 0; --clen) {
625 GETCHAR(x, p);
626 printer(arg, "%.2x", x);
627 }
628 printer(arg, ">, name = ");
629 ppp_print_string(p, nlen, printer, arg);
630 break;
631 case CHAP_FAILURE:
632 case CHAP_SUCCESS:
633 printer(arg, " ");
634 ppp_print_string(p, len, printer, arg);
635 break;
636 default:
637 for (clen = len; clen > 0; --clen) {
638 GETCHAR(x, p);
639 printer(arg, " %.2x", x);
640 }
641 /* no break */
642 }
643
644 return len + CHAP_HDRLEN;
645}
646#endif /* PRINTPKT_SUPPORT */
647
648const struct protent chap_protent = {
649 PPP_CHAP,
650 chap_init,
651 chap_input,
652 chap_protrej,
653 chap_lowerup,
654 chap_lowerdown,
655 NULL, /* open */
656 NULL, /* close */
657#if PRINTPKT_SUPPORT
658 chap_print_pkt,
659#endif /* PRINTPKT_SUPPORT */
660#if PPP_DATAINPUT
661 NULL, /* datainput */
662#endif /* PPP_DATAINPUT */
663#if PRINTPKT_SUPPORT
664 "CHAP", /* name */
665 NULL, /* data_name */
666#endif /* PRINTPKT_SUPPORT */
667#if PPP_OPTIONS
668 chap_option_list,
669 NULL, /* check_options */
670#endif /* PPP_OPTIONS */
671#if DEMAND_SUPPORT
672 NULL,
673 NULL
674#endif /* DEMAND_SUPPORT */
675};
676
677#endif /* PPP_SUPPORT && CHAP_SUPPORT */
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ok(value,...)
Definition: atltest.h:57
@ AUTH_FAILED
Definition: auth.h:158
#define msg(x)
Definition: auth_time.c:54
size_t strlcpy(char *d, const char *s, size_t bufsize)
Definition: compat.c:3
#define LWIP_ARRAYSIZE(x)
Definition: def.h:69
#define NULL
Definition: types.h:112
UCHAR u_char
Definition: types.h:80
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
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
Definition: glfuncs.h:248
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:402
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
@ PBUF_RAM
Definition: pbuf.h:152
@ PBUF_RAW
Definition: pbuf.h:111
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define MAXNAMELEN
Definition: maxpath.h:119
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static DATA_BLOB CRYPTPROTECT_PROMPTSTRUCT DATA_BLOB *static LPWSTR DATA_BLOB CRYPTPROTECT_PROMPTSTRUCT DATA_BLOB *static char secret[]
Definition: protectdata.c:33
#define TIMEOUT
Definition: ntpclient.c:12
#define memset(x, y, z)
Definition: compat.h:39
Definition: inflate.c:139
Definition: tftpd.h:60
Definition: name.c:39
WCHAR * name
Definition: name.c:42
Definition: pbuf.h:186