mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
upstream: permitlisten option for authorized_keys; ok markus@
OpenBSD-Commit-ID: 8650883018d7aa893173d703379e4456a222c672
This commit is contained in:
parent
115063a664
commit
93c06ab6b7
140
auth-options.c
140
auth-options.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth-options.c,v 1.79 2018/04/06 04:15:45 djm Exp $ */
|
/* $OpenBSD: auth-options.c,v 1.80 2018/06/06 18:23:32 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
|
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
|
||||||
*
|
*
|
||||||
@ -283,6 +283,10 @@ sshauthopt_free(struct sshauthopt *opts)
|
|||||||
free(opts->permitopen[i]);
|
free(opts->permitopen[i]);
|
||||||
free(opts->permitopen);
|
free(opts->permitopen);
|
||||||
|
|
||||||
|
for (i = 0; i < opts->npermitlisten; i++)
|
||||||
|
free(opts->permitlisten[i]);
|
||||||
|
free(opts->permitlisten);
|
||||||
|
|
||||||
explicit_bzero(opts, sizeof(*opts));
|
explicit_bzero(opts, sizeof(*opts));
|
||||||
free(opts);
|
free(opts);
|
||||||
}
|
}
|
||||||
@ -304,10 +308,70 @@ sshauthopt_new_with_keys_defaults(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse and record a permitopen/permitlisten directive.
|
||||||
|
* Return 0 on success. Return -1 on failure and sets *errstrp to error reason.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
handle_permit(const char *opts, char ***permitsp, size_t *npermitsp,
|
||||||
|
const char **errstrp)
|
||||||
|
{
|
||||||
|
char *opt, *tmp, *cp, *host, **permits = *permitsp;
|
||||||
|
size_t npermits = *npermitsp;
|
||||||
|
const char *errstr = "unknown error";
|
||||||
|
|
||||||
|
if (npermits > INT_MAX) {
|
||||||
|
*errstrp = "too many permission directives";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((opt = opt_dequote(&opts, &errstr)) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((tmp = strdup(opt)) == NULL) {
|
||||||
|
free(opt);
|
||||||
|
*errstrp = "memory allocation failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cp = tmp;
|
||||||
|
/* validate syntax before recording it. */
|
||||||
|
host = hpdelim(&cp);
|
||||||
|
if (host == NULL || strlen(host) >= NI_MAXHOST) {
|
||||||
|
free(tmp);
|
||||||
|
free(opt);
|
||||||
|
*errstrp = "invalid permission hostname";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* don't want to use permitopen_port to avoid
|
||||||
|
* dependency on channels.[ch] here.
|
||||||
|
*/
|
||||||
|
if (cp == NULL ||
|
||||||
|
(strcmp(cp, "*") != 0 && a2port(cp) <= 0)) {
|
||||||
|
free(tmp);
|
||||||
|
free(opt);
|
||||||
|
*errstrp = "invalid permission port";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* XXX - add streamlocal support */
|
||||||
|
free(tmp);
|
||||||
|
/* Record it */
|
||||||
|
if ((permits = recallocarray(permits, npermits, npermits + 1,
|
||||||
|
sizeof(*permits))) == NULL) {
|
||||||
|
free(opt);
|
||||||
|
/* NB. don't update *permitsp if alloc fails */
|
||||||
|
*errstrp = "memory allocation failed";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
permits[npermits++] = opt;
|
||||||
|
*permitsp = permits;
|
||||||
|
*npermitsp = npermits;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct sshauthopt *
|
struct sshauthopt *
|
||||||
sshauthopt_parse(const char *opts, const char **errstrp)
|
sshauthopt_parse(const char *opts, const char **errstrp)
|
||||||
{
|
{
|
||||||
char **oarray, *opt, *cp, *tmp, *host;
|
char **oarray, *opt, *cp, *tmp;
|
||||||
int r;
|
int r;
|
||||||
struct sshauthopt *ret = NULL;
|
struct sshauthopt *ret = NULL;
|
||||||
const char *errstr = "unknown error";
|
const char *errstr = "unknown error";
|
||||||
@ -410,48 +474,13 @@ sshauthopt_parse(const char *opts, const char **errstrp)
|
|||||||
}
|
}
|
||||||
ret->env[ret->nenv++] = opt;
|
ret->env[ret->nenv++] = opt;
|
||||||
} else if (opt_match(&opts, "permitopen")) {
|
} else if (opt_match(&opts, "permitopen")) {
|
||||||
if (ret->npermitopen > INT_MAX) {
|
if (handle_permit(opts, &ret->permitopen,
|
||||||
errstr = "too many permitopens";
|
&ret->npermitopen, &errstr) != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
} else if (opt_match(&opts, "permitlisten")) {
|
||||||
if ((opt = opt_dequote(&opts, &errstr)) == NULL)
|
if (handle_permit(opts, &ret->permitlisten,
|
||||||
|
&ret->npermitlisten, &errstr) != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((tmp = strdup(opt)) == NULL) {
|
|
||||||
free(opt);
|
|
||||||
goto alloc_fail;
|
|
||||||
}
|
|
||||||
cp = tmp;
|
|
||||||
/* validate syntax of permitopen before recording it. */
|
|
||||||
host = hpdelim(&cp);
|
|
||||||
if (host == NULL || strlen(host) >= NI_MAXHOST) {
|
|
||||||
free(tmp);
|
|
||||||
free(opt);
|
|
||||||
errstr = "invalid permitopen hostname";
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* don't want to use permitopen_port to avoid
|
|
||||||
* dependency on channels.[ch] here.
|
|
||||||
*/
|
|
||||||
if (cp == NULL ||
|
|
||||||
(strcmp(cp, "*") != 0 && a2port(cp) <= 0)) {
|
|
||||||
free(tmp);
|
|
||||||
free(opt);
|
|
||||||
errstr = "invalid permitopen port";
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* XXX - add streamlocal support */
|
|
||||||
free(tmp);
|
|
||||||
/* Record it */
|
|
||||||
oarray = ret->permitopen;
|
|
||||||
if ((ret->permitopen = recallocarray(ret->permitopen,
|
|
||||||
ret->npermitopen, ret->npermitopen + 1,
|
|
||||||
sizeof(*ret->permitopen))) == NULL) {
|
|
||||||
free(opt);
|
|
||||||
ret->permitopen = oarray;
|
|
||||||
goto alloc_fail;
|
|
||||||
}
|
|
||||||
ret->permitopen[ret->npermitopen++] = opt;
|
|
||||||
} else if (opt_match(&opts, "tunnel")) {
|
} else if (opt_match(&opts, "tunnel")) {
|
||||||
if ((opt = opt_dequote(&opts, &errstr)) == NULL)
|
if ((opt = opt_dequote(&opts, &errstr)) == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -554,7 +583,10 @@ sshauthopt_merge(const struct sshauthopt *primary,
|
|||||||
if (tmp != NULL && (ret->required_from_host_keys = strdup(tmp)) == NULL)
|
if (tmp != NULL && (ret->required_from_host_keys = strdup(tmp)) == NULL)
|
||||||
goto alloc_fail;
|
goto alloc_fail;
|
||||||
|
|
||||||
/* force_tun_device, permitopen and environment prefer the primary. */
|
/*
|
||||||
|
* force_tun_device, permitopen/permitlisten and environment all
|
||||||
|
* prefer the primary.
|
||||||
|
*/
|
||||||
ret->force_tun_device = primary->force_tun_device;
|
ret->force_tun_device = primary->force_tun_device;
|
||||||
if (ret->force_tun_device == -1)
|
if (ret->force_tun_device == -1)
|
||||||
ret->force_tun_device = additional->force_tun_device;
|
ret->force_tun_device = additional->force_tun_device;
|
||||||
@ -577,6 +609,16 @@ sshauthopt_merge(const struct sshauthopt *primary,
|
|||||||
goto alloc_fail;
|
goto alloc_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (primary->npermitlisten > 0) {
|
||||||
|
if (dup_strings(&ret->permitlisten, &ret->npermitlisten,
|
||||||
|
primary->permitlisten, primary->npermitlisten) != 0)
|
||||||
|
goto alloc_fail;
|
||||||
|
} else if (additional->npermitlisten > 0) {
|
||||||
|
if (dup_strings(&ret->permitlisten, &ret->npermitlisten,
|
||||||
|
additional->permitlisten, additional->npermitlisten) != 0)
|
||||||
|
goto alloc_fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Flags are logical-AND (i.e. must be set in both for permission) */
|
/* Flags are logical-AND (i.e. must be set in both for permission) */
|
||||||
#define OPTFLAG(x) ret->x = (primary->x == 1) && (additional->x == 1)
|
#define OPTFLAG(x) ret->x = (primary->x == 1) && (additional->x == 1)
|
||||||
OPTFLAG(permit_port_forwarding_flag);
|
OPTFLAG(permit_port_forwarding_flag);
|
||||||
@ -669,7 +711,9 @@ sshauthopt_copy(const struct sshauthopt *orig)
|
|||||||
|
|
||||||
if (dup_strings(&ret->env, &ret->nenv, orig->env, orig->nenv) != 0 ||
|
if (dup_strings(&ret->env, &ret->nenv, orig->env, orig->nenv) != 0 ||
|
||||||
dup_strings(&ret->permitopen, &ret->npermitopen,
|
dup_strings(&ret->permitopen, &ret->npermitopen,
|
||||||
orig->permitopen, orig->npermitopen) != 0) {
|
orig->permitopen, orig->npermitopen) != 0 ||
|
||||||
|
dup_strings(&ret->permitlisten, &ret->npermitlisten,
|
||||||
|
orig->permitlisten, orig->npermitlisten) != 0) {
|
||||||
sshauthopt_free(ret);
|
sshauthopt_free(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -805,7 +849,9 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
|
|||||||
if ((r = serialise_array(m, opts->env,
|
if ((r = serialise_array(m, opts->env,
|
||||||
untrusted ? 0 : opts->nenv)) != 0 ||
|
untrusted ? 0 : opts->nenv)) != 0 ||
|
||||||
(r = serialise_array(m, opts->permitopen,
|
(r = serialise_array(m, opts->permitopen,
|
||||||
untrusted ? 0 : opts->npermitopen)) != 0)
|
untrusted ? 0 : opts->npermitopen)) ||
|
||||||
|
(r = serialise_array(m, opts->permitlisten,
|
||||||
|
untrusted ? 0 : opts->npermitlisten)) != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
@ -859,7 +905,9 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
|
|||||||
/* Array options */
|
/* Array options */
|
||||||
if ((r = deserialise_array(m, &opts->env, &opts->nenv)) != 0 ||
|
if ((r = deserialise_array(m, &opts->env, &opts->nenv)) != 0 ||
|
||||||
(r = deserialise_array(m,
|
(r = deserialise_array(m,
|
||||||
&opts->permitopen, &opts->npermitopen)) != 0)
|
&opts->permitopen, &opts->npermitopen)) != 0 ||
|
||||||
|
(r = deserialise_array(m,
|
||||||
|
&opts->permitlisten, &opts->npermitlisten)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth-options.h,v 1.26 2018/03/12 00:52:01 djm Exp $ */
|
/* $OpenBSD: auth-options.h,v 1.27 2018/06/06 18:23:32 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
|
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
|
||||||
@ -55,6 +55,10 @@ struct sshauthopt {
|
|||||||
size_t npermitopen;
|
size_t npermitopen;
|
||||||
char **permitopen;
|
char **permitopen;
|
||||||
|
|
||||||
|
/* Permitted listens (remote forwarding) */
|
||||||
|
size_t npermitlisten;
|
||||||
|
char **permitlisten;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Permitted host/addresses (comma-separated)
|
* Permitted host/addresses (comma-separated)
|
||||||
* Caller must check source address matches both lists (if present).
|
* Caller must check source address matches both lists (if present).
|
||||||
|
15
auth.c
15
auth.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: auth.c,v 1.129 2018/06/01 03:33:53 djm Exp $ */
|
/* $OpenBSD: auth.c,v 1.130 2018/06/06 18:23:32 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -1005,17 +1005,20 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
|
|||||||
int do_env = options.permit_user_env && opts->nenv > 0;
|
int do_env = options.permit_user_env && opts->nenv > 0;
|
||||||
int do_permitopen = opts->npermitopen > 0 &&
|
int do_permitopen = opts->npermitopen > 0 &&
|
||||||
(options.allow_tcp_forwarding & FORWARD_LOCAL) != 0;
|
(options.allow_tcp_forwarding & FORWARD_LOCAL) != 0;
|
||||||
|
int do_permitlisten = opts->npermitlisten > 0 &&
|
||||||
|
(options.allow_tcp_forwarding & FORWARD_REMOTE) != 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
char msg[1024], buf[64];
|
char msg[1024], buf[64];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
|
snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
|
||||||
/* Try to keep this alphabetically sorted */
|
/* Try to keep this alphabetically sorted */
|
||||||
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s",
|
snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||||
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
|
opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
|
||||||
opts->force_command == NULL ? "" : " command",
|
opts->force_command == NULL ? "" : " command",
|
||||||
do_env ? " environment" : "",
|
do_env ? " environment" : "",
|
||||||
opts->valid_before == 0 ? "" : "expires",
|
opts->valid_before == 0 ? "" : "expires",
|
||||||
do_permitopen ? " permitopen" : "",
|
do_permitopen ? " permitopen" : "",
|
||||||
|
do_permitlisten ? " permitlisten" : "",
|
||||||
opts->permit_port_forwarding_flag ? " port-forwarding" : "",
|
opts->permit_port_forwarding_flag ? " port-forwarding" : "",
|
||||||
opts->cert_principals == NULL ? "" : " principals",
|
opts->cert_principals == NULL ? "" : " principals",
|
||||||
opts->permit_pty_flag ? " pty" : "",
|
opts->permit_pty_flag ? " pty" : "",
|
||||||
@ -1049,12 +1052,18 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
|
|||||||
}
|
}
|
||||||
if (opts->force_command != NULL)
|
if (opts->force_command != NULL)
|
||||||
debug("%s: forced command: \"%s\"", loc, opts->force_command);
|
debug("%s: forced command: \"%s\"", loc, opts->force_command);
|
||||||
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) {
|
if (do_permitopen) {
|
||||||
for (i = 0; i < opts->npermitopen; i++) {
|
for (i = 0; i < opts->npermitopen; i++) {
|
||||||
debug("%s: permitted open: %s",
|
debug("%s: permitted open: %s",
|
||||||
loc, opts->permitopen[i]);
|
loc, opts->permitopen[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (do_permitlisten) {
|
||||||
|
for (i = 0; i < opts->npermitlisten; i++) {
|
||||||
|
debug("%s: permitted listen: %s",
|
||||||
|
loc, opts->permitlisten[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate a new set of key/cert options; merging with what is there. */
|
/* Activate a new set of key/cert options; merging with what is there. */
|
||||||
|
32
servconf.c
32
servconf.c
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
/* $OpenBSD: servconf.c,v 1.329 2018/06/06 18:22:41 djm Exp $ */
|
/* $OpenBSD: servconf.c,v 1.330 2018/06/06 18:23:32 djm 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
|
||||||
@ -160,7 +160,7 @@ initialize_server_options(ServerOptions *options)
|
|||||||
options->num_accept_env = 0;
|
options->num_accept_env = 0;
|
||||||
options->permit_tun = -1;
|
options->permit_tun = -1;
|
||||||
options->permitted_opens = NULL;
|
options->permitted_opens = NULL;
|
||||||
options->permitted_remote_opens = NULL;
|
options->permitted_listens = NULL;
|
||||||
options->adm_forced_command = NULL;
|
options->adm_forced_command = NULL;
|
||||||
options->chroot_directory = NULL;
|
options->chroot_directory = NULL;
|
||||||
options->authorized_keys_command = NULL;
|
options->authorized_keys_command = NULL;
|
||||||
@ -463,7 +463,7 @@ typedef enum {
|
|||||||
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
|
||||||
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
|
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
|
||||||
sAcceptEnv, sPermitTunnel,
|
sAcceptEnv, sPermitTunnel,
|
||||||
sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory,
|
sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
|
||||||
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
sUsePrivilegeSeparation, sAllowAgentForwarding,
|
||||||
sHostCertificate,
|
sHostCertificate,
|
||||||
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
|
||||||
@ -598,7 +598,7 @@ static struct {
|
|||||||
{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
|
{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
|
||||||
{ "match", sMatch, SSHCFG_ALL },
|
{ "match", sMatch, SSHCFG_ALL },
|
||||||
{ "permitopen", sPermitOpen, SSHCFG_ALL },
|
{ "permitopen", sPermitOpen, SSHCFG_ALL },
|
||||||
{ "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL },
|
{ "permitlisten", sPermitListen, SSHCFG_ALL },
|
||||||
{ "forcecommand", sForceCommand, SSHCFG_ALL },
|
{ "forcecommand", sForceCommand, SSHCFG_ALL },
|
||||||
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
|
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
|
||||||
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
|
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
|
||||||
@ -878,9 +878,9 @@ process_permitopen(struct ssh *ssh, ServerOptions *options)
|
|||||||
{
|
{
|
||||||
process_permitopen_list(ssh, sPermitOpen,
|
process_permitopen_list(ssh, sPermitOpen,
|
||||||
options->permitted_opens, options->num_permitted_opens);
|
options->permitted_opens, options->num_permitted_opens);
|
||||||
process_permitopen_list(ssh, sPermitRemoteOpen,
|
process_permitopen_list(ssh, sPermitListen,
|
||||||
options->permitted_remote_opens,
|
options->permitted_listens,
|
||||||
options->num_permitted_remote_opens);
|
options->num_permitted_listens);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct connection_info *
|
struct connection_info *
|
||||||
@ -1831,11 +1831,11 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||||||
*activep = value;
|
*activep = value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sPermitRemoteOpen:
|
case sPermitListen:
|
||||||
case sPermitOpen:
|
case sPermitOpen:
|
||||||
if (opcode == sPermitRemoteOpen) {
|
if (opcode == sPermitListen) {
|
||||||
uintptr = &options->num_permitted_remote_opens;
|
uintptr = &options->num_permitted_listens;
|
||||||
chararrayptr = &options->permitted_remote_opens;
|
chararrayptr = &options->permitted_listens;
|
||||||
} else {
|
} else {
|
||||||
uintptr = &options->num_permitted_opens;
|
uintptr = &options->num_permitted_opens;
|
||||||
chararrayptr = &options->permitted_opens;
|
chararrayptr = &options->permitted_opens;
|
||||||
@ -1857,7 +1857,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||||||
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
|
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
|
||||||
arg2 = xstrdup(arg);
|
arg2 = xstrdup(arg);
|
||||||
p = hpdelim(&arg);
|
p = hpdelim(&arg);
|
||||||
/* XXX support bare port number for PermitRemoteOpen */
|
/* XXX support bare port number for PermitListen */
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
fatal("%s line %d: missing host in %s",
|
fatal("%s line %d: missing host in %s",
|
||||||
filename, linenum,
|
filename, linenum,
|
||||||
@ -2596,12 +2596,12 @@ dump_config(ServerOptions *o)
|
|||||||
printf(" %s", o->permitted_opens[i]);
|
printf(" %s", o->permitted_opens[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("permitremoteopen");
|
printf("permitlisten");
|
||||||
if (o->num_permitted_remote_opens == 0)
|
if (o->num_permitted_listens == 0)
|
||||||
printf(" any");
|
printf(" any");
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < o->num_permitted_remote_opens; i++)
|
for (i = 0; i < o->num_permitted_listens; i++)
|
||||||
printf(" %s", o->permitted_remote_opens[i]);
|
printf(" %s", o->permitted_listens[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: servconf.h,v 1.132 2018/06/06 18:22:41 djm Exp $ */
|
/* $OpenBSD: servconf.h,v 1.133 2018/06/06 18:23:32 djm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -183,8 +183,8 @@ typedef struct {
|
|||||||
|
|
||||||
char **permitted_opens; /* May also be one of PERMITOPEN_* */
|
char **permitted_opens; /* May also be one of PERMITOPEN_* */
|
||||||
u_int num_permitted_opens;
|
u_int num_permitted_opens;
|
||||||
char **permitted_remote_opens; /* May also be one of PERMITOPEN_* */
|
char **permitted_listens; /* May also be one of PERMITOPEN_* */
|
||||||
u_int num_permitted_remote_opens;
|
u_int num_permitted_listens;
|
||||||
|
|
||||||
char *chroot_directory;
|
char *chroot_directory;
|
||||||
char *revoked_keys_file;
|
char *revoked_keys_file;
|
||||||
@ -248,8 +248,7 @@ struct connection_info {
|
|||||||
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
|
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
|
||||||
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
|
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
|
||||||
M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
|
M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
|
||||||
M_CP_STRARRAYOPT(permitted_remote_opens, \
|
M_CP_STRARRAYOPT(permitted_listens, num_permitted_listens); \
|
||||||
num_permitted_remote_opens); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
struct connection_info *get_connection_info(int, int);
|
struct connection_info *get_connection_info(int, int);
|
||||||
|
52
session.c
52
session.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: session.c,v 1.296 2018/06/06 18:22:41 djm Exp $ */
|
/* $OpenBSD: session.c,v 1.297 2018/06/06 18:23:32 djm 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
|
||||||
@ -290,27 +290,43 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_permitopen_from_authopts(struct ssh *ssh, const struct sshauthopt *opts)
|
set_fwdpermit_from_authopts(struct ssh *ssh, const struct sshauthopt *opts)
|
||||||
{
|
{
|
||||||
char *tmp, *cp, *host;
|
char *tmp, *cp, *host;
|
||||||
int port;
|
int port;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
|
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) {
|
||||||
return;
|
channel_clear_permission(ssh, FORWARD_USER, FORWARD_LOCAL);
|
||||||
channel_clear_permission(ssh, FORWARD_USER, FORWARD_LOCAL);
|
for (i = 0; i < auth_opts->npermitopen; i++) {
|
||||||
for (i = 0; i < auth_opts->npermitopen; i++) {
|
tmp = cp = xstrdup(auth_opts->permitopen[i]);
|
||||||
tmp = cp = xstrdup(auth_opts->permitopen[i]);
|
/* This shouldn't fail as it has already been checked */
|
||||||
/* This shouldn't fail as it has already been checked */
|
if ((host = hpdelim(&cp)) == NULL)
|
||||||
if ((host = hpdelim(&cp)) == NULL)
|
fatal("%s: internal error: hpdelim", __func__);
|
||||||
fatal("%s: internal error: hpdelim", __func__);
|
host = cleanhostname(host);
|
||||||
host = cleanhostname(host);
|
if (cp == NULL || (port = permitopen_port(cp)) < 0)
|
||||||
if (cp == NULL || (port = permitopen_port(cp)) < 0)
|
fatal("%s: internal error: permitopen port",
|
||||||
fatal("%s: internal error: permitopen port",
|
__func__);
|
||||||
__func__);
|
channel_add_permission(ssh,
|
||||||
channel_add_permission(ssh, FORWARD_USER, FORWARD_LOCAL,
|
FORWARD_USER, FORWARD_LOCAL, host, port);
|
||||||
host, port);
|
free(tmp);
|
||||||
free(tmp);
|
}
|
||||||
|
}
|
||||||
|
if ((options.allow_tcp_forwarding & FORWARD_REMOTE) != 0) {
|
||||||
|
channel_clear_permission(ssh, FORWARD_USER, FORWARD_REMOTE);
|
||||||
|
for (i = 0; i < auth_opts->npermitlisten; i++) {
|
||||||
|
tmp = cp = xstrdup(auth_opts->permitlisten[i]);
|
||||||
|
/* This shouldn't fail as it has already been checked */
|
||||||
|
if ((host = hpdelim(&cp)) == NULL)
|
||||||
|
fatal("%s: internal error: hpdelim", __func__);
|
||||||
|
host = cleanhostname(host);
|
||||||
|
if (cp == NULL || (port = permitopen_port(cp)) < 0)
|
||||||
|
fatal("%s: internal error: permitlisten port",
|
||||||
|
__func__);
|
||||||
|
channel_add_permission(ssh,
|
||||||
|
FORWARD_USER, FORWARD_REMOTE, host, port);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +339,7 @@ do_authenticated(struct ssh *ssh, Authctxt *authctxt)
|
|||||||
|
|
||||||
/* setup the channel layer */
|
/* setup the channel layer */
|
||||||
/* XXX - streamlocal? */
|
/* XXX - streamlocal? */
|
||||||
set_permitopen_from_authopts(ssh, auth_opts);
|
set_fwdpermit_from_authopts(ssh, auth_opts);
|
||||||
|
|
||||||
if (!auth_opts->permit_port_forwarding_flag ||
|
if (!auth_opts->permit_port_forwarding_flag ||
|
||||||
options.disable_forwarding) {
|
options.disable_forwarding) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user