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 OmniWheels by
lwip_auth.c
00001 /* 00002 * auth.c - PPP authentication and phase control. 00003 * 00004 * Copyright (c) 1993-2002 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 * Derived from main.c, which is: 00031 * 00032 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 00033 * 00034 * Redistribution and use in source and binary forms, with or without 00035 * modification, are permitted provided that the following conditions 00036 * are met: 00037 * 00038 * 1. Redistributions of source code must retain the above copyright 00039 * notice, this list of conditions and the following disclaimer. 00040 * 00041 * 2. Redistributions in binary form must reproduce the above copyright 00042 * notice, this list of conditions and the following disclaimer in 00043 * the documentation and/or other materials provided with the 00044 * distribution. 00045 * 00046 * 3. The name "Carnegie Mellon University" must not be used to 00047 * endorse or promote products derived from this software without 00048 * prior written permission. For permission or any legal 00049 * details, please contact 00050 * Office of Technology Transfer 00051 * Carnegie Mellon University 00052 * 5000 Forbes Avenue 00053 * Pittsburgh, PA 15213-3890 00054 * (412) 268-4387, fax: (412) 268-7395 00055 * tech-transfer@andrew.cmu.edu 00056 * 00057 * 4. Redistributions of any form whatsoever must retain the following 00058 * acknowledgment: 00059 * "This product includes software developed by Computing Services 00060 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 00061 * 00062 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 00063 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00064 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 00065 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00066 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 00067 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 00068 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00069 */ 00070 00071 #include "netif/ppp/ppp_opts.h" 00072 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ 00073 00074 #if 0 /* UNUSED */ 00075 #include <stdio.h> 00076 #include <stddef.h> 00077 #include <stdlib.h> 00078 #include <unistd.h> 00079 #include <errno.h> 00080 #include <pwd.h> 00081 #include <grp.h> 00082 #include <string.h> 00083 #include <sys/types.h> 00084 #include <sys/stat.h> 00085 #include <sys/socket.h> 00086 #include <utmp.h> 00087 #include <fcntl.h> 00088 #if defined(_PATH_LASTLOG) && defined(__linux__) 00089 #include <lastlog.h> 00090 #endif 00091 00092 #include <netdb.h> 00093 #include <netinet/in.h> 00094 #include <arpa/inet.h> 00095 00096 #ifdef HAS_SHADOW 00097 #include <shadow.h> 00098 #ifndef PW_PPP 00099 #define PW_PPP PW_LOGIN 00100 #endif 00101 #endif 00102 00103 #include <time.h> 00104 #endif /* UNUSED */ 00105 00106 #include "netif/ppp/ppp_impl.h" 00107 00108 #include "netif/ppp/fsm.h" 00109 #include "netif/ppp/lcp.h" 00110 #if CCP_SUPPORT 00111 #include "netif/ppp/ccp.h" 00112 #endif /* CCP_SUPPORT */ 00113 #if ECP_SUPPORT 00114 #include "netif/ppp/ecp.h" 00115 #endif /* ECP_SUPPORT */ 00116 #include "netif/ppp/ipcp.h" 00117 #if PAP_SUPPORT 00118 #include "netif/ppp/upap.h" 00119 #endif /* PAP_SUPPORT */ 00120 #if CHAP_SUPPORT 00121 #include "netif/ppp/chap-new.h" 00122 #endif /* CHAP_SUPPORT */ 00123 #if EAP_SUPPORT 00124 #include "netif/ppp/eap.h" 00125 #endif /* EAP_SUPPORT */ 00126 #if CBCP_SUPPORT 00127 #include "netif/ppp/cbcp.h" 00128 #endif 00129 00130 #if 0 /* UNUSED */ 00131 #include "session.h" 00132 #endif /* UNUSED */ 00133 00134 #if 0 /* UNUSED */ 00135 /* Bits in scan_authfile return value */ 00136 #define NONWILD_SERVER 1 00137 #define NONWILD_CLIENT 2 00138 00139 #define ISWILD(word) (word[0] == '*' && word[1] == 0) 00140 #endif /* UNUSED */ 00141 00142 #if 0 /* UNUSED */ 00143 /* List of addresses which the peer may use. */ 00144 static struct permitted_ip *addresses[NUM_PPP]; 00145 00146 /* Wordlist giving addresses which the peer may use 00147 without authenticating itself. */ 00148 static struct wordlist *noauth_addrs; 00149 00150 /* Remote telephone number, if available */ 00151 char remote_number[MAXNAMELEN]; 00152 00153 /* Wordlist giving remote telephone numbers which may connect. */ 00154 static struct wordlist *permitted_numbers; 00155 00156 /* Extra options to apply, from the secrets file entry for the peer. */ 00157 static struct wordlist *extra_options; 00158 #endif /* UNUSED */ 00159 00160 #if 0 /* UNUSED */ 00161 /* Set if we require authentication only because we have a default route. */ 00162 static bool default_auth; 00163 00164 /* Hook to enable a plugin to control the idle time limit */ 00165 int (*idle_time_hook) (struct ppp_idle *) = NULL; 00166 00167 /* Hook for a plugin to say whether we can possibly authenticate any peer */ 00168 int (*pap_check_hook) (void) = NULL; 00169 00170 /* Hook for a plugin to check the PAP user and password */ 00171 int (*pap_auth_hook) (char *user, char *passwd, char **msgp, 00172 struct wordlist **paddrs, 00173 struct wordlist **popts) = NULL; 00174 00175 /* Hook for a plugin to know about the PAP user logout */ 00176 void (*pap_logout_hook) (void) = NULL; 00177 00178 /* Hook for a plugin to get the PAP password for authenticating us */ 00179 int (*pap_passwd_hook) (char *user, char *passwd) = NULL; 00180 00181 /* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ 00182 int (*chap_check_hook) (void) = NULL; 00183 00184 /* Hook for a plugin to get the CHAP password for authenticating us */ 00185 int (*chap_passwd_hook) (char *user, char *passwd) = NULL; 00186 00187 /* Hook for a plugin to say whether it is OK if the peer 00188 refuses to authenticate. */ 00189 int (*null_auth_hook) (struct wordlist **paddrs, 00190 struct wordlist **popts) = NULL; 00191 00192 int (*allowed_address_hook) (u32_t addr) = NULL; 00193 #endif /* UNUSED */ 00194 00195 #ifdef HAVE_MULTILINK 00196 /* Hook for plugin to hear when an interface joins a multilink bundle */ 00197 void (*multilink_join_hook) (void) = NULL; 00198 #endif 00199 00200 #if PPP_NOTIFY 00201 /* A notifier for when the peer has authenticated itself, 00202 and we are proceeding to the network phase. */ 00203 struct notifier *auth_up_notifier = NULL; 00204 00205 /* A notifier for when the link goes down. */ 00206 struct notifier *link_down_notifier = NULL; 00207 #endif /* PPP_NOTIFY */ 00208 00209 /* 00210 * Option variables. 00211 */ 00212 #if 0 /* MOVED TO ppp_settings */ 00213 bool uselogin = 0; /* Use /etc/passwd for checking PAP */ 00214 bool session_mgmt = 0; /* Do session management (login records) */ 00215 bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ 00216 bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ 00217 bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ 00218 bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ 00219 #if MSCHAP_SUPPORT 00220 bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ 00221 bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ 00222 #else /* MSCHAP_SUPPORT */ 00223 bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ 00224 bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ 00225 #endif /* MSCHAP_SUPPORT */ 00226 bool usehostname = 0; /* Use hostname for our_name */ 00227 bool auth_required = 0; /* Always require authentication from peer */ 00228 bool allow_any_ip = 0; /* Allow peer to use any IP address */ 00229 bool explicit_remote = 0; /* User specified explicit remote name */ 00230 bool explicit_user = 0; /* Set if "user" option supplied */ 00231 bool explicit_passwd = 0; /* Set if "password" option supplied */ 00232 char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ 00233 static char *uafname; /* name of most recent +ua file */ 00234 00235 extern char *crypt (const char *, const char *); 00236 #endif /* UNUSED */ 00237 /* Prototypes for procedures local to this file. */ 00238 00239 static void network_phase(ppp_pcb *pcb); 00240 #if PPP_IDLETIMELIMIT 00241 static void check_idle(void *arg); 00242 #endif /* PPP_IDLETIMELIMIT */ 00243 #if PPP_MAXCONNECT 00244 static void connect_time_expired(void *arg); 00245 #endif /* PPP_MAXCONNECT */ 00246 #if 0 /* UNUSED */ 00247 static int null_login (int); 00248 /* static int get_pap_passwd (char *); */ 00249 static int have_pap_secret (int *); 00250 static int have_chap_secret (char *, char *, int, int *); 00251 static int have_srp_secret (char *client, char *server, int need_ip, 00252 int *lacks_ipp); 00253 static int ip_addr_check (u32_t, struct permitted_ip *); 00254 static int scan_authfile (FILE *, char *, char *, char *, 00255 struct wordlist **, struct wordlist **, 00256 char *, int); 00257 static void free_wordlist (struct wordlist *); 00258 static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); 00259 static int some_ip_ok (struct wordlist *); 00260 static int setupapfile (char **); 00261 static int privgroup (char **); 00262 static int set_noauth_addr (char **); 00263 static int set_permitted_number (char **); 00264 static void check_access (FILE *, char *); 00265 static int wordlist_count (struct wordlist *); 00266 #endif /* UNUSED */ 00267 00268 #ifdef MAXOCTETS 00269 static void check_maxoctets (void *); 00270 #endif 00271 00272 #if PPP_OPTIONS 00273 /* 00274 * Authentication-related options. 00275 */ 00276 option_t auth_options[] = { 00277 { "auth", o_bool, &auth_required, 00278 "Require authentication from peer", OPT_PRIO | 1 }, 00279 { "noauth", o_bool, &auth_required, 00280 "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, 00281 &allow_any_ip }, 00282 { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, 00283 "Require PAP authentication from peer", 00284 OPT_PRIOSUB | 1, &auth_required }, 00285 { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, 00286 "Require PAP authentication from peer", 00287 OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, 00288 { "require-chap", o_bool, &auth_required, 00289 "Require CHAP authentication from peer", 00290 OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, 00291 &lcp_wantoptions[0].chap_mdtype }, 00292 { "+chap", o_bool, &auth_required, 00293 "Require CHAP authentication from peer", 00294 OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, 00295 &lcp_wantoptions[0].chap_mdtype }, 00296 #if MSCHAP_SUPPORT 00297 { "require-mschap", o_bool, &auth_required, 00298 "Require MS-CHAP authentication from peer", 00299 OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, 00300 &lcp_wantoptions[0].chap_mdtype }, 00301 { "+mschap", o_bool, &auth_required, 00302 "Require MS-CHAP authentication from peer", 00303 OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, 00304 &lcp_wantoptions[0].chap_mdtype }, 00305 { "require-mschap-v2", o_bool, &auth_required, 00306 "Require MS-CHAPv2 authentication from peer", 00307 OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, 00308 &lcp_wantoptions[0].chap_mdtype }, 00309 { "+mschap-v2", o_bool, &auth_required, 00310 "Require MS-CHAPv2 authentication from peer", 00311 OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, 00312 &lcp_wantoptions[0].chap_mdtype }, 00313 #endif /* MSCHAP_SUPPORT */ 00314 #if 0 00315 { "refuse-pap", o_bool, &refuse_pap, 00316 "Don't agree to auth to peer with PAP", 1 }, 00317 { "-pap", o_bool, &refuse_pap, 00318 "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, 00319 { "refuse-chap", o_bool, &refuse_chap, 00320 "Don't agree to auth to peer with CHAP", 00321 OPT_A2CLRB | MDTYPE_MD5, 00322 &lcp_allowoptions[0].chap_mdtype }, 00323 { "-chap", o_bool, &refuse_chap, 00324 "Don't allow CHAP authentication with peer", 00325 OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, 00326 &lcp_allowoptions[0].chap_mdtype }, 00327 #endif 00328 #if MSCHAP_SUPPORT 00329 #if 0 00330 { "refuse-mschap", o_bool, &refuse_mschap, 00331 "Don't agree to auth to peer with MS-CHAP", 00332 OPT_A2CLRB | MDTYPE_MICROSOFT, 00333 &lcp_allowoptions[0].chap_mdtype }, 00334 { "-mschap", o_bool, &refuse_mschap, 00335 "Don't allow MS-CHAP authentication with peer", 00336 OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, 00337 &lcp_allowoptions[0].chap_mdtype }, 00338 { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, 00339 "Don't agree to auth to peer with MS-CHAPv2", 00340 OPT_A2CLRB | MDTYPE_MICROSOFT_V2, 00341 &lcp_allowoptions[0].chap_mdtype }, 00342 { "-mschap-v2", o_bool, &refuse_mschap_v2, 00343 "Don't allow MS-CHAPv2 authentication with peer", 00344 OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, 00345 &lcp_allowoptions[0].chap_mdtype }, 00346 #endif 00347 #endif /* MSCHAP_SUPPORT*/ 00348 #if EAP_SUPPORT 00349 { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, 00350 "Require EAP authentication from peer", OPT_PRIOSUB | 1, 00351 &auth_required }, 00352 #if 0 00353 { "refuse-eap", o_bool, &refuse_eap, 00354 "Don't agree to authenticate to peer with EAP", 1 }, 00355 #endif 00356 #endif /* EAP_SUPPORT */ 00357 { "name", o_string, our_name, 00358 "Set local name for authentication", 00359 OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, 00360 00361 { "+ua", o_special, (void *)setupapfile, 00362 "Get PAP user and password from file", 00363 OPT_PRIO | OPT_A2STRVAL, &uafname }, 00364 00365 #if 0 00366 { "user", o_string, user, 00367 "Set name for auth with peer", OPT_PRIO | OPT_STATIC, 00368 &explicit_user, MAXNAMELEN }, 00369 00370 { "password", o_string, passwd, 00371 "Password for authenticating us to the peer", 00372 OPT_PRIO | OPT_STATIC | OPT_HIDE, 00373 &explicit_passwd, MAXSECRETLEN }, 00374 #endif 00375 00376 { "usehostname", o_bool, &usehostname, 00377 "Must use hostname for authentication", 1 }, 00378 00379 { "remotename", o_string, remote_name, 00380 "Set remote name for authentication", OPT_PRIO | OPT_STATIC, 00381 &explicit_remote, MAXNAMELEN }, 00382 00383 { "login", o_bool, &uselogin, 00384 "Use system password database for PAP", OPT_A2COPY | 1 , 00385 &session_mgmt }, 00386 { "enable-session", o_bool, &session_mgmt, 00387 "Enable session accounting for remote peers", OPT_PRIV | 1 }, 00388 00389 { "papcrypt", o_bool, &cryptpap, 00390 "PAP passwords are encrypted", 1 }, 00391 00392 { "privgroup", o_special, (void *)privgroup, 00393 "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, 00394 00395 { "allow-ip", o_special, (void *)set_noauth_addr, 00396 "Set IP address(es) which can be used without authentication", 00397 OPT_PRIV | OPT_A2LIST }, 00398 00399 { "remotenumber", o_string, remote_number, 00400 "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, 00401 NULL, MAXNAMELEN }, 00402 00403 { "allow-number", o_special, (void *)set_permitted_number, 00404 "Set telephone number(s) which are allowed to connect", 00405 OPT_PRIV | OPT_A2LIST }, 00406 00407 { NULL } 00408 }; 00409 #endif /* PPP_OPTIONS */ 00410 00411 #if 0 /* UNUSED */ 00412 /* 00413 * setupapfile - specifies UPAP info for authenticating with peer. 00414 */ 00415 static int 00416 setupapfile(argv) 00417 char **argv; 00418 { 00419 FILE *ufile; 00420 int l; 00421 uid_t euid; 00422 char u[MAXNAMELEN], p[MAXSECRETLEN]; 00423 char *fname; 00424 00425 lcp_allowoptions[0].neg_upap = 1; 00426 00427 /* open user info file */ 00428 fname = strdup(*argv); 00429 if (fname == NULL) 00430 novm("+ua file name"); 00431 euid = geteuid(); 00432 if (seteuid(getuid()) == -1) { 00433 option_error("unable to reset uid before opening %s: %m", fname); 00434 return 0; 00435 } 00436 ufile = fopen(fname, "r"); 00437 if (seteuid(euid) == -1) 00438 fatal("unable to regain privileges: %m"); 00439 if (ufile == NULL) { 00440 option_error("unable to open user login data file %s", fname); 00441 return 0; 00442 } 00443 check_access(ufile, fname); 00444 uafname = fname; 00445 00446 /* get username */ 00447 if (fgets(u, MAXNAMELEN - 1, ufile) == NULL 00448 || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { 00449 fclose(ufile); 00450 option_error("unable to read user login data file %s", fname); 00451 return 0; 00452 } 00453 fclose(ufile); 00454 00455 /* get rid of newlines */ 00456 l = strlen(u); 00457 if (l > 0 && u[l-1] == '\n') 00458 u[l-1] = 0; 00459 l = strlen(p); 00460 if (l > 0 && p[l-1] == '\n') 00461 p[l-1] = 0; 00462 00463 if (override_value("user", option_priority, fname)) { 00464 strlcpy(ppp_settings.user, u, sizeof(ppp_settings.user)); 00465 explicit_user = 1; 00466 } 00467 if (override_value("passwd", option_priority, fname)) { 00468 strlcpy(ppp_settings.passwd, p, sizeof(ppp_settings.passwd)); 00469 explicit_passwd = 1; 00470 } 00471 00472 return (1); 00473 } 00474 00475 /* 00476 * privgroup - allow members of the group to have privileged access. 00477 */ 00478 static int 00479 privgroup(argv) 00480 char **argv; 00481 { 00482 struct group *g; 00483 int i; 00484 00485 g = getgrnam(*argv); 00486 if (g == 0) { 00487 option_error("group %s is unknown", *argv); 00488 return 0; 00489 } 00490 for (i = 0; i < ngroups; ++i) { 00491 if (groups[i] == g->gr_gid) { 00492 privileged = 1; 00493 break; 00494 } 00495 } 00496 return 1; 00497 } 00498 00499 00500 /* 00501 * set_noauth_addr - set address(es) that can be used without authentication. 00502 * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. 00503 */ 00504 static int 00505 set_noauth_addr(argv) 00506 char **argv; 00507 { 00508 char *addr = *argv; 00509 int l = strlen(addr) + 1; 00510 struct wordlist *wp; 00511 00512 wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); 00513 if (wp == NULL) 00514 novm("allow-ip argument"); 00515 wp->word = (char *) (wp + 1); 00516 wp->next = noauth_addrs; 00517 MEMCPY(wp->word, addr, l); 00518 noauth_addrs = wp; 00519 return 1; 00520 } 00521 00522 00523 /* 00524 * set_permitted_number - set remote telephone number(s) that may connect. 00525 */ 00526 static int 00527 set_permitted_number(argv) 00528 char **argv; 00529 { 00530 char *number = *argv; 00531 int l = strlen(number) + 1; 00532 struct wordlist *wp; 00533 00534 wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); 00535 if (wp == NULL) 00536 novm("allow-number argument"); 00537 wp->word = (char *) (wp + 1); 00538 wp->next = permitted_numbers; 00539 MEMCPY(wp->word, number, l); 00540 permitted_numbers = wp; 00541 return 1; 00542 } 00543 #endif 00544 00545 /* 00546 * An Open on LCP has requested a change from Dead to Establish phase. 00547 */ 00548 void link_required(ppp_pcb *pcb) { 00549 LWIP_UNUSED_ARG(pcb); 00550 } 00551 00552 #if 0 00553 /* 00554 * Bring the link up to the point of being able to do ppp. 00555 */ 00556 void start_link(unit) 00557 int unit; 00558 { 00559 ppp_pcb *pcb = &ppp_pcb_list[unit]; 00560 char *msg; 00561 00562 status = EXIT_NEGOTIATION_FAILED; 00563 new_phase(pcb, PPP_PHASE_SERIALCONN); 00564 00565 hungup = 0; 00566 devfd = the_channel->connect(); 00567 msg = "Connect script failed"; 00568 if (devfd < 0) 00569 goto fail; 00570 00571 /* set up the serial device as a ppp interface */ 00572 /* 00573 * N.B. we used to do tdb_writelock/tdb_writeunlock around this 00574 * (from establish_ppp to set_ifunit). However, we won't be 00575 * doing the set_ifunit in multilink mode, which is the only time 00576 * we need the atomicity that the tdb_writelock/tdb_writeunlock 00577 * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. 00578 */ 00579 fd_ppp = the_channel->establish_ppp(devfd); 00580 msg = "ppp establishment failed"; 00581 if (fd_ppp < 0) { 00582 status = EXIT_FATAL_ERROR; 00583 goto disconnect; 00584 } 00585 00586 if (!demand && ifunit >= 0) 00587 set_ifunit(1); 00588 00589 /* 00590 * Start opening the connection and wait for 00591 * incoming events (reply, timeout, etc.). 00592 */ 00593 if (ifunit >= 0) 00594 ppp_notice("Connect: %s <--> %s", ifname, ppp_devnam); 00595 else 00596 ppp_notice("Starting negotiation on %s", ppp_devnam); 00597 add_fd(fd_ppp); 00598 00599 new_phase(pcb, PPP_PHASE_ESTABLISH); 00600 00601 lcp_lowerup(pcb); 00602 return; 00603 00604 disconnect: 00605 new_phase(pcb, PPP_PHASE_DISCONNECT); 00606 if (the_channel->disconnect) 00607 the_channel->disconnect(); 00608 00609 fail: 00610 new_phase(pcb, PPP_PHASE_DEAD); 00611 if (the_channel->cleanup) 00612 (*the_channel->cleanup)(); 00613 } 00614 #endif 00615 00616 /* 00617 * LCP has terminated the link; go to the Dead phase and take the 00618 * physical layer down. 00619 */ 00620 void link_terminated(ppp_pcb *pcb) { 00621 if (pcb->phase == PPP_PHASE_DEAD 00622 #ifdef HAVE_MULTILINK 00623 || pcb->phase == PPP_PHASE_MASTER 00624 #endif /* HAVE_MULTILINK */ 00625 ) 00626 return; 00627 new_phase(pcb, PPP_PHASE_DISCONNECT); 00628 00629 #if 0 /* UNUSED */ 00630 if (pap_logout_hook) { 00631 pap_logout_hook(); 00632 } 00633 session_end(devnam); 00634 #endif /* UNUSED */ 00635 00636 if (!doing_multilink) { 00637 ppp_notice("Connection terminated."); 00638 #if PPP_STATS_SUPPORT 00639 print_link_stats(); 00640 #endif /* PPP_STATS_SUPPORT */ 00641 } else 00642 ppp_notice("Link terminated."); 00643 00644 lcp_lowerdown(pcb); 00645 00646 ppp_link_terminated(pcb); 00647 #if 0 00648 /* 00649 * Delete pid files before disestablishing ppp. Otherwise it 00650 * can happen that another pppd gets the same unit and then 00651 * we delete its pid file. 00652 */ 00653 if (!doing_multilink && !demand) 00654 remove_pidfiles(); 00655 00656 /* 00657 * If we may want to bring the link up again, transfer 00658 * the ppp unit back to the loopback. Set the 00659 * real serial device back to its normal mode of operation. 00660 */ 00661 if (fd_ppp >= 0) { 00662 remove_fd(fd_ppp); 00663 clean_check(); 00664 the_channel->disestablish_ppp(devfd); 00665 if (doing_multilink) 00666 mp_exit_bundle(); 00667 fd_ppp = -1; 00668 } 00669 if (!hungup) 00670 lcp_lowerdown(pcb); 00671 if (!doing_multilink && !demand) 00672 script_unsetenv("IFNAME"); 00673 00674 /* 00675 * Run disconnector script, if requested. 00676 * XXX we may not be able to do this if the line has hung up! 00677 */ 00678 if (devfd >= 0 && the_channel->disconnect) { 00679 the_channel->disconnect(); 00680 devfd = -1; 00681 } 00682 if (the_channel->cleanup) 00683 (*the_channel->cleanup)(); 00684 00685 if (doing_multilink && multilink_master) { 00686 if (!bundle_terminating) 00687 new_phase(pcb, PPP_PHASE_MASTER); 00688 else 00689 mp_bundle_terminated(); 00690 } else 00691 new_phase(pcb, PPP_PHASE_DEAD); 00692 #endif 00693 } 00694 00695 /* 00696 * LCP has gone down; it will either die or try to re-establish. 00697 */ 00698 void link_down(ppp_pcb *pcb) { 00699 #if PPP_NOTIFY 00700 notify(link_down_notifier, 0); 00701 #endif /* PPP_NOTIFY */ 00702 00703 if (!doing_multilink) { 00704 upper_layers_down(pcb); 00705 if (pcb->phase != PPP_PHASE_DEAD 00706 #ifdef HAVE_MULTILINK 00707 && pcb->phase != PPP_PHASE_MASTER 00708 #endif /* HAVE_MULTILINK */ 00709 ) 00710 new_phase(pcb, PPP_PHASE_ESTABLISH); 00711 } 00712 /* XXX if doing_multilink, should do something to stop 00713 network-layer traffic on the link */ 00714 } 00715 00716 void upper_layers_down(ppp_pcb *pcb) { 00717 int i; 00718 const struct protent *protp; 00719 00720 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 00721 if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) 00722 (*protp->lowerdown)(pcb); 00723 if (protp->protocol < 0xC000 && protp->close != NULL) 00724 (*protp->close)(pcb, "LCP down"); 00725 } 00726 pcb->num_np_open = 0; 00727 pcb->num_np_up = 0; 00728 } 00729 00730 /* 00731 * The link is established. 00732 * Proceed to the Dead, Authenticate or Network phase as appropriate. 00733 */ 00734 void link_established(ppp_pcb *pcb) { 00735 #if PPP_AUTH_SUPPORT 00736 int auth; 00737 #if PPP_SERVER 00738 #if PAP_SUPPORT 00739 lcp_options *wo = &pcb->lcp_wantoptions; 00740 #endif /* PAP_SUPPORT */ 00741 lcp_options *go = &pcb->lcp_gotoptions; 00742 #endif /* PPP_SERVER */ 00743 lcp_options *ho = &pcb->lcp_hisoptions; 00744 #endif /* PPP_AUTH_SUPPORT */ 00745 int i; 00746 const struct protent *protp; 00747 00748 /* 00749 * Tell higher-level protocols that LCP is up. 00750 */ 00751 if (!doing_multilink) { 00752 for (i = 0; (protp = protocols[i]) != NULL; ++i) 00753 if (protp->protocol != PPP_LCP 00754 && protp->lowerup != NULL) 00755 (*protp->lowerup)(pcb); 00756 } 00757 00758 #if PPP_AUTH_SUPPORT 00759 #if PPP_SERVER 00760 #if PPP_ALLOWED_ADDRS 00761 if (!auth_required && noauth_addrs != NULL) 00762 set_allowed_addrs(unit, NULL, NULL); 00763 #endif /* PPP_ALLOWED_ADDRS */ 00764 00765 if (pcb->settings.auth_required && !(0 00766 #if PAP_SUPPORT 00767 || go->neg_upap 00768 #endif /* PAP_SUPPORT */ 00769 #if CHAP_SUPPORT 00770 || go->neg_chap 00771 #endif /* CHAP_SUPPORT */ 00772 #if EAP_SUPPORT 00773 || go->neg_eap 00774 #endif /* EAP_SUPPORT */ 00775 )) { 00776 00777 #if PPP_ALLOWED_ADDRS 00778 /* 00779 * We wanted the peer to authenticate itself, and it refused: 00780 * if we have some address(es) it can use without auth, fine, 00781 * otherwise treat it as though it authenticated with PAP using 00782 * a username of "" and a password of "". If that's not OK, 00783 * boot it out. 00784 */ 00785 if (noauth_addrs != NULL) { 00786 set_allowed_addrs(unit, NULL, NULL); 00787 } else 00788 #endif /* PPP_ALLOWED_ADDRS */ 00789 if (!pcb->settings.null_login 00790 #if PAP_SUPPORT 00791 || !wo->neg_upap 00792 #endif /* PAP_SUPPORT */ 00793 ) { 00794 ppp_warn("peer refused to authenticate: terminating link"); 00795 #if 0 /* UNUSED */ 00796 status = EXIT_PEER_AUTH_FAILED; 00797 #endif /* UNUSED */ 00798 pcb->err_code = PPPERR_AUTHFAIL; 00799 lcp_close(pcb, "peer refused to authenticate"); 00800 return; 00801 } 00802 } 00803 #endif /* PPP_SERVER */ 00804 00805 new_phase(pcb, PPP_PHASE_AUTHENTICATE); 00806 auth = 0; 00807 #if PPP_SERVER 00808 #if EAP_SUPPORT 00809 if (go->neg_eap) { 00810 eap_authpeer(pcb, PPP_OUR_NAME); 00811 auth |= EAP_PEER; 00812 } else 00813 #endif /* EAP_SUPPORT */ 00814 #if CHAP_SUPPORT 00815 if (go->neg_chap) { 00816 chap_auth_peer(pcb, PPP_OUR_NAME, CHAP_DIGEST(go->chap_mdtype)); 00817 auth |= CHAP_PEER; 00818 } else 00819 #endif /* CHAP_SUPPORT */ 00820 #if PAP_SUPPORT 00821 if (go->neg_upap) { 00822 upap_authpeer(pcb); 00823 auth |= PAP_PEER; 00824 } else 00825 #endif /* PAP_SUPPORT */ 00826 {} 00827 #endif /* PPP_SERVER */ 00828 00829 #if EAP_SUPPORT 00830 if (ho->neg_eap) { 00831 eap_authwithpeer(pcb, pcb->settings.user); 00832 auth |= EAP_WITHPEER; 00833 } else 00834 #endif /* EAP_SUPPORT */ 00835 #if CHAP_SUPPORT 00836 if (ho->neg_chap) { 00837 chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); 00838 auth |= CHAP_WITHPEER; 00839 } else 00840 #endif /* CHAP_SUPPORT */ 00841 #if PAP_SUPPORT 00842 if (ho->neg_upap) { 00843 upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd); 00844 auth |= PAP_WITHPEER; 00845 } else 00846 #endif /* PAP_SUPPORT */ 00847 {} 00848 00849 pcb->auth_pending = auth; 00850 pcb->auth_done = 0; 00851 00852 if (!auth) 00853 #endif /* PPP_AUTH_SUPPORT */ 00854 network_phase(pcb); 00855 } 00856 00857 /* 00858 * Proceed to the network phase. 00859 */ 00860 static void network_phase(ppp_pcb *pcb) { 00861 #if CBCP_SUPPORT 00862 ppp_pcb *pcb = &ppp_pcb_list[unit]; 00863 #endif 00864 #if 0 /* UNUSED */ 00865 lcp_options *go = &lcp_gotoptions[unit]; 00866 #endif /* UNUSED */ 00867 00868 #if 0 /* UNUSED */ 00869 /* Log calling number. */ 00870 if (*remote_number) 00871 ppp_notice("peer from calling number %q authorized", remote_number); 00872 #endif /* UNUSED */ 00873 00874 #if PPP_NOTIFY 00875 /* 00876 * If the peer had to authenticate, notify it now. 00877 */ 00878 if (0 00879 #if CHAP_SUPPORT 00880 || go->neg_chap 00881 #endif /* CHAP_SUPPORT */ 00882 #if PAP_SUPPORT 00883 || go->neg_upap 00884 #endif /* PAP_SUPPORT */ 00885 #if EAP_SUPPORT 00886 || go->neg_eap 00887 #endif /* EAP_SUPPORT */ 00888 ) { 00889 notify(auth_up_notifier, 0); 00890 } 00891 #endif /* PPP_NOTIFY */ 00892 00893 #if CBCP_SUPPORT 00894 /* 00895 * If we negotiated callback, do it now. 00896 */ 00897 if (go->neg_cbcp) { 00898 new_phase(pcb, PPP_PHASE_CALLBACK); 00899 (*cbcp_protent.open)(pcb); 00900 return; 00901 } 00902 #endif 00903 00904 #if PPP_OPTIONS 00905 /* 00906 * Process extra options from the secrets file 00907 */ 00908 if (extra_options) { 00909 options_from_list(extra_options, 1); 00910 free_wordlist(extra_options); 00911 extra_options = 0; 00912 } 00913 #endif /* PPP_OPTIONS */ 00914 start_networks(pcb); 00915 } 00916 00917 void start_networks(ppp_pcb *pcb) { 00918 #if CCP_SUPPORT || ECP_SUPPORT 00919 int i; 00920 const struct protent *protp; 00921 #endif /* CCP_SUPPORT || ECP_SUPPORT */ 00922 00923 new_phase(pcb, PPP_PHASE_NETWORK); 00924 00925 #ifdef HAVE_MULTILINK 00926 if (multilink) { 00927 if (mp_join_bundle()) { 00928 if (multilink_join_hook) 00929 (*multilink_join_hook)(); 00930 if (updetach && !nodetach) 00931 detach(); 00932 return; 00933 } 00934 } 00935 #endif /* HAVE_MULTILINK */ 00936 00937 #ifdef PPP_FILTER 00938 if (!demand) 00939 set_filters(&pass_filter, &active_filter); 00940 #endif 00941 #if CCP_SUPPORT || ECP_SUPPORT 00942 /* Start CCP and ECP */ 00943 for (i = 0; (protp = protocols[i]) != NULL; ++i) 00944 if ( 00945 (0 00946 #if ECP_SUPPORT 00947 || protp->protocol == PPP_ECP 00948 #endif /* ECP_SUPPORT */ 00949 #if CCP_SUPPORT 00950 || protp->protocol == PPP_CCP 00951 #endif /* CCP_SUPPORT */ 00952 ) 00953 && protp->open != NULL) 00954 (*protp->open)(pcb); 00955 #endif /* CCP_SUPPORT || ECP_SUPPORT */ 00956 00957 /* 00958 * Bring up other network protocols iff encryption is not required. 00959 */ 00960 if (1 00961 #if ECP_SUPPORT 00962 && !ecp_gotoptions[unit].required 00963 #endif /* ECP_SUPPORT */ 00964 #if MPPE_SUPPORT 00965 && !pcb->ccp_gotoptions.mppe 00966 #endif /* MPPE_SUPPORT */ 00967 ) 00968 continue_networks(pcb); 00969 } 00970 00971 void continue_networks(ppp_pcb *pcb) { 00972 int i; 00973 const struct protent *protp; 00974 00975 /* 00976 * Start the "real" network protocols. 00977 */ 00978 for (i = 0; (protp = protocols[i]) != NULL; ++i) 00979 if (protp->protocol < 0xC000 00980 #if CCP_SUPPORT 00981 && protp->protocol != PPP_CCP 00982 #endif /* CCP_SUPPORT */ 00983 #if ECP_SUPPORT 00984 && protp->protocol != PPP_ECP 00985 #endif /* ECP_SUPPORT */ 00986 && protp->open != NULL) { 00987 (*protp->open)(pcb); 00988 ++pcb->num_np_open; 00989 } 00990 00991 if (pcb->num_np_open == 0) 00992 /* nothing to do */ 00993 lcp_close(pcb, "No network protocols running"); 00994 } 00995 00996 #if PPP_AUTH_SUPPORT 00997 #if PPP_SERVER 00998 /* 00999 * auth_check_passwd - Check the user name and passwd against configuration. 01000 * 01001 * returns: 01002 * 0: Authentication failed. 01003 * 1: Authentication succeeded. 01004 * In either case, msg points to an appropriate message and msglen to the message len. 01005 */ 01006 int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen) { 01007 int secretuserlen; 01008 int secretpasswdlen; 01009 01010 if (pcb->settings.user && pcb->settings.passwd) { 01011 secretuserlen = (int)strlen(pcb->settings.user); 01012 secretpasswdlen = (int)strlen(pcb->settings.passwd); 01013 if (secretuserlen == userlen 01014 && secretpasswdlen == passwdlen 01015 && !memcmp(auser, pcb->settings.user, userlen) 01016 && !memcmp(apasswd, pcb->settings.passwd, passwdlen) ) { 01017 *msg = "Login ok"; 01018 *msglen = sizeof("Login ok")-1; 01019 return 1; 01020 } 01021 } 01022 01023 *msg = "Login incorrect"; 01024 *msglen = sizeof("Login incorrect")-1; 01025 return 0; 01026 } 01027 01028 /* 01029 * The peer has failed to authenticate himself using `protocol'. 01030 */ 01031 void auth_peer_fail(ppp_pcb *pcb, int protocol) { 01032 LWIP_UNUSED_ARG(protocol); 01033 /* 01034 * Authentication failure: take the link down 01035 */ 01036 #if 0 /* UNUSED */ 01037 status = EXIT_PEER_AUTH_FAILED; 01038 #endif /* UNUSED */ 01039 pcb->err_code = PPPERR_AUTHFAIL; 01040 lcp_close(pcb, "Authentication failed"); 01041 } 01042 01043 /* 01044 * The peer has been successfully authenticated using `protocol'. 01045 */ 01046 void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen) { 01047 int bit; 01048 #ifndef HAVE_MULTILINK 01049 LWIP_UNUSED_ARG(name); 01050 LWIP_UNUSED_ARG(namelen); 01051 #endif /* HAVE_MULTILINK */ 01052 01053 switch (protocol) { 01054 #if CHAP_SUPPORT 01055 case PPP_CHAP: 01056 bit = CHAP_PEER; 01057 switch (prot_flavor) { 01058 case CHAP_MD5: 01059 bit |= CHAP_MD5_PEER; 01060 break; 01061 #if MSCHAP_SUPPORT 01062 case CHAP_MICROSOFT: 01063 bit |= CHAP_MS_PEER; 01064 break; 01065 case CHAP_MICROSOFT_V2: 01066 bit |= CHAP_MS2_PEER; 01067 break; 01068 #endif /* MSCHAP_SUPPORT */ 01069 default: 01070 break; 01071 } 01072 break; 01073 #endif /* CHAP_SUPPORT */ 01074 #if PAP_SUPPORT 01075 case PPP_PAP: 01076 bit = PAP_PEER; 01077 break; 01078 #endif /* PAP_SUPPORT */ 01079 #if EAP_SUPPORT 01080 case PPP_EAP: 01081 bit = EAP_PEER; 01082 break; 01083 #endif /* EAP_SUPPORT */ 01084 default: 01085 ppp_warn("auth_peer_success: unknown protocol %x", protocol); 01086 return; 01087 } 01088 01089 #ifdef HAVE_MULTILINK 01090 /* 01091 * Save the authenticated name of the peer for later. 01092 */ 01093 if (namelen > (int)sizeof(pcb->peer_authname) - 1) 01094 namelen = (int)sizeof(pcb->peer_authname) - 1; 01095 MEMCPY(pcb->peer_authname, name, namelen); 01096 pcb->peer_authname[namelen] = 0; 01097 #endif /* HAVE_MULTILINK */ 01098 #if 0 /* UNUSED */ 01099 script_setenv("PEERNAME", , 0); 01100 #endif /* UNUSED */ 01101 01102 /* Save the authentication method for later. */ 01103 pcb->auth_done |= bit; 01104 01105 /* 01106 * If there is no more authentication still to be done, 01107 * proceed to the network (or callback) phase. 01108 */ 01109 if ((pcb->auth_pending &= ~bit) == 0) 01110 network_phase(pcb); 01111 } 01112 #endif /* PPP_SERVER */ 01113 01114 /* 01115 * We have failed to authenticate ourselves to the peer using `protocol'. 01116 */ 01117 void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { 01118 LWIP_UNUSED_ARG(protocol); 01119 /* 01120 * We've failed to authenticate ourselves to our peer. 01121 * 01122 * Some servers keep sending CHAP challenges, but there 01123 * is no point in persisting without any way to get updated 01124 * authentication secrets. 01125 * 01126 * He'll probably take the link down, and there's not much 01127 * we can do except wait for that. 01128 */ 01129 pcb->err_code = PPPERR_AUTHFAIL; 01130 lcp_close(pcb, "Failed to authenticate ourselves to peer"); 01131 } 01132 01133 /* 01134 * We have successfully authenticated ourselves with the peer using `protocol'. 01135 */ 01136 void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { 01137 int bit; 01138 const char *prot = ""; 01139 01140 switch (protocol) { 01141 #if CHAP_SUPPORT 01142 case PPP_CHAP: 01143 bit = CHAP_WITHPEER; 01144 prot = "CHAP"; 01145 switch (prot_flavor) { 01146 case CHAP_MD5: 01147 bit |= CHAP_MD5_WITHPEER; 01148 break; 01149 #if MSCHAP_SUPPORT 01150 case CHAP_MICROSOFT: 01151 bit |= CHAP_MS_WITHPEER; 01152 break; 01153 case CHAP_MICROSOFT_V2: 01154 bit |= CHAP_MS2_WITHPEER; 01155 break; 01156 #endif /* MSCHAP_SUPPORT */ 01157 default: 01158 break; 01159 } 01160 break; 01161 #endif /* CHAP_SUPPORT */ 01162 #if PAP_SUPPORT 01163 case PPP_PAP: 01164 bit = PAP_WITHPEER; 01165 prot = "PAP"; 01166 break; 01167 #endif /* PAP_SUPPORT */ 01168 #if EAP_SUPPORT 01169 case PPP_EAP: 01170 bit = EAP_WITHPEER; 01171 prot = "EAP"; 01172 break; 01173 #endif /* EAP_SUPPORT */ 01174 default: 01175 ppp_warn("auth_withpeer_success: unknown protocol %x", protocol); 01176 bit = 0; 01177 /* no break */ 01178 } 01179 01180 ppp_notice("%s authentication succeeded", prot); 01181 01182 /* Save the authentication method for later. */ 01183 pcb->auth_done |= bit; 01184 01185 /* 01186 * If there is no more authentication still being done, 01187 * proceed to the network (or callback) phase. 01188 */ 01189 if ((pcb->auth_pending &= ~bit) == 0) 01190 network_phase(pcb); 01191 } 01192 #endif /* PPP_AUTH_SUPPORT */ 01193 01194 01195 /* 01196 * np_up - a network protocol has come up. 01197 */ 01198 void np_up(ppp_pcb *pcb, int proto) { 01199 #if PPP_IDLETIMELIMIT 01200 int tlim; 01201 #endif /* PPP_IDLETIMELIMIT */ 01202 LWIP_UNUSED_ARG(proto); 01203 01204 if (pcb->num_np_up == 0) { 01205 /* 01206 * At this point we consider that the link has come up successfully. 01207 */ 01208 new_phase(pcb, PPP_PHASE_RUNNING); 01209 01210 #if PPP_IDLETIMELIMIT 01211 #if 0 /* UNUSED */ 01212 if (idle_time_hook != 0) 01213 tlim = (*idle_time_hook)(NULL); 01214 else 01215 #endif /* UNUSED */ 01216 tlim = pcb->settings.idle_time_limit; 01217 if (tlim > 0) 01218 TIMEOUT(check_idle, (void*)pcb, tlim); 01219 #endif /* PPP_IDLETIMELIMIT */ 01220 01221 #if PPP_MAXCONNECT 01222 /* 01223 * Set a timeout to close the connection once the maximum 01224 * connect time has expired. 01225 */ 01226 if (pcb->settings.maxconnect > 0) 01227 TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); 01228 #endif /* PPP_MAXCONNECT */ 01229 01230 #ifdef MAXOCTETS 01231 if (maxoctets > 0) 01232 TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); 01233 #endif 01234 01235 #if 0 /* Unused */ 01236 /* 01237 * Detach now, if the updetach option was given. 01238 */ 01239 if (updetach && !nodetach) 01240 detach(); 01241 #endif /* Unused */ 01242 } 01243 ++pcb->num_np_up; 01244 } 01245 01246 /* 01247 * np_down - a network protocol has gone down. 01248 */ 01249 void np_down(ppp_pcb *pcb, int proto) { 01250 LWIP_UNUSED_ARG(proto); 01251 if (--pcb->num_np_up == 0) { 01252 #if PPP_IDLETIMELIMIT 01253 UNTIMEOUT(check_idle, (void*)pcb); 01254 #endif /* PPP_IDLETIMELIMIT */ 01255 #if PPP_MAXCONNECT 01256 UNTIMEOUT(connect_time_expired, NULL); 01257 #endif /* PPP_MAXCONNECT */ 01258 #ifdef MAXOCTETS 01259 UNTIMEOUT(check_maxoctets, NULL); 01260 #endif 01261 new_phase(pcb, PPP_PHASE_NETWORK); 01262 } 01263 } 01264 01265 /* 01266 * np_finished - a network protocol has finished using the link. 01267 */ 01268 void np_finished(ppp_pcb *pcb, int proto) { 01269 LWIP_UNUSED_ARG(proto); 01270 if (--pcb->num_np_open <= 0) { 01271 /* no further use for the link: shut up shop. */ 01272 lcp_close(pcb, "No network protocols running"); 01273 } 01274 } 01275 01276 #ifdef MAXOCTETS 01277 static void 01278 check_maxoctets(arg) 01279 void *arg; 01280 { 01281 #if PPP_STATS_SUPPORT 01282 unsigned int used; 01283 01284 update_link_stats(ifunit); 01285 link_stats_valid=0; 01286 01287 switch(maxoctets_dir) { 01288 case PPP_OCTETS_DIRECTION_IN: 01289 used = link_stats.bytes_in; 01290 break; 01291 case PPP_OCTETS_DIRECTION_OUT: 01292 used = link_stats.bytes_out; 01293 break; 01294 case PPP_OCTETS_DIRECTION_MAXOVERAL: 01295 case PPP_OCTETS_DIRECTION_MAXSESSION: 01296 used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; 01297 break; 01298 default: 01299 used = link_stats.bytes_in+link_stats.bytes_out; 01300 break; 01301 } 01302 if (used > maxoctets) { 01303 ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); 01304 status = EXIT_TRAFFIC_LIMIT; 01305 lcp_close(pcb, "Traffic limit"); 01306 #if 0 /* UNUSED */ 01307 need_holdoff = 0; 01308 #endif /* UNUSED */ 01309 } else { 01310 TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); 01311 } 01312 #endif /* PPP_STATS_SUPPORT */ 01313 } 01314 #endif /* MAXOCTETS */ 01315 01316 #if PPP_IDLETIMELIMIT 01317 /* 01318 * check_idle - check whether the link has been idle for long 01319 * enough that we can shut it down. 01320 */ 01321 static void check_idle(void *arg) { 01322 ppp_pcb *pcb = (ppp_pcb*)arg; 01323 struct ppp_idle idle; 01324 time_t itime; 01325 int tlim; 01326 01327 if (!get_idle_time(pcb, &idle)) 01328 return; 01329 #if 0 /* UNUSED */ 01330 if (idle_time_hook != 0) { 01331 tlim = idle_time_hook(&idle); 01332 } else { 01333 #endif /* UNUSED */ 01334 itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); 01335 tlim = pcb->settings.idle_time_limit - itime; 01336 #if 0 /* UNUSED */ 01337 } 01338 #endif /* UNUSED */ 01339 if (tlim <= 0) { 01340 /* link is idle: shut it down. */ 01341 ppp_notice("Terminating connection due to lack of activity."); 01342 pcb->err_code = PPPERR_IDLETIMEOUT; 01343 lcp_close(pcb, "Link inactive"); 01344 #if 0 /* UNUSED */ 01345 need_holdoff = 0; 01346 #endif /* UNUSED */ 01347 } else { 01348 TIMEOUT(check_idle, (void*)pcb, tlim); 01349 } 01350 } 01351 #endif /* PPP_IDLETIMELIMIT */ 01352 01353 #if PPP_MAXCONNECT 01354 /* 01355 * connect_time_expired - log a message and close the connection. 01356 */ 01357 static void connect_time_expired(void *arg) { 01358 ppp_pcb *pcb = (ppp_pcb*)arg; 01359 ppp_info("Connect time expired"); 01360 pcb->err_code = PPPERR_CONNECTTIME; 01361 lcp_close(pcb, "Connect time expired"); /* Close connection */ 01362 } 01363 #endif /* PPP_MAXCONNECT */ 01364 01365 #if PPP_OPTIONS 01366 /* 01367 * auth_check_options - called to check authentication options. 01368 */ 01369 void 01370 auth_check_options() 01371 { 01372 lcp_options *wo = &lcp_wantoptions[0]; 01373 int can_auth; 01374 int lacks_ip; 01375 01376 /* Default our_name to hostname, and user to our_name */ 01377 if (our_name[0] == 0 || usehostname) 01378 strlcpy(our_name, hostname, sizeof(our_name)); 01379 /* If a blank username was explicitly given as an option, trust 01380 the user and don't use our_name */ 01381 if (ppp_settings.user[0] == 0 && !explicit_user) 01382 strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user)); 01383 01384 /* 01385 * If we have a default route, require the peer to authenticate 01386 * unless the noauth option was given or the real user is root. 01387 */ 01388 if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { 01389 auth_required = 1; 01390 default_auth = 1; 01391 } 01392 01393 #if CHAP_SUPPORT 01394 /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ 01395 if (wo->chap_mdtype) 01396 wo->neg_chap = 1; 01397 #endif /* CHAP_SUPPORT */ 01398 01399 /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ 01400 if (auth_required) { 01401 allow_any_ip = 0; 01402 if (1 01403 #if CHAP_SUPPORT 01404 && !wo->neg_chap 01405 #endif /* CHAP_SUPPORT */ 01406 #if PAP_SUPPORT 01407 && !wo->neg_upap 01408 #endif /* PAP_SUPPORT */ 01409 #if EAP_SUPPORT 01410 && !wo->neg_eap 01411 #endif /* EAP_SUPPORT */ 01412 ) { 01413 #if CHAP_SUPPORT 01414 wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE; 01415 wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED; 01416 #endif /* CHAP_SUPPORT */ 01417 #if PAP_SUPPORT 01418 wo->neg_upap = 1; 01419 #endif /* PAP_SUPPORT */ 01420 #if EAP_SUPPORT 01421 wo->neg_eap = 1; 01422 #endif /* EAP_SUPPORT */ 01423 } 01424 } else { 01425 #if CHAP_SUPPORT 01426 wo->neg_chap = 0; 01427 wo->chap_mdtype = MDTYPE_NONE; 01428 #endif /* CHAP_SUPPORT */ 01429 #if PAP_SUPPORT 01430 wo->neg_upap = 0; 01431 #endif /* PAP_SUPPORT */ 01432 #if EAP_SUPPORT 01433 wo->neg_eap = 0; 01434 #endif /* EAP_SUPPORT */ 01435 } 01436 01437 /* 01438 * Check whether we have appropriate secrets to use 01439 * to authenticate the peer. Note that EAP can authenticate by way 01440 * of a CHAP-like exchanges as well as SRP. 01441 */ 01442 lacks_ip = 0; 01443 #if PAP_SUPPORT 01444 can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); 01445 #else 01446 can_auth = 0; 01447 #endif /* PAP_SUPPORT */ 01448 if (!can_auth && (0 01449 #if CHAP_SUPPORT 01450 || wo->neg_chap 01451 #endif /* CHAP_SUPPORT */ 01452 #if EAP_SUPPORT 01453 || wo->neg_eap 01454 #endif /* EAP_SUPPORT */ 01455 )) { 01456 #if CHAP_SUPPORT 01457 can_auth = have_chap_secret((explicit_remote? remote_name: NULL), 01458 our_name, 1, &lacks_ip); 01459 #else 01460 can_auth = 0; 01461 #endif 01462 } 01463 if (!can_auth 01464 #if EAP_SUPPORT 01465 && wo->neg_eap 01466 #endif /* EAP_SUPPORT */ 01467 ) { 01468 can_auth = have_srp_secret((explicit_remote? remote_name: NULL), 01469 our_name, 1, &lacks_ip); 01470 } 01471 01472 if (auth_required && !can_auth && noauth_addrs == NULL) { 01473 if (default_auth) { 01474 option_error( 01475 "By default the remote system is required to authenticate itself"); 01476 option_error( 01477 "(because this system has a default route to the internet)"); 01478 } else if (explicit_remote) 01479 option_error( 01480 "The remote system (%s) is required to authenticate itself", 01481 remote_name); 01482 else 01483 option_error( 01484 "The remote system is required to authenticate itself"); 01485 option_error( 01486 "but I couldn't find any suitable secret (password) for it to use to do so."); 01487 if (lacks_ip) 01488 option_error( 01489 "(None of the available passwords would let it use an IP address.)"); 01490 01491 exit(1); 01492 } 01493 01494 /* 01495 * Early check for remote number authorization. 01496 */ 01497 if (!auth_number()) { 01498 ppp_warn("calling number %q is not authorized", remote_number); 01499 exit(EXIT_CNID_AUTH_FAILED); 01500 } 01501 } 01502 #endif /* PPP_OPTIONS */ 01503 01504 #if 0 /* UNUSED */ 01505 /* 01506 * auth_reset - called when LCP is starting negotiations to recheck 01507 * authentication options, i.e. whether we have appropriate secrets 01508 * to use for authenticating ourselves and/or the peer. 01509 */ 01510 void 01511 auth_reset(unit) 01512 int unit; 01513 { 01514 lcp_options *go = &lcp_gotoptions[unit]; 01515 lcp_options *ao = &lcp_allowoptions[unit]; 01516 int hadchap; 01517 01518 hadchap = -1; 01519 ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); 01520 ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) 01521 && (passwd[0] != 0 || 01522 (hadchap = have_chap_secret(user, (explicit_remote? remote_name: 01523 NULL), 0, NULL))); 01524 ao->neg_eap = !refuse_eap && ( 01525 passwd[0] != 0 || 01526 (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, 01527 (explicit_remote? remote_name: NULL), 0, NULL))) || 01528 have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); 01529 01530 hadchap = -1; 01531 if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) 01532 go->neg_upap = 0; 01533 if (go->neg_chap) { 01534 if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), 01535 our_name, 1, NULL))) 01536 go->neg_chap = 0; 01537 } 01538 if (go->neg_eap && 01539 (hadchap == 0 || (hadchap == -1 && 01540 !have_chap_secret((explicit_remote? remote_name: NULL), our_name, 01541 1, NULL))) && 01542 !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, 01543 NULL)) 01544 go->neg_eap = 0; 01545 } 01546 01547 /* 01548 * check_passwd - Check the user name and passwd against the PAP secrets 01549 * file. If requested, also check against the system password database, 01550 * and login the user if OK. 01551 * 01552 * returns: 01553 * UPAP_AUTHNAK: Authentication failed. 01554 * UPAP_AUTHACK: Authentication succeeded. 01555 * In either case, msg points to an appropriate message. 01556 */ 01557 int 01558 check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) 01559 int unit; 01560 char *auser; 01561 int userlen; 01562 char *apasswd; 01563 int passwdlen; 01564 char **msg; 01565 { 01566 return UPAP_AUTHNAK; 01567 int ret; 01568 char *filename; 01569 FILE *f; 01570 struct wordlist *addrs = NULL, *opts = NULL; 01571 char passwd[256], user[256]; 01572 char secret[MAXWORDLEN]; 01573 static int attempts = 0; 01574 01575 /* 01576 * Make copies of apasswd and auser, then null-terminate them. 01577 * If there are unprintable characters in the password, make 01578 * them visible. 01579 */ 01580 slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd); 01581 slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser); 01582 *msg = ""; 01583 01584 /* 01585 * Check if a plugin wants to handle this. 01586 */ 01587 if (pap_auth_hook) { 01588 ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts); 01589 if (ret >= 0) { 01590 /* note: set_allowed_addrs() saves opts (but not addrs): 01591 don't free it! */ 01592 if (ret) 01593 set_allowed_addrs(unit, addrs, opts); 01594 else if (opts != 0) 01595 free_wordlist(opts); 01596 if (addrs != 0) 01597 free_wordlist(addrs); 01598 BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); 01599 return ret? UPAP_AUTHACK: UPAP_AUTHNAK; 01600 } 01601 } 01602 01603 /* 01604 * Open the file of pap secrets and scan for a suitable secret 01605 * for authenticating this user. 01606 */ 01607 filename = _PATH_UPAPFILE; 01608 addrs = opts = NULL; 01609 ret = UPAP_AUTHNAK; 01610 f = fopen(filename, "r"); 01611 if (f == NULL) { 01612 ppp_error("Can't open PAP password file %s: %m", filename); 01613 01614 } else { 01615 check_access(f, filename); 01616 if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { 01617 ppp_warn("no PAP secret found for %s", user); 01618 } else { 01619 /* 01620 * If the secret is "@login", it means to check 01621 * the password against the login database. 01622 */ 01623 int login_secret = strcmp(secret, "@login") == 0; 01624 ret = UPAP_AUTHACK; 01625 if (uselogin || login_secret) { 01626 /* login option or secret is @login */ 01627 if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) { 01628 ret = UPAP_AUTHNAK; 01629 } 01630 } else if (session_mgmt) { 01631 if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { 01632 ppp_warn("Peer %q failed PAP Session verification", user); 01633 ret = UPAP_AUTHNAK; 01634 } 01635 } 01636 if (secret[0] != 0 && !login_secret) { 01637 /* password given in pap-secrets - must match */ 01638 if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0) 01639 && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0) 01640 ret = UPAP_AUTHNAK; 01641 } 01642 } 01643 fclose(f); 01644 } 01645 01646 if (ret == UPAP_AUTHNAK) { 01647 if (**msg == 0) 01648 *msg = "Login incorrect"; 01649 /* 01650 * XXX can we ever get here more than once?? 01651 * Frustrate passwd stealer programs. 01652 * Allow 10 tries, but start backing off after 3 (stolen from login). 01653 * On 10'th, drop the connection. 01654 */ 01655 if (attempts++ >= 10) { 01656 ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); 01657 lcp_close(pcb, "login failed"); 01658 } 01659 if (attempts > 3) 01660 sleep((u_int) (attempts - 3) * 5); 01661 if (opts != NULL) 01662 free_wordlist(opts); 01663 01664 } else { 01665 attempts = 0; /* Reset count */ 01666 if (**msg == 0) 01667 *msg = "Login ok"; 01668 set_allowed_addrs(unit, addrs, opts); 01669 } 01670 01671 if (addrs != NULL) 01672 free_wordlist(addrs); 01673 BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); 01674 BZERO(secret, sizeof(secret)); 01675 01676 return ret; 01677 } 01678 01679 /* 01680 * null_login - Check if a username of "" and a password of "" are 01681 * acceptable, and iff so, set the list of acceptable IP addresses 01682 * and return 1. 01683 */ 01684 static int 01685 null_login(unit) 01686 int unit; 01687 { 01688 char *filename; 01689 FILE *f; 01690 int i, ret; 01691 struct wordlist *addrs, *opts; 01692 char secret[MAXWORDLEN]; 01693 01694 /* 01695 * Check if a plugin wants to handle this. 01696 */ 01697 ret = -1; 01698 if (null_auth_hook) 01699 ret = (*null_auth_hook)(&addrs, &opts); 01700 01701 /* 01702 * Open the file of pap secrets and scan for a suitable secret. 01703 */ 01704 if (ret <= 0) { 01705 filename = _PATH_UPAPFILE; 01706 addrs = NULL; 01707 f = fopen(filename, "r"); 01708 if (f == NULL) 01709 return 0; 01710 check_access(f, filename); 01711 01712 i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); 01713 ret = i >= 0 && secret[0] == 0; 01714 BZERO(secret, sizeof(secret)); 01715 fclose(f); 01716 } 01717 01718 if (ret) 01719 set_allowed_addrs(unit, addrs, opts); 01720 else if (opts != 0) 01721 free_wordlist(opts); 01722 if (addrs != 0) 01723 free_wordlist(addrs); 01724 01725 return ret; 01726 } 01727 01728 /* 01729 * get_pap_passwd - get a password for authenticating ourselves with 01730 * our peer using PAP. Returns 1 on success, 0 if no suitable password 01731 * could be found. 01732 * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). 01733 */ 01734 static int 01735 get_pap_passwd(passwd) 01736 char *passwd; 01737 { 01738 char *filename; 01739 FILE *f; 01740 int ret; 01741 char secret[MAXWORDLEN]; 01742 01743 /* 01744 * Check whether a plugin wants to supply this. 01745 */ 01746 if (pap_passwd_hook) { 01747 ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd); 01748 if (ret >= 0) 01749 return ret; 01750 } 01751 01752 filename = _PATH_UPAPFILE; 01753 f = fopen(filename, "r"); 01754 if (f == NULL) 01755 return 0; 01756 check_access(f, filename); 01757 ret = scan_authfile(f, user, 01758 (remote_name[0]? remote_name: NULL), 01759 secret, NULL, NULL, filename, 0); 01760 fclose(f); 01761 if (ret < 0) 01762 return 0; 01763 if (passwd != NULL) 01764 strlcpy(passwd, secret, MAXSECRETLEN); 01765 BZERO(secret, sizeof(secret)); 01766 return 1; 01767 } 01768 01769 /* 01770 * have_pap_secret - check whether we have a PAP file with any 01771 * secrets that we could possibly use for authenticating the peer. 01772 */ 01773 static int 01774 have_pap_secret(lacks_ipp) 01775 int *lacks_ipp; 01776 { 01777 FILE *f; 01778 int ret; 01779 char *filename; 01780 struct wordlist *addrs; 01781 01782 /* let the plugin decide, if there is one */ 01783 if (pap_check_hook) { 01784 ret = (*pap_check_hook)(); 01785 if (ret >= 0) 01786 return ret; 01787 } 01788 01789 filename = _PATH_UPAPFILE; 01790 f = fopen(filename, "r"); 01791 if (f == NULL) 01792 return 0; 01793 01794 ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, 01795 NULL, &addrs, NULL, filename, 0); 01796 fclose(f); 01797 if (ret >= 0 && !some_ip_ok(addrs)) { 01798 if (lacks_ipp != 0) 01799 *lacks_ipp = 1; 01800 ret = -1; 01801 } 01802 if (addrs != 0) 01803 free_wordlist(addrs); 01804 01805 return ret >= 0; 01806 } 01807 01808 /* 01809 * have_chap_secret - check whether we have a CHAP file with a 01810 * secret that we could possibly use for authenticating `client' 01811 * on `server'. Either can be the null string, meaning we don't 01812 * know the identity yet. 01813 */ 01814 static int 01815 have_chap_secret(client, server, need_ip, lacks_ipp) 01816 char *client; 01817 char *server; 01818 int need_ip; 01819 int *lacks_ipp; 01820 { 01821 FILE *f; 01822 int ret; 01823 char *filename; 01824 struct wordlist *addrs; 01825 01826 if (chap_check_hook) { 01827 ret = (*chap_check_hook)(); 01828 if (ret >= 0) { 01829 return ret; 01830 } 01831 } 01832 01833 filename = _PATH_CHAPFILE; 01834 f = fopen(filename, "r"); 01835 if (f == NULL) 01836 return 0; 01837 01838 if (client != NULL && client[0] == 0) 01839 client = NULL; 01840 else if (server != NULL && server[0] == 0) 01841 server = NULL; 01842 01843 ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); 01844 fclose(f); 01845 if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { 01846 if (lacks_ipp != 0) 01847 *lacks_ipp = 1; 01848 ret = -1; 01849 } 01850 if (addrs != 0) 01851 free_wordlist(addrs); 01852 01853 return ret >= 0; 01854 } 01855 01856 /* 01857 * have_srp_secret - check whether we have a SRP file with a 01858 * secret that we could possibly use for authenticating `client' 01859 * on `server'. Either can be the null string, meaning we don't 01860 * know the identity yet. 01861 */ 01862 static int 01863 have_srp_secret(client, server, need_ip, lacks_ipp) 01864 char *client; 01865 char *server; 01866 int need_ip; 01867 int *lacks_ipp; 01868 { 01869 FILE *f; 01870 int ret; 01871 char *filename; 01872 struct wordlist *addrs; 01873 01874 filename = _PATH_SRPFILE; 01875 f = fopen(filename, "r"); 01876 if (f == NULL) 01877 return 0; 01878 01879 if (client != NULL && client[0] == 0) 01880 client = NULL; 01881 else if (server != NULL && server[0] == 0) 01882 server = NULL; 01883 01884 ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); 01885 fclose(f); 01886 if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { 01887 if (lacks_ipp != 0) 01888 *lacks_ipp = 1; 01889 ret = -1; 01890 } 01891 if (addrs != 0) 01892 free_wordlist(addrs); 01893 01894 return ret >= 0; 01895 } 01896 #endif /* UNUSED */ 01897 01898 #if PPP_AUTH_SUPPORT 01899 /* 01900 * get_secret - open the CHAP secret file and return the secret 01901 * for authenticating the given client on the given server. 01902 * (We could be either client or server). 01903 */ 01904 int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server) { 01905 int len; 01906 LWIP_UNUSED_ARG(server); 01907 LWIP_UNUSED_ARG(am_server); 01908 01909 if (!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) { 01910 return 0; 01911 } 01912 01913 len = (int)strlen(pcb->settings.passwd); 01914 if (len > MAXSECRETLEN) { 01915 ppp_error("Secret for %s on %s is too long", client, server); 01916 len = MAXSECRETLEN; 01917 } 01918 01919 MEMCPY(secret, pcb->settings.passwd, len); 01920 *secret_len = len; 01921 return 1; 01922 01923 #if 0 /* UNUSED */ 01924 FILE *f; 01925 int ret, len; 01926 char *filename; 01927 struct wordlist *addrs, *opts; 01928 char secbuf[MAXWORDLEN]; 01929 struct wordlist *addrs; 01930 addrs = NULL; 01931 01932 if (!am_server && ppp_settings.passwd[0] != 0) { 01933 strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); 01934 } else if (!am_server && chap_passwd_hook) { 01935 if ( (*chap_passwd_hook)(client, secbuf) < 0) { 01936 ppp_error("Unable to obtain CHAP password for %s on %s from plugin", 01937 client, server); 01938 return 0; 01939 } 01940 } else { 01941 filename = _PATH_CHAPFILE; 01942 addrs = NULL; 01943 secbuf[0] = 0; 01944 01945 f = fopen(filename, "r"); 01946 if (f == NULL) { 01947 ppp_error("Can't open chap secret file %s: %m", filename); 01948 return 0; 01949 } 01950 check_access(f, filename); 01951 01952 ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); 01953 fclose(f); 01954 if (ret < 0) 01955 return 0; 01956 01957 if (am_server) 01958 set_allowed_addrs(unit, addrs, opts); 01959 else if (opts != 0) 01960 free_wordlist(opts); 01961 if (addrs != 0) 01962 free_wordlist(addrs); 01963 } 01964 01965 len = strlen(secbuf); 01966 if (len > MAXSECRETLEN) { 01967 ppp_error("Secret for %s on %s is too long", client, server); 01968 len = MAXSECRETLEN; 01969 } 01970 MEMCPY(secret, secbuf, len); 01971 BZERO(secbuf, sizeof(secbuf)); 01972 *secret_len = len; 01973 01974 return 1; 01975 #endif /* UNUSED */ 01976 } 01977 #endif /* PPP_AUTH_SUPPORT */ 01978 01979 01980 #if 0 /* UNUSED */ 01981 /* 01982 * get_srp_secret - open the SRP secret file and return the secret 01983 * for authenticating the given client on the given server. 01984 * (We could be either client or server). 01985 */ 01986 int 01987 get_srp_secret(unit, client, server, secret, am_server) 01988 int unit; 01989 char *client; 01990 char *server; 01991 char *secret; 01992 int am_server; 01993 { 01994 FILE *fp; 01995 int ret; 01996 char *filename; 01997 struct wordlist *addrs, *opts; 01998 01999 if (!am_server && ppp_settings.passwd[0] != '\0') { 02000 strlcpy(secret, ppp_settings.passwd, MAXWORDLEN); 02001 } else { 02002 filename = _PATH_SRPFILE; 02003 addrs = NULL; 02004 02005 fp = fopen(filename, "r"); 02006 if (fp == NULL) { 02007 ppp_error("Can't open srp secret file %s: %m", filename); 02008 return 0; 02009 } 02010 check_access(fp, filename); 02011 02012 secret[0] = '\0'; 02013 ret = scan_authfile(fp, client, server, secret, &addrs, &opts, 02014 filename, am_server); 02015 fclose(fp); 02016 if (ret < 0) 02017 return 0; 02018 02019 if (am_server) 02020 set_allowed_addrs(unit, addrs, opts); 02021 else if (opts != NULL) 02022 free_wordlist(opts); 02023 if (addrs != NULL) 02024 free_wordlist(addrs); 02025 } 02026 02027 return 1; 02028 } 02029 02030 /* 02031 * set_allowed_addrs() - set the list of allowed addresses. 02032 * Also looks for `--' indicating options to apply for this peer 02033 * and leaves the following words in extra_options. 02034 */ 02035 static void 02036 set_allowed_addrs(unit, addrs, opts) 02037 int unit; 02038 struct wordlist *addrs; 02039 struct wordlist *opts; 02040 { 02041 int n; 02042 struct wordlist *ap, **plink; 02043 struct permitted_ip *ip; 02044 char *ptr_word, *ptr_mask; 02045 struct hostent *hp; 02046 struct netent *np; 02047 u32_t a, mask, ah, offset; 02048 struct ipcp_options *wo = &ipcp_wantoptions[unit]; 02049 u32_t suggested_ip = 0; 02050 02051 if (addresses[unit] != NULL) 02052 free(addresses[unit]); 02053 addresses[unit] = NULL; 02054 if (extra_options != NULL) 02055 free_wordlist(extra_options); 02056 extra_options = opts; 02057 02058 /* 02059 * Count the number of IP addresses given. 02060 */ 02061 n = wordlist_count(addrs) + wordlist_count(noauth_addrs); 02062 if (n == 0) 02063 return; 02064 ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); 02065 if (ip == 0) 02066 return; 02067 02068 /* temporarily append the noauth_addrs list to addrs */ 02069 for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) 02070 ; 02071 *plink = noauth_addrs; 02072 02073 n = 0; 02074 for (ap = addrs; ap != NULL; ap = ap->next) { 02075 /* "-" means no addresses authorized, "*" means any address allowed */ 02076 ptr_word = ap->word; 02077 if (strcmp(ptr_word, "-") == 0) 02078 break; 02079 if (strcmp(ptr_word, "*") == 0) { 02080 ip[n].permit = 1; 02081 ip[n].base = ip[n].mask = 0; 02082 ++n; 02083 break; 02084 } 02085 02086 ip[n].permit = 1; 02087 if (*ptr_word == '!') { 02088 ip[n].permit = 0; 02089 ++ptr_word; 02090 } 02091 02092 mask = ~ (u32_t) 0; 02093 offset = 0; 02094 ptr_mask = strchr (ptr_word, '/'); 02095 if (ptr_mask != NULL) { 02096 int bit_count; 02097 char *endp; 02098 02099 bit_count = (int) strtol (ptr_mask+1, &endp, 10); 02100 if (bit_count <= 0 || bit_count > 32) { 02101 ppp_warn("invalid address length %v in auth. address list", 02102 ptr_mask+1); 02103 continue; 02104 } 02105 bit_count = 32 - bit_count; /* # bits in host part */ 02106 if (*endp == '+') { 02107 offset = ifunit + 1; 02108 ++endp; 02109 } 02110 if (*endp != 0) { 02111 ppp_warn("invalid address length syntax: %v", ptr_mask+1); 02112 continue; 02113 } 02114 *ptr_mask = '\0'; 02115 mask <<= bit_count; 02116 } 02117 02118 hp = gethostbyname(ptr_word); 02119 if (hp != NULL && hp->h_addrtype == AF_INET) { 02120 a = *(u32_t *)hp->h_addr; 02121 } else { 02122 np = getnetbyname (ptr_word); 02123 if (np != NULL && np->n_addrtype == AF_INET) { 02124 a = lwip_htonl ((u32_t)np->n_net); 02125 if (ptr_mask == NULL) { 02126 /* calculate appropriate mask for net */ 02127 ah = lwip_ntohl(a); 02128 if (IN_CLASSA(ah)) 02129 mask = IN_CLASSA_NET; 02130 else if (IN_CLASSB(ah)) 02131 mask = IN_CLASSB_NET; 02132 else if (IN_CLASSC(ah)) 02133 mask = IN_CLASSC_NET; 02134 } 02135 } else { 02136 a = inet_addr (ptr_word); 02137 } 02138 } 02139 02140 if (ptr_mask != NULL) 02141 *ptr_mask = '/'; 02142 02143 if (a == (u32_t)-1L) { 02144 ppp_warn("unknown host %s in auth. address list", ap->word); 02145 continue; 02146 } 02147 if (offset != 0) { 02148 if (offset >= ~mask) { 02149 ppp_warn("interface unit %d too large for subnet %v", 02150 ifunit, ptr_word); 02151 continue; 02152 } 02153 a = lwip_htonl((lwip_ntohl(a) & mask) + offset); 02154 mask = ~(u32_t)0; 02155 } 02156 ip[n].mask = lwip_htonl(mask); 02157 ip[n].base = a & ip[n].mask; 02158 ++n; 02159 if (~mask == 0 && suggested_ip == 0) 02160 suggested_ip = a; 02161 } 02162 *plink = NULL; 02163 02164 ip[n].permit = 0; /* make the last entry forbid all addresses */ 02165 ip[n].base = 0; /* to terminate the list */ 02166 ip[n].mask = 0; 02167 02168 addresses[unit] = ip; 02169 02170 /* 02171 * If the address given for the peer isn't authorized, or if 02172 * the user hasn't given one, AND there is an authorized address 02173 * which is a single host, then use that if we find one. 02174 */ 02175 if (suggested_ip != 0 02176 && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { 02177 wo->hisaddr = suggested_ip; 02178 /* 02179 * Do we insist on this address? No, if there are other 02180 * addresses authorized than the suggested one. 02181 */ 02182 if (n > 1) 02183 wo->accept_remote = 1; 02184 } 02185 } 02186 02187 /* 02188 * auth_ip_addr - check whether the peer is authorized to use 02189 * a given IP address. Returns 1 if authorized, 0 otherwise. 02190 */ 02191 int 02192 auth_ip_addr(unit, addr) 02193 int unit; 02194 u32_t addr; 02195 { 02196 int ok; 02197 02198 /* don't allow loopback or multicast address */ 02199 if (bad_ip_adrs(addr)) 02200 return 0; 02201 02202 if (allowed_address_hook) { 02203 ok = allowed_address_hook(addr); 02204 if (ok >= 0) return ok; 02205 } 02206 02207 if (addresses[unit] != NULL) { 02208 ok = ip_addr_check(addr, addresses[unit]); 02209 if (ok >= 0) 02210 return ok; 02211 } 02212 02213 if (auth_required) 02214 return 0; /* no addresses authorized */ 02215 return allow_any_ip || privileged || !have_route_to(addr); 02216 } 02217 02218 static int 02219 ip_addr_check(addr, addrs) 02220 u32_t addr; 02221 struct permitted_ip *addrs; 02222 { 02223 for (; ; ++addrs) 02224 if ((addr & addrs->mask) == addrs->base) 02225 return addrs->permit; 02226 } 02227 02228 /* 02229 * bad_ip_adrs - return 1 if the IP address is one we don't want 02230 * to use, such as an address in the loopback net or a multicast address. 02231 * addr is in network byte order. 02232 */ 02233 int 02234 bad_ip_adrs(addr) 02235 u32_t addr; 02236 { 02237 addr = lwip_ntohl(addr); 02238 return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET 02239 || IN_MULTICAST(addr) || IN_BADCLASS(addr); 02240 } 02241 02242 /* 02243 * some_ip_ok - check a wordlist to see if it authorizes any 02244 * IP address(es). 02245 */ 02246 static int 02247 some_ip_ok(addrs) 02248 struct wordlist *addrs; 02249 { 02250 for (; addrs != 0; addrs = addrs->next) { 02251 if (addrs->word[0] == '-') 02252 break; 02253 if (addrs->word[0] != '!') 02254 return 1; /* some IP address is allowed */ 02255 } 02256 return 0; 02257 } 02258 02259 /* 02260 * auth_number - check whether the remote number is allowed to connect. 02261 * Returns 1 if authorized, 0 otherwise. 02262 */ 02263 int 02264 auth_number() 02265 { 02266 struct wordlist *wp = permitted_numbers; 02267 int l; 02268 02269 /* Allow all if no authorization list. */ 02270 if (!wp) 02271 return 1; 02272 02273 /* Allow if we have a match in the authorization list. */ 02274 while (wp) { 02275 /* trailing '*' wildcard */ 02276 l = strlen(wp->word); 02277 if ((wp->word)[l - 1] == '*') 02278 l--; 02279 if (!strncasecmp(wp->word, remote_number, l)) 02280 return 1; 02281 wp = wp->next; 02282 } 02283 02284 return 0; 02285 } 02286 02287 /* 02288 * check_access - complain if a secret file has too-liberal permissions. 02289 */ 02290 static void 02291 check_access(f, filename) 02292 FILE *f; 02293 char *filename; 02294 { 02295 struct stat sbuf; 02296 02297 if (fstat(fileno(f), &sbuf) < 0) { 02298 ppp_warn("cannot stat secret file %s: %m", filename); 02299 } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { 02300 ppp_warn("Warning - secret file %s has world and/or group access", 02301 filename); 02302 } 02303 } 02304 02305 /* 02306 * scan_authfile - Scan an authorization file for a secret suitable 02307 * for authenticating `client' on `server'. The return value is -1 02308 * if no secret is found, otherwise >= 0. The return value has 02309 * NONWILD_CLIENT set if the secret didn't have "*" for the client, and 02310 * NONWILD_SERVER set if the secret didn't have "*" for the server. 02311 * Any following words on the line up to a "--" (i.e. address authorization 02312 * info) are placed in a wordlist and returned in *addrs. Any 02313 * following words (extra options) are placed in a wordlist and 02314 * returned in *opts. 02315 * We assume secret is NULL or points to MAXWORDLEN bytes of space. 02316 * Flags are non-zero if we need two colons in the secret in order to 02317 * match. 02318 */ 02319 static int 02320 scan_authfile(f, client, server, secret, addrs, opts, filename, flags) 02321 FILE *f; 02322 char *client; 02323 char *server; 02324 char *secret; 02325 struct wordlist **addrs; 02326 struct wordlist **opts; 02327 char *filename; 02328 int flags; 02329 { 02330 int newline, xxx; 02331 int got_flag, best_flag; 02332 FILE *sf; 02333 struct wordlist *ap, *addr_list, *alist, **app; 02334 char word[MAXWORDLEN]; 02335 char atfile[MAXWORDLEN]; 02336 char lsecret[MAXWORDLEN]; 02337 char *cp; 02338 02339 if (addrs != NULL) 02340 *addrs = NULL; 02341 if (opts != NULL) 02342 *opts = NULL; 02343 addr_list = NULL; 02344 if (!getword(f, word, &newline, filename)) 02345 return -1; /* file is empty??? */ 02346 newline = 1; 02347 best_flag = -1; 02348 for (;;) { 02349 /* 02350 * Skip until we find a word at the start of a line. 02351 */ 02352 while (!newline && getword(f, word, &newline, filename)) 02353 ; 02354 if (!newline) 02355 break; /* got to end of file */ 02356 02357 /* 02358 * Got a client - check if it's a match or a wildcard. 02359 */ 02360 got_flag = 0; 02361 if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { 02362 newline = 0; 02363 continue; 02364 } 02365 if (!ISWILD(word)) 02366 got_flag = NONWILD_CLIENT; 02367 02368 /* 02369 * Now get a server and check if it matches. 02370 */ 02371 if (!getword(f, word, &newline, filename)) 02372 break; 02373 if (newline) 02374 continue; 02375 if (!ISWILD(word)) { 02376 if (server != NULL && strcmp(word, server) != 0) 02377 continue; 02378 got_flag |= NONWILD_SERVER; 02379 } 02380 02381 /* 02382 * Got some sort of a match - see if it's better than what 02383 * we have already. 02384 */ 02385 if (got_flag <= best_flag) 02386 continue; 02387 02388 /* 02389 * Get the secret. 02390 */ 02391 if (!getword(f, word, &newline, filename)) 02392 break; 02393 if (newline) 02394 continue; 02395 02396 /* 02397 * SRP-SHA1 authenticator should never be reading secrets from 02398 * a file. (Authenticatee may, though.) 02399 */ 02400 if (flags && ((cp = strchr(word, ':')) == NULL || 02401 strchr(cp + 1, ':') == NULL)) 02402 continue; 02403 02404 if (secret != NULL) { 02405 /* 02406 * Special syntax: @/pathname means read secret from file. 02407 */ 02408 if (word[0] == '@' && word[1] == '/') { 02409 strlcpy(atfile, word+1, sizeof(atfile)); 02410 if ((sf = fopen(atfile, "r")) == NULL) { 02411 ppp_warn("can't open indirect secret file %s", atfile); 02412 continue; 02413 } 02414 check_access(sf, atfile); 02415 if (!getword(sf, word, &xxx, atfile)) { 02416 ppp_warn("no secret in indirect secret file %s", atfile); 02417 fclose(sf); 02418 continue; 02419 } 02420 fclose(sf); 02421 } 02422 strlcpy(lsecret, word, sizeof(lsecret)); 02423 } 02424 02425 /* 02426 * Now read address authorization info and make a wordlist. 02427 */ 02428 app = &alist; 02429 for (;;) { 02430 if (!getword(f, word, &newline, filename) || newline) 02431 break; 02432 ap = (struct wordlist *) 02433 malloc(sizeof(struct wordlist) + strlen(word) + 1); 02434 if (ap == NULL) 02435 novm("authorized addresses"); 02436 ap->word = (char *) (ap + 1); 02437 strcpy(ap->word, word); 02438 *app = ap; 02439 app = &ap->next; 02440 } 02441 *app = NULL; 02442 02443 /* 02444 * This is the best so far; remember it. 02445 */ 02446 best_flag = got_flag; 02447 if (addr_list) 02448 free_wordlist(addr_list); 02449 addr_list = alist; 02450 if (secret != NULL) 02451 strlcpy(secret, lsecret, MAXWORDLEN); 02452 02453 if (!newline) 02454 break; 02455 } 02456 02457 /* scan for a -- word indicating the start of options */ 02458 for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) 02459 if (strcmp(ap->word, "--") == 0) 02460 break; 02461 /* ap = start of options */ 02462 if (ap != NULL) { 02463 ap = ap->next; /* first option */ 02464 free(*app); /* free the "--" word */ 02465 *app = NULL; /* terminate addr list */ 02466 } 02467 if (opts != NULL) 02468 *opts = ap; 02469 else if (ap != NULL) 02470 free_wordlist(ap); 02471 if (addrs != NULL) 02472 *addrs = addr_list; 02473 else if (addr_list != NULL) 02474 free_wordlist(addr_list); 02475 02476 return best_flag; 02477 } 02478 02479 /* 02480 * wordlist_count - return the number of items in a wordlist 02481 */ 02482 static int 02483 wordlist_count(wp) 02484 struct wordlist *wp; 02485 { 02486 int n; 02487 02488 for (n = 0; wp != NULL; wp = wp->next) 02489 ++n; 02490 return n; 02491 } 02492 02493 /* 02494 * free_wordlist - release memory allocated for a wordlist. 02495 */ 02496 static void 02497 free_wordlist(wp) 02498 struct wordlist *wp; 02499 { 02500 struct wordlist *next; 02501 02502 while (wp != NULL) { 02503 next = wp->next; 02504 free(wp); 02505 wp = next; 02506 } 02507 } 02508 #endif /* UNUSED */ 02509 02510 #endif /* PPP_SUPPORT */
Generated on Fri Jul 22 2022 04:53:51 by
1.7.2
