summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-17 11:47:23 +1100
committerDamien Miller <djm@mindrot.org>2013-10-17 11:47:23 +1100
commit0faf747e2f77f0f7083bcd59cbed30c4b5448444 (patch)
tree1f1b80f60be01d61f284070affc314d1b97b6b69 /sshconnect.c
parentd77b81f856e078714ec6b0f86f61c20249b7ead4 (diff)
- djm@cvs.openbsd.org 2013/10/16 02:31:47
[readconf.c readconf.h roaming_client.c ssh.1 ssh.c ssh_config.5] [sshconnect.c sshconnect.h] Implement client-side hostname canonicalisation to allow an explicit search path of domain suffixes to use to convert unqualified host names to fully-qualified ones for host key matching. This is particularly useful for host certificates, which would otherwise need to list unqualified names alongside fully-qualified ones (and this causes a number of problems). "looks fine" markus@
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c74
1 files changed, 29 insertions, 45 deletions
diff --git a/sshconnect.c b/sshconnect.c
index aee38198b..3cdc46149 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.240 2013/09/19 01:26:29 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.241 2013/10/16 02:31:46 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
@@ -86,7 +86,7 @@ expand_proxy_command(const char *proxy_command, const char *user,
86{ 86{
87 char *tmp, *ret, strport[NI_MAXSERV]; 87 char *tmp, *ret, strport[NI_MAXSERV];
88 88
89 snprintf(strport, sizeof strport, "%hu", port); 89 snprintf(strport, sizeof strport, "%d", port);
90 xasprintf(&tmp, "exec %s", proxy_command); 90 xasprintf(&tmp, "exec %s", proxy_command);
91 ret = percent_expand(tmp, "h", host, "p", strport, 91 ret = percent_expand(tmp, "h", host, "p", strport,
92 "r", options.user, (char *)NULL); 92 "r", options.user, (char *)NULL);
@@ -170,8 +170,6 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
170 170
171 /* Set the connection file descriptors. */ 171 /* Set the connection file descriptors. */
172 packet_set_connection(sock, sock); 172 packet_set_connection(sock, sock);
173 packet_set_timeout(options.server_alive_interval,
174 options.server_alive_count_max);
175 173
176 return 0; 174 return 0;
177} 175}
@@ -187,16 +185,6 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
187 pid_t pid; 185 pid_t pid;
188 char *shell; 186 char *shell;
189 187
190 if (!strcmp(proxy_command, "-")) {
191 packet_set_connection(STDIN_FILENO, STDOUT_FILENO);
192 packet_set_timeout(options.server_alive_interval,
193 options.server_alive_count_max);
194 return 0;
195 }
196
197 if (options.proxy_use_fdpass)
198 return ssh_proxy_fdpass_connect(host, port, proxy_command);
199
200 if ((shell = getenv("SHELL")) == NULL || *shell == '\0') 188 if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
201 shell = _PATH_BSHELL; 189 shell = _PATH_BSHELL;
202 190
@@ -258,8 +246,6 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
258 246
259 /* Set the connection file descriptors. */ 247 /* Set the connection file descriptors. */
260 packet_set_connection(pout[0], pin[1]); 248 packet_set_connection(pout[0], pin[1]);
261 packet_set_timeout(options.server_alive_interval,
262 options.server_alive_count_max);
263 249
264 /* Indicate OK return */ 250 /* Indicate OK return */
265 return 0; 251 return 0;
@@ -429,33 +415,18 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
429 * and %p substituted for host and port, respectively) to use to contact 415 * and %p substituted for host and port, respectively) to use to contact
430 * the daemon. 416 * the daemon.
431 */ 417 */
432int 418static int
433ssh_connect(const char *host, struct sockaddr_storage * hostaddr, 419ssh_connect_direct(const char *host, struct addrinfo *aitop,
434 u_short port, int family, int connection_attempts, int *timeout_ms, 420 struct sockaddr_storage *hostaddr, u_short port, int family,
435 int want_keepalive, int needpriv, const char *proxy_command) 421 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
436{ 422{
437 int gaierr;
438 int on = 1; 423 int on = 1;
439 int sock = -1, attempt; 424 int sock = -1, attempt;
440 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 425 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
441 struct addrinfo hints, *ai, *aitop; 426 struct addrinfo *ai;
442 427
443 debug2("ssh_connect: needpriv %d", needpriv); 428 debug2("ssh_connect: needpriv %d", needpriv);
444 429
445 /* If a proxy command is given, connect using it. */
446 if (proxy_command != NULL)
447 return ssh_proxy_connect(host, port, proxy_command);
448
449 /* No proxy command. */
450
451 memset(&hints, 0, sizeof(hints));
452 hints.ai_family = family;
453 hints.ai_socktype = SOCK_STREAM;
454 snprintf(strport, sizeof strport, "%u", port);
455 if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
456 fatal("%s: Could not resolve hostname %.100s: %s", __progname,
457 host, ssh_gai_strerror(gaierr));
458
459 for (attempt = 0; attempt < connection_attempts; attempt++) { 430 for (attempt = 0; attempt < connection_attempts; attempt++) {
460 if (attempt > 0) { 431 if (attempt > 0) {
461 /* Sleep a moment before retrying. */ 432 /* Sleep a moment before retrying. */
@@ -467,7 +438,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
467 * sequence until the connection succeeds. 438 * sequence until the connection succeeds.
468 */ 439 */
469 for (ai = aitop; ai; ai = ai->ai_next) { 440 for (ai = aitop; ai; ai = ai->ai_next) {
470 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 441 if (ai->ai_family != AF_INET &&
442 ai->ai_family != AF_INET6)
471 continue; 443 continue;
472 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, 444 if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
473 ntop, sizeof(ntop), strport, sizeof(strport), 445 ntop, sizeof(ntop), strport, sizeof(strport),
@@ -500,8 +472,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
500 break; /* Successful connection. */ 472 break; /* Successful connection. */
501 } 473 }
502 474
503 freeaddrinfo(aitop);
504
505 /* Return failure if we didn't get a successful connection. */ 475 /* Return failure if we didn't get a successful connection. */
506 if (sock == -1) { 476 if (sock == -1) {
507 error("ssh: connect to host %s port %s: %s", 477 error("ssh: connect to host %s port %s: %s",
@@ -519,12 +489,28 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
519 489
520 /* Set the connection. */ 490 /* Set the connection. */
521 packet_set_connection(sock, sock); 491 packet_set_connection(sock, sock);
522 packet_set_timeout(options.server_alive_interval,
523 options.server_alive_count_max);
524 492
525 return 0; 493 return 0;
526} 494}
527 495
496int
497ssh_connect(const char *host, struct addrinfo *addrs,
498 struct sockaddr_storage *hostaddr, u_short port, int family,
499 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
500{
501 if (options.proxy_command == NULL) {
502 return ssh_connect_direct(host, addrs, hostaddr, port, family,
503 connection_attempts, timeout_ms, want_keepalive, needpriv);
504 } else if (strcmp(options.proxy_command, "-") == 0) {
505 packet_set_connection(STDIN_FILENO, STDOUT_FILENO);
506 return 0; /* Always succeeds */
507 } else if (options.proxy_use_fdpass) {
508 return ssh_proxy_fdpass_connect(host, port,
509 options.proxy_command);
510 }
511 return ssh_proxy_connect(host, port, options.proxy_command);
512}
513
528static void 514static void
529send_client_banner(int connection_out, int minor1) 515send_client_banner(int connection_out, int minor1)
530{ 516{
@@ -1265,7 +1251,7 @@ void
1265ssh_login(Sensitive *sensitive, const char *orighost, 1251ssh_login(Sensitive *sensitive, const char *orighost,
1266 struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) 1252 struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms)
1267{ 1253{
1268 char *host, *cp; 1254 char *host;
1269 char *server_user, *local_user; 1255 char *server_user, *local_user;
1270 1256
1271 local_user = xstrdup(pw->pw_name); 1257 local_user = xstrdup(pw->pw_name);
@@ -1273,9 +1259,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
1273 1259
1274 /* Convert the user-supplied hostname into all lowercase. */ 1260 /* Convert the user-supplied hostname into all lowercase. */
1275 host = xstrdup(orighost); 1261 host = xstrdup(orighost);
1276 for (cp = host; *cp; cp++) 1262 lowercase(host);
1277 if (isupper(*cp))
1278 *cp = (char)tolower(*cp);
1279 1263
1280 /* Exchange protocol version identification strings with the server. */ 1264 /* Exchange protocol version identification strings with the server. */
1281 ssh_exchange_identification(timeout_ms); 1265 ssh_exchange_identification(timeout_ms);