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.