diff options
author | Colin Watson <cjwatson@debian.org> | 2017-04-02 01:26:17 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-04-02 01:54:08 +0100 |
commit | 20adc7e0fc13ff9c7d270db250aac1fa140e3851 (patch) | |
tree | 5d9f06b0ff195db88093037d9102f0cdcf3884c6 /channels.c | |
parent | af27669f905133925224acc753067dea710881dd (diff) | |
parent | ec338656a3d6b21bb87f3b6367b232d297f601e5 (diff) |
New upstream release (7.5p1)
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 81 |
1 files changed, 67 insertions, 14 deletions
diff --git a/channels.c b/channels.c index bef8ad6aa..d030fcdd9 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 | */ | ||
4030 | static Channel * | 4033 | static Channel * |
4031 | connect_to(const char *name, int port, char *ctype, char *rname) | 4034 | connect_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 */ | ||
4105 | static Channel * | ||
4106 | connect_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. */ |
4138 | Channel * | 4154 | Channel * |
4139 | channel_connect_to_port(const char *host, u_short port, char *ctype, char *rname) | 4155 | channel_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. */ |
@@ -4354,6 +4373,33 @@ connect_local_xsocket(u_int dnr) | |||
4354 | return connect_local_xsocket_path(buf); | 4373 | return connect_local_xsocket_path(buf); |
4355 | } | 4374 | } |
4356 | 4375 | ||
4376 | #ifdef __APPLE__ | ||
4377 | static int | ||
4378 | is_path_to_xsocket(const char *display, char *path, size_t pathlen) | ||
4379 | { | ||
4380 | struct stat sbuf; | ||
4381 | |||
4382 | if (strlcpy(path, display, pathlen) >= pathlen) { | ||
4383 | error("%s: display path too long", __func__); | ||
4384 | return 0; | ||
4385 | } | ||
4386 | if (display[0] != '/') | ||
4387 | return 0; | ||
4388 | if (stat(path, &sbuf) == 0) { | ||
4389 | return 1; | ||
4390 | } else { | ||
4391 | char *dot = strrchr(path, '.'); | ||
4392 | if (dot != NULL) { | ||
4393 | *dot = '\0'; | ||
4394 | if (stat(path, &sbuf) == 0) { | ||
4395 | return 1; | ||
4396 | } | ||
4397 | } | ||
4398 | } | ||
4399 | return 0; | ||
4400 | } | ||
4401 | #endif | ||
4402 | |||
4357 | int | 4403 | int |
4358 | x11_connect_display(void) | 4404 | x11_connect_display(void) |
4359 | { | 4405 | { |
@@ -4375,15 +4421,22 @@ x11_connect_display(void) | |||
4375 | * connection to the real X server. | 4421 | * connection to the real X server. |
4376 | */ | 4422 | */ |
4377 | 4423 | ||
4378 | /* Check if the display is from launchd. */ | ||
4379 | #ifdef __APPLE__ | 4424 | #ifdef __APPLE__ |
4380 | if (strncmp(display, "/tmp/launch", 11) == 0) { | 4425 | /* Check if display is a path to a socket (as set by launchd). */ |
4381 | sock = connect_local_xsocket_path(display); | 4426 | { |
4382 | if (sock < 0) | 4427 | char path[PATH_MAX]; |
4383 | return -1; | ||
4384 | 4428 | ||
4385 | /* OK, we now have a connection to the display. */ | 4429 | if (is_path_to_xsocket(display, path, sizeof(path))) { |
4386 | return sock; | 4430 | debug("x11_connect_display: $DISPLAY is launchd"); |
4431 | |||
4432 | /* Create a socket. */ | ||
4433 | sock = connect_local_xsocket_path(path); | ||
4434 | if (sock < 0) | ||
4435 | return -1; | ||
4436 | |||
4437 | /* OK, we now have a connection to the display. */ | ||
4438 | return sock; | ||
4439 | } | ||
4387 | } | 4440 | } |
4388 | #endif | 4441 | #endif |
4389 | /* | 4442 | /* |