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