On Wed, Nov 23, 2016 at 01:35:17PM -0500, Jiri B wrote:
> I was using ssh socks5 tunnel (-D9999) today and I saw many:
> 
>   channel 4: open failed: administratively prohibited: open failed
> 
> messages. It seems non-resolvable hostnames on my gw (ie. end of ssh
> socks5 tunnel) is passed to client as "prohibited" event.
> 
> This seems odd and confusing. GW is an older 6.0-current amd64.

The code in sshd where the response is composed doesn't know what the
reason for the failure is.  I suspect thid dates back to the original
Protocol 1 code becuase Protocol 1 didn't (I think) have a reason field.
This passes the reason back up the stack and sends it to the client.

Index: channels.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/channels.c,v
retrieving revision 1.356
diff -u -p -r1.356 channels.c
--- channels.c  18 Oct 2016 17:32:54 -0000      1.356
+++ channels.c  24 Nov 2016 04:36:58 -0000
@@ -3038,7 +3038,7 @@ channel_input_port_open(int type, u_int3
        }
        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) {
@@ -3995,7 +3995,8 @@ channel_connect_ctx_free(struct channel_
 
 /* Return CONNECTING channel to remote host:port or local socket path */
 static Channel *
-connect_to(const char *name, int port, char *ctype, char *rname)
+connect_to(const char *name, int port, char *ctype, char *rname, int *reason,
+    char **errmsg)
 {
        struct addrinfo hints;
        int gaierr;
@@ -4036,7 +4037,12 @@ connect_to(const char *name, int port, c
                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;
@@ -4076,7 +4082,8 @@ channel_connect_by_listen_address(const 
                                return permitted_opens[i].downstream;
                        return connect_to(
                            permitted_opens[i].host_to_connect,
-                           permitted_opens[i].port_to_connect, ctype, rname);
+                           permitted_opens[i].port_to_connect, ctype, rname,
+                           NULL, NULL);
                }
        }
        error("WARNING: Server requests forwarding for unknown listen_port %d",
@@ -4093,7 +4100,8 @@ channel_connect_by_listen_path(const cha
                if (open_listen_match_streamlocal(&permitted_opens[i], path)) {
                        return connect_to(
                            permitted_opens[i].host_to_connect,
-                           permitted_opens[i].port_to_connect, ctype, rname);
+                           permitted_opens[i].port_to_connect, ctype, rname,
+                           NULL, NULL);
                }
        }
        error("WARNING: Server requests forwarding for unknown path %.100s",
@@ -4103,7 +4111,8 @@ channel_connect_by_listen_path(const cha
 
 /* 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, char **errmsg)
 {
        int i, permit, permit_adm = 1;
 
@@ -4128,9 +4137,10 @@ channel_connect_to_port(const char *host
        if (!permit || !permit_adm) {
                logit("Received request to connect to host %.100s port %d, "
                    "but the request was denied.", host, port);
+               *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
                return NULL;
        }
-       return connect_to(host, port, ctype, rname);
+       return connect_to(host, port, ctype, rname, reason, errmsg);
 }
 
 /* Check if connecting to that path is permitted and connect. */
@@ -4162,7 +4172,7 @@ channel_connect_to_path(const char *path
                    "but the request was denied.", path);
                return NULL;
        }
-       return connect_to(path, PORT_STREAMLOCAL, ctype, rname);
+       return connect_to(path, PORT_STREAMLOCAL, ctype, rname, NULL, NULL);
 }
 
 void
Index: channels.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/channels.h,v
retrieving revision 1.120
diff -u -p -r1.120 channels.h
--- channels.h  18 Oct 2016 17:32:54 -0000      1.120
+++ channels.h  24 Nov 2016 04:36:58 -0000
@@ -272,7 +272,8 @@ void         channel_update_permitted_opens(int
 void    channel_clear_permitted_opens(void);
 void    channel_clear_adm_permitted_opens(void);
 void    channel_print_adm_permitted_opens(void);
-Channel        *channel_connect_to_port(const char *, u_short, char *, char *);
+Channel        *channel_connect_to_port(const char *, u_short, char *, char *, 
int *,
+            char **);
 Channel *channel_connect_to_path(const char *, char *, char *);
 Channel        *channel_connect_stdio_fwd(const char*, u_short, int, int);
 Channel        *channel_connect_by_listen_address(const char *, u_short,
Index: serverloop.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/serverloop.c,v
retrieving revision 1.187
diff -u -p -r1.187 serverloop.c
--- serverloop.c        23 Oct 2016 22:04:05 -0000      1.187
+++ serverloop.c        24 Nov 2016 04:36:58 -0000
@@ -423,7 +423,7 @@ server_input_keep_alive(int type, u_int3
 }
 
 static Channel *
-server_request_direct_tcpip(void)
+server_request_direct_tcpip(int *reason, char **errmsg)
 {
        Channel *c = NULL;
        char *target, *originator;
@@ -442,11 +442,12 @@ server_request_direct_tcpip(void)
        if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
            !no_port_forwarding_flag) {
                c = channel_connect_to_port(target, target_port,
-                   "direct-tcpip", "direct-tcpip");
+                   "direct-tcpip", "direct-tcpip", reason, errmsg);
        } else {
                logit("refused local port forward: "
                    "originator %s port %d, target %s port %d",
                    originator, originator_port, target, target_port);
+               *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
        }
 
        free(originator);
@@ -563,8 +564,8 @@ static int
 server_input_channel_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
-       char *ctype;
-       int rchan;
+       char *ctype, *errmsg = NULL;
+       int rchan, reason = SSH2_OPEN_CONNECT_FAILED;
        u_int rmaxpack, rwindow, len;
 
        ctype = packet_get_string(&len);
@@ -578,7 +579,7 @@ server_input_channel_open(int type, u_in
        if (strcmp(ctype, "session") == 0) {
                c = server_request_session();
        } else if (strcmp(ctype, "direct-tcpip") == 0) {
-               c = server_request_direct_tcpip();
+               c = server_request_direct_tcpip(&reason, &errmsg);
        } else if (strcmp(ctype, "direct-streamlo...@openssh.com") == 0) {
                c = server_request_direct_streamlocal();
        } else if (strcmp(ctype, "t...@openssh.com") == 0) {
@@ -601,9 +602,9 @@ server_input_channel_open(int type, u_in
                debug("server_input_channel_open: failure %s", ctype);
                packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
                packet_put_int(rchan);
-               packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
+               packet_put_int(reason);
                if (!(datafellows & SSH_BUG_OPENFAILURE)) {
-                       packet_put_cstring("open failed");
+                       packet_put_cstring(errmsg ? errmsg : "open failed");
                        packet_put_cstring("");
                }
                packet_send();

-- 
Darren Tucker (dtucker at zip.com.au)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860  37F4 9357 ECEF 11EA A6FA (new)
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.

Reply via email to