[PATCH] sftp-server (secure) chroot patch, 3.7.1p2 update

magnus at mandarin.nu magnus at mandarin.nu
Wed Oct 1 01:43:37 EST 2003


Hello all,

Here is an updated patch. I published the original patch published on
august 16.

--- openssh-3.7.1p2/sftp-server.c.org	2003-08-22 01:34:41.000000000
+0200
+++ openssh-3.7.1p2/sftp-server.c	2003-09-30 17:22:43.730402000 +0200
@@ -24,6 +24,7 @@
 #include \"includes.h\"
 RCSID(\"$OpenBSD: sftp-server.c,v 1.43 2003/06/25 22:39:36 miod Exp
$\");
 
+#define CHROOT
 #include \"buffer.h\"
 #include \"bufaux.h\"
 #include \"getput.h\"
@@ -33,6 +34,15 @@
 #include \"sftp.h\"
 #include \"sftp-common.h\"
 
+#ifdef CHROOT
+#include \"uidswap.h\"
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#endif /* CHROOT */
+
 /* helper */
 #define get_int64()			buffer_get_int64(&iqueue);
 #define get_int()			buffer_get_int(&iqueue);
@@ -62,6 +72,49 @@
 	Attrib attrib;
 };
 
+#ifdef CHROOT
+static void
+chroot_init(void)
+{
+	struct passwd *pw;
+	struct stat st;
+
+	/* Sanity checking before chroot */
+	if ((pw = getpwuid(getuid())) == NULL)
+		fatal(\"getpwuid failed for %u\", (u_int)pw->pw_uid );
+
+	/* Sets passwd pointer to null */
+        memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
+	endpwent();
+
+	if (geteuid() != 0)
+		fatal(\"must be SUID root to use chroot feature\");
+
+	if ((stat(pw->pw_dir, &st)) == -1)
+		fatal(\"cannot stat chroot directory %s: %s\", pw->pw_dir,
strerror(errno));
+
+	if (!S_ISDIR(st.st_mode))
+		fatal(\"%s is not a directory: %s\", pw->pw_dir, strerror(errno));
+
+	/* Drop our privileges */
+	debug3(\"chroot user:group %u:%u\", (u_int)pw->pw_uid,
(u_int)pw->pw_gid);
+
+	/* Change our root directory */
+	if (chroot(pw->pw_dir) == -1)
+		fatal(\"chroot(\\\"%s\\\"): %s\", pw->pw_dir, strerror(errno));
+
+	/* Change dir to prevent chroot break */
+	if (chdir(\"/\") == -1)
+		fatal(\"chdir(\\\"/\\\"): %s\", strerror(errno));
+
+	if (setgid(pw->pw_gid) < 0)
+		fatal(\"setgid failed for %u\", (u_int)pw->pw_gid );
+
+	permanently_set_uid(pw);
+
+}
+#endif /* CHROOT */
+
 static int
 errno_to_portable(int unixerrno)
 {
@@ -1028,15 +1081,19 @@
 	int in, out, max;
 	ssize_t len, olen, set_size;
 
+#ifdef DEBUG_SFTP_SERVER
+	log_init(\"sftp-server\", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH,
0);
+#endif
+
+#ifdef CHROOT
+	chroot_init();
+#endif
+
 	/* XXX should use getopt */
 
 	__progname = ssh_get_progname(av[0]);
 	handle_init();
 
-#ifdef DEBUG_SFTP_SERVER
-	log_init(\"sftp-server\", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH,
0);
-#endif
-
 	in = dup(STDIN_FILENO);
 	out = dup(STDOUT_FILENO);
  
To apply this patch on OpenSSH 3.7.1p2:
- patch -p0 < sftp-server.patch
- edit Makefile and include uidswap.o in sftp-server
- make sftp-server
- copy sftp-server into your chroot and set u+s

Any problems with it, please share, works ok for me on Solaris 8.

Regards
Magnus




More information about the openssh-unix-dev mailing list