Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
lwip_chap-new.c
00001 /* 00002 * chap-new.c - New CHAP implementation. 00003 * 00004 * Copyright (c) 2003 Paul Mackerras. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * 2. The name(s) of the authors of this software must not be used to 00014 * endorse or promote products derived from this software without 00015 * prior written permission. 00016 * 00017 * 3. Redistributions of any form whatsoever must retain the following 00018 * acknowledgment: 00019 * "This product includes software developed by Paul Mackerras 00020 * <paulus@samba.org>". 00021 * 00022 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 00023 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00024 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 00025 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00026 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 00027 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 00028 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00029 */ 00030 00031 #include "netif/ppp/ppp_opts.h" 00032 #if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 00033 00034 #if 0 /* UNUSED */ 00035 #include <stdlib.h> 00036 #include <string.h> 00037 #endif /* UNUSED */ 00038 00039 #include "netif/ppp/ppp_impl.h" 00040 00041 #if 0 /* UNUSED */ 00042 #include "session.h" 00043 #endif /* UNUSED */ 00044 00045 #include "netif/ppp/chap-new.h" 00046 #include "netif/ppp/chap-md5.h" 00047 #if MSCHAP_SUPPORT 00048 #include "netif/ppp/chap_ms.h" 00049 #endif 00050 #include "netif/ppp/magic.h" 00051 00052 #if 0 /* UNUSED */ 00053 /* Hook for a plugin to validate CHAP challenge */ 00054 int (*chap_verify_hook)(const char *name, const char *ourname, int id, 00055 const struct chap_digest_type *digest, 00056 const unsigned char *challenge, const unsigned char *response, 00057 char *message, int message_space) = NULL; 00058 #endif /* UNUSED */ 00059 00060 #if PPP_OPTIONS 00061 /* 00062 * Command-line options. 00063 */ 00064 static option_t chap_option_list[] = { 00065 { "chap-restart", o_int, &chap_timeout_time, 00066 "Set timeout for CHAP", OPT_PRIO }, 00067 { "chap-max-challenge", o_int, &pcb->settings.chap_max_transmits, 00068 "Set max #xmits for challenge", OPT_PRIO }, 00069 { "chap-interval", o_int, &pcb->settings.chap_rechallenge_time, 00070 "Set interval for rechallenge", OPT_PRIO }, 00071 { NULL } 00072 }; 00073 #endif /* PPP_OPTIONS */ 00074 00075 00076 /* Values for flags in chap_client_state and chap_server_state */ 00077 #define LOWERUP 1 00078 #define AUTH_STARTED 2 00079 #define AUTH_DONE 4 00080 #define AUTH_FAILED 8 00081 #define TIMEOUT_PENDING 0x10 00082 #define CHALLENGE_VALID 0x20 00083 00084 /* 00085 * Prototypes. 00086 */ 00087 static void chap_init(ppp_pcb *pcb); 00088 static void chap_lowerup(ppp_pcb *pcb); 00089 static void chap_lowerdown(ppp_pcb *pcb); 00090 #if PPP_SERVER 00091 static void chap_timeout(void *arg); 00092 static void chap_generate_challenge(ppp_pcb *pcb); 00093 static void chap_handle_response(ppp_pcb *pcb, int code, 00094 unsigned char *pkt, int len); 00095 static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id, 00096 const struct chap_digest_type *digest, 00097 const unsigned char *challenge, const unsigned char *response, 00098 char *message, int message_space); 00099 #endif /* PPP_SERVER */ 00100 static void chap_respond(ppp_pcb *pcb, int id, 00101 unsigned char *pkt, int len); 00102 static void chap_handle_status(ppp_pcb *pcb, int code, int id, 00103 unsigned char *pkt, int len); 00104 static void chap_protrej(ppp_pcb *pcb); 00105 static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen); 00106 #if PRINTPKT_SUPPORT 00107 static int chap_print_pkt(const unsigned char *p, int plen, 00108 void (*printer) (void *, const char *, ...), void *arg); 00109 #endif /* PRINTPKT_SUPPORT */ 00110 00111 /* List of digest types that we know about */ 00112 static const struct chap_digest_type* const chap_digests[] = { 00113 &md5_digest, 00114 #if MSCHAP_SUPPORT 00115 &chapms_digest, 00116 &chapms2_digest, 00117 #endif /* MSCHAP_SUPPORT */ 00118 NULL 00119 }; 00120 00121 /* 00122 * chap_init - reset to initial state. 00123 */ 00124 static void chap_init(ppp_pcb *pcb) { 00125 LWIP_UNUSED_ARG(pcb); 00126 00127 #if 0 /* Not necessary, everything is cleared in ppp_new() */ 00128 memset(&pcb->chap_client, 0, sizeof(chap_client_state)); 00129 #if PPP_SERVER 00130 memset(&pcb->chap_server, 0, sizeof(chap_server_state)); 00131 #endif /* PPP_SERVER */ 00132 #endif /* 0 */ 00133 } 00134 00135 /* 00136 * chap_lowerup - we can start doing stuff now. 00137 */ 00138 static void chap_lowerup(ppp_pcb *pcb) { 00139 00140 pcb->chap_client.flags |= LOWERUP; 00141 #if PPP_SERVER 00142 pcb->chap_server.flags |= LOWERUP; 00143 if (pcb->chap_server.flags & AUTH_STARTED) 00144 chap_timeout(pcb); 00145 #endif /* PPP_SERVER */ 00146 } 00147 00148 static void chap_lowerdown(ppp_pcb *pcb) { 00149 00150 pcb->chap_client.flags = 0; 00151 #if PPP_SERVER 00152 if (pcb->chap_server.flags & TIMEOUT_PENDING) 00153 UNTIMEOUT(chap_timeout, pcb); 00154 pcb->chap_server.flags = 0; 00155 #endif /* PPP_SERVER */ 00156 } 00157 00158 #if PPP_SERVER 00159 /* 00160 * chap_auth_peer - Start authenticating the peer. 00161 * If the lower layer is already up, we start sending challenges, 00162 * otherwise we wait for the lower layer to come up. 00163 */ 00164 void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { 00165 const struct chap_digest_type *dp; 00166 int i; 00167 00168 if (pcb->chap_server.flags & AUTH_STARTED) { 00169 ppp_error("CHAP: peer authentication already started!"); 00170 return; 00171 } 00172 for (i = 0; (dp = chap_digests[i]) != NULL; ++i) 00173 if (dp->code == digest_code) 00174 break; 00175 if (dp == NULL) 00176 ppp_fatal("CHAP digest 0x%x requested but not available", 00177 digest_code); 00178 00179 pcb->chap_server.digest = dp; 00180 pcb->chap_server.name = our_name; 00181 /* Start with a random ID value */ 00182 pcb->chap_server.id = magic(); 00183 pcb->chap_server.flags |= AUTH_STARTED; 00184 if (pcb->chap_server.flags & LOWERUP) 00185 chap_timeout(pcb); 00186 } 00187 #endif /* PPP_SERVER */ 00188 00189 /* 00190 * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. 00191 * There isn't much to do until we receive a challenge. 00192 */ 00193 void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { 00194 const struct chap_digest_type *dp; 00195 int i; 00196 00197 if(NULL == our_name) 00198 return; 00199 00200 if (pcb->chap_client.flags & AUTH_STARTED) { 00201 ppp_error("CHAP: authentication with peer already started!"); 00202 return; 00203 } 00204 for (i = 0; (dp = chap_digests[i]) != NULL; ++i) 00205 if (dp->code == digest_code) 00206 break; 00207 00208 if (dp == NULL) 00209 ppp_fatal("CHAP digest 0x%x requested but not available", 00210 digest_code); 00211 00212 pcb->chap_client.digest = dp; 00213 pcb->chap_client.name = our_name; 00214 pcb->chap_client.flags |= AUTH_STARTED; 00215 } 00216 00217 #if PPP_SERVER 00218 /* 00219 * chap_timeout - It's time to send another challenge to the peer. 00220 * This could be either a retransmission of a previous challenge, 00221 * or a new challenge to start re-authentication. 00222 */ 00223 static void chap_timeout(void *arg) { 00224 ppp_pcb *pcb = (ppp_pcb*)arg; 00225 struct pbuf *p; 00226 00227 pcb->chap_server.flags &= ~TIMEOUT_PENDING; 00228 if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) { 00229 pcb->chap_server.challenge_xmits = 0; 00230 chap_generate_challenge(pcb); 00231 pcb->chap_server.flags |= CHALLENGE_VALID; 00232 } else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) { 00233 pcb->chap_server.flags &= ~CHALLENGE_VALID; 00234 pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED; 00235 auth_peer_fail(pcb, PPP_CHAP); 00236 return; 00237 } 00238 00239 p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PPP_CTRL_PBUF_TYPE); 00240 if(NULL == p) 00241 return; 00242 if(p->tot_len != p->len) { 00243 pbuf_free(p); 00244 return; 00245 } 00246 MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); 00247 ppp_write(pcb, p); 00248 ++pcb->chap_server.challenge_xmits; 00249 pcb->chap_server.flags |= TIMEOUT_PENDING; 00250 TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); 00251 } 00252 00253 /* 00254 * chap_generate_challenge - generate a challenge string and format 00255 * the challenge packet in pcb->chap_server.challenge_pkt. 00256 */ 00257 static void chap_generate_challenge(ppp_pcb *pcb) { 00258 int clen = 1, nlen, len; 00259 unsigned char *p; 00260 00261 p = pcb->chap_server.challenge; 00262 MAKEHEADER(p, PPP_CHAP); 00263 p += CHAP_HDRLEN; 00264 pcb->chap_server.digest->generate_challenge(pcb, p); 00265 clen = *p; 00266 nlen = strlen(pcb->chap_server.name); 00267 memcpy(p + 1 + clen, pcb->chap_server.name, nlen); 00268 00269 len = CHAP_HDRLEN + 1 + clen + nlen; 00270 pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len; 00271 00272 p = pcb->chap_server.challenge + PPP_HDRLEN; 00273 p[0] = CHAP_CHALLENGE; 00274 p[1] = ++pcb->chap_server.id; 00275 p[2] = len >> 8; 00276 p[3] = len; 00277 } 00278 00279 /* 00280 * chap_handle_response - check the response to our challenge. 00281 */ 00282 static void chap_handle_response(ppp_pcb *pcb, int id, 00283 unsigned char *pkt, int len) { 00284 int response_len, ok, mlen; 00285 const unsigned char *response; 00286 unsigned char *outp; 00287 struct pbuf *p; 00288 const char *name = NULL; /* initialized to shut gcc up */ 00289 #if 0 /* UNUSED */ 00290 int (*verifier)(const char *, const char *, int, const struct chap_digest_type *, 00291 const unsigned char *, const unsigned char *, char *, int); 00292 #endif /* UNUSED */ 00293 char rname[MAXNAMELEN+1]; 00294 char message[256]; 00295 00296 if ((pcb->chap_server.flags & LOWERUP) == 0) 00297 return; 00298 if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2) 00299 return; 00300 if (pcb->chap_server.flags & CHALLENGE_VALID) { 00301 response = pkt; 00302 GETCHAR(response_len, pkt); 00303 len -= response_len + 1; /* length of name */ 00304 name = (char *)pkt + response_len; 00305 if (len < 0) 00306 return; 00307 00308 if (pcb->chap_server.flags & TIMEOUT_PENDING) { 00309 pcb->chap_server.flags &= ~TIMEOUT_PENDING; 00310 UNTIMEOUT(chap_timeout, pcb); 00311 } 00312 #if PPP_REMOTENAME 00313 if (pcb->settings.explicit_remote) { 00314 name = pcb->remote_name; 00315 } else 00316 #endif /* PPP_REMOTENAME */ 00317 { 00318 /* Null terminate and clean remote name. */ 00319 ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); 00320 name = rname; 00321 } 00322 00323 #if 0 /* UNUSED */ 00324 if (chap_verify_hook) 00325 verifier = chap_verify_hook; 00326 else 00327 verifier = chap_verify_response; 00328 ok = (*verifier)(name, pcb->chap_server.name, id, pcb->chap_server.digest, 00329 pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, 00330 response, pcb->chap_server.message, sizeof(pcb->chap_server.message)); 00331 #endif /* UNUSED */ 00332 ok = chap_verify_response(pcb, name, pcb->chap_server.name, id, pcb->chap_server.digest, 00333 pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, 00334 response, message, sizeof(message)); 00335 #if 0 /* UNUSED */ 00336 if (!ok || !auth_number()) { 00337 #endif /* UNUSED */ 00338 if (!ok) { 00339 pcb->chap_server.flags |= AUTH_FAILED; 00340 ppp_warn("Peer %q failed CHAP authentication", name); 00341 } 00342 } else if ((pcb->chap_server.flags & AUTH_DONE) == 0) 00343 return; 00344 00345 /* send the response */ 00346 mlen = strlen(message); 00347 len = CHAP_HDRLEN + mlen; 00348 p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PPP_CTRL_PBUF_TYPE); 00349 if(NULL == p) 00350 return; 00351 if(p->tot_len != p->len) { 00352 pbuf_free(p); 00353 return; 00354 } 00355 00356 outp = (unsigned char *)p->payload; 00357 MAKEHEADER(outp, PPP_CHAP); 00358 00359 outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; 00360 outp[1] = id; 00361 outp[2] = len >> 8; 00362 outp[3] = len; 00363 if (mlen > 0) 00364 memcpy(outp + CHAP_HDRLEN, message, mlen); 00365 ppp_write(pcb, p); 00366 00367 if (pcb->chap_server.flags & CHALLENGE_VALID) { 00368 pcb->chap_server.flags &= ~CHALLENGE_VALID; 00369 if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags & AUTH_FAILED)) { 00370 00371 #if 0 /* UNUSED */ 00372 /* 00373 * Auth is OK, so now we need to check session restrictions 00374 * to ensure everything is OK, but only if we used a 00375 * plugin, and only if we're configured to check. This 00376 * allows us to do PAM checks on PPP servers that 00377 * authenticate against ActiveDirectory, and use AD for 00378 * account info (like when using Winbind integrated with 00379 * PAM). 00380 */ 00381 if (session_mgmt && 00382 session_check(name, NULL, devnam, NULL) == 0) { 00383 pcb->chap_server.flags |= AUTH_FAILED; 00384 ppp_warn("Peer %q failed CHAP Session verification", name); 00385 } 00386 #endif /* UNUSED */ 00387 00388 } 00389 if (pcb->chap_server.flags & AUTH_FAILED) { 00390 auth_peer_fail(pcb, PPP_CHAP); 00391 } else { 00392 if ((pcb->chap_server.flags & AUTH_DONE) == 0) 00393 auth_peer_success(pcb, PPP_CHAP, 00394 pcb->chap_server.digest->code, 00395 name, strlen(name)); 00396 if (pcb->settings.chap_rechallenge_time) { 00397 pcb->chap_server.flags |= TIMEOUT_PENDING; 00398 TIMEOUT(chap_timeout, pcb, 00399 pcb->settings.chap_rechallenge_time); 00400 } 00401 } 00402 pcb->chap_server.flags |= AUTH_DONE; 00403 } 00404 } 00405 00406 /* 00407 * chap_verify_response - check whether the peer's response matches 00408 * what we think it should be. Returns 1 if it does (authentication 00409 * succeeded), or 0 if it doesn't. 00410 */ 00411 static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id, 00412 const struct chap_digest_type *digest, 00413 const unsigned char *challenge, const unsigned char *response, 00414 char *message, int message_space) { 00415 int ok; 00416 unsigned char secret[MAXSECRETLEN]; 00417 int secret_len; 00418 00419 /* Get the secret that the peer is supposed to know */ 00420 if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { 00421 ppp_error("No CHAP secret found for authenticating %q", name); 00422 return 0; 00423 } 00424 ok = digest->verify_response(pcb, id, name, secret, secret_len, challenge, 00425 response, message, message_space); 00426 memset(secret, 0, sizeof(secret)); 00427 00428 return ok; 00429 } 00430 #endif /* PPP_SERVER */ 00431 00432 /* 00433 * chap_respond - Generate and send a response to a challenge. 00434 */ 00435 static void chap_respond(ppp_pcb *pcb, int id, 00436 unsigned char *pkt, int len) { 00437 int clen, nlen; 00438 int secret_len; 00439 struct pbuf *p; 00440 u_char *outp; 00441 char rname[MAXNAMELEN+1]; 00442 char secret[MAXSECRETLEN+1]; 00443 00444 p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PPP_CTRL_PBUF_TYPE); 00445 if(NULL == p) 00446 return; 00447 if(p->tot_len != p->len) { 00448 pbuf_free(p); 00449 return; 00450 } 00451 00452 if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) 00453 return; /* not ready */ 00454 if (len < 2 || len < pkt[0] + 1) 00455 return; /* too short */ 00456 clen = pkt[0]; 00457 nlen = len - (clen + 1); 00458 00459 /* Null terminate and clean remote name. */ 00460 ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); 00461 00462 #if PPP_REMOTENAME 00463 /* Microsoft doesn't send their name back in the PPP packet */ 00464 if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0)) 00465 strlcpy(rname, pcb->settings.remote_name, sizeof(rname)); 00466 #endif /* PPP_REMOTENAME */ 00467 00468 /* get secret for authenticating ourselves with the specified host */ 00469 if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) { 00470 secret_len = 0; /* assume null secret if can't find one */ 00471 ppp_warn("No CHAP secret found for authenticating us to %q", rname); 00472 } 00473 00474 outp = (u_char*)p->payload; 00475 MAKEHEADER(outp, PPP_CHAP); 00476 outp += CHAP_HDRLEN; 00477 00478 pcb->chap_client.digest->make_response(pcb, outp, id, pcb->chap_client.name, pkt, 00479 secret, secret_len, pcb->chap_client.priv); 00480 memset(secret, 0, secret_len); 00481 00482 clen = *outp; 00483 nlen = strlen(pcb->chap_client.name); 00484 memcpy(outp + clen + 1, pcb->chap_client.name, nlen); 00485 00486 outp = (u_char*)p->payload + PPP_HDRLEN; 00487 len = CHAP_HDRLEN + clen + 1 + nlen; 00488 outp[0] = CHAP_RESPONSE; 00489 outp[1] = id; 00490 outp[2] = len >> 8; 00491 outp[3] = len; 00492 00493 pbuf_realloc(p, PPP_HDRLEN + len); 00494 ppp_write(pcb, p); 00495 } 00496 00497 static void chap_handle_status(ppp_pcb *pcb, int code, int id, 00498 unsigned char *pkt, int len) { 00499 const char *msg = NULL; 00500 LWIP_UNUSED_ARG(id); 00501 00502 if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) 00503 != (AUTH_STARTED|LOWERUP)) 00504 return; 00505 pcb->chap_client.flags |= AUTH_DONE; 00506 00507 if (code == CHAP_SUCCESS) { 00508 /* used for MS-CHAP v2 mutual auth, yuck */ 00509 if (pcb->chap_client.digest->check_success != NULL) { 00510 if (!(*pcb->chap_client.digest->check_success)(pcb, pkt, len, pcb->chap_client.priv)) 00511 code = CHAP_FAILURE; 00512 } else 00513 msg = "CHAP authentication succeeded"; 00514 } else { 00515 if (pcb->chap_client.digest->handle_failure != NULL) 00516 (*pcb->chap_client.digest->handle_failure)(pcb, pkt, len); 00517 else 00518 msg = "CHAP authentication failed"; 00519 } 00520 if (msg) { 00521 if (len > 0) 00522 ppp_info("%s: %.*v", msg, len, pkt); 00523 else 00524 ppp_info("%s", msg); 00525 } 00526 if (code == CHAP_SUCCESS) 00527 auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code); 00528 else { 00529 pcb->chap_client.flags |= AUTH_FAILED; 00530 ppp_error("CHAP authentication failed"); 00531 auth_withpeer_fail(pcb, PPP_CHAP); 00532 } 00533 } 00534 00535 static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) { 00536 unsigned char code, id; 00537 int len; 00538 00539 if (pktlen < CHAP_HDRLEN) 00540 return; 00541 GETCHAR(code, pkt); 00542 GETCHAR(id, pkt); 00543 GETSHORT(len, pkt); 00544 if (len < CHAP_HDRLEN || len > pktlen) 00545 return; 00546 len -= CHAP_HDRLEN; 00547 00548 switch (code) { 00549 case CHAP_CHALLENGE: 00550 chap_respond(pcb, id, pkt, len); 00551 break; 00552 #if PPP_SERVER 00553 case CHAP_RESPONSE: 00554 chap_handle_response(pcb, id, pkt, len); 00555 break; 00556 #endif /* PPP_SERVER */ 00557 case CHAP_FAILURE: 00558 case CHAP_SUCCESS: 00559 chap_handle_status(pcb, code, id, pkt, len); 00560 break; 00561 default: 00562 break; 00563 } 00564 } 00565 00566 static void chap_protrej(ppp_pcb *pcb) { 00567 00568 #if PPP_SERVER 00569 if (pcb->chap_server.flags & TIMEOUT_PENDING) { 00570 pcb->chap_server.flags &= ~TIMEOUT_PENDING; 00571 UNTIMEOUT(chap_timeout, pcb); 00572 } 00573 if (pcb->chap_server.flags & AUTH_STARTED) { 00574 pcb->chap_server.flags = 0; 00575 auth_peer_fail(pcb, PPP_CHAP); 00576 } 00577 #endif /* PPP_SERVER */ 00578 if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { 00579 pcb->chap_client.flags &= ~AUTH_STARTED; 00580 ppp_error("CHAP authentication failed due to protocol-reject"); 00581 auth_withpeer_fail(pcb, PPP_CHAP); 00582 } 00583 } 00584 00585 #if PRINTPKT_SUPPORT 00586 /* 00587 * chap_print_pkt - print the contents of a CHAP packet. 00588 */ 00589 static const char* const chap_code_names[] = { 00590 "Challenge", "Response", "Success", "Failure" 00591 }; 00592 00593 static int chap_print_pkt(const unsigned char *p, int plen, 00594 void (*printer) (void *, const char *, ...), void *arg) { 00595 int code, id, len; 00596 int clen, nlen; 00597 unsigned char x; 00598 00599 if (plen < CHAP_HDRLEN) 00600 return 0; 00601 GETCHAR(code, p); 00602 GETCHAR(id, p); 00603 GETSHORT(len, p); 00604 if (len < CHAP_HDRLEN || len > plen) 00605 return 0; 00606 00607 if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(chap_code_names)) 00608 printer(arg, " %s", chap_code_names[code-1]); 00609 else 00610 printer(arg, " code=0x%x", code); 00611 printer(arg, " id=0x%x", id); 00612 len -= CHAP_HDRLEN; 00613 switch (code) { 00614 case CHAP_CHALLENGE: 00615 case CHAP_RESPONSE: 00616 if (len < 1) 00617 break; 00618 clen = p[0]; 00619 if (len < clen + 1) 00620 break; 00621 ++p; 00622 nlen = len - clen - 1; 00623 printer(arg, " <"); 00624 for (; clen > 0; --clen) { 00625 GETCHAR(x, p); 00626 printer(arg, "%.2x", x); 00627 } 00628 printer(arg, ">, name = "); 00629 ppp_print_string(p, nlen, printer, arg); 00630 break; 00631 case CHAP_FAILURE: 00632 case CHAP_SUCCESS: 00633 printer(arg, " "); 00634 ppp_print_string(p, len, printer, arg); 00635 break; 00636 default: 00637 for (clen = len; clen > 0; --clen) { 00638 GETCHAR(x, p); 00639 printer(arg, " %.2x", x); 00640 } 00641 /* no break */ 00642 } 00643 00644 return len + CHAP_HDRLEN; 00645 } 00646 #endif /* PRINTPKT_SUPPORT */ 00647 00648 const struct protent chap_protent = { 00649 PPP_CHAP, 00650 chap_init, 00651 chap_input, 00652 chap_protrej, 00653 chap_lowerup, 00654 chap_lowerdown, 00655 NULL, /* open */ 00656 NULL, /* close */ 00657 #if PRINTPKT_SUPPORT 00658 chap_print_pkt, 00659 #endif /* PRINTPKT_SUPPORT */ 00660 #if PPP_DATAINPUT 00661 NULL, /* datainput */ 00662 #endif /* PPP_DATAINPUT */ 00663 #if PRINTPKT_SUPPORT 00664 "CHAP", /* name */ 00665 NULL, /* data_name */ 00666 #endif /* PRINTPKT_SUPPORT */ 00667 #if PPP_OPTIONS 00668 chap_option_list, 00669 NULL, /* check_options */ 00670 #endif /* PPP_OPTIONS */ 00671 #if DEMAND_SUPPORT 00672 NULL, 00673 NULL 00674 #endif /* DEMAND_SUPPORT */ 00675 }; 00676 00677 #endif /* PPP_SUPPORT && CHAP_SUPPORT */
Generated on Tue Jul 12 2022 13:15:52 by
