upstream commit
Add optional rdomain qualifier to sshd_config's ListenAddress option to allow listening on a different rdomain(4), e.g. ListenAddress 0.0.0.0 rdomain 4 Upstream-ID: 24b6622c376feeed9e9be8b9605e593695ac9091
This commit is contained in:
parent
b9903ee8ee
commit
acf559e1cf
19
channels.c
19
channels.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: channels.c,v 1.375 2017/09/24 13:45:34 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.376 2017/10/25 00:15:35 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1668,19 +1668,6 @@ port_open_helper(struct ssh *ssh, Channel *c, char *rtype)
|
|||
free(local_ipaddr);
|
||||
}
|
||||
|
||||
static void
|
||||
channel_set_reuseaddr(int fd)
|
||||
{
|
||||
int on = 1;
|
||||
|
||||
/*
|
||||
* Set socket options.
|
||||
* Allow local port reuse in TIME_WAIT.
|
||||
*/
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
|
||||
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
|
||||
{
|
||||
|
@ -3368,7 +3355,7 @@ channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
|
|||
continue;
|
||||
}
|
||||
|
||||
channel_set_reuseaddr(sock);
|
||||
set_reuseaddr(sock);
|
||||
if (ai->ai_family == AF_INET6)
|
||||
sock_set_v6only(sock);
|
||||
|
||||
|
@ -4439,7 +4426,7 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
|
|||
if (ai->ai_family == AF_INET6)
|
||||
sock_set_v6only(sock);
|
||||
if (x11_use_localhost)
|
||||
channel_set_reuseaddr(sock);
|
||||
set_reuseaddr(sock);
|
||||
if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
debug2("%s: bind port %d: %.100s", __func__,
|
||||
port, strerror(errno));
|
||||
|
|
40
misc.c
40
misc.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: misc.c,v 1.116 2017/10/24 19:41:45 millert Exp $ */
|
||||
/* $OpenBSD: misc.c,v 1.117 2017/10/25 00:15:35 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
|
||||
|
@ -167,6 +167,44 @@ set_nodelay(int fd)
|
|||
error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
|
||||
}
|
||||
|
||||
/* Allow local port reuse in TIME_WAIT */
|
||||
int
|
||||
set_reuseaddr(int fd)
|
||||
{
|
||||
int on = 1;
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
|
||||
error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set routing table */
|
||||
int
|
||||
set_rdomain(int fd, const char *name)
|
||||
{
|
||||
int rtable;
|
||||
const char *errstr;
|
||||
|
||||
if (name == NULL)
|
||||
return 0; /* default table */
|
||||
|
||||
rtable = (int)strtonum(name, 0, 255, &errstr);
|
||||
if (errstr != NULL) {
|
||||
/* Shouldn't happen */
|
||||
error("Invalid routing domain \"%s\": %s", name, errstr);
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RTABLE,
|
||||
&rtable, sizeof(rtable)) == -1) {
|
||||
error("Failed to set routing domain %d on fd %d: %s",
|
||||
rtable, fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Characters considered whitespace in strsep calls. */
|
||||
#define WHITESPACE " \t\r\n"
|
||||
#define QUOTE "\""
|
||||
|
|
4
misc.h
4
misc.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: misc.h,v 1.65 2017/10/23 05:08:00 djm Exp $ */
|
||||
/* $OpenBSD: misc.h,v 1.66 2017/10/25 00:15:35 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -48,6 +48,8 @@ char *strdelim(char **);
|
|||
int set_nonblock(int);
|
||||
int unset_nonblock(int);
|
||||
void set_nodelay(int);
|
||||
int set_reuseaddr(int);
|
||||
int set_rdomain(int, const char *);
|
||||
int a2port(const char *);
|
||||
int a2tun(const char *, int *);
|
||||
char *put_host_port(const char *, u_short);
|
||||
|
|
231
servconf.c
231
servconf.c
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* $OpenBSD: servconf.c,v 1.314 2017/10/05 15:52:03 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.315 2017/10/25 00:15:35 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -15,10 +15,16 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#ifdef HAVE_NET_ROUTE_H
|
||||
#include <net/route.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
|
@ -58,8 +64,10 @@
|
|||
#include "myproposal.h"
|
||||
#include "digest.h"
|
||||
|
||||
static void add_listen_addr(ServerOptions *, char *, int);
|
||||
static void add_one_listen_addr(ServerOptions *, char *, int);
|
||||
static void add_listen_addr(ServerOptions *, const char *,
|
||||
const char *, int);
|
||||
static void add_one_listen_addr(ServerOptions *, const char *,
|
||||
const char *, int);
|
||||
|
||||
/* Use of privilege separation or not */
|
||||
extern int use_privsep;
|
||||
|
@ -81,6 +89,7 @@ initialize_server_options(ServerOptions *options)
|
|||
options->queued_listen_addrs = NULL;
|
||||
options->num_queued_listens = 0;
|
||||
options->listen_addrs = NULL;
|
||||
options->num_listen_addrs = 0;
|
||||
options->address_family = -1;
|
||||
options->num_host_key_files = 0;
|
||||
options->num_host_cert_files = 0;
|
||||
|
@ -252,7 +261,7 @@ fill_default_server_options(ServerOptions *options)
|
|||
if (options->address_family == -1)
|
||||
options->address_family = AF_UNSPEC;
|
||||
if (options->listen_addrs == NULL)
|
||||
add_listen_addr(options, NULL, 0);
|
||||
add_listen_addr(options, NULL, NULL, 0);
|
||||
if (options->pid_file == NULL)
|
||||
options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE);
|
||||
if (options->login_grace_time == -1)
|
||||
|
@ -658,23 +667,51 @@ derelativise_path(const char *path)
|
|||
}
|
||||
|
||||
static void
|
||||
add_listen_addr(ServerOptions *options, char *addr, int port)
|
||||
add_listen_addr(ServerOptions *options, const char *addr,
|
||||
const char *rdomain, int port)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (port == 0)
|
||||
for (i = 0; i < options->num_ports; i++)
|
||||
add_one_listen_addr(options, addr, options->ports[i]);
|
||||
else
|
||||
add_one_listen_addr(options, addr, port);
|
||||
if (port > 0)
|
||||
add_one_listen_addr(options, addr, rdomain, port);
|
||||
else {
|
||||
for (i = 0; i < options->num_ports; i++) {
|
||||
add_one_listen_addr(options, addr, rdomain,
|
||||
options->ports[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_one_listen_addr(ServerOptions *options, char *addr, int port)
|
||||
add_one_listen_addr(ServerOptions *options, const char *addr,
|
||||
const char *rdomain, int port)
|
||||
{
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char strport[NI_MAXSERV];
|
||||
int gaierr;
|
||||
u_int i;
|
||||
|
||||
/* Find listen_addrs entry for this rdomain */
|
||||
for (i = 0; i < options->num_listen_addrs; i++) {
|
||||
if (rdomain == NULL && options->listen_addrs[i].rdomain == NULL)
|
||||
break;
|
||||
if (rdomain == NULL || options->listen_addrs[i].rdomain == NULL)
|
||||
continue;
|
||||
if (strcmp(rdomain, options->listen_addrs[i].rdomain) == 0)
|
||||
break;
|
||||
}
|
||||
if (i >= options->num_listen_addrs) {
|
||||
/* No entry for this rdomain; allocate one */
|
||||
if (i >= INT_MAX)
|
||||
fatal("%s: too many listen addresses", __func__);
|
||||
options->listen_addrs = xrecallocarray(options->listen_addrs,
|
||||
options->num_listen_addrs, options->num_listen_addrs + 1,
|
||||
sizeof(*options->listen_addrs));
|
||||
i = options->num_listen_addrs++;
|
||||
if (rdomain != NULL)
|
||||
options->listen_addrs[i].rdomain = xstrdup(rdomain);
|
||||
}
|
||||
/* options->listen_addrs[i] points to the addresses for this rdomain */
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = options->address_family;
|
||||
|
@ -687,8 +724,37 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
|
|||
ssh_gai_strerror(gaierr));
|
||||
for (ai = aitop; ai->ai_next; ai = ai->ai_next)
|
||||
;
|
||||
ai->ai_next = options->listen_addrs;
|
||||
options->listen_addrs = aitop;
|
||||
ai->ai_next = options->listen_addrs[i].addrs;
|
||||
options->listen_addrs[i].addrs = aitop;
|
||||
}
|
||||
|
||||
/* Returns nonzero if the routing domain name is valid */
|
||||
static int
|
||||
valid_rdomain(const char *name)
|
||||
{
|
||||
const char *errstr;
|
||||
long long num;
|
||||
struct rt_tableinfo info;
|
||||
int mib[6];
|
||||
size_t miblen = sizeof(mib);
|
||||
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
|
||||
num = strtonum(name, 0, 255, &errstr);
|
||||
if (errstr != NULL)
|
||||
return 0;
|
||||
|
||||
/* Check whether the table actually exists */
|
||||
memset(mib, 0, sizeof(mib));
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[4] = NET_RT_TABLE;
|
||||
mib[5] = (int)num;
|
||||
if (sysctl(mib, 6, &info, &miblen, NULL, 0) == -1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -696,18 +762,19 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port)
|
|||
* and AddressFamily options.
|
||||
*/
|
||||
static void
|
||||
queue_listen_addr(ServerOptions *options, char *addr, int port)
|
||||
queue_listen_addr(ServerOptions *options, const char *addr,
|
||||
const char *rdomain, 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++;
|
||||
struct queued_listenaddr *qla;
|
||||
|
||||
options->queued_listen_addrs = xrecallocarray(
|
||||
options->queued_listen_addrs,
|
||||
options->num_queued_listens, options->num_queued_listens + 1,
|
||||
sizeof(*options->queued_listen_addrs));
|
||||
qla = &options->queued_listen_addrs[options->num_queued_listens++];
|
||||
qla->addr = xstrdup(addr);
|
||||
qla->port = port;
|
||||
qla->rdomain = rdomain == NULL ? NULL : xstrdup(rdomain);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -717,6 +784,7 @@ static void
|
|||
process_queued_listen_addrs(ServerOptions *options)
|
||||
{
|
||||
u_int i;
|
||||
struct queued_listenaddr *qla;
|
||||
|
||||
if (options->num_ports == 0)
|
||||
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
|
||||
|
@ -724,15 +792,13 @@ process_queued_listen_addrs(ServerOptions *options)
|
|||
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;
|
||||
qla = &options->queued_listen_addrs[i];
|
||||
add_listen_addr(options, qla->addr, qla->rdomain, qla->port);
|
||||
free(qla->addr);
|
||||
free(qla->rdomain);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1127,20 +1193,33 @@ 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) {
|
||||
queue_listen_addr(options, arg, 0);
|
||||
break;
|
||||
}
|
||||
p = hpdelim(&arg);
|
||||
if (p == NULL)
|
||||
fatal("%s line %d: bad address:port usage",
|
||||
filename, linenum);
|
||||
p = cleanhostname(p);
|
||||
if (arg == NULL)
|
||||
port = 0;
|
||||
else if ((port = a2port(arg)) <= 0)
|
||||
fatal("%s line %d: bad port number", filename, linenum);
|
||||
p = arg;
|
||||
} else {
|
||||
p = hpdelim(&arg);
|
||||
if (p == NULL)
|
||||
fatal("%s line %d: bad address:port usage",
|
||||
filename, linenum);
|
||||
p = cleanhostname(p);
|
||||
if (arg == NULL)
|
||||
port = 0;
|
||||
else if ((port = a2port(arg)) <= 0)
|
||||
fatal("%s line %d: bad port number",
|
||||
filename, linenum);
|
||||
}
|
||||
/* Optional routing table */
|
||||
arg2 = NULL;
|
||||
if ((arg = strdelim(&cp)) != NULL) {
|
||||
if (strcmp(arg, "rdomain") != 0 ||
|
||||
(arg2 = strdelim(&cp)) == NULL)
|
||||
fatal("%s line %d: bad ListenAddress syntax",
|
||||
filename, linenum);
|
||||
if (!valid_rdomain(arg2))
|
||||
fatal("%s line %d: bad routing domain",
|
||||
filename, linenum);
|
||||
}
|
||||
|
||||
queue_listen_addr(options, p, port);
|
||||
queue_listen_addr(options, p, arg2, port);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -2251,45 +2330,61 @@ dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
dump_config(ServerOptions *o)
|
||||
static char *
|
||||
format_listen_addrs(struct listenaddr *la)
|
||||
{
|
||||
u_int i;
|
||||
int ret;
|
||||
int r;
|
||||
struct addrinfo *ai;
|
||||
char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
|
||||
char addr[NI_MAXHOST], port[NI_MAXSERV];
|
||||
char *laddr1 = xstrdup(""), *laddr2 = NULL;
|
||||
|
||||
/* these are usually at the top of the config */
|
||||
for (i = 0; i < o->num_ports; i++)
|
||||
printf("port %d\n", o->ports[i]);
|
||||
dump_cfg_fmtint(sAddressFamily, o->address_family);
|
||||
|
||||
/*
|
||||
* ListenAddress must be after Port. add_one_listen_addr pushes
|
||||
* addresses onto a stack, so to maintain ordering we need to
|
||||
* print these in reverse order.
|
||||
*/
|
||||
for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
|
||||
if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
|
||||
for (ai = la->addrs; ai; ai = ai->ai_next) {
|
||||
if ((r = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
|
||||
sizeof(addr), port, sizeof(port),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
|
||||
error("getnameinfo failed: %.100s",
|
||||
(ret != EAI_SYSTEM) ? gai_strerror(ret) :
|
||||
strerror(errno));
|
||||
} else {
|
||||
laddr2 = laddr1;
|
||||
if (ai->ai_family == AF_INET6)
|
||||
xasprintf(&laddr1, "listenaddress [%s]:%s\n%s",
|
||||
addr, port, laddr2);
|
||||
else
|
||||
xasprintf(&laddr1, "listenaddress %s:%s\n%s",
|
||||
addr, port, laddr2);
|
||||
free(laddr2);
|
||||
error("getnameinfo: %.100s", ssh_gai_strerror(r));
|
||||
continue;
|
||||
}
|
||||
laddr2 = laddr1;
|
||||
if (ai->ai_family == AF_INET6) {
|
||||
xasprintf(&laddr1, "listenaddress [%s]:%s%s%s\n%s",
|
||||
addr, port,
|
||||
la->rdomain == NULL ? "" : " rdomain ",
|
||||
la->rdomain == NULL ? "" : la->rdomain,
|
||||
laddr2);
|
||||
} else {
|
||||
xasprintf(&laddr1, "listenaddress %s:%s%s%s\n%s",
|
||||
addr, port,
|
||||
la->rdomain == NULL ? "" : " rdomain ",
|
||||
la->rdomain == NULL ? "" : la->rdomain,
|
||||
laddr2);
|
||||
}
|
||||
free(laddr2);
|
||||
}
|
||||
return laddr1;
|
||||
}
|
||||
|
||||
void
|
||||
dump_config(ServerOptions *o)
|
||||
{
|
||||
char *s;
|
||||
u_int i;
|
||||
|
||||
/* these are usually at the top of the config */
|
||||
for (i = 0; i < o->num_ports; i++)
|
||||
printf("port %d\n", o->ports[i]);
|
||||
dump_cfg_fmtint(sAddressFamily, o->address_family);
|
||||
|
||||
for (i = 0; i < o->num_listen_addrs; i++) {
|
||||
s = format_listen_addrs(&o->listen_addrs[i]);
|
||||
printf("%s", s);
|
||||
free(s);
|
||||
}
|
||||
printf("%s", laddr1);
|
||||
free(laddr1);
|
||||
|
||||
/* integer arguments */
|
||||
#ifdef USE_PAM
|
||||
|
|
25
servconf.h
25
servconf.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: servconf.h,v 1.127 2017/10/05 15:52:03 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.128 2017/10/25 00:15:35 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -51,14 +51,31 @@
|
|||
struct ssh;
|
||||
struct fwd_perm_list;
|
||||
|
||||
/*
|
||||
* Used to store addresses from ListenAddr directives. These may be
|
||||
* incomplete, as they may specify addresses that need to be merged
|
||||
* with any ports requested by ListenPort.
|
||||
*/
|
||||
struct queued_listenaddr {
|
||||
char *addr;
|
||||
int port; /* <=0 if unspecified */
|
||||
char *rdomain;
|
||||
};
|
||||
|
||||
/* Resolved listen addresses, grouped by optional routing domain */
|
||||
struct listenaddr {
|
||||
char *rdomain;
|
||||
struct addrinfo *addrs;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u_int num_ports;
|
||||
u_int ports_from_cmdline;
|
||||
int ports[MAX_PORTS]; /* Port number to listen on. */
|
||||
struct queued_listenaddr *queued_listen_addrs;
|
||||
u_int num_queued_listens;
|
||||
char **queued_listen_addrs;
|
||||
int *queued_listen_ports;
|
||||
struct addrinfo *listen_addrs; /* Addresses for server to listen. */
|
||||
struct listenaddr *listen_addrs;
|
||||
u_int num_listen_addrs;
|
||||
int address_family; /* Address family used by the server. */
|
||||
|
||||
char **host_key_files; /* Files containing host keys. */
|
||||
|
|
45
sshd.c
45
sshd.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshd.c,v 1.493 2017/10/05 15:52:03 djm Exp $ */
|
||||
/* $OpenBSD: sshd.c,v 1.494 2017/10/25 00:15:35 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1015,13 +1015,13 @@ server_accept_inetd(int *sock_in, int *sock_out)
|
|||
* Listen for TCP connections
|
||||
*/
|
||||
static void
|
||||
server_listen(void)
|
||||
listen_on_addrs(struct listenaddr *la)
|
||||
{
|
||||
int ret, listen_sock, on = 1;
|
||||
int ret, listen_sock;
|
||||
struct addrinfo *ai;
|
||||
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
|
||||
|
||||
for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
|
||||
for (ai = la->addrs; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||
continue;
|
||||
if (num_listen_socks >= MAX_LISTEN_SOCKS)
|
||||
|
@ -1051,13 +1051,13 @@ server_listen(void)
|
|||
close(listen_sock);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Set socket options.
|
||||
* Allow local port reuse in TIME_WAIT.
|
||||
*/
|
||||
if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
&on, sizeof(on)) == -1)
|
||||
error("setsockopt SO_REUSEADDR: %s", strerror(errno));
|
||||
/* Socket options */
|
||||
set_reuseaddr(listen_sock);
|
||||
if (la->rdomain != NULL &&
|
||||
set_rdomain(listen_sock, la->rdomain) == -1) {
|
||||
close(listen_sock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only communicate in IPv6 over AF_INET6 sockets. */
|
||||
if (ai->ai_family == AF_INET6)
|
||||
|
@ -1079,9 +1079,28 @@ server_listen(void)
|
|||
if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
|
||||
fatal("listen on [%s]:%s: %.100s",
|
||||
ntop, strport, strerror(errno));
|
||||
logit("Server listening on %s port %s.", ntop, strport);
|
||||
logit("Server listening on %s port %s%s%s.",
|
||||
ntop, strport,
|
||||
la->rdomain == NULL ? "" : " rdomain ",
|
||||
la->rdomain == NULL ? "" : la->rdomain);
|
||||
}
|
||||
freeaddrinfo(options.listen_addrs);
|
||||
}
|
||||
|
||||
static void
|
||||
server_listen(void)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < options.num_listen_addrs; i++) {
|
||||
listen_on_addrs(&options.listen_addrs[i]);
|
||||
freeaddrinfo(options.listen_addrs[i].addrs);
|
||||
free(options.listen_addrs[i].rdomain);
|
||||
memset(&options.listen_addrs[i], 0,
|
||||
sizeof(options.listen_addrs[i]));
|
||||
}
|
||||
free(options.listen_addrs);
|
||||
options.listen_addrs = NULL;
|
||||
options.num_listen_addrs = 0;
|
||||
|
||||
if (!num_listen_socks)
|
||||
fatal("Cannot bind any address.");
|
||||
|
|
|
@ -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.255 2017/10/13 16:50:45 jmc Exp $
|
||||
.Dd $Mdocdate: October 13 2017 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.256 2017/10/25 00:15:35 djm Exp $
|
||||
.Dd $Mdocdate: October 25 2017 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -909,31 +909,48 @@ The following forms may be used:
|
|||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar host | Ar IPv4_addr | Ar IPv6_addr
|
||||
.Ar hostname | Ar address
|
||||
.Sm on
|
||||
.Oo rdomain Ar domain Oc
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar host | Ar IPv4_addr : Ar port
|
||||
.Ar hostname : Ar port
|
||||
.Sm on
|
||||
.Oo rdomain Ar domain Oc
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Ar IPv4_address : Ar port
|
||||
.Sm on
|
||||
.Oo rdomain Ar domain Oc
|
||||
.It
|
||||
.Cm ListenAddress
|
||||
.Sm off
|
||||
.Oo
|
||||
.Ar host | Ar IPv6_addr Oc : Ar port
|
||||
.Ar hostname | address Oc : Ar port
|
||||
.Sm on
|
||||
.Oo rdomain Ar domain Oc
|
||||
.El
|
||||
.Pp
|
||||
The optional
|
||||
.Cm rdomain
|
||||
qualifier requests
|
||||
.Xr sshd 8
|
||||
listen in an explicit routing domain.
|
||||
If
|
||||
.Ar port
|
||||
is not specified,
|
||||
sshd will listen on the address and all
|
||||
.Cm Port
|
||||
options specified.
|
||||
The default is to listen on all local addresses.
|
||||
The default is to listen on all local addresses on the current default
|
||||
routing domain.
|
||||
Multiple
|
||||
.Cm ListenAddress
|
||||
options are permitted.
|
||||
For more information on routing domains, see
|
||||
.Xr rdomain 4.
|
||||
.It Cm LoginGraceTime
|
||||
The server disconnects after this time if the user has not
|
||||
successfully logged in.
|
||||
|
|
Loading…
Reference in New Issue