diff options
Diffstat (limited to 'crypto/openssh/sshconnect.c')
-rw-r--r-- | crypto/openssh/sshconnect.c | 75 |
1 files changed, 27 insertions, 48 deletions
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index 1a6f8e4..707a9c0 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.119 2002/01/21 15:13:51 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.125 2002/06/19 00:27:55 deraadt Exp $"); RCSID("$FreeBSD$"); #include <openssl/bn.h> @@ -37,27 +37,20 @@ RCSID("$FreeBSD$"); char *client_version_string = NULL; char *server_version_string = NULL; +/* import */ extern Options options; extern char *__progname; +extern uid_t original_real_uid; +extern uid_t original_effective_uid; static const char * -sockaddr_ntop(struct sockaddr *sa) +sockaddr_ntop(struct sockaddr *sa, socklen_t salen) { - void *addr; - static char addrbuf[INET6_ADDRSTRLEN]; + static char addrbuf[NI_MAXHOST]; - switch (sa->sa_family) { - case AF_INET: - addr = &((struct sockaddr_in *)sa)->sin_addr; - break; - case AF_INET6: - addr = &((struct sockaddr_in6 *)sa)->sin6_addr; - break; - default: - /* This case should be protected against elsewhere */ - abort(); /* XXX abort is bad -- do something else */ - } - inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf)); + if (getnameinfo(sa, salen, addrbuf, sizeof(addrbuf), NULL, 0, + NI_NUMERICHOST) != 0) + fatal("sockaddr_ntop: getnameinfo NI_NUMERICHOST failed"); return addrbuf; } @@ -65,8 +58,7 @@ sockaddr_ntop(struct sockaddr *sa) * Connect to the given ssh server using a proxy command. */ static int -ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, - const char *proxy_command) +ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) { Buffer command; const char *cp; @@ -116,7 +108,8 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, char *argv[10]; /* Child. Permanently give up superuser privileges. */ - permanently_set_uid(pw); + seteuid(original_real_uid); + setuid(original_real_uid); /* Redirect stdin and stdout. */ close(pin[1]); @@ -166,7 +159,7 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, * Creates a (possibly privileged) socket for use as the ssh connection. */ static int -ssh_create_socket(struct passwd *pw, int privileged, int family) +ssh_create_socket(int privileged, int family) { int sock, gaierr; struct addrinfo hints, *res; @@ -177,22 +170,18 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) */ if (privileged) { int p = IPPORT_RESERVED - 1; + PRIV_START; sock = rresvport_af(&p, family); + PRIV_END; if (sock < 0) error("rresvport: af=%d %.100s", family, strerror(errno)); else debug("Allocated local port %d.", p); return sock; } - /* - * Just create an ordinary socket on arbitrary port. We use - * the user's uid to create the socket. - */ - temporarily_use_uid(pw); sock = socket(family, SOCK_STREAM, 0); if (sock < 0) error("socket: %.100s", strerror(errno)); - restore_uid(); /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL) @@ -222,9 +211,9 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) /* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. - * If port is 0, the default port will be used. If anonymous is zero, + * If port is 0, the default port will be used. If needpriv is true, * a privileged port will be allocated to make the connection. - * This requires super-user privileges if anonymous is false. + * This requires super-user privileges if needpriv is true. * Connection_attempts specifies the maximum number of tries (one per * second). If proxy_command is non-NULL, it specifies the command (with %h * and %p substituted for host and port, respectively) to use to contact @@ -239,7 +228,7 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) int ssh_connect(const char *host, struct sockaddr_storage * hostaddr, u_short port, int family, int connection_attempts, - int anonymous, struct passwd *pw, const char *proxy_command) + int needpriv, const char *proxy_command) { int gaierr; int on = 1; @@ -255,8 +244,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, */ int full_failure = 1; - debug("ssh_connect: getuid %u geteuid %u anon %d", - (u_int) getuid(), (u_int) geteuid(), anonymous); + debug("ssh_connect: needpriv %d", needpriv); /* Get default port if port has not been set. */ if (port == 0) { @@ -268,7 +256,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, } /* If a proxy command is given, connect using it. */ if (proxy_command != NULL) - return ssh_proxy_connect(host, port, pw, proxy_command); + return ssh_proxy_connect(host, port, proxy_command); /* No proxy command. */ @@ -304,30 +292,21 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, host, ntop, strport); /* Create a socket for connecting. */ - sock = ssh_create_socket(pw, - !anonymous && geteuid() == 0, - ai->ai_family); + sock = ssh_create_socket(needpriv, ai->ai_family); if (sock < 0) /* Any error is already output */ continue; - /* Connect to the host. We use the user's uid in the - * hope that it will help with tcp_wrappers showing - * the remote uid as root. - */ - temporarily_use_uid(pw); if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); - restore_uid(); break; } else { if (errno == ECONNREFUSED) full_failure = 0; log("ssh: connect to address %s port %s: %s", - sockaddr_ntop(ai->ai_addr), strport, - strerror(errno)); - restore_uid(); + sockaddr_ntop(ai->ai_addr, ai->ai_addrlen), + strport, strerror(errno)); /* * Close the failed socket; there appear to * be some problems when reusing a socket for @@ -785,7 +764,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, len = strlen(msg); snprintf(msg + len, sizeof(msg) - len, "\nMatching host key in %s:%d", - host_file, host_line); + host_file, host_line); } if (options.strict_host_key_checking == 1) { log(msg); @@ -833,7 +812,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) * This function does not require super-user privileges. */ void -ssh_login(Key **keys, int nkeys, const char *orighost, +ssh_login(Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr, struct passwd *pw) { char *host, *cp; @@ -858,10 +837,10 @@ ssh_login(Key **keys, int nkeys, const char *orighost, /* authenticate user */ if (compat20) { ssh_kex2(host, hostaddr); - ssh_userauth2(local_user, server_user, host, keys, nkeys); + ssh_userauth2(local_user, server_user, host, sensitive); } else { ssh_kex(host, hostaddr); - ssh_userauth1(local_user, server_user, host, keys, nkeys); + ssh_userauth1(local_user, server_user, host, sensitive); } } |