mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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
|
static int
|
||||||
rdynamic_connect_finish(struct ssh *ssh, Channel *c)
|
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;
|
struct channel_connect cctx;
|
||||||
|
u_int i, permit_adm = 1;
|
||||||
int sock;
|
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));
|
memset(&cctx, 0, sizeof(cctx));
|
||||||
sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,
|
sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,
|
||||||
NULL, &cctx, NULL, 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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
@ -147,6 +147,7 @@ typedef enum {
|
|||||||
oPasswordAuthentication,
|
oPasswordAuthentication,
|
||||||
oChallengeResponseAuthentication, oXAuthLocation,
|
oChallengeResponseAuthentication, oXAuthLocation,
|
||||||
oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
|
oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
|
||||||
|
oPermitRemoteOpen,
|
||||||
oCertificateFile, oAddKeysToAgent, oIdentityAgent,
|
oCertificateFile, oAddKeysToAgent, oIdentityAgent,
|
||||||
oUser, oEscapeChar, oProxyCommand,
|
oUser, oEscapeChar, oProxyCommand,
|
||||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||||
@ -247,6 +248,7 @@ static struct {
|
|||||||
{ "macs", oMacs },
|
{ "macs", oMacs },
|
||||||
{ "remoteforward", oRemoteForward },
|
{ "remoteforward", oRemoteForward },
|
||||||
{ "localforward", oLocalForward },
|
{ "localforward", oLocalForward },
|
||||||
|
{ "permitremoteopen", oPermitRemoteOpen },
|
||||||
{ "user", oUser },
|
{ "user", oUser },
|
||||||
{ "host", oHost },
|
{ "host", oHost },
|
||||||
{ "match", oMatch },
|
{ "match", oMatch },
|
||||||
@ -318,6 +320,7 @@ static struct {
|
|||||||
{ NULL, oBadOption }
|
{ NULL, oBadOption }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *lookup_opcode_name(OpCodes code);
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
kex_default_pk_alg(void)
|
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,
|
const char *original_host, char *line, const char *filename,
|
||||||
int linenum, int *activep, int flags, int *want_final_pass, int depth)
|
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];
|
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 r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
|
||||||
int remotefwd, dynamicfwd;
|
int remotefwd, dynamicfwd;
|
||||||
LogLevel *log_level_ptr;
|
LogLevel *log_level_ptr;
|
||||||
@ -1482,6 +1485,51 @@ parse_pubkey_algos:
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case oClearAllForwardings:
|
||||||
intptr = &options->clear_forwardings;
|
intptr = &options->clear_forwardings;
|
||||||
goto parse_flag;
|
goto parse_flag;
|
||||||
@ -2173,6 +2221,8 @@ initialize_options(Options * options)
|
|||||||
options->num_local_forwards = 0;
|
options->num_local_forwards = 0;
|
||||||
options->remote_forwards = NULL;
|
options->remote_forwards = NULL;
|
||||||
options->num_remote_forwards = 0;
|
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_facility = SYSLOG_FACILITY_NOT_SET;
|
||||||
options->log_level = SYSLOG_LEVEL_NOT_SET;
|
options->log_level = SYSLOG_LEVEL_NOT_SET;
|
||||||
options->num_log_verbose = 0;
|
options->num_log_verbose = 0;
|
||||||
@ -3126,6 +3176,13 @@ dump_client_config(Options *o, const char *host)
|
|||||||
|
|
||||||
/* Special cases */
|
/* 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 */
|
/* AddKeysToAgent */
|
||||||
if (o->add_keys_to_agent_lifespan <= 0)
|
if (o->add_keys_to_agent_lifespan <= 0)
|
||||||
dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
|
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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -110,6 +110,10 @@ typedef struct {
|
|||||||
struct Forward *remote_forwards;
|
struct Forward *remote_forwards;
|
||||||
int clear_forwardings;
|
int clear_forwardings;
|
||||||
|
|
||||||
|
/* Restrict remote dynamic forwarding */
|
||||||
|
char **permitted_remote_opens;
|
||||||
|
u_int num_permitted_remote_opens;
|
||||||
|
|
||||||
/* stdio forwarding (-W) host and port */
|
/* stdio forwarding (-W) host and port */
|
||||||
char *stdio_forward_host;
|
char *stdio_forward_host;
|
||||||
int stdio_forward_port;
|
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
|
.\" (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: ssh.1,v 1.418 2021/01/26 15:40:17 naddy Exp $
|
.\" $OpenBSD: ssh.1,v 1.419 2021/02/15 20:43:15 markus Exp $
|
||||||
.Dd $Mdocdate: January 26 2021 $
|
.Dd $Mdocdate: February 15 2021 $
|
||||||
.Dt SSH 1
|
.Dt SSH 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -531,6 +531,7 @@ For full details of the options listed below, and their possible values, see
|
|||||||
.It NumberOfPasswordPrompts
|
.It NumberOfPasswordPrompts
|
||||||
.It PasswordAuthentication
|
.It PasswordAuthentication
|
||||||
.It PermitLocalCommand
|
.It PermitLocalCommand
|
||||||
|
.It PermitRemoteOpen
|
||||||
.It PKCS11Provider
|
.It PKCS11Provider
|
||||||
.It Port
|
.It Port
|
||||||
.It PreferredAuthentications
|
.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>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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);
|
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
|
static void
|
||||||
ssh_init_forwarding(struct ssh *ssh, char **ifname)
|
ssh_init_forwarding(struct ssh *ssh, char **ifname)
|
||||||
{
|
{
|
||||||
int success = 0;
|
int success = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
ssh_init_forward_permissions(ssh, "permitremoteopen",
|
||||||
|
options.permitted_remote_opens,
|
||||||
|
options.num_permitted_remote_opens);
|
||||||
|
|
||||||
if (options.exit_on_forward_failure)
|
if (options.exit_on_forward_failure)
|
||||||
forward_confirms_pending = 0; /* track pending requests */
|
forward_confirms_pending = 0; /* track pending requests */
|
||||||
/* Initiate local TCP/IP port forwardings. */
|
/* 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
|
.\" (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: 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 $
|
.Dd $Mdocdate: February 15 2021 $
|
||||||
.Dt SSH_CONFIG 5
|
.Dt SSH_CONFIG 5
|
||||||
.Os
|
.Os
|
||||||
@ -1290,6 +1290,42 @@ The argument must be
|
|||||||
or
|
or
|
||||||
.Cm no
|
.Cm no
|
||||||
(the default).
|
(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
|
.It Cm PKCS11Provider
|
||||||
Specifies which PKCS#11 provider to use or
|
Specifies which PKCS#11 provider to use or
|
||||||
.Cm none
|
.Cm none
|
||||||
@ -1484,6 +1520,9 @@ If forwarding to a specific destination then the second argument must be
|
|||||||
or a Unix domain socket path,
|
or a Unix domain socket path,
|
||||||
otherwise if no destination argument is specified then the remote forwarding
|
otherwise if no destination argument is specified then the remote forwarding
|
||||||
will be established as a SOCKS proxy.
|
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
|
.Pp
|
||||||
IPv6 addresses can be specified by enclosing addresses in square brackets.
|
IPv6 addresses can be specified by enclosing addresses in square brackets.
|
||||||
Multiple forwardings may be specified, and additional
|
Multiple forwardings may be specified, and additional
|
||||||
|
Loading…
x
Reference in New Issue
Block a user