Chroot patch (v3.4p1)

John Furman john at furman.net
Fri Jul 5 13:40:50 EST 2002


On Thu, 4 Jul 2002 10:08 AM, Markus Friedl wrote:

>
> +                         if(chroot(pw->pw_dir) != 0) {
>
> please don't chroot into $HOME but a configurable (sub)directory,
> similar to the AuthorizedKeysFile option, e.g
>
>       ChrootDir %h/public_html
>
> otherwise people start messing around with $HOME/.ssh/
> or $HOME/.forward, etc.
> 
> -m

Thanks!

Here is the latest.  It includes a ChrootDir option.


diff -uNr openssh-3.4p1.vanilla/auth.c openssh-3.4p1/auth.c
--- openssh-3.4p1.vanilla/auth.c	Wed May 22 01:06:28 2002
+++ openssh-3.4p1/auth.c	Thu Jul  4 21:47:31 2002
@@ -351,6 +351,12 @@
	return expand_filename(options.authorized_keys_file2, pw);
 }
 
+char *
+chroot_dir(struct passwd *pw)
+{
+	return expand_filename(options.chroot_dir, pw);
+}
+
 /* return ok if key exists in sysfile or userfile */
 HostStatus
 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
diff -uNr openssh-3.4p1.vanilla/auth.h openssh-3.4p1/auth.h
--- openssh-3.4p1.vanilla/auth.h	Thu Jun  6 16:52:37 2002
+++ openssh-3.4p1/auth.h	Thu Jul  4 21:47:31 2002
@@ -165,6 +165,7 @@
 char	*expand_filename(const char *, struct passwd *);
 char	*authorized_keys_file(struct passwd *);
 char	*authorized_keys_file2(struct passwd *);
+char	*chroot_dir(struct passwd *);
 
 int
 secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
diff -uNr openssh-3.4p1.vanilla/pathnames.h openssh-3.4p1/pathnames.h
--- openssh-3.4p1.vanilla/pathnames.h	Thu Jun  6 15:57:34 2002
+++ openssh-3.4p1/pathnames.h	Thu Jul  4 22:20:42 2002
@@ -97,6 +97,9 @@
 /* backward compat for protocol v2 */
 #define _PATH_SSH_USER_PERMITTED_KEYS2	".ssh/authorized_keys2"
 
+/* */
+#define _SSH_USER_CHROOT_DIR	"chome"
+
 /*
  * Per-user and system-wide ssh "rc" files.  These files are executed with
  * /bin/sh before starting the shell or command if they exist.  They will be
diff -uNr openssh-3.4p1.vanilla/servconf.c openssh-3.4p1/servconf.c
--- openssh-3.4p1.vanilla/servconf.c	Mon Jun 24 23:22:04 2002
+++ openssh-3.4p1/servconf.c	Thu Jul  4 21:47:31 2002
@@ -120,6 +120,7 @@
	options->verify_reverse_mapping = -1;
	options->client_alive_interval = -1;
	options->client_alive_count_max = -1;
+	options->chroot_dir = NULL;
	options->authorized_keys_file = NULL;
	options->authorized_keys_file2 = NULL;
 
@@ -252,6 +253,8 @@
	}
	if (options->authorized_keys_file == NULL)
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
+	if (options->chroot_dir == NULL)
+		options->chroot_dir = _SSH_USER_CHROOT_DIR;
 
	/* Turn privilege separation on by default */
	if (use_privsep == -1)
@@ -292,12 +295,12 @@
	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
	sStrictModes, sEmptyPasswd, sKeepAlives,
	sUseLogin, sAllowTcpForwarding, sCompression,
-	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
+       sAllowUsers, sDenyUsers, sChrootUsers, sAllowGroups, sDenyGroups,
	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
	sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
-	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
+	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sChrootDir,
	sUsePrivilegeSeparation,
	sDeprecated
 } ServerOpCodes;
@@ -360,6 +363,7 @@
	{ "allowtcpforwarding", sAllowTcpForwarding },
	{ "allowusers", sAllowUsers },
	{ "denyusers", sDenyUsers },
+       { "chrootusers", sChrootUsers },
	{ "allowgroups", sAllowGroups },
	{ "denygroups", sDenyGroups },
	{ "ciphers", sCiphers },
@@ -375,6 +379,7 @@
	{ "clientalivecountmax", sClientAliveCountMax },
	{ "authorizedkeysfile", sAuthorizedKeysFile },
	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
+	{ "chrootdir", sChrootDir },
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
	{ NULL, sBadOption }
 };
@@ -779,6 +784,16 @@
		}
		break;
 
+        case sChrootUsers:
+                while ((arg = strdelim(&cp)) && *arg != '\0') {
+                        if (options->num_chroot_users >= MAX_CHROOT_USERS)
+                                fatal( "%s line %d: too many chroot users.",
+                                    filename, linenum);
+                        options->chroot_users[options->num_chroot_users++] =
+                            xstrdup(arg);
+                }
+                break;
+
	case sAllowGroups:
		while ((arg = strdelim(&cp)) && *arg != '\0') {
			if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
@@ -893,6 +908,10 @@
		    &options->authorized_keys_file2;
		goto parse_filename;
 
+	case sChrootDir:
+		charptr = &options->chroot_dir;
+		goto parse_filename;
+
	case sClientAliveInterval:
		intptr = &options->client_alive_interval;
		goto parse_time;
diff -uNr openssh-3.4p1.vanilla/servconf.h openssh-3.4p1/servconf.h
--- openssh-3.4p1.vanilla/servconf.h	Thu Jun 20 21:09:47 2002
+++ openssh-3.4p1/servconf.h	Thu Jul  4 21:47:31 2002
@@ -20,6 +20,7 @@
 
 #define MAX_ALLOW_USERS		256	/* Max # users on allow list. */
 #define MAX_DENY_USERS		256	/* Max # users on deny list. */
+#define MAX_CHROOT_USERS       256     /* Max # users on chroot list. */
 #define MAX_ALLOW_GROUPS	256	/* Max # groups on allow list. */
 #define MAX_DENY_GROUPS		256	/* Max # groups on deny list. */
 #define MAX_SUBSYSTEMS		256	/* Max # subsystems. */
@@ -104,6 +105,8 @@
	char   *allow_users[MAX_ALLOW_USERS];
	u_int num_deny_users;
	char   *deny_users[MAX_DENY_USERS];
+       u_int num_chroot_users;
+       char   *chroot_users[MAX_CHROOT_USERS];
	u_int num_allow_groups;
	char   *allow_groups[MAX_ALLOW_GROUPS];
	u_int num_deny_groups;
@@ -130,6 +133,7 @@
 
	char   *authorized_keys_file;	/* File containing public keys */
	char   *authorized_keys_file2;
+	char   *chroot_dir;
	int	pam_authentication_via_kbd_int;
 }       ServerOptions;
 
diff -uNr openssh-3.4p1.vanilla/session.c openssh-3.4p1/session.c
--- openssh-3.4p1.vanilla/session.c	Wed Jun 26 09:51:06 2002
+++ openssh-3.4p1/session.c	Thu Jul  4 22:22:03 2002
@@ -57,6 +57,8 @@
 #include "canohost.h"
 #include "session.h"
 #include "monitor_wrap.h"
+#include "match.h"
+#include "readconf.h"
 
 #ifdef HAVE_CYGWIN
 #include <windows.h>
@@ -64,6 +66,8 @@
 #define is_winnt       (GetVersion() < 0x80000000)
 #endif
 
+#define CHROOT
+
 /* func */
 
 Session *session_new(void);
@@ -1160,6 +1164,14 @@
 do_setusercontext(struct passwd *pw)
 {
	char tty='\0';
+       int i;
+#ifdef CHROOT
+	char *new_root = "/";
+	char *new_home = NULL;
+	char *dir = NULL;
+	const char *hostname = NULL;
+	const char *ipaddr = NULL;
+#endif /* CHROOT */
 
 #ifdef HAVE_CYGWIN
	if (is_winnt) {
@@ -1187,6 +1199,29 @@
 
		if (setlogin(pw->pw_name) < 0)
			error("setlogin failed: %s", strerror(errno));
+#ifdef CHROOT
+
+		if (options.num_chroot_users > 0) {
+		    for (i = 0; i < options.num_chroot_users; i++) {
+		        hostname = get_canonical_hostname(options.verify_reverse_mapping);
+		        ipaddr = get_remote_ipaddr();
+			if (match_user(pw->pw_name, hostname, ipaddr, 
+			    options.chroot_users[i])) {
+		                dir = chroot_dir(pw);
+		                new_home = dir;
+		                xfree(dir);
+			    if(chroot(new_home) != 0) {
+				fatal("Couldn't chroot to user directory %s", 
+				new_home);
+			    }
+			    else
+			    pw->pw_dir = new_root;
+			}
+		    }
+		}
+
+
+#endif /* CHROOT */
		if (setgid(pw->pw_gid) < 0) {
			perror("setgid");
			exit(1);


Regards,
--
John Furman <john at furman.net>





More information about the openssh-unix-dev mailing list