fix allow-ip option, allow @login for secret meaning authenticate against
authorPaul Mackerras <paulus@samba.org>
Mon, 24 Jul 2000 14:58:15 +0000 (14:58 +0000)
committerPaul Mackerras <paulus@samba.org>
Mon, 24 Jul 2000 14:58:15 +0000 (14:58 +0000)
login database, update to 2.4.0b5, update man page for multilink options,
fix restoring device permissions

pppd/auth.c
pppd/multilink.c
pppd/patchlevel.h
pppd/pppd.8
pppd/sys-linux.c
pppd/tty.c

index 4ca883ca8b7081d4a1437466bf1f5d2e3a249d24..31b082e9089a15c1ba713ff09371233ef548940e 100644 (file)
@@ -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 <stdio.h>
 #include <stddef.h>
@@ -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.
  */
index da8b33a40c418b638eafb206bdcf818f6bba36be..23f0fa084962a4ffb7baa345919f58b9b2ab6068 100644 (file)
@@ -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;
 }
 
index 0fc28cbbb353da105ea9cdad6bdf1483b59a247c..e0b1625607510664358f89a6dda8fab61821c7e9 100644 (file)
@@ -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"
index 359403df549f0d1919e4e4086efda47107aa9838..d4b3df4bd26cfa67511792bebb99b2bc76e28a93 100644 (file)
@@ -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<epdisc>
+Sets the endpoint discriminator sent by the local machine to the peer
+during multilink negotiation to \fI<epdisc>\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<addr>
 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
index f25e6c3c393dc70dac0300b8ac1f270dd1273fe3..154f2a74b552613b5928c7c4fad70372e4aa8868 100644 (file)
@@ -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)
index 751bfadb5a5261fc220f480d8cf7fa398708d07e..d9ba1bb1d0289e7a8befd10a2d6a5fa4dcb10f7f 100644 (file)
@@ -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 <stdio.h>
 #include <ctype.h>
@@ -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;
        }
 
        /*