xref: /openbsd/usr.sbin/pppd/options.c (revision 3a50f0a9)
1 /*	$OpenBSD: options.c,v 1.30 2022/12/28 21:30:18 jmc Exp $	*/
2 
3 /*
4  * options.c - handles option processing for PPP.
5  *
6  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. The name "Carnegie Mellon University" must not be used to
21  *    endorse or promote products derived from this software without
22  *    prior written permission. For permission or any legal
23  *    details, please contact
24  *      Office of Technology Transfer
25  *      Carnegie Mellon University
26  *      5000 Forbes Avenue
27  *      Pittsburgh, PA  15213-3890
28  *      (412) 268-4387, fax: (412) 268-7395
29  *      tech-transfer@andrew.cmu.edu
30  *
31  * 4. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by Computing Services
34  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35  *
36  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43  */
44 
45 #include <ctype.h>
46 #include <stdio.h>
47 #include <errno.h>
48 #include <unistd.h>
49 #include <limits.h>
50 #include <stdlib.h>
51 #include <termios.h>
52 #include <syslog.h>
53 #include <string.h>
54 #include <netdb.h>
55 #include <pwd.h>
56 #include <sys/types.h>
57 #include <sys/stat.h>
58 #include <netinet/in.h>
59 #include <arpa/inet.h>
60 #ifdef PPP_FILTER
61 #include <pcap.h>
62 #include <pcap-int.h>	/* XXX: To get struct pcap */
63 #endif
64 
65 #include "pppd.h"
66 #include "pathnames.h"
67 #include "patchlevel.h"
68 #include "fsm.h"
69 #include "lcp.h"
70 #include "ipcp.h"
71 #include "upap.h"
72 #include "chap.h"
73 #include "ccp.h"
74 #ifdef CBCP_SUPPORT
75 #include "cbcp.h"
76 #endif
77 
78 #include <net/ppp-comp.h>
79 
80 #define FALSE	0
81 #define TRUE	1
82 
83 #if defined(ultrix) || defined(NeXT)
84 char *strdup(char *);
85 #endif
86 
87 #ifndef GIDSET_TYPE
88 #define GIDSET_TYPE	gid_t
89 #endif
90 
91 /*
92  * Option variables and default values.
93  */
94 #ifdef PPP_FILTER
95 int	dflag = 0;		/* Tell libpcap we want debugging */
96 #endif
97 int	debug = 0;		/* Debug flag */
98 int	kdebugflag = 0;		/* Tell kernel to print debug messages */
99 int	default_device = 1;	/* Using /dev/tty or equivalent */
100 char	devnam[PATH_MAX] = "/dev/tty";	/* Device name */
101 int	crtscts = 0;		/* Use hardware flow control */
102 int	modem = 1;		/* Use modem control lines */
103 int	modem_chat = 0;		/* Use modem control lines during chat */
104 int	inspeed = 0;		/* Input/Output speed requested */
105 u_int32_t netmask = 0;		/* IP netmask to set on interface */
106 int	lockflag = 0;		/* Create lock file to lock the serial dev */
107 int	nodetach = 0;		/* Don't detach from controlling tty */
108 char	*connector = NULL;	/* Script to establish physical link */
109 char	*disconnector = NULL;	/* Script to disestablish physical link */
110 char	*welcomer = NULL;	/* Script to run after phys link estab. */
111 int	maxconnect = 0;		/* Maximum connect time */
112 char	user[MAXNAMELEN];	/* Username for PAP */
113 char	passwd[MAXSECRETLEN];	/* Password for PAP */
114 int	auth_required = 0;	/* Peer is required to authenticate */
115 int	persist = 0;		/* Reopen link after it goes down */
116 int	uselogin = 0;		/* Use /etc/passwd for checking PAP */
117 int	lcp_echo_interval = 0; 	/* Interval between LCP echo-requests */
118 int	lcp_echo_fails = 0;	/* Tolerance to unanswered echo-requests */
119 char	our_name[MAXNAMELEN];	/* Our name for authentication purposes */
120 char	remote_name[MAXNAMELEN]; /* Peer's name for authentication */
121 int	explicit_remote = 0;	/* User specified explicit remote name */
122 int	usehostname = 0;	/* Use hostname for our_name */
123 int	disable_defaultip = 0;	/* Don't use hostname for default IP adrs */
124 int	demand = 0;		/* do dial-on-demand */
125 char	*ipparam = NULL;	/* Extra parameter for ip up/down scripts */
126 int	cryptpap;		/* Passwords in pap-secrets are encrypted */
127 int	idle_time_limit = 0;	/* Disconnect if idle for this many seconds */
128 int	holdoff = 30;		/* # seconds to pause before reconnecting */
129 int	refuse_pap = 0;		/* Set to say we won't do PAP */
130 int	refuse_chap = 0;	/* Set to say we won't do CHAP */
131 
132 #ifdef MSLANMAN
133 int	ms_lanman = 0;    	/* Nonzero if use LanMan password instead of NT */
134 			  	/* Has meaning only with MS-CHAP challenges */
135 #endif
136 
137 struct option_info auth_req_info;
138 struct option_info connector_info;
139 struct option_info disconnector_info;
140 struct option_info welcomer_info;
141 struct option_info devnam_info;
142 #ifdef PPP_FILTER
143 struct	bpf_program pass_filter;/* Filter program for packets to pass */
144 struct	bpf_program active_filter; /* Filter program for link-active pkts */
145 pcap_t  pc;			/* Fake struct pcap so we can compile expr */
146 #endif
147 
148 /*
149  * Prototypes
150  */
151 static int setdevname(char *, int);
152 static int setipaddr(char *);
153 static int setspeed(char *);
154 static int setdebug(char **);
155 static int setkdebug(char **);
156 static int setpassive(char **);
157 static int setsilent(char **);
158 static int noopt(char **);
159 static int setnovj(char **);
160 static int setnovjccomp(char **);
161 static int setvjslots(char **);
162 static int reqpap(char **);
163 static int nopap(char **);
164 static int nochap(char **);
165 static int reqchap(char **);
166 static int noaccomp(char **);
167 static int noasyncmap(char **);
168 static int noip(char **);
169 static int nomagicnumber(char **);
170 static int setasyncmap(char **);
171 static int setescape(char **);
172 static int setmru(char **);
173 static int setmtu(char **);
174 #ifdef CBCP_SUPPORT
175 static int setcbcp(char **);
176 #endif
177 static int nomru(char **);
178 static int nopcomp(char **);
179 static int setconnector(char **);
180 static int setdisconnector(char **);
181 static int setwelcomer(char **);
182 static int setmaxconnect(char **);
183 static int setdomain(char **);
184 static int setnetmask(char **);
185 static int setcrtscts(char **);
186 static int setnocrtscts(char **);
187 static int setxonxoff(char **);
188 static int setnodetach(char **);
189 static int setupdetach(char **);
190 static int setmodem(char **);
191 static int setmodem_chat(char **);
192 static int setlocal(char **);
193 static int setlock(char **);
194 static int setname(char **);
195 static int setuser(char **);
196 static int setremote(char **);
197 static int setauth(char **);
198 static int setnoauth(char **);
199 static int readfile(char **);
200 static int callfile(char **);
201 static int setdefaultroute(char **);
202 static int setnodefaultroute(char **);
203 static int setproxyarp(char **);
204 static int setnoproxyarp(char **);
205 static int setpersist(char **);
206 static int setnopersist(char **);
207 static int setdologin(char **);
208 static int setusehostname(char **);
209 static int setnoipdflt(char **);
210 static int setlcptimeout(char **);
211 static int setlcpterm(char **);
212 static int setlcpconf(char **);
213 static int setlcpfails(char **);
214 static int setipcptimeout(char **);
215 static int setipcpterm(char **);
216 static int setipcpconf(char **);
217 static int setipcpfails(char **);
218 static int setpaptimeout(char **);
219 static int setpapreqs(char **);
220 static int setpapreqtime(char **);
221 static int setchaptimeout(char **);
222 static int setchapchal(char **);
223 static int setchapintv(char **);
224 static int setipcpaccl(char **);
225 static int setipcpaccr(char **);
226 static int setlcpechointv(char **);
227 static int setlcpechofails(char **);
228 static int noccp(char **);
229 static int setbsdcomp(char **);
230 static int setnobsdcomp(char **);
231 static int setdeflate(char **);
232 static int setnodeflate(char **);
233 static int setnodeflatedraft(char **);
234 static int setdemand(char **);
235 static int setpred1comp(char **);
236 static int setnopred1comp(char **);
237 static int setipparam(char **);
238 static int setpapcrypt(char **);
239 static int setidle(char **);
240 static int setholdoff(char **);
241 static int setdnsaddr(char **);
242 static int setwinsaddr(char **);
243 static int showversion(char **);
244 static int showhelp(char **);
245 
246 #ifdef PPP_FILTER
247 static int setpdebug(char **);
248 static int setpassfilter(char **);
249 static int setactivefilter(char **);
250 #endif
251 
252 #ifdef MSLANMAN
253 static int setmslanman(char **);
254 #endif
255 
256 static int number_option(char *, u_int32_t *, int);
257 static int int_option(char *, int *);
258 static int readable(int fd);
259 
260 /*
261  * Valid arguments.
262  */
263 static struct cmd {
264     char *cmd_name;
265     int num_args;
266     int (*cmd_func)(char **);
267 } cmds[] = {
268     {"-all", 0, noopt},		/* Don't request/allow any options (useless) */
269     {"noaccomp", 0, noaccomp},	/* Disable Address/Control compression */
270     {"-ac", 0, noaccomp},	/* Disable Address/Control compress */
271     {"default-asyncmap", 0, noasyncmap}, /* Disable asyncmap negotiation */
272     {"-am", 0, noasyncmap},	/* Disable asyncmap negotiation */
273     {"-as", 1, setasyncmap},	/* set the desired async map */
274     {"-d", 0, setdebug},	/* Increase debugging level */
275     {"nodetach", 0, setnodetach}, /* Don't detach from controlling tty */
276     {"-detach", 0, setnodetach}, /* don't fork */
277     {"updetach", 0, setupdetach}, /* Detach once an NP has come up */
278     {"noip", 0, noip},		/* Disable IP and IPCP */
279     {"-ip", 0, noip},		/* Disable IP and IPCP */
280     {"nomagic", 0, nomagicnumber}, /* Disable magic number negotiation */
281     {"-mn", 0, nomagicnumber},	/* Disable magic number negotiation */
282     {"default-mru", 0, nomru},	/* Disable MRU negotiation */
283     {"-mru", 0, nomru},		/* Disable mru negotiation */
284     {"-p", 0, setpassive},	/* Set passive mode */
285     {"nopcomp", 0, nopcomp},	/* Disable protocol field compression */
286     {"-pc", 0, nopcomp},	/* Disable protocol field compress */
287     {"require-pap", 0, reqpap},	/* Require PAP authentication from peer */
288     {"+pap", 0, reqpap},	/* Require PAP auth from peer */
289     {"refuse-pap", 0, nopap},	/* Don't agree to auth to peer with PAP */
290     {"-pap", 0, nopap},		/* Don't allow UPAP authentication with peer */
291     {"require-chap", 0, reqchap}, /* Require CHAP authentication from peer */
292     {"+chap", 0, reqchap},	/* Require CHAP authentication from peer */
293     {"refuse-chap", 0, nochap},	/* Don't agree to auth to peer with CHAP */
294     {"-chap", 0, nochap},	/* Don't allow CHAP authentication with peer */
295     {"novj", 0, setnovj},	/* Disable VJ compression */
296     {"-vj", 0, setnovj},	/* disable VJ compression */
297     {"novjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
298     {"-vjccomp", 0, setnovjccomp}, /* disable VJ connection-ID compression */
299     {"vj-max-slots", 1, setvjslots}, /* Set maximum VJ header slots */
300     {"asyncmap", 1, setasyncmap}, /* set the desired async map */
301     {"escape", 1, setescape},	/* set chars to escape on transmission */
302     {"connect", 1, setconnector}, /* A program to set up a connection */
303     {"disconnect", 1, setdisconnector},	/* program to disconnect serial dev. */
304     {"welcome", 1, setwelcomer},/* Script to welcome client */
305     {"maxconnect", 1, setmaxconnect},  /* specify a maximum connect time */
306     {"crtscts", 0, setcrtscts},	/* set h/w flow control */
307     {"nocrtscts", 0, setnocrtscts}, /* clear h/w flow control */
308     {"-crtscts", 0, setnocrtscts}, /* clear h/w flow control */
309     {"xonxoff", 0, setxonxoff},	/* set s/w flow control */
310     {"debug", 0, setdebug},	/* Increase debugging level */
311     {"kdebug", 1, setkdebug},	/* Enable kernel-level debugging */
312     {"domain", 1, setdomain},	/* Add given domain name to hostname*/
313     {"mru", 1, setmru},		/* Set MRU value for negotiation */
314     {"mtu", 1, setmtu},		/* Set our MTU */
315 #ifdef CBCP_SUPPORT
316     {"callback", 1, setcbcp},	/* Ask for callback */
317 #endif
318     {"netmask", 1, setnetmask},	/* set netmask */
319     {"passive", 0, setpassive},	/* Set passive mode */
320     {"silent", 0, setsilent},	/* Set silent mode */
321     {"modem", 0, setmodem},	/* Use modem control lines */
322     {"modem_chat", 0, setmodem_chat}, /* Use modem control lines during chat */
323     {"local", 0, setlocal},	/* Don't use modem control lines */
324     {"lock", 0, setlock},	/* Lock serial device (with lock file) */
325     {"name", 1, setname},	/* Set local name for authentication */
326     {"user", 1, setuser},	/* Set name for auth with peer */
327     {"usehostname", 0, setusehostname},	/* Must use hostname for auth. */
328     {"remotename", 1, setremote}, /* Set remote name for authentication */
329     {"auth", 0, setauth},	/* Require authentication from peer */
330     {"noauth", 0, setnoauth},	/* Don't require peer to authenticate */
331     {"file", 1, readfile},	/* Take options from a file */
332     {"call", 1, callfile},	/* Take options from a privileged file */
333     {"defaultroute", 0, setdefaultroute}, /* Add default route */
334     {"nodefaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
335     {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */
336     {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */
337     {"noproxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
338     {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */
339     {"persist", 0, setpersist},	/* Keep on reopening connection after close */
340     {"nopersist", 0, setnopersist},  /* Turn off persist option */
341     {"demand", 0, setdemand},	/* Dial on demand */
342     {"login", 0, setdologin},	/* Use system password database for UPAP */
343     {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */
344     {"lcp-echo-failure", 1, setlcpechofails}, /* consecutive echo failures */
345     {"lcp-echo-interval", 1, setlcpechointv}, /* time for lcp echo events */
346     {"lcp-restart", 1, setlcptimeout}, /* Set timeout for LCP */
347     {"lcp-max-terminate", 1, setlcpterm}, /* Set max #xmits for term-reqs */
348     {"lcp-max-configure", 1, setlcpconf}, /* Set max #xmits for conf-reqs */
349     {"lcp-max-failure", 1, setlcpfails}, /* Set max #conf-naks for LCP */
350     {"ipcp-restart", 1, setipcptimeout}, /* Set timeout for IPCP */
351     {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */
352     {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */
353     {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */
354     {"pap-restart", 1, setpaptimeout},	/* Set retransmit timeout for PAP */
355     {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */
356     {"pap-timeout", 1, setpapreqtime},	/* Set time limit for peer PAP auth. */
357     {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */
358     {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */
359     {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */
360     {"ipcp-accept-local", 0, setipcpaccl}, /* Accept peer's address for us */
361     {"ipcp-accept-remote", 0, setipcpaccr}, /* Accept peer's address for it */
362     {"noccp", 0, noccp},		/* Disable CCP negotiation */
363     {"-ccp", 0, noccp},			/* Disable CCP negotiation */
364     {"bsdcomp", 1, setbsdcomp},		/* request BSD-Compress */
365     {"nobsdcomp", 0, setnobsdcomp},	/* don't allow BSD-Compress */
366     {"-bsdcomp", 0, setnobsdcomp},	/* don't allow BSD-Compress */
367     {"deflate", 1, setdeflate},		/* request Deflate compression */
368     {"nodeflate", 0, setnodeflate},	/* don't allow Deflate compression */
369     {"-deflate", 0, setnodeflate},	/* don't allow Deflate compression */
370     {"nodeflatedraft", 0, setnodeflatedraft}, /* don't use draft deflate # */
371     {"predictor1", 0, setpred1comp},	/* request Predictor-1 */
372     {"nopredictor1", 0, setnopred1comp},/* don't allow Predictor-1 */
373     {"-predictor1", 0, setnopred1comp},	/* don't allow Predictor-1 */
374     {"ipparam", 1, setipparam},		/* set ip script parameter */
375     {"papcrypt", 0, setpapcrypt},	/* PAP passwords encrypted */
376     {"idle", 1, setidle},		/* idle time limit (seconds) */
377     {"holdoff", 1, setholdoff},		/* set holdoff time (seconds) */
378     {"ms-dns", 1, setdnsaddr},		/* DNS address for the peer's use */
379     {"ms-wins", 1, setwinsaddr},	/* Nameserver for SMB over TCP/IP for peer */
380     {"--version", 0, showversion},	/* Show version number */
381     {"--help", 0, showhelp},		/* Show brief listing of options */
382     {"-h", 0, showhelp},		/* ditto */
383 
384 #ifdef PPP_FILTER
385     {"pdebug", 1, setpdebug},		/* libpcap debugging */
386     {"pass-filter", 1, setpassfilter},	/* set filter for packets to pass */
387     {"active-filter", 1, setactivefilter}, /* set filter for active pkts */
388 #endif
389 
390 #ifdef MSLANMAN
391     {"ms-lanman", 0, setmslanman},	/* Use LanMan psswd when using MS-CHAP */
392 #endif
393 
394     {NULL, 0, NULL}
395 };
396 
397 
398 #ifndef IMPLEMENTATION
399 #define IMPLEMENTATION ""
400 #endif
401 
402 static const char usage_string[] = "\
403 pppd version %s patch level %d%s\n\
404 Usage: %s [ options ], where options are:\n\
405 	<device>	Communicate over the named device\n\
406 	<speed>		Set the baud rate to <speed>\n\
407 	<loc>:<rem>	Set the local and/or remote interface IP\n\
408 			addresses.  Either one may be omitted.\n\
409 	asyncmap <n>	Set the desired async map to hex <n>\n\
410 	auth		Require authentication from peer\n\
411         connect <p>     Invoke shell command <p> to set up the serial line\n\
412 	crtscts		Use hardware RTS/CTS flow control\n\
413 	defaultroute	Add default route through interface\n\
414 	file <f>	Take options from file <f>\n\
415 	modem		Use modem control lines\n\
416 	modem_chat	Use modem control lines during chat\n\
417 	mru <n>		Set MRU value to <n> for negotiation\n\
418 	netmask <n>	Set interface netmask to <n>\n\
419 See pppd(8) for more options.\n\
420 ";
421 
422 static char *current_option;	/* the name of the option being parsed */
423 static int privileged_option;	/* set iff the current option came from root */
424 static char *option_source;	/* string saying where the option came from */
425 
426 /*
427  * parse_args - parse a string of arguments from the command line.
428  */
429 int
parse_args(argc,argv)430 parse_args(argc, argv)
431     int argc;
432     char **argv;
433 {
434     char *arg;
435     struct cmd *cmdp;
436     int ret;
437 
438     privileged_option = privileged;
439     option_source = "command line";
440     while (argc > 0) {
441 	arg = *argv++;
442 	--argc;
443 
444 	/*
445 	 * First see if it's a command.
446 	 */
447 	for (cmdp = cmds; cmdp->cmd_name; cmdp++)
448 	    if (!strcmp(arg, cmdp->cmd_name))
449 		break;
450 
451 	if (cmdp->cmd_name != NULL) {
452 	    if (argc < cmdp->num_args) {
453 		option_error("too few parameters for option %s", arg);
454 		return 0;
455 	    }
456 	    current_option = arg;
457 	    if (!(*cmdp->cmd_func)(argv))
458 		return 0;
459 	    argc -= cmdp->num_args;
460 	    argv += cmdp->num_args;
461 
462 	} else {
463 	    /*
464 	     * Maybe a tty name, speed or IP address?
465 	     */
466 	    if ((ret = setdevname(arg, 0)) == 0
467 		&& (ret = setspeed(arg)) == 0
468 		&& (ret = setipaddr(arg)) == 0) {
469 		option_error("unrecognized option '%s'", arg);
470 		usage();
471 		return 0;
472 	    }
473 	    if (ret < 0)	/* error */
474 		return 0;
475 	}
476     }
477     return 1;
478 }
479 
480 /*
481  * scan_args - scan the command line arguments to get the tty name,
482  * if specified.
483  */
484 void
scan_args(argc,argv)485 scan_args(argc, argv)
486     int argc;
487     char **argv;
488 {
489     char *arg;
490     struct cmd *cmdp;
491 
492     while (argc > 0) {
493 	arg = *argv++;
494 	--argc;
495 
496 	/* Skip options and their arguments */
497 	for (cmdp = cmds; cmdp->cmd_name; cmdp++)
498 	    if (!strcmp(arg, cmdp->cmd_name))
499 		break;
500 
501 	if (cmdp->cmd_name != NULL) {
502 	    argc -= cmdp->num_args;
503 	    argv += cmdp->num_args;
504 	    continue;
505 	}
506 
507 	/* Check if it's a tty name and copy it if so */
508 	(void) setdevname(arg, 1);
509     }
510 }
511 
512 /*
513  * usage - print out a message telling how to use the program.
514  */
515 void
usage()516 usage()
517 {
518     if (phase == PHASE_INITIALIZE)
519 	fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION,
520 		__progname);
521 }
522 
523 /*
524  * showhelp - print out usage message and exit.
525  */
526 static int
showhelp(argv)527 showhelp(argv)
528     char **argv;
529 {
530     if (phase == PHASE_INITIALIZE) {
531 	usage();
532 	exit(0);
533     }
534     return 0;
535 }
536 
537 /*
538  * showversion - print out the version number and exit.
539  */
540 static int
showversion(argv)541 showversion(argv)
542     char **argv;
543 {
544     if (phase == PHASE_INITIALIZE) {
545 	fprintf(stderr, "pppd version %s patch level %d%s\n",
546 		VERSION, PATCHLEVEL, IMPLEMENTATION);
547 	exit(0);
548     }
549     return 0;
550 }
551 
552 /*
553  * options_from_file - Read a string of options from a file,
554  * and interpret them.
555  */
556 int
options_from_file(filename,must_exist,check_prot,priv)557 options_from_file(filename, must_exist, check_prot, priv)
558     char *filename;
559     int must_exist;
560     int check_prot;
561     int priv;
562 {
563     FILE *f;
564     int i, newline, ret;
565     struct cmd *cmdp;
566     int oldpriv;
567     char *argv[MAXARGS];
568     char args[MAXARGS][MAXWORDLEN];
569     char cmd[MAXWORDLEN];
570 
571     if ((f = fopen(filename, "r")) == NULL) {
572 	if (!must_exist && errno == ENOENT)
573 	    return 1;
574 	option_error("Can't open options file %s: %m", filename);
575 	return 0;
576     }
577     if (check_prot && !readable(fileno(f))) {
578 	option_error("Can't open options file %s: access denied", filename);
579 	fclose(f);
580 	return 0;
581     }
582 
583     oldpriv = privileged_option;
584     privileged_option = priv;
585     ret = 0;
586     while (getword(f, cmd, &newline, filename)) {
587 	/*
588 	 * First see if it's a command.
589 	 */
590 	for (cmdp = cmds; cmdp->cmd_name; cmdp++)
591 	    if (!strcmp(cmd, cmdp->cmd_name))
592 		break;
593 
594 	if (cmdp->cmd_name != NULL) {
595 	    for (i = 0; i < cmdp->num_args; ++i) {
596 		if (!getword(f, args[i], &newline, filename)) {
597 		    option_error(
598 			"In file %s: too few parameters for option '%s'",
599 			filename, cmd);
600 		    goto err;
601 		}
602 		argv[i] = args[i];
603 	    }
604 	    current_option = cmd;
605 	    if (!(*cmdp->cmd_func)(argv))
606 		goto err;
607 
608 	} else {
609 	    /*
610 	     * Maybe a tty name, speed or IP address?
611 	     */
612 	    if ((i = setdevname(cmd, 0)) == 0
613 		&& (i = setspeed(cmd)) == 0
614 		&& (i = setipaddr(cmd)) == 0) {
615 		option_error("In file %s: unrecognized option '%s'",
616 			     filename, cmd);
617 		goto err;
618 	    }
619 	    if (i < 0)		/* error */
620 		goto err;
621 	}
622     }
623     ret = 1;
624 
625 err:
626     fclose(f);
627     privileged_option = oldpriv;
628     return ret;
629 }
630 
631 /*
632  * options_from_user - See if the use has a ~/.ppprc file,
633  * and if so, interpret options from it.
634  */
635 int
options_from_user()636 options_from_user()
637 {
638     char *user, *path, *file;
639     int ret;
640     struct passwd *pw;
641 
642     pw = getpwuid(getuid());
643     if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0)
644 	return 1;
645     file = _PATH_USEROPT;
646     if (asprintf(&path, "%s/%s", user, file) == -1)
647 	novm("init file name");
648     ret = options_from_file(path, 0, 1, privileged);
649     free(path);
650     return ret;
651 }
652 
653 /*
654  * options_for_tty - See if an options file exists for the serial
655  * device, and if so, interpret options from it.
656  */
657 int
options_for_tty()658 options_for_tty()
659 {
660     char *dev, *path;
661     int ret;
662 
663     dev = devnam;
664     if (strncmp(dev, "/dev/", 5) == 0)
665 	dev += 5;
666     if (strcmp(dev, "tty") == 0)
667 	return 1;		/* don't look for /etc/ppp/options.tty */
668     if (asprintf(&path, "%s%s", _PATH_TTYOPT, dev) == -1)
669 	novm("tty init file name");
670     ret = options_from_file(path, 0, 0, 1);
671     free(path);
672     return ret;
673 }
674 
675 /*
676  * option_error - print a message about an error in an option.
677  * The message is logged, and also sent to
678  * stderr if phase == PHASE_INITIALIZE.
679  */
680 void
option_error(char * fmt,...)681 option_error(char *fmt, ...)
682 {
683     va_list args;
684     char buf[256];
685 
686     va_start(args, fmt);
687     vfmtmsg(buf, sizeof(buf), fmt, args);
688     va_end(args);
689     if (phase == PHASE_INITIALIZE)
690 	fprintf(stderr, "%s: %s\n", __progname, buf);
691     syslog(LOG_ERR, "%s", buf);
692 }
693 
694 /*
695  * readable - check if a file is readable by the real user.
696  */
697 static int
readable(fd)698 readable(fd)
699     int fd;
700 {
701     uid_t uid;
702     int ngroups, i;
703     struct stat sbuf;
704     GIDSET_TYPE groups[NGROUPS_MAX];
705 
706     uid = getuid();
707     if (uid == 0)
708 	return 1;
709     if (fstat(fd, &sbuf) != 0)
710 	return 0;
711     if (sbuf.st_uid == uid)
712 	return sbuf.st_mode & S_IRUSR;
713     if (sbuf.st_gid == getgid())
714 	return sbuf.st_mode & S_IRGRP;
715     ngroups = getgroups(NGROUPS_MAX, groups);
716     for (i = 0; i < ngroups; ++i)
717 	if (sbuf.st_gid == groups[i])
718 	    return sbuf.st_mode & S_IRGRP;
719     return sbuf.st_mode & S_IROTH;
720 }
721 
722 /*
723  * Read a word from a file.
724  * Words are delimited by white-space or by quotes (" or ').
725  * Quotes, white-space and \ may be escaped with \.
726  * \<newline> is ignored.
727  */
728 int
getword(f,word,newlinep,filename)729 getword(f, word, newlinep, filename)
730     FILE *f;
731     char *word;
732     int *newlinep;
733     char *filename;
734 {
735     int c, len, escape;
736     int quoted, comment;
737     int value, digit, got, n;
738 
739 #define isoctal(c) ((c) >= '0' && (c) < '8')
740 
741     *newlinep = 0;
742     len = 0;
743     escape = 0;
744     comment = 0;
745 
746     /*
747      * First skip white-space and comments.
748      */
749     for (;;) {
750 	c = getc(f);
751 	if (c == EOF)
752 	    break;
753 
754 	/*
755 	 * A newline means the end of a comment; backslash-newline
756 	 * is ignored.  Note that we cannot have escape && comment.
757 	 */
758 	if (c == '\n') {
759 	    if (!escape) {
760 		*newlinep = 1;
761 		comment = 0;
762 	    } else
763 		escape = 0;
764 	    continue;
765 	}
766 
767 	/*
768 	 * Ignore characters other than newline in a comment.
769 	 */
770 	if (comment)
771 	    continue;
772 
773 	/*
774 	 * If this character is escaped, we have a word start.
775 	 */
776 	if (escape)
777 	    break;
778 
779 	/*
780 	 * If this is the escape character, look at the next character.
781 	 */
782 	if (c == '\\') {
783 	    escape = 1;
784 	    continue;
785 	}
786 
787 	/*
788 	 * If this is the start of a comment, ignore the rest of the line.
789 	 */
790 	if (c == '#') {
791 	    comment = 1;
792 	    continue;
793 	}
794 
795 	/*
796 	 * A non-whitespace character is the start of a word.
797 	 */
798 	if (!isspace(c))
799 	    break;
800     }
801 
802     /*
803      * Save the delimiter for quoted strings.
804      */
805     if (!escape && (c == '"' || c == '\'')) {
806         quoted = c;
807 	c = getc(f);
808     } else
809         quoted = 0;
810 
811     /*
812      * Process characters until the end of the word.
813      */
814     while (c != EOF) {
815 	if (escape) {
816 	    /*
817 	     * This character is escaped: backslash-newline is ignored,
818 	     * various other characters indicate particular values
819 	     * as for C backslash-escapes.
820 	     */
821 	    escape = 0;
822 	    if (c == '\n') {
823 	        c = getc(f);
824 		continue;
825 	    }
826 
827 	    got = 0;
828 	    switch (c) {
829 	    case 'a':
830 		value = '\a';
831 		break;
832 	    case 'b':
833 		value = '\b';
834 		break;
835 	    case 'f':
836 		value = '\f';
837 		break;
838 	    case 'n':
839 		value = '\n';
840 		break;
841 	    case 'r':
842 		value = '\r';
843 		break;
844 	    case 's':
845 		value = ' ';
846 		break;
847 	    case 't':
848 		value = '\t';
849 		break;
850 
851 	    default:
852 		if (isoctal(c)) {
853 		    /*
854 		     * \ddd octal sequence
855 		     */
856 		    value = 0;
857 		    for (n = 0; n < 3 && isoctal(c); ++n) {
858 			value = (value << 3) + (c & 07);
859 			c = getc(f);
860 		    }
861 		    got = 1;
862 		    break;
863 		}
864 
865 		if (c == 'x') {
866 		    /*
867 		     * \x<hex_string> sequence
868 		     */
869 		    value = 0;
870 		    c = getc(f);
871 		    for (n = 0; n < 2 && isxdigit(c); ++n) {
872 			digit = toupper(c) - '0';
873 			if (digit > 10)
874 			    digit += '0' + 10 - 'A';
875 			value = (value << 4) + digit;
876 			c = getc (f);
877 		    }
878 		    got = 1;
879 		    break;
880 		}
881 
882 		/*
883 		 * Otherwise the character stands for itself.
884 		 */
885 		value = c;
886 		break;
887 	    }
888 
889 	    /*
890 	     * Store the resulting character for the escape sequence.
891 	     */
892 	    if (len < MAXWORDLEN) {
893 		word[len] = value;
894 		++len;
895 	    }
896 
897 	    if (!got)
898 		c = getc(f);
899 	    continue;
900 
901 	}
902 
903 	/*
904 	 * Not escaped: see if we've reached the end of the word.
905 	 */
906 	if (quoted) {
907 	    if (c == quoted)
908 		break;
909 	} else {
910 	    if (isspace(c) || c == '#') {
911 		ungetc (c, f);
912 		break;
913 	    }
914 	}
915 
916 	/*
917 	 * Backslash starts an escape sequence.
918 	 */
919 	if (c == '\\') {
920 	    escape = 1;
921 	    c = getc(f);
922 	    continue;
923 	}
924 
925 	/*
926 	 * An ordinary character: store it in the word and get another.
927 	 */
928 	if (len < MAXWORDLEN) {
929 	    word[len] = c;
930 	    ++len;
931 	}
932 
933 	c = getc(f);
934     }
935 
936     /*
937      * End of the word: check for errors.
938      */
939     if (c == EOF) {
940 	if (ferror(f)) {
941 	    if (errno == 0)
942 		errno = EIO;
943 	    option_error("Error reading %s: %m", filename);
944 	    die(1);
945 	}
946 	/*
947 	 * If len is zero, then we didn't find a word before the
948 	 * end of the file.
949 	 */
950 	if (len == 0)
951 	    return 0;
952     }
953 
954     /*
955      * Warn if the word was too long, and append a terminating null.
956      */
957     if (len >= MAXWORDLEN) {
958 	option_error("warning: word in file %s too long (%.20s...)",
959 		     filename, word);
960 	len = MAXWORDLEN - 1;
961     }
962     word[len] = 0;
963 
964     return 1;
965 
966 #undef isoctal
967 
968 }
969 
970 /*
971  * number_option - parse an unsigned numeric parameter for an option.
972  */
973 static int
number_option(str,valp,base)974 number_option(str, valp, base)
975     char *str;
976     u_int32_t *valp;
977     int base;
978 {
979     char *ptr;
980 
981     *valp = strtoul(str, &ptr, base);
982     if (ptr == str) {
983 	option_error("invalid numeric parameter '%s' for %s option",
984 		     str, current_option);
985 	return 0;
986     }
987     return 1;
988 }
989 
990 
991 /*
992  * int_option - like number_option, but valp is int *,
993  * the base is assumed to be 0, and *valp is not changed
994  * if there is an error.
995  */
996 static int
int_option(str,valp)997 int_option(str, valp)
998     char *str;
999     int *valp;
1000 {
1001     u_int32_t v;
1002 
1003     if (!number_option(str, &v, 0))
1004 	return 0;
1005     *valp = (int) v;
1006     return 1;
1007 }
1008 
1009 
1010 /*
1011  * The following procedures parse options.
1012  */
1013 
1014 /*
1015  * readfile - take commands from a file.
1016  */
1017 static int
readfile(argv)1018 readfile(argv)
1019     char **argv;
1020 {
1021     return options_from_file(*argv, 1, 1, privileged_option);
1022 }
1023 
1024 /*
1025  * callfile - take commands from /etc/ppp/peers/<name>.
1026  * Name may not contain /../, start with / or ../, or end in /..
1027  */
1028 static int
callfile(argv)1029 callfile(argv)
1030     char **argv;
1031 {
1032     char *fname, *arg, *p;
1033     int l, ok;
1034 
1035     arg = *argv;
1036     ok = 1;
1037     if (arg[0] == '/' || arg[0] == 0)
1038 	ok = 0;
1039     else {
1040 	for (p = arg; *p != 0; ) {
1041 	    if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) {
1042 		ok = 0;
1043 		break;
1044 	    }
1045 	    while (*p != '/' && *p != 0)
1046 		++p;
1047 	    if (*p == '/')
1048 		++p;
1049 	}
1050     }
1051     if (!ok) {
1052 	option_error("call option value may not contain .. or start with /");
1053 	return 0;
1054     }
1055 
1056     l = strlen(arg) + strlen(_PATH_PEERFILES) + 1;
1057     if ((fname = (char *) malloc(l)) == NULL)
1058 	novm("call file name");
1059     strlcpy(fname, _PATH_PEERFILES, l);
1060     strlcat(fname, arg, l);
1061 
1062     ok = options_from_file(fname, 1, 1, 1);
1063 
1064     free(fname);
1065     return ok;
1066 }
1067 
1068 
1069 /*
1070  * setdebug - Set debug (command line argument).
1071  */
1072 static int
setdebug(argv)1073 setdebug(argv)
1074     char **argv;
1075 {
1076     debug++;
1077     return (1);
1078 }
1079 
1080 /*
1081  * setkdebug - Set kernel debugging level.
1082  */
1083 static int
setkdebug(argv)1084 setkdebug(argv)
1085     char **argv;
1086 {
1087     return int_option(*argv, &kdebugflag);
1088 }
1089 
1090 #ifdef PPP_FILTER
1091 /*
1092  * setpdebug - Set libpcap debugging level.
1093  */
1094 static int
setpdebug(argv)1095 setpdebug(argv)
1096     char **argv;
1097 {
1098     return int_option(*argv, &dflag);
1099 }
1100 
1101 /*
1102  * setpassfilter - Set the pass filter for packets
1103  */
1104 static int
setpassfilter(argv)1105 setpassfilter(argv)
1106     char **argv;
1107 {
1108     pc.linktype = DLT_PPP;
1109     pc.snapshot = PPP_HDRLEN;
1110 
1111     if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0)
1112 	return 1;
1113     option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc));
1114     return 0;
1115 }
1116 
1117 /*
1118  * setactivefilter - Set the active filter for packets
1119  */
1120 static int
setactivefilter(argv)1121 setactivefilter(argv)
1122     char **argv;
1123 {
1124     pc.linktype = DLT_PPP;
1125     pc.snapshot = PPP_HDRLEN;
1126 
1127     if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0)
1128 	return 1;
1129     option_error("error in active-filter expression: %s\n", pcap_geterr(&pc));
1130     return 0;
1131 }
1132 #endif
1133 
1134 /*
1135  * noopt - Disable all options.
1136  */
1137 static int
noopt(argv)1138 noopt(argv)
1139     char **argv;
1140 {
1141     BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
1142     BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
1143     BZERO((char *) &ipcp_wantoptions[0], sizeof (struct ipcp_options));
1144     BZERO((char *) &ipcp_allowoptions[0], sizeof (struct ipcp_options));
1145 
1146     return (1);
1147 }
1148 
1149 /*
1150  * noaccomp - Disable Address/Control field compression negotiation.
1151  */
1152 static int
noaccomp(argv)1153 noaccomp(argv)
1154     char **argv;
1155 {
1156     lcp_wantoptions[0].neg_accompression = 0;
1157     lcp_allowoptions[0].neg_accompression = 0;
1158     return (1);
1159 }
1160 
1161 
1162 /*
1163  * noasyncmap - Disable async map negotiation.
1164  */
1165 static int
noasyncmap(argv)1166 noasyncmap(argv)
1167     char **argv;
1168 {
1169     lcp_wantoptions[0].neg_asyncmap = 0;
1170     lcp_allowoptions[0].neg_asyncmap = 0;
1171     return (1);
1172 }
1173 
1174 
1175 /*
1176  * noip - Disable IP and IPCP.
1177  */
1178 static int
noip(argv)1179 noip(argv)
1180     char **argv;
1181 {
1182     ipcp_protent.enabled_flag = 0;
1183     return (1);
1184 }
1185 
1186 
1187 /*
1188  * nomagicnumber - Disable magic number negotiation.
1189  */
1190 static int
nomagicnumber(argv)1191 nomagicnumber(argv)
1192     char **argv;
1193 {
1194     lcp_wantoptions[0].neg_magicnumber = 0;
1195     lcp_allowoptions[0].neg_magicnumber = 0;
1196     return (1);
1197 }
1198 
1199 
1200 /*
1201  * nomru - Disable mru negotiation.
1202  */
1203 static int
nomru(argv)1204 nomru(argv)
1205     char **argv;
1206 {
1207     lcp_wantoptions[0].neg_mru = 0;
1208     lcp_allowoptions[0].neg_mru = 0;
1209     return (1);
1210 }
1211 
1212 
1213 /*
1214  * setmru - Set MRU for negotiation.
1215  */
1216 static int
setmru(argv)1217 setmru(argv)
1218     char **argv;
1219 {
1220     u_int32_t mru;
1221 
1222     if (!number_option(*argv, &mru, 0))
1223 	return 0;
1224     lcp_wantoptions[0].mru = mru;
1225     lcp_wantoptions[0].neg_mru = 1;
1226     return (1);
1227 }
1228 
1229 
1230 /*
1231  * setmru - Set the largest MTU we'll use.
1232  */
1233 static int
setmtu(argv)1234 setmtu(argv)
1235     char **argv;
1236 {
1237     u_int32_t mtu;
1238 
1239     if (!number_option(*argv, &mtu, 0))
1240 	return 0;
1241     if (mtu < MINMRU || mtu > MAXMRU) {
1242 	option_error("mtu option value of %u is too %s", mtu,
1243 		     (mtu < MINMRU? "small": "large"));
1244 	return 0;
1245     }
1246     lcp_allowoptions[0].mru = mtu;
1247     return (1);
1248 }
1249 
1250 #ifdef CBCP_SUPPORT
1251 static int
setcbcp(argv)1252 setcbcp(argv)
1253     char **argv;
1254 {
1255     lcp_wantoptions[0].neg_cbcp = 1;
1256     cbcp_protent.enabled_flag = 1;
1257     cbcp[0].us_number = strdup(*argv);
1258     if (cbcp[0].us_number == 0)
1259 	novm("callback number");
1260     cbcp[0].us_type |= (1 << CB_CONF_USER);
1261     cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
1262     return (1);
1263 }
1264 #endif
1265 
1266 /*
1267  * nopcomp - Disable Protocol field compression negotiation.
1268  */
1269 static int
nopcomp(argv)1270 nopcomp(argv)
1271     char **argv;
1272 {
1273     lcp_wantoptions[0].neg_pcompression = 0;
1274     lcp_allowoptions[0].neg_pcompression = 0;
1275     return (1);
1276 }
1277 
1278 
1279 /*
1280  * setpassive - Set passive mode (don't give up if we time out sending
1281  * LCP configure-requests).
1282  */
1283 static int
setpassive(argv)1284 setpassive(argv)
1285     char **argv;
1286 {
1287     lcp_wantoptions[0].passive = 1;
1288     return (1);
1289 }
1290 
1291 
1292 /*
1293  * setsilent - Set silent mode (don't start sending LCP configure-requests
1294  * until we get one from the peer).
1295  */
1296 static int
setsilent(argv)1297 setsilent(argv)
1298     char **argv;
1299 {
1300     lcp_wantoptions[0].silent = 1;
1301     return 1;
1302 }
1303 
1304 
1305 /*
1306  * nopap - Disable PAP authentication with peer.
1307  */
1308 static int
nopap(argv)1309 nopap(argv)
1310     char **argv;
1311 {
1312     refuse_pap = 1;
1313     return (1);
1314 }
1315 
1316 
1317 /*
1318  * reqpap - Require PAP authentication from peer.
1319  */
1320 static int
reqpap(argv)1321 reqpap(argv)
1322     char **argv;
1323 {
1324     lcp_wantoptions[0].neg_upap = 1;
1325     setauth(NULL);
1326     return 1;
1327 }
1328 
1329 /*
1330  * nochap - Disable CHAP authentication with peer.
1331  */
1332 static int
nochap(argv)1333 nochap(argv)
1334     char **argv;
1335 {
1336     refuse_chap = 1;
1337     return (1);
1338 }
1339 
1340 
1341 /*
1342  * reqchap - Require CHAP authentication from peer.
1343  */
1344 static int
reqchap(argv)1345 reqchap(argv)
1346     char **argv;
1347 {
1348     lcp_wantoptions[0].neg_chap = 1;
1349     setauth(NULL);
1350     return (1);
1351 }
1352 
1353 
1354 /*
1355  * setnovj - disable vj compression
1356  */
1357 static int
setnovj(argv)1358 setnovj(argv)
1359     char **argv;
1360 {
1361     ipcp_wantoptions[0].neg_vj = 0;
1362     ipcp_allowoptions[0].neg_vj = 0;
1363     return (1);
1364 }
1365 
1366 
1367 /*
1368  * setnovjccomp - disable VJ connection-ID compression
1369  */
1370 static int
setnovjccomp(argv)1371 setnovjccomp(argv)
1372     char **argv;
1373 {
1374     ipcp_wantoptions[0].cflag = 0;
1375     ipcp_allowoptions[0].cflag = 0;
1376     return 1;
1377 }
1378 
1379 
1380 /*
1381  * setvjslots - set maximum number of connection slots for VJ compression
1382  */
1383 static int
setvjslots(argv)1384 setvjslots(argv)
1385     char **argv;
1386 {
1387     int value;
1388 
1389     if (!int_option(*argv, &value))
1390 	return 0;
1391     if (value < 2 || value > 16) {
1392 	option_error("vj-max-slots value must be between 2 and 16");
1393 	return 0;
1394     }
1395     ipcp_wantoptions [0].maxslotindex =
1396         ipcp_allowoptions[0].maxslotindex = value - 1;
1397     return 1;
1398 }
1399 
1400 
1401 /*
1402  * setconnector - Set a program to connect to a serial line
1403  */
1404 static int
setconnector(argv)1405 setconnector(argv)
1406     char **argv;
1407 {
1408     connector = strdup(*argv);
1409     if (connector == NULL)
1410 	novm("connect script");
1411     connector_info.priv = privileged_option;
1412     connector_info.source = option_source;
1413 
1414     return (1);
1415 }
1416 
1417 /*
1418  * setdisconnector - Set a program to disconnect from the serial line
1419  */
1420 static int
setdisconnector(argv)1421 setdisconnector(argv)
1422     char **argv;
1423 {
1424     disconnector = strdup(*argv);
1425     if (disconnector == NULL)
1426 	novm("disconnect script");
1427     disconnector_info.priv = privileged_option;
1428     disconnector_info.source = option_source;
1429 
1430     return (1);
1431 }
1432 
1433 /*
1434  * setwelcomer - Set a program to welcome a client after connection
1435  */
1436 static int
setwelcomer(argv)1437 setwelcomer(argv)
1438     char **argv;
1439 {
1440     welcomer = strdup(*argv);
1441     if (welcomer == NULL)
1442 	novm("welcome script");
1443     welcomer_info.priv = privileged_option;
1444     welcomer_info.source = option_source;
1445 
1446     return (1);
1447 }
1448 
1449 /*
1450  * setmaxconnect - Set the maximum connect time
1451  */
1452 static int
setmaxconnect(argv)1453 setmaxconnect(argv)
1454     char **argv;
1455 {
1456     int value;
1457 
1458     if (!int_option(*argv, &value))
1459 	return 0;
1460     if (value < 0) {
1461 	option_error("maxconnect time must be positive");
1462 	return 0;
1463     }
1464     if (maxconnect > 0 && (value == 0 || value > maxconnect)) {
1465 	option_error("maxconnect time cannot be increased");
1466 	return 0;
1467     }
1468     maxconnect = value;
1469     return 1;
1470 }
1471 
1472 /*
1473  * setdomain - Set domain name to append to hostname
1474  */
1475 static int
setdomain(argv)1476 setdomain(argv)
1477     char **argv;
1478 {
1479     if (!privileged_option) {
1480 	option_error("using the domain option requires root privilege");
1481 	return 0;
1482     }
1483     gethostname(hostname, MAXNAMELEN);
1484     if (**argv != 0) {
1485 	if (**argv != '.')
1486 	    strlcat(hostname, ".", MAXNAMELEN);
1487 	strlcat(hostname, *argv, MAXNAMELEN);
1488     }
1489     hostname[MAXNAMELEN-1] = 0;
1490     return (1);
1491 }
1492 
1493 
1494 /*
1495  * setasyncmap - add bits to asyncmap (what we request peer to escape).
1496  */
1497 static int
setasyncmap(argv)1498 setasyncmap(argv)
1499     char **argv;
1500 {
1501     u_int32_t asyncmap;
1502 
1503     if (!number_option(*argv, &asyncmap, 16))
1504 	return 0;
1505     lcp_wantoptions[0].asyncmap |= asyncmap;
1506     lcp_wantoptions[0].neg_asyncmap = 1;
1507     return(1);
1508 }
1509 
1510 
1511 /*
1512  * setescape - add chars to the set we escape on transmission.
1513  */
1514 static int
setescape(argv)1515 setescape(argv)
1516     char **argv;
1517 {
1518     int n, ret;
1519     char *p, *endp;
1520 
1521     p = *argv;
1522     ret = 1;
1523     while (*p) {
1524 	n = strtol(p, &endp, 16);
1525 	if (p == endp) {
1526 	    option_error("escape parameter contains invalid hex number '%s'",
1527 			 p);
1528 	    return 0;
1529 	}
1530 	p = endp;
1531 	if (n < 0 || (0x20 <= n && n <= 0x3F) || n == 0x5E || n > 0xFF) {
1532 	    option_error("can't escape character 0x%x", n);
1533 	    ret = 0;
1534 	} else
1535 	    xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
1536 	while (*p == ',' || *p == ' ')
1537 	    ++p;
1538     }
1539     return ret;
1540 }
1541 
1542 
1543 /*
1544  * setspeed - Set the speed.
1545  */
1546 static int
setspeed(arg)1547 setspeed(arg)
1548     char *arg;
1549 {
1550     char *ptr;
1551     int spd;
1552 
1553     spd = strtol(arg, &ptr, 0);
1554     if (ptr == arg || *ptr != 0 || spd == 0)
1555 	return 0;
1556     inspeed = spd;
1557     return 1;
1558 }
1559 
1560 
1561 /*
1562  * setdevname - Set the device name.
1563  */
1564 static int
setdevname(cp,quiet)1565 setdevname(cp, quiet)
1566     char *cp;
1567     int quiet;
1568 {
1569     struct stat statbuf;
1570     char dev[PATH_MAX];
1571 
1572     if (*cp == 0)
1573 	return 0;
1574 
1575     if (strncmp("/dev/", cp, 5) != 0) {
1576 	strlcpy(dev, "/dev/", sizeof dev);
1577 	strlcat(dev, cp, sizeof dev);
1578 	cp = dev;
1579     }
1580 
1581     /*
1582      * Check if there is a device by this name.
1583      */
1584     if (stat(cp, &statbuf) < 0) {
1585 	if (errno == ENOENT || quiet)
1586 	    return 0;
1587 	option_error("Couldn't stat %s: %m", cp);
1588 	return -1;
1589     }
1590 
1591     (void) strlcpy(devnam, cp, PATH_MAX);
1592     default_device = FALSE;
1593     devnam_info.priv = privileged_option;
1594     devnam_info.source = option_source;
1595 
1596     return 1;
1597 }
1598 
1599 
1600 /*
1601  * setipaddr - Set the IP address
1602  */
1603 static int
setipaddr(arg)1604 setipaddr(arg)
1605     char *arg;
1606 {
1607     struct hostent *hp;
1608     char *colon;
1609     struct in_addr ina;
1610     u_int32_t local, remote;
1611     ipcp_options *wo = &ipcp_wantoptions[0];
1612 
1613     /*
1614      * IP address pair separated by ":".
1615      */
1616     if ((colon = strchr(arg, ':')) == NULL)
1617 	return 0;
1618 
1619     /*
1620      * If colon first character, then no local addr.
1621      */
1622     if (colon != arg) {
1623 	*colon = '\0';
1624 	if (inet_aton(arg, &ina) == 0) {
1625 	    if ((hp = gethostbyname(arg)) == NULL) {
1626 		option_error("unknown host: %s", arg);
1627 		return -1;
1628 	    } else {
1629 		local = *(u_int32_t *)hp->h_addr;
1630 		if (our_name[0] == 0)
1631 		    strlcpy(our_name, arg, MAXNAMELEN);
1632 	    }
1633 	} else
1634 	    local = ina.s_addr;
1635 	if (bad_ip_adrs(local)) {
1636 	    option_error("bad local IP address %s", ip_ntoa(local));
1637 	    return -1;
1638 	}
1639 	if (local != 0)
1640 	    wo->ouraddr = local;
1641 	*colon = ':';
1642     }
1643 
1644     /*
1645      * If colon last character, then no remote addr.
1646      */
1647     if (*++colon != '\0') {
1648 	if (inet_aton(colon, &ina) == 0) {
1649 	    if ((hp = gethostbyname(colon)) == NULL) {
1650 		option_error("unknown host: %s", colon);
1651 		return -1;
1652 	    } else {
1653 		remote = *(u_int32_t *)hp->h_addr;
1654 		if (remote_name[0] == 0)
1655 		    strlcpy(remote_name, colon, MAXNAMELEN);
1656 	    }
1657 	} else
1658 	    remote = ina.s_addr;
1659 	if (bad_ip_adrs(remote)) {
1660 	    option_error("bad remote IP address %s", ip_ntoa(remote));
1661 	    return -1;
1662 	}
1663 	if (remote != 0)
1664 	    wo->hisaddr = remote;
1665     }
1666 
1667     return 1;
1668 }
1669 
1670 
1671 /*
1672  * setnoipdflt - disable setipdefault()
1673  */
1674 static int
setnoipdflt(argv)1675 setnoipdflt(argv)
1676     char **argv;
1677 {
1678     disable_defaultip = 1;
1679     return 1;
1680 }
1681 
1682 
1683 /*
1684  * setipcpaccl - accept peer's idea of our address
1685  */
1686 static int
setipcpaccl(argv)1687 setipcpaccl(argv)
1688     char **argv;
1689 {
1690     ipcp_wantoptions[0].accept_local = 1;
1691     return 1;
1692 }
1693 
1694 
1695 /*
1696  * setipcpaccr - accept peer's idea of its address
1697  */
1698 static int
setipcpaccr(argv)1699 setipcpaccr(argv)
1700     char **argv;
1701 {
1702     ipcp_wantoptions[0].accept_remote = 1;
1703     return 1;
1704 }
1705 
1706 
1707 /*
1708  * setnetmask - set the netmask to be used on the interface.
1709  */
1710 static int
setnetmask(argv)1711 setnetmask(argv)
1712     char **argv;
1713 {
1714     struct in_addr ina;
1715 
1716     if (inet_aton(*argv, &ina) == 0 || (netmask & ~ina.s_addr) != 0) {
1717 	option_error("invalid netmask value '%s'", *argv);
1718 	return (0);
1719     }
1720 
1721     netmask = ina.s_addr;
1722     return (1);
1723 }
1724 
1725 static int
setcrtscts(argv)1726 setcrtscts(argv)
1727     char **argv;
1728 {
1729     crtscts = 1;
1730     return (1);
1731 }
1732 
1733 static int
setnocrtscts(argv)1734 setnocrtscts(argv)
1735     char **argv;
1736 {
1737     crtscts = -1;
1738     return (1);
1739 }
1740 
1741 static int
setxonxoff(argv)1742 setxonxoff(argv)
1743     char **argv;
1744 {
1745     lcp_wantoptions[0].asyncmap |= 0x000A0000;	/* escape ^S and ^Q */
1746     lcp_wantoptions[0].neg_asyncmap = 1;
1747 
1748     crtscts = -2;
1749     return (1);
1750 }
1751 
1752 static int
setnodetach(argv)1753 setnodetach(argv)
1754     char **argv;
1755 {
1756     nodetach = 1;
1757     return (1);
1758 }
1759 
1760 static int
setupdetach(argv)1761 setupdetach(argv)
1762     char **argv;
1763 {
1764     nodetach = -1;
1765     return (1);
1766 }
1767 
1768 static int
setdemand(argv)1769 setdemand(argv)
1770     char **argv;
1771 {
1772     demand = 1;
1773     persist = 1;
1774     return 1;
1775 }
1776 
1777 static int
setmodem(argv)1778 setmodem(argv)
1779     char **argv;
1780 {
1781     modem = 1;
1782     return 1;
1783 }
1784 
1785 static int
setmodem_chat(argv)1786 setmodem_chat(argv)
1787     char **argv;
1788 {
1789     modem_chat = 1;
1790     return 1;
1791 }
1792 
1793 static int
setlocal(argv)1794 setlocal(argv)
1795     char **argv;
1796 {
1797     modem = 0;
1798     return 1;
1799 }
1800 
1801 static int
setlock(argv)1802 setlock(argv)
1803     char **argv;
1804 {
1805     lockflag = 1;
1806     return 1;
1807 }
1808 
1809 static int
setusehostname(argv)1810 setusehostname(argv)
1811     char **argv;
1812 {
1813     usehostname = 1;
1814     return 1;
1815 }
1816 
1817 static int
setname(argv)1818 setname(argv)
1819     char **argv;
1820 {
1821     if (!privileged_option) {
1822 	option_error("using the name option requires root privilege");
1823 	return 0;
1824     }
1825     strlcpy(our_name, argv[0], MAXNAMELEN);
1826     return 1;
1827 }
1828 
1829 static int
setuser(argv)1830 setuser(argv)
1831     char **argv;
1832 {
1833     strlcpy(user, argv[0], MAXNAMELEN);
1834     return 1;
1835 }
1836 
1837 static int
setremote(argv)1838 setremote(argv)
1839     char **argv;
1840 {
1841     strlcpy(remote_name, argv[0], MAXNAMELEN);
1842     return 1;
1843 }
1844 
1845 static int
setauth(argv)1846 setauth(argv)
1847     char **argv;
1848 {
1849     auth_required = 1;
1850     if (privileged_option > auth_req_info.priv) {
1851 	auth_req_info.priv = privileged_option;
1852 	auth_req_info.source = option_source;
1853     }
1854     return 1;
1855 }
1856 
1857 static int
setnoauth(argv)1858 setnoauth(argv)
1859     char **argv;
1860 {
1861     if (auth_required && privileged_option < auth_req_info.priv) {
1862 	if (auth_req_info.source == NULL)
1863 	    option_error("cannot override default auth option");
1864 	else
1865 	    option_error("cannot override auth option set by %s",
1866 	        auth_req_info.source);
1867 	return 0;
1868     }
1869     auth_required = 0;
1870     return 1;
1871 }
1872 
1873 static int
setdefaultroute(argv)1874 setdefaultroute(argv)
1875     char **argv;
1876 {
1877     if (!ipcp_allowoptions[0].default_route) {
1878 	option_error("defaultroute option is disabled");
1879 	return 0;
1880     }
1881     ipcp_wantoptions[0].default_route = 1;
1882     return 1;
1883 }
1884 
1885 static int
setnodefaultroute(argv)1886 setnodefaultroute(argv)
1887     char **argv;
1888 {
1889     ipcp_allowoptions[0].default_route = 0;
1890     ipcp_wantoptions[0].default_route = 0;
1891     return 1;
1892 }
1893 
1894 static int
setproxyarp(argv)1895 setproxyarp(argv)
1896     char **argv;
1897 {
1898     if (!ipcp_allowoptions[0].proxy_arp) {
1899 	option_error("proxyarp option is disabled");
1900 	return 0;
1901     }
1902     ipcp_wantoptions[0].proxy_arp = 1;
1903     return 1;
1904 }
1905 
1906 static int
setnoproxyarp(argv)1907 setnoproxyarp(argv)
1908     char **argv;
1909 {
1910     ipcp_wantoptions[0].proxy_arp = 0;
1911     ipcp_allowoptions[0].proxy_arp = 0;
1912     return 1;
1913 }
1914 
1915 static int
setpersist(argv)1916 setpersist(argv)
1917     char **argv;
1918 {
1919     persist = 1;
1920     return 1;
1921 }
1922 
1923 static int
setnopersist(argv)1924 setnopersist(argv)
1925     char **argv;
1926 {
1927     persist = 0;
1928     return 1;
1929 }
1930 
1931 static int
setdologin(argv)1932 setdologin(argv)
1933     char **argv;
1934 {
1935     uselogin = 1;
1936     return 1;
1937 }
1938 
1939 /*
1940  * Functions to set the echo interval for modem-less monitors
1941  */
1942 
1943 static int
setlcpechointv(argv)1944 setlcpechointv(argv)
1945     char **argv;
1946 {
1947     return int_option(*argv, &lcp_echo_interval);
1948 }
1949 
1950 static int
setlcpechofails(argv)1951 setlcpechofails(argv)
1952     char **argv;
1953 {
1954     return int_option(*argv, &lcp_echo_fails);
1955 }
1956 
1957 /*
1958  * Functions to set timeouts, max transmits, etc.
1959  */
1960 static int
setlcptimeout(argv)1961 setlcptimeout(argv)
1962     char **argv;
1963 {
1964     return int_option(*argv, &lcp_fsm[0].timeouttime);
1965 }
1966 
1967 static int
setlcpterm(argv)1968 setlcpterm(argv)
1969     char **argv;
1970 {
1971     return int_option(*argv, &lcp_fsm[0].maxtermtransmits);
1972 }
1973 
1974 static int
setlcpconf(argv)1975 setlcpconf(argv)
1976     char **argv;
1977 {
1978     return int_option(*argv, &lcp_fsm[0].maxconfreqtransmits);
1979 }
1980 
1981 static int
setlcpfails(argv)1982 setlcpfails(argv)
1983     char **argv;
1984 {
1985     return int_option(*argv, &lcp_fsm[0].maxnakloops);
1986 }
1987 
1988 static int
setipcptimeout(argv)1989 setipcptimeout(argv)
1990     char **argv;
1991 {
1992     return int_option(*argv, &ipcp_fsm[0].timeouttime);
1993 }
1994 
1995 static int
setipcpterm(argv)1996 setipcpterm(argv)
1997     char **argv;
1998 {
1999     return int_option(*argv, &ipcp_fsm[0].maxtermtransmits);
2000 }
2001 
2002 static int
setipcpconf(argv)2003 setipcpconf(argv)
2004     char **argv;
2005 {
2006     return int_option(*argv, &ipcp_fsm[0].maxconfreqtransmits);
2007 }
2008 
2009 static int
setipcpfails(argv)2010 setipcpfails(argv)
2011     char **argv;
2012 {
2013     return int_option(*argv, &lcp_fsm[0].maxnakloops);
2014 }
2015 
2016 static int
setpaptimeout(argv)2017 setpaptimeout(argv)
2018     char **argv;
2019 {
2020     return int_option(*argv, &upap[0].us_timeouttime);
2021 }
2022 
2023 static int
setpapreqtime(argv)2024 setpapreqtime(argv)
2025     char **argv;
2026 {
2027     return int_option(*argv, &upap[0].us_reqtimeout);
2028 }
2029 
2030 static int
setpapreqs(argv)2031 setpapreqs(argv)
2032     char **argv;
2033 {
2034     return int_option(*argv, &upap[0].us_maxtransmits);
2035 }
2036 
2037 static int
setchaptimeout(argv)2038 setchaptimeout(argv)
2039     char **argv;
2040 {
2041     return int_option(*argv, &chap[0].timeouttime);
2042 }
2043 
2044 static int
setchapchal(argv)2045 setchapchal(argv)
2046     char **argv;
2047 {
2048     return int_option(*argv, &chap[0].max_transmits);
2049 }
2050 
2051 static int
setchapintv(argv)2052 setchapintv(argv)
2053     char **argv;
2054 {
2055     return int_option(*argv, &chap[0].chal_interval);
2056 }
2057 
2058 static int
noccp(argv)2059 noccp(argv)
2060     char **argv;
2061 {
2062     ccp_protent.enabled_flag = 0;
2063     return 1;
2064 }
2065 
2066 static int
setbsdcomp(argv)2067 setbsdcomp(argv)
2068     char **argv;
2069 {
2070     int rbits, abits;
2071     char *str, *endp;
2072 
2073     str = *argv;
2074     abits = rbits = strtol(str, &endp, 0);
2075     if (endp != str && *endp == ',') {
2076 	str = endp + 1;
2077 	abits = strtol(str, &endp, 0);
2078     }
2079     if (*endp != 0 || endp == str) {
2080 	option_error("invalid parameter '%s' for bsdcomp option", *argv);
2081 	return 0;
2082     }
2083     if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
2084 	|| (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
2085 	option_error("bsdcomp option values must be 0 or %d .. %d",
2086 		     BSD_MIN_BITS, BSD_MAX_BITS);
2087 	return 0;
2088     }
2089     if (rbits > 0) {
2090 	ccp_wantoptions[0].bsd_compress = 1;
2091 	ccp_wantoptions[0].bsd_bits = rbits;
2092     } else
2093 	ccp_wantoptions[0].bsd_compress = 0;
2094     if (abits > 0) {
2095 	ccp_allowoptions[0].bsd_compress = 1;
2096 	ccp_allowoptions[0].bsd_bits = abits;
2097     } else
2098 	ccp_allowoptions[0].bsd_compress = 0;
2099     return 1;
2100 }
2101 
2102 static int
setnobsdcomp(argv)2103 setnobsdcomp(argv)
2104     char **argv;
2105 {
2106     ccp_wantoptions[0].bsd_compress = 0;
2107     ccp_allowoptions[0].bsd_compress = 0;
2108     return 1;
2109 }
2110 
2111 static int
setdeflate(argv)2112 setdeflate(argv)
2113     char **argv;
2114 {
2115     int rbits, abits;
2116     char *str, *endp;
2117 
2118     str = *argv;
2119     abits = rbits = strtol(str, &endp, 0);
2120     if (endp != str && *endp == ',') {
2121 	str = endp + 1;
2122 	abits = strtol(str, &endp, 0);
2123     }
2124     if (*endp != 0 || endp == str) {
2125 	option_error("invalid parameter '%s' for deflate option", *argv);
2126 	return 0;
2127     }
2128     if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
2129 	|| (abits != 0 && (abits < DEFLATE_MIN_SIZE
2130 			  || abits > DEFLATE_MAX_SIZE))) {
2131 	option_error("deflate option values must be 0 or %d .. %d",
2132 		     DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
2133 	return 0;
2134     }
2135     if (rbits > 0) {
2136 	ccp_wantoptions[0].deflate = 1;
2137 	ccp_wantoptions[0].deflate_size = rbits;
2138     } else
2139 	ccp_wantoptions[0].deflate = 0;
2140     if (abits > 0) {
2141 	ccp_allowoptions[0].deflate = 1;
2142 	ccp_allowoptions[0].deflate_size = abits;
2143     } else
2144 	ccp_allowoptions[0].deflate = 0;
2145     return 1;
2146 }
2147 
2148 static int
setnodeflate(argv)2149 setnodeflate(argv)
2150     char **argv;
2151 {
2152     ccp_wantoptions[0].deflate = 0;
2153     ccp_allowoptions[0].deflate = 0;
2154     return 1;
2155 }
2156 
2157 static int
setnodeflatedraft(argv)2158 setnodeflatedraft(argv)
2159     char **argv;
2160 {
2161     ccp_wantoptions[0].deflate_draft = 0;
2162     ccp_allowoptions[0].deflate_draft = 0;
2163     return 1;
2164 }
2165 
2166 static int
setpred1comp(argv)2167 setpred1comp(argv)
2168     char **argv;
2169 {
2170     ccp_wantoptions[0].predictor_1 = 1;
2171     ccp_allowoptions[0].predictor_1 = 1;
2172     return 1;
2173 }
2174 
2175 static int
setnopred1comp(argv)2176 setnopred1comp(argv)
2177     char **argv;
2178 {
2179     ccp_wantoptions[0].predictor_1 = 0;
2180     ccp_allowoptions[0].predictor_1 = 0;
2181     return 1;
2182 }
2183 
2184 static int
setipparam(argv)2185 setipparam(argv)
2186     char **argv;
2187 {
2188     ipparam = strdup(*argv);
2189     if (ipparam == NULL)
2190 	novm("ipparam string");
2191 
2192     return 1;
2193 }
2194 
2195 static int
setpapcrypt(argv)2196 setpapcrypt(argv)
2197     char **argv;
2198 {
2199     cryptpap = 1;
2200     return 1;
2201 }
2202 
2203 static int
setidle(argv)2204 setidle(argv)
2205     char **argv;
2206 {
2207     return int_option(*argv, &idle_time_limit);
2208 }
2209 
2210 static int
setholdoff(argv)2211 setholdoff(argv)
2212     char **argv;
2213 {
2214     return int_option(*argv, &holdoff);
2215 }
2216 
2217 /*
2218  * setdnsaddr - set the dns address(es)
2219  */
2220 static int
setdnsaddr(argv)2221 setdnsaddr(argv)
2222     char **argv;
2223 {
2224     struct in_addr ina;
2225     struct hostent *hp;
2226 
2227     if (inet_aton(*argv, &ina) == 0) {
2228 	if ((hp = gethostbyname(*argv)) == NULL) {
2229 	    option_error("invalid address parameter '%s' for ms-dns option",
2230 			 *argv);
2231 	    return (0);
2232 	}
2233 	ina.s_addr = *(u_int32_t *)hp->h_addr;
2234     }
2235 
2236     /* if there is no primary then update it. */
2237     if (ipcp_allowoptions[0].dnsaddr[0] == 0)
2238 	ipcp_allowoptions[0].dnsaddr[0] = ina.s_addr;
2239 
2240     /* always set the secondary address value to the same value. */
2241     ipcp_allowoptions[0].dnsaddr[1] = ina.s_addr;
2242 
2243     return (1);
2244 }
2245 
2246 /*
2247  * setwinsaddr - set the wins address(es)
2248  * This is primrarly used with the Samba package under UNIX or for pointing
2249  * the caller to the existing WINS server on a Windows NT platform.
2250  */
2251 static int
setwinsaddr(argv)2252 setwinsaddr(argv)
2253     char **argv;
2254 {
2255     struct in_addr ina;
2256     struct hostent *hp;
2257 
2258     if (inet_aton(*argv, &ina) == 0) {
2259 	if ((hp = gethostbyname(*argv)) == NULL) {
2260 	    option_error("invalid address parameter '%s' for ms-wins option",
2261 			 *argv);
2262 	    return (0);
2263 	}
2264 	ina.s_addr = *(u_int32_t *)hp->h_addr;
2265     }
2266 
2267     /* if there is no primary then update it. */
2268     if (ipcp_allowoptions[0].winsaddr[0] == 0)
2269 	ipcp_allowoptions[0].winsaddr[0] = ina.s_addr;
2270 
2271     /* always set the secondary address value to the same value. */
2272     ipcp_allowoptions[0].winsaddr[1] = ina.s_addr;
2273 
2274     return (1);
2275 }
2276 
2277 #ifdef MSLANMAN
2278 static int
setmslanman(argv)2279 setmslanman(argv)
2280     char **argv;
2281 {
2282     ms_lanman = 1;
2283     return (1);
2284 }
2285 #endif
2286