1- /* $OpenBSD: channels.c,v 1.356 2016/10/18 17:32:54 dtucker Exp $ */
1+ /* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */
22/*
33 * Author: Tatu Ylonen <[email protected] > 44 * Copyright (c) 1995 Tatu Ylonen <[email protected] >, Espoo, Finland @@ -3067,7 +3067,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt)
30673067 }
30683068 packet_check_eom ();
30693069 c = channel_connect_to_port (host , host_port ,
3070- "connected socket" , originator_string );
3070+ "connected socket" , originator_string , NULL , NULL );
30713071 free (originator_string );
30723072 free (host );
30733073 if (c == NULL ) {
@@ -4028,9 +4028,13 @@ channel_connect_ctx_free(struct channel_connect *cctx)
40284028 memset (cctx , 0 , sizeof (* cctx ));
40294029}
40304030
4031- /* Return CONNECTING channel to remote host:port or local socket path */
4031+ /*
4032+ * Return CONNECTING channel to remote host:port or local socket path,
4033+ * passing back the failure reason if appropriate.
4034+ */
40324035static Channel *
4033- connect_to (const char * name , int port , char * ctype , char * rname )
4036+ connect_to_reason (const char * name , int port , char * ctype , char * rname ,
4037+ int * reason , const char * * errmsg )
40344038{
40354039 struct addrinfo hints ;
40364040 int gaierr ;
@@ -4071,7 +4075,12 @@ connect_to(const char *name, int port, char *ctype, char *rname)
40714075 hints .ai_family = IPv4or6 ;
40724076 hints .ai_socktype = SOCK_STREAM ;
40734077 snprintf (strport , sizeof strport , "%d" , port );
4074- if ((gaierr = getaddrinfo (name , strport , & hints , & cctx .aitop )) != 0 ) {
4078+ if ((gaierr = getaddrinfo (name , strport , & hints , & cctx .aitop ))
4079+ != 0 ) {
4080+ if (errmsg != NULL )
4081+ * errmsg = ssh_gai_strerror (gaierr );
4082+ if (reason != NULL )
4083+ * reason = SSH2_OPEN_CONNECT_FAILED ;
40754084 error ("connect_to %.100s: unknown host (%s)" , name ,
40764085 ssh_gai_strerror (gaierr ));
40774086 return NULL ;
@@ -4094,6 +4103,13 @@ connect_to(const char *name, int port, char *ctype, char *rname)
40944103 return c ;
40954104}
40964105
4106+ /* Return CONNECTING channel to remote host:port or local socket path */
4107+ static Channel *
4108+ connect_to (const char * name , int port , char * ctype , char * rname )
4109+ {
4110+ return connect_to_reason (name , port , ctype , rname , NULL , NULL );
4111+ }
4112+
40974113/*
40984114 * returns either the newly connected channel or the downstream channel
40994115 * that needs to deal with this connection.
@@ -4138,7 +4154,8 @@ channel_connect_by_listen_path(const char *path, char *ctype, char *rname)
41384154
41394155/* Check if connecting to that port is permitted and connect. */
41404156Channel *
4141- channel_connect_to_port (const char * host , u_short port , char * ctype , char * rname )
4157+ channel_connect_to_port (const char * host , u_short port , char * ctype ,
4158+ char * rname , int * reason , const char * * errmsg )
41424159{
41434160 int i , permit , permit_adm = 1 ;
41444161
@@ -4163,9 +4180,11 @@ channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname
41634180 if (!permit || !permit_adm ) {
41644181 logit ("Received request to connect to host %.100s port %d, "
41654182 "but the request was denied." , host , port );
4183+ if (reason != NULL )
4184+ * reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED ;
41664185 return NULL ;
41674186 }
4168- return connect_to (host , port , ctype , rname );
4187+ return connect_to_reason (host , port , ctype , rname , reason , errmsg );
41694188}
41704189
41714190/* Check if connecting to that path is permitted and connect. */
0 commit comments