From f7299304b96a809e38af243ee3c416922034b597 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 6 Apr 2016 06:42:18 +0000 Subject: 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@ --- usr.bin/ssh/misc.c | 40 +++++++++++++++++++++++++++++++++++++++- usr.bin/ssh/misc.h | 4 +++- usr.bin/ssh/readconf.c | 14 +++++++++++++- 3 files changed, 55 insertions(+), 3 deletions(-) (limited to 'usr.bin') 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 @@ -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 * Copyright (c) 1995 Tatu Ylonen , 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)); -- cgit v1.2.3