summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2016-04-06 06:42:18 +0000
committerDamien Miller <djm@cvs.openbsd.org>2016-04-06 06:42:18 +0000
commitf7299304b96a809e38af243ee3c416922034b597 (patch)
tree80436f0253d9fe2dc5bf36865e9f3a6e9dd7a803
parentc13124bee887f3bbe860cbc4414e93d32b5483ba (diff)
don't record duplicate LocalForward and RemoteForward entries;
fixes failure with ExitOnForwardFailure+hostname canonicalisation where the same forwards are added on the second pass through the configuration file. bz#2562; ok dtucker@
-rw-r--r--usr.bin/ssh/misc.c40
-rw-r--r--usr.bin/ssh/misc.h4
-rw-r--r--usr.bin/ssh/readconf.c14
3 files changed, 55 insertions, 3 deletions
diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c
index 1f72253660f..bb26c3a0cbb 100644
--- a/usr.bin/ssh/misc.c
+++ b/usr.bin/ssh/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.103 2016/04/02 14:37:42 krw Exp $ */
+/* $OpenBSD: misc.c,v 1.104 2016/04/06 06:42:17 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -1080,3 +1080,41 @@ unix_listener(const char *path, int backlog, int unlink_first)
}
return sock;
}
+
+/*
+ * Compares two strings that maybe be NULL. Returns non-zero if strings
+ * are both NULL or are identical, returns zero otherwise.
+ */
+static int
+strcmp_maybe_null(const char *a, const char *b)
+{
+ if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
+ return 0;
+ if (a != NULL && strcmp(a, b) != 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Compare two forwards, returning non-zero if they are identical or
+ * zero otherwise.
+ */
+int
+forward_equals(const struct Forward *a, const struct Forward *b)
+{
+ if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
+ return 0;
+ if (a->listen_port != b->listen_port)
+ return 0;
+ if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
+ return 0;
+ if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
+ return 0;
+ if (a->connect_port != b->connect_port)
+ return 0;
+ if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
+ return 0;
+ /* allocated_port and handle are not checked */
+ return 1;
+}
+
diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h
index 1b81be82e50..58f3f775952 100644
--- a/usr.bin/ssh/misc.h
+++ b/usr.bin/ssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.55 2016/03/02 22:42:40 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.56 2016/04/06 06:42:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -27,6 +27,8 @@ struct Forward {
int handle; /* Handle for dynamic listen ports */
};
+int forward_equals(const struct Forward *, const struct Forward *);
+
/* Common server and client forwarding options. */
struct ForwardOptions {
int gateway_ports; /* Allow remote connects to forwarded ports. */
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index 0e2e9e0de46..91a8e00a463 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.251 2016/04/06 06:42:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -284,10 +284,16 @@ add_local_forward(Options *options, const struct Forward *newfwd)
{
struct Forward *fwd;
extern uid_t original_real_uid;
+ int i;
if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
newfwd->listen_path == NULL)
fatal("Privileged ports can only be forwarded by root.");
+ /* Don't add duplicates */
+ for (i = 0; i < options->num_local_forwards; i++) {
+ if (forward_equals(newfwd, options->local_forwards + i))
+ return;
+ }
options->local_forwards = xreallocarray(options->local_forwards,
options->num_local_forwards + 1,
sizeof(*options->local_forwards));
@@ -310,7 +316,13 @@ void
add_remote_forward(Options *options, const struct Forward *newfwd)
{
struct Forward *fwd;
+ int i;
+ /* Don't add duplicates */
+ for (i = 0; i < options->num_remote_forwards; i++) {
+ if (forward_equals(newfwd, options->remote_forwards + i))
+ return;
+ }
options->remote_forwards = xreallocarray(options->remote_forwards,
options->num_remote_forwards + 1,
sizeof(*options->remote_forwards));