X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Foptions.c;h=5c207d7bb2adf205b93da1bb764ac91dc69caa3a;hp=2661fa4d26d141204505e0fb7df3a22c1f423393;hb=7ff1691466ad589562e84516e29a4a83bab71e1f;hpb=0b63a24d54ba4708c88e31bdd74b0145956c1478 diff --git a/pppd/options.c b/pppd/options.c index 2661fa4..5c207d7 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,21 +18,23 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.1 1993/11/11 03:54:25 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.18 1995/04/26 06:46:09 paulus Exp $"; #endif #include #include #include +#include #include #include #include #include #include +#include #include #include +#include -#include "ppp.h" #include "pppd.h" #include "pathnames.h" #include "patchlevel.h" @@ -41,90 +43,132 @@ static char rcsid[] = "$Id: options.c,v 1.1 1993/11/11 03:54:25 paulus Exp $"; #include "ipcp.h" #include "upap.h" #include "chap.h" +#include "ccp.h" + +#include #define FALSE 0 #define TRUE 1 +#if defined(ultrix) || defined(NeXT) +char *strdup __P((char *)); +#endif + +#ifndef GIDSET_TYPE +#define GIDSET_TYPE gid_t +#endif /* - * Prototypes + * Option variables and default values. */ -static int setdebug __ARGS((void)); -static int setpassive __ARGS((void)); -static int setsilent __ARGS((void)); -static int noopt __ARGS((void)); -static int setnovj __ARGS((void)); -static int reqpap __ARGS((void)); -static int nopap __ARGS((void)); -static int setupapfile __ARGS((char **)); -static int nochap __ARGS((void)); -static int reqchap __ARGS((void)); -static int setspeed __ARGS((char *)); -static int noaccomp __ARGS((void)); -static int noasyncmap __ARGS((void)); -static int noipaddr __ARGS((void)); -static int nomagicnumber __ARGS((void)); -static int setasyncmap __ARGS((char **)); -static int setmru __ARGS((char **)); -static int nomru __ARGS((void)); -static int nopcomp __ARGS((void)); -static int setconnector __ARGS((char **)); -static int setdomain __ARGS((char **)); -static int setnetmask __ARGS((char **)); -static int setcrtscts __ARGS((void)); -static int setnodetach __ARGS((void)); -static int setmodem __ARGS((void)); -static int setlocal __ARGS((void)); -static int setname __ARGS((char **)); -static int setuser __ARGS((char **)); -static int setremote __ARGS((char **)); -static int setauth __ARGS((void)); -static int readfile __ARGS((char **)); -static int setdefaultroute __ARGS((void)); -static int setproxyarp __ARGS((void)); -static int setpersist __ARGS((void)); -static int setdologin __ARGS((void)); -static int setusehostname __ARGS((void)); -static int setlcptimeout __ARGS((char **)); -static int setlcpterm __ARGS((char **)); -static int setlcpconf __ARGS((char **)); -static int setlcpfails __ARGS((char **)); -static int setipcptimeout __ARGS((char **)); -static int setipcpterm __ARGS((char **)); -static int setipcpconf __ARGS((char **)); -static int setipcpfails __ARGS((char **)); -static int setpaptimeout __ARGS((char **)); -static int setpapreqs __ARGS((char **)); -static int setchaptimeout __ARGS((char **)); -static int setchapchal __ARGS((char **)); -static int setchapintv __ARGS((char **)); - -static int number_option __ARGS((char *, long *, int)); - +int debug = 0; /* Debug flag */ +int kdebugflag = 0; /* Tell kernel to print debug messages */ +int default_device = 1; /* Using /dev/tty or equivalent */ +char devnam[MAXPATHLEN] = "/dev/tty"; /* Device name */ +int crtscts = 0; /* Use hardware flow control */ +int modem = 1; /* Use modem control lines */ +int inspeed = 0; /* Input/Output speed requested */ +u_int32_t netmask = 0; /* IP netmask to set on interface */ +int lockflag = 0; /* Create lock file to lock the serial dev */ +int nodetach = 0; /* Don't detach from controlling tty */ +char *connector = NULL; /* Script to establish physical link */ +char *disconnector = NULL; /* Script to disestablish physical link */ +char user[MAXNAMELEN]; /* Username for PAP */ +char passwd[MAXSECRETLEN]; /* Password for PAP */ +int auth_required = 0; /* Peer is required to authenticate */ +int defaultroute = 0; /* assign default route through interface */ +int proxyarp = 0; /* Set up proxy ARP entry for peer */ +int persist = 0; /* Reopen link after it goes down */ +int uselogin = 0; /* Use /etc/passwd for checking PAP */ +int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ +int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ +char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ +int usehostname = 0; /* Use hostname for our_name */ +int disable_defaultip = 0; /* Don't use hostname for default IP adrs */ +char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ +int cryptpap; /* Passwords in pap-secrets are encrypted */ + +#ifdef _linux_ +int idle_time_limit = 0; +static int setidle __P((char **)); +#endif /* - * Option variables + * Prototypes */ -extern char *progname; -extern int debug; -extern int modem; -extern int crtscts; -extern int nodetach; -extern char *connector; -extern int inspeed; -extern char devname[]; -extern int default_device; -extern u_long netmask; -extern int detach; -extern char user[]; -extern char passwd[]; -extern int auth_required; -extern int proxyarp; -extern int persist; -extern int uselogin; -extern char our_name[]; -extern char remote_name[]; -int usehostname; +static int setdebug __P((void)); +static int setkdebug __P((char **)); +static int setpassive __P((void)); +static int setsilent __P((void)); +static int noopt __P((void)); +static int setnovj __P((void)); +static int setnovjccomp __P((void)); +static int setvjslots __P((char **)); +static int reqpap __P((void)); +static int nopap __P((void)); +static int setupapfile __P((char **)); +static int nochap __P((void)); +static int reqchap __P((void)); +static int setspeed __P((char *)); +static int noaccomp __P((void)); +static int noasyncmap __P((void)); +static int noipaddr __P((void)); +static int nomagicnumber __P((void)); +static int setasyncmap __P((char **)); +static int setescape __P((char **)); +static int setmru __P((char **)); +static int setmtu __P((char **)); +static int nomru __P((void)); +static int nopcomp __P((void)); +static int setconnector __P((char **)); +static int setdisconnector __P((char **)); +static int setdomain __P((char **)); +static int setnetmask __P((char **)); +static int setcrtscts __P((void)); +static int setnocrtscts __P((void)); +static int setxonxoff __P((void)); +static int setnodetach __P((void)); +static int setmodem __P((void)); +static int setlocal __P((void)); +static int setlock __P((void)); +static int setname __P((char **)); +static int setuser __P((char **)); +static int setremote __P((char **)); +static int setauth __P((void)); +static int readfile __P((char **)); +static int setdefaultroute __P((void)); +static int setproxyarp __P((void)); +static int setpersist __P((void)); +static int setdologin __P((void)); +static int setusehostname __P((void)); +static int setnoipdflt __P((void)); +static int setlcptimeout __P((char **)); +static int setlcpterm __P((char **)); +static int setlcpconf __P((char **)); +static int setlcpfails __P((char **)); +static int setipcptimeout __P((char **)); +static int setipcpterm __P((char **)); +static int setipcpconf __P((char **)); +static int setipcpfails __P((char **)); +static int setpaptimeout __P((char **)); +static int setpapreqs __P((char **)); +static int setchaptimeout __P((char **)); +static int setchapchal __P((char **)); +static int setchapintv __P((char **)); +static int setipcpaccl __P((void)); +static int setipcpaccr __P((void)); +static int setlcpechointv __P((char **)); +static int setlcpechofails __P((char **)); +static int setbsdcomp __P((char **)); +static int setnobsdcomp __P((void)); +static int setipparam __P((char **)); +static int setpapcrypt __P((void)); + +static int number_option __P((char *, long *, int)); +static int readable __P((int fd)); + +void usage(); /* * Valid arguments. @@ -134,63 +178,88 @@ static struct cmd { int num_args; int (*cmd_func)(); } cmds[] = { - "-all", 0, noopt, /* Don't request/allow any options */ - "-ac", 0, noaccomp, /* Disable Address/Control compress */ - "-am", 0, noasyncmap, /* Disable asyncmap negotiation */ - "-as", 1, setasyncmap, /* set the desired async map */ - "-d", 0, setdebug, /* Increase debugging level */ - "-detach", 0, setnodetach, /* don't fork */ - "-ip", 0, noipaddr, /* Disable IP address negotiation */ - "-mn", 0, nomagicnumber, /* Disable magic number negotiation */ - "-mru", 0, nomru, /* Disable mru negotiation */ - "-p", 0, setpassive, /* Set passive mode */ - "-pc", 0, nopcomp, /* Disable protocol field compress */ - "+ua", 1, setupapfile, /* Get PAP user and password from file */ - "+pap", 0, reqpap, /* Require PAP auth from peer */ - "-pap", 0, nopap, /* Don't allow UPAP authentication with peer */ - "+chap", 0, reqchap, /* Require CHAP authentication from peer */ - "-chap", 0, nochap, /* Don't allow CHAP authentication with peer */ - "-vj", 0, setnovj, /* disable VJ compression */ - "asyncmap", 1, setasyncmap, /* set the desired async map */ - "connect", 1, setconnector, /* A program to set up a connection */ - "crtscts", 0, setcrtscts, /* set h/w flow control */ - "debug", 0, setdebug, /* Increase debugging level */ - "domain", 1, setdomain, /* Add given domain name to hostname*/ - "mru", 1, setmru, /* Set MRU value for negotiation */ - "netmask", 1, setnetmask, /* set netmask */ - "passive", 0, setpassive, /* Set passive mode */ - "silent", 0, setsilent, /* Set silent mode */ - "modem", 0, setmodem, /* Use modem control lines */ - "local", 0, setlocal, /* Don't use modem control lines */ - "name", 1, setname, /* Set local name for authentication */ - "user", 1, setuser, /* Set username for PAP auth with peer */ - "usehostname", 0, setusehostname, /* Must use hostname for auth. */ - "remotename", 1, setremote, /* Set remote name for authentication */ - "auth", 0, setauth, /* Require authentication from peer */ - "file", 1, readfile, /* Take options from a file */ - "defaultroute", 0, setdefaultroute, /* Add default route */ - "proxyarp", 0, setproxyarp, /* Add proxy ARP entry */ - "persist", 0, setpersist, /* Keep on reopening connection after close */ - "login", 0, setdologin, /* Use system password database for UPAP */ - "lcp-restart", 1, setlcptimeout, /* Set timeout for LCP */ - "lcp-max-terminate", 1, setlcpterm, /* Set max #xmits for term-reqs */ - "lcp-max-configure", 1, setlcpconf, /* Set max #xmits for conf-reqs */ - "lcp-max-failure", 1, setlcpfails, /* Set max #conf-naks for LCP */ - "ipcp-restart", 1, setipcptimeout, /* Set timeout for IPCP */ - "ipcp-max-terminate", 1, setipcpterm, /* Set max #xmits for term-reqs */ - "ipcp-max-configure", 1, setipcpconf, /* Set max #xmits for conf-reqs */ - "ipcp-max-failure", 1, setipcpfails, /* Set max #conf-naks for IPCP */ - "pap-restart", 1, setpaptimeout, /* Set timeout for UPAP */ - "pap-max-authreq", 1, setpapreqs, /* Set max #xmits for auth-reqs */ - "chap-restart", 1, setchaptimeout, /* Set timeout for CHAP */ - "chap-max-challenge", 1, setchapchal, /* Set max #xmits for challenge */ - "chap-interval", 1, setchapintv, /* Set interval for rechallenge */ - NULL + {"-all", 0, noopt}, /* Don't request/allow any options */ + {"-ac", 0, noaccomp}, /* Disable Address/Control compress */ + {"-am", 0, noasyncmap}, /* Disable asyncmap negotiation */ + {"-as", 1, setasyncmap}, /* set the desired async map */ + {"-d", 0, setdebug}, /* Increase debugging level */ + {"-detach", 0, setnodetach}, /* don't fork */ + {"-ip", 0, noipaddr}, /* Disable IP address negotiation */ + {"-mn", 0, nomagicnumber}, /* Disable magic number negotiation */ + {"-mru", 0, nomru}, /* Disable mru negotiation */ + {"-p", 0, setpassive}, /* Set passive mode */ + {"-pc", 0, nopcomp}, /* Disable protocol field compress */ + {"+ua", 1, setupapfile}, /* Get PAP user and password from file */ + {"+pap", 0, reqpap}, /* Require PAP auth from peer */ + {"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */ + {"+chap", 0, reqchap}, /* Require CHAP authentication from peer */ + {"-chap", 0, nochap}, /* Don't allow CHAP authentication with peer */ + {"-vj", 0, setnovj}, /* disable VJ compression */ + {"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */ + {"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */ + {"asyncmap", 1, setasyncmap}, /* set the desired async map */ + {"escape", 1, setescape}, /* set chars to escape on transmission */ + {"connect", 1, setconnector}, /* A program to set up a connection */ + {"disconnect", 1, setdisconnector}, /* program to disconnect serial dev. */ + {"crtscts", 0, setcrtscts}, /* set h/w flow control */ + {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */ + {"xonxoff", 0, setxonxoff}, /* set s/w flow control */ + {"debug", 0, setdebug}, /* Increase debugging level */ + {"kdebug", 1, setkdebug}, /* Enable kernel-level debugging */ + {"domain", 1, setdomain}, /* Add given domain name to hostname*/ + {"mru", 1, setmru}, /* Set MRU value for negotiation */ + {"mtu", 1, setmtu}, /* Set our MTU */ + {"netmask", 1, setnetmask}, /* set netmask */ + {"passive", 0, setpassive}, /* Set passive mode */ + {"silent", 0, setsilent}, /* Set silent mode */ + {"modem", 0, setmodem}, /* Use modem control lines */ + {"local", 0, setlocal}, /* Don't use modem control lines */ + {"lock", 0, setlock}, /* Lock serial device (with lock file) */ + {"name", 1, setname}, /* Set local name for authentication */ + {"user", 1, setuser}, /* Set username for PAP auth with peer */ + {"usehostname", 0, setusehostname}, /* Must use hostname for auth. */ + {"remotename", 1, setremote}, /* Set remote name for authentication */ + {"auth", 0, setauth}, /* Require authentication from peer */ + {"file", 1, readfile}, /* Take options from a file */ + {"defaultroute", 0, setdefaultroute}, /* Add default route */ + {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */ + {"persist", 0, setpersist}, /* Keep on reopening connection after close */ + {"login", 0, setdologin}, /* Use system password database for UPAP */ + {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */ + {"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */ + {"lcp-echo-interval", 1, setlcpechointv}, /* time for lcp echo events */ + {"lcp-restart", 1, setlcptimeout}, /* Set timeout for LCP */ + {"lcp-max-terminate", 1, setlcpterm}, /* Set max #xmits for term-reqs */ + {"lcp-max-configure", 1, setlcpconf}, /* Set max #xmits for conf-reqs */ + {"lcp-max-failure", 1, setlcpfails}, /* Set max #conf-naks for LCP */ + {"ipcp-restart", 1, setipcptimeout}, /* Set timeout for IPCP */ + {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */ + {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */ + {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */ + {"pap-restart", 1, setpaptimeout}, /* Set timeout for UPAP */ + {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */ + {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */ + {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */ + {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */ + {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */ + {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */ + {"bsdcomp", 1, setbsdcomp}, /* request BSD-Compress */ + {"-bsdcomp", 0, setnobsdcomp}, /* don't allow BSD-Compress */ + {"ipparam", 1, setipparam}, /* set ip script parameter */ + {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ +#ifdef _linux_ + {"idle-disconnect", 1, setidle}, /* seconds for disconnect of idle IP */ +#endif + {NULL, 0, NULL} }; +#ifndef IMPLEMENTATION +#define IMPLEMENTATION "" +#endif + static char *usage_string = "\ -pppd version %s patch level %d\n\ +pppd version %s patch level %d%s\n\ Usage: %s [ arguments ], where arguments are:\n\ Communicate over the named device\n\ Set the baud rate to \n\ @@ -208,34 +277,6 @@ Usage: %s [ arguments ], where arguments are:\n\ See pppd(8) for more options.\n\ "; -/* -Options omitted: - -all Don't request/allow any options\n\ - -ac Disable Address/Control compression\n\ - -am Disable asyncmap negotiation\n\ - -as Set the desired async map to hex \n\ - -d Increase debugging level\n\ - -detach Don't fork to background\n\ - -ip Disable IP address negotiation\n\ - -mn Disable magic number negotiation\n\ - -mru Disable mru negotiation\n\ - -p Set passive mode\n\ - -pc Disable protocol field compression\n\ - +ua Get username and password for authenticating\n\ - with peer using PAP from file \n\ - +pap Require PAP authentication from peer\n\ - -pap Don't agree to authenticating with peer using PAP\n\ - +chap Require CHAP authentication from peer\n\ - -chap Don't agree to authenticating with peer using CHAP\n\ - -vj disable VJ compression\n\ - -auth Don't agree to authenticate with peer\n\ - debug Increase debugging level\n\ - domain Append domain name to hostname for authentication\n\ - passive Set passive mode\n\ - local Don't use modem control lines\n\ - proxyarp Add proxy ARP entry\n\ -*/ - /* * parse_args - parse a string of arguments, from the command @@ -248,6 +289,7 @@ parse_args(argc, argv) { char *arg, *val; struct cmd *cmdp; + int ret; while (argc > 0) { arg = *argv++; @@ -274,11 +316,15 @@ parse_args(argc, argv) /* * Maybe a tty name, speed or IP address? */ - if (!setdevname(arg) && !setspeed(arg) && !setipaddr(arg)) { + if ((ret = setdevname(arg)) == 0 + && (ret = setspeed(arg)) == 0 + && (ret = setipaddr(arg)) == 0) { fprintf(stderr, "%s: unrecognized command\n", arg); usage(); return 0; } + if (ret < 0) /* error */ + return 0; } } return 1; @@ -287,9 +333,11 @@ parse_args(argc, argv) /* * usage - print out a message telling how to use the program. */ +void usage() { - fprintf(stderr, usage_string, VERSION, PATCHLEVEL, progname); + fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, + progname); } /* @@ -297,22 +345,30 @@ usage() * and interpret them. */ int -options_from_file(filename) +options_from_file(filename, must_exist, check_prot) char *filename; + int must_exist; + int check_prot; { FILE *f; - int i, newline; + int i, newline, ret; struct cmd *cmdp; char *argv[MAXARGS]; char args[MAXARGS][MAXWORDLEN]; char cmd[MAXWORDLEN]; if ((f = fopen(filename, "r")) == NULL) { - if (errno == ENOENT) + if (!must_exist && errno == ENOENT) return 1; perror(filename); - exit(1); + return 0; } + if (check_prot && !readable(fileno(f))) { + fprintf(stderr, "%s: access denied\n", filename); + fclose(f); + return 0; + } + while (getword(f, cmd, &newline, filename)) { /* * First see if it's a command. @@ -341,12 +397,16 @@ options_from_file(filename) /* * Maybe a tty name, speed or IP address? */ - if (!setdevname(cmd) && !setspeed(cmd) && !setipaddr(cmd)) { + if ((ret = setdevname(cmd)) == 0 + && (ret = setspeed(cmd)) == 0 + && (ret = setipaddr(cmd)) == 0) { fprintf(stderr, "In file %s: unrecognized command %s\n", filename, cmd); fclose(f); return 0; } + if (ret < 0) /* error */ + return 0; } } return 1; @@ -361,20 +421,78 @@ options_from_user() { char *user, *path, *file; int ret; + struct passwd *pw; - if ((user = getenv("HOME")) == NULL) - return; - file = "/.ppprc"; - path = malloc(strlen(user) + strlen(file) + 1); + pw = getpwuid(getuid()); + if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) + return 1; + file = _PATH_USEROPT; + path = malloc(strlen(user) + strlen(file) + 2); if (path == NULL) novm("init file name"); strcpy(path, user); + strcat(path, "/"); strcat(path, file); - ret = options_from_file(path); + ret = options_from_file(path, 0, 1); free(path); return ret; } +/* + * options_for_tty - See if an options file exists for the serial + * device, and if so, interpret options from it. + */ +int +options_for_tty() +{ + char *dev, *path; + int ret; + + dev = strrchr(devnam, '/'); + if (dev == NULL) + dev = devnam; + else + ++dev; + if (strcmp(dev, "tty") == 0) + return 1; /* don't look for /etc/ppp/options.tty */ + path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1); + if (path == NULL) + novm("tty init file name"); + strcpy(path, _PATH_TTYOPT); + strcat(path, dev); + ret = options_from_file(path, 0, 0); + free(path); + return ret; +} + +/* + * readable - check if a file is readable by the real user. + */ +static int +readable(fd) + int fd; +{ + uid_t uid; + int ngroups, i; + struct stat sbuf; + GIDSET_TYPE groups[NGROUPS_MAX]; + + uid = getuid(); + if (uid == 0) + return 1; + if (fstat(fd, &sbuf) != 0) + return 0; + if (sbuf.st_uid == uid) + return sbuf.st_mode & S_IRUSR; + if (sbuf.st_gid == getgid()) + return sbuf.st_mode & S_IRGRP; + ngroups = getgroups(NGROUPS_MAX, groups); + for (i = 0; i < ngroups; ++i) + if (sbuf.st_gid == groups[i]) + return sbuf.st_mode & S_IRGRP; + return sbuf.st_mode & S_IROTH; +} + /* * Read a word from a file. * Words are delimited by white-space or by quotes ("). @@ -460,7 +578,7 @@ getword(f, word, newlinep, filename) word[len] = c; ++len; if (c == '\\') - quoted = 1; + escape = 1; } if ((c = getc(f)) == EOF) break; @@ -531,7 +649,7 @@ static int readfile(argv) char **argv; { - return options_from_file(*argv); + return options_from_file(*argv, 1, 1); } /* @@ -541,10 +659,19 @@ static int setdebug() { debug++; - setlogmask(LOG_UPTO(LOG_DEBUG)); return (1); } +/* + * setkdebug - Set kernel debugging level. + */ +static int +setkdebug(argv) + char **argv; +{ + return int_option(*argv, &kdebugflag); +} + /* * noopt - Disable all options. */ @@ -635,6 +762,27 @@ setmru(argv) } +/* + * setmru - Set the largest MTU we'll use. + */ +static int +setmtu(argv) + char **argv; +{ + long mtu; + + if (!number_option(*argv, &mtu, 0)) + return 0; + if (mtu < MINMRU || mtu > MAXMRU) { + fprintf(stderr, "mtu option value of %ld is too %s\n", mtu, + (mtu < MINMRU? "small": "large")); + return 0; + } + lcp_allowoptions[0].mru = mtu; + return (1); +} + + /* * nopcomp - Disable Protocol field compression negotiation. */ @@ -690,6 +838,7 @@ reqpap() { lcp_wantoptions[0].neg_upap = 1; auth_required = 1; + return 1; } @@ -708,7 +857,11 @@ setupapfile(argv) /* open user info file */ if ((ufile = fopen(*argv, "r")) == NULL) { fprintf(stderr, "unable to open user login data file %s\n", *argv); - exit(1); + return 0; + } + if (!readable(fileno(ufile))) { + fprintf(stderr, "%s: access denied\n", *argv); + return 0; } check_access(ufile, *argv); @@ -716,7 +869,7 @@ setupapfile(argv) if (fgets(user, MAXNAMELEN - 1, ufile) == NULL || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ fprintf(stderr, "Unable to read user login data file %s.\n", *argv); - exit(2); + return 0; } fclose(ufile); @@ -756,7 +909,7 @@ reqchap() /* - * setnovj - diable vj compression + * setnovj - disable vj compression */ static int setnovj() @@ -766,6 +919,40 @@ setnovj() return (1); } + +/* + * setnovjccomp - disable VJ connection-ID compression + */ +static int +setnovjccomp() +{ + ipcp_wantoptions[0].cflag = 0; + ipcp_allowoptions[0].cflag = 0; + return 1; +} + + +/* + * setvjslots - set maximum number of connection slots for VJ compression + */ +static int +setvjslots(argv) + char **argv; +{ + int value; + + if (!int_option(*argv, &value)) + return 0; + if (value < 2 || value > 16) { + fprintf(stderr, "pppd: vj-max-slots value must be between 2 and 16\n"); + return 0; + } + ipcp_wantoptions [0].maxslotindex = + ipcp_allowoptions[0].maxslotindex = value - 1; + return 1; +} + + /* * setconnector - Set a program to connect to a serial line */ @@ -780,6 +967,20 @@ setconnector(argv) return (1); } +/* + * setdisconnector - Set a program to disconnect from the serial line + */ +static int +setdisconnector(argv) + char **argv; +{ + disconnector = strdup(*argv); + if (disconnector == NULL) + novm("disconnector string"); + + return (1); +} + /* * setdomain - Set domain name to append to hostname @@ -793,6 +994,10 @@ setdomain(argv) return (1); } + +/* + * setasyncmap - add bits to asyncmap (what we request peer to escape). + */ static int setasyncmap(argv) char **argv; @@ -806,6 +1011,38 @@ setasyncmap(argv) return(1); } + +/* + * setescape - add chars to the set we escape on transmission. + */ +static int +setescape(argv) + char **argv; +{ + int n, ret; + char *p, *endp; + + p = *argv; + ret = 1; + while (*p) { + n = strtol(p, &endp, 16); + if (p == endp) { + fprintf(stderr, "%s: invalid hex number: %s\n", progname, p); + return 0; + } + p = endp; + if (n < 0 || 0x20 <= n && n <= 0x3F || n == 0x5E || n > 0xFF) { + fprintf(stderr, "%s: can't escape character 0x%x\n", progname, n); + ret = 0; + } else + xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); + while (*p == ',' || *p == ' ') + ++p; + } + return ret; +} + + /* * setspeed - Set the speed. */ @@ -847,16 +1084,16 @@ setdevname(cp) */ if (stat(cp, &statbuf) < 0) { if (errno == ENOENT) - return (0); + return 0; syslog(LOG_ERR, cp); - exit(1); + return -1; } - (void) strncpy(devname, cp, MAXPATHLEN); - devname[MAXPATHLEN-1] = 0; + (void) strncpy(devnam, cp, MAXPATHLEN); + devnam[MAXPATHLEN-1] = 0; default_device = FALSE; - return (1); + return 1; } @@ -868,15 +1105,15 @@ setipaddr(arg) char *arg; { struct hostent *hp; - char *colon, *index(); - u_long local, remote; + char *colon; + u_int32_t local, remote; ipcp_options *wo = &ipcp_wantoptions[0]; /* * IP address pair separated by ":". */ - if ((colon = index(arg, ':')) == NULL) - return (0); + if ((colon = strchr(arg, ':')) == NULL) + return 0; /* * If colon first character, then no local addr. @@ -885,16 +1122,20 @@ setipaddr(arg) *colon = '\0'; if ((local = inet_addr(arg)) == -1) { if ((hp = gethostbyname(arg)) == NULL) { - fprintf(stderr, "unknown host: %s", arg); - local = 0; + fprintf(stderr, "unknown host: %s\n", arg); + return -1; } else { - local = *(long *)hp->h_addr; + local = *(u_int32_t *)hp->h_addr; if (our_name[0] == 0) { strncpy(our_name, arg, MAXNAMELEN); our_name[MAXNAMELEN-1] = 0; } } } + if (bad_ip_adrs(local)) { + fprintf(stderr, "bad local IP address %s\n", ip_ntoa(local)); + return -1; + } if (local != 0) wo->ouraddr = local; *colon = ':'; @@ -906,21 +1147,58 @@ setipaddr(arg) if (*++colon != '\0') { if ((remote = inet_addr(colon)) == -1) { if ((hp = gethostbyname(colon)) == NULL) { - fprintf(stderr, "unknown host: %s", colon); - remote = 0; + fprintf(stderr, "unknown host: %s\n", colon); + return -1; } else { - remote = *(long *)hp->h_addr; + remote = *(u_int32_t *)hp->h_addr; if (remote_name[0] == 0) { strncpy(remote_name, colon, MAXNAMELEN); remote_name[MAXNAMELEN-1] = 0; } } } + if (bad_ip_adrs(remote)) { + fprintf(stderr, "bad remote IP address %s\n", ip_ntoa(remote)); + return -1; + } if (remote != 0) wo->hisaddr = remote; } - return (1); + return 1; +} + + +/* + * setnoipdflt - disable setipdefault() + */ +static int +setnoipdflt() +{ + disable_defaultip = 1; + return 1; +} + + +/* + * setipcpaccl - accept peer's idea of our address + */ +static int +setipcpaccl() +{ + ipcp_wantoptions[0].accept_local = 1; + return 1; +} + + +/* + * setipcpaccr - accept peer's idea of its address + */ +static int +setipcpaccr() +{ + ipcp_wantoptions[0].accept_remote = 1; + return 1; } @@ -931,13 +1209,13 @@ void setipdefault() { struct hostent *hp; - u_long local; + u_int32_t local; ipcp_options *wo = &ipcp_wantoptions[0]; /* * If local IP address already given, don't bother. */ - if (wo->ouraddr != 0) + if (wo->ouraddr != 0 || disable_defaultip) return; /* @@ -945,10 +1223,11 @@ setipdefault() * and take the first IP address as our local IP address. * If there isn't an IP address for our hostname, too bad. */ + wo->accept_local = 1; /* don't insist on this default value */ if ((hp = gethostbyname(hostname)) == NULL) return; - local = *(long *)hp->h_addr; - if (local != 0) + local = *(u_int32_t *)hp->h_addr; + if (local != 0 && !bad_ip_adrs(local)) wo->ouraddr = local; } @@ -960,17 +1239,30 @@ static int setnetmask(argv) char **argv; { - u_long mask; - - if ((mask = inet_addr(*argv)) == -1) { + u_int32_t mask; + + if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) { fprintf(stderr, "Invalid netmask %s\n", *argv); - exit(1); + return 0; } netmask = mask; return (1); } +/* + * Return user specified netmask. A value of zero means no netmask has + * been set. + */ +/* ARGSUSED */ +u_int32_t +GetMask(addr) + u_int32_t addr; +{ + return(netmask); +} + + static int setcrtscts() { @@ -978,6 +1270,20 @@ setcrtscts() return (1); } +static int +setnocrtscts() +{ + crtscts = -1; + return (1); +} + +static int +setxonxoff() +{ + crtscts = 2; + return (1); +} + static int setnodetach() { @@ -999,6 +1305,13 @@ setlocal() return 1; } +static int +setlock() +{ + lockflag = 1; + return 1; +} + static int setusehostname() { @@ -1070,6 +1383,24 @@ setdologin() return 1; } +/* + * Functions to set the echo interval for modem-less monitors + */ + +static int +setlcpechointv(argv) + char **argv; +{ + return int_option(*argv, &lcp_echo_interval); +} + +static int +setlcpechofails(argv) + char **argv; +{ + return int_option(*argv, &lcp_echo_fails); +} + /* * Functions to set timeouts, max transmits, etc. */ @@ -1077,77 +1408,160 @@ static int setlcptimeout(argv) char **argv; { - return int_option(*argv, &lcp_fsm[0].timeouttime, 0); + return int_option(*argv, &lcp_fsm[0].timeouttime); +} + +static int +setlcpterm(argv) + char **argv; +{ + return int_option(*argv, &lcp_fsm[0].maxtermtransmits); } -static int setlcpterm(argv) +static int +setlcpconf(argv) + char **argv; +{ + return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits); +} + +static int +setlcpfails(argv) + char **argv; +{ + return int_option(*argv, &lcp_fsm[0].maxnakloops); +} + +static int +setipcptimeout(argv) char **argv; { - return int_option(*argv, &lcp_fsm[0].maxtermtransmits, 0); + return int_option(*argv, &ipcp_fsm[0].timeouttime); } -static int setlcpconf(argv) +static int +setipcpterm(argv) char **argv; { - return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits, 0); + return int_option(*argv, &ipcp_fsm[0].maxtermtransmits); } -static int setlcpfails(argv) +static int +setipcpconf(argv) char **argv; { - return int_option(*argv, &lcp_fsm[0].maxnakloops, 0); + return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits); } -static int setipcptimeout(argv) +static int +setipcpfails(argv) char **argv; { - return int_option(*argv, &ipcp_fsm[0].timeouttime, 0); + return int_option(*argv, &lcp_fsm[0].maxnakloops); } -static int setipcpterm(argv) +static int +setpaptimeout(argv) char **argv; { - return int_option(*argv, &ipcp_fsm[0].maxtermtransmits, 0); + return int_option(*argv, &upap[0].us_timeouttime); } -static int setipcpconf(argv) +static int +setpapreqs(argv) char **argv; { - return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits, 0); + return int_option(*argv, &upap[0].us_maxtransmits); } -static int setipcpfails(argv) +static int +setchaptimeout(argv) char **argv; { - return int_option(*argv, &lcp_fsm[0].maxnakloops, 0); + return int_option(*argv, &chap[0].timeouttime); } -static int setpaptimeout(argv) +static int +setchapchal(argv) char **argv; { - return int_option(*argv, &upap[0].us_timeouttime, 0); + return int_option(*argv, &chap[0].max_transmits); } -static int setpapreqs(argv) +static int +setchapintv(argv) char **argv; { - return int_option(*argv, &upap[0].us_maxtransmits, 0); + return int_option(*argv, &chap[0].chal_interval); } -static int setchaptimeout(argv) +static int +setbsdcomp(argv) char **argv; { - return int_option(*argv, &chap[0].timeouttime, 0); + int rbits, abits; + char *str, *endp; + + str = *argv; + abits = rbits = strtol(str, &endp, 0); + if (endp != str && *endp == ',') { + str = endp + 1; + abits = strtol(str, &endp, 0); + } + if (*endp != 0 || endp == str) { + fprintf(stderr, "%s: invalid argument format for bsdcomp option\n", + progname); + return 0; + } + if (rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS) + || abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS)) { + fprintf(stderr, "%s: bsdcomp option values must be 0 or %d .. %d\n", + progname, BSD_MIN_BITS, BSD_MAX_BITS); + return 0; + } + if (rbits > 0) { + ccp_wantoptions[0].bsd_compress = 1; + ccp_wantoptions[0].bsd_bits = rbits; + } else + ccp_wantoptions[0].bsd_compress = 0; + if (abits > 0) { + ccp_allowoptions[0].bsd_compress = 1; + ccp_allowoptions[0].bsd_bits = abits; + } else + ccp_allowoptions[0].bsd_compress = 0; + return 1; +} + +static int +setnobsdcomp() +{ + ccp_wantoptions[0].bsd_compress = 0; + ccp_allowoptions[0].bsd_compress = 0; + return 1; } -static int setchapchal(argv) +static int +setipparam(argv) char **argv; { - return int_option(*argv, &chap[0].max_transmits, 0); + ipparam = strdup(*argv); + if (ipparam == NULL) + novm("ipparam string"); + + return 1; +} + +static int +setpapcrypt() +{ + cryptpap = 1; + return 1; } -static int setchapintv(argv) +#ifdef _linux_ +static int setidle (argv) char **argv; { - return int_option(*argv, &chap[0].chal_interval, 0); + return int_option(*argv, &idle_time_limit); } +#endif