summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2002-06-11 16:37:51 +0000
committerBen Lindstrom <mouring@eviladmin.org>2002-06-11 16:37:51 +0000
commitf9c4884c8effe6dd78ab3ed4e42ed69c4a8652d0 (patch)
treebf92c1c3374176a70d0a2dd9ea23d97e13d5ee57
parent8bb6f36c8fab33f7ca59b9c56e11d54caf36f965 (diff)
- markus@cvs.openbsd.org 2002/06/11 04:14:26
[ssh.c sshconnect.c sshconnect.h] no longer use uidswap.[ch] from the ssh client run less code with euid==0 if ssh is installed setuid root just switch the euid, don't switch the complete set of groups (this is only needed by sshd). ok provos@
-rw-r--r--ChangeLog8
-rw-r--r--ssh.c20
-rw-r--r--sshconnect.c47
-rw-r--r--sshconnect.h20
4 files changed, 51 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index 99448aa9d..9e0b5159a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,6 +29,12 @@
29 [channels.c channels.h session.c] 29 [channels.c channels.h session.c]
30 move creation of agent socket to session.c; no need for uidswapping 30 move creation of agent socket to session.c; no need for uidswapping
31 in channel.c. 31 in channel.c.
32 - markus@cvs.openbsd.org 2002/06/11 04:14:26
33 [ssh.c sshconnect.c sshconnect.h]
34 no longer use uidswap.[ch] from the ssh client
35 run less code with euid==0 if ssh is installed setuid root
36 just switch the euid, don't switch the complete set of groups
37 (this is only needed by sshd). ok provos@
32 38
3320020609 3920020609
34 - (bal) OpenBSD CVS Sync 40 - (bal) OpenBSD CVS Sync
@@ -894,4 +900,4 @@
894 - (stevesk) entropy.c: typo in debug message 900 - (stevesk) entropy.c: typo in debug message
895 - (djm) ssh-keygen -i needs seeded RNG; report from markus@ 901 - (djm) ssh-keygen -i needs seeded RNG; report from markus@
896 902
897$Id: ChangeLog,v 1.2207 2002/06/11 15:59:02 mouring Exp $ 903$Id: ChangeLog,v 1.2208 2002/06/11 16:37:51 mouring Exp $
diff --git a/ssh.c b/ssh.c
index 7cadc1873..5693c0d39 100644
--- a/ssh.c
+++ b/ssh.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: ssh.c,v 1.176 2002/06/08 05:17:01 markus Exp $"); 43RCSID("$OpenBSD: ssh.c,v 1.177 2002/06/11 04:14:26 markus Exp $");
44 44
45#include <openssl/evp.h> 45#include <openssl/evp.h>
46#include <openssl/err.h> 46#include <openssl/err.h>
@@ -53,7 +53,6 @@ RCSID("$OpenBSD: ssh.c,v 1.176 2002/06/08 05:17:01 markus Exp $");
53#include "xmalloc.h" 53#include "xmalloc.h"
54#include "packet.h" 54#include "packet.h"
55#include "buffer.h" 55#include "buffer.h"
56#include "uidswap.h"
57#include "channels.h" 56#include "channels.h"
58#include "key.h" 57#include "key.h"
59#include "authfd.h" 58#include "authfd.h"
@@ -136,6 +135,7 @@ Sensitive sensitive_data;
136 135
137/* Original real UID. */ 136/* Original real UID. */
138uid_t original_real_uid; 137uid_t original_real_uid;
138uid_t original_effective_uid;
139 139
140/* command to be executed */ 140/* command to be executed */
141Buffer command; 141Buffer command;
@@ -217,7 +217,6 @@ main(int ac, char **av)
217 struct stat st; 217 struct stat st;
218 struct passwd *pw; 218 struct passwd *pw;
219 int dummy; 219 int dummy;
220 uid_t original_effective_uid;
221 extern int optind, optreset; 220 extern int optind, optreset;
222 extern char *optarg; 221 extern char *optarg;
223 222
@@ -256,7 +255,7 @@ main(int ac, char **av)
256 * them when the port has been created (actually, when the connection 255 * them when the port has been created (actually, when the connection
257 * has been made, as we may need to create the port several times). 256 * has been made, as we may need to create the port several times).
258 */ 257 */
259 temporarily_use_uid(pw); 258 PRIV_END;
260 259
261 /* 260 /*
262 * Set our umask to something reasonable, as some files are created 261 * Set our umask to something reasonable, as some files are created
@@ -612,15 +611,12 @@ again:
612 "originating port will not be trusted."); 611 "originating port will not be trusted.");
613 options.rhosts_authentication = 0; 612 options.rhosts_authentication = 0;
614 } 613 }
615 /* Restore our superuser privileges. */
616 restore_uid();
617
618 /* Open a connection to the remote host. */ 614 /* Open a connection to the remote host. */
619 615
620 cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6, 616 cerr = ssh_connect(host, &hostaddr, options.port, IPv4or6,
621 options.connection_attempts, 617 options.connection_attempts,
622 original_effective_uid != 0 || !options.use_privileged_port, 618 original_effective_uid == 0 && options.use_privileged_port,
623 pw, options.proxy_command); 619 options.proxy_command);
624 620
625 /* 621 /*
626 * If we successfully made the connection, load the host private key 622 * If we successfully made the connection, load the host private key
@@ -637,12 +633,15 @@ again:
637 options.hostbased_authentication)) { 633 options.hostbased_authentication)) {
638 sensitive_data.nkeys = 3; 634 sensitive_data.nkeys = 3;
639 sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key)); 635 sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
636
637 PRIV_START;
640 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, 638 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
641 _PATH_HOST_KEY_FILE, "", NULL); 639 _PATH_HOST_KEY_FILE, "", NULL);
642 sensitive_data.keys[1] = key_load_private_type(KEY_DSA, 640 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
643 _PATH_HOST_DSA_KEY_FILE, "", NULL); 641 _PATH_HOST_DSA_KEY_FILE, "", NULL);
644 sensitive_data.keys[2] = key_load_private_type(KEY_RSA, 642 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
645 _PATH_HOST_RSA_KEY_FILE, "", NULL); 643 _PATH_HOST_RSA_KEY_FILE, "", NULL);
644 PRIV_END;
646 645
647 if (sensitive_data.keys[0] == NULL && 646 if (sensitive_data.keys[0] == NULL &&
648 sensitive_data.keys[1] == NULL && 647 sensitive_data.keys[1] == NULL &&
@@ -661,7 +660,8 @@ again:
661 * user's home directory if it happens to be on a NFS volume where 660 * user's home directory if it happens to be on a NFS volume where
662 * root is mapped to nobody. 661 * root is mapped to nobody.
663 */ 662 */
664 permanently_set_uid(pw); 663 seteuid(original_real_uid);
664 setuid(original_real_uid);
665 665
666 /* 666 /*
667 * Now that we are back to our own permissions, create ~/.ssh 667 * Now that we are back to our own permissions, create ~/.ssh
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"
16RCSID("$OpenBSD: sshconnect.c,v 1.123 2002/06/09 22:17:21 itojun Exp $"); 16RCSID("$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 $");
36char *client_version_string = NULL; 36char *client_version_string = NULL;
37char *server_version_string = NULL; 37char *server_version_string = NULL;
38 38
39/* import */
39extern Options options; 40extern Options options;
40extern char *__progname; 41extern char *__progname;
42extern uid_t original_real_uid;
43extern 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 */
60static int 63static int
61ssh_proxy_connect(const char *host, u_short port, struct passwd *pw, 64ssh_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 */
161static int 164static int
162ssh_create_socket(struct passwd *pw, int privileged, int family) 165ssh_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)
232int 231int
233ssh_connect(const char *host, struct sockaddr_storage * hostaddr, 232ssh_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
diff --git a/sshconnect.h b/sshconnect.h
index aeb2e51a5..48148833f 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.15 2002/06/09 13:32:01 markus Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.16 2002/06/11 04:14:26 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -35,7 +35,7 @@ struct Sensitive {
35 35
36int 36int
37ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, 37ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int,
38 int, struct passwd *, const char *); 38 int, const char *);
39 39
40void 40void
41ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *); 41ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *);
@@ -50,4 +50,20 @@ void ssh_userauth2(const char *, const char *, char *, Sensitive *);
50 50
51void ssh_put_password(char *); 51void ssh_put_password(char *);
52 52
53
54/*
55 * Macros to raise/lower permissions.
56 */
57#define PRIV_START do { \
58 int save_errno = errno; \
59 (void)seteuid(original_effective_uid); \
60 errno = save_errno; \
61} while (0)
62
63#define PRIV_END do { \
64 int save_errno = errno; \
65 (void)seteuid(original_real_uid); \
66 errno = save_errno; \
67} while (0)
68
53#endif 69#endif