]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream commit
authordtucker@openbsd.org <dtucker@openbsd.org>
Wed, 29 Apr 2015 03:48:56 +0000 (03:48 +0000)
committerDamien Miller <djm@mindrot.org>
Wed, 29 Apr 2015 08:20:32 +0000 (18:20 +1000)
Allow ListenAddress, Port and AddressFamily in any
 order.  bz#68, ok djm@, jmc@ (for the man page bit).

servconf.c
servconf.h
sshd_config.5

index 8d56a309b2cc646a438dc61f4e22f16f639133f6..29457b8335637ad9ecbdc528830af1b6ead743e8 100644 (file)
@@ -1,5 +1,5 @@
 
-/* $OpenBSD: servconf.c,v 1.265 2015/04/27 21:42:48 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.266 2015/04/29 03:48:56 dtucker Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -78,6 +78,8 @@ initialize_server_options(ServerOptions *options)
        /* Standard Options */
        options->num_ports = 0;
        options->ports_from_cmdline = 0;
+       options->queued_listen_addrs = NULL;
+       options->num_queued_listens = 0;
        options->listen_addrs = NULL;
        options->address_family = -1;
        options->num_host_key_files = 0;
@@ -205,6 +207,8 @@ fill_default_server_options(ServerOptions *options)
        /* No certificates by default */
        if (options->num_ports == 0)
                options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
+       if (options->address_family == -1)
+               options->address_family = AF_UNSPEC;
        if (options->listen_addrs == NULL)
                add_listen_addr(options, NULL, 0);
        if (options->pid_file == NULL)
@@ -591,10 +595,6 @@ add_listen_addr(ServerOptions *options, char *addr, int port)
 {
        u_int i;
 
-       if (options->num_ports == 0)
-               options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
-       if (options->address_family == -1)
-               options->address_family = AF_UNSPEC;
        if (port == 0)
                for (i = 0; i < options->num_ports; i++)
                        add_one_listen_addr(options, addr, options->ports[i]);
@@ -624,6 +624,51 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
        options->listen_addrs = aitop;
 }
 
+/*
+ * Queue a ListenAddress to be processed once we have all of the Ports
+ * and AddressFamily options.
+ */
+static void
+queue_listen_addr(ServerOptions *options, char *addr, int port)
+{
+       options->queued_listen_addrs = xreallocarray(
+           options->queued_listen_addrs, options->num_queued_listens + 1,
+           sizeof(addr));
+       options->queued_listen_ports = xreallocarray(
+           options->queued_listen_ports, options->num_queued_listens + 1,
+           sizeof(port));
+       options->queued_listen_addrs[options->num_queued_listens] =
+           xstrdup(addr);
+       options->queued_listen_ports[options->num_queued_listens] = port;
+       options->num_queued_listens++;
+}
+
+/*
+ * Process queued (text) ListenAddress entries.
+ */
+static void
+process_queued_listen_addrs(ServerOptions *options)
+{
+       u_int i;
+
+       if (options->num_ports == 0)
+               options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
+       if (options->address_family == -1)
+               options->address_family = AF_UNSPEC;
+
+       for (i = 0; i < options->num_queued_listens; i++) {
+               add_listen_addr(options, options->queued_listen_addrs[i],
+                   options->queued_listen_ports[i]);
+               free(options->queued_listen_addrs[i]);
+               options->queued_listen_addrs[i] = NULL;
+       }
+       free(options->queued_listen_addrs);
+       options->queued_listen_addrs = NULL;
+       free(options->queued_listen_ports);
+       options->queued_listen_ports = NULL;
+       options->num_queued_listens = 0;
+}
+
 struct connection_info *
 get_connection_info(int populate, int use_dns)
 {
@@ -940,9 +985,6 @@ process_server_config_line(ServerOptions *options, char *line,
                /* ignore ports from configfile if cmdline specifies ports */
                if (options->ports_from_cmdline)
                        return 0;
-               if (options->listen_addrs != NULL)
-                       fatal("%s line %d: ports must be specified before "
-                           "ListenAddress.", filename, linenum);
                if (options->num_ports >= MAX_PORTS)
                        fatal("%s line %d: too many ports.",
                            filename, linenum);
@@ -994,7 +1036,7 @@ process_server_config_line(ServerOptions *options, char *line,
                /* check for bare IPv6 address: no "[]" and 2 or more ":" */
                if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
                    && strchr(p+1, ':') != NULL) {
-                       add_listen_addr(options, arg, 0);
+                       queue_listen_addr(options, arg, 0);
                        break;
                }
                p = hpdelim(&arg);
@@ -1007,16 +1049,13 @@ process_server_config_line(ServerOptions *options, char *line,
                else if ((port = a2port(arg)) <= 0)
                        fatal("%s line %d: bad port number", filename, linenum);
 
-               add_listen_addr(options, p, port);
+               queue_listen_addr(options, p, port);
 
                break;
 
        case sAddressFamily:
                intptr = &options->address_family;
                multistate_ptr = multistate_addressfamily;
-               if (options->listen_addrs != NULL)
-                       fatal("%s line %d: address family must be specified "
-                           "before ListenAddress.", filename, linenum);
  parse_multistate:
                arg = strdelim(&cp);
                if (!arg || *arg == '\0')
@@ -1951,6 +1990,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
        if (bad_options > 0)
                fatal("%s: terminating, %d bad configuration options",
                    filename, bad_options);
+       process_queued_listen_addrs(options);
 }
 
 static const char *
index 9922f0c8caf3e530fb2df8a7a6e20b69c23b327a..38520f47629de41eca5eebc2f001be87fe93b7b3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.116 2015/01/13 07:39:19 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.117 2015/04/29 03:48:56 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -58,7 +58,9 @@ typedef struct {
        u_int   num_ports;
        u_int   ports_from_cmdline;
        int     ports[MAX_PORTS];       /* Port number to listen on. */
-       char   *listen_addr;            /* Address on which the server listens. */
+       u_int   num_queued_listens;
+       char   **queued_listen_addrs;
+       int    *queued_listen_ports;
        struct addrinfo *listen_addrs;  /* Addresses on which the server listens. */
        int     address_family;         /* Address family used by the server. */
        char   *host_key_files[MAX_HOSTKEYS];   /* Files containing host keys. */
index 33e401170c974f5d23fad7769d5702da08d63ea3..562dad3560085c94667b665de01ffe81ce50eb60 100644 (file)
@@ -33,8 +33,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd_config.5,v 1.199 2015/04/28 13:47:38 jmc Exp $
-.Dd $Mdocdate: April 28 2015 $
+.\" $OpenBSD: sshd_config.5,v 1.200 2015/04/29 03:48:56 dtucker Exp $
+.Dd $Mdocdate: April 29 2015 $
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
@@ -830,16 +830,13 @@ The following forms may be used:
 If
 .Ar port
 is not specified,
-sshd will listen on the address and all prior
+sshd will listen on the address and all
 .Cm Port
 options specified.
 The default is to listen on all local addresses.
 Multiple
 .Cm ListenAddress
 options are permitted.
-Additionally, any
-.Cm Port
-options must precede this option for non-port qualified addresses.
 .It Cm LoginGraceTime
 The server disconnects after this time if the user has not
 successfully logged in.