upstream commit

Allow ListenAddress, Port and AddressFamily in any
 order.  bz#68, ok djm@, jmc@ (for the man page bit).
This commit is contained in:
dtucker@openbsd.org 2015-04-29 03:48:56 +00:00 committed by Damien Miller
parent c1d5bcf1aa
commit 531a57a389
3 changed files with 60 additions and 21 deletions

View 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 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved * All rights reserved
@ -78,6 +78,8 @@ initialize_server_options(ServerOptions *options)
/* Standard Options */ /* Standard Options */
options->num_ports = 0; options->num_ports = 0;
options->ports_from_cmdline = 0; options->ports_from_cmdline = 0;
options->queued_listen_addrs = NULL;
options->num_queued_listens = 0;
options->listen_addrs = NULL; options->listen_addrs = NULL;
options->address_family = -1; options->address_family = -1;
options->num_host_key_files = 0; options->num_host_key_files = 0;
@ -205,6 +207,8 @@ fill_default_server_options(ServerOptions *options)
/* No certificates by default */ /* No certificates by default */
if (options->num_ports == 0) if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT; options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
if (options->listen_addrs == NULL) if (options->listen_addrs == NULL)
add_listen_addr(options, NULL, 0); add_listen_addr(options, NULL, 0);
if (options->pid_file == NULL) if (options->pid_file == NULL)
@ -591,10 +595,6 @@ add_listen_addr(ServerOptions *options, char *addr, int port)
{ {
u_int i; 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) if (port == 0)
for (i = 0; i < options->num_ports; i++) for (i = 0; i < options->num_ports; i++)
add_one_listen_addr(options, addr, options->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; 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 * struct connection_info *
get_connection_info(int populate, int use_dns) 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 */ /* ignore ports from configfile if cmdline specifies ports */
if (options->ports_from_cmdline) if (options->ports_from_cmdline)
return 0; 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) if (options->num_ports >= MAX_PORTS)
fatal("%s line %d: too many ports.", fatal("%s line %d: too many ports.",
filename, linenum); filename, linenum);
@ -994,7 +1036,7 @@ process_server_config_line(ServerOptions *options, char *line,
/* check for bare IPv6 address: no "[]" and 2 or more ":" */ /* check for bare IPv6 address: no "[]" and 2 or more ":" */
if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
&& strchr(p+1, ':') != NULL) { && strchr(p+1, ':') != NULL) {
add_listen_addr(options, arg, 0); queue_listen_addr(options, arg, 0);
break; break;
} }
p = hpdelim(&arg); p = hpdelim(&arg);
@ -1007,16 +1049,13 @@ process_server_config_line(ServerOptions *options, char *line,
else if ((port = a2port(arg)) <= 0) else if ((port = a2port(arg)) <= 0)
fatal("%s line %d: bad port number", filename, linenum); fatal("%s line %d: bad port number", filename, linenum);
add_listen_addr(options, p, port); queue_listen_addr(options, p, port);
break; break;
case sAddressFamily: case sAddressFamily:
intptr = &options->address_family; intptr = &options->address_family;
multistate_ptr = multistate_addressfamily; multistate_ptr = multistate_addressfamily;
if (options->listen_addrs != NULL)
fatal("%s line %d: address family must be specified "
"before ListenAddress.", filename, linenum);
parse_multistate: parse_multistate:
arg = strdelim(&cp); arg = strdelim(&cp);
if (!arg || *arg == '\0') if (!arg || *arg == '\0')
@ -1951,6 +1990,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
if (bad_options > 0) if (bad_options > 0)
fatal("%s: terminating, %d bad configuration options", fatal("%s: terminating, %d bad configuration options",
filename, bad_options); filename, bad_options);
process_queued_listen_addrs(options);
} }
static const char * static const char *

View 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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -58,7 +58,9 @@ typedef struct {
u_int num_ports; u_int num_ports;
u_int ports_from_cmdline; u_int ports_from_cmdline;
int ports[MAX_PORTS]; /* Port number to listen on. */ 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. */ struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
int address_family; /* Address family used by the server. */ int address_family; /* Address family used by the server. */
char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */ char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" 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 $ .\" $OpenBSD: sshd_config.5,v 1.200 2015/04/29 03:48:56 dtucker Exp $
.Dd $Mdocdate: April 28 2015 $ .Dd $Mdocdate: April 29 2015 $
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -830,16 +830,13 @@ The following forms may be used:
If If
.Ar port .Ar port
is not specified, is not specified,
sshd will listen on the address and all prior sshd will listen on the address and all
.Cm Port .Cm Port
options specified. options specified.
The default is to listen on all local addresses. The default is to listen on all local addresses.
Multiple Multiple
.Cm ListenAddress .Cm ListenAddress
options are permitted. options are permitted.
Additionally, any
.Cm Port
options must precede this option for non-port qualified addresses.
.It Cm LoginGraceTime .It Cm LoginGraceTime
The server disconnects after this time if the user has not The server disconnects after this time if the user has not
successfully logged in. successfully logged in.