upstream: ssh: add PermitRemoteOpen for remote dynamic forwarding
with SOCKS ok djm@, dtucker@ OpenBSD-Commit-ID: 64fe7b6360acc4ea56aa61b66498b5ecc0a96a7c
This commit is contained in:
parent
b696858a7f
commit
da0a9afcc4
21
channels.c
21
channels.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: channels.c,v 1.404 2021/01/27 09:26:53 djm Exp $ */
|
||||
/* $OpenBSD: channels.c,v 1.405 2021/02/15 20:43:15 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -4478,9 +4478,28 @@ rdynamic_connect_prepare(struct ssh *ssh, char *ctype, char *rname)
|
|||
static int
|
||||
rdynamic_connect_finish(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
struct ssh_channels *sc = ssh->chanctxt;
|
||||
struct permission_set *pset = &sc->local_perms;
|
||||
struct permission *perm;
|
||||
struct channel_connect cctx;
|
||||
u_int i, permit_adm = 1;
|
||||
int sock;
|
||||
|
||||
if (pset->num_permitted_admin > 0) {
|
||||
permit_adm = 0;
|
||||
for (i = 0; i < pset->num_permitted_admin; i++) {
|
||||
perm = &pset->permitted_admin[i];
|
||||
if (open_match(perm, c->path, c->host_port)) {
|
||||
permit_adm = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!permit_adm) {
|
||||
debug_f("requested forward not permitted");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&cctx, 0, sizeof(cctx));
|
||||
sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,
|
||||
NULL, &cctx, NULL, NULL);
|
||||
|
|
63
readconf.c
63
readconf.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.c,v 1.350 2021/01/26 05:32:21 dtucker Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.351 2021/02/15 20:43:15 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -147,6 +147,7 @@ typedef enum {
|
|||
oPasswordAuthentication,
|
||||
oChallengeResponseAuthentication, oXAuthLocation,
|
||||
oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
|
||||
oPermitRemoteOpen,
|
||||
oCertificateFile, oAddKeysToAgent, oIdentityAgent,
|
||||
oUser, oEscapeChar, oProxyCommand,
|
||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||
|
@ -247,6 +248,7 @@ static struct {
|
|||
{ "macs", oMacs },
|
||||
{ "remoteforward", oRemoteForward },
|
||||
{ "localforward", oLocalForward },
|
||||
{ "permitremoteopen", oPermitRemoteOpen },
|
||||
{ "user", oUser },
|
||||
{ "host", oHost },
|
||||
{ "match", oMatch },
|
||||
|
@ -318,6 +320,7 @@ static struct {
|
|||
{ NULL, oBadOption }
|
||||
};
|
||||
|
||||
static const char *lookup_opcode_name(OpCodes code);
|
||||
|
||||
const char *
|
||||
kex_default_pk_alg(void)
|
||||
|
@ -912,9 +915,9 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
|
|||
const char *original_host, char *line, const char *filename,
|
||||
int linenum, int *activep, int flags, int *want_final_pass, int depth)
|
||||
{
|
||||
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
|
||||
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
|
||||
char **cpptr, ***cppptr, fwdarg[256];
|
||||
u_int i, *uintptr, max_entries = 0;
|
||||
u_int i, *uintptr, uvalue, max_entries = 0;
|
||||
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
|
||||
int remotefwd, dynamicfwd;
|
||||
LogLevel *log_level_ptr;
|
||||
|
@ -1482,6 +1485,51 @@ parse_pubkey_algos:
|
|||
}
|
||||
break;
|
||||
|
||||
case oPermitRemoteOpen:
|
||||
uintptr = &options->num_permitted_remote_opens;
|
||||
cppptr = &options->permitted_remote_opens;
|
||||
arg = strdelim(&s);
|
||||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing %s specification",
|
||||
filename, linenum, lookup_opcode_name(opcode));
|
||||
uvalue = *uintptr; /* modified later */
|
||||
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
|
||||
if (*activep && uvalue == 0) {
|
||||
*uintptr = 1;
|
||||
*cppptr = xcalloc(1, sizeof(**cppptr));
|
||||
(*cppptr)[0] = xstrdup(arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (; arg != NULL && *arg != '\0'; arg = strdelim(&s)) {
|
||||
arg2 = xstrdup(arg);
|
||||
ch = '\0';
|
||||
p = hpdelim2(&arg, &ch);
|
||||
if (p == NULL || ch == '/') {
|
||||
fatal("%s line %d: missing host in %s",
|
||||
filename, linenum,
|
||||
lookup_opcode_name(opcode));
|
||||
}
|
||||
p = cleanhostname(p);
|
||||
/*
|
||||
* don't want to use permitopen_port to avoid
|
||||
* dependency on channels.[ch] here.
|
||||
*/
|
||||
if (arg == NULL ||
|
||||
(strcmp(arg, "*") != 0 && a2port(arg) <= 0)) {
|
||||
fatal("%s line %d: bad port number in %s",
|
||||
filename, linenum,
|
||||
lookup_opcode_name(opcode));
|
||||
}
|
||||
if (*activep && uvalue == 0) {
|
||||
opt_array_append(filename, linenum,
|
||||
lookup_opcode_name(opcode),
|
||||
cppptr, uintptr, arg2);
|
||||
}
|
||||
free(arg2);
|
||||
}
|
||||
break;
|
||||
|
||||
case oClearAllForwardings:
|
||||
intptr = &options->clear_forwardings;
|
||||
goto parse_flag;
|
||||
|
@ -2173,6 +2221,8 @@ initialize_options(Options * options)
|
|||
options->num_local_forwards = 0;
|
||||
options->remote_forwards = NULL;
|
||||
options->num_remote_forwards = 0;
|
||||
options->permitted_remote_opens = NULL;
|
||||
options->num_permitted_remote_opens = 0;
|
||||
options->log_facility = SYSLOG_FACILITY_NOT_SET;
|
||||
options->log_level = SYSLOG_LEVEL_NOT_SET;
|
||||
options->num_log_verbose = 0;
|
||||
|
@ -3126,6 +3176,13 @@ dump_client_config(Options *o, const char *host)
|
|||
|
||||
/* Special cases */
|
||||
|
||||
/* PermitRemoteOpen */
|
||||
if (o->num_permitted_remote_opens == 0)
|
||||
printf("%s any\n", lookup_opcode_name(oPermitRemoteOpen));
|
||||
else
|
||||
dump_cfg_strarray_oneline(oPermitRemoteOpen,
|
||||
o->num_permitted_remote_opens, o->permitted_remote_opens);
|
||||
|
||||
/* AddKeysToAgent */
|
||||
if (o->add_keys_to_agent_lifespan <= 0)
|
||||
dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.h,v 1.139 2021/01/26 05:32:21 dtucker Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.140 2021/02/15 20:43:15 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -110,6 +110,10 @@ typedef struct {
|
|||
struct Forward *remote_forwards;
|
||||
int clear_forwardings;
|
||||
|
||||
/* Restrict remote dynamic forwarding */
|
||||
char **permitted_remote_opens;
|
||||
u_int num_permitted_remote_opens;
|
||||
|
||||
/* stdio forwarding (-W) host and port */
|
||||
char *stdio_forward_host;
|
||||
int stdio_forward_port;
|
||||
|
|
5
ssh.1
5
ssh.1
|
@ -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: ssh.1,v 1.418 2021/01/26 15:40:17 naddy Exp $
|
||||
.Dd $Mdocdate: January 26 2021 $
|
||||
.\" $OpenBSD: ssh.1,v 1.419 2021/02/15 20:43:15 markus Exp $
|
||||
.Dd $Mdocdate: February 15 2021 $
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -531,6 +531,7 @@ For full details of the options listed below, and their possible values, see
|
|||
.It NumberOfPasswordPrompts
|
||||
.It PasswordAuthentication
|
||||
.It PermitLocalCommand
|
||||
.It PermitRemoteOpen
|
||||
.It PKCS11Provider
|
||||
.It Port
|
||||
.It PreferredAuthentications
|
||||
|
|
43
ssh.c
43
ssh.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh.c,v 1.550 2021/02/02 22:36:59 djm Exp $ */
|
||||
/* $OpenBSD: ssh.c,v 1.551 2021/02/15 20:43:15 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1874,12 +1874,53 @@ ssh_init_stdio_forwarding(struct ssh *ssh)
|
|||
channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_init_forward_permissions(struct ssh *ssh, const char *what, char **opens,
|
||||
u_int num_opens)
|
||||
{
|
||||
u_int i;
|
||||
int port;
|
||||
char *addr, *arg, *oarg, ch;
|
||||
int where = FORWARD_LOCAL;
|
||||
|
||||
channel_clear_permission(ssh, FORWARD_ADM, where);
|
||||
if (num_opens == 0)
|
||||
return; /* permit any */
|
||||
|
||||
/* handle keywords: "any" / "none" */
|
||||
if (num_opens == 1 && strcmp(opens[0], "any") == 0)
|
||||
return;
|
||||
if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
|
||||
channel_disable_admin(ssh, where);
|
||||
return;
|
||||
}
|
||||
/* Otherwise treat it as a list of permitted host:port */
|
||||
for (i = 0; i < num_opens; i++) {
|
||||
oarg = arg = xstrdup(opens[i]);
|
||||
ch = '\0';
|
||||
addr = hpdelim2(&arg, &ch);
|
||||
if (addr == NULL || ch == '/')
|
||||
fatal_f("missing host in %s", what);
|
||||
addr = cleanhostname(addr);
|
||||
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
|
||||
fatal_f("bad port number in %s", what);
|
||||
/* Send it to channels layer */
|
||||
channel_add_permission(ssh, FORWARD_ADM,
|
||||
where, addr, port);
|
||||
free(oarg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_init_forwarding(struct ssh *ssh, char **ifname)
|
||||
{
|
||||
int success = 0;
|
||||
int i;
|
||||
|
||||
ssh_init_forward_permissions(ssh, "permitremoteopen",
|
||||
options.permitted_remote_opens,
|
||||
options.num_permitted_remote_opens);
|
||||
|
||||
if (options.exit_on_forward_failure)
|
||||
forward_confirms_pending = 0; /* track pending requests */
|
||||
/* Initiate local TCP/IP port forwardings. */
|
||||
|
|
41
ssh_config.5
41
ssh_config.5
|
@ -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: ssh_config.5,v 1.346 2021/02/15 11:09:22 dlg Exp $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.347 2021/02/15 20:43:15 markus Exp $
|
||||
.Dd $Mdocdate: February 15 2021 $
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
|
@ -1290,6 +1290,42 @@ The argument must be
|
|||
or
|
||||
.Cm no
|
||||
(the default).
|
||||
.It Cm PermitRemoteOpen
|
||||
Specifies the destinations to which remote TCP port forwarding is permitted when
|
||||
.Cm RemoteForward
|
||||
is used as a SOCKS proxy.
|
||||
The forwarding specification must be one of the following forms:
|
||||
.Pp
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
.Cm PermitRemoteOpen
|
||||
.Sm off
|
||||
.Ar host : port
|
||||
.Sm on
|
||||
.It
|
||||
.Cm PermitRemoteOpen
|
||||
.Sm off
|
||||
.Ar IPv4_addr : port
|
||||
.Sm on
|
||||
.It
|
||||
.Cm PermitRemoteOpen
|
||||
.Sm off
|
||||
.Ar \&[ IPv6_addr \&] : port
|
||||
.Sm on
|
||||
.El
|
||||
.Pp
|
||||
Multiple forwards may be specified by separating them with whitespace.
|
||||
An argument of
|
||||
.Cm any
|
||||
can be used to remove all restrictions and permit any forwarding requests.
|
||||
An argument of
|
||||
.Cm none
|
||||
can be used to prohibit all forwarding requests.
|
||||
The wildcard
|
||||
.Sq *
|
||||
can be used for host or port to allow all hosts or ports respectively.
|
||||
Otherwise, no pattern matching or address lookups are performed on supplied
|
||||
names.
|
||||
.It Cm PKCS11Provider
|
||||
Specifies which PKCS#11 provider to use or
|
||||
.Cm none
|
||||
|
@ -1484,6 +1520,9 @@ If forwarding to a specific destination then the second argument must be
|
|||
or a Unix domain socket path,
|
||||
otherwise if no destination argument is specified then the remote forwarding
|
||||
will be established as a SOCKS proxy.
|
||||
When acting as a SOCKS proxy the destination of the connection can be
|
||||
restricted by
|
||||
.Cm PermitRemoteOpen .
|
||||
.Pp
|
||||
IPv6 addresses can be specified by enclosing addresses in square brackets.
|
||||
Multiple forwardings may be specified, and additional
|
||||
|
|
Loading…
Reference in New Issue