diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 69 |
1 files changed, 20 insertions, 49 deletions
diff --git a/sshconnect.c b/sshconnect.c index 15d8b807e..d3656e47a 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.297 2018/02/23 15:58:38 markus Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.304 2018/07/27 05:34:42 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 |
@@ -49,14 +49,12 @@ | |||
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #include "xmalloc.h" | 51 | #include "xmalloc.h" |
52 | #include "key.h" | ||
53 | #include "hostfile.h" | 52 | #include "hostfile.h" |
54 | #include "ssh.h" | 53 | #include "ssh.h" |
55 | #include "buffer.h" | 54 | #include "sshbuf.h" |
56 | #include "packet.h" | 55 | #include "packet.h" |
57 | #include "uidswap.h" | ||
58 | #include "compat.h" | 56 | #include "compat.h" |
59 | #include "key.h" | 57 | #include "sshkey.h" |
60 | #include "sshconnect.h" | 58 | #include "sshconnect.h" |
61 | #include "hostfile.h" | 59 | #include "hostfile.h" |
62 | #include "log.h" | 60 | #include "log.h" |
@@ -82,8 +80,6 @@ static pid_t proxy_command_pid = 0; | |||
82 | /* import */ | 80 | /* import */ |
83 | extern Options options; | 81 | extern Options options; |
84 | extern char *__progname; | 82 | extern char *__progname; |
85 | extern uid_t original_real_uid; | ||
86 | extern uid_t original_effective_uid; | ||
87 | 83 | ||
88 | static int show_other_keys(struct hostkeys *, struct sshkey *); | 84 | static int show_other_keys(struct hostkeys *, struct sshkey *); |
89 | static void warn_changed_key(struct sshkey *); | 85 | static void warn_changed_key(struct sshkey *); |
@@ -131,9 +127,6 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port, | |||
131 | if ((pid = fork()) == 0) { | 127 | if ((pid = fork()) == 0) { |
132 | char *argv[10]; | 128 | char *argv[10]; |
133 | 129 | ||
134 | /* Child. Permanently give up superuser privileges. */ | ||
135 | permanently_drop_suid(original_real_uid); | ||
136 | |||
137 | close(sp[1]); | 130 | close(sp[1]); |
138 | /* Redirect stdin and stdout. */ | 131 | /* Redirect stdin and stdout. */ |
139 | if (sp[0] != 0) { | 132 | if (sp[0] != 0) { |
@@ -213,9 +206,6 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port, | |||
213 | if ((pid = fork()) == 0) { | 206 | if ((pid = fork()) == 0) { |
214 | char *argv[10]; | 207 | char *argv[10]; |
215 | 208 | ||
216 | /* Child. Permanently give up superuser privileges. */ | ||
217 | permanently_drop_suid(original_real_uid); | ||
218 | |||
219 | /* Redirect stdin and stdout. */ | 209 | /* Redirect stdin and stdout. */ |
220 | close(pin[1]); | 210 | close(pin[1]); |
221 | if (pin[0] != 0) { | 211 | if (pin[0] != 0) { |
@@ -277,7 +267,7 @@ ssh_kill_proxy_command(void) | |||
277 | #ifdef HAVE_IFADDRS_H | 267 | #ifdef HAVE_IFADDRS_H |
278 | /* | 268 | /* |
279 | * Search a interface address list (returned from getifaddrs(3)) for an | 269 | * Search a interface address list (returned from getifaddrs(3)) for an |
280 | * address that matches the desired address family on the specifed interface. | 270 | * address that matches the desired address family on the specified interface. |
281 | * Returns 0 and fills in *resultp and *rlenp on success. Returns -1 on failure. | 271 | * Returns 0 and fills in *resultp and *rlenp on success. Returns -1 on failure. |
282 | */ | 272 | */ |
283 | static int | 273 | static int |
@@ -338,12 +328,12 @@ check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs, | |||
338 | #endif | 328 | #endif |
339 | 329 | ||
340 | /* | 330 | /* |
341 | * Creates a (possibly privileged) socket for use as the ssh connection. | 331 | * Creates a socket for use as the ssh connection. |
342 | */ | 332 | */ |
343 | static int | 333 | static int |
344 | ssh_create_socket(int privileged, struct addrinfo *ai) | 334 | ssh_create_socket(struct addrinfo *ai) |
345 | { | 335 | { |
346 | int sock, r, oerrno; | 336 | int sock, r; |
347 | struct sockaddr_storage bindaddr; | 337 | struct sockaddr_storage bindaddr; |
348 | socklen_t bindaddrlen = 0; | 338 | socklen_t bindaddrlen = 0; |
349 | struct addrinfo hints, *res = NULL; | 339 | struct addrinfo hints, *res = NULL; |
@@ -360,8 +350,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai) | |||
360 | fcntl(sock, F_SETFD, FD_CLOEXEC); | 350 | fcntl(sock, F_SETFD, FD_CLOEXEC); |
361 | 351 | ||
362 | /* Bind the socket to an alternative local IP address */ | 352 | /* Bind the socket to an alternative local IP address */ |
363 | if (options.bind_address == NULL && options.bind_interface == NULL && | 353 | if (options.bind_address == NULL && options.bind_interface == NULL) |
364 | !privileged) | ||
365 | return sock; | 354 | return sock; |
366 | 355 | ||
367 | if (options.bind_address != NULL) { | 356 | if (options.bind_address != NULL) { |
@@ -410,22 +399,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai) | |||
410 | ssh_gai_strerror(r)); | 399 | ssh_gai_strerror(r)); |
411 | goto fail; | 400 | goto fail; |
412 | } | 401 | } |
413 | /* | 402 | if (bind(sock, (struct sockaddr *)&bindaddr, bindaddrlen) != 0) { |
414 | * If we are running as root and want to connect to a privileged | ||
415 | * port, bind our own socket to a privileged port. | ||
416 | */ | ||
417 | if (privileged) { | ||
418 | PRIV_START; | ||
419 | r = bindresvport_sa(sock, | ||
420 | bindaddrlen == 0 ? NULL : (struct sockaddr *)&bindaddr); | ||
421 | oerrno = errno; | ||
422 | PRIV_END; | ||
423 | if (r < 0) { | ||
424 | error("bindresvport_sa %s: %s", ntop, | ||
425 | strerror(oerrno)); | ||
426 | goto fail; | ||
427 | } | ||
428 | } else if (bind(sock, (struct sockaddr *)&bindaddr, bindaddrlen) != 0) { | ||
429 | error("bind %s: %s", ntop, strerror(errno)); | 403 | error("bind %s: %s", ntop, strerror(errno)); |
430 | goto fail; | 404 | goto fail; |
431 | } | 405 | } |
@@ -515,9 +489,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr, | |||
515 | /* | 489 | /* |
516 | * Opens a TCP/IP connection to the remote server on the given host. | 490 | * Opens a TCP/IP connection to the remote server on the given host. |
517 | * The address of the remote host will be returned in hostaddr. | 491 | * The address of the remote host will be returned in hostaddr. |
518 | * If port is 0, the default port will be used. If needpriv is true, | 492 | * If port is 0, the default port will be used. |
519 | * a privileged port will be allocated to make the connection. | ||
520 | * This requires super-user privileges if needpriv is true. | ||
521 | * Connection_attempts specifies the maximum number of tries (one per | 493 | * Connection_attempts specifies the maximum number of tries (one per |
522 | * second). If proxy_command is non-NULL, it specifies the command (with %h | 494 | * second). If proxy_command is non-NULL, it specifies the command (with %h |
523 | * and %p substituted for host and port, respectively) to use to contact | 495 | * and %p substituted for host and port, respectively) to use to contact |
@@ -526,14 +498,14 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr, | |||
526 | static int | 498 | static int |
527 | ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, | 499 | ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, |
528 | struct sockaddr_storage *hostaddr, u_short port, int family, | 500 | struct sockaddr_storage *hostaddr, u_short port, int family, |
529 | int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) | 501 | int connection_attempts, int *timeout_ms, int want_keepalive) |
530 | { | 502 | { |
531 | int on = 1; | 503 | int on = 1; |
532 | int oerrno, sock = -1, attempt; | 504 | int oerrno, sock = -1, attempt; |
533 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 505 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
534 | struct addrinfo *ai; | 506 | struct addrinfo *ai; |
535 | 507 | ||
536 | debug2("%s: needpriv %d", __func__, needpriv); | 508 | debug2("%s", __func__); |
537 | memset(ntop, 0, sizeof(ntop)); | 509 | memset(ntop, 0, sizeof(ntop)); |
538 | memset(strport, 0, sizeof(strport)); | 510 | memset(strport, 0, sizeof(strport)); |
539 | 511 | ||
@@ -565,7 +537,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, | |||
565 | host, ntop, strport); | 537 | host, ntop, strport); |
566 | 538 | ||
567 | /* Create a socket for connecting. */ | 539 | /* Create a socket for connecting. */ |
568 | sock = ssh_create_socket(needpriv, ai); | 540 | sock = ssh_create_socket(ai); |
569 | if (sock < 0) { | 541 | if (sock < 0) { |
570 | /* Any error is already output */ | 542 | /* Any error is already output */ |
571 | errno = 0; | 543 | errno = 0; |
@@ -615,12 +587,11 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop, | |||
615 | int | 587 | int |
616 | ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs, | 588 | ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs, |
617 | struct sockaddr_storage *hostaddr, u_short port, int family, | 589 | struct sockaddr_storage *hostaddr, u_short port, int family, |
618 | int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) | 590 | int connection_attempts, int *timeout_ms, int want_keepalive) |
619 | { | 591 | { |
620 | if (options.proxy_command == NULL) { | 592 | if (options.proxy_command == NULL) { |
621 | return ssh_connect_direct(ssh, host, addrs, hostaddr, port, | 593 | return ssh_connect_direct(ssh, host, addrs, hostaddr, port, |
622 | family, connection_attempts, timeout_ms, want_keepalive, | 594 | family, connection_attempts, timeout_ms, want_keepalive); |
623 | needpriv); | ||
624 | } else if (strcmp(options.proxy_command, "-") == 0) { | 595 | } else if (strcmp(options.proxy_command, "-") == 0) { |
625 | if ((ssh_packet_set_connection(ssh, | 596 | if ((ssh_packet_set_connection(ssh, |
626 | STDIN_FILENO, STDOUT_FILENO)) == NULL) | 597 | STDIN_FILENO, STDOUT_FILENO)) == NULL) |
@@ -767,11 +738,11 @@ check_host_cert(const char *host, const struct sshkey *host_key) | |||
767 | { | 738 | { |
768 | const char *reason; | 739 | const char *reason; |
769 | 740 | ||
770 | if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) { | 741 | if (sshkey_cert_check_authority(host_key, 1, 0, host, &reason) != 0) { |
771 | error("%s", reason); | 742 | error("%s", reason); |
772 | return 0; | 743 | return 0; |
773 | } | 744 | } |
774 | if (buffer_len(host_key->cert->critical) != 0) { | 745 | if (sshbuf_len(host_key->cert->critical) != 0) { |
775 | error("Certificate for %s contains unsupported " | 746 | error("Certificate for %s contains unsupported " |
776 | "critical options(s)", host); | 747 | "critical options(s)", host); |
777 | return 0; | 748 | return 0; |
@@ -1503,9 +1474,9 @@ show_other_keys(struct hostkeys *hostkeys, struct sshkey *key) | |||
1503 | logit("WARNING: %s key found for host %s\n" | 1474 | logit("WARNING: %s key found for host %s\n" |
1504 | "in %s:%lu\n" | 1475 | "in %s:%lu\n" |
1505 | "%s key fingerprint %s.", | 1476 | "%s key fingerprint %s.", |
1506 | key_type(found->key), | 1477 | sshkey_type(found->key), |
1507 | found->host, found->file, found->line, | 1478 | found->host, found->file, found->line, |
1508 | key_type(found->key), fp); | 1479 | sshkey_type(found->key), fp); |
1509 | if (options.visual_host_key) | 1480 | if (options.visual_host_key) |
1510 | logit("%s", ra); | 1481 | logit("%s", ra); |
1511 | free(ra); | 1482 | free(ra); |
@@ -1532,7 +1503,7 @@ warn_changed_key(struct sshkey *host_key) | |||
1532 | error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); | 1503 | error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); |
1533 | error("It is also possible that a host key has just been changed."); | 1504 | error("It is also possible that a host key has just been changed."); |
1534 | error("The fingerprint for the %s key sent by the remote host is\n%s.", | 1505 | error("The fingerprint for the %s key sent by the remote host is\n%s.", |
1535 | key_type(host_key), fp); | 1506 | sshkey_type(host_key), fp); |
1536 | error("Please contact your system administrator."); | 1507 | error("Please contact your system administrator."); |
1537 | 1508 | ||
1538 | free(fp); | 1509 | free(fp); |