diff options
author | dtucker@openbsd.org <dtucker@openbsd.org> | 2017-02-01 02:59:09 +0000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2017-02-03 14:23:24 +1100 |
commit | 858252fb1d451ebb0969cf9749116c8f0ee42753 (patch) | |
tree | 86168774d4d73763e0114ec62d7abeb29fbfba12 /channels.c | |
parent | 6ba9f893838489add6ec4213c7a997b425e4a9e0 (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.c | 33 |
1 files changed, 26 insertions, 7 deletions
@@ -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. */ |