Bugzilla – Attachment 586 Details for
Bug 430
Could add option to sftp-server to disable write access
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Another sftp restriction patch
sftp-restriction-patch.diff (text/plain), 6.06 KB, created by
Damien Miller
on 2004-03-31 10:35:27 AEST
(
hide
)
Description:
Another sftp restriction patch
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2004-03-31 10:35:27 AEST
Size:
6.06 KB
patch
obsolete
>Index: sftp-server.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/sftp-server.c,v >retrieving revision 1.45 >diff -u -r1.45 sftp-server.c >--- sftp-server.c 19 Feb 2004 21:15:04 -0000 1.45 >+++ sftp-server.c 31 Mar 2004 00:07:51 -0000 >@@ -38,6 +38,56 @@ > /* Version of client */ > int version; > >+/* Path restrictions */ >+ >+/* Path, relative to user home directory, to jail users in */ >+char *restrict_path = NULL; >+ >+int >+check_path_restrict(const char *try_path) >+{ >+ struct passwd *pw; >+ size_t len; >+ int i; >+ char rpath[PATH_MAX], tmp[PATH_MAX]; >+ >+ if (restrict_path == NULL) >+ return (0); >+ >+ if (strlen(try_path) == 0) >+ return (-1); >+ if ((pw = getpwuid(getuid())) == NULL) >+ return (-1); >+ if (pw->pw_dir == NULL || strlen(pw->pw_dir) == 0) >+ return (-1); >+ if (strlcpy(tmp, pw->pw_dir, sizeof(tmp)) >= sizeof(tmp)) >+ return (-1); >+ if (strlcat(tmp, "/", sizeof(tmp)) >= sizeof(tmp)) >+ return (-1); >+ if (strlcat(tmp, restrict_path, sizeof(tmp)) >= sizeof(tmp)) >+ return (-1); >+ if (realpath(tmp, rpath) == NULL) >+ return (-1); >+ if (realpath(try_path, tmp) == NULL) { >+ if (errno != ENOENT) >+ return (-1); >+ >+ strlcpy(tmp, try_path, sizeof(tmp)); >+ len = strlen(tmp); >+ for (i = 0; i < len; i++) { >+ if (tmp[i] == '.' && tmp[i + 1] == '.' && >+ (i == 0 || tmp[i - 1] == '/') && >+ (tmp[i + 2] == '/' || tmp[i + 2] == '\0')) >+ return (-1); >+ } >+ } >+ if ((len = strlen(rpath)) == 0) >+ return (-1); >+ if (strncmp(rpath, tmp, len) != 0) >+ return (-1); >+ return (0); >+} >+ > /* portable attributes, etc. */ > > typedef struct Stat Stat; >@@ -380,7 +430,12 @@ > flags = flags_from_portable(pflags); > mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; > TRACE("open id %u name %s flags %d mode 0%o", id, name, pflags, mode); >- fd = open(name, flags, mode); >+ if (check_path_restrict(name) == -1) { >+ errno = EPERM; >+ fd = -1; >+ } else >+ fd = open(name, flags, mode); >+ > if (fd < 0) { > status = errno_to_portable(errno); > } else { >@@ -501,7 +556,11 @@ > id = get_int(); > name = get_string(NULL); > TRACE("%sstat id %u name %s", do_lstat ? "l" : "", id, name); >- ret = do_lstat ? lstat(name, &st) : stat(name, &st); >+ if (check_path_restrict(name) == -1) { >+ errno = EPERM; >+ ret = -1; >+ } else >+ ret = do_lstat ? lstat(name, &st) : stat(name, &st); > if (ret < 0) { > status = errno_to_portable(errno); > } else { >@@ -575,6 +634,11 @@ > id = get_int(); > name = get_string(NULL); > a = get_attrib(); >+ if (check_path_restrict(name) == -1) { >+ status = errno_to_portable(errno); >+ ret = -1; >+ a->flags = 0; >+ } > TRACE("setstat id %u name %s", id, name); > if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { > ret = truncate(name, a->size); >@@ -651,7 +715,12 @@ > id = get_int(); > path = get_string(NULL); > TRACE("opendir id %u path %s", id, path); >- dirp = opendir(path); >+ if (check_path_restrict(path) == -1) { >+ errno = EPERM; >+ dirp = NULL; >+ } else >+ dirp = opendir(path); >+ > if (dirp == NULL) { > status = errno_to_portable(errno); > } else { >@@ -735,7 +804,11 @@ > id = get_int(); > name = get_string(NULL); > TRACE("remove id %u name %s", id, name); >- ret = unlink(name); >+ if (check_path_restrict(name) == -1) { >+ errno = EPERM; >+ ret = -1; >+ } else >+ ret = unlink(name); > status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; > send_status(id, status); > xfree(name); >@@ -755,7 +828,11 @@ > mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? > a->perm & 0777 : 0777; > TRACE("mkdir id %u name %s mode 0%o", id, name, mode); >- ret = mkdir(name, mode); >+ if (check_path_restrict(name) == -1) { >+ errno = EPERM; >+ ret = -1; >+ } else >+ ret = mkdir(name, mode); > status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; > send_status(id, status); > xfree(name); >@@ -771,7 +848,11 @@ > id = get_int(); > name = get_string(NULL); > TRACE("rmdir id %u name %s", id, name); >- ret = rmdir(name); >+ if (check_path_restrict(name) == -1) { >+ errno = EPERM; >+ ret = -1; >+ } else >+ ret = rmdir(name); > status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; > send_status(id, status); > xfree(name); >@@ -791,7 +872,9 @@ > path = xstrdup("."); > } > TRACE("realpath id %u path %s", id, path); >- if (realpath(path, resolvedname) == NULL) { >+ if (check_path_restrict(path) == -1) { >+ send_status(id, errno_to_portable(EPERM)); >+ } else if (realpath(path, resolvedname) == NULL) { > send_status(id, errno_to_portable(errno)); > } else { > Stat s; >@@ -815,7 +898,10 @@ > newpath = get_string(NULL); > TRACE("rename id %u old %s new %s", id, oldpath, newpath); > status = SSH2_FX_FAILURE; >- if (lstat(oldpath, &sb) == -1) >+ errno = EPERM; >+ if (check_path_restrict(oldpath) == -1 || >+ check_path_restrict(newpath) == -1 || >+ lstat(oldpath, &sb) == -1) > status = errno_to_portable(errno); > else if (S_ISREG(sb.st_mode)) { > /* Race-free rename of regular files */ >@@ -849,7 +935,9 @@ > id = get_int(); > path = get_string(NULL); > TRACE("readlink id %u path %s", id, path); >- if ((len = readlink(path, link, sizeof(link) - 1)) == -1) >+ errno = EPERM; >+ if (check_path_restrict(path) == -1 || >+ (len = readlink(path, link, sizeof(link) - 1)) == -1) > send_status(id, errno_to_portable(errno)); > else { > Stat s; >@@ -874,7 +962,12 @@ > newpath = get_string(NULL); > TRACE("symlink id %u old %s new %s", id, oldpath, newpath); > /* this will fail if 'newpath' exists */ >- ret = symlink(oldpath, newpath); >+ if (check_path_restrict(oldpath) == -1 || >+ check_path_restrict(newpath) == -1) { >+ ret = -1; >+ errno = EPERM; >+ } else >+ ret = symlink(oldpath, newpath); > status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; > send_status(id, status); > xfree(oldpath); >@@ -1003,6 +1096,20 @@ > /* XXX should use getopt */ > > handle_init(); >+ >+ if (ac > 1) { >+ struct passwd *pw; >+ >+ restrict_path = av[1]; >+ if ((pw = getpwuid(getuid())) == NULL) >+ exit(1); >+ if (pw->pw_dir == NULL || strlen(pw->pw_dir) == 0) >+ exit(1); >+ if (chdir(pw->pw_dir) == -1) >+ exit(1); >+ if (chdir(restrict_path) == -1) >+ exit(1); >+ } > > #ifdef DEBUG_SFTP_SERVER > log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 430
:
173
|
586
|
1763