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 | |
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.
-rw-r--r-- | usr.sbin/pppd/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/pppd/auth.c | 177 | ||||
-rw-r--r-- | usr.sbin/pppd/cbcp.c | 434 | ||||
-rw-r--r-- | usr.sbin/pppd/cbcp.h | 28 | ||||
-rw-r--r-- | usr.sbin/pppd/ccp.c | 15 | ||||
-rw-r--r-- | usr.sbin/pppd/chap.c | 26 | ||||
-rw-r--r-- | usr.sbin/pppd/chap.h | 21 | ||||
-rw-r--r-- | usr.sbin/pppd/demand.c | 15 | ||||
-rw-r--r-- | usr.sbin/pppd/ipcp.c | 69 | ||||
-rw-r--r-- | usr.sbin/pppd/ipxcp.c | 105 | ||||
-rw-r--r-- | usr.sbin/pppd/lcp.c | 98 | ||||
-rw-r--r-- | usr.sbin/pppd/lcp.h | 7 | ||||
-rw-r--r-- | usr.sbin/pppd/main.c | 116 | ||||
-rw-r--r-- | usr.sbin/pppd/options.c | 318 | ||||
-rw-r--r-- | usr.sbin/pppd/patchlevel.h | 6 | ||||
-rw-r--r-- | usr.sbin/pppd/pathnames.h | 3 | ||||
-rw-r--r-- | usr.sbin/pppd/pppd.8 | 557 | ||||
-rw-r--r-- | usr.sbin/pppd/pppd.h | 57 | ||||
-rw-r--r-- | usr.sbin/pppd/sys-bsd.c | 169 | ||||
-rw-r--r-- | usr.sbin/pppd/upap.c | 36 |
20 files changed, 1573 insertions, 688 deletions
diff --git a/usr.sbin/pppd/Makefile b/usr.sbin/pppd/Makefile index 33fcbf8190a..9c697d00f4a 100644 --- a/usr.sbin/pppd/Makefile +++ b/usr.sbin/pppd/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.7 1996/12/15 23:20:32 millert Exp $ +# $OpenBSD: Makefile,v 1.8 1996/12/23 13:22:36 mickey Exp $ # $NetBSD: Makefile,v 1.12 1996/03/19 03:03:04 jtc Exp $ PROG= pppd @@ -15,7 +15,7 @@ BINOWN= root LDADD= -lutil #DPADD= ${LIBCRYPT} ${LIBUTIL} DPADD= ${LIBUTIL} -CFLAGS+= -I. -I${.CURDIR} -DHAVE_PATHS_H +CFLAGS+= -I. -I${.CURDIR} -DHAVE_PATHS_H -DIPX_CHANGE CLEANFILES=y.tab.h grammar.c scanner.c MLINKS= pppd.8 ppp.8 diff --git a/usr.sbin/pppd/auth.c b/usr.sbin/pppd/auth.c index 600c69fc1c0..466828eb213 100644 --- a/usr.sbin/pppd/auth.c +++ b/usr.sbin/pppd/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.5 1996/12/15 23:20:33 millert Exp $ */ +/* $OpenBSD: auth.c,v 1.6 1996/12/23 13:22:37 mickey Exp $ */ /* * auth.c - PPP authentication and phase control. @@ -35,7 +35,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: auth.c,v 1.5 1996/12/15 23:20:33 millert Exp $"; +static char rcsid[] = "$OpenBSD: auth.c,v 1.6 1996/12/23 13:22:37 mickey Exp $"; #endif #include <stdio.h> @@ -56,6 +56,7 @@ static char rcsid[] = "$OpenBSD: auth.c,v 1.5 1996/12/15 23:20:33 millert Exp $" #ifdef USE_PAM #include <security/pam_appl.h> #include <security/pam_modules.h> +int isexpired (struct passwd *, struct spwd *); #endif #ifdef HAS_SHADOW @@ -72,6 +73,9 @@ static char rcsid[] = "$OpenBSD: auth.c,v 1.5 1996/12/15 23:20:33 millert Exp $" #include "ipcp.h" #include "upap.h" #include "chap.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif #include "pathnames.h" #if defined(sun) && defined(sparc) @@ -118,8 +122,8 @@ static int num_np_up; static int passwd_from_file; /* Bits in auth_pending[] */ -#define UPAP_WITHPEER 1 -#define UPAP_PEER 2 +#define PAP_WITHPEER 1 +#define PAP_PEER 2 #define CHAP_WITHPEER 4 #define CHAP_PEER 8 @@ -130,15 +134,17 @@ static void check_idle __P((caddr_t)); static int login __P((char *, char *, char **, int *)); static void logout __P((void)); static int null_login __P((int)); -static int get_upap_passwd __P((char *)); -static int have_upap_secret __P((void)); +static int get_pap_passwd __P((char *)); +static int have_pap_secret __P((void)); static int have_chap_secret __P((char *, char *, u_int32_t)); static int ip_addr_check __P((u_int32_t, struct wordlist *)); static int scan_authfile __P((FILE *, char *, char *, u_int32_t, char *, struct wordlist **, char *)); static void free_wordlist __P((struct wordlist *)); static void auth_script __P((char *)); - +#ifdef CBCP_SUPPORT +static void callback_phase __P((int)); +#endif /* * An Open on LCP has requested a change from Dead to Establish phase. @@ -186,8 +192,7 @@ link_down(unit) if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) (*protp->lowerdown)(unit); if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(unit, "LCP link down"); - + (*protp->close)(unit, "LCP down"); } num_np_open = 0; num_np_up = 0; @@ -226,7 +231,6 @@ link_established(unit) if (!wo->neg_upap || !null_login(unit)) { syslog(LOG_WARNING, "peer refused to authenticate"); lcp_close(unit, "peer refused to authenticate"); - phase = PHASE_TERMINATE; return; } } @@ -238,19 +242,19 @@ link_established(unit) auth |= CHAP_PEER; } else if (go->neg_upap) { upap_authpeer(unit); - auth |= UPAP_PEER; + auth |= PAP_PEER; } if (ho->neg_chap) { - ChapAuthWithPeer(unit, our_name, ho->chap_mdtype); + ChapAuthWithPeer(unit, user, ho->chap_mdtype); auth |= CHAP_WITHPEER; } else if (ho->neg_upap) { if (passwd[0] == 0) { passwd_from_file = 1; - if (!get_upap_passwd(passwd)) + if (!get_pap_passwd(passwd)) syslog(LOG_ERR, "No secret found for PAP login"); } upap_authwithpeer(unit, user, passwd); - auth |= UPAP_WITHPEER; + auth |= PAP_WITHPEER; } auth_pending[unit] = auth; @@ -277,6 +281,17 @@ network_phase(unit) did_authup = 1; } +#ifdef CBCP_SUPPORT + /* + * If we negotiated callback, do it now. + */ + if (go->neg_cbcp) { + phase = PHASE_CALLBACK; + (*cbcp_protent.open)(unit); + return; + } +#endif + phase = PHASE_NETWORK; #if 0 if (!demand) @@ -302,7 +317,6 @@ auth_peer_fail(unit, protocol) * Authentication failure: take the link down */ lcp_close(unit, "Authentication failed"); - phase = PHASE_TERMINATE; } /* @@ -321,7 +335,7 @@ auth_peer_success(unit, protocol, name, namelen) bit = CHAP_PEER; break; case PPP_PAP: - bit = UPAP_PEER; + bit = PAP_PEER; break; default: syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", @@ -339,7 +353,7 @@ auth_peer_success(unit, protocol, name, namelen) /* * If there is no more authentication still to be done, - * proceed to the network phase. + * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit); @@ -378,7 +392,7 @@ auth_withpeer_success(unit, protocol) case PPP_PAP: if (passwd_from_file) BZERO(passwd, MAXSECRETLEN); - bit = UPAP_WITHPEER; + bit = PAP_WITHPEER; break; default: syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", @@ -388,7 +402,7 @@ auth_withpeer_success(unit, protocol) /* * If there is no more authentication still being done, - * proceed to the network phase. + * proceed to the network (or callback) phase. */ if ((auth_pending[unit] &= ~bit) == 0) network_phase(unit); @@ -450,6 +464,7 @@ check_idle(arg) if (itime >= idle_time_limit) { /* link is idle: shut it down. */ syslog(LOG_INFO, "Terminating connection due to lack of activity."); + need_holdoff = 0; lcp_close(0, "Link inactive"); } else { TIMEOUT(check_idle, NULL, idle_time_limit - itime); @@ -464,7 +479,6 @@ auth_check_options() { lcp_options *wo = &lcp_wantoptions[0]; int can_auth; - lcp_options *ao = &lcp_allowoptions[0]; ipcp_options *ipwo = &ipcp_wantoptions[0]; u_int32_t remote; @@ -482,26 +496,41 @@ auth_check_options() /* * Check whether we have appropriate secrets to use - * to authenticate ourselves and/or the peer. + * to authenticate the peer. */ - if (ao->neg_upap && passwd[0] == 0 && !get_upap_passwd(passwd)) - ao->neg_upap = 0; - if (wo->neg_upap && !uselogin && !have_upap_secret()) - wo->neg_upap = 0; - if (ao->neg_chap && !have_chap_secret(our_name, remote_name, (u_int32_t)0)) - ao->neg_chap = 0; - if (wo->neg_chap) { - remote = ipwo->accept_remote? 0: ipwo->hisaddr; - if (!have_chap_secret(remote_name, our_name, remote)) - wo->neg_chap = 0; + can_auth = wo->neg_upap && (uselogin || have_pap_secret()); + if (!can_auth && wo->neg_chap) { + remote = ipwo->accept_remote? 0: ipwo->hisaddr; + can_auth = have_chap_secret(remote_name, our_name, remote); } - if (auth_required && !wo->neg_chap && !wo->neg_upap) { - fprintf(stderr, "\ -pppd: peer authentication required but no suitable secret(s) found\n"); + if (auth_required && !can_auth) { + option_error("peer authentication required but no suitable secret(s) found\n"); + if (remote_name[0] == 0) + option_error("for authenticating any peer to us (%s)\n", our_name); + else + option_error("for authenticating peer %s to us (%s)\n", + remote_name, our_name); exit(1); } + /* + * Check whether the user tried to override certain values + * set by root. + */ + if (!auth_required && auth_req_info.priv > 0) { + if (!default_device && devnam_info.priv == 0) { + option_error("can't override device name when noauth option used"); + exit(1); + } + if (connector != NULL && connector_info.priv == 0 + || disconnector != NULL && disconnector_info.priv == 0 + || welcomer != NULL && welcomer_info.priv == 0) { + option_error("can't override connect, disconnect or welcome"); + option_error("option values when noauth option used"); + exit(1); + } + } } /* @@ -518,11 +547,11 @@ auth_reset(unit) ipcp_options *ipwo = &ipcp_wantoptions[0]; u_int32_t remote; - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_upap_passwd(NULL)); + ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); ao->neg_chap = !refuse_chap - && have_chap_secret(our_name, remote_name, (u_int32_t)0); + && have_chap_secret(user, remote_name, (u_int32_t)0); - if (go->neg_upap && !uselogin && !have_upap_secret()) + if (go->neg_upap && !uselogin && !have_pap_secret()) go->neg_upap = 0; if (go->neg_chap) { remote = ipwo->accept_remote? 0: ipwo->hisaddr; @@ -572,9 +601,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) user[userlen] = '\0'; *msg = (char *) 0; - /* - * Open the file of upap secrets and scan for a suitable secret + * Open the file of pap secrets and scan for a suitable secret * for authenticating this user. */ filename = _PATH_UPAPFILE; @@ -786,14 +814,20 @@ login(user, passwd, msg, msglen) struct spwd *getspnam(); #endif - if ((pw = getpwnam(user)) == NULL) { + pw = getpwnam(user); + if (pw == NULL) { return (UPAP_AUTHNAK); } #ifdef HAS_SHADOW - if ((spwd = getspnam(user)) == NULL) { - pw->pw_passwd = ""; - } else { + spwd = getspnam(user); + endspent(); + if (spwd) { + /* check the age of the password entry */ + if (isexpired(pw, spwd)) { + syslog(LOG_WARNING,"Expired password for %s",user); + return (UPAP_AUTHNAK); + } pw->pw_passwd = spwd->sp_pwdp; } #endif @@ -801,33 +835,12 @@ login(user, passwd, msg, msglen) /* * XXX If no passwd, let them login without one. */ - if (pw->pw_passwd == '\0') { - return (UPAP_AUTHACK); - } - -#ifdef HAS_SHADOW - if (pw->pw_passwd) { - if (pw->pw_passwd[0] == '@') { - if (pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL)) { - return (UPAP_AUTHNAK); - } - } else { - epasswd = pw_encrypt(passwd, pw->pw_passwd); - if (strcmp(epasswd, pw->pw_passwd)) { - return (UPAP_AUTHNAK); - } - } - /* check the age of the password entry */ - if (spwd && (isexpired (pw, spwd) != 0)) { - return (UPAP_AUTHNAK); - } - } -#else + if (pw->pw_passwd != NULL && *pw->pw_passwd != '\0') { epasswd = crypt(passwd, pw->pw_passwd); - if (strcmp(epasswd, pw->pw_passwd)) { + if (strcmp(epasswd, pw->pw_passwd) != 0) { return (UPAP_AUTHNAK); } -#endif + } #endif /* #ifdef USE_PAM */ syslog(LOG_INFO, "user %s logged in", user); @@ -876,7 +889,7 @@ null_login(unit) char secret[MAXWORDLEN]; /* - * Open the file of upap secrets and scan for a suitable secret. + * Open the file of pap secrets and scan for a suitable secret. * We don't accept a wildcard client. */ filename = _PATH_UPAPFILE; @@ -902,13 +915,13 @@ null_login(unit) /* - * get_upap_passwd - get a password for authenticating ourselves with + * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password * could be found. */ static int -get_upap_passwd(passwd) -char *passwd; +get_pap_passwd(passwd) + char *passwd; { char *filename; FILE *f; @@ -935,11 +948,11 @@ char *passwd; /* - * have_upap_secret - check whether we have a PAP file with any + * have_pap_secret - check whether we have a PAP file with any * secrets that we could possibly use for authenticating the peer. */ static int -have_upap_secret() +have_pap_secret() { FILE *f; int ret; @@ -1046,6 +1059,7 @@ get_secret(unit, client, server, secret, secret_len, save_addrs) len = MAXSECRETLEN; } BCOPY(secbuf, secret, len); + BZERO(secbuf, sizeof(secbuf)); *secret_len = len; return 1; @@ -1068,9 +1082,8 @@ ip_addr_check(addr, addrs) u_int32_t addr; struct wordlist *addrs; { - u_int32_t mask, ah; - struct in_addr ina; - int accept, r = 1; + u_int32_t a, mask, ah; + int accept; char *ptr_word, *ptr_mask; struct hostent *hp; struct netent *np; @@ -1112,17 +1125,17 @@ ip_addr_check(addr, addrs) hp = gethostbyname(ptr_word); if (hp != NULL && hp->h_addrtype == AF_INET) { - ina.s_addr = *(u_int32_t *)hp->h_addr; + a = *(u_int32_t *)hp->h_addr; mask = ~ (u_int32_t) 0; /* are we sure we want this? */ } else { np = getnetbyname (ptr_word); if (np != NULL && np->n_addrtype == AF_INET) - ina.s_addr = htonl (*(u_int32_t *)np->n_net); + a = htonl (*(u_int32_t *)np->n_net); else - r = inet_aton (ptr_word, &ina); + a = inet_addr (ptr_word); if (ptr_mask == NULL) { /* calculate appropriate mask for net */ - ah = ntohl(ina.s_addr); + ah = ntohl(a); if (IN_CLASSA(ah)) mask = IN_CLASSA_NET; else if (IN_CLASSB(ah)) @@ -1135,12 +1148,12 @@ ip_addr_check(addr, addrs) if (ptr_mask != NULL) *ptr_mask = '/'; - if (r == 0) + if (a == -1L) syslog (LOG_WARNING, "unknown host %s in auth. address list", addrs->word); else - if (((addr ^ ina.s_addr) & htonl(mask)) == 0) + if (((addr ^ a) & htonl(mask)) == 0) return accept; } return 0; /* not in list => can't have it */ diff --git a/usr.sbin/pppd/cbcp.c b/usr.sbin/pppd/cbcp.c new file mode 100644 index 00000000000..2ee07283e50 --- /dev/null +++ b/usr.sbin/pppd/cbcp.c @@ -0,0 +1,434 @@ +/* $OpenBSD: cbcp.c,v 1.1 1996/12/23 13:22:37 mickey Exp $ */ + +/* + * cbcp - Call Back Configuration Protocol. + * + * Copyright (c) 1995 Pedro Roque Marques + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Pedro Roque Marques. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static char rcsid[] = "$OpenBSD: cbcp.c,v 1.1 1996/12/23 13:22:37 mickey Exp $"; +#endif + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/time.h> +#include <syslog.h> + +#include "pppd.h" +#include "cbcp.h" +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" + +/* + * Protocol entry points. + */ +static void cbcp_init __P((int unit)); +static void cbcp_open __P((int unit)); +static void cbcp_lowerup __P((int unit)); +static void cbcp_input __P((int unit, u_char *pkt, int len)); +static void cbcp_protrej __P((int unit)); +static int cbcp_printpkt __P((u_char *pkt, int len, + void (*printer) __P((void *, char *, ...)), + void *arg)); + +struct protent cbcp_protent = { + PPP_CBCP, + cbcp_init, + cbcp_input, + cbcp_protrej, + cbcp_lowerup, + NULL, + cbcp_open, + NULL, + cbcp_printpkt, + NULL, + 0, + "CBCP", + NULL, + NULL, + NULL +}; + +cbcp_state cbcp[NUM_PPP]; + +/* internal prototypes */ + +static void cbcp_recvreq(cbcp_state *us, char *pckt, int len); +static void cbcp_resp(cbcp_state *us); +static void cbcp_up(cbcp_state *us); +static void cbcp_recvack(cbcp_state *us, char *pckt, int len); +static void cbcp_send(cbcp_state *us, u_char code, u_char *buf, int len); + +/* init state */ +static void +cbcp_init(iface) + int iface; +{ + cbcp_state *us; + + us = &cbcp[iface]; + memset(us, 0, sizeof(cbcp_state)); + us->us_unit = iface; + us->us_type |= (1 << CB_CONF_NO); +} + +/* lower layer is up */ +static void +cbcp_lowerup(iface) + int iface; +{ + cbcp_state *us = &cbcp[iface]; + + syslog(LOG_DEBUG, "cbcp_lowerup"); + syslog(LOG_DEBUG, "want: %d", us->us_type); + + if (us->us_type == CB_CONF_USER) + syslog(LOG_DEBUG, "phone no: %s", us->us_number); +} + +static void +cbcp_open(unit) + int unit; +{ + syslog(LOG_DEBUG, "cbcp_open"); +} + +/* process an incomming packet */ +static void +cbcp_input(unit, inpacket, pktlen) + int unit; + u_char *inpacket; + int pktlen; +{ + u_char *inp; + u_char code, id; + u_short len; + + cbcp_state *us = &cbcp[unit]; + + inp = inpacket; + + if (pktlen < CBCP_MINLEN) { + syslog(LOG_ERR, "CBCP packet is too small"); + return; + } + + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + +#if 0 + if (len > pktlen) { + syslog(LOG_ERR, "CBCP packet: invalid length"); + return; + } +#endif + + len -= CBCP_MINLEN; + + switch(code) { + case CBCP_REQ: + us->us_id = id; + cbcp_recvreq(us, inp, len); + break; + + case CBCP_RESP: + syslog(LOG_DEBUG, "CBCP_RESP received"); + break; + + case CBCP_ACK: + if (id != us->us_id) + syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d", + us->us_id, id); + + cbcp_recvack(us, inp, len); + break; + + default: + break; + } +} + +/* protocol was rejected by foe */ +void cbcp_protrej(int iface) +{ +} + +char *cbcp_codenames[] = { + "Request", "Response", "Ack" +}; + +char *cbcp_optionnames[] = { + "NoCallback", + "UserDefined", + "AdminDefined", + "List" +}; + +/* pretty print a packet */ +static int +cbcp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) __P((void *, char *, ...)); + void *arg; +{ + int code, opt, id, len, olen, delay; + u_char *pstart, *optend; + u_short cishort; + u_long cilong; + + if (plen < HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *)) + printer(arg, " %s", cbcp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + + switch (code) { + case CBCP_REQ: + case CBCP_RESP: + case CBCP_ACK: + while(len >= 2) { + GETCHAR(opt, p); + GETCHAR(olen, p); + + if (olen < 2 || olen > len) { + break; + } + + printer(arg, " <"); + len -= olen; + + if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *)) + printer(arg, " %s", cbcp_optionnames[opt-1]); + else + printer(arg, " option=0x%x", opt); + + if (olen > 2) { + GETCHAR(delay, p); + printer(arg, " delay = %d", delay); + } + + if (olen > 3) { + int addrt; + char str[256]; + + GETCHAR(addrt, p); + memcpy(str, p, olen - 4); + str[olen - 4] = 0; + printer(arg, " number = %s", str); + } + printer(arg, ">"); + break; + } + + default: + break; + } + + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return p - pstart; +} + +/* received CBCP request */ +static void +cbcp_recvreq(us, pckt, pcktlen) + cbcp_state *us; + char *pckt; + int pcktlen; +{ + u_char type, opt_len, delay, addr_type; + char address[256]; + int len = pcktlen; + + address[0] = 0; + + while (len) { + syslog(LOG_DEBUG, "length: %d", len); + + GETCHAR(type, pckt); + GETCHAR(opt_len, pckt); + + if (opt_len > 2) + GETCHAR(delay, pckt); + + us->us_allowed |= (1 << type); + + switch(type) { + case CB_CONF_NO: + syslog(LOG_DEBUG, "no callback allowed"); + break; + + case CB_CONF_USER: + syslog(LOG_DEBUG, "user callback allowed"); + if (opt_len > 4) { + GETCHAR(addr_type, pckt); + memcpy(address, pckt, opt_len - 4); + address[opt_len - 4] = 0; + if (address[0]) + syslog(LOG_DEBUG, "address: %s", address); + } + break; + + case CB_CONF_ADMIN: + syslog(LOG_DEBUG, "user admin defined allowed"); + break; + + case CB_CONF_LIST: + break; + } + len -= opt_len; + } + + cbcp_resp(us); +} + +static void +cbcp_resp(us) + cbcp_state *us; +{ + u_char cb_type; + u_char buf[256]; + u_char *bufp = buf; + int len = 0; + + cb_type = us->us_allowed & us->us_type; + syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type); + +#if 0 + if (!cb_type) + lcp_down(us->us_unit); +#endif + + if (cb_type & ( 1 << CB_CONF_USER ) ) { + syslog(LOG_DEBUG, "cbcp_resp CONF_USER"); + PUTCHAR(CB_CONF_USER, bufp); + len = 3 + 1 + strlen(us->us_number) + 1; + PUTCHAR(len , bufp); + PUTCHAR(5, bufp); /* delay */ + PUTCHAR(1, bufp); + BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); + cbcp_send(us, CBCP_RESP, buf, len); + return; + } + + if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { + syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN"); + PUTCHAR(CB_CONF_ADMIN, bufp); + len = 3 + 1; + PUTCHAR(len , bufp); + PUTCHAR(5, bufp); /* delay */ + PUTCHAR(0, bufp); + cbcp_send(us, CBCP_RESP, buf, len); + return; + } + + if (cb_type & ( 1 << CB_CONF_NO ) ) { + syslog(LOG_DEBUG, "cbcp_resp CONF_NO"); + PUTCHAR(CB_CONF_NO, bufp); + len = 3; + PUTCHAR(len , bufp); + PUTCHAR(0, bufp); + cbcp_send(us, CBCP_RESP, buf, len); + ipcp_open(us->us_unit); + return; + } +} + +static void +cbcp_send(us, code, buf, len) + cbcp_state *us; + u_char code; + u_char *buf; + int len; +{ + u_char *outp; + int outlen; + + outp = outpacket_buf; + + outlen = 4 + len; + + MAKEHEADER(outp, PPP_CBCP); + + PUTCHAR(code, outp); + PUTCHAR(us->us_id, outp); + PUTSHORT(outlen, outp); + + if (len) + BCOPY(buf, outp, len); + + output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN); +} + +static void +cbcp_recvack(us, pckt, len) + cbcp_state *us; + char *pckt; + int len; +{ + u_char type, delay, addr_type; + int opt_len; + char address[256]; + + if (len) { + GETCHAR(type, pckt); + GETCHAR(opt_len, pckt); + + if (opt_len > 2) + GETCHAR(delay, pckt); + + if (opt_len > 4) { + GETCHAR(addr_type, pckt); + memcpy(address, pckt, opt_len - 4); + address[opt_len - 4] = 0; + if (address[0]) + syslog(LOG_DEBUG, "peer will call: %s", address); + } + } + + cbcp_up(us); +} + +extern int persist; + +/* ok peer will do callback */ +static void +cbcp_up(us) + cbcp_state *us; +{ + persist = 0; + lcp_close(0,0); +} diff --git a/usr.sbin/pppd/cbcp.h b/usr.sbin/pppd/cbcp.h new file mode 100644 index 00000000000..14a30e25e7b --- /dev/null +++ b/usr.sbin/pppd/cbcp.h @@ -0,0 +1,28 @@ +/* $OpenBSD: cbcp.h,v 1.1 1996/12/23 13:22:38 mickey Exp $ */ + +#ifndef CBCP_H +#define CBCP_H + +typedef struct cbcp_state { + int us_unit; /* Interface unit number */ + u_char us_id; /* Current id */ + u_char us_allowed; + int us_type; + char *us_number; /* Telefone Number */ +} cbcp_state; + +extern cbcp_state cbcp[]; + +extern struct protent cbcp_protent; + +#define CBCP_MINLEN 4 + +#define CBCP_REQ 1 +#define CBCP_RESP 2 +#define CBCP_ACK 3 + +#define CB_CONF_NO 1 +#define CB_CONF_USER 2 +#define CB_CONF_ADMIN 3 +#define CB_CONF_LIST 4 +#endif diff --git a/usr.sbin/pppd/ccp.c b/usr.sbin/pppd/ccp.c index dab6a1d676a..35d19385240 100644 --- a/usr.sbin/pppd/ccp.c +++ b/usr.sbin/pppd/ccp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ccp.c,v 1.4 1996/07/20 12:02:05 joshd Exp $ */ +/* $OpenBSD: ccp.c,v 1.5 1996/12/23 13:22:38 mickey Exp $ */ /* * ccp.c - PPP Compression Control Protocol. @@ -28,12 +28,14 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: ccp.c,v 1.4 1996/07/20 12:02:05 joshd Exp $"; +static char rcsid[] = "$OpenBSD: ccp.c,v 1.5 1996/12/23 13:22:38 mickey Exp $"; #endif #include <string.h> #include <syslog.h> #include <sys/ioctl.h> +#include <sys/types.h> +#include <net/ppp_defs.h> #include <net/ppp-comp.h> #include "pppd.h" @@ -93,6 +95,7 @@ static void ccp_up __P((fsm *)); static void ccp_down __P((fsm *)); static int ccp_extcode __P((fsm *, int, int, u_char *, int)); static void ccp_rack_timeout __P(()); +static char *method_name __P((ccp_options *, ccp_options *)); static fsm_callbacks ccp_callbacks = { ccp_resetci, @@ -164,7 +167,7 @@ ccp_init(unit) /* * ccp_open - CCP is allowed to come up. */ -void +static void ccp_open(unit) int unit; { @@ -831,7 +834,7 @@ method_name(opt, opt2) } /* - * CCP has come up - inform the kernel driver. + * CCP has come up - inform the kernel driver and log a message. */ static void ccp_up(f) @@ -856,7 +859,7 @@ ccp_up(f) } else syslog(LOG_NOTICE, "%s receive compression enabled", method_name(go, NULL)); - } else + } else if (ANY_COMPRESS(*ho)) syslog(LOG_NOTICE, "%s transmit compression enabled", method_name(ho, NULL)); } @@ -994,7 +997,7 @@ ccp_printpkt(p, plen, printer, arg) * decompression; if it was, we take CCP down, thus disabling * compression :-(, otherwise we issue the reset-request. */ -void +static void ccp_datainput(unit, pkt, len) int unit; u_char *pkt; diff --git a/usr.sbin/pppd/chap.c b/usr.sbin/pppd/chap.c index a91bf2c38fe..8715b87d29b 100644 --- a/usr.sbin/pppd/chap.c +++ b/usr.sbin/pppd/chap.c @@ -1,7 +1,22 @@ -/* $OpenBSD: chap.c,v 1.3 1996/07/20 12:02:06 joshd Exp $ */ +/* $OpenBSD: chap.c,v 1.4 1996/12/23 13:22:39 mickey Exp $ */ /* - * chap.c - Crytographic Handshake Authentication Protocol. + * chap.c - Challenge Handshake Authentication Protocol. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Copyright (c) 1991 Gregory M. Christy. * All rights reserved. @@ -21,7 +36,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: chap.c,v 1.3 1996/07/20 12:02:06 joshd Exp $"; +static char rcsid[] = "$OpenBSD: chap.c,v 1.4 1996/12/23 13:22:39 mickey Exp $"; #endif /* @@ -51,8 +66,7 @@ static void ChapLowerDown __P((int)); static void ChapInput __P((int, u_char *, int)); static void ChapProtocolReject __P((int)); static int ChapPrintPkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void -*)); + void (*) __P((void *, char *, ...)), void *)); struct protent chap_protent = { PPP_CHAP, @@ -435,7 +449,7 @@ ChapReceiveChallenge(cstate, inp, id, len) /* generate MD based on negotiated type */ switch (cstate->resp_type) { - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ + case CHAP_DIGEST_MD5: MD5Init(&mdContext); MD5Update(&mdContext, &cstate->resp_id, 1); MD5Update(&mdContext, secret, secret_len); diff --git a/usr.sbin/pppd/chap.h b/usr.sbin/pppd/chap.h index 2f57d434ed1..a0839748f3e 100644 --- a/usr.sbin/pppd/chap.h +++ b/usr.sbin/pppd/chap.h @@ -1,7 +1,22 @@ -/* $OpenBSD: chap.h,v 1.4 1996/07/20 12:02:06 joshd Exp $ */ +/* $OpenBSD: chap.h,v 1.5 1996/12/23 13:22:39 mickey Exp $ */ /* - * chap.h - Challenge-Handshake Authentication Protocol definitions. + * chap.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Copyright (c) 1991 Gregory M. Christy * All rights reserved. @@ -42,7 +57,7 @@ */ #define MIN_CHALLENGE_LENGTH 32 #define MAX_CHALLENGE_LENGTH 64 -#define MAX_RESPONSE_LENGTH 16 /* sufficient for MD5 */ +#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ /* * Each interface is described by a chap structure. diff --git a/usr.sbin/pppd/demand.c b/usr.sbin/pppd/demand.c index d57f12db57a..dfe8212a729 100644 --- a/usr.sbin/pppd/demand.c +++ b/usr.sbin/pppd/demand.c @@ -1,7 +1,7 @@ -/* $OpenBSD: demand.c,v 1.2 1996/07/20 12:02:07 joshd Exp $ */ +/* $OpenBSD: demand.c,v 1.3 1996/12/23 13:22:40 mickey Exp $ */ /* - * demand.c - Dial on demand support. + * demand.c - Support routines for demand-dialling. * * Copyright (c) 1993 The Australian National University. * All rights reserved. @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: demand.c,v 1.2 1996/07/20 12:02:07 joshd Exp $"; +static char rcsid[] = "$OpenBSD: demand.c,v 1.3 1996/12/23 13:22:40 mickey Exp $"; #endif #include <stdio.h> @@ -38,7 +38,6 @@ static char rcsid[] = "$OpenBSD: demand.c,v 1.2 1996/07/20 12:02:07 joshd Exp $" #include <sys/stat.h> #include <sys/socket.h> #include <net/if.h> -#include <net/bpf.h> #include "pppd.h" #include "fsm.h" @@ -250,10 +249,6 @@ loop_chars(p, n) * decide whether to bring up the link or not, and, if we want * to transmit this frame later, put it on the pending queue. * Return value is 1 if we need to bring up the link, 0 otherwise. - * We assume that the kernel driver has already applied the - * pass_filter, so we won't get packets it rejected. - * We apply the active_filter to see if we want this packet to - * bring up the link. */ int loop_frame(frame, len) @@ -262,12 +257,12 @@ loop_frame(frame, len) { struct packet *pkt; + /* log_packet(frame, len, "from loop: "); */ if (len < PPP_HDRLEN) return 0; if ((PPP_PROTOCOL(frame) & 0x8000) != 0) return 0; /* shouldn't get any of these anyway */ - if (active_filter.bf_len != 0 - && bpf_filter(active_filter.bf_insns, frame, len, len) == 0) + if (!active_packet(frame, len)) return 0; pkt = (struct packet *) malloc(sizeof(struct packet) + len); diff --git a/usr.sbin/pppd/ipcp.c b/usr.sbin/pppd/ipcp.c index 3532480a81b..c0c581702db 100644 --- a/usr.sbin/pppd/ipcp.c +++ b/usr.sbin/pppd/ipcp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipcp.c,v 1.3 1996/07/20 12:02:08 joshd Exp $ */ +/* $OpenBSD: ipcp.c,v 1.4 1996/12/23 13:22:41 mickey Exp $ */ /* * ipcp.c - PPP IP Control Protocol. @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: ipcp.c,v 1.3 1996/07/20 12:02:08 joshd Exp $"; +static char rcsid[] = "$OpenBSD: ipcp.c,v 1.4 1996/12/23 13:22:41 mickey Exp $"; #endif /* @@ -35,9 +35,6 @@ static char rcsid[] = "$OpenBSD: ipcp.c,v 1.3 1996/07/20 12:02:08 joshd Exp $"; #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> #include "pppd.h" #include "fsm.h" @@ -1065,13 +1062,11 @@ ip_check_options() } if (demand && wo->hisaddr == 0) { - fprintf(stderr, "%s: remote IP address required for demand-dialling\n", - progname); + option_error("remote IP address required for demand-dialling\n"); exit(1); } if (demand && wo->accept_remote) { - fprintf(stderr, "%s: ipcp-accept-remote is incompatible with demand\n", - progname); + option_error("ipcp-accept-remote is incompatible with demand\n"); exit(1); } } @@ -1089,10 +1084,10 @@ ip_demand_conf(u) if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) return 0; - if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) - return 0; if (!sifup(u)) return 0; + if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) + return 0; if (wo->default_route) if (sifdefaultroute(u, wo->hisaddr)) default_route_set[u] = 1; @@ -1174,11 +1169,14 @@ ipcp_up(f) * Set IP addresses and (if specified) netmask. */ mask = GetMask(go->ouraddr); + +#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { IPCPDEBUG((LOG_WARNING, "sifaddr failed")); ipcp_close(f->unit, "Interface configuration failed"); return; } +#endif /* bring the interface up for IP */ if (!sifup(f->unit)) { @@ -1187,6 +1185,13 @@ ipcp_up(f) return; } +#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { + IPCPDEBUG((LOG_WARNING, "sifaddr failed")); + ipcp_close(f->unit, "Interface configuration failed"); + return; + } +#endif sifnpmode(f->unit, PPP_IP, NPMODE_PASS); /* assign a default route through the interface if required */ @@ -1408,35 +1413,49 @@ ipcp_printpkt(p, plen, printer, arg) } /* - * ip_active_pkt - see if this IP packet is worth bringing the link up -for. + * ip_active_pkt - see if this IP packet is worth bringing the link up for. * We don't bring the link up for IP fragments or for TCP FIN packets * with no data. */ -#ifndef IP_OFFMASK +#define IP_HDRLEN 20 /* bytes */ #define IP_OFFMASK 0x1fff -#endif +#define IPPROTO_TCP 6 +#define TCP_HDRLEN 20 +#define TH_FIN 0x01 +/* + * We use these macros because the IP header may be at an odd address, + * and some compilers might use word loads to get th_off or ip_hl. + */ + +#define net_short(x) (((x)[0] << 8) + (x)[1]) +#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) +#define get_ipoff(x) net_short((unsigned char *)(x) + 6) +#define get_ipproto(x) (((unsigned char *)(x))[9]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int ip_active_pkt(pkt, len) u_char *pkt; int len; { - struct ip *ip; - struct tcphdr *tcp; + u_char *tcp; int hlen; - if (len < sizeof(struct ip) + PPP_HDRLEN) + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP_HDRLEN) return 0; - ip = (struct ip *) (pkt + PPP_HDRLEN); - if ((ntohs(ip->ip_off) & IP_OFFMASK) != 0) + if ((get_ipoff(pkt) & IP_OFFMASK) != 0) return 0; - if (ip->ip_p != IPPROTO_TCP) + if (get_ipproto(pkt) != IPPROTO_TCP) return 1; - hlen = ip->ip_hl * 4; - if (len < hlen + sizeof(struct tcphdr) + PPP_HDRLEN) + hlen = get_iphl(pkt) * 4; + if (len < hlen + TCP_HDRLEN) return 0; - tcp = (struct tcphdr *) (pkt + PPP_HDRLEN + hlen); - if ((tcp->th_flags & TH_FIN) != 0 && hlen + tcp->th_off * 4 == len) + tcp = pkt + hlen; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) return 0; return 1; } diff --git a/usr.sbin/pppd/ipxcp.c b/usr.sbin/pppd/ipxcp.c index 39f57b36afd..15fec2acbf5 100644 --- a/usr.sbin/pppd/ipxcp.c +++ b/usr.sbin/pppd/ipxcp.c @@ -19,7 +19,7 @@ #ifdef IPX_CHANGE #ifndef lint -static char rcsid[] = "$Id: ipxcp.c,v 1.1 1996/07/20 12:02:09 joshd Exp $"; +static char rcsid[] = "$OpenBSD: ipxcp.c,v 1.2 1996/12/23 13:22:42 mickey Exp $"; #endif /* @@ -428,23 +428,9 @@ ipxcp_addci(f, ucp, lenp) } if (go->neg_router && (go->router & (BIT(0) | BIT(2) | BIT(4)))) { - if (go->router & BIT(0)) { PUTCHAR (IPX_ROUTER_PROTOCOL, ucp); PUTCHAR (CILEN_PROTOCOL, ucp); - PUTSHORT (0, ucp); - } else { - if (go->router & BIT(2)) { - PUTCHAR (IPX_ROUTER_PROTOCOL, ucp); - PUTCHAR (CILEN_PROTOCOL, ucp); - PUTSHORT (2, ucp); - } - - if (go->router & BIT(4)) { - PUTCHAR (IPX_ROUTER_PROTOCOL, ucp); - PUTCHAR (CILEN_PROTOCOL, ucp); - PUTSHORT (4, ucp); - } - } + PUTSHORT (go->router, ucp); } if (go->neg_complete) { @@ -521,20 +507,13 @@ ipxcp_ackci(f, p, len) break; \ } -#define ACKCIPROTO(opt, neg, val, bit) \ - if (neg && (val & BIT(bit))) \ +#define ACKCIPROTO(opt, neg, val) \ + if (neg && p[1] == CILEN_PROTOCOL && len >= p[1] && p[0] == opt) \ { \ - if (len < 2) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_PROTOCOL || citype != opt) \ - break; \ - len -= cilen; \ - if (len < 0) \ - break; \ + INCPTR(2, p); \ + len -= CILEN_PROTOCOL; \ GETSHORT(cishort, p); \ - if (cishort != (bit)) \ + if (cishort != (val)) \ break; \ } /* @@ -544,9 +523,7 @@ ipxcp_ackci(f, p, len) ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router, 0); - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router, 2); - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router, 4); + ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); ACKCICOMPLETE (IPX_COMPLETE, go->neg_complete); /* * This is the end of the record. @@ -700,33 +677,22 @@ ipxcp_rejci(f, p, len) ipxcp_options try; /* options to request next time */ #define REJCINETWORK(opt, neg, val) \ - if (neg) { \ + if (neg && p[1] == CILEN_NETN && len >= p[1] && p[0] == opt) { \ neg = 0; \ - if ((len -= CILEN_NETN) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_NETN || \ - citype != opt) \ - break; \ + INCPTR(2, p); \ + len -= CILEN_NETN; \ GETLONG(cilong, p); \ if (cilong != val) \ break; \ - IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected long opt %d", opt)); \ + IPXCPDEBUG((LOG_INFO,"ipxcp_rejci rejected network 0x%08x", val)); \ } #define REJCICHARS(opt, neg, val, cnt) \ - if (neg) { \ + if (neg && p[1] == cnt + 2 && p[1] >= len && p[0] == opt) { \ int indx, count = cnt; \ neg = 0; \ - len -= (count + 2); \ - if (len < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != (count + 2) || \ - citype != opt) \ - break; \ + INCPTR(2, p); \ + len -= (cnt + 2); \ for (indx = 0; indx < count; ++indx) {\ GETCHAR(cichar, p); \ if (cichar != ((u_char *) &val)[indx]) \ @@ -741,34 +707,23 @@ ipxcp_rejci(f, p, len) #define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen(val)) #define REJCIVOID(opt, neg) \ - if (neg) { \ + if (neg && p[1] == CILEN_VOID && len >= p[1] && p[0] == opt) { \ neg = 0; \ - if ((len -= CILEN_VOID) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || citype != opt) \ - break; \ + INCPTR(2, p); \ + len -= CILEN_VOID; \ IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected void opt %d", opt)); \ } -#define REJCIPROTO(opt, neg, val, bit) \ - if (neg && (val & BIT(bit))) \ +#define REJCIPROTO(opt, neg, val) \ + if (neg && p[1] == CILEN_PROTOCOL && len >= p[1] && p[0] == opt) \ { \ - if (len < 2) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_PROTOCOL || citype != opt) \ - break; \ - len -= cilen; \ - if (len < 0) \ - break; \ + INCPTR(2, p); \ + len -= CILEN_PROTOCOL; \ GETSHORT(cishort, p); \ - if (cishort != (bit)) \ + IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected router proto 0x%04x", cishort)); \ + if ((cishort & val) == 0) \ break; \ - IPXCPDEBUG((LOG_INFO, "ipxcp_rejci rejected router proto %d", bit)); \ - val &= ~BIT(bit); \ + val &= ~cishort; \ if (val == 0) \ neg = 0; \ } @@ -783,9 +738,7 @@ ipxcp_rejci(f, p, len) do { REJCINETWORK (IPX_NETWORK_NUMBER, try.neg_nn, try.our_network); REJCINODE (IPX_NODE_NUMBER, try.neg_node, try.our_node); - REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0); - REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 2); - REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 4); + REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router); REJCINAME (IPX_ROUTER_NAME, try.neg_name, try.name); REJCIVOID (IPX_COMPLETE, try.neg_complete); /* @@ -1163,7 +1116,7 @@ ipxcp_up(f) * /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX */ - ipxcp_script (f, "/etc/ppp/ipx-up"); + ipxcp_script (f, _PATH_IPXUP); } /* @@ -1183,7 +1136,7 @@ ipxcp_down(f) cipxfaddr (f->unit); sifdown(f->unit); - ipxcp_script (f, "/etc/ppp/ipx-down"); + ipxcp_script (f, _PATH_IPXDOWN); } @@ -1269,7 +1222,7 @@ static int ipxcp_printpkt(p, plen, printer, arg) u_char *p; int plen; - void (*printer)(); + void (*printer) __P((void *, char *, ...)); void *arg; { int code, id, len, olen; diff --git a/usr.sbin/pppd/lcp.c b/usr.sbin/pppd/lcp.c index a0dfdcd747d..db600552892 100644 --- a/usr.sbin/pppd/lcp.c +++ b/usr.sbin/pppd/lcp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lcp.c,v 1.3 1996/07/20 12:02:10 joshd Exp $ */ +/* $OpenBSD: lcp.c,v 1.4 1996/12/23 13:22:43 mickey Exp $ */ /* * lcp.c - PPP Link Control Protocol. @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: lcp.c,v 1.3 1996/07/20 12:02:10 joshd Exp $"; +static char rcsid[] = "$OpenBSD: lcp.c,v 1.4 1996/12/23 13:22:43 mickey Exp $"; #endif /* @@ -138,10 +138,12 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL; * Length of each type of configuration option (in octets) */ #define CILEN_VOID 2 +#define CILEN_CHAR 3 #define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */ #define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ #define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ #define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ +#define CILEN_CBCP 3 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ (x) == CONFNAK ? "NAK" : "REJ") @@ -179,6 +181,7 @@ lcp_init(unit) wo->neg_pcompression = 1; wo->neg_accompression = 1; wo->neg_lqr = 0; /* no LQR implementation yet */ + wo->neg_cbcp = 0; ao->neg_mru = 1; ao->mru = MAXMRU; @@ -191,6 +194,11 @@ lcp_init(unit) ao->neg_pcompression = 1; ao->neg_accompression = 1; ao->neg_lqr = 0; /* no LQR implementation yet */ +#ifdef CBCP_SUPPORT + ao->neg_cbcp = 1; +#else + ao->neg_cbcp = 0; +#endif memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); xmit_accm[unit][3] = 0x60000000; @@ -453,6 +461,7 @@ lcp_cilen(f) #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) +#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) /* * NB: we only ask for one of CHAP and UPAP, even if we will * accept either. @@ -462,6 +471,7 @@ lcp_cilen(f) LENCICHAP(go->neg_chap) + LENCISHORT(!go->neg_chap && go->neg_upap) + LENCILQR(go->neg_lqr) + + LENCICBCP(go->neg_cbcp) + LENCILONG(go->neg_magicnumber) + LENCIVOID(go->neg_pcompression) + LENCIVOID(go->neg_accompression)); @@ -511,6 +521,12 @@ lcp_addci(f, ucp, lenp) PUTSHORT(PPP_LQR, ucp); \ PUTLONG(val, ucp); \ } +#define ADDCICHAR(opt, neg, val) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR, ucp); \ + PUTCHAR(val, ucp); \ + } ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, @@ -518,6 +534,7 @@ lcp_addci(f, ucp, lenp) ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); @@ -576,6 +593,19 @@ lcp_ackci(f, p, len) if (cishort != val) \ goto bad; \ } +#define ACKCICHAR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_CHAR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR || \ + citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != val) \ + goto bad; \ + } #define ACKCICHAP(opt, neg, val, digest) \ if (neg) { \ if ((len -= CILEN_CHAP) < 0) \ @@ -628,6 +658,7 @@ lcp_ackci(f, p, len) ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); @@ -699,6 +730,17 @@ lcp_nakci(f, p, len) no.neg = 1; \ code \ } +#define NAKCICHAR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[1] == CILEN_CHAR && \ + p[0] == opt) { \ + len -= CILEN_CHAR; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } #define NAKCISHORT(opt, neg, code) \ if (go->neg && \ len >= CILEN_SHORT && \ @@ -773,7 +815,7 @@ lcp_nakci(f, p, len) GETSHORT(cishort, p); if (cishort == PPP_PAP && cilen == CILEN_SHORT) { /* - * If they are asking for PAP, then they don't want to do CHAP. + * If we were asking for CHAP, they obviously don't want to do it. * If we weren't asking for CHAP, then we were asking for PAP, * in which case this Nak is bad. */ @@ -812,17 +854,6 @@ lcp_nakci(f, p, len) } /* - * Peer shouldn't send Nak for protocol compression or - * address/control compression requests; they should send - * a Reject instead. If they send a Nak, treat it as a Reject. - */ - if (!go->neg_chap ){ - NAKCISHORT(CI_AUTHTYPE, neg_upap, - try.neg_upap = 0; - ); - } - - /* * If they can't cope with our link quality protocol, we'll have * to stop asking for LQR. We haven't got any other protocol. * If they Nak the reporting period, take their value XXX ? @@ -835,6 +866,13 @@ lcp_nakci(f, p, len) ); /* + * Only implementing CBCP...not the rest of the callback options + */ + NAKCICHAR(CI_CALLBACK, neg_cbcp, + try.neg_cbcp = 0; + ); + + /* * Check for a looped-back line. */ NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, @@ -1040,6 +1078,20 @@ lcp_rejci(f, p, len) try.neg = 0; \ LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \ } +#define REJCICBCP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CBCP && \ + p[1] == CILEN_CBCP && \ + p[0] == opt) { \ + len -= CILEN_CBCP; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if (cichar != val) \ + goto bad; \ + try.neg = 0; \ + LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \ + } REJCISHORT(CI_MRU, neg_mru, go->mru); REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); @@ -1048,6 +1100,7 @@ lcp_rejci(f, p, len) REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); } REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); + REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); REJCIVOID(CI_PCOMPRESSION, neg_pcompression); REJCIVOID(CI_ACCOMPRESSION, neg_accompression); @@ -1088,7 +1141,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree) lcp_options *ho = &lcp_hisoptions[f->unit]; lcp_options *ao = &lcp_allowoptions[f->unit]; u_char *cip, *next; /* Pointer to current and next CIs */ - int cilen, citype, cichar;/* Parsed len, type, char value */ + int cilen, citype, cichar; /* Parsed len, type, char value */ u_short cishort; /* Parsed short value */ u_int32_t cilong; /* Parse long value */ int rc = CONFACK; /* Final packet return code */ @@ -1592,6 +1645,20 @@ lcp_printpkt(p, plen, printer, arg) } } break; + case CI_CALLBACK: + if (olen >= CILEN_CHAR) { + p += 2; + printer(arg, "callback "); + GETSHORT(cishort, p); + switch (cishort) { + case CBCP_OPT: + printer(arg, "CBCP"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; case CI_MAGICNUMBER: if (olen == CILEN_LONG) { p += 2; @@ -1663,7 +1730,6 @@ void LcpLinkFailure (f) syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending); syslog(LOG_NOTICE, "Serial link appears to be disconnected."); lcp_close(f->unit, "Peer not responding"); - phase = PHASE_TERMINATE; } } diff --git a/usr.sbin/pppd/lcp.h b/usr.sbin/pppd/lcp.h index e7ad1b3eb19..6c6f7910f2c 100644 --- a/usr.sbin/pppd/lcp.h +++ b/usr.sbin/pppd/lcp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lcp.h,v 1.3 1996/07/20 12:02:11 joshd Exp $ */ +/* $OpenBSD: lcp.h,v 1.4 1996/12/23 13:22:43 mickey Exp $ */ /* * lcp.h - Link Control Protocol definitions. @@ -29,6 +29,7 @@ #define CI_MAGICNUMBER 5 /* Magic Number */ #define CI_PCOMPRESSION 7 /* Protocol Field Compression */ #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ +#define CI_CALLBACK 13 /* callback */ /* * LCP-specific packet types. @@ -37,6 +38,7 @@ #define ECHOREQ 9 /* Echo Request */ #define ECHOREP 10 /* Echo Reply */ #define DISCREQ 11 /* Discard Request */ +#define CBCP_OPT 6 /* Use callback control protocol */ /* * The state of options is described by an lcp_options structure. @@ -53,6 +55,7 @@ typedef struct lcp_options { int neg_pcompression : 1; /* HDLC Protocol Field Compression? */ int neg_accompression : 1; /* HDLC Address/Control Field Compression? */ int neg_lqr : 1; /* Negotiate use of Link Quality Reports */ + int neg_cbcp : 1; /* Negotiate use of CBCP */ u_short mru; /* Value of MRU */ u_char chap_mdtype; /* which MD type (hashing algorithm) */ u_int32_t asyncmap; /* Value of async map */ @@ -82,4 +85,4 @@ extern struct protent lcp_protent; /* Default number of times we receive our magic number from the peer before deciding the link is looped-back. */ -#define DEFLOOPBACKFAIL 5 +#define DEFLOOPBACKFAIL 10 diff --git a/usr.sbin/pppd/main.c b/usr.sbin/pppd/main.c index 374bad88bf7..8d520951a7e 100644 --- a/usr.sbin/pppd/main.c +++ b/usr.sbin/pppd/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.12 1996/12/22 03:29:01 deraadt Exp $ */ +/* $OpenBSD: main.c,v 1.13 1996/12/23 13:22:44 mickey Exp $ */ /* * main.c - Point-to-Point Protocol main module @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: main.c,v 1.12 1996/12/22 03:29:01 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: main.c,v 1.13 1996/12/23 13:22:44 mickey Exp $"; #endif #include <stdio.h> @@ -54,18 +54,18 @@ static char rcsid[] = "$OpenBSD: main.c,v 1.12 1996/12/22 03:29:01 deraadt Exp $ #include "pathnames.h" #include "patchlevel.h" +#ifdef CBCP_SUPPORT +#include "cbcp.h" +#endif + +#if defined(SUNOS4) +extern char *strerror(); +#endif + #ifdef IPX_CHANGE #include "ipxcp.h" #endif /* IPX_CHANGE */ -/* - * If REQ_SYSOPTIONS is defined to 1, pppd will not run unless - * /etc/ppp/options exists. - */ -#ifndef REQ_SYSOPTIONS -#define REQ_SYSOPTIONS 1 -#endif - /* interface vars */ char ifname[IFNAMSIZ]; /* Interface name */ int ifunit; /* Interface unit number */ @@ -76,12 +76,14 @@ static char pidfilename[MAXPATHLEN]; /* name of pid file */ static char default_devnam[MAXPATHLEN]; /* name of default device */ static pid_t pid; /* Our pid */ static uid_t uid; /* Our real user-id */ +static int conn_running; /* we have a [dis]connector running */ int ttyfd = -1; /* Serial port file descriptor */ mode_t tty_mode = -1; /* Original access permissions to tty */ int baud_rate; /* Actual bits/second for serial device */ int hungup; /* terminal has been hung up */ - +int privileged; /* we're running as real uid root */ +int need_holdoff; /* need holdoff period before restarting */ int phase; /* where the link is at */ int kill_link; @@ -91,20 +93,12 @@ int redirect_stderr; /* Connector's stderr should go to file */ u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ -int hungup; /* terminal has been hung up */ static int n_children; /* # child processes still running */ -int baud_rate; /* Actual bits/second for serial device */ - static int locked; /* lock() has succeeded */ char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; -static char *restricted_environ[] = { - "PATH=" _PATH_STDPATH, - NULL -}; - /* Prototypes for procedures local to this file. */ static void cleanup __P((void)); @@ -132,7 +126,7 @@ extern char *getlogin __P((void)); #define O_NONBLOCK O_NDELAY #endif -#ifdef PRIMITIVE_SYSLOG +#ifdef ULTRIX #define setlogmask(x) #endif @@ -145,6 +139,9 @@ struct protent *protocols[] = { &lcp_protent, &pap_protent, &chap_protent, +#ifdef CBCP_SUPPORT + &cbcp_protent, +#endif &ipcp_protent, &ccp_protent, #ifdef IPX_CHANGE @@ -175,7 +172,7 @@ main(argc, argv) strcpy(default_devnam, devnam); /* Initialize syslog facilities */ -#ifdef PRIMITIVE_SYSLOG +#ifdef ULTRIX openlog("pppd", LOG_PID); #else openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); @@ -183,12 +180,13 @@ main(argc, argv) #endif if (gethostname(hostname, MAXNAMELEN) < 0 ) { - syslog(LOG_ERR, "couldn't get hostname: %m"); + option_error("Couldn't get hostname: %m"); die(1); } hostname[MAXNAMELEN-1] = 0; uid = getuid(); + privileged = uid == 0; /* * Initialize to the standard option set, then parse, in order, @@ -200,7 +198,7 @@ main(argc, argv) progname = *argv; - if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) + if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) || !options_from_user()) exit(1); scan_args(argc-1, argv+1); /* look for tty name on command line */ @@ -209,11 +207,20 @@ main(argc, argv) exit(1); if (!ppp_available()) { - fprintf(stderr, no_ppp_msg); + option_error(no_ppp_msg); exit(1); } /* + * Check that we are running as root. + */ + if (geteuid() != 0) { + option_error("must be root to run %s, since it is not setuid-root", + argv[0]); + die(1); + } + + /* * Check that the options given are valid and consistent. */ sys_check_options(); @@ -222,8 +229,7 @@ main(argc, argv) if (protp->check_options != NULL) (*protp->check_options)(); if (demand && connector == 0) { - fprintf(stderr, "%s: connect script required for demand-dialling\n", - progname); + option_error("connect script required for demand-dialling\n"); exit(1); } @@ -370,6 +376,8 @@ main(argc, argv) for (;;) { + need_holdoff = 1; + if (demand) { /* * Don't do anything until we see some activity. @@ -509,7 +517,6 @@ main(argc, argv) get_input(); if (kill_link) { lcp_close(0, "User request"); - phase = PHASE_TERMINATE; kill_link = 0; } if (open_ccp_flag) { @@ -560,11 +567,11 @@ main(argc, argv) } if (!persist) - die(1); + break; if (demand) demand_discard(); - if (holdoff > 0) { + if (holdoff > 0 && need_holdoff) { phase = PHASE_HOLDOFF; TIMEOUT(holdoff_end, NULL, holdoff); do { @@ -690,8 +697,6 @@ connect_time_expired(arg) caddr_t arg; { syslog(LOG_INFO, "Connect time expired"); - - phase = PHASE_TERMINATE; lcp_close(0, "Connect time expired"); /* Close connection */ } @@ -873,6 +878,23 @@ timeleft(tvp) /* + * kill_my_pg - send a signal to our process group, and ignore it ourselves. + */ +static void +kill_my_pg(sig) + int sig; +{ + struct sigaction act, oldact; + + act.sa_handler = SIG_IGN; + act.sa_flags = 0; + sigaction(sig, &act, &oldact); + kill(-getpgrp(), sig); + sigaction(sig, &oldact, NULL); +} + + +/* * hup - Catch SIGHUP signal. * * Indicates that the physical layer has been disconnected. @@ -885,6 +907,9 @@ hup(sig) { syslog(LOG_INFO, "Hangup (SIGHUP)"); kill_link = 1; + if (conn_running) + /* Send the signal to the [dis]connector process(es) also */ + kill_my_pg(sig); } @@ -901,6 +926,9 @@ term(sig) syslog(LOG_INFO, "Terminating on signal %d.", sig); persist = 0; /* don't try to restart */ kill_link = 1; + if (conn_running) + /* Send the signal to the [dis]connector process(es) also */ + kill_my_pg(sig); } @@ -957,6 +985,8 @@ bad_signal(sig) int sig; { syslog(LOG_ERR, "Fatal signal %d", sig); + if (conn_running) + kill_my_pg(SIGTERM); die(1); } @@ -974,9 +1004,11 @@ device_script(program, in, out) int status; int errfd; + conn_running = 1; pid = fork(); if (pid < 0) { + conn_running = 0; syslog(LOG_ERR, "Failed to create child process: %m"); die(1); } @@ -1027,6 +1059,7 @@ device_script(program, in, out) syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); die(1); } + conn_running = 0; return (status == 0 ? 0 : -1); } @@ -1045,6 +1078,7 @@ run_program(prog, args, must_exist) int must_exist; { int pid; + char *nullenv[1]; pid = fork(); if (pid == -1) { @@ -1089,7 +1123,8 @@ run_program(prog, args, must_exist) /* SysV recommends a second fork at this point. */ /* run the program; give it a null environment */ - execve(prog, args, restricted_environ); + nullenv[0] = NULL; + execve(prog, args, nullenv); if (must_exist || errno != ENOENT) syslog(LOG_WARNING, "Can't execute %s: %m", prog); _exit(-1); @@ -1301,7 +1336,11 @@ fmtmsg __V((char *buf, int buflen, char *fmt, ...)) #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int -vfmtmsg(char *buf, int buflen, char *fmt, va_list args) +vfmtmsg(buf, buflen, fmt, args) + char *buf; + int buflen; + char *fmt; + va_list args; { int c, i, n; int width, prec, fillch; @@ -1309,10 +1348,10 @@ vfmtmsg(char *buf, int buflen, char *fmt, va_list args) unsigned long val; char *str, *f, *buf0; unsigned char *p; - va_list a; + void *a; char num[32]; time_t t; - static char hexchars[16] = "0123456789abcdef"; + static char hexchars[] = "0123456789abcdef"; buf0 = buf; --buflen; @@ -1401,7 +1440,11 @@ vfmtmsg(char *buf, int buflen, char *fmt, va_list args) break; case 'r': f = va_arg(args, char *); - a = va_arg(args, va_list); + /* + * XXX We assume a va_list is either a pointer or an array, so + * what gets passed for a va_list is like a void * in some sense. + */ + a = va_arg(args, void *); n = vfmtmsg(buf, buflen + 1, f, a); buf += n; buflen -= n; @@ -1507,4 +1550,3 @@ vfmtmsg(char *buf, int buflen, char *fmt, va_list args) *buf = 0; return buf - buf0; } - 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 */ diff --git a/usr.sbin/pppd/patchlevel.h b/usr.sbin/pppd/patchlevel.h index be9ce8cac2f..dcb8acbf046 100644 --- a/usr.sbin/pppd/patchlevel.h +++ b/usr.sbin/pppd/patchlevel.h @@ -1,7 +1,7 @@ -/* $OpenBSD: patchlevel.h,v 1.3 1996/07/20 12:02:13 joshd Exp $ */ +/* $OpenBSD: patchlevel.h,v 1.4 1996/12/23 13:22:46 mickey Exp $ */ #define PATCHLEVEL 0 #define VERSION "2.3" -#define IMPLEMENTATION "beta1" -#define DATE "24 May 96" +#define IMPLEMENTATION "beta3" +#define DATE "8 Oct 96" diff --git a/usr.sbin/pppd/pathnames.h b/usr.sbin/pppd/pathnames.h index 823076e9881..1879ed453b5 100644 --- a/usr.sbin/pppd/pathnames.h +++ b/usr.sbin/pppd/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.3 1996/07/20 12:02:13 joshd Exp $ */ +/* $OpenBSD: pathnames.h,v 1.4 1996/12/23 13:22:46 mickey Exp $ */ /* * define path names @@ -22,6 +22,7 @@ #define _PATH_TTYOPT "/etc/ppp/options." #define _PATH_CONNERRS "/etc/ppp/connect-errors" #define _PATH_USEROPT ".ppprc" +#define _PATH_PEERFILES "/etc/ppp/peers/" #ifdef IPX_CHANGE #define _PATH_IPXUP "/etc/ppp/ipx-up" diff --git a/usr.sbin/pppd/pppd.8 b/usr.sbin/pppd/pppd.8 index e89171378ff..92cc7dcfe12 100644 --- a/usr.sbin/pppd/pppd.8 +++ b/usr.sbin/pppd/pppd.8 @@ -1,5 +1,5 @@ -.\" $OpenBSD: pppd.8,v 1.6 1996/10/08 01:20:59 michaels Exp $ -.\" manual page [] for pppd 2.0 +.\" $OpenBSD: pppd.8,v 1.8 1996/12/23 13:22:47 mickey Exp $ +.\" manual page [] for pppd 2.3 .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -39,7 +39,8 @@ is prepended if necessary. If no device name is given, or if the name of the controlling terminal is given, .I pppd will use the controlling terminal, and will not fork to put itself in -the background. +the background. This option is privileged if the \fInoauth\fR option is +used. .TP .I <speed> Set the baud rate to <speed> (a decimal number). On systems such as @@ -47,46 +48,57 @@ Set the baud rate to <speed> (a decimal number). On systems such as (e.g. SunOS) allow only a limited set of speeds. .TP .B asyncmap \fI<map> -Set the async character map to <map>. -This map describes which control characters cannot be successfully -received over the serial line. +Set the async character map to <map>. This map describes which +control characters cannot be successfully received over the serial +line. .I pppd will ask the peer to send these characters as a 2-byte escape sequence. -The argument is a 32 bit hex number -with each bit representing a character to escape. +The argument is a 32 bit hex number with each bit representing a character +to escape. Bit 0 (00000001) represents the character 0x00; bit 31 (80000000) represents the character 0x1f or ^_. If multiple \fBasyncmap\fR options are given, the values are ORed together. If no \fBasyncmap\fR option is given, no async character map will be negotiated for the receive direction; the peer should then escape -\fIall\fR control characters. +\fIall\fR control characters. To escape transmitted +characters, use the \fIescape\fR option. .TP .B auth Require the peer to authenticate itself before allowing network packets to be sent or received. .TP +.B call \fIname +Read options from the file /etc/ppp/peers/\fIname\fR. This file may +contain privileged options, such as \fInoauth\fR, even if pppd +is not being run by root. The \fIname\fR string may not begin with / +or include .. as a pathname component. The format of the options file +is described below. +.TP .B connect \fI<p> -Use the executable or shell command specified by \fI<p>\fR to set up the -serial line. This script would typically use the chat(8) program to -dial the modem and start the remote ppp session. +Use the executable or shell command specified by \fI<p>\fR to set +up the serial line. This script would typically use the chat(8) +program to dial the modem and start the remote ppp session. This +option is privileged if the \fBnoauth\fR option is used. .TP .B crtscts Use hardware flow control (i.e. RTS/CTS) to control the flow of data on the serial port. If neither the \fBcrtscts\fR nor the -\fB\-crtscts\fR option is given, the hardware flow control setting for -the serial port is left unchanged. +\fB\-crtscts\fR option is given, the hardware flow control setting +for the serial port is left unchanged. .TP .B defaultroute Add a default route to the system routing tables, using the peer as the gateway, when IPCP negotiation is successfully completed. -This entry is removed when the PPP connection is broken. +This entry is removed when the PPP connection is broken. This option +is privileged if the \fBnodefaultroute\fR option has been specified. .TP -.B disconnect \fI<p> -Run the executable or shell command specified by \fI<p>\fR after +.B disconnect \fIscript +Run the executable or shell command specified by \fIscript\fR after \fIpppd\fR has terminated the link. This script could, for example, issue commands to the modem to cause it to hang up if hardware modem -control signals were not available. +control signals were not available. This option is privileged if the +\fBnoauth\fR option is used. .TP .B escape \fIxx,yy,... Specifies that certain characters should be escaped on transmission @@ -98,8 +110,9 @@ unlike the \fBasyncmap\fR option which only allows control characters to be specified. The characters which may not be escaped are those with hex values 0x20 - 0x3f or 0x5e. .TP -.B file \fI<f> -Read options from file <f> (the format is described below). +.B file \fIname +Read options from file \fIname\fR (the format is described below). +The file must be readable by the user who has invoked pppd. .TP .B lock Specifies that \fIpppd\fR should create a UUCP-style lock file for the @@ -119,15 +132,6 @@ peer requests a smaller value via MRU negotiation, \fIpppd\fR will request that the kernel networking code send data packets of no more than \fIn\fR bytes through the PPP network interface. .TP -.B netmask \fI<n> -Set the interface netmask to <n>, a 32 bit netmask in "decimal dot" -notation (e.g. 255.255.255.0). If this option is given, the value -specified is ORed with the default netmask. The default netmask is -chosen based on the negotiated remote IP address; it is the -appropriate network mask for the class of the remote IP address, ORed -with the netmasks for any non point-to-point network interfaces in the -system which are on the same network. -.TP .B passive Enables the "passive" option in the LCP. With this option, .I pppd @@ -136,13 +140,6 @@ the peer, .I pppd will then just wait passively for a valid LCP packet from the peer (instead of exiting, as it does without this option). -.TP -.B silent -With this option, -.I pppd -will not transmit LCP packets to initiate a connection until a valid -LCP packet is received from the peer (as for the `passive' option with -ancient versions of \fIpppd\fR). .SH OPTIONS .TP .I <local_IP_address>\fB:\fI<remote_IP_address> @@ -150,48 +147,15 @@ Set the local and/or remote interface IP addresses. Either one may be omitted. The IP addresses can be specified with a host name or in decimal dot notation (e.g. 150.234.56.78). The default local address is the (first) IP address of the system (unless the -.B noipdefault +\fInoipdefault\fR option is given). The remote address will be obtained from the peer if not specified in any option. Thus, in simple cases, this option is not required. If a local and/or remote IP address is specified with this option, .I pppd will not accept a different value from the peer in the IPCP -negotiation, unless the -.B ipcp-accept-local -and/or -.B ipcp-accept-remote -options are given, respectively. -.TP -.B -ac -Disable Address/Control compression negotiation (use default, i.e. -address/control field compression disabled). -.TP -.B active-filter \fIfilter-expression -Specifies a packet filter to be applied to data packets to determine -which packets are to be regarded as link activity, and therefore reset -the idle timer, or cause the link to be brought up in demand-dialling -mode. This option is useful in conjunction with the -\fBidle\fR option if there are packets being sent or received -regularly over the link (for example, routing information packets) -which would otherwise prevent the link from ever appearing to be idle. -The \fIfilter-expression\fR syntax is as described for tcpdump(1), -except that qualifiers which are inappropriate for a PPP link, such as -\fBether\fR and \fBarp\fR, are not permitted. Generally the filter -expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. -.TP -.B -all -Don't request or allow negotiation of any options for LCP and IPCP (use -default values). -.TP -.B -am -Disable asyncmap negotiation (use the default asyncmap, i.e. escape -all control characters). -.TP -.B -as \fI<n> -Same as -.B asyncmap \fI<n> +negotiation, unless the \fBipcp-accept-local\fR and/or +\fBipcp-accept-remote\fR options are given, respectively. .TP .B bsdcomp \fInr,nt Request that the peer compress packets that it sends, using the @@ -204,24 +168,6 @@ consume more kernel memory for compression dictionaries. Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables compression in the corresponding direction. .TP -.B \-bsdcomp -Disables BSD-Compress compression; \fBpppd\fR will not request or -agree to compress packets using the BSD-Compress scheme. -.TP -.B -ccp -Disable CCP (Compression Control Protocol) negotiation. This option -should only be required if the peer is buggy and gets confused by -requests from -.I pppd -for CCP negotiation. -.TP -.B +chap -Require the peer to authenticate itself using CHAP [Challenge-Handshake -Authentication Protocol] authentication. -.TP -.B -chap -Don't agree to authenticate using CHAP. -.TP .B chap-interval \fI<n> If this option is given, .I pppd @@ -235,15 +181,6 @@ Set the maximum number of CHAP challenge transmissions to <n> (default Set the CHAP restart interval (retransmission timeout for challenges) to <n> seconds (default 3). .TP -.B -crtscts -Disable hardware flow control (i.e. RTS/CTS) on the serial port. If -neither the \fBcrtscts\fR nor the \fB\-crtscts\fR option is given, -the hardware flow control setting for the serial port is left -unchanged. -.TP -.B -d -Increase debugging level (same as the \fBdebug\fR option). -.TP .B debug Increase debugging level (same as \fB\-d\fR). If this option is given, \fIpppd\fR will log the contents of all @@ -252,10 +189,14 @@ logged through syslog with facility \fIdaemon\fR and level \fIdebug\fR. This information can be directed to a file by setting up /etc/syslog.conf appropriately (see syslog.conf(5)). .TP -.B \-defaultroute -Disable the \fBdefaultroute\fR option. The system administrator who -wishes to prevent users from creating default routes with \fIpppd\fR -can do so by placing this option in the /etc/ppp/options file. +.B default-asyncmap +Disable asyncmap negotiation, forcing all control characters to be +escaped for both the transmit and the receive direction. +.TP +.B default-mru +Disable MRU [Maximum Receive Unit] negotiation. With this option, +pppd will use the default MRU value of 1500 bytes for both the +transmit and receive direction. .TP .B deflate \fInr,nt Request that the peer compress packets that it sends, using the @@ -270,10 +211,6 @@ compression in the corresponding direction. (Note: \fBpppd\fR requests Deflate compression in preference to BSD-Compress if the peer can do either.) .TP -.B \-deflate -Disables Deflate compression; \fBpppd\fR will not request or agree to -compress packets using the Deflate scheme. -.TP .B demand Initiate the link only on demand, i.e. when data traffic is present. With this option, the remote IP address must be specific by the user @@ -285,28 +222,14 @@ When this is completed, \fBpppd\fR will commence passing data packets (i.e., IP packets) across the link. The persist, idle and holdoff options are often useful in conjuction with this option. .TP -.B -detach -Don't fork to become a background process (otherwise -.I pppd -will do so if a serial device other than its controlling terminal is -specified). -.TP -.B ms-dns \fI<addr> -If -.I pppd -is acting as a server for Microsoft Windows clients, this option -allows -.I pppd -to supply one or two DNS (Domain Name Server) addresses to the -clients. The first instance of this option specifies the primary DNS -address; the second instance (if given) specifies the secondary DNS -address. -.TP .B domain \fI<d> Append the domain name <d> to the local host name for authentication purposes. For example, if gethostname() returns the name porsche, but the -fully qualified domain name is porsche.Quotron.COM, you would use the -domain option to set the domain name to Quotron.COM. +fully qualified domain name is porsche.Quotron.COM, you could use the +specify \fIdomain Quotron.COM\fR. Pppd would then use the name +\fIporsche.Quotron.COM\fR for looking up secrets in the secrets file, +and as the default name to send to the peer when authenticating itself +to the peer. This option is privileged. .TP .B holdoff \fI<n> Specifies how many seconds to wait before re-initiating the link after @@ -320,13 +243,6 @@ packets) are being sent or received. If the \fBactive-filter\fR option is given, data packets which are rejected by the specified activity filter also count as the link being idle. .TP -.B -ip -Disable IPCP negotiation and IP communication. This option should -only be required if the peer is buggy and gets confused by requests -from -.I pppd -for IPCP negotiation. -.TP .B ipcp-accept-local With this option, .I pppd @@ -360,12 +276,78 @@ Provides an extra parameter to the ip-up and ip-down scripts. If this option is given, the \fIstring\fR supplied is given as the 6th parameter to those scripts. .TP -.B kdebug \fIn +.B ipx +Enable the IPXCP and IPX protocols. Under Linux, this is the default +condition if your kernel supports IPX. This option is presently only +supported under Linux and OpenBSD. +.TP +.B ipx-network \fI<n> +Set the IPX network number in the IPXCP configure request frame to +\fI<n>\fR, a hexadecimal number (without a leading 0x). There is no +valid default. If this option is not specified, the network number is +obtained from the peer. If the peer does not have the network number, +the IPX protocol will not be started. +.TP +.B ipx-node \fI<n>\fB:\fI<m> +Set the IPX node numbers. The two node numbers are separated from each +other with a colon character. The first number \fI<n>\fR is the local +node number. The second number \fI<m>\fR is the peer's node number. Each +node number is a hexadecimal number, at most 10 digits long. The node +numbers on the ipx-network must be unique. There is no valid +default. If this option is not specified then the node numbers are +obtained from the peer. +.TP +.B ipx-router-name \fI<string> +Set the name of the router. This is a string and is sent to the peer +as information data. +.TP +.B ipx-routing \fI<n> +Set the routing protocol to be received by this option. More than one +instance of \fIipx-routing\fR may be specified. The '\fInone\fR' +option (0) may be specified as the only instance of ipx-routing. The +values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and +\fI4\fR for \fINLSP\fR. +.TP +.B ipxcp-accept-local +Accept the peer's NAK for the node number specified in the ipx-node +option. If a node number was specified, and non-zero, the default is +to insist that the value be used. If you include this option then you +will permit the peer to override the entry of the node number. +.TP +.B ipxcp-accept-network +Accept the peer's NAK for the network number specified in the +ipx-network option. If a network number was specified, and non-zero, the +default is to insist that the value be used. If you include this +option then you will permit the peer to override the entry of the node +number. +.TP +.B ipxcp-accept-remote +Use the peer's network number specified in the configure request +frame. If a node number was specified for the peer and this option was +not specified, the peer will be forced to use the value which you have +specified. +.TP +.B ipxcp-max-configure \fI<n> +Set the maximum number of IPXCP configure request frames which the +system will send to \fI<n>\fR. The default is 10. +.TP +.B ipxcp-max-failure \fI<n> +Set the maximum number of IPXCP NAK frames which the local system will +send before it rejects the options. The default value is 3. +.TP +.B ipxcp-max-terminate \fI<n> +Set the maximum nuber of IPXCP terminate request frames before the +local system considers that the peer is not listening to them. The +default value is 3. +.TP +.B kdebug \fI<n> Enable debugging code in the kernel-level PPP driver. The argument -\fIn\fR is a number which is the sum of the following values: 1 to +\fI<n>\fR is a number which is the sum of the following values: 1 to enable general debug messages, 2 to request that the contents of received packets be printed, and 4 to request that the contents of -transmitted packets be printed. +transmitted packets be printed. On most systems, messages printed by +the kernel are logged by syslog(1) to a file as directed in the +/etc/syslog.conf configuration file. .TP .B lcp-echo-failure \fI<n> If this option is given, \fIpppd\fR will presume the peer to be dead @@ -424,18 +406,72 @@ executing the connect script. On Ultrix, this option implies hardware flow control, as for the \fBcrtscts\fR option. .TP -.B -mn -Disable magic number negotiation. With this option, +.B ms-dns \fI<addr> +If .I pppd -cannot detect a looped-back line. -.TP -.B -mru -Disable MRU [Maximum Receive Unit] negotiation. With this option, -\fIpppd\fR will use the default MRU value of 1500 bytes. +is acting as a server for Microsoft Windows clients, this option +allows +.I pppd +to supply one or two DNS (Domain Name Server) addresses to the +clients. The first instance of this option specifies the primary DNS +address; the second instance (if given) specifies the secondary DNS +address. .TP .B name \fI<n> Set the name of the local system for authentication purposes to <n>. .TP +.B netmask \fI<n> +Set the interface netmask to \fI<n>\fR, a 32 bit netmask in "decimal dot" +notation (e.g. 255.255.255.0). If this option is given, the value +specified is ORed with the default netmask. The default netmask is +chosen based on the negotiated remote IP address; it is the +appropriate network mask for the class of the remote IP address, ORed +with the netmasks for any non point-to-point network interfaces in the +system which are on the same network. +.TP +.B noaccomp +Disable Address/Control compression in both directions (send and +receive). +.TP +.B noauth +Do not require the peer to authenticate itself. This option is +privileged if the \fBauth\fR option is specified in /etc/ppp/options. +.TP +.B nobsdcomp +Disables BSD-Compress compression; +.I pppd +will not request or agree to compress packets using the BSD-Compress scheme. +.TP +.B noccp +Disable CCP (Compression Control Protocol) negotiation. This option +should only be required if the peer is buggy and gets confused by +requests from +.I pppd +for CCP negotiation. +.B nocrtscts +Disable hardware flow control (i.e. RTS/CTS) on the serial port. If +neither the \fBcrtscts\fR nor the \fB\nocrtscts\fR option is given, +the hardware flow control setting for the serial port is left +unchanged. +.B nodefaultroute +Disable the \fBdefaultroute\fR option. The system administrator who +wishes to prevent users from creating default routes with pppd +can do so by placing this option in the /etc/ppp/options file. +.TP +.B nodeflate +Disables Deflate compression; pppd will not request or agree to +compress packets using the Deflate scheme. +.TP +.B nodetach +Don't detach from the controlling terminal. Without this option, if a +serial device other than the terminal on the standard input is +specified, pppd will fork to become a background process. +.TP +.B noip +Disable IPCP negotiation and IP communication. This option should +only be required if the peer is buggy and gets confused by requests +from pppd for IPCP negotiation. +.TP .B noipdefault Disables the default behaviour when no local IP address is specified, which is to determine (if possible) the local IP address from the @@ -443,17 +479,43 @@ hostname. With this option, the peer will have to supply the local IP address during IPCP negotiation (unless it specified explicitly on the command line or in an options file). .TP -.B -p -Same as the -.B passive -option. +.B noipx +Disable the IPXCP and IPX protocols. This option should only be +required if the peer is buggy and gets confused by requests from +.I pppd +for IPXCP negotiation. +.TP +.B nomagic +Disable magic number negotiation. With this option, pppd cannot +detect a looped-back line. This option should only be needed if the +peer is buggy. +.TP +.B nopcomp +Disable protocol field compression negotiation in both the receive and +the transmit direction. .TP -.B +pap -Require the peer to authenticate itself using PAP. +.B nopersist +Exit once a connection has been made and terminated. This is the +default unless the \fIpersist\fR or \fIdemand\fR option has been +specified. .TP -.B -pap -Don't agree to authenticate using PAP. +.B nopredictor1 +Do not accept or agree to Predictor-1 comprssion. .TP +.B noproxyarp +Disable the \fBproxyarp\fR option. The system administrator who +wishes to prevent users from creating proxy ARP entries with pppd can +do so by placing this option in the /etc/ppp/options file. +.TP +.B novj +Disable Van Jacobson style TCP/IP header compression in both the +transmit and the receive direction. +.TP +.B novjccomp +Disable the connection-ID compression option in Van Jacobson style +TCP/IP header compression. With this option, pppd will not omit the +connection-ID byte from Van Jacobson compressed TCP/IP headers, nor +ask the peer to do so. .B papcrypt Indicates that all secrets in the /etc/ppp/pap-secrets file which are used for checking the identity of the peer are encrypted, and thus @@ -474,50 +536,47 @@ Set the maximum time that will wait for the peer to authenticate itself with PAP to <n> seconds (0 means no limit). .TP -.B pass-filter \fIfilter-expression -Specifies a packet filter to applied to data packets being sent or -received to determine which packets should be allowed to pass. -Packets which are rejected by the filter are silently discarded. This -option can be used to provide protection against IP address spoofing -and other attacks. -The \fIfilter-expression\fR syntax is as described for tcpdump(1), -except that qualifiers which are inappropriate for a PPP link, such as -\fBether\fR and \fBarp\fR, are not permitted. Generally the filter -expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. Note that it -is possible to apply different constraints to incoming and outgoing -packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. -.TP -.B -pc -Disable protocol field compression negotiation (use default, i.e. -protocol field compression disabled). -.TP .B persist Do not exit after a connection is terminated; instead try to reopen the connection. .TP +.B predictor1 +Request that the peer compress frames that it sends using Predictor-1 +compression, and agree to compress transmitted frames with Predictor-1 +if requested. This option has no effect unless the kernel driver +supports Predictor-1 compression. +.TP .B proxyarp Add an entry to this system's ARP [Address Resolution Protocol] table with the IP address of the peer and the Ethernet address of this system. .TP -.B \-proxyarp -Disable the \fBproxyarp\fR option. The system administrator who -wishes to prevent users from creating proxy ARP entries with -\fIpppd\fR can do so by placing this option in the /etc/ppp/options -file. -.TP .B remotename \fI<n> Set the assumed name of the remote system for authentication purposes to <n>. .TP -.B +ua \fI<p> -Agree to authenticate using PAP [Password Authentication Protocol] if -requested by the peer, and -use the data in file <p> for the user and password to send to the -peer. The file contains the remote user name, followed by a newline, -followed by the remote password, followed by a newline. This option -is obsolescent. +.B refuse-chap +With this option, pppd will not agree to authenticate itself to the +peer using CHAP. +.TP +.B refuse-pap +With this option, pppd will not agree to authenticate itself to the +peer using PAP. +.TP +.B require-chap +Require the peer to authenticate itself using CHAP [Challenge +Handshake Authentication Protocol] authentication +.TP +.B require-pap +Require the peer to authenticate itself using PAP [Password +Authentication Protocol] authentication. +.TP +.B silent +With this option, +.I pppd +will not transmit LCP packets to initiate a connection until a valid +LCP packet is received from the peer (as for the `passive' option with +ancient versions of \fIpppd\fR). .TP .B usehostname Enforce the use of the hostname as the name of the local system for @@ -529,21 +588,17 @@ option). Set the user name to use for authenticating this machine with the peer using PAP to <u>. .TP -.B -vj -Disable negotiation of Van Jacobson style TCP/IP header compression (use -default, i.e. no compression). -.TP -.B -vjccomp -Disable the connection-ID compression option in Van Jacobson style -TCP/IP header compression. With this option, \fIpppd\fR will not omit -the connection-ID byte from Van Jacobson compressed TCP/IP headers, -nor ask the peer to do so. -.TP .B vj-max-slots \fIn Sets the number of connection slots to be used by the Van Jacobson TCP/IP header compression and decompression code to \fIn\fR, which must be between 2 and 16 (inclusive). .TP +.B welcome \fIscript +Run the executable or shell command specified by \fIscript\fR before +initiating PPP negotiation, after the connect script (if any) has +completed. This option is privileged if the \fBnoauth\fR option is +used. +.TP .B xonxoff Use software flow control (i.e. XON/XOFF) to control the flow of data on the serial port. This option is only implemented on Linux systems @@ -551,12 +606,40 @@ at present. .SH OPTIONS FILES Options can be taken from files as well as the command line. .I pppd -reads options from the files /etc/ppp/options and ~/.ppprc before -looking at the command line. An options file is parsed into a series -of words, delimited by whitespace. Whitespace can be included in a -word by enclosing the word in quotes ("). A backslash (\\) quotes the -following character. A hash (#) starts a comment, which continues -until the end of the line. +reads options from the files /etc/ppp/options, ~/.ppprc and +/etc/ppp/options.\fBttyname\fR (in that order) before processing the +option on the command line. (In fact, the command-line options are +scanned to find the terminal name before the options.\fIttyname\fR +file is read.) In forming the name of the options.\fIttyname\fR file, +the initial /dev/ is removed from the terminal name, and any remaining +/ characters are replaced with dots. +.PP +An options file is parsed into a series of words, delimited by +whitespace. Whitespace can be included in a word by enclosing the +word in quotes ("). A backslash (\\) quotes the following character. +A hash (#) starts a comment, which continues until the end of the +line. There is no restriction on using the \fBfile\fR or \fBcall\fR +options within an options file. +.SH PRIVILEGED OPTIONS +As indicated above, some security-sensitive options are privileged, +which means that they may not be used by an ordinary non-privileged +user running a setuid-root pppd, either on the command line, in the +user's ~/.ppprc file, or in an options file read using the \fBfile\fR +option. Privileged options may be used in /etc/ppp/options file or in +an options file read using the \fBcall\fR option. If pppd is being +run by the root user, privileged options can be used without +restriction. +.PP +The normal way that pppd should be set up is to have the \fBauth\fR +option in the /etc/ppp/options file. (This may become the default in +later releases.) If users wish to use pppd to dial out to a peer +which will refuse to authenticate itself (such as an internet service +provider), the system administrator should create an options file +under /etc/ppp/peers containing the \fBnoauth\fR option, the name of +the serial port to use, and the \fBconnect\fR option (if required), +plus any other appropriate options. In this way, pppd can be set up +to allow non-privileged users to make unauthenticated connections only +to trusted peers. .SH AUTHENTICATION .I pppd provides system administrators with sufficient access control that PPP @@ -590,14 +673,20 @@ directions if desired. .LP A secrets file is parsed into words as for a options file. A secret is specified by a line containing at least 3 words, in the order -client name, server name, secret. Any following words on the same line are -taken to be a list of acceptable IP addresses for that client. If -there are only 3 words on the line, it is assumed that any IP address -is OK; to disallow all IP addresses, use "-". If the secret starts -with an `@', what follows is assumed to be the name of a file from -which to read the secret. A "*" as the client or server name matches -any name. When selecting a secret, \fIpppd\fR takes the best match, i.e. -the match with the fewest wildcards. +client name, server name, secret. Any following words on the same +line are taken to be a list of acceptable IP addresses for that +client. If there are only 3 words on the line, it is assumed that any +IP address is OK; to disallow all IP addresses, use "-". A word +starting with "!" indicates that the specified address is \fInot\fR +acceptable. An address may be followed by "/" and a number \fIn\fR, +to indicate a whole subnet, i.e. all addresses which have the same +value in the most significant \fIn\fR bits. Note that case is +significant in the client and server names and in the secret. +.LP +If the secret starts with an `@', what follows is assumed to be the +name of a file from which to read the secret. A "*" as the client or +server name matches any name. When selecting a secret, \fIpppd\fR takes the +best match, i.e. the match with the fewest wildcards. .LP Thus a secrets file contains both secrets for use in authenticating other hosts, plus secrets which we use for authenticating ourselves to @@ -773,6 +862,23 @@ process. This signal acts as a toggle. .B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others) Process-ID for \fIpppd\fR process on ppp interface unit \fIn\fR. .TP +.B /etc/ppp/auth-up +A program or script which is executed after the remote system +successfully authenticates itself. It is executed with the parameters +.IP +\fIinterface-name peer-name user-name tty-device speed\fR +.IP +and with its standard input, output and error redirected to +/dev/null. This program or script is executed with the real and +effective user-IDs set to root, and with an empty environment. (Note +that this script is not executed if the peer doesn't authenticate +itself, for example when the \fInoauth\fR option is used.) +.TP +.B /etc/ppp/auth-down +A program or script which is executed when the link goes down, if +/etc/ppp/auth-up was previously executed. It is executed in the same +manner with the same parameters as /etc/ppp/auth-up. +.TP .B /etc/ppp/ip-up A program or script which is executed when the link is available for sending and receiving IP packets (that is, IPCP has come up). It is @@ -804,6 +910,45 @@ invoked with the same parameters as the ip-up script, and the same security considerations apply, since it is executed with the same effective and real user-IDs as \fIpppd\fR. .TP +.B /etc/ppp/ipx-up +A program or script which is executed when the link is available for +sending and receiving IPX packets (that is, IPXCP has come up). It is +executed with the parameters +.IP +\fIinterface-name tty-device speed network-number local-IPX-node-address +remote-IPX-node-address local-IPX-routing-protocol remote-IPX-routing-protocol +local-IPX-router-name remote-IPX-router-name ipparam pppd-pid\fR +.IP +and with its standard input, +output and error streams redirected to /dev/null. +.br +.IP +The local-IPX-routing-protocol and remote-IPX-routing-protocol field +may be one of the following: +.IP +NONE to indicate that there is no routing protocol +.br +RIP to indicate that RIP/SAP should be used +.br +NLSP to indicate that Novell NLSP should be used +.br +RIP NLSP to indicate that both RIP/SAP and NLSP should be used +.br +.IP +This program or script is executed with the real and effective +user-IDs set to root, and with an empty environment. This is so +that it can be used to manipulate routes, run privileged daemons (e.g. +\fIripd\fR), etc. Be careful that the contents of the /etc/ppp/ipx-up +and /etc/ppp/ipx-down scripts do not compromise your system's +security. +.TP +.B /etc/ppp/ipx-down +A program or script which is executed when the link is no longer +available for sending and receiving IPX packets. This script can be +used for undoing the effects of the /etc/ppp/ipx-up script. It is +invoked in the same manner and with the same parameters as the ipx-up +script, and the same security considerations apply. +.TP .B /etc/ppp/pap-secrets Usernames, passwords and IP addresses for PAP authentication. .TP diff --git a/usr.sbin/pppd/pppd.h b/usr.sbin/pppd/pppd.h index 61dde417eb0..2aba5212ded 100644 --- a/usr.sbin/pppd/pppd.h +++ b/usr.sbin/pppd/pppd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pppd.h,v 1.3 1996/07/20 12:02:14 joshd Exp $ */ +/* $OpenBSD: pppd.h,v 1.4 1996/12/23 13:22:48 mickey Exp $ */ /* * pppd.h - PPP daemon global declarations. @@ -31,7 +31,6 @@ #include <sys/types.h> /* for u_int32_t, if defined */ #include <sys/time.h> /* for struct timeval */ #include <net/ppp_defs.h> -#include <net/bpf.h> #if __STDC__ #include <stdarg.h> @@ -41,12 +40,11 @@ #define __V(x) (va_alist) va_dcl #endif -#define NUM_PPP 1 /* One PPP interface supported (per process) */ - /* * Limits. */ +#define NUM_PPP 1 /* One PPP interface supported (per process) */ #define MAXWORDLEN 1024 /* max length of word in file (incl null) */ #define MAXARGS 1 /* max # args to a command */ #define MAXNAMELEN 256 /* max length of hostname or name for auth */ @@ -65,8 +63,10 @@ extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ extern int phase; /* Current state of link - see values below */ extern int baud_rate; /* Current link speed in bits/sec */ extern char *progname; /* Name of this program */ -extern int redirect_stderr; /* Connector's stderr should go to file */ -extern char peer_authname[]; /* Authenticated name of peer */ +extern int redirect_stderr;/* Connector's stderr should go to file */ +extern char peer_authname[];/* Authenticated name of peer */ +extern int privileged; /* We were run by real-uid root */ +extern int need_holdoff; /* Need holdoff period after link terminates */ /* * Variables set by command-line options. @@ -85,8 +85,8 @@ extern int nodetach; /* Don't detach from controlling tty */ extern char *connector; /* Script to establish physical link */ extern char *disconnector; /* Script to disestablish physical link */ extern char *welcomer; /* Script to welcome client after connection */ -extern int maxconnect; /* maximum number of seconds for a connection */ -extern char user[]; /* Username for PAP */ +extern int maxconnect; /* Maximum connect time (seconds) */ +extern char user[]; /* Our name for authenticating ourselves */ extern char passwd[]; /* Password for PAP */ extern int auth_required; /* Peer is required to authenticate */ extern int proxyarp; /* Set up proxy ARP entry for peer */ @@ -103,8 +103,6 @@ extern char *ipparam; /* Extra parameter for ip up/down scripts */ extern int cryptpap; /* Others' PAP passwords are encrypted */ extern int idle_time_limit;/* Shut down link if idle for this long */ extern int holdoff; /* Dead time before restarting */ -extern struct bpf_program pass_filter; /* Filter for pkts to pass */ -extern struct bpf_program active_filter; /* Filter for link-active pkts */ extern int refuse_pap; /* Don't wanna auth. ourselves with PAP */ extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */ @@ -117,9 +115,10 @@ extern int refuse_chap; /* Don't wanna auth. ourselves with CHAP */ #define PHASE_DORMANT 2 #define PHASE_ESTABLISH 3 #define PHASE_AUTHENTICATE 4 -#define PHASE_NETWORK 5 -#define PHASE_TERMINATE 6 -#define PHASE_HOLDOFF 7 +#define PHASE_CALLBACK 5 +#define PHASE_NETWORK 6 +#define PHASE_TERMINATE 7 +#define PHASE_HOLDOFF 8 /* * The following struct gives the addresses of procedures to call @@ -231,7 +230,6 @@ void sys_init __P((void)); /* Do system-dependent initialization */ void sys_cleanup __P((void)); /* Restore system state before exiting */ void sys_check_options __P((void)); /* Check options specified */ void sys_close __P((void)); /* Clean up in a child before execing */ -void note_debug_level __P((void)); /* Note change in debug level */ int ppp_available __P((void)); /* Test whether ppp kernel support exists */ void open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ void establish_ppp __P((int)); /* Turn serial port into a ppp interface */ @@ -286,22 +284,39 @@ void unlock __P((void)); /* Delete previously-created lock file */ int daemon __P((int, int)); /* Detach us from terminal session */ int logwtmp __P((char *, char *, char *)); /* Write entry to wtmp file */ -int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); - /* Set filter programs in kernel */ /* Procedures exported from options.c */ int parse_args __P((int argc, char **argv)); /* Parse options from arguments given */ void usage __P((void)); /* Print a usage message */ -int options_from_file __P((char *filename, int must_exist, int check_prot)); +int options_from_file __P((char *filename, int must_exist, int check_prot, + int privileged)); /* Parse options from an options file */ int options_from_user __P((void)); /* Parse options from user's .ppprc */ int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ void scan_args __P((int argc, char **argv)); /* Look for tty name in command-line args */ - int getword __P((FILE *f, char *word, int *newlinep, char *filename)); /* Read a word from a file */ +void option_error __P((char *fmt, ...)); + /* Print an error message about an option */ + +/* + * This structure is used to store information about certain + * options, such as where the option value came from (/etc/ppp/options, + * command line, etc.) and whether it came from a privileged source. + */ + +struct option_info { + int priv; /* was value set by sysadmin? */ + char *source; /* where option came from */ +}; + +extern struct option_info auth_req_info; +extern struct option_info connector_info; +extern struct option_info disconnector_info; +extern struct option_info welcomer_info; +extern struct option_info devnam_info; /* * Inline versions of get/put char/short/long. @@ -432,6 +447,12 @@ int getword __P((FILE *f, char *word, int *newlinep, char *filename)); #define CHAPDEBUG(x) #endif +#ifdef DEBUGIPXCP +#define IPXCPDEBUG(x) if (debug) syslog x +#else +#define IPXCPDEBUG(x) +#endif + #ifndef SIGTYPE #if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) #define SIGTYPE void diff --git a/usr.sbin/pppd/sys-bsd.c b/usr.sbin/pppd/sys-bsd.c index 5512f007ad5..f37ab3bd6e3 100644 --- a/usr.sbin/pppd/sys-bsd.c +++ b/usr.sbin/pppd/sys-bsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys-bsd.c,v 1.4 1996/07/14 00:27:09 downsj Exp $ */ +/* $OpenBSD: sys-bsd.c,v 1.5 1996/12/23 13:22:49 mickey Exp $ */ /* * sys-bsd.c - System-dependent procedures for setting up @@ -23,7 +23,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: sys-bsd.c,v 1.4 1996/07/14 00:27:09 downsj Exp $"; +static char rcsid[] = "$OpenBSD: sys-bsd.c,v 1.5 1996/12/23 13:22:49 mickey Exp $"; #endif /* @@ -57,6 +57,15 @@ static char rcsid[] = "$OpenBSD: sys-bsd.c,v 1.4 1996/07/14 00:27:09 downsj Exp #endif #include "pppd.h" +#include "fsm.h" + +#ifdef IPX_CHANGE +#include <netipx/ipx.h> +#include <netipx/ipx_if.h> +#include "ipxcp.h" +#endif + +#define ok_error(num) ((num)==EIO) static int initdisc = -1; /* Initial TTY discipline for ppp_fd */ static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */ @@ -155,20 +164,6 @@ sys_check_options() /* - * note_debug_level - note a change in the debug level. - */ -void -note_debug_level() -{ - if (debug) { - syslog(LOG_INFO, "Debug turned ON, Level %d", debug); - setlogmask(LOG_UPTO(LOG_DEBUG)); - } else { - setlogmask(LOG_UPTO(LOG_WARNING)); - } -} - -/* * ppp_available - check whether the system has any ppp interfaces * (in fact we check whether we can do an ioctl on ppp0). */ @@ -310,6 +305,102 @@ restore_loop() ppp_fd = loop_slave; } +#ifdef IPX_CHANGE +/* + * sipxfaddr - Config the interface IPX networknumber + */ +int +sipxfaddr(unit, network, node) + int unit; + u_long network; + u_char * node; +{ + int skfd; + int result = 1; + struct sockaddr_ipx ipx_addr; + struct ifreq ifr; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; + + skfd = socket (AF_IPX, SOCK_DGRAM, 0); + if (skfd < 0) { + if (!ok_error (errno)) + syslog (LOG_DEBUG, "socket(AF_IPX): %m(%d)", errno); + result = 0; + } else { + bzero (&ifr, sizeof (ifr)); + strncpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + sipx->sipx_len = sizeof(*sipx); + sipx->sipx_family = AF_IPX; + sipx->sipx_type = ETHERTYPE_II; + sipx->sipx_port = 0; + sipx->sipx_network = htonl (network); + memcpy (sipx->sipx_node, node, IPX_HOSTADDRLEN); + + /* + * Set the IPX device + */ + if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { + result = 0; + if (errno != EEXIST && !ok_error (errno)) { + syslog (LOG_DEBUG, + "ioctl(SIOCAIFADDR, CRTITF): %m(%d)", + errno); + } else { + syslog (LOG_WARNING, + "ioctl(SIOCAIFADDR, CRTITF): Address already exists"); + } + } + close (skfd); + } + + return result; +} + +/* + * cipxfaddr - Clear the information for the IPX network. The IPX routes + * are removed and the device is no longer able to pass IPX + * frames. + */ +int +cipxfaddr(unit) + int unit; +{ + int skfd; + int result = 1; + struct sockaddr_ipx ipx_addr; + struct ifreq ifr; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; + + skfd = socket (AF_IPX, SOCK_DGRAM, 0); + if (skfd < 0) { + if (! ok_error (errno)) + syslog (LOG_DEBUG, "socket(AF_IPX): %m(%d)", errno); + result = 0; + } else { + bzero (&ifr, sizeof (ifr)); + strncpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + sipx->sipx_len = sizeof(*sipx); + sipx->sipx_family = AF_IPX; + sipx->sipx_type = ETHERTYPE_II; + + /* + * Set the IPX device + */ + if (ioctl(skfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { + if (!ok_error (errno)) + syslog (LOG_INFO, + "ioctl(SIOCAIFADDR, IPX_DLTITF): %m(%d)", + errno); + result = 0; + } + close (skfd); + } + + return result; +} +#endif /* * disestablish_ppp - Restore the serial port to normal operation. @@ -645,7 +736,6 @@ get_loop_output() { int rv = 0; int n; - struct ppp_idle idle; while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) { if (loop_chars(inbuf, n)) @@ -659,16 +749,7 @@ get_loop_output() syslog(LOG_ERR, "read from loopback: %m"); die(1); } - if (get_idle_time(0, &idle)) { - /* somebody sent a packet which poked the active filter. */ - /* VJ compression may result in get_loop_output() never - matching the idle filter since it's applied here in user space - after the kernel has compressed the packet. - The kernel applies the active filter before the VJ compression. */ - if (idle.xmit_idle < idle_time_limit) - rv = 1; - SYSDEBUG((LOG_DEBUG, "xmit idle %d", idle.xmit_idle)); - } + return rv; } @@ -826,31 +907,6 @@ get_idle_time(u, ip) /* - * set_filters - transfer the pass and active filters to the kernel. - */ -int -set_filters(pass, active) - struct bpf_program *pass, *active; -{ - int ret = 1; - - if (pass->bf_len > 0) { - if (ioctl(ppp_fd, PPPIOCSPASS, pass) < 0) { - syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m"); - ret = 0; - } - } - if (active->bf_len > 0) { - if (ioctl(ppp_fd, PPPIOCSACTIVE, active) < 0) { - syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m"); - ret = 0; - } - } - return ret; -} - - -/* * sifvjcomp - config tcp header compression */ int @@ -869,7 +925,7 @@ sifvjcomp(u, vjcomp, cidcomp, maxcid) syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); return 0; } - if (ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { + if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); return 0; } @@ -884,7 +940,6 @@ sifup(u) int u; { struct ifreq ifr; - struct npioctl npi; strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { @@ -897,12 +952,6 @@ sifup(u) return 0; } if_is_up = 1; - npi.protocol = PPP_IP; - npi.mode = NPMODE_PASS; - if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) { - syslog(LOG_ERR, "ioctl(set IP mode to PASS): %m"); - return 0; - } return 1; } diff --git a/usr.sbin/pppd/upap.c b/usr.sbin/pppd/upap.c index 5764f86022b..e5ffcbb2212 100644 --- a/usr.sbin/pppd/upap.c +++ b/usr.sbin/pppd/upap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: upap.c,v 1.3 1996/07/20 12:02:14 joshd Exp $ */ +/* $OpenBSD: upap.c,v 1.4 1996/12/23 13:22:49 mickey Exp $ */ /* * upap.c - User/Password Authentication Protocol. @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: upap.c,v 1.3 1996/07/20 12:02:14 joshd Exp $"; +static char rcsid[] = "$OpenBSD: upap.c,v 1.4 1996/12/23 13:22:49 mickey Exp $"; #endif /* @@ -286,18 +286,18 @@ upap_input(unit, inpacket, l) */ inp = inpacket; if (l < UPAP_HEADERLEN) { - UPAPDEBUG((LOG_INFO, "upap_input: rcvd short header.")); + UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.")); return; } GETCHAR(code, inp); GETCHAR(id, inp); GETSHORT(len, inp); if (len < UPAP_HEADERLEN) { - UPAPDEBUG((LOG_INFO, "upap_input: rcvd illegal length.")); + UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.")); return; } if (len > l) { - UPAPDEBUG((LOG_INFO, "upap_input: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.")); return; } len -= UPAP_HEADERLEN; @@ -340,7 +340,7 @@ upap_rauthreq(u, inp, id, len) char *msg; int msglen; - UPAPDEBUG((LOG_INFO, "upap_rauth: Rcvd id %d.", id)); + UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.", id)); if (u->us_serverstate < UPAPSS_LISTEN) return; @@ -362,20 +362,20 @@ upap_rauthreq(u, inp, id, len) * Parse user/passwd. */ if (len < sizeof (u_char)) { - UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.")); return; } GETCHAR(ruserlen, inp); len -= sizeof (u_char) + ruserlen + sizeof (u_char); if (len < 0) { - UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.")); return; } ruser = (char *) inp; INCPTR(ruserlen, inp); GETCHAR(rpasswdlen, inp); if (len < rpasswdlen) { - UPAPDEBUG((LOG_INFO, "upap_rauth: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.")); return; } rpasswd = (char *) inp; @@ -415,7 +415,7 @@ upap_rauthack(u, inp, id, len) u_char msglen; char *msg; - UPAPDEBUG((LOG_INFO, "upap_rauthack: Rcvd id %d.", id)); + UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d.", id)); if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ return; @@ -423,13 +423,13 @@ upap_rauthack(u, inp, id, len) * Parse message. */ if (len < sizeof (u_char)) { - UPAPDEBUG((LOG_INFO, "upap_rauthack: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.")); return; } GETCHAR(msglen, inp); len -= sizeof (u_char); if (len < msglen) { - UPAPDEBUG((LOG_INFO, "upap_rauthack: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.")); return; } msg = (char *) inp; @@ -454,7 +454,7 @@ upap_rauthnak(u, inp, id, len) u_char msglen; char *msg; - UPAPDEBUG((LOG_INFO, "upap_rauthnak: Rcvd id %d.", id)); + UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d.", id)); if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ return; @@ -462,13 +462,13 @@ upap_rauthnak(u, inp, id, len) * Parse message. */ if (len < sizeof (u_char)) { - UPAPDEBUG((LOG_INFO, "upap_rauthnak: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.")); return; } GETCHAR(msglen, inp); len -= sizeof (u_char); if (len < msglen) { - UPAPDEBUG((LOG_INFO, "upap_rauthnak: rcvd short packet.")); + UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.")); return; } msg = (char *) inp; @@ -508,7 +508,7 @@ upap_sauthreq(u) output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); - UPAPDEBUG((LOG_INFO, "upap_sauth: Sent id %d.", u->us_id)); + UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d.", u->us_id)); TIMEOUT(upap_timeout, (caddr_t) u, u->us_timeouttime); ++u->us_transmits; @@ -540,7 +540,7 @@ upap_sresp(u, code, id, msg, msglen) BCOPY(msg, outp, msglen); output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); - UPAPDEBUG((LOG_INFO, "upap_sresp: Sent code %d, id %d.", code, id)); + UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d.", code, id)); } /* @@ -606,7 +606,7 @@ upap_printpkt(p, plen, printer, arg) msg = (char *) (p + 1); p += mlen + 1; len -= mlen + 1; - printer(arg, "msg="); + printer(arg, " "); print_string(msg, mlen, printer, arg); break; } |