From: Paul Mackerras Date: Mon, 24 Jul 2000 14:58:15 +0000 (+0000) Subject: fix allow-ip option, allow @login for secret meaning authenticate against X-Git-Tag: ppp-2.4.7~529 X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=141e4209b6e794a91035fa1cb63ab88fca0fb150 fix allow-ip option, allow @login for secret meaning authenticate against login database, update to 2.4.0b5, update man page for multilink options, fix restoring device permissions --- diff --git a/pppd/auth.c b/pppd/auth.c index 4ca883c..31b082e 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -32,7 +32,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: auth.c,v 1.65 2000/04/15 01:27:10 masputra Exp $" +#define RCSID "$Id: auth.c,v 1.66 2000/07/24 14:58:14 paulus Exp $" #include #include @@ -145,6 +145,8 @@ static enum script_state auth_state = s_down; static enum script_state auth_script_state = s_down; static pid_t auth_script_pid = 0; +static int used_login; /* peer authenticated against login database */ + /* * Option variables. */ @@ -190,6 +192,7 @@ static int setupapfile __P((char **)); static int privgroup __P((char **)); static int set_noauth_addr __P((char **)); static void check_access __P((FILE *, char *)); +static int wordlist_count __P((struct wordlist *)); /* * Authentication-related options. @@ -318,10 +321,10 @@ set_noauth_addr(argv) char **argv; { char *addr = *argv; - int l = strlen(addr); + int l = strlen(addr) + 1; struct wordlist *wp; - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1); + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); if (wp == NULL) novm("allow-ip argument"); wp->word = (char *) (wp + 1); @@ -424,8 +427,8 @@ link_established(unit) * boot it out. */ if (noauth_addrs != NULL) { - set_allowed_addrs(unit, noauth_addrs, NULL); - } else if (!wo->neg_upap || !null_login(unit)) { + set_allowed_addrs(unit, NULL, NULL); + } else if (!wo->neg_upap || uselogin || !null_login(unit)) { warn("peer refused to authenticate: terminating link"); lcp_close(unit, "peer refused to authenticate"); status = EXIT_PEER_AUTH_FAILED; @@ -434,6 +437,7 @@ link_established(unit) } new_phase(PHASE_AUTHENTICATE); + used_login = 0; auth = 0; if (go->neg_chap) { ChapAuthPeer(unit, our_name, go->chap_mdtype); @@ -915,21 +919,29 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) check_access(f, filename); if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename) < 0) { warn("no PAP secret found for %s", user); - } else if (secret[0] != 0) { - /* password given in pap-secrets - must match */ - if ((!cryptpap && strcmp(passwd, secret) == 0) - || strcmp(crypt(passwd, secret), secret) == 0) - ret = UPAP_AUTHACK; - else - warn("PAP authentication failure for %s", user); - } else if (uselogin) { - /* empty password in pap-secrets and login option */ - ret = plogin(user, passwd, msg); - if (ret == UPAP_AUTHNAK) - warn("PAP login failure for %s", user); } else { - /* empty password in pap-secrets and login option not used */ + /* + * If the secret is "@login", it means to check + * the password against the login database. + */ + int login_secret = strcmp(secret, "@login") == 0; ret = UPAP_AUTHACK; + if (uselogin || login_secret) { + /* login option or secret is @login */ + ret = plogin(user, passwd, msg); + if (ret == UPAP_AUTHNAK) + warn("PAP login failure for %s", user); + else + used_login = 1; + } + if (secret[0] != 0 && !login_secret) { + /* password given in pap-secrets - must match */ + if ((cryptpap || strcmp(passwd, secret) != 0) + && strcmp(crypt(passwd, secret), secret) != 0) { + ret = UPAP_AUTHNAK; + warn("PAP authentication failure for %s", user); + } + } } fclose(f); } @@ -1426,7 +1438,7 @@ set_allowed_addrs(unit, addrs, opts) struct wordlist *opts; { int n; - struct wordlist *ap, **pap; + struct wordlist *ap, **plink; struct permitted_ip *ip; char *ptr_word, *ptr_mask; struct hostent *hp; @@ -1445,14 +1457,18 @@ set_allowed_addrs(unit, addrs, opts) /* * Count the number of IP addresses given. */ - for (n = 0, pap = &addrs; (ap = *pap) != NULL; pap = &ap->next) - ++n; + n = wordlist_count(addrs) + wordlist_count(noauth_addrs); if (n == 0) return; ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); if (ip == 0) return; + /* temporarily append the noauth_addrs list to addrs */ + for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) + ; + *plink = noauth_addrs; + n = 0; for (ap = addrs; ap != NULL; ap = ap->next) { /* "-" means no addresses authorized, "*" means any address allowed */ @@ -1542,6 +1558,7 @@ set_allowed_addrs(unit, addrs, opts) if (~mask == 0 && suggested_ip == 0) suggested_ip = a; } + *plink = NULL; ip[n].permit = 0; /* make the last entry forbid all addresses */ ip[n].base = 0; /* to terminate the list */ @@ -1731,25 +1748,26 @@ scan_authfile(f, client, server, secret, addrs, opts, filename) if (newline) continue; - /* - * Special syntax: @filename means read secret from file. - */ - if (word[0] == '@') { - strlcpy(atfile, word+1, sizeof(atfile)); - if ((sf = fopen(atfile, "r")) == NULL) { - warn("can't open indirect secret file %s", atfile); - continue; - } - check_access(sf, atfile); - if (!getword(sf, word, &xxx, atfile)) { - warn("no secret in indirect secret file %s", atfile); + if (secret != NULL) { + /* + * Special syntax: @/pathname means read secret from file. + */ + if (word[0] == '@' && word[1] == '/') { + strlcpy(atfile, word+1, sizeof(atfile)); + if ((sf = fopen(atfile, "r")) == NULL) { + warn("can't open indirect secret file %s", atfile); + continue; + } + check_access(sf, atfile); + if (!getword(sf, word, &xxx, atfile)) { + warn("no secret in indirect secret file %s", atfile); + fclose(sf); + continue; + } fclose(sf); - continue; } - fclose(sf); - } - if (secret != NULL) strlcpy(lsecret, word, sizeof(lsecret)); + } /* * Now read address authorization info and make a wordlist. @@ -1805,6 +1823,20 @@ scan_authfile(f, client, server, secret, addrs, opts, filename) return best_flag; } +/* + * wordlist_count - return the number of items in a wordlist + */ +static int +wordlist_count(wp) + struct wordlist *wp; +{ + int n; + + for (n = 0; wp != NULL; wp = wp->next) + ++n; + return n; +} + /* * free_wordlist - release memory allocated for a wordlist. */ diff --git a/pppd/multilink.c b/pppd/multilink.c index da8b33a..23f0fa0 100644 --- a/pppd/multilink.c +++ b/pppd/multilink.c @@ -129,7 +129,6 @@ mp_join_bundle() epdisc_to_str(&ho->endpoint)); if (bundle_name) p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); - dbglog("bundle_id = %s", bundle_id+7); /* * For demand mode, we only need to configure the bundle @@ -360,12 +359,10 @@ str_to_epdisc(ep, str) if (i == 0 || str[i] != 0) return 0; set_ip_epdisc(ep, addr); - dbglog("str_to_epdisc -> %s", epdisc_to_str(ep)); return 1; } if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { ep->length = 6; - dbglog("str_to_epdisc -> %s", epdisc_to_str(ep)); return 1; } @@ -388,7 +385,6 @@ str_to_epdisc(ep, str) if (*str != 0 || (ep->class == EPD_MAC && l != 6)) return 0; ep->length = l; - dbglog("str_to_epdisc -> %s", epdisc_to_str(ep)); return 1; } diff --git a/pppd/patchlevel.h b/pppd/patchlevel.h index 0fc28cb..e0b1625 100644 --- a/pppd/patchlevel.h +++ b/pppd/patchlevel.h @@ -1,6 +1,6 @@ -/* $Id: patchlevel.h,v 1.48 2000/07/06 11:17:02 paulus Exp $ */ +/* $Id: patchlevel.h,v 1.49 2000/07/24 14:58:14 paulus Exp $ */ #define PATCHLEVEL 0 #define VERSION "2.4" -#define IMPLEMENTATION "b4" -#define DATE "6 July 2000" +#define IMPLEMENTATION "b5" +#define DATE "20 July 2000" diff --git a/pppd/pppd.8 b/pppd/pppd.8 index 359403d..d4b3df4 100644 --- a/pppd/pppd.8 +++ b/pppd/pppd.8 @@ -1,5 +1,5 @@ .\" manual page [] for pppd 2.3 -.\" $Id: pppd.8,v 1.51 1999/12/23 01:29:11 paulus Exp $ +.\" $Id: pppd.8,v 1.52 2000/07/24 14:58:15 paulus Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -298,6 +298,22 @@ specify \fIdomain Quotron.COM\fR. Pppd would then use the name and as the default name to send to the peer when authenticating itself to the peer. This option is privileged. .TP +.B endpoint \fI +Sets the endpoint discriminator sent by the local machine to the peer +during multilink negotiation to \fI\fR. The default is to use +the MAC address of the first ethernet interface on the system, if any, +otherwise the IPv4 address corresponding to the hostname, if any, +provided it is not in the multicast or locally-assigned IP address +ranges, or the localhost address. The endpoint discriminator can be +the string \fBnull\fR or of the form \fItype\fR:\fIvalue\fR, where +type is a decimal number or one of the strings \fBlocal\fR, \fBIP\fR, +\fBMAC\fR, \fBmagic\fR, or \fBphone\fR. The value is an IP address in +dotted-decimal notation for the \fBIP\fR type, or a string of bytes in +hexadecimal, separated by periods or colons for the other types. For +the MAC type, the value may also be the name of an ethernet or similar +network interface. This option is currently only available under +Linux. +.TP .B hide-password When logging the contents of PAP packets, this option causes pppd to exclude the password string from the log. This is the default. @@ -524,6 +540,23 @@ signal briefly when the connection is terminated and before executing the connect script. On Ultrix, this option implies hardware flow control, as for the \fIcrtscts\fR option. .TP +.B mp +Enables the use of PPP multilink; this is an alias for the `multilink' +option. This option is currently only available under Linux. +.TP +.B mpshortseq +Enables the use of short (12-bit) sequence numbers in multilink +headers, as opposed to 24-bit sequence numbers. This option is only +available under Linux, and only has any effect if multilink is +enabled (see the multilink option). +.TP +.B mrru \fIn +Sets the Maximum Reconstructed Receive Unit to \fIn\fR. The MRRU is +the maximum size for a received packet on a multilink bundle, and is +analogous to the MRU for the individual links. This option is +currently only available under Linux, and only has any effect if +multilink is enabled (see the multilink option). +.TP .B ms-dns \fI If pppd is acting as a server for Microsoft Windows clients, this option allows pppd to supply one or two DNS (Domain Name Server) @@ -539,6 +572,14 @@ Internet Name Services) server addresses to the clients. The first instance of this option specifies the primary WINS address; the second instance (if given) specifies the secondary WINS address. .TP +.B multilink +Enables the use of the PPP multilink protocol. If the peer also +supports multilink, then this link can become part of a bundle between +the local system and the peer. If there is an existing bundle to the +peer, pppd will join this link to that bundle, otherwise pppd will +create a new bundle. See the MULTILINK section below. This option is +currently only available under Linux. +.TP .B name \fIname Set the name of the local system for authentication purposes to \fIname\fR. This is a privileged option. With this option, pppd will @@ -601,6 +642,11 @@ 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 noendpoint +Disables pppd from sending an endpoint discriminator to the peer or +accepting one from the peer (see the MULTILINK section below). This +option should only be required if the peer is buggy. +.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 @@ -630,11 +676,26 @@ settings. .B nolog Do not send log messages to a file or file descriptor. This option cancels the \fBlogfd\fR and \fBlogfile\fR options. +.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 nomp +Disables the use of PPP multilink. This option is currently only +available under Linux. +.TP +.B nompshortseq +Disables the use of short (12-bit) sequence numbers in the PPP +multilink protocol, forcing the use of 24-bit sequence numbers. This +option is currently only available under Linux, and only has any +effect if multilink is enabled. +.TP +.B nomultilink +Disables the use of PPP multilink. This option is currently only +available under Linux. +.TP .B nopcomp Disable protocol field compression negotiation in both the receive and the transmit direction. @@ -1063,6 +1124,39 @@ IP address assignment), pppd has to change the interface IP addresses to the negotiated addresses. This may disrupt existing connections, and the use of demand dialling with peers that do dynamic IP address assignment is not recommended. +.SH MULTILINK +Multilink PPP provides the capability to combine two or more PPP links +between a pair of machines into a single `bundle', which appears as a +single virtual PPP link which has the combined bandwidth of the +individual links. Currently, multilink PPP is only supported under +Linux. +.LP +Pppd detects that the link it is controlling is connected to the same +peer as another link using the peer's endpoint discriminator and the +authenticated identity of the peer (if it authenticates itself). The +endpoint discriminator is a block of data which is hopefully unique +for each peer. Several types of data can be used, including +locally-assigned strings of bytes, IP addresses, MAC addresses, +randomly strings of bytes, or E-164 phone numbers. The endpoint +discriminator sent to the peer by pppd can be set using the endpoint +option. +.LP +In circumstances the peer may send no endpoint discriminator or a +non-unique value. The optional bundle option adds an extra string +which is added to the peer's endpoint discriminator and authenticated +identity when matching up links to be joined together in a bundle. +The bundle option can also be used to allow the establishment of +multiple bundles between the local system and the peer. Pppd uses a +TDB database in /var/run/pppd.tdb to match up links. +.LP +Assuming that multilink is enabled and the peer is willing to +negotiate multilink, then when pppd is invoked to bring up the first +link to the peer, it will detect that no other link is connected to +the peer and create a new bundle, that is, another ppp network +interface unit. When another pppd is invoked to bring up another link +to the peer, it will detect the existing bundle and join its link to +it. Currently, if the first pppd terminates (for example, because of +a hangup or a received signal) the bundle is destroyed. .SH EXAMPLES .LP The following examples assume that the /etc/ppp/options file contains diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index f25e6c3..154f2a7 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -442,8 +442,9 @@ int establish_ppp (int tty_fd) */ set_ppp_fd (tty_fd); if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) { - if ( ! ok_error (errno)) - fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); + if (ok_error (errno)) + goto err; + fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); } /* Check that we got the same unit again. */ if (looped && x != ifunit) diff --git a/pppd/tty.c b/pppd/tty.c index 751bfad..d9ba1bb 100644 --- a/pppd/tty.c +++ b/pppd/tty.c @@ -20,7 +20,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: tty.c,v 1.2 2000/07/06 11:17:03 paulus Exp $" +#define RCSID "$Id: tty.c,v 1.3 2000/07/24 14:58:15 paulus Exp $" #include #include @@ -331,6 +331,7 @@ int connect_tty() if (!persist || err != EINTR) return -1; } + real_ttyfd = ttyfd; if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) warn("Couldn't reset non-blocking mode on device: %m"); @@ -356,7 +357,6 @@ int connect_tty() */ set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0) || initializer != NULL)); - real_ttyfd = ttyfd; } /*