summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/servconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/ssh/servconf.c')
-rw-r--r--usr.bin/ssh/servconf.c87
1 files changed, 66 insertions, 21 deletions
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index 10fed9b23bb..5adb370937f 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/servconf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: servconf.c,v 1.309 2017/06/24 06:34:38 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.310 2017/09/12 06:32:07 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -139,7 +139,7 @@ initialize_server_options(ServerOptions *options)
options->num_authkeys_files = 0;
options->num_accept_env = 0;
options->permit_tun = -1;
- options->num_permitted_opens = -1;
+ options->permitted_opens = NULL;
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
options->authorized_keys_command = NULL;
@@ -651,6 +651,44 @@ process_queued_listen_addrs(ServerOptions *options)
options->num_queued_listens = 0;
}
+/*
+ * Inform channels layer of permitopen options from configuration.
+ */
+void
+process_permitopen(struct ssh *ssh, ServerOptions *options)
+{
+ u_int i;
+ int port;
+ char *host, *arg, *oarg;
+
+ channel_clear_adm_permitted_opens(ssh);
+ if (options->num_permitted_opens == 0)
+ return; /* permit any */
+
+ /* handle keywords: "any" / "none" */
+ if (options->num_permitted_opens == 1 &&
+ strcmp(options->permitted_opens[0], "any") == 0)
+ return;
+ if (options->num_permitted_opens == 1 &&
+ strcmp(options->permitted_opens[0], "none") == 0) {
+ channel_disable_adm_local_opens(ssh);
+ 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]);
+ host = hpdelim(&arg);
+ if (host == NULL)
+ fatal("%s: missing host in PermitOpen", __func__);
+ host = cleanhostname(host);
+ if (arg == NULL || ((port = permitopen_port(arg)) < 0))
+ fatal("%s: bad port number in PermitOpen", __func__);
+ /* Send it to channels layer */
+ channel_add_adm_permitted_opens(ssh, host, port);
+ free(oarg);
+ }
+}
+
struct connection_info *
get_connection_info(int populate, int use_dns)
{
@@ -908,7 +946,7 @@ process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum, int *activep,
struct connection_info *connectinfo)
{
- char *cp, **charptr, *arg, *p;
+ char *cp, **charptr, *arg, *arg2, *p;
int cmdline = 0, *intptr, value, value2, n, port;
SyslogFacility *log_facility_ptr;
LogLevel *log_level_ptr;
@@ -1573,24 +1611,17 @@ process_server_config_line(ServerOptions *options, char *line,
if (!arg || *arg == '\0')
fatal("%s line %d: missing PermitOpen specification",
filename, linenum);
- n = options->num_permitted_opens; /* modified later */
- if (strcmp(arg, "any") == 0) {
- if (*activep && n == -1) {
- channel_clear_adm_permitted_opens();
- options->num_permitted_opens = 0;
- }
- break;
- }
- if (strcmp(arg, "none") == 0) {
- if (*activep && n == -1) {
+ i = options->num_permitted_opens; /* modified later */
+ if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
+ if (*activep && i == 0)
options->num_permitted_opens = 1;
- channel_disable_adm_local_opens();
- }
+ options->permitted_opens = xcalloc(1,
+ sizeof(*options->permitted_opens));
+ options->permitted_opens[0] = xstrdup(arg);
break;
}
- if (*activep && n == -1)
- channel_clear_adm_permitted_opens();
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",
@@ -1599,9 +1630,16 @@ process_server_config_line(ServerOptions *options, char *line,
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
fatal("%s line %d: bad port number in "
"PermitOpen", filename, linenum);
- if (*activep && n == -1)
- options->num_permitted_opens =
- channel_add_adm_permitted_opens(p, port);
+ if (*activep && i == 0) {
+ options->permitted_opens = xrecallocarray(
+ options->permitted_opens,
+ options->num_permitted_opens,
+ options->num_permitted_opens + 1,
+ sizeof(*options->permitted_opens));
+ i = options->num_permitted_opens++;
+ options->permitted_opens[i] = arg2;
+ } else
+ free(arg2);
}
break;
@@ -2293,5 +2331,12 @@ dump_config(ServerOptions *o)
printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
o->rekey_interval);
- channel_print_adm_permitted_opens();
+ printf("permitopen");
+ if (o->num_permitted_opens == 0)
+ printf(" any");
+ else {
+ for (i = 0; i < o->num_permitted_opens; i++)
+ printf(" %s", o->permitted_opens[i]);
+ }
+ printf("\n");
}