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_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 || pcb->phase == PPP_PHASE_MASTER) 00622 return; 00623 new_phase(pcb, PPP_PHASE_DISCONNECT); 00624 00625 #if 0 /* UNUSED */ 00626 if (pap_logout_hook) { 00627 pap_logout_hook(); 00628 } 00629 session_end(devnam); 00630 #endif /* UNUSED */ 00631 00632 if (!doing_multilink) { 00633 ppp_notice("Connection terminated."); 00634 #if PPP_STATS_SUPPORT 00635 print_link_stats(); 00636 #endif /* PPP_STATS_SUPPORT */ 00637 } else 00638 ppp_notice("Link terminated."); 00639 00640 lcp_lowerdown(pcb); 00641 00642 new_phase(pcb, PPP_PHASE_DEAD); 00643 ppp_link_terminated(pcb); 00644 #if 0 00645 /* 00646 * Delete pid files before disestablishing ppp. Otherwise it 00647 * can happen that another pppd gets the same unit and then 00648 * we delete its pid file. 00649 */ 00650 if (!doing_multilink && !demand) 00651 remove_pidfiles(); 00652 00653 /* 00654 * If we may want to bring the link up again, transfer 00655 * the ppp unit back to the loopback. Set the 00656 * real serial device back to its normal mode of operation. 00657 */ 00658 if (fd_ppp >= 0) { 00659 remove_fd(fd_ppp); 00660 clean_check(); 00661 the_channel->disestablish_ppp(devfd); 00662 if (doing_multilink) 00663 mp_exit_bundle(); 00664 fd_ppp = -1; 00665 } 00666 if (!hungup) 00667 lcp_lowerdown(pcb); 00668 if (!doing_multilink && !demand) 00669 script_unsetenv("IFNAME"); 00670 00671 /* 00672 * Run disconnector script, if requested. 00673 * XXX we may not be able to do this if the line has hung up! 00674 */ 00675 if (devfd >= 0 && the_channel->disconnect) { 00676 the_channel->disconnect(); 00677 devfd = -1; 00678 } 00679 if (the_channel->cleanup) 00680 (*the_channel->cleanup)(); 00681 00682 if (doing_multilink && multilink_master) { 00683 if (!bundle_terminating) 00684 new_phase(pcb, PPP_PHASE_MASTER); 00685 else 00686 mp_bundle_terminated(); 00687 } else 00688 new_phase(pcb, PPP_PHASE_DEAD); 00689 #endif 00690 } 00691 00692 /* 00693 * LCP has gone down; it will either die or try to re-establish. 00694 */ 00695 void link_down(ppp_pcb *pcb) { 00696 #if PPP_NOTIFY 00697 notify(link_down_notifier, 0); 00698 #endif /* PPP_NOTIFY */ 00699 00700 if (!doing_multilink) { 00701 upper_layers_down(pcb); 00702 if (pcb->phase != PPP_PHASE_DEAD && pcb->phase != PPP_PHASE_MASTER) 00703 new_phase(pcb, PPP_PHASE_ESTABLISH); 00704 } 00705 /* XXX if doing_multilink, should do something to stop 00706 network-layer traffic on the link */ 00707 } 00708 00709 void upper_layers_down(ppp_pcb *pcb) { 00710 int i; 00711 const struct protent *protp; 00712 00713 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 00714 if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) 00715 (*protp->lowerdown)(pcb); 00716 if (protp->protocol < 0xC000 && protp->close != NULL) 00717 (*protp->close)(pcb, "LCP down"); 00718 } 00719 pcb->num_np_open = 0; 00720 pcb->num_np_up = 0; 00721 } 00722 00723 /* 00724 * The link is established. 00725 * Proceed to the Dead, Authenticate or Network phase as appropriate. 00726 */ 00727 void link_established(ppp_pcb *pcb) { 00728 #if PPP_AUTH_SUPPORT 00729 int auth; 00730 #if PPP_SERVER 00731 #if PAP_SUPPORT 00732 lcp_options *wo = &pcb->lcp_wantoptions; 00733 #endif /* PAP_SUPPORT */ 00734 lcp_options *go = &pcb->lcp_gotoptions; 00735 #endif /* PPP_SERVER */ 00736 lcp_options *ho = &pcb->lcp_hisoptions; 00737 #endif /* PPP_AUTH_SUPPORT */ 00738 int i; 00739 const struct protent *protp; 00740 00741 /* 00742 * Tell higher-level protocols that LCP is up. 00743 */ 00744 if (!doing_multilink) { 00745 for (i = 0; (protp = protocols[i]) != NULL; ++i) 00746 if (protp->protocol != PPP_LCP 00747 && protp->lowerup != NULL) 00748 (*protp->lowerup)(pcb); 00749 } 00750 00751 #if PPP_AUTH_SUPPORT 00752 #if PPP_SERVER 00753 #if PPP_ALLOWED_ADDRS 00754 if (!auth_required && noauth_addrs != NULL) 00755 set_allowed_addrs(unit, NULL, NULL); 00756 #endif /* PPP_ALLOWED_ADDRS */ 00757 00758 if (pcb->settings.auth_required && !(0 00759 #if PAP_SUPPORT 00760 || go->neg_upap 00761 #endif /* PAP_SUPPORT */ 00762 #if CHAP_SUPPORT 00763 || go->neg_chap 00764 #endif /* CHAP_SUPPORT */ 00765 #if EAP_SUPPORT 00766 || go->neg_eap 00767 #endif /* EAP_SUPPORT */ 00768 )) { 00769 00770 #if PPP_ALLOWED_ADDRS 00771 /* 00772 * We wanted the peer to authenticate itself, and it refused: 00773 * if we have some address(es) it can use without auth, fine, 00774 * otherwise treat it as though it authenticated with PAP using 00775 * a username of "" and a password of "". If that's not OK, 00776 * boot it out. 00777 */ 00778 if (noauth_addrs != NULL) { 00779 set_allowed_addrs(unit, NULL, NULL); 00780 } else 00781 #endif /* PPP_ALLOWED_ADDRS */ 00782 if (!pcb->settings.null_login 00783 #if PAP_SUPPORT 00784 || !wo->neg_upap 00785 #endif /* PAP_SUPPORT */ 00786 ) { 00787 ppp_warn("peer refused to authenticate: terminating link"); 00788 #if 0 /* UNUSED */ 00789 status = EXIT_PEER_AUTH_FAILED; 00790 #endif /* UNUSED */ 00791 pcb->err_code = PPPERR_AUTHFAIL; 00792 lcp_close(pcb, "peer refused to authenticate"); 00793 return; 00794 } 00795 } 00796 #endif /* PPP_SERVER */ 00797 00798 new_phase(pcb, PPP_PHASE_AUTHENTICATE); 00799 auth = 0; 00800 #if PPP_SERVER 00801 #if EAP_SUPPORT 00802 if (go->neg_eap) { 00803 eap_authpeer(pcb, PPP_OUR_NAME); 00804 auth |= EAP_PEER; 00805 } else 00806 #endif /* EAP_SUPPORT */ 00807 #if CHAP_SUPPORT 00808 if (go->neg_chap) { 00809 chap_auth_peer(pcb, PPP_OUR_NAME, CHAP_DIGEST(go->chap_mdtype)); 00810 auth |= CHAP_PEER; 00811 } else 00812 #endif /* CHAP_SUPPORT */ 00813 #if PAP_SUPPORT 00814 if (go->neg_upap) { 00815 upap_authpeer(pcb); 00816 auth |= PAP_PEER; 00817 } else 00818 #endif /* PAP_SUPPORT */ 00819 {} 00820 #endif /* PPP_SERVER */ 00821 00822 #if EAP_SUPPORT 00823 if (ho->neg_eap) { 00824 eap_authwithpeer(pcb, pcb->settings.user); 00825 auth |= EAP_WITHPEER; 00826 } else 00827 #endif /* EAP_SUPPORT */ 00828 #if CHAP_SUPPORT 00829 if (ho->neg_chap) { 00830 chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); 00831 auth |= CHAP_WITHPEER; 00832 } else 00833 #endif /* CHAP_SUPPORT */ 00834 #if PAP_SUPPORT 00835 if (ho->neg_upap) { 00836 upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd); 00837 auth |= PAP_WITHPEER; 00838 } else 00839 #endif /* PAP_SUPPORT */ 00840 {} 00841 00842 pcb->auth_pending = auth; 00843 pcb->auth_done = 0; 00844 00845 if (!auth) 00846 #endif /* PPP_AUTH_SUPPORT */ 00847 network_phase(pcb); 00848 } 00849 00850 /* 00851 * Proceed to the network phase. 00852 */ 00853 static void network_phase(ppp_pcb *pcb) { 00854 #if CBCP_SUPPORT 00855 ppp_pcb *pcb = &ppp_pcb_list[unit]; 00856 #endif 00857 #if 0 /* UNUSED */ 00858 lcp_options *go = &lcp_gotoptions[unit]; 00859 #endif /* UNUSED */ 00860 00861 #if 0 /* UNUSED */ 00862 /* Log calling number. */ 00863 if (*remote_number) 00864 ppp_notice("peer from calling number %q authorized", remote_number); 00865 #endif /* UNUSED */ 00866 00867 #if PPP_NOTIFY 00868 /* 00869 * If the peer had to authenticate, notify it now. 00870 */ 00871 if (0 00872 #if CHAP_SUPPORT 00873 || go->neg_chap 00874 #endif /* CHAP_SUPPORT */ 00875 #if PAP_SUPPORT 00876 || go->neg_upap 00877 #endif /* PAP_SUPPORT */ 00878 #if EAP_SUPPORT 00879 || go->neg_eap 00880 #endif /* EAP_SUPPORT */ 00881 ) { 00882 notify(auth_up_notifier, 0); 00883 } 00884 #endif /* PPP_NOTIFY */ 00885 00886 #if CBCP_SUPPORT 00887 /* 00888 * If we negotiated callback, do it now. 00889 */ 00890 if (go->neg_cbcp) { 00891 new_phase(pcb, PPP_PHASE_CALLBACK); 00892 (*cbcp_protent.open)(pcb); 00893 return; 00894 } 00895 #endif 00896 00897 #if PPP_OPTIONS 00898 /* 00899 * Process extra options from the secrets file 00900 */ 00901 if (extra_options) { 00902 options_from_list(extra_options, 1); 00903 free_wordlist(extra_options); 00904 extra_options = 0; 00905 } 00906 #endif /* PPP_OPTIONS */ 00907 start_networks(pcb); 00908 } 00909 00910 void start_networks(ppp_pcb *pcb) { 00911 #if CCP_SUPPORT || ECP_SUPPORT 00912 int i; 00913 const struct protent *protp; 00914 #endif /* CCP_SUPPORT || ECP_SUPPORT */ 00915 00916 new_phase(pcb, PPP_PHASE_NETWORK); 00917 00918 #ifdef HAVE_MULTILINK 00919 if (multilink) { 00920 if (mp_join_bundle()) { 00921 if (multilink_join_hook) 00922 (*multilink_join_hook)(); 00923 if (updetach && !nodetach) 00924 detach(); 00925 return; 00926 } 00927 } 00928 #endif /* HAVE_MULTILINK */ 00929 00930 #ifdef PPP_FILTER 00931 if (!demand) 00932 set_filters(&pass_filter, &active_filter); 00933 #endif 00934 #if CCP_SUPPORT || ECP_SUPPORT 00935 /* Start CCP and ECP */ 00936 for (i = 0; (protp = protocols[i]) != NULL; ++i) 00937 if ( 00938 (0 00939 #if ECP_SUPPORT 00940 || protp->protocol == PPP_ECP 00941 #endif /* ECP_SUPPORT */ 00942 #if CCP_SUPPORT 00943 || protp->protocol == PPP_CCP 00944 #endif /* CCP_SUPPORT */ 00945 ) 00946 && protp->open != NULL) 00947 (*protp->open)(pcb); 00948 #endif /* CCP_SUPPORT || ECP_SUPPORT */ 00949 00950 /* 00951 * Bring up other network protocols iff encryption is not required. 00952 */ 00953 if (1 00954 #if ECP_SUPPORT 00955 && !ecp_gotoptions[unit].required 00956 #endif /* ECP_SUPPORT */ 00957 #if MPPE_SUPPORT 00958 && !pcb->ccp_gotoptions.mppe 00959 #endif /* MPPE_SUPPORT */ 00960 ) 00961 continue_networks(pcb); 00962 } 00963 00964 void continue_networks(ppp_pcb *pcb) { 00965 int i; 00966 const struct protent *protp; 00967 00968 /* 00969 * Start the "real" network protocols. 00970 */ 00971 for (i = 0; (protp = protocols[i]) != NULL; ++i) 00972 if (protp->protocol < 0xC000 00973 #if CCP_SUPPORT 00974 && protp->protocol != PPP_CCP 00975 #endif /* CCP_SUPPORT */ 00976 #if ECP_SUPPORT 00977 && protp->protocol != PPP_ECP 00978 #endif /* ECP_SUPPORT */ 00979 && protp->open != NULL) { 00980 (*protp->open)(pcb); 00981 ++pcb->num_np_open; 00982 } 00983 00984 if (pcb->num_np_open == 0) 00985 /* nothing to do */ 00986 lcp_close(pcb, "No network protocols running"); 00987 } 00988 00989 #if PPP_AUTH_SUPPORT 00990 #if PPP_SERVER 00991 /* 00992 * auth_check_passwd - Check the user name and passwd against configuration. 00993 * 00994 * returns: 00995 * 0: Authentication failed. 00996 * 1: Authentication succeeded. 00997 * In either case, msg points to an appropriate message and msglen to the message len. 00998 */ 00999 int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen) { 01000 int secretuserlen; 01001 int secretpasswdlen; 01002 01003 if (pcb->settings.user && pcb->settings.passwd) { 01004 secretuserlen = (int)strlen(pcb->settings.user); 01005 secretpasswdlen = (int)strlen(pcb->settings.passwd); 01006 if (secretuserlen == userlen 01007 && secretpasswdlen == passwdlen 01008 && !memcmp(auser, pcb->settings.user, userlen) 01009 && !memcmp(apasswd, pcb->settings.passwd, passwdlen) ) { 01010 *msg = "Login ok"; 01011 *msglen = sizeof("Login ok")-1; 01012 return 1; 01013 } 01014 } 01015 01016 *msg = "Login incorrect"; 01017 *msglen = sizeof("Login incorrect")-1; 01018 return 0; 01019 } 01020 01021 /* 01022 * The peer has failed to authenticate himself using `protocol'. 01023 */ 01024 void auth_peer_fail(ppp_pcb *pcb, int protocol) { 01025 LWIP_UNUSED_ARG(protocol); 01026 /* 01027 * Authentication failure: take the link down 01028 */ 01029 #if 0 /* UNUSED */ 01030 status = EXIT_PEER_AUTH_FAILED; 01031 #endif /* UNUSED */ 01032 pcb->err_code = PPPERR_AUTHFAIL; 01033 lcp_close(pcb, "Authentication failed"); 01034 } 01035 01036 /* 01037 * The peer has been successfully authenticated using `protocol'. 01038 */ 01039 void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen) { 01040 int bit; 01041 #ifndef HAVE_MULTILINK 01042 LWIP_UNUSED_ARG(name); 01043 LWIP_UNUSED_ARG(namelen); 01044 #endif /* HAVE_MULTILINK */ 01045 01046 switch (protocol) { 01047 #if CHAP_SUPPORT 01048 case PPP_CHAP: 01049 bit = CHAP_PEER; 01050 switch (prot_flavor) { 01051 case CHAP_MD5: 01052 bit |= CHAP_MD5_PEER; 01053 break; 01054 #if MSCHAP_SUPPORT 01055 case CHAP_MICROSOFT: 01056 bit |= CHAP_MS_PEER; 01057 break; 01058 case CHAP_MICROSOFT_V2: 01059 bit |= CHAP_MS2_PEER; 01060 break; 01061 #endif /* MSCHAP_SUPPORT */ 01062 default: 01063 break; 01064 } 01065 break; 01066 #endif /* CHAP_SUPPORT */ 01067 #if PAP_SUPPORT 01068 case PPP_PAP: 01069 bit = PAP_PEER; 01070 break; 01071 #endif /* PAP_SUPPORT */ 01072 #if EAP_SUPPORT 01073 case PPP_EAP: 01074 bit = EAP_PEER; 01075 break; 01076 #endif /* EAP_SUPPORT */ 01077 default: 01078 ppp_warn("auth_peer_success: unknown protocol %x", protocol); 01079 return; 01080 } 01081 01082 #ifdef HAVE_MULTILINK 01083 /* 01084 * Save the authenticated name of the peer for later. 01085 */ 01086 if (namelen > (int)sizeof(pcb->peer_authname) - 1) 01087 namelen = (int)sizeof(pcb->peer_authname) - 1; 01088 MEMCPY(pcb->peer_authname, name, namelen); 01089 pcb->peer_authname[namelen] = 0; 01090 #endif /* HAVE_MULTILINK */ 01091 #if 0 /* UNUSED */ 01092 script_setenv("PEERNAME", , 0); 01093 #endif /* UNUSED */ 01094 01095 /* Save the authentication method for later. */ 01096 pcb->auth_done |= bit; 01097 01098 /* 01099 * If there is no more authentication still to be done, 01100 * proceed to the network (or callback) phase. 01101 */ 01102 if ((pcb->auth_pending &= ~bit) == 0) 01103 network_phase(pcb); 01104 } 01105 #endif /* PPP_SERVER */ 01106 01107 /* 01108 * We have failed to authenticate ourselves to the peer using `protocol'. 01109 */ 01110 void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { 01111 LWIP_UNUSED_ARG(protocol); 01112 /* 01113 * We've failed to authenticate ourselves to our peer. 01114 * 01115 * Some servers keep sending CHAP challenges, but there 01116 * is no point in persisting without any way to get updated 01117 * authentication secrets. 01118 * 01119 * He'll probably take the link down, and there's not much 01120 * we can do except wait for that. 01121 */ 01122 pcb->err_code = PPPERR_AUTHFAIL; 01123 lcp_close(pcb, "Failed to authenticate ourselves to peer"); 01124 } 01125 01126 /* 01127 * We have successfully authenticated ourselves with the peer using `protocol'. 01128 */ 01129 void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { 01130 int bit; 01131 const char *prot = ""; 01132 01133 switch (protocol) { 01134 #if CHAP_SUPPORT 01135 case PPP_CHAP: 01136 bit = CHAP_WITHPEER; 01137 prot = "CHAP"; 01138 switch (prot_flavor) { 01139 case CHAP_MD5: 01140 bit |= CHAP_MD5_WITHPEER; 01141 break; 01142 #if MSCHAP_SUPPORT 01143 case CHAP_MICROSOFT: 01144 bit |= CHAP_MS_WITHPEER; 01145 break; 01146 case CHAP_MICROSOFT_V2: 01147 bit |= CHAP_MS2_WITHPEER; 01148 break; 01149 #endif /* MSCHAP_SUPPORT */ 01150 default: 01151 break; 01152 } 01153 break; 01154 #endif /* CHAP_SUPPORT */ 01155 #if PAP_SUPPORT 01156 case PPP_PAP: 01157 bit = PAP_WITHPEER; 01158 prot = "PAP"; 01159 break; 01160 #endif /* PAP_SUPPORT */ 01161 #if EAP_SUPPORT 01162 case PPP_EAP: 01163 bit = EAP_WITHPEER; 01164 prot = "EAP"; 01165 break; 01166 #endif /* EAP_SUPPORT */ 01167 default: 01168 ppp_warn("auth_withpeer_success: unknown protocol %x", protocol); 01169 bit = 0; 01170 /* no break */ 01171 } 01172 01173 ppp_notice("%s authentication succeeded", prot); 01174 01175 /* Save the authentication method for later. */ 01176 pcb->auth_done |= bit; 01177 01178 /* 01179 * If there is no more authentication still being done, 01180 * proceed to the network (or callback) phase. 01181 */ 01182 if ((pcb->auth_pending &= ~bit) == 0) 01183 network_phase(pcb); 01184 } 01185 #endif /* PPP_AUTH_SUPPORT */ 01186 01187 01188 /* 01189 * np_up - a network protocol has come up. 01190 */ 01191 void np_up(ppp_pcb *pcb, int proto) { 01192 #if PPP_IDLETIMELIMIT 01193 int tlim; 01194 #endif /* PPP_IDLETIMELIMIT */ 01195 LWIP_UNUSED_ARG(proto); 01196 01197 if (pcb->num_np_up == 0) { 01198 /* 01199 * At this point we consider that the link has come up successfully. 01200 */ 01201 new_phase(pcb, PPP_PHASE_RUNNING); 01202 01203 #if PPP_IDLETIMELIMIT 01204 #if 0 /* UNUSED */ 01205 if (idle_time_hook != 0) 01206 tlim = (*idle_time_hook)(NULL); 01207 else 01208 #endif /* UNUSED */ 01209 tlim = pcb->settings.idle_time_limit; 01210 if (tlim > 0) 01211 TIMEOUT(check_idle, (void*)pcb, tlim); 01212 #endif /* PPP_IDLETIMELIMIT */ 01213 01214 #if PPP_MAXCONNECT 01215 /* 01216 * Set a timeout to close the connection once the maximum 01217 * connect time has expired. 01218 */ 01219 if (pcb->settings.maxconnect > 0) 01220 TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); 01221 #endif /* PPP_MAXCONNECT */ 01222 01223 #ifdef MAXOCTETS 01224 if (maxoctets > 0) 01225 TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); 01226 #endif 01227 01228 #if 0 /* Unused */ 01229 /* 01230 * Detach now, if the updetach option was given. 01231 */ 01232 if (updetach && !nodetach) 01233 detach(); 01234 #endif /* Unused */ 01235 } 01236 ++pcb->num_np_up; 01237 } 01238 01239 /* 01240 * np_down - a network protocol has gone down. 01241 */ 01242 void np_down(ppp_pcb *pcb, int proto) { 01243 LWIP_UNUSED_ARG(proto); 01244 if (--pcb->num_np_up == 0) { 01245 #if PPP_IDLETIMELIMIT 01246 UNTIMEOUT(check_idle, (void*)pcb); 01247 #endif /* PPP_IDLETIMELIMIT */ 01248 #if PPP_MAXCONNECT 01249 UNTIMEOUT(connect_time_expired, NULL); 01250 #endif /* PPP_MAXCONNECT */ 01251 #ifdef MAXOCTETS 01252 UNTIMEOUT(check_maxoctets, NULL); 01253 #endif 01254 new_phase(pcb, PPP_PHASE_NETWORK); 01255 } 01256 } 01257 01258 /* 01259 * np_finished - a network protocol has finished using the link. 01260 */ 01261 void np_finished(ppp_pcb *pcb, int proto) { 01262 LWIP_UNUSED_ARG(proto); 01263 if (--pcb->num_np_open <= 0) { 01264 /* no further use for the link: shut up shop. */ 01265 lcp_close(pcb, "No network protocols running"); 01266 } 01267 } 01268 01269 #ifdef MAXOCTETS 01270 static void 01271 check_maxoctets(arg) 01272 void *arg; 01273 { 01274 #if PPP_STATS_SUPPORT 01275 unsigned int used; 01276 01277 update_link_stats(ifunit); 01278 link_stats_valid=0; 01279 01280 switch(maxoctets_dir) { 01281 case PPP_OCTETS_DIRECTION_IN: 01282 used = link_stats.bytes_in; 01283 break; 01284 case PPP_OCTETS_DIRECTION_OUT: 01285 used = link_stats.bytes_out; 01286 break; 01287 case PPP_OCTETS_DIRECTION_MAXOVERAL: 01288 case PPP_OCTETS_DIRECTION_MAXSESSION: 01289 used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; 01290 break; 01291 default: 01292 used = link_stats.bytes_in+link_stats.bytes_out; 01293 break; 01294 } 01295 if (used > maxoctets) { 01296 ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); 01297 status = EXIT_TRAFFIC_LIMIT; 01298 lcp_close(pcb, "Traffic limit"); 01299 #if 0 /* UNUSED */ 01300 need_holdoff = 0; 01301 #endif /* UNUSED */ 01302 } else { 01303 TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); 01304 } 01305 #endif /* PPP_STATS_SUPPORT */ 01306 } 01307 #endif /* MAXOCTETS */ 01308 01309 #if PPP_IDLETIMELIMIT 01310 /* 01311 * check_idle - check whether the link has been idle for long 01312 * enough that we can shut it down. 01313 */ 01314 static void check_idle(void *arg) { 01315 ppp_pcb *pcb = (ppp_pcb*)arg; 01316 struct ppp_idle idle; 01317 time_t itime; 01318 int tlim; 01319 01320 if (!get_idle_time(pcb, &idle)) 01321 return; 01322 #if 0 /* UNUSED */ 01323 if (idle_time_hook != 0) { 01324 tlim = idle_time_hook(&idle); 01325 } else { 01326 #endif /* UNUSED */ 01327 itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); 01328 tlim = pcb->settings.idle_time_limit - itime; 01329 #if 0 /* UNUSED */ 01330 } 01331 #endif /* UNUSED */ 01332 if (tlim <= 0) { 01333 /* link is idle: shut it down. */ 01334 ppp_notice("Terminating connection due to lack of activity."); 01335 pcb->err_code = PPPERR_IDLETIMEOUT; 01336 lcp_close(pcb, "Link inactive"); 01337 #if 0 /* UNUSED */ 01338 need_holdoff = 0; 01339 #endif /* UNUSED */ 01340 } else { 01341 TIMEOUT(check_idle, (void*)pcb, tlim); 01342 } 01343 } 01344 #endif /* PPP_IDLETIMELIMIT */ 01345 01346 #if PPP_MAXCONNECT 01347 /* 01348 * connect_time_expired - log a message and close the connection. 01349 */ 01350 static void connect_time_expired(void *arg) { 01351 ppp_pcb *pcb = (ppp_pcb*)arg; 01352 ppp_info("Connect time expired"); 01353 pcb->err_code = PPPERR_CONNECTTIME; 01354 lcp_close(pcb, "Connect time expired"); /* Close connection */ 01355 } 01356 #endif /* PPP_MAXCONNECT */ 01357 01358 #if PPP_OPTIONS 01359 /* 01360 * auth_check_options - called to check authentication options. 01361 */ 01362 void 01363 auth_check_options() 01364 { 01365 lcp_options *wo = &lcp_wantoptions[0]; 01366 int can_auth; 01367 int lacks_ip; 01368 01369 /* Default our_name to hostname, and user to our_name */ 01370 if (our_name[0] == 0 || usehostname) 01371 strlcpy(our_name, hostname, sizeof(our_name)); 01372 /* If a blank username was explicitly given as an option, trust 01373 the user and don't use our_name */ 01374 if (ppp_settings.user[0] == 0 && !explicit_user) 01375 strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user)); 01376 01377 /* 01378 * If we have a default route, require the peer to authenticate 01379 * unless the noauth option was given or the real user is root. 01380 */ 01381 if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { 01382 auth_required = 1; 01383 default_auth = 1; 01384 } 01385 01386 #if CHAP_SUPPORT 01387 /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ 01388 if (wo->chap_mdtype) 01389 wo->neg_chap = 1; 01390 #endif /* CHAP_SUPPORT */ 01391 01392 /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ 01393 if (auth_required) { 01394 allow_any_ip = 0; 01395 if (1 01396 #if CHAP_SUPPORT 01397 && !wo->neg_chap 01398 #endif /* CHAP_SUPPORT */ 01399 #if PAP_SUPPORT 01400 && !wo->neg_upap 01401 #endif /* PAP_SUPPORT */ 01402 #if EAP_SUPPORT 01403 && !wo->neg_eap 01404 #endif /* EAP_SUPPORT */ 01405 ) { 01406 #if CHAP_SUPPORT 01407 wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE; 01408 wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED; 01409 #endif /* CHAP_SUPPORT */ 01410 #if PAP_SUPPORT 01411 wo->neg_upap = 1; 01412 #endif /* PAP_SUPPORT */ 01413 #if EAP_SUPPORT 01414 wo->neg_eap = 1; 01415 #endif /* EAP_SUPPORT */ 01416 } 01417 } else { 01418 #if CHAP_SUPPORT 01419 wo->neg_chap = 0; 01420 wo->chap_mdtype = MDTYPE_NONE; 01421 #endif /* CHAP_SUPPORT */ 01422 #if PAP_SUPPORT 01423 wo->neg_upap = 0; 01424 #endif /* PAP_SUPPORT */ 01425 #if EAP_SUPPORT 01426 wo->neg_eap = 0; 01427 #endif /* EAP_SUPPORT */ 01428 } 01429 01430 /* 01431 * Check whether we have appropriate secrets to use 01432 * to authenticate the peer. Note that EAP can authenticate by way 01433 * of a CHAP-like exchanges as well as SRP. 01434 */ 01435 lacks_ip = 0; 01436 #if PAP_SUPPORT 01437 can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); 01438 #else 01439 can_auth = 0; 01440 #endif /* PAP_SUPPORT */ 01441 if (!can_auth && (0 01442 #if CHAP_SUPPORT 01443 || wo->neg_chap 01444 #endif /* CHAP_SUPPORT */ 01445 #if EAP_SUPPORT 01446 || wo->neg_eap 01447 #endif /* EAP_SUPPORT */ 01448 )) { 01449 #if CHAP_SUPPORT 01450 can_auth = have_chap_secret((explicit_remote? remote_name: NULL), 01451 our_name, 1, &lacks_ip); 01452 #else 01453 can_auth = 0; 01454 #endif 01455 } 01456 if (!can_auth 01457 #if EAP_SUPPORT 01458 && wo->neg_eap 01459 #endif /* EAP_SUPPORT */ 01460 ) { 01461 can_auth = have_srp_secret((explicit_remote? remote_name: NULL), 01462 our_name, 1, &lacks_ip); 01463 } 01464 01465 if (auth_required && !can_auth && noauth_addrs == NULL) { 01466 if (default_auth) { 01467 option_error( 01468 "By default the remote system is required to authenticate itself"); 01469 option_error( 01470 "(because this system has a default route to the internet)"); 01471 } else if (explicit_remote) 01472 option_error( 01473 "The remote system (%s) is required to authenticate itself", 01474 remote_name); 01475 else 01476 option_error( 01477 "The remote system is required to authenticate itself"); 01478 option_error( 01479 "but I couldn't find any suitable secret (password) for it to use to do so."); 01480 if (lacks_ip) 01481 option_error( 01482 "(None of the available passwords would let it use an IP address.)"); 01483 01484 exit(1); 01485 } 01486 01487 /* 01488 * Early check for remote number authorization. 01489 */ 01490 if (!auth_number()) { 01491 ppp_warn("calling number %q is not authorized", remote_number); 01492 exit(EXIT_CNID_AUTH_FAILED); 01493 } 01494 } 01495 #endif /* PPP_OPTIONS */ 01496 01497 #if 0 /* UNUSED */ 01498 /* 01499 * auth_reset - called when LCP is starting negotiations to recheck 01500 * authentication options, i.e. whether we have appropriate secrets 01501 * to use for authenticating ourselves and/or the peer. 01502 */ 01503 void 01504 auth_reset(unit) 01505 int unit; 01506 { 01507 lcp_options *go = &lcp_gotoptions[unit]; 01508 lcp_options *ao = &lcp_allowoptions[unit]; 01509 int hadchap; 01510 01511 hadchap = -1; 01512 ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); 01513 ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) 01514 && (passwd[0] != 0 || 01515 (hadchap = have_chap_secret(user, (explicit_remote? remote_name: 01516 NULL), 0, NULL))); 01517 ao->neg_eap = !refuse_eap && ( 01518 passwd[0] != 0 || 01519 (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, 01520 (explicit_remote? remote_name: NULL), 0, NULL))) || 01521 have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); 01522 01523 hadchap = -1; 01524 if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) 01525 go->neg_upap = 0; 01526 if (go->neg_chap) { 01527 if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), 01528 our_name, 1, NULL))) 01529 go->neg_chap = 0; 01530 } 01531 if (go->neg_eap && 01532 (hadchap == 0 || (hadchap == -1 && 01533 !have_chap_secret((explicit_remote? remote_name: NULL), our_name, 01534 1, NULL))) && 01535 !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, 01536 NULL)) 01537 go->neg_eap = 0; 01538 } 01539 01540 /* 01541 * check_passwd - Check the user name and passwd against the PAP secrets 01542 * file. If requested, also check against the system password database, 01543 * and login the user if OK. 01544 * 01545 * returns: 01546 * UPAP_AUTHNAK: Authentication failed. 01547 * UPAP_AUTHACK: Authentication succeeded. 01548 * In either case, msg points to an appropriate message. 01549 */ 01550 int 01551 check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) 01552 int unit; 01553 char *auser; 01554 int userlen; 01555 char *apasswd; 01556 int passwdlen; 01557 char **msg; 01558 { 01559 return UPAP_AUTHNAK; 01560 int ret; 01561 char *filename; 01562 FILE *f; 01563 struct wordlist *addrs = NULL, *opts = NULL; 01564 char passwd[256], user[256]; 01565 char secret[MAXWORDLEN]; 01566 static int attempts = 0; 01567 01568 /* 01569 * Make copies of apasswd and auser, then null-terminate them. 01570 * If there are unprintable characters in the password, make 01571 * them visible. 01572 */ 01573 slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd); 01574 slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser); 01575 *msg = ""; 01576 01577 /* 01578 * Check if a plugin wants to handle this. 01579 */ 01580 if (pap_auth_hook) { 01581 ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts); 01582 if (ret >= 0) { 01583 /* note: set_allowed_addrs() saves opts (but not addrs): 01584 don't free it! */ 01585 if (ret) 01586 set_allowed_addrs(unit, addrs, opts); 01587 else if (opts != 0) 01588 free_wordlist(opts); 01589 if (addrs != 0) 01590 free_wordlist(addrs); 01591 BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); 01592 return ret? UPAP_AUTHACK: UPAP_AUTHNAK; 01593 } 01594 } 01595 01596 /* 01597 * Open the file of pap secrets and scan for a suitable secret 01598 * for authenticating this user. 01599 */ 01600 filename = _PATH_UPAPFILE; 01601 addrs = opts = NULL; 01602 ret = UPAP_AUTHNAK; 01603 f = fopen(filename, "r"); 01604 if (f == NULL) { 01605 ppp_error("Can't open PAP password file %s: %m", filename); 01606 01607 } else { 01608 check_access(f, filename); 01609 if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { 01610 ppp_warn("no PAP secret found for %s", user); 01611 } else { 01612 /* 01613 * If the secret is "@login", it means to check 01614 * the password against the login database. 01615 */ 01616 int login_secret = strcmp(secret, "@login") == 0; 01617 ret = UPAP_AUTHACK; 01618 if (uselogin || login_secret) { 01619 /* login option or secret is @login */ 01620 if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) { 01621 ret = UPAP_AUTHNAK; 01622 } 01623 } else if (session_mgmt) { 01624 if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { 01625 ppp_warn("Peer %q failed PAP Session verification", user); 01626 ret = UPAP_AUTHNAK; 01627 } 01628 } 01629 if (secret[0] != 0 && !login_secret) { 01630 /* password given in pap-secrets - must match */ 01631 if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0) 01632 && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0) 01633 ret = UPAP_AUTHNAK; 01634 } 01635 } 01636 fclose(f); 01637 } 01638 01639 if (ret == UPAP_AUTHNAK) { 01640 if (**msg == 0) 01641 *msg = "Login incorrect"; 01642 /* 01643 * XXX can we ever get here more than once?? 01644 * Frustrate passwd stealer programs. 01645 * Allow 10 tries, but start backing off after 3 (stolen from login). 01646 * On 10'th, drop the connection. 01647 */ 01648 if (attempts++ >= 10) { 01649 ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); 01650 lcp_close(pcb, "login failed"); 01651 } 01652 if (attempts > 3) 01653 sleep((u_int) (attempts - 3) * 5); 01654 if (opts != NULL) 01655 free_wordlist(opts); 01656 01657 } else { 01658 attempts = 0; /* Reset count */ 01659 if (**msg == 0) 01660 *msg = "Login ok"; 01661 set_allowed_addrs(unit, addrs, opts); 01662 } 01663 01664 if (addrs != NULL) 01665 free_wordlist(addrs); 01666 BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); 01667 BZERO(secret, sizeof(secret)); 01668 01669 return ret; 01670 } 01671 01672 /* 01673 * null_login - Check if a username of "" and a password of "" are 01674 * acceptable, and iff so, set the list of acceptable IP addresses 01675 * and return 1. 01676 */ 01677 static int 01678 null_login(unit) 01679 int unit; 01680 { 01681 char *filename; 01682 FILE *f; 01683 int i, ret; 01684 struct wordlist *addrs, *opts; 01685 char secret[MAXWORDLEN]; 01686 01687 /* 01688 * Check if a plugin wants to handle this. 01689 */ 01690 ret = -1; 01691 if (null_auth_hook) 01692 ret = (*null_auth_hook)(&addrs, &opts); 01693 01694 /* 01695 * Open the file of pap secrets and scan for a suitable secret. 01696 */ 01697 if (ret <= 0) { 01698 filename = _PATH_UPAPFILE; 01699 addrs = NULL; 01700 f = fopen(filename, "r"); 01701 if (f == NULL) 01702 return 0; 01703 check_access(f, filename); 01704 01705 i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); 01706 ret = i >= 0 && secret[0] == 0; 01707 BZERO(secret, sizeof(secret)); 01708 fclose(f); 01709 } 01710 01711 if (ret) 01712 set_allowed_addrs(unit, addrs, opts); 01713 else if (opts != 0) 01714 free_wordlist(opts); 01715 if (addrs != 0) 01716 free_wordlist(addrs); 01717 01718 return ret; 01719 } 01720 01721 /* 01722 * get_pap_passwd - get a password for authenticating ourselves with 01723 * our peer using PAP. Returns 1 on success, 0 if no suitable password 01724 * could be found. 01725 * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). 01726 */ 01727 static int 01728 get_pap_passwd(passwd) 01729 char *passwd; 01730 { 01731 char *filename; 01732 FILE *f; 01733 int ret; 01734 char secret[MAXWORDLEN]; 01735 01736 /* 01737 * Check whether a plugin wants to supply this. 01738 */ 01739 if (pap_passwd_hook) { 01740 ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd); 01741 if (ret >= 0) 01742 return ret; 01743 } 01744 01745 filename = _PATH_UPAPFILE; 01746 f = fopen(filename, "r"); 01747 if (f == NULL) 01748 return 0; 01749 check_access(f, filename); 01750 ret = scan_authfile(f, user, 01751 (remote_name[0]? remote_name: NULL), 01752 secret, NULL, NULL, filename, 0); 01753 fclose(f); 01754 if (ret < 0) 01755 return 0; 01756 if (passwd != NULL) 01757 strlcpy(passwd, secret, MAXSECRETLEN); 01758 BZERO(secret, sizeof(secret)); 01759 return 1; 01760 } 01761 01762 /* 01763 * have_pap_secret - check whether we have a PAP file with any 01764 * secrets that we could possibly use for authenticating the peer. 01765 */ 01766 static int 01767 have_pap_secret(lacks_ipp) 01768 int *lacks_ipp; 01769 { 01770 FILE *f; 01771 int ret; 01772 char *filename; 01773 struct wordlist *addrs; 01774 01775 /* let the plugin decide, if there is one */ 01776 if (pap_check_hook) { 01777 ret = (*pap_check_hook)(); 01778 if (ret >= 0) 01779 return ret; 01780 } 01781 01782 filename = _PATH_UPAPFILE; 01783 f = fopen(filename, "r"); 01784 if (f == NULL) 01785 return 0; 01786 01787 ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, 01788 NULL, &addrs, NULL, filename, 0); 01789 fclose(f); 01790 if (ret >= 0 && !some_ip_ok(addrs)) { 01791 if (lacks_ipp != 0) 01792 *lacks_ipp = 1; 01793 ret = -1; 01794 } 01795 if (addrs != 0) 01796 free_wordlist(addrs); 01797 01798 return ret >= 0; 01799 } 01800 01801 /* 01802 * have_chap_secret - check whether we have a CHAP file with a 01803 * secret that we could possibly use for authenticating `client' 01804 * on `server'. Either can be the null string, meaning we don't 01805 * know the identity yet. 01806 */ 01807 static int 01808 have_chap_secret(client, server, need_ip, lacks_ipp) 01809 char *client; 01810 char *server; 01811 int need_ip; 01812 int *lacks_ipp; 01813 { 01814 FILE *f; 01815 int ret; 01816 char *filename; 01817 struct wordlist *addrs; 01818 01819 if (chap_check_hook) { 01820 ret = (*chap_check_hook)(); 01821 if (ret >= 0) { 01822 return ret; 01823 } 01824 } 01825 01826 filename = _PATH_CHAPFILE; 01827 f = fopen(filename, "r"); 01828 if (f == NULL) 01829 return 0; 01830 01831 if (client != NULL && client[0] == 0) 01832 client = NULL; 01833 else if (server != NULL && server[0] == 0) 01834 server = NULL; 01835 01836 ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); 01837 fclose(f); 01838 if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { 01839 if (lacks_ipp != 0) 01840 *lacks_ipp = 1; 01841 ret = -1; 01842 } 01843 if (addrs != 0) 01844 free_wordlist(addrs); 01845 01846 return ret >= 0; 01847 } 01848 01849 /* 01850 * have_srp_secret - check whether we have a SRP file with a 01851 * secret that we could possibly use for authenticating `client' 01852 * on `server'. Either can be the null string, meaning we don't 01853 * know the identity yet. 01854 */ 01855 static int 01856 have_srp_secret(client, server, need_ip, lacks_ipp) 01857 char *client; 01858 char *server; 01859 int need_ip; 01860 int *lacks_ipp; 01861 { 01862 FILE *f; 01863 int ret; 01864 char *filename; 01865 struct wordlist *addrs; 01866 01867 filename = _PATH_SRPFILE; 01868 f = fopen(filename, "r"); 01869 if (f == NULL) 01870 return 0; 01871 01872 if (client != NULL && client[0] == 0) 01873 client = NULL; 01874 else if (server != NULL && server[0] == 0) 01875 server = NULL; 01876 01877 ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); 01878 fclose(f); 01879 if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { 01880 if (lacks_ipp != 0) 01881 *lacks_ipp = 1; 01882 ret = -1; 01883 } 01884 if (addrs != 0) 01885 free_wordlist(addrs); 01886 01887 return ret >= 0; 01888 } 01889 #endif /* UNUSED */ 01890 01891 #if PPP_AUTH_SUPPORT 01892 /* 01893 * get_secret - open the CHAP secret file and return the secret 01894 * for authenticating the given client on the given server. 01895 * (We could be either client or server). 01896 */ 01897 int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server) { 01898 int len; 01899 LWIP_UNUSED_ARG(server); 01900 LWIP_UNUSED_ARG(am_server); 01901 01902 if (!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) { 01903 return 0; 01904 } 01905 01906 len = (int)strlen(pcb->settings.passwd); 01907 if (len > MAXSECRETLEN) { 01908 ppp_error("Secret for %s on %s is too long", client, server); 01909 len = MAXSECRETLEN; 01910 } 01911 01912 MEMCPY(secret, pcb->settings.passwd, len); 01913 *secret_len = len; 01914 return 1; 01915 01916 #if 0 /* UNUSED */ 01917 FILE *f; 01918 int ret, len; 01919 char *filename; 01920 struct wordlist *addrs, *opts; 01921 char secbuf[MAXWORDLEN]; 01922 struct wordlist *addrs; 01923 addrs = NULL; 01924 01925 if (!am_server && ppp_settings.passwd[0] != 0) { 01926 strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); 01927 } else if (!am_server && chap_passwd_hook) { 01928 if ( (*chap_passwd_hook)(client, secbuf) < 0) { 01929 ppp_error("Unable to obtain CHAP password for %s on %s from plugin", 01930 client, server); 01931 return 0; 01932 } 01933 } else { 01934 filename = _PATH_CHAPFILE; 01935 addrs = NULL; 01936 secbuf[0] = 0; 01937 01938 f = fopen(filename, "r"); 01939 if (f == NULL) { 01940 ppp_error("Can't open chap secret file %s: %m", filename); 01941 return 0; 01942 } 01943 check_access(f, filename); 01944 01945 ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); 01946 fclose(f); 01947 if (ret < 0) 01948 return 0; 01949 01950 if (am_server) 01951 set_allowed_addrs(unit, addrs, opts); 01952 else if (opts != 0) 01953 free_wordlist(opts); 01954 if (addrs != 0) 01955 free_wordlist(addrs); 01956 } 01957 01958 len = strlen(secbuf); 01959 if (len > MAXSECRETLEN) { 01960 ppp_error("Secret for %s on %s is too long", client, server); 01961 len = MAXSECRETLEN; 01962 } 01963 MEMCPY(secret, secbuf, len); 01964 BZERO(secbuf, sizeof(secbuf)); 01965 *secret_len = len; 01966 01967 return 1; 01968 #endif /* UNUSED */ 01969 } 01970 #endif /* PPP_AUTH_SUPPORT */ 01971 01972 01973 #if 0 /* UNUSED */ 01974 /* 01975 * get_srp_secret - open the SRP secret file and return the secret 01976 * for authenticating the given client on the given server. 01977 * (We could be either client or server). 01978 */ 01979 int 01980 get_srp_secret(unit, client, server, secret, am_server) 01981 int unit; 01982 char *client; 01983 char *server; 01984 char *secret; 01985 int am_server; 01986 { 01987 FILE *fp; 01988 int ret; 01989 char *filename; 01990 struct wordlist *addrs, *opts; 01991 01992 if (!am_server && ppp_settings.passwd[0] != '\0') { 01993 strlcpy(secret, ppp_settings.passwd, MAXWORDLEN); 01994 } else { 01995 filename = _PATH_SRPFILE; 01996 addrs = NULL; 01997 01998 fp = fopen(filename, "r"); 01999 if (fp == NULL) { 02000 ppp_error("Can't open srp secret file %s: %m", filename); 02001 return 0; 02002 } 02003 check_access(fp, filename); 02004 02005 secret[0] = '\0'; 02006 ret = scan_authfile(fp, client, server, secret, &addrs, &opts, 02007 filename, am_server); 02008 fclose(fp); 02009 if (ret < 0) 02010 return 0; 02011 02012 if (am_server) 02013 set_allowed_addrs(unit, addrs, opts); 02014 else if (opts != NULL) 02015 free_wordlist(opts); 02016 if (addrs != NULL) 02017 free_wordlist(addrs); 02018 } 02019 02020 return 1; 02021 } 02022 02023 /* 02024 * set_allowed_addrs() - set the list of allowed addresses. 02025 * Also looks for `--' indicating options to apply for this peer 02026 * and leaves the following words in extra_options. 02027 */ 02028 static void 02029 set_allowed_addrs(unit, addrs, opts) 02030 int unit; 02031 struct wordlist *addrs; 02032 struct wordlist *opts; 02033 { 02034 int n; 02035 struct wordlist *ap, **plink; 02036 struct permitted_ip *ip; 02037 char *ptr_word, *ptr_mask; 02038 struct hostent *hp; 02039 struct netent *np; 02040 u32_t a, mask, ah, offset; 02041 struct ipcp_options *wo = &ipcp_wantoptions[unit]; 02042 u32_t suggested_ip = 0; 02043 02044 if (addresses[unit] != NULL) 02045 free(addresses[unit]); 02046 addresses[unit] = NULL; 02047 if (extra_options != NULL) 02048 free_wordlist(extra_options); 02049 extra_options = opts; 02050 02051 /* 02052 * Count the number of IP addresses given. 02053 */ 02054 n = wordlist_count(addrs) + wordlist_count(noauth_addrs); 02055 if (n == 0) 02056 return; 02057 ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); 02058 if (ip == 0) 02059 return; 02060 02061 /* temporarily append the noauth_addrs list to addrs */ 02062 for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) 02063 ; 02064 *plink = noauth_addrs; 02065 02066 n = 0; 02067 for (ap = addrs; ap != NULL; ap = ap->next) { 02068 /* "-" means no addresses authorized, "*" means any address allowed */ 02069 ptr_word = ap->word; 02070 if (strcmp(ptr_word, "-") == 0) 02071 break; 02072 if (strcmp(ptr_word, "*") == 0) { 02073 ip[n].permit = 1; 02074 ip[n].base = ip[n].mask = 0; 02075 ++n; 02076 break; 02077 } 02078 02079 ip[n].permit = 1; 02080 if (*ptr_word == '!') { 02081 ip[n].permit = 0; 02082 ++ptr_word; 02083 } 02084 02085 mask = ~ (u32_t) 0; 02086 offset = 0; 02087 ptr_mask = strchr (ptr_word, '/'); 02088 if (ptr_mask != NULL) { 02089 int bit_count; 02090 char *endp; 02091 02092 bit_count = (int) strtol (ptr_mask+1, &endp, 10); 02093 if (bit_count <= 0 || bit_count > 32) { 02094 ppp_warn("invalid address length %v in auth. address list", 02095 ptr_mask+1); 02096 continue; 02097 } 02098 bit_count = 32 - bit_count; /* # bits in host part */ 02099 if (*endp == '+') { 02100 offset = ifunit + 1; 02101 ++endp; 02102 } 02103 if (*endp != 0) { 02104 ppp_warn("invalid address length syntax: %v", ptr_mask+1); 02105 continue; 02106 } 02107 *ptr_mask = '\0'; 02108 mask <<= bit_count; 02109 } 02110 02111 hp = gethostbyname(ptr_word); 02112 if (hp != NULL && hp->h_addrtype == AF_INET) { 02113 a = *(u32_t *)hp->h_addr; 02114 } else { 02115 np = getnetbyname (ptr_word); 02116 if (np != NULL && np->n_addrtype == AF_INET) { 02117 a = htonl ((u32_t)np->n_net); 02118 if (ptr_mask == NULL) { 02119 /* calculate appropriate mask for net */ 02120 ah = ntohl(a); 02121 if (IN_CLASSA(ah)) 02122 mask = IN_CLASSA_NET; 02123 else if (IN_CLASSB(ah)) 02124 mask = IN_CLASSB_NET; 02125 else if (IN_CLASSC(ah)) 02126 mask = IN_CLASSC_NET; 02127 } 02128 } else { 02129 a = inet_addr (ptr_word); 02130 } 02131 } 02132 02133 if (ptr_mask != NULL) 02134 *ptr_mask = '/'; 02135 02136 if (a == (u32_t)-1L) { 02137 ppp_warn("unknown host %s in auth. address list", ap->word); 02138 continue; 02139 } 02140 if (offset != 0) { 02141 if (offset >= ~mask) { 02142 ppp_warn("interface unit %d too large for subnet %v", 02143 ifunit, ptr_word); 02144 continue; 02145 } 02146 a = htonl((ntohl(a) & mask) + offset); 02147 mask = ~(u32_t)0; 02148 } 02149 ip[n].mask = htonl(mask); 02150 ip[n].base = a & ip[n].mask; 02151 ++n; 02152 if (~mask == 0 && suggested_ip == 0) 02153 suggested_ip = a; 02154 } 02155 *plink = NULL; 02156 02157 ip[n].permit = 0; /* make the last entry forbid all addresses */ 02158 ip[n].base = 0; /* to terminate the list */ 02159 ip[n].mask = 0; 02160 02161 addresses[unit] = ip; 02162 02163 /* 02164 * If the address given for the peer isn't authorized, or if 02165 * the user hasn't given one, AND there is an authorized address 02166 * which is a single host, then use that if we find one. 02167 */ 02168 if (suggested_ip != 0 02169 && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { 02170 wo->hisaddr = suggested_ip; 02171 /* 02172 * Do we insist on this address? No, if there are other 02173 * addresses authorized than the suggested one. 02174 */ 02175 if (n > 1) 02176 wo->accept_remote = 1; 02177 } 02178 } 02179 02180 /* 02181 * auth_ip_addr - check whether the peer is authorized to use 02182 * a given IP address. Returns 1 if authorized, 0 otherwise. 02183 */ 02184 int 02185 auth_ip_addr(unit, addr) 02186 int unit; 02187 u32_t addr; 02188 { 02189 int ok; 02190 02191 /* don't allow loopback or multicast address */ 02192 if (bad_ip_adrs(addr)) 02193 return 0; 02194 02195 if (allowed_address_hook) { 02196 ok = allowed_address_hook(addr); 02197 if (ok >= 0) return ok; 02198 } 02199 02200 if (addresses[unit] != NULL) { 02201 ok = ip_addr_check(addr, addresses[unit]); 02202 if (ok >= 0) 02203 return ok; 02204 } 02205 02206 if (auth_required) 02207 return 0; /* no addresses authorized */ 02208 return allow_any_ip || privileged || !have_route_to(addr); 02209 } 02210 02211 static int 02212 ip_addr_check(addr, addrs) 02213 u32_t addr; 02214 struct permitted_ip *addrs; 02215 { 02216 for (; ; ++addrs) 02217 if ((addr & addrs->mask) == addrs->base) 02218 return addrs->permit; 02219 } 02220 02221 /* 02222 * bad_ip_adrs - return 1 if the IP address is one we don't want 02223 * to use, such as an address in the loopback net or a multicast address. 02224 * addr is in network byte order. 02225 */ 02226 int 02227 bad_ip_adrs(addr) 02228 u32_t addr; 02229 { 02230 addr = ntohl(addr); 02231 return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET 02232 || IN_MULTICAST(addr) || IN_BADCLASS(addr); 02233 } 02234 02235 /* 02236 * some_ip_ok - check a wordlist to see if it authorizes any 02237 * IP address(es). 02238 */ 02239 static int 02240 some_ip_ok(addrs) 02241 struct wordlist *addrs; 02242 { 02243 for (; addrs != 0; addrs = addrs->next) { 02244 if (addrs->word[0] == '-') 02245 break; 02246 if (addrs->word[0] != '!') 02247 return 1; /* some IP address is allowed */ 02248 } 02249 return 0; 02250 } 02251 02252 /* 02253 * auth_number - check whether the remote number is allowed to connect. 02254 * Returns 1 if authorized, 0 otherwise. 02255 */ 02256 int 02257 auth_number() 02258 { 02259 struct wordlist *wp = permitted_numbers; 02260 int l; 02261 02262 /* Allow all if no authorization list. */ 02263 if (!wp) 02264 return 1; 02265 02266 /* Allow if we have a match in the authorization list. */ 02267 while (wp) { 02268 /* trailing '*' wildcard */ 02269 l = strlen(wp->word); 02270 if ((wp->word)[l - 1] == '*') 02271 l--; 02272 if (!strncasecmp(wp->word, remote_number, l)) 02273 return 1; 02274 wp = wp->next; 02275 } 02276 02277 return 0; 02278 } 02279 02280 /* 02281 * check_access - complain if a secret file has too-liberal permissions. 02282 */ 02283 static void 02284 check_access(f, filename) 02285 FILE *f; 02286 char *filename; 02287 { 02288 struct stat sbuf; 02289 02290 if (fstat(fileno(f), &sbuf) < 0) { 02291 ppp_warn("cannot stat secret file %s: %m", filename); 02292 } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { 02293 ppp_warn("Warning - secret file %s has world and/or group access", 02294 filename); 02295 } 02296 } 02297 02298 /* 02299 * scan_authfile - Scan an authorization file for a secret suitable 02300 * for authenticating `client' on `server'. The return value is -1 02301 * if no secret is found, otherwise >= 0. The return value has 02302 * NONWILD_CLIENT set if the secret didn't have "*" for the client, and 02303 * NONWILD_SERVER set if the secret didn't have "*" for the server. 02304 * Any following words on the line up to a "--" (i.e. address authorization 02305 * info) are placed in a wordlist and returned in *addrs. Any 02306 * following words (extra options) are placed in a wordlist and 02307 * returned in *opts. 02308 * We assume secret is NULL or points to MAXWORDLEN bytes of space. 02309 * Flags are non-zero if we need two colons in the secret in order to 02310 * match. 02311 */ 02312 static int 02313 scan_authfile(f, client, server, secret, addrs, opts, filename, flags) 02314 FILE *f; 02315 char *client; 02316 char *server; 02317 char *secret; 02318 struct wordlist **addrs; 02319 struct wordlist **opts; 02320 char *filename; 02321 int flags; 02322 { 02323 int newline, xxx; 02324 int got_flag, best_flag; 02325 FILE *sf; 02326 struct wordlist *ap, *addr_list, *alist, **app; 02327 char word[MAXWORDLEN]; 02328 char atfile[MAXWORDLEN]; 02329 char lsecret[MAXWORDLEN]; 02330 char *cp; 02331 02332 if (addrs != NULL) 02333 *addrs = NULL; 02334 if (opts != NULL) 02335 *opts = NULL; 02336 addr_list = NULL; 02337 if (!getword(f, word, &newline, filename)) 02338 return -1; /* file is empty??? */ 02339 newline = 1; 02340 best_flag = -1; 02341 for (;;) { 02342 /* 02343 * Skip until we find a word at the start of a line. 02344 */ 02345 while (!newline && getword(f, word, &newline, filename)) 02346 ; 02347 if (!newline) 02348 break; /* got to end of file */ 02349 02350 /* 02351 * Got a client - check if it's a match or a wildcard. 02352 */ 02353 got_flag = 0; 02354 if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { 02355 newline = 0; 02356 continue; 02357 } 02358 if (!ISWILD(word)) 02359 got_flag = NONWILD_CLIENT; 02360 02361 /* 02362 * Now get a server and check if it matches. 02363 */ 02364 if (!getword(f, word, &newline, filename)) 02365 break; 02366 if (newline) 02367 continue; 02368 if (!ISWILD(word)) { 02369 if (server != NULL && strcmp(word, server) != 0) 02370 continue; 02371 got_flag |= NONWILD_SERVER; 02372 } 02373 02374 /* 02375 * Got some sort of a match - see if it's better than what 02376 * we have already. 02377 */ 02378 if (got_flag <= best_flag) 02379 continue; 02380 02381 /* 02382 * Get the secret. 02383 */ 02384 if (!getword(f, word, &newline, filename)) 02385 break; 02386 if (newline) 02387 continue; 02388 02389 /* 02390 * SRP-SHA1 authenticator should never be reading secrets from 02391 * a file. (Authenticatee may, though.) 02392 */ 02393 if (flags && ((cp = strchr(word, ':')) == NULL || 02394 strchr(cp + 1, ':') == NULL)) 02395 continue; 02396 02397 if (secret != NULL) { 02398 /* 02399 * Special syntax: @/pathname means read secret from file. 02400 */ 02401 if (word[0] == '@' && word[1] == '/') { 02402 strlcpy(atfile, word+1, sizeof(atfile)); 02403 if ((sf = fopen(atfile, "r")) == NULL) { 02404 ppp_warn("can't open indirect secret file %s", atfile); 02405 continue; 02406 } 02407 check_access(sf, atfile); 02408 if (!getword(sf, word, &xxx, atfile)) { 02409 ppp_warn("no secret in indirect secret file %s", atfile); 02410 fclose(sf); 02411 continue; 02412 } 02413 fclose(sf); 02414 } 02415 strlcpy(lsecret, word, sizeof(lsecret)); 02416 } 02417 02418 /* 02419 * Now read address authorization info and make a wordlist. 02420 */ 02421 app = &alist; 02422 for (;;) { 02423 if (!getword(f, word, &newline, filename) || newline) 02424 break; 02425 ap = (struct wordlist *) 02426 malloc(sizeof(struct wordlist) + strlen(word) + 1); 02427 if (ap == NULL) 02428 novm("authorized addresses"); 02429 ap->word = (char *) (ap + 1); 02430 strcpy(ap->word, word); 02431 *app = ap; 02432 app = &ap->next; 02433 } 02434 *app = NULL; 02435 02436 /* 02437 * This is the best so far; remember it. 02438 */ 02439 best_flag = got_flag; 02440 if (addr_list) 02441 free_wordlist(addr_list); 02442 addr_list = alist; 02443 if (secret != NULL) 02444 strlcpy(secret, lsecret, MAXWORDLEN); 02445 02446 if (!newline) 02447 break; 02448 } 02449 02450 /* scan for a -- word indicating the start of options */ 02451 for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) 02452 if (strcmp(ap->word, "--") == 0) 02453 break; 02454 /* ap = start of options */ 02455 if (ap != NULL) { 02456 ap = ap->next; /* first option */ 02457 free(*app); /* free the "--" word */ 02458 *app = NULL; /* terminate addr list */ 02459 } 02460 if (opts != NULL) 02461 *opts = ap; 02462 else if (ap != NULL) 02463 free_wordlist(ap); 02464 if (addrs != NULL) 02465 *addrs = addr_list; 02466 else if (addr_list != NULL) 02467 free_wordlist(addr_list); 02468 02469 return best_flag; 02470 } 02471 02472 /* 02473 * wordlist_count - return the number of items in a wordlist 02474 */ 02475 static int 02476 wordlist_count(wp) 02477 struct wordlist *wp; 02478 { 02479 int n; 02480 02481 for (n = 0; wp != NULL; wp = wp->next) 02482 ++n; 02483 return n; 02484 } 02485 02486 /* 02487 * free_wordlist - release memory allocated for a wordlist. 02488 */ 02489 static void 02490 free_wordlist(wp) 02491 struct wordlist *wp; 02492 { 02493 struct wordlist *next; 02494 02495 while (wp != NULL) { 02496 next = wp->next; 02497 free(wp); 02498 wp = next; 02499 } 02500 } 02501 #endif /* UNUSED */ 02502 02503 #endif /* PPP_SUPPORT */
Generated on Tue Jul 12 2022 13:15:52 by
