summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels.c33
-rw-r--r--channels.h5
-rw-r--r--serverloop.c17
3 files changed, 39 insertions, 16 deletions
diff --git a/channels.c b/channels.c
index bef8ad6aa..398da9a89 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
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 $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * 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)
3065 } 3065 }
3066 packet_check_eom(); 3066 packet_check_eom();
3067 c = channel_connect_to_port(host, host_port, 3067 c = channel_connect_to_port(host, host_port,
3068 "connected socket", originator_string); 3068 "connected socket", originator_string, NULL, NULL);
3069 free(originator_string); 3069 free(originator_string);
3070 free(host); 3070 free(host);
3071 if (c == NULL) { 3071 if (c == NULL) {
@@ -4026,9 +4026,13 @@ channel_connect_ctx_free(struct channel_connect *cctx)
4026 memset(cctx, 0, sizeof(*cctx)); 4026 memset(cctx, 0, sizeof(*cctx));
4027} 4027}
4028 4028
4029/* Return CONNECTING channel to remote host:port or local socket path */ 4029/*
4030 * Return CONNECTING channel to remote host:port or local socket path,
4031 * passing back the failure reason if appropriate.
4032 */
4030static Channel * 4033static Channel *
4031connect_to(const char *name, int port, char *ctype, char *rname) 4034connect_to_reason(const char *name, int port, char *ctype, char *rname,
4035 int *reason, const char **errmsg)
4032{ 4036{
4033 struct addrinfo hints; 4037 struct addrinfo hints;
4034 int gaierr; 4038 int gaierr;
@@ -4069,7 +4073,12 @@ connect_to(const char *name, int port, char *ctype, char *rname)
4069 hints.ai_family = IPv4or6; 4073 hints.ai_family = IPv4or6;
4070 hints.ai_socktype = SOCK_STREAM; 4074 hints.ai_socktype = SOCK_STREAM;
4071 snprintf(strport, sizeof strport, "%d", port); 4075 snprintf(strport, sizeof strport, "%d", port);
4072 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop)) != 0) { 4076 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop))
4077 != 0) {
4078 if (errmsg != NULL)
4079 *errmsg = ssh_gai_strerror(gaierr);
4080 if (reason != NULL)
4081 *reason = SSH2_OPEN_CONNECT_FAILED;
4073 error("connect_to %.100s: unknown host (%s)", name, 4082 error("connect_to %.100s: unknown host (%s)", name,
4074 ssh_gai_strerror(gaierr)); 4083 ssh_gai_strerror(gaierr));
4075 return NULL; 4084 return NULL;
@@ -4092,6 +4101,13 @@ connect_to(const char *name, int port, char *ctype, char *rname)
4092 return c; 4101 return c;
4093} 4102}
4094 4103
4104/* Return CONNECTING channel to remote host:port or local socket path */
4105static Channel *
4106connect_to(const char *name, int port, char *ctype, char *rname)
4107{
4108 return connect_to_reason(name, port, ctype, rname, NULL, NULL);
4109}
4110
4095/* 4111/*
4096 * returns either the newly connected channel or the downstream channel 4112 * returns either the newly connected channel or the downstream channel
4097 * that needs to deal with this connection. 4113 * that needs to deal with this connection.
@@ -4136,7 +4152,8 @@ channel_connect_by_listen_path(const char *path, char *ctype, char *rname)
4136 4152
4137/* Check if connecting to that port is permitted and connect. */ 4153/* Check if connecting to that port is permitted and connect. */
4138Channel * 4154Channel *
4139channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname) 4155channel_connect_to_port(const char *host, u_short port, char *ctype,
4156 char *rname, int *reason, const char **errmsg)
4140{ 4157{
4141 int i, permit, permit_adm = 1; 4158 int i, permit, permit_adm = 1;
4142 4159
@@ -4161,9 +4178,11 @@ channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname
4161 if (!permit || !permit_adm) { 4178 if (!permit || !permit_adm) {
4162 logit("Received request to connect to host %.100s port %d, " 4179 logit("Received request to connect to host %.100s port %d, "
4163 "but the request was denied.", host, port); 4180 "but the request was denied.", host, port);
4181 if (reason != NULL)
4182 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
4164 return NULL; 4183 return NULL;
4165 } 4184 }
4166 return connect_to(host, port, ctype, rname); 4185 return connect_to_reason(host, port, ctype, rname, reason, errmsg);
4167} 4186}
4168 4187
4169/* Check if connecting to that path is permitted and connect. */ 4188/* Check if connecting to that path is permitted and connect. */
diff --git a/channels.h b/channels.h
index 09c3c3655..ce43236d5 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.120 2016/10/18 17:32:54 dtucker Exp $ */ 1/* $OpenBSD: channels.h,v 1.121 2017/02/01 02:59:09 dtucker Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -275,7 +275,8 @@ void channel_update_permitted_opens(int, int);
275void channel_clear_permitted_opens(void); 275void channel_clear_permitted_opens(void);
276void channel_clear_adm_permitted_opens(void); 276void channel_clear_adm_permitted_opens(void);
277void channel_print_adm_permitted_opens(void); 277void channel_print_adm_permitted_opens(void);
278Channel *channel_connect_to_port(const char *, u_short, char *, char *); 278Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *,
279 const char **);
279Channel *channel_connect_to_path(const char *, char *, char *); 280Channel *channel_connect_to_path(const char *, char *, char *);
280Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); 281Channel *channel_connect_stdio_fwd(const char*, u_short, int, int);
281Channel *channel_connect_by_listen_address(const char *, u_short, 282Channel *channel_connect_by_listen_address(const char *, u_short,
diff --git a/serverloop.c b/serverloop.c
index bdb944fa3..2976f5594 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.190 2017/01/04 05:37:40 djm Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.191 2017/02/01 02:59:09 dtucker Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -430,7 +430,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
430} 430}
431 431
432static Channel * 432static Channel *
433server_request_direct_tcpip(void) 433server_request_direct_tcpip(int *reason, const char **errmsg)
434{ 434{
435 Channel *c = NULL; 435 Channel *c = NULL;
436 char *target, *originator; 436 char *target, *originator;
@@ -449,11 +449,13 @@ server_request_direct_tcpip(void)
449 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && 449 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
450 !no_port_forwarding_flag && !options.disable_forwarding) { 450 !no_port_forwarding_flag && !options.disable_forwarding) {
451 c = channel_connect_to_port(target, target_port, 451 c = channel_connect_to_port(target, target_port,
452 "direct-tcpip", "direct-tcpip"); 452 "direct-tcpip", "direct-tcpip", reason, errmsg);
453 } else { 453 } else {
454 logit("refused local port forward: " 454 logit("refused local port forward: "
455 "originator %s port %d, target %s port %d", 455 "originator %s port %d, target %s port %d",
456 originator, originator_port, target, target_port); 456 originator, originator_port, target, target_port);
457 if (reason != NULL)
458 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
457 } 459 }
458 460
459 free(originator); 461 free(originator);
@@ -581,7 +583,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
581{ 583{
582 Channel *c = NULL; 584 Channel *c = NULL;
583 char *ctype; 585 char *ctype;
584 int rchan; 586 const char *errmsg = NULL;
587 int rchan, reason = SSH2_OPEN_CONNECT_FAILED;
585 u_int rmaxpack, rwindow, len; 588 u_int rmaxpack, rwindow, len;
586 589
587 ctype = packet_get_string(&len); 590 ctype = packet_get_string(&len);
@@ -595,7 +598,7 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
595 if (strcmp(ctype, "session") == 0) { 598 if (strcmp(ctype, "session") == 0) {
596 c = server_request_session(); 599 c = server_request_session();
597 } else if (strcmp(ctype, "direct-tcpip") == 0) { 600 } else if (strcmp(ctype, "direct-tcpip") == 0) {
598 c = server_request_direct_tcpip(); 601 c = server_request_direct_tcpip(&reason, &errmsg);
599 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { 602 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
600 c = server_request_direct_streamlocal(); 603 c = server_request_direct_streamlocal();
601 } else if (strcmp(ctype, "tun@openssh.com") == 0) { 604 } else if (strcmp(ctype, "tun@openssh.com") == 0) {
@@ -618,9 +621,9 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
618 debug("server_input_channel_open: failure %s", ctype); 621 debug("server_input_channel_open: failure %s", ctype);
619 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 622 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
620 packet_put_int(rchan); 623 packet_put_int(rchan);
621 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 624 packet_put_int(reason);
622 if (!(datafellows & SSH_BUG_OPENFAILURE)) { 625 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
623 packet_put_cstring("open failed"); 626 packet_put_cstring(errmsg ? errmsg : "open failed");
624 packet_put_cstring(""); 627 packet_put_cstring("");
625 } 628 }
626 packet_send(); 629 packet_send();