From 858252fb1d451ebb0969cf9749116c8f0ee42753 Mon Sep 17 00:00:00 2001 From: "dtucker@openbsd.org" Date: Wed, 1 Feb 2017 02:59:09 +0000 Subject: upstream commit Return true reason for port forwarding failures where feasible rather than always "administratively prohibited". bz#2674, ok djm@ Upstream-ID: d901d9887951774e604ca970e1827afaaef9e419 --- channels.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'channels.c') 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 * Copyright (c) 1995 Tatu Ylonen , 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. */ -- cgit v1.2.3