summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/sshconnect.c b/sshconnect.c
index 1183ffe0e..27daef74f 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.314 2019/02/27 19:37:01 markus Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.319 2019/09/13 04:31:19 djm 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
@@ -56,7 +56,6 @@
56#include "compat.h" 56#include "compat.h"
57#include "sshkey.h" 57#include "sshkey.h"
58#include "sshconnect.h" 58#include "sshconnect.h"
59#include "hostfile.h"
60#include "log.h" 59#include "log.h"
61#include "misc.h" 60#include "misc.h"
62#include "readconf.h" 61#include "readconf.h"
@@ -87,14 +86,18 @@ static void warn_changed_key(struct sshkey *);
87/* Expand a proxy command */ 86/* Expand a proxy command */
88static char * 87static char *
89expand_proxy_command(const char *proxy_command, const char *user, 88expand_proxy_command(const char *proxy_command, const char *user,
90 const char *host, int port) 89 const char *host, const char *host_arg, int port)
91{ 90{
92 char *tmp, *ret, strport[NI_MAXSERV]; 91 char *tmp, *ret, strport[NI_MAXSERV];
93 92
94 snprintf(strport, sizeof strport, "%d", port); 93 snprintf(strport, sizeof strport, "%d", port);
95 xasprintf(&tmp, "exec %s", proxy_command); 94 xasprintf(&tmp, "exec %s", proxy_command);
96 ret = percent_expand(tmp, "h", host, "p", strport, 95 ret = percent_expand(tmp,
97 "r", options.user, (char *)NULL); 96 "h", host,
97 "n", host_arg,
98 "p", strport,
99 "r", options.user,
100 (char *)NULL);
98 free(tmp); 101 free(tmp);
99 return ret; 102 return ret;
100} 103}
@@ -122,8 +125,8 @@ stderr_null(void)
122 * a connected fd back to us. 125 * a connected fd back to us.
123 */ 126 */
124static int 127static int
125ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port, 128ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host,
126 const char *proxy_command) 129 const char *host_arg, u_short port, const char *proxy_command)
127{ 130{
128 char *command_string; 131 char *command_string;
129 int sp[2], sock; 132 int sp[2], sock;
@@ -133,12 +136,12 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
133 if ((shell = getenv("SHELL")) == NULL) 136 if ((shell = getenv("SHELL")) == NULL)
134 shell = _PATH_BSHELL; 137 shell = _PATH_BSHELL;
135 138
136 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) 139 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == -1)
137 fatal("Could not create socketpair to communicate with " 140 fatal("Could not create socketpair to communicate with "
138 "proxy dialer: %.100s", strerror(errno)); 141 "proxy dialer: %.100s", strerror(errno));
139 142
140 command_string = expand_proxy_command(proxy_command, options.user, 143 command_string = expand_proxy_command(proxy_command, options.user,
141 host, port); 144 host_arg, host, port);
142 debug("Executing proxy dialer command: %.500s", command_string); 145 debug("Executing proxy dialer command: %.500s", command_string);
143 146
144 /* Fork and execute the proxy command. */ 147 /* Fork and execute the proxy command. */
@@ -148,11 +151,11 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
148 close(sp[1]); 151 close(sp[1]);
149 /* Redirect stdin and stdout. */ 152 /* Redirect stdin and stdout. */
150 if (sp[0] != 0) { 153 if (sp[0] != 0) {
151 if (dup2(sp[0], 0) < 0) 154 if (dup2(sp[0], 0) == -1)
152 perror("dup2 stdin"); 155 perror("dup2 stdin");
153 } 156 }
154 if (sp[0] != 1) { 157 if (sp[0] != 1) {
155 if (dup2(sp[0], 1) < 0) 158 if (dup2(sp[0], 1) == -1)
156 perror("dup2 stdout"); 159 perror("dup2 stdout");
157 } 160 }
158 if (sp[0] >= 2) 161 if (sp[0] >= 2)
@@ -180,7 +183,7 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
180 exit(1); 183 exit(1);
181 } 184 }
182 /* Parent. */ 185 /* Parent. */
183 if (pid < 0) 186 if (pid == -1)
184 fatal("fork failed: %.100s", strerror(errno)); 187 fatal("fork failed: %.100s", strerror(errno));
185 close(sp[0]); 188 close(sp[0]);
186 free(command_string); 189 free(command_string);
@@ -204,8 +207,8 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
204 * Connect to the given ssh server using a proxy command. 207 * Connect to the given ssh server using a proxy command.
205 */ 208 */
206static int 209static int
207ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port, 210ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg,
208 const char *proxy_command) 211 u_short port, const char *proxy_command)
209{ 212{
210 char *command_string; 213 char *command_string;
211 int pin[2], pout[2]; 214 int pin[2], pout[2];
@@ -216,12 +219,12 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
216 shell = _PATH_BSHELL; 219 shell = _PATH_BSHELL;
217 220
218 /* Create pipes for communicating with the proxy. */ 221 /* Create pipes for communicating with the proxy. */
219 if (pipe(pin) < 0 || pipe(pout) < 0) 222 if (pipe(pin) == -1 || pipe(pout) == -1)
220 fatal("Could not create pipes to communicate with the proxy: %.100s", 223 fatal("Could not create pipes to communicate with the proxy: %.100s",
221 strerror(errno)); 224 strerror(errno));
222 225
223 command_string = expand_proxy_command(proxy_command, options.user, 226 command_string = expand_proxy_command(proxy_command, options.user,
224 host, port); 227 host_arg, host, port);
225 debug("Executing proxy command: %.500s", command_string); 228 debug("Executing proxy command: %.500s", command_string);
226 229
227 /* Fork and execute the proxy command. */ 230 /* Fork and execute the proxy command. */
@@ -231,12 +234,12 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
231 /* Redirect stdin and stdout. */ 234 /* Redirect stdin and stdout. */
232 close(pin[1]); 235 close(pin[1]);
233 if (pin[0] != 0) { 236 if (pin[0] != 0) {
234 if (dup2(pin[0], 0) < 0) 237 if (dup2(pin[0], 0) == -1)
235 perror("dup2 stdin"); 238 perror("dup2 stdin");
236 close(pin[0]); 239 close(pin[0]);
237 } 240 }
238 close(pout[0]); 241 close(pout[0]);
239 if (dup2(pout[1], 1) < 0) 242 if (dup2(pout[1], 1) == -1)
240 perror("dup2 stdout"); 243 perror("dup2 stdout");
241 /* Cannot be 1 because pin allocated two descriptors. */ 244 /* Cannot be 1 because pin allocated two descriptors. */
242 close(pout[1]); 245 close(pout[1]);
@@ -262,7 +265,7 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
262 exit(1); 265 exit(1);
263 } 266 }
264 /* Parent. */ 267 /* Parent. */
265 if (pid < 0) 268 if (pid == -1)
266 fatal("fork failed: %.100s", strerror(errno)); 269 fatal("fork failed: %.100s", strerror(errno));
267 else 270 else
268 proxy_command_pid = pid; /* save pid to clean up later */ 271 proxy_command_pid = pid; /* save pid to clean up later */
@@ -371,7 +374,7 @@ ssh_create_socket(struct addrinfo *ai)
371 char ntop[NI_MAXHOST]; 374 char ntop[NI_MAXHOST];
372 375
373 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 376 sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
374 if (sock < 0) { 377 if (sock == -1) {
375 error("socket: %s", strerror(errno)); 378 error("socket: %s", strerror(errno));
376 return -1; 379 return -1;
377 } 380 }
@@ -532,20 +535,20 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
532 /* Set SO_KEEPALIVE if requested. */ 535 /* Set SO_KEEPALIVE if requested. */
533 if (want_keepalive && 536 if (want_keepalive &&
534 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, 537 setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
535 sizeof(on)) < 0) 538 sizeof(on)) == -1)
536 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 539 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
537 540
538 /* Set the connection. */ 541 /* Set the connection. */
539 if (ssh_packet_set_connection(ssh, sock, sock) == NULL) 542 if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
540 return -1; /* ssh_packet_set_connection logs error */ 543 return -1; /* ssh_packet_set_connection logs error */
541 544
542 return 0; 545 return 0;
543} 546}
544 547
545int 548int
546ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs, 549ssh_connect(struct ssh *ssh, const char *host, const char *host_arg,
547 struct sockaddr_storage *hostaddr, u_short port, int family, 550 struct addrinfo *addrs, struct sockaddr_storage *hostaddr, u_short port,
548 int connection_attempts, int *timeout_ms, int want_keepalive) 551 int family, int connection_attempts, int *timeout_ms, int want_keepalive)
549{ 552{
550 int in, out; 553 int in, out;
551 554
@@ -553,8 +556,8 @@ ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs,
553 return ssh_connect_direct(ssh, host, addrs, hostaddr, port, 556 return ssh_connect_direct(ssh, host, addrs, hostaddr, port,
554 family, connection_attempts, timeout_ms, want_keepalive); 557 family, connection_attempts, timeout_ms, want_keepalive);
555 } else if (strcmp(options.proxy_command, "-") == 0) { 558 } else if (strcmp(options.proxy_command, "-") == 0) {
556 if ((in = dup(STDIN_FILENO)) < 0 || 559 if ((in = dup(STDIN_FILENO)) == -1 ||
557 (out = dup(STDOUT_FILENO)) < 0) { 560 (out = dup(STDOUT_FILENO)) == -1) {
558 if (in >= 0) 561 if (in >= 0)
559 close(in); 562 close(in);
560 error("%s: dup() in/out failed", __func__); 563 error("%s: dup() in/out failed", __func__);
@@ -564,10 +567,11 @@ ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs,
564 return -1; /* ssh_packet_set_connection logs error */ 567 return -1; /* ssh_packet_set_connection logs error */
565 return 0; 568 return 0;
566 } else if (options.proxy_use_fdpass) { 569 } else if (options.proxy_use_fdpass) {
567 return ssh_proxy_fdpass_connect(ssh, host, port, 570 return ssh_proxy_fdpass_connect(ssh, host, host_arg, port,
568 options.proxy_command); 571 options.proxy_command);
569 } 572 }
570 return ssh_proxy_connect(ssh, host, port, options.proxy_command); 573 return ssh_proxy_connect(ssh, host, host_arg, port,
574 options.proxy_command);
571} 575}
572 576
573/* defaults to 'no' */ 577/* defaults to 'no' */
@@ -789,7 +793,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
789 ip_status = check_key_in_hostkeys(ip_hostkeys, host_key, 793 ip_status = check_key_in_hostkeys(ip_hostkeys, host_key,
790 &ip_found); 794 &ip_found);
791 if (host_status == HOST_CHANGED && 795 if (host_status == HOST_CHANGED &&
792 (ip_status != HOST_CHANGED || 796 (ip_status != HOST_CHANGED ||
793 (ip_found != NULL && 797 (ip_found != NULL &&
794 !sshkey_equal(ip_found->key, host_found->key)))) 798 !sshkey_equal(ip_found->key, host_found->key))))
795 host_ip_differ = 1; 799 host_ip_differ = 1;
@@ -1299,6 +1303,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
1299 ssh_kex2(ssh, host, hostaddr, port); 1303 ssh_kex2(ssh, host, hostaddr, port);
1300 ssh_userauth2(ssh, local_user, server_user, host, sensitive); 1304 ssh_userauth2(ssh, local_user, server_user, host, sensitive);
1301 free(local_user); 1305 free(local_user);
1306 free(host);
1302} 1307}
1303 1308
1304/* print all known host keys for a given host, but skip keys of given type */ 1309/* print all known host keys for a given host, but skip keys of given type */
@@ -1407,7 +1412,7 @@ ssh_local_cmd(const char *args)
1407} 1412}
1408 1413
1409void 1414void
1410maybe_add_key_to_agent(char *authfile, const struct sshkey *private, 1415maybe_add_key_to_agent(char *authfile, struct sshkey *private,
1411 char *comment, char *passphrase) 1416 char *comment, char *passphrase)
1412{ 1417{
1413 int auth_sock = -1, r; 1418 int auth_sock = -1, r;