You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

130 lines
3.4 KiB

Index: scp.c
--- scp.c.orig 2021-03-02 11:31:47.000000000 +0100
+++ scp.c 2021-03-03 08:26:22.056945000 +0100
@@ -159,6 +159,11 @@
/* This is the program to execute for the secured connection. ("ssh" or -S) */
char *ssh_program = _PATH_SSH_PROGRAM;
+/* The directory to perform a chroot(2) to before operation (intended for server-side only) */
+#ifdef USE_CHROOT
+char *chrootdir = NULL;
+#endif
+
/* This is used to store the pid of ssh_program */
pid_t do_cmd_pid = -1;
@@ -432,7 +437,11 @@
fflag = Tflag = tflag = 0;
while ((ch = getopt(argc, argv,
+#ifdef USE_CHROOT
+ "12346ABCTdfpqrtvF:J:P:S:c:i:l:o:R:")) != -1) {
+#else
"12346ABCTdfpqrtvF:J:P:S:c:i:l:o:")) != -1) {
+#endif
switch (ch) {
/* User-visible flags. */
case '1':
@@ -516,6 +525,11 @@
case 'T':
Tflag = 1;
break;
+#ifdef USE_CHROOT
+ case 'R':
+ chrootdir = xstrdup(optarg);
+ break;
+#endif
default:
usage();
}
@@ -545,6 +559,19 @@
remin = STDIN_FILENO;
remout = STDOUT_FILENO;
+#ifdef USE_CHROOT
+ if (chrootdir != NULL) {
+ if (geteuid() != 0)
+ fatal("chroot(2) not possible: euid %ld != 0", (long)geteuid());
+ if (chroot(chrootdir) == -1)
+ fatal("couldn't chroot(2) to directory \"%s\": %s", chrootdir, strerror(errno));
+ if (setuid(getuid()) == -1)
+ fatal("couldn't drop privileges with setuid(2): %s", strerror(errno));
+ if (chdir("/") == -1)
+ fatal("couldn't change to root directory: %s", strerror(errno));
+ }
+#endif
+
if (fflag) {
/* Follow "protocol", send data. */
(void) response();
Index: session.c
--- session.c.orig 2021-03-02 11:31:47.000000000 +0100
+++ session.c 2021-03-03 08:25:31.704168000 +0100
@@ -1402,6 +1402,25 @@
options.chroot_directory = NULL;
in_chroot = 1;
}
+# ifdef USE_CHROOT
+ {
+ char *user_dir;
+ char *new_root;
+ user_dir = xstrdup(pw->pw_dir);
+ new_root = user_dir + 1;
+ while ((new_root = strchr(new_root, '.')) != NULL) {
+ new_root--;
+ if (strncmp(new_root, "/./", 3) == 0) {
+ *new_root = '\0';
+ new_root += 2;
+ safely_chroot(user_dir, pw->pw_uid);
+ pw->pw_dir = new_root;
+ break;
+ }
+ new_root += 2;
+ }
+ }
+# endif /* USE_CHROOT */
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
Index: sftp-server.c
--- sftp-server.c.orig 2021-03-02 11:31:47.000000000 +0100
+++ sftp-server.c 2021-03-03 08:25:31.704450000 +0100
@@ -1717,6 +1717,38 @@
logit("session opened for local user %s from [%s]",
pw->pw_name, client_addr);
+#ifdef USE_CHROOT
+{
+ char *user_dir;
+ char *new_root;
+ user_dir = getenv("HOME");
+ if (user_dir == NULL)
+ fatal("HOME variable not found in environment");
+ new_root = user_dir + 1;
+ while ((new_root = strchr(new_root, '.')) != NULL) {
+ new_root--;
+ if (strncmp(new_root, "/./", 3) == 0) {
+ *new_root = '\0';
+ new_root += 2;
+ if (geteuid() == 0) {
+ /* chroot to subdir and adjust HOME for remaining path */
+ if (chroot(user_dir) == -1)
+ fatal("Couldn't chroot to user directory \"%s\": %s", user_dir, strerror(errno));
+ if (setuid(getuid()) == -1)
+ fatal("Couldn't drop privileges: %s", strerror(errno));
+ setenv("HOME", new_root, 1);
+ }
+ else {
+ /* ignore chroot request and adjust HOME for preceeding path */
+ setenv("HOME", user_dir, 1);
+ }
+ break;
+ }
+ new_root += 2;
+ }
+}
+#endif /* USE_CHROOT */
+
in = STDIN_FILENO;
out = STDOUT_FILENO;