upstream commit

add sshd_config RDomain keyword to place sshd and the
subsequent user session (including the shell and any TCP/IP forwardings) into
the specified rdomain(4)

ok markus@

Upstream-ID: be2358e86346b5cacf20d90f59f980b87d1af0f5
This commit is contained in:
djm@openbsd.org 2017-10-25 00:17:08 +00:00 committed by Damien Miller
parent acf559e1cf
commit 35eb33fb95
8 changed files with 104 additions and 10 deletions

20
misc.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.c,v 1.117 2017/10/25 00:15:35 djm Exp $ */
/* $OpenBSD: misc.c,v 1.118 2017/10/25 00:17:08 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@ -180,7 +180,23 @@ set_reuseaddr(int fd)
return 0;
}
/* Set routing table */
/* Get/set routing domain */
char *
get_rdomain(int fd)
{
int rtable;
char *ret;
socklen_t len = sizeof(rtable);
if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) {
error("Failed to get routing domain for fd %d: %s",
fd, strerror(errno));
return NULL;
}
xasprintf(&ret, "%d", rtable);
return ret;
}
int
set_rdomain(int fd, const char *name)
{

3
misc.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: misc.h,v 1.66 2017/10/25 00:15:35 djm Exp $ */
/* $OpenBSD: misc.h,v 1.67 2017/10/25 00:17:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -49,6 +49,7 @@ int set_nonblock(int);
int unset_nonblock(int);
void set_nodelay(int);
int set_reuseaddr(int);
char *get_rdomain(int);
int set_rdomain(int, const char *);
int a2port(const char *);
int a2tun(const char *, int *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.265 2017/10/13 21:13:54 djm Exp $ */
/* $OpenBSD: packet.c,v 1.266 2017/10/25 00:17:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -557,6 +557,18 @@ ssh_local_port(struct ssh *ssh)
return ssh->local_port;
}
/* Returns the routing domain of the input socket, or NULL if unavailable */
const char *
ssh_packet_rdomain_in(struct ssh *ssh)
{
if (ssh->rdomain_in != NULL)
return ssh->rdomain_in;
if (!ssh_packet_connection_is_on_socket(ssh))
return NULL;
ssh->rdomain_in = get_rdomain(ssh->state->connection_in);
return ssh->rdomain_in;
}
/* Closes the connection and clears and frees internal data structures. */
static void

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.82 2017/09/12 06:32:07 djm Exp $ */
/* $OpenBSD: packet.h,v 1.83 2017/10/25 00:17:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -61,6 +61,7 @@ struct ssh {
int remote_port;
char *local_ipaddr;
int local_port;
char *rdomain_in;
/* Optional preamble for log messages (e.g. username) */
char *log_preamble;
@ -162,6 +163,7 @@ const char *ssh_remote_ipaddr(struct ssh *);
int ssh_remote_port(struct ssh *);
const char *ssh_local_ipaddr(struct ssh *);
int ssh_local_port(struct ssh *);
const char *ssh_packet_rdomain_in(struct ssh *);
void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, u_int32_t);
time_t ssh_packet_get_rekey_timeout(struct ssh *);

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.c,v 1.315 2017/10/25 00:15:35 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.316 2017/10/25 00:17:08 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -91,6 +91,7 @@ initialize_server_options(ServerOptions *options)
options->listen_addrs = NULL;
options->num_listen_addrs = 0;
options->address_family = -1;
options->routing_domain = NULL;
options->num_host_key_files = 0;
options->num_host_cert_files = 0;
options->host_key_agent = NULL;
@ -406,6 +407,7 @@ fill_default_server_options(ServerOptions *options)
CLEAR_ON_NONE(options->authorized_principals_file);
CLEAR_ON_NONE(options->adm_forced_command);
CLEAR_ON_NONE(options->chroot_directory);
CLEAR_ON_NONE(options->routing_domain);
for (i = 0; i < options->num_host_key_files; i++)
CLEAR_ON_NONE(options->host_key_files[i]);
for (i = 0; i < options->num_host_cert_files; i++)
@ -469,7 +471,7 @@ typedef enum {
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
sExposeAuthInfo,
sExposeAuthInfo, sRDomain,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@ -614,6 +616,7 @@ static struct {
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
{ "disableforwarding", sDisableForwarding, SSHCFG_ALL },
{ "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
{ "rdomain", sRDomain, SSHCFG_ALL },
{ NULL, sBadOption, 0 }
};
@ -1984,6 +1987,19 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->expose_userauth_info;
goto parse_flag;
case sRDomain:
charptr = &options->routing_domain;
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.",
filename, linenum);
if (strcasecmp(arg, "none") != 0 && strcmp(arg, "%D") != 0 &&
!valid_rdomain(arg))
fatal("%s line %d: bad routing domain",
filename, linenum);
if (*activep && *charptr == NULL)
*charptr = xstrdup(arg);
case sDeprecated:
case sIgnore:
case sUnsupported:
@ -2473,6 +2489,7 @@ dump_config(ServerOptions *o)
o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
dump_cfg_string(sRDomain, o->routing_domain);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.128 2017/10/25 00:15:35 djm Exp $ */
/* $OpenBSD: servconf.h,v 1.129 2017/10/25 00:17:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -78,6 +78,8 @@ typedef struct {
u_int num_listen_addrs;
int address_family; /* Address family used by the server. */
char *routing_domain; /* Bind session to routing domain */
char **host_key_files; /* Files containing host keys. */
u_int num_host_key_files; /* Number of files for host keys. */
char **host_cert_files; /* Files containing host certs. */
@ -239,6 +241,7 @@ struct connection_info {
M_CP_STROPT(authorized_principals_command_user); \
M_CP_STROPT(hostbased_key_types); \
M_CP_STROPT(pubkey_key_types); \
M_CP_STROPT(routing_domain); \
M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \
M_CP_STRARRAYOPT(allow_users, num_allow_users); \
M_CP_STRARRAYOPT(deny_users, num_deny_users); \

30
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.494 2017/10/25 00:15:35 djm Exp $ */
/* $OpenBSD: sshd.c,v 1.495 2017/10/25 00:17:08 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1368,6 +1368,31 @@ check_ip_options(struct ssh *ssh)
#endif /* IP_OPTIONS */
}
/* Set the routing domain for this process */
static void
set_process_rdomain(struct ssh *ssh, const char *name)
{
int rtable, ortable = getrtable();
const char *errstr;
if (name == NULL)
return; /* default */
if (strcmp(name, "%D") == 0) {
/* "expands" to routing domain of connection */
if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
return;
}
rtable = (int)strtonum(name, 0, 255, &errstr);
if (errstr != NULL) /* Shouldn't happen */
fatal("Invalid routing domain \"%s\": %s", name, errstr);
if (rtable != ortable && setrtable(rtable) != 0)
fatal("Unable to set routing domain %d: %s",
rtable, strerror(errno));
debug("%s: set routing domain %d (was %d)", __func__, rtable, ortable);
}
/*
* Main program for the daemon.
*/
@ -1983,6 +2008,9 @@ main(int ac, char **av)
cleanup_exit(255);
}
if (options.routing_domain != NULL)
set_process_rdomain(ssh, options.routing_domain);
/*
* The rest of the code depends on the fact that
* ssh_remote_ipaddr() caches the remote ip, even if

View File

@ -33,7 +33,7 @@
.\" (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.256 2017/10/25 00:15:35 djm Exp $
.\" $OpenBSD: sshd_config.5,v 1.257 2017/10/25 00:17:08 djm Exp $
.Dd $Mdocdate: October 25 2017 $
.Dt SSHD_CONFIG 5
.Os
@ -1118,6 +1118,7 @@ Available keywords are
.Cm PubkeyAuthentication ,
.Cm RekeyLimit ,
.Cm RevokedKeys ,
.Cm RDomain ,
.Cm StreamLocalBindMask ,
.Cm StreamLocalBindUnlink ,
.Cm TrustedUserCAKeys ,
@ -1378,6 +1379,15 @@ an OpenSSH Key Revocation List (KRL) as generated by
.Xr ssh-keygen 1 .
For more information on KRLs, see the KEY REVOCATION LISTS section in
.Xr ssh-keygen 1 .
.It Cm RDomain
Specifies an explicit routing domain that is applied after authentication
has completed.
The user session, as well and any forwarded or listening IP sockets will
be bound to this
.Xr rdomain 4 .
If the routing domain is set to
.Cm \&%D ,
then the domain in which the incoming connection was recieved will be applied.
.It Cm StreamLocalBindMask
Sets the octal file creation mode mask
.Pq umask
@ -1643,6 +1653,8 @@ which are expanded at runtime:
.It %%
A literal
.Sq % .
.It \&%D
The routing domain in which the incoming connection was received.
.It %F
The fingerprint of the CA key.
.It %f
@ -1679,6 +1691,9 @@ accepts the tokens %%, %h, and %u.
.Pp
.Cm ChrootDirectory
accepts the tokens %%, %h, and %u.
.Pp
.Cm RoutingDomain
accepts the token %D.
.Sh FILES
.Bl -tag -width Ds
.It Pa /etc/ssh/sshd_config