summaryrefslogtreecommitdiffstats
path: root/servconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'servconf.c')
-rw-r--r--servconf.c138
1 files changed, 90 insertions, 48 deletions
diff --git a/servconf.c b/servconf.c
index 5ca84515..b75faf3f 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: servconf.c,v 1.328 2018/04/10 00:10:49 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.329 2018/06/06 18:22:41 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -160,6 +160,7 @@ initialize_server_options(ServerOptions *options)
options->num_accept_env = 0;
options->permit_tun = -1;
options->permitted_opens = NULL;
+ options->permitted_remote_opens = NULL;
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
options->authorized_keys_command = NULL;
@@ -462,7 +463,7 @@ typedef enum {
sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
sAcceptEnv, sPermitTunnel,
- sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
+ sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory,
sUsePrivilegeSeparation, sAllowAgentForwarding,
sHostCertificate,
sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
@@ -597,6 +598,7 @@ static struct {
{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
{ "match", sMatch, SSHCFG_ALL },
{ "permitopen", sPermitOpen, SSHCFG_ALL },
+ { "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
@@ -632,6 +634,20 @@ static struct {
{ -1, NULL }
};
+/* Returns an opcode name from its number */
+
+static const char *
+lookup_opcode_name(ServerOpCodes code)
+{
+ u_int i;
+
+ for (i = 0; keywords[i].name != NULL; i++)
+ if (keywords[i].opcode == code)
+ return(keywords[i].name);
+ return "UNKNOWN";
+}
+
+
/*
* Returns the number of the token pointed to by cp or sBadOption.
*/
@@ -814,43 +830,59 @@ process_queued_listen_addrs(ServerOptions *options)
}
/*
- * Inform channels layer of permitopen options from configuration.
+ * Inform channels layer of permitopen options for a single forwarding
+ * direction (local/remote).
*/
-void
-process_permitopen(struct ssh *ssh, ServerOptions *options)
+static void
+process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
+ char **opens, u_int num_opens)
{
u_int i;
int port;
char *host, *arg, *oarg;
+ int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
+ const char *what = lookup_opcode_name(opcode);
- channel_clear_adm_permitted_opens(ssh);
- if (options->num_permitted_opens == 0)
+ channel_clear_permission(ssh, FORWARD_ADM, where);
+ if (num_opens == 0)
return; /* permit any */
/* handle keywords: "any" / "none" */
- if (options->num_permitted_opens == 1 &&
- strcmp(options->permitted_opens[0], "any") == 0)
+ if (num_opens == 1 && strcmp(opens[0], "any") == 0)
return;
- if (options->num_permitted_opens == 1 &&
- strcmp(options->permitted_opens[0], "none") == 0) {
- channel_disable_adm_local_opens(ssh);
+ 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 < options->num_permitted_opens; i++) {
- oarg = arg = xstrdup(options->permitted_opens[i]);
+ for (i = 0; i < num_opens; i++) {
+ oarg = arg = xstrdup(opens[i]);
host = hpdelim(&arg);
if (host == NULL)
- fatal("%s: missing host in PermitOpen", __func__);
+ fatal("%s: missing host in %s", __func__, what);
host = cleanhostname(host);
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
- fatal("%s: bad port number in PermitOpen", __func__);
+ fatal("%s: bad port number in %s", __func__, what);
/* Send it to channels layer */
- channel_add_adm_permitted_opens(ssh, host, port);
+ channel_add_permission(ssh, FORWARD_ADM,
+ where, host, port);
free(oarg);
}
}
+/*
+ * Inform channels layer of permitopen options from configuration.
+ */
+void
+process_permitopen(struct ssh *ssh, ServerOptions *options)
+{
+ process_permitopen_list(ssh, sPermitOpen,
+ options->permitted_opens, options->num_permitted_opens);
+ process_permitopen_list(ssh, sPermitRemoteOpen,
+ options->permitted_remote_opens,
+ options->num_permitted_remote_opens);
+}
+
struct connection_info *
get_connection_info(int populate, int use_dns)
{
@@ -1144,12 +1176,12 @@ process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep,
struct connection_info *connectinfo)
{
- char *cp, **charptr, *arg, *arg2, *p;
+ char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
int cmdline = 0, *intptr, value, value2, n, port;
SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr;
ServerOpCodes opcode;
- u_int i, flags = 0;
+ u_int i, *uintptr, uvalue, flags = 0;
size_t len;
long long val64;
const struct multistate *multistate_ptr;
@@ -1799,36 +1831,49 @@ process_server_config_line(ServerOptions *options, char *line,
*activep = value;
break;
+ case sPermitRemoteOpen:
case sPermitOpen:
+ if (opcode == sPermitRemoteOpen) {
+ uintptr = &options->num_permitted_remote_opens;
+ chararrayptr = &options->permitted_remote_opens;
+ } else {
+ uintptr = &options->num_permitted_opens;
+ chararrayptr = &options->permitted_opens;
+ }
arg = strdelim(&cp);
if (!arg || *arg == '\0')
- fatal("%s line %d: missing PermitOpen specification",
- filename, linenum);
- value = options->num_permitted_opens; /* modified later */
+ 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 && value == 0) {
- options->num_permitted_opens = 1;
- options->permitted_opens = xcalloc(1,
- sizeof(*options->permitted_opens));
- options->permitted_opens[0] = xstrdup(arg);
+ if (*activep && uvalue == 0) {
+ *uintptr = 1;
+ *chararrayptr = xcalloc(1,
+ sizeof(**chararrayptr));
+ (*chararrayptr)[0] = xstrdup(arg);
}
break;
}
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
arg2 = xstrdup(arg);
p = hpdelim(&arg);
- if (p == NULL)
- fatal("%s line %d: missing host in PermitOpen",
- filename, linenum);
+ /* XXX support bare port number for PermitRemoteOpen */
+ if (p == NULL) {
+ fatal("%s line %d: missing host in %s",
+ filename, linenum,
+ lookup_opcode_name(opcode));
+ }
p = cleanhostname(p);
- if (arg == NULL || ((port = permitopen_port(arg)) < 0))
- fatal("%s line %d: bad port number in "
- "PermitOpen", filename, linenum);
- if (*activep && value == 0) {
+ if (arg == NULL ||
+ ((port = permitopen_port(arg)) < 0)) {
+ fatal("%s line %d: bad port number in %s",
+ filename, linenum,
+ lookup_opcode_name(opcode));
+ }
+ if (*activep && uvalue == 0) {
array_append(filename, linenum,
- "PermitOpen",
- &options->permitted_opens,
- &options->num_permitted_opens, arg2);
+ lookup_opcode_name(opcode),
+ chararrayptr, uintptr, arg2);
}
free(arg2);
}
@@ -2307,17 +2352,6 @@ fmt_intarg(ServerOpCodes code, int val)
}
}
-static const char *
-lookup_opcode_name(ServerOpCodes code)
-{
- u_int i;
-
- for (i = 0; keywords[i].name != NULL; i++)
- if (keywords[i].opcode == code)
- return(keywords[i].name);
- return "UNKNOWN";
-}
-
static void
dump_cfg_int(ServerOpCodes code, int val)
{
@@ -2562,4 +2596,12 @@ dump_config(ServerOptions *o)
printf(" %s", o->permitted_opens[i]);
}
printf("\n");
+ printf("permitremoteopen");
+ if (o->num_permitted_remote_opens == 0)
+ printf(" any");
+ else {
+ for (i = 0; i < o->num_permitted_remote_opens; i++)
+ printf(" %s", o->permitted_remote_opens[i]);
+ }
+ printf("\n");
}