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
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; |
|
|
|
|