diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 47 |
1 files changed, 16 insertions, 31 deletions
diff --git a/sshconnect.c b/sshconnect.c index 651e3fcf4..3a93a4fbb 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include "includes.h" | 15 | #include "includes.h" |
16 | RCSID("$OpenBSD: sshconnect.c,v 1.123 2002/06/09 22:17:21 itojun Exp $"); | 16 | RCSID("$OpenBSD: sshconnect.c,v 1.124 2002/06/11 04:14:26 markus Exp $"); |
17 | 17 | ||
18 | #include <openssl/bn.h> | 18 | #include <openssl/bn.h> |
19 | 19 | ||
@@ -36,8 +36,11 @@ RCSID("$OpenBSD: sshconnect.c,v 1.123 2002/06/09 22:17:21 itojun Exp $"); | |||
36 | char *client_version_string = NULL; | 36 | char *client_version_string = NULL; |
37 | char *server_version_string = NULL; | 37 | char *server_version_string = NULL; |
38 | 38 | ||
39 | /* import */ | ||
39 | extern Options options; | 40 | extern Options options; |
40 | extern char *__progname; | 41 | extern char *__progname; |
42 | extern uid_t original_real_uid; | ||
43 | extern uid_t original_effective_uid; | ||
41 | 44 | ||
42 | #ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ | 45 | #ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ |
43 | #define INET6_ADDRSTRLEN 46 | 46 | #define INET6_ADDRSTRLEN 46 |
@@ -58,8 +61,7 @@ sockaddr_ntop(struct sockaddr *sa, socklen_t salen) | |||
58 | * Connect to the given ssh server using a proxy command. | 61 | * Connect to the given ssh server using a proxy command. |
59 | */ | 62 | */ |
60 | static int | 63 | static int |
61 | ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, | 64 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) |
62 | const char *proxy_command) | ||
63 | { | 65 | { |
64 | Buffer command; | 66 | Buffer command; |
65 | const char *cp; | 67 | const char *cp; |
@@ -109,7 +111,8 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, | |||
109 | char *argv[10]; | 111 | char *argv[10]; |
110 | 112 | ||
111 | /* Child. Permanently give up superuser privileges. */ | 113 | /* Child. Permanently give up superuser privileges. */ |
112 | permanently_set_uid(pw); | 114 | seteuid(original_real_uid); |
115 | setuid(original_real_uid); | ||
113 | 116 | ||
114 | /* Redirect stdin and stdout. */ | 117 | /* Redirect stdin and stdout. */ |
115 | close(pin[1]); | 118 | close(pin[1]); |
@@ -159,7 +162,7 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, | |||
159 | * Creates a (possibly privileged) socket for use as the ssh connection. | 162 | * Creates a (possibly privileged) socket for use as the ssh connection. |
160 | */ | 163 | */ |
161 | static int | 164 | static int |
162 | ssh_create_socket(struct passwd *pw, int privileged, int family) | 165 | ssh_create_socket(int privileged, int family) |
163 | { | 166 | { |
164 | int sock, gaierr; | 167 | int sock, gaierr; |
165 | struct addrinfo hints, *res; | 168 | struct addrinfo hints, *res; |
@@ -170,22 +173,18 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) | |||
170 | */ | 173 | */ |
171 | if (privileged) { | 174 | if (privileged) { |
172 | int p = IPPORT_RESERVED - 1; | 175 | int p = IPPORT_RESERVED - 1; |
176 | PRIV_START; | ||
173 | sock = rresvport_af(&p, family); | 177 | sock = rresvport_af(&p, family); |
178 | PRIV_END; | ||
174 | if (sock < 0) | 179 | if (sock < 0) |
175 | error("rresvport: af=%d %.100s", family, strerror(errno)); | 180 | error("rresvport: af=%d %.100s", family, strerror(errno)); |
176 | else | 181 | else |
177 | debug("Allocated local port %d.", p); | 182 | debug("Allocated local port %d.", p); |
178 | return sock; | 183 | return sock; |
179 | } | 184 | } |
180 | /* | ||
181 | * Just create an ordinary socket on arbitrary port. We use | ||
182 | * the user's uid to create the socket. | ||
183 | */ | ||
184 | temporarily_use_uid(pw); | ||
185 | sock = socket(family, SOCK_STREAM, 0); | 185 | sock = socket(family, SOCK_STREAM, 0); |
186 | if (sock < 0) | 186 | if (sock < 0) |
187 | error("socket: %.100s", strerror(errno)); | 187 | error("socket: %.100s", strerror(errno)); |
188 | restore_uid(); | ||
189 | 188 | ||
190 | /* Bind the socket to an alternative local IP address */ | 189 | /* Bind the socket to an alternative local IP address */ |
191 | if (options.bind_address == NULL) | 190 | if (options.bind_address == NULL) |
@@ -215,9 +214,9 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) | |||
215 | /* | 214 | /* |
216 | * Opens a TCP/IP connection to the remote server on the given host. | 215 | * Opens a TCP/IP connection to the remote server on the given host. |
217 | * The address of the remote host will be returned in hostaddr. | 216 | * The address of the remote host will be returned in hostaddr. |
218 | * If port is 0, the default port will be used. If anonymous is zero, | 217 | * If port is 0, the default port will be used. If needpriv is true, |
219 | * a privileged port will be allocated to make the connection. | 218 | * a privileged port will be allocated to make the connection. |
220 | * This requires super-user privileges if anonymous is false. | 219 | * This requires super-user privileges if needpriv is true. |
221 | * Connection_attempts specifies the maximum number of tries (one per | 220 | * Connection_attempts specifies the maximum number of tries (one per |
222 | * second). If proxy_command is non-NULL, it specifies the command (with %h | 221 | * second). If proxy_command is non-NULL, it specifies the command (with %h |
223 | * and %p substituted for host and port, respectively) to use to contact | 222 | * and %p substituted for host and port, respectively) to use to contact |
@@ -232,7 +231,7 @@ ssh_create_socket(struct passwd *pw, int privileged, int family) | |||
232 | int | 231 | int |
233 | ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | 232 | ssh_connect(const char *host, struct sockaddr_storage * hostaddr, |
234 | u_short port, int family, int connection_attempts, | 233 | u_short port, int family, int connection_attempts, |
235 | int anonymous, struct passwd *pw, const char *proxy_command) | 234 | int needpriv, const char *proxy_command) |
236 | { | 235 | { |
237 | int gaierr; | 236 | int gaierr; |
238 | int on = 1; | 237 | int on = 1; |
@@ -248,8 +247,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
248 | */ | 247 | */ |
249 | int full_failure = 1; | 248 | int full_failure = 1; |
250 | 249 | ||
251 | debug("ssh_connect: getuid %u geteuid %u anon %d", | 250 | debug("ssh_connect: needpriv %d", needpriv); |
252 | (u_int) getuid(), (u_int) geteuid(), anonymous); | ||
253 | 251 | ||
254 | /* Get default port if port has not been set. */ | 252 | /* Get default port if port has not been set. */ |
255 | if (port == 0) { | 253 | if (port == 0) { |
@@ -261,7 +259,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
261 | } | 259 | } |
262 | /* If a proxy command is given, connect using it. */ | 260 | /* If a proxy command is given, connect using it. */ |
263 | if (proxy_command != NULL) | 261 | if (proxy_command != NULL) |
264 | return ssh_proxy_connect(host, port, pw, proxy_command); | 262 | return ssh_proxy_connect(host, port, proxy_command); |
265 | 263 | ||
266 | /* No proxy command. */ | 264 | /* No proxy command. */ |
267 | 265 | ||
@@ -297,26 +295,14 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
297 | host, ntop, strport); | 295 | host, ntop, strport); |
298 | 296 | ||
299 | /* Create a socket for connecting. */ | 297 | /* Create a socket for connecting. */ |
300 | sock = ssh_create_socket(pw, | 298 | sock = ssh_create_socket(needpriv, ai->ai_family); |
301 | #ifdef HAVE_CYGWIN | ||
302 | !anonymous, | ||
303 | #else | ||
304 | !anonymous && geteuid() == 0, | ||
305 | #endif | ||
306 | ai->ai_family); | ||
307 | if (sock < 0) | 299 | if (sock < 0) |
308 | /* Any error is already output */ | 300 | /* Any error is already output */ |
309 | continue; | 301 | continue; |
310 | 302 | ||
311 | /* Connect to the host. We use the user's uid in the | ||
312 | * hope that it will help with tcp_wrappers showing | ||
313 | * the remote uid as root. | ||
314 | */ | ||
315 | temporarily_use_uid(pw); | ||
316 | if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { | 303 | if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { |
317 | /* Successful connection. */ | 304 | /* Successful connection. */ |
318 | memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); | 305 | memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); |
319 | restore_uid(); | ||
320 | break; | 306 | break; |
321 | } else { | 307 | } else { |
322 | if (errno == ECONNREFUSED) | 308 | if (errno == ECONNREFUSED) |
@@ -324,7 +310,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, | |||
324 | log("ssh: connect to address %s port %s: %s", | 310 | log("ssh: connect to address %s port %s: %s", |
325 | sockaddr_ntop(ai->ai_addr, ai->ai_addrlen), | 311 | sockaddr_ntop(ai->ai_addr, ai->ai_addrlen), |
326 | strport, strerror(errno)); | 312 | strport, strerror(errno)); |
327 | restore_uid(); | ||
328 | /* | 313 | /* |
329 | * Close the failed socket; there appear to | 314 | * Close the failed socket; there appear to |
330 | * be some problems when reusing a socket for | 315 | * be some problems when reusing a socket for |