diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1996-12-23 13:22:50 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1996-12-23 13:22:50 +0000 |
commit | 244ae4f36d8485d801b276c564b0912f8970db1a (patch) | |
tree | c2338ca08d1a28b6a12f5a03b849eebdb17a864c /usr.sbin/pppd/options.c | |
parent | b091d7e1ea9e2cf69fd0694da9b01b1c022b4611 (diff) |
pppd 2.3b3 import. some minor buf oflow fixes and so.
try it out ppl, but i've got it running talking to cisco w/ all the AFs
enabled in kernel.
Diffstat (limited to 'usr.sbin/pppd/options.c')
-rw-r--r-- | usr.sbin/pppd/options.c | 318 |
1 files changed, 201 insertions, 117 deletions
diff --git a/usr.sbin/pppd/options.c b/usr.sbin/pppd/options.c index d789c32e0d1..4f5347908b5 100644 --- a/usr.sbin/pppd/options.c +++ b/usr.sbin/pppd/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.5 1996/12/15 23:20:34 millert Exp $ */ +/* $OpenBSD: options.c,v 1.6 1996/12/23 13:22:45 mickey Exp $ */ /* * options.c - handles option processing for PPP. @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: options.c,v 1.5 1996/12/15 23:20:34 millert Exp $"; +static char rcsid[] = "$OpenBSD: options.c,v 1.6 1996/12/23 13:22:45 mickey Exp $"; #endif #include <ctype.h> @@ -48,7 +48,9 @@ static char rcsid[] = "$OpenBSD: options.c,v 1.5 1996/12/15 23:20:34 millert Exp #include "upap.h" #include "chap.h" #include "ccp.h" -#include "bpf_compile.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif #ifdef IPX_CHANGE #include "ipxcp.h" @@ -102,11 +104,14 @@ char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ int cryptpap; /* Passwords in pap-secrets are encrypted */ int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ int holdoff = 30; /* # seconds to pause before reconnecting */ -struct bpf_program pass_filter;/* Filter program for packets to pass */ -struct bpf_program active_filter; /* Filter program for link-active pkts */ int refuse_pap = 0; /* Set to say we won't do PAP */ int refuse_chap = 0; /* Set to say we won't do CHAP */ +struct option_info auth_req_info; +struct option_info connector_info; +struct option_info disconnector_info; +struct option_info welcomer_info; +struct option_info devnam_info; /* * Prototypes @@ -137,6 +142,9 @@ static int setasyncmap __P((char **)); static int setescape __P((char **)); static int setmru __P((char **)); static int setmtu __P((char **)); +#ifdef CBCP_SUPPORT +static int setcbcp __P((char **)); +#endif static int nomru __P((void)); static int nopcomp __P((void)); static int setconnector __P((char **)); @@ -156,12 +164,15 @@ static int setname __P((char **)); static int setuser __P((char **)); static int setremote __P((char **)); static int setauth __P((void)); +static int setnoauth __P((void)); static int readfile __P((char **)); +static int callfile __P((char **)); static int setdefaultroute __P((void)); static int setnodefaultroute __P((void)); static int setproxyarp __P((void)); static int setnoproxyarp __P((void)); static int setpersist __P((void)); +static int setnopersist __P((void)); static int setdologin __P((void)); static int setusehostname __P((void)); static int setnoipdflt __P((void)); @@ -195,12 +206,11 @@ static int setipparam __P((char **)); static int setpapcrypt __P((void)); static int setidle __P((char **)); static int setholdoff __P((char **)); -static int setpassfilter __P((char **)); -static int setactivefilter __P((char **)); +static int setdnsaddr __P((char **)); +static int resetipxproto __P((void)); #ifdef IPX_CHANGE static int setipxproto __P((void)); -static int resetipxproto __P((void)); static int setipxanet __P((void)); static int setipxalcl __P((void)); static int setipxarmt __P((void)); @@ -214,16 +224,9 @@ static int setipxcpconf __P((char **)); static int setipxcpfails __P((char **)); #endif /* IPX_CHANGE */ -#ifdef USE_MS_DNS -static int setdnsaddr __P((char **)); -#endif - static int number_option __P((char *, u_int32_t *, int)); static int int_option __P((char *, int *)); static int readable __P((int fd)); -static void option_error __P((char *fmt, ...)); - -void usage(); /* * Valid arguments. @@ -250,13 +253,11 @@ static struct cmd { {"-mru", 0, nomru}, /* Disable mru negotiation */ {"-p", 0, setpassive}, /* Set passive mode */ {"nopcomp", 0, nopcomp}, /* Disable protocol field compression */ -#ifdef OLD_OPTIONS {"-pc", 0, nopcomp}, /* Disable protocol field compress */ -#endif - {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */ -#ifdef OLD_OPTIONS +#if OLD_OPTIONS {"+ua", 1, setupapfile}, /* Get PAP user and password from file */ #endif + {"require-pap", 0, reqpap}, /* Require PAP authentication from peer */ {"+pap", 0, reqpap}, /* Require PAP auth from peer */ {"refuse-pap", 0, nopap}, /* Don't agree to auth to peer with PAP */ {"-pap", 0, nopap}, /* Don't allow UPAP authentication with peer */ @@ -284,6 +285,9 @@ static struct cmd { {"domain", 1, setdomain}, /* Add given domain name to hostname*/ {"mru", 1, setmru}, /* Set MRU value for negotiation */ {"mtu", 1, setmtu}, /* Set our MTU */ +#ifdef CBCP_SUPPORT + {"callback", 1, setcbcp}, /* Ask for callback */ +#endif {"netmask", 1, setnetmask}, /* set netmask */ {"passive", 0, setpassive}, /* Set passive mode */ {"silent", 0, setsilent}, /* Set silent mode */ @@ -291,11 +295,13 @@ static struct cmd { {"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 */ + {"user", 1, setuser}, /* Set name for 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 */ + {"noauth", 0, setnoauth}, /* Don't require peer to authenticate */ {"file", 1, readfile}, /* Take options from a file */ + {"call", 1, callfile}, /* Take options from a privileged file */ {"defaultroute", 0, setdefaultroute}, /* Add default route */ {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ @@ -303,6 +309,7 @@ static struct cmd { {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ {"persist", 0, setpersist}, /* Keep on reopening connection after close */ + {"nopersist", 0, setnopersist}, /* Turn off persist option */ {"demand", 0, setdemand}, /* Dial on demand */ {"login", 0, setdologin}, /* Use system password database for UPAP */ {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */ @@ -339,8 +346,9 @@ static struct cmd { {"papcrypt", 0, setpapcrypt}, /* PAP passwords encrypted */ {"idle", 1, setidle}, /* idle time limit (seconds) */ {"holdoff", 1, setholdoff}, /* set holdoff time (seconds) */ - {"pass-filter", 1, setpassfilter}, /* set filter for packets to pass */ - {"active-filter", 1, setactivefilter}, /* set filter for active pkts */ + {"ms-dns", 1, setdnsaddr}, /* DNS address for the peer's use */ + {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ + {"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ #ifdef IPX_CHANGE {"ipx-network", 1, setipxnetwork}, /* IPX network number */ @@ -358,19 +366,9 @@ static struct cmd { {"ipx-compression", 1, setipxcompression}, /* IPX compression number */ #endif {"ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */ - {"noipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ {"+ipx", 0, setipxproto}, /* Enable IPXCP (and IPX) */ - {"-ipx", 0, resetipxproto}, /* Disable IPXCP (and IPX) */ #endif /* IPX_CHANGE */ -#ifdef _linux_ - {"idle-disconnect", 1, setidle}, /* seconds for disconnect of idle IP */ -#endif - -#ifdef USE_MS_DNS - {"ms-dns", 1, setdnsaddr}, /* DNS address(es) for the peer's use */ -#endif - {NULL, 0, NULL} }; @@ -399,11 +397,11 @@ See pppd(8) for more options.\n\ "; static char *current_option; /* the name of the option being parsed */ - +static int privileged_option; /* set iff the current option came from root */ +static char *option_source; /* string saying where the option came from */ /* - * parse_args - parse a string of arguments, from the command - * line or from a file. + * parse_args - parse a string of arguments from the command line. */ int parse_args(argc, argv) @@ -414,6 +412,8 @@ parse_args(argc, argv) struct cmd *cmdp; int ret; + privileged_option = privileged; + option_source = "command line"; while (argc > 0) { arg = *argv++; --argc; @@ -503,14 +503,16 @@ usage() * and interpret them. */ int -options_from_file(filename, must_exist, check_prot) +options_from_file(filename, must_exist, check_prot, priv) char *filename; int must_exist; int check_prot; + int priv; { FILE *f; int i, newline, ret; struct cmd *cmdp; + int oldpriv; char *argv[MAXARGS]; char args[MAXARGS][MAXWORDLEN]; char cmd[MAXWORDLEN]; @@ -527,6 +529,9 @@ options_from_file(filename, must_exist, check_prot) return 0; } + oldpriv = privileged_option; + privileged_option = priv; + ret = 0; while (getword(f, cmd, &newline, filename)) { /* * First see if it's a command. @@ -541,34 +546,35 @@ options_from_file(filename, must_exist, check_prot) option_error( "In file %s: too few parameters for option '%s'", filename, cmd); - fclose(f); - return 0; + goto err; } argv[i] = args[i]; } current_option = cmd; - if (!(*cmdp->cmd_func)(argv)) { - fclose(f); - return 0; - } + if (!(*cmdp->cmd_func)(argv)) + goto err; } else { /* * Maybe a tty name, speed or IP address? */ - if ((ret = setdevname(cmd, 0)) == 0 - && (ret = setspeed(cmd)) == 0 - && (ret = setipaddr(cmd)) == 0) { + if ((i = setdevname(cmd, 0)) == 0 + && (i = setspeed(cmd)) == 0 + && (i = setipaddr(cmd)) == 0) { option_error("In file %s: unrecognized option '%s'", filename, cmd); - fclose(f); - return 0; + goto err; } - if (ret < 0) /* error */ - return 0; + if (i < 0) /* error */ + goto err; } } - return 1; + ret = 1; + +err: + fclose(f); + privileged_option = oldpriv; + return ret; } /* @@ -592,7 +598,7 @@ options_from_user() strcpy(path, user); strcat(path, "/"); strcat(path, file); - ret = options_from_file(path, 0, 1); + ret = options_from_file(path, 0, 1, privileged); free(path); return ret; } @@ -620,7 +626,7 @@ options_for_tty() for (p = path + strlen(path); *dev != 0; ++dev) *p++ = (*dev == '/'? '.': *dev); *p = 0; - ret = options_from_file(path, 0, 0); + ret = options_from_file(path, 0, 0, 1); free(path); return ret; } @@ -967,7 +973,7 @@ int_option(str, valp) /* - * The following procedures execute commands. + * The following procedures parse options. */ /* @@ -977,10 +983,55 @@ static int readfile(argv) char **argv; { - return options_from_file(*argv, 1, 1); + return options_from_file(*argv, 1, 1, privileged_option); } /* + * callfile - take commands from /etc/ppp/peers/<name>. + * Name may not contain /../, start with / or ../, or end in /.. + */ +static int +callfile(argv) + char **argv; +{ + char *fname, *arg, *p; + int l, ok; + + arg = *argv; + ok = 1; + if (arg[0] == '/' || arg[0] == 0) + ok = 0; + else { + for (p = arg; *p != 0; ) { + if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) { + ok = 0; + break; + } + while (*p != '/' && *p != 0) + ++p; + if (*p == '/') + ++p; + } + } + if (!ok) { + option_error("call option value may not contain .. or start with /"); + return 0; + } + + l = strlen(arg) + strlen(_PATH_PEERFILES) + 1; + if ((fname = (char *) malloc(l)) == NULL) + novm("call file name"); + strcpy(fname, _PATH_PEERFILES); + strcat(fname, arg); + + ok = options_from_file(fname, 1, 1, 1); + + free(fname); + return ok; +} + + +/* * setdebug - Set debug (command line argument). */ static int @@ -1115,6 +1166,21 @@ setmtu(argv) return (1); } +#ifdef CBCP_SUPPORT +static int +setcbcp(argv) + char **argv; +{ + lcp_wantoptions[0].neg_cbcp = 1; + cbcp_protent.enabled_flag = 1; + cbcp[0].us_number = strdup(*argv); + if (cbcp[0].us_number == 0) + novm("callback number"); + cbcp[0].us_type |= (1 << CB_CONF_USER); + cbcp[0].us_type |= (1 << CB_CONF_ADMIN); + return (1); +} +#endif /* * nopcomp - Disable Protocol field compression negotiation. @@ -1170,7 +1236,7 @@ static int reqpap() { lcp_wantoptions[0].neg_upap = 1; - auth_required = 1; + setauth(); return 1; } @@ -1190,11 +1256,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); + option_error("unable to open user login data file %s", *argv); return 0; } if (!readable(fileno(ufile))) { - option_error("unable to open user login data file %s", *argv); + option_error("%s: access denied", *argv); return 0; } check_access(ufile, *argv); @@ -1202,7 +1268,7 @@ setupapfile(argv) /* get username */ if (fgets(user, MAXNAMELEN - 1, ufile) == NULL || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ - option_error("%s: access denied", *argv); + option_error("unable to read user login data file %s", *argv); return 0; } fclose(ufile); @@ -1238,7 +1304,7 @@ static int reqchap() { lcp_wantoptions[0].neg_chap = 1; - auth_required = 1; + setauth(); return (1); } @@ -1298,6 +1364,8 @@ setconnector(argv) connector = strdup(*argv); if (connector == NULL) novm("connect script"); + connector_info.priv = privileged_option; + connector_info.source = option_source; return (1); } @@ -1312,6 +1380,8 @@ setdisconnector(argv) disconnector = strdup(*argv); if (disconnector == NULL) novm("disconnect script"); + disconnector_info.priv = privileged_option; + disconnector_info.source = option_source; return (1); } @@ -1326,6 +1396,8 @@ setwelcomer(argv) welcomer = strdup(*argv); if (welcomer == NULL) novm("welcome script"); + welcomer_info.priv = privileged_option; + welcomer_info.source = option_source; return (1); } @@ -1345,6 +1417,10 @@ setmaxconnect(argv) option_error("maxconnect time must be positive"); return 0; } + if (maxconnect > 0 && (value == 0 || value > maxconnect)) { + option_error("maxconnect time cannot be increased"); + return 0; + } maxconnect = value; return 1; } @@ -1356,6 +1432,10 @@ static int setdomain(argv) char **argv; { + if (!privileged_option) { + option_error("using the domain option requires root privilege"); + return 0; + } gethostname(hostname, MAXNAMELEN); if (**argv != 0) { if (**argv != '.') @@ -1468,6 +1548,8 @@ setdevname(cp, quiet) (void) strncpy(devnam, cp, MAXPATHLEN); devnam[MAXPATHLEN-1] = 0; default_device = FALSE; + devnam_info.priv = privileged_option; + devnam_info.source = option_source; return 1; } @@ -1482,7 +1564,6 @@ setipaddr(arg) { struct hostent *hp; char *colon; - struct in_addr ina; u_int32_t local, remote; ipcp_options *wo = &ipcp_wantoptions[0]; @@ -1497,19 +1578,14 @@ setipaddr(arg) */ if (colon != arg) { *colon = '\0'; - if (inet_aton(arg, &ina) == 0) { + if ((local = inet_addr(arg)) == -1) { if ((hp = gethostbyname(arg)) == NULL) { option_error("unknown host: %s", arg); return -1; } else { local = *(u_int32_t *)hp->h_addr; - if (our_name[0] == 0) { - strncpy(our_name, arg, MAXNAMELEN); - our_name[MAXNAMELEN-1] = 0; } } - } else - local = ina.s_addr; if (bad_ip_adrs(local)) { option_error("bad local IP address %s", ip_ntoa(local)); return -1; @@ -1523,7 +1599,7 @@ setipaddr(arg) * If colon last character, then no remote addr. */ if (*++colon != '\0') { - if (inet_aton(colon, &ina) == 0) { + if ((remote = inet_addr(colon)) == -1) { if ((hp = gethostbyname(colon)) == NULL) { option_error("unknown host: %s", colon); return -1; @@ -1534,8 +1610,7 @@ setipaddr(arg) remote_name[MAXNAMELEN-1] = 0; } } - } else - remote = ina.s_addr; + } if (bad_ip_adrs(remote)) { option_error("bad remote IP address %s", ip_ntoa(remote)); return -1; @@ -1588,14 +1663,14 @@ static int setnetmask(argv) char **argv; { - struct in_addr ina; + u_int32_t mask; - if (inet_aton(*argv, &ina) == 0 || (netmask & ~ina.s_addr) != 0) { + if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) { option_error("invalid netmask value '%s'", *argv); return 0; } - netmask = ina.s_addr; + netmask = mask; return (1); } @@ -1634,6 +1709,7 @@ static int setdemand() { demand = 1; + persist = 1; return 1; } @@ -1669,10 +1745,12 @@ static int setname(argv) char **argv; { - if (our_name[0] == 0) { + if (!privileged_option) { + option_error("using the name option requires root privilege"); + return 0; + } strncpy(our_name, argv[0], MAXNAMELEN); our_name[MAXNAMELEN-1] = 0; - } return 1; } @@ -1698,6 +1776,22 @@ static int setauth() { auth_required = 1; + if (privileged_option > auth_req_info.priv) { + auth_req_info.priv = privileged_option; + auth_req_info.source = option_source; + } + return 1; +} + +static int +setnoauth() +{ + if (auth_required && privileged_option < auth_req_info.priv) { + option_error("cannot override auth option set by %s", + auth_req_info.source); + return 0; + } + auth_required = 0; return 1; } @@ -1747,6 +1841,13 @@ setpersist() } static int +setnopersist() +{ + persist = 0; + return 1; +} + +static int setdologin() { uselogin = 1; @@ -2016,26 +2117,33 @@ setholdoff(argv) return int_option(*argv, &holdoff); } +/* + * setdnsaddr - set the dns address(es) + */ static int -setpassfilter(argv) +setdnsaddr(argv) char **argv; { - if (bpf_compile(&pass_filter, *argv, 1) == 0) - return 1; - fprintf(stderr, "%s: error in pass-filter expression: %s\n", - progname, bpf_geterr()); - return 0; -} + u_int32_t dns; + struct hostent *hp; -static int -setactivefilter(argv) - char **argv; -{ - if (bpf_compile(&active_filter, *argv, 1) == 0) - return 1; - fprintf(stderr, "%s: error in active-filter expression: %s\n", - progname, bpf_geterr()); + dns = inet_addr(*argv); + if (dns == -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-dns option", + *argv); return 0; + } + dns = *(u_int32_t *)hp->h_addr; + } + + if (ipcp_allowoptions[0].dnsaddr[0] == 0) { + ipcp_allowoptions[0].dnsaddr[0] = dns; + } else { + ipcp_allowoptions[0].dnsaddr[1] = dns; + } + + return (1); } #ifdef IPX_CHANGE @@ -2199,35 +2307,11 @@ resetipxproto() ipxcp_protent.enabled_flag = 0; return 1; } -#endif /* IPX_CHANGE */ - -#ifdef USE_MS_DNS -/* - * setdnsaddr - set the dns address(es) - */ +#else static int -setdnsaddr(argv) - char **argv; +resetipxproto() { - u_int32_t dns; - struct hostent *hp; - - if (inet_aton(*argv, &dns) == 0) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-dns option", - *argv); - return 0; - } - dns = *(u_int32_t *)hp->h_addr; - } - - if (ipcp_allowoptions[0].dnsaddr[0] == 0) { - ipcp_allowoptions[0].dnsaddr[0] = dns; - } else { - ipcp_allowoptions[0].dnsaddr[1] = dns; - } - - return (1); + return 1; } -#endif /* USE_MS_DNS */ +#endif /* IPX_CHANGE */ |