summaryrefslogtreecommitdiffstats
path: root/channels.c
diff options
context:
space:
mode:
authordtucker@openbsd.org <dtucker@openbsd.org>2017-02-01 02:59:09 +0000
committerDarren Tucker <dtucker@zip.com.au>2017-02-03 14:23:24 +1100
commit858252fb1d451ebb0969cf9749116c8f0ee42753 (patch)
tree86168774d4d73763e0114ec62d7abeb29fbfba12 /channels.c
parent6ba9f893838489add6ec4213c7a997b425e4a9e0 (diff)
upstream commit
Return true reason for port forwarding failures where feasible rather than always "administratively prohibited". bz#2674, ok djm@ Upstream-ID: d901d9887951774e604ca970e1827afaaef9e419
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/channels.c b/channels.c
index bef8ad6a..398da9a8 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.356 2016/10/18 17:32:54 dtucker Exp $ */
+/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -3065,7 +3065,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
}
packet_check_eom();
c = channel_connect_to_port(host, host_port,
- "connected socket", originator_string);
+ "connected socket", originator_string, NULL, NULL);
free(originator_string);
free(host);
if (c == NULL) {
@@ -4026,9 +4026,13 @@ channel_connect_ctx_free(struct channel_connect *cctx)
memset(cctx, 0, sizeof(*cctx));
}
-/* Return CONNECTING channel to remote host:port or local socket path */
+/*
+ * Return CONNECTING channel to remote host:port or local socket path,
+ * passing back the failure reason if appropriate.
+ */
static Channel *
-connect_to(const char *name, int port, char *ctype, char *rname)
+connect_to_reason(const char *name, int port, char *ctype, char *rname,
+ int *reason, const char **errmsg)
{
struct addrinfo hints;
int gaierr;
@@ -4069,7 +4073,12 @@ connect_to(const char *name, int port, char *ctype, char *rname)
hints.ai_family = IPv4or6;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%d", port);
- if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop)) != 0) {
+ if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop))
+ != 0) {
+ if (errmsg != NULL)
+ *errmsg = ssh_gai_strerror(gaierr);
+ if (reason != NULL)
+ *reason = SSH2_OPEN_CONNECT_FAILED;
error("connect_to %.100s: unknown host (%s)", name,
ssh_gai_strerror(gaierr));
return NULL;
@@ -4092,6 +4101,13 @@ connect_to(const char *name, int port, char *ctype, char *rname)
return c;
}
+/* Return CONNECTING channel to remote host:port or local socket path */
+static Channel *
+connect_to(const char *name, int port, char *ctype, char *rname)
+{
+ return connect_to_reason(name, port, ctype, rname, NULL, NULL);
+}
+
/*
* returns either the newly connected channel or the downstream channel
* that needs to deal with this connection.
@@ -4136,7 +4152,8 @@ channel_connect_by_listen_path(const char *path, char *ctype, char *rname)
/* Check if connecting to that port is permitted and connect. */
Channel *
-channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname)
+channel_connect_to_port(const char *host, u_short port, char *ctype,
+ char *rname, int *reason, const char **errmsg)
{
int i, permit, permit_adm = 1;
@@ -4161,9 +4178,11 @@ channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname
if (!permit || !permit_adm) {
logit("Received request to connect to host %.100s port %d, "
"but the request was denied.", host, port);
+ if (reason != NULL)
+ *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
return NULL;
}
- return connect_to(host, port, ctype, rname);
+ return connect_to_reason(host, port, ctype, rname, reason, errmsg);
}
/* Check if connecting to that path is permitted and connect. */