Projects
Mega:23.09
openssh
_service:tar_scm:feature-openssh-7.4-hima-sftps...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch of Package openssh
From 6d98c61e18fe65a52e21df9cece74675f9c18125 Mon Sep 17 00:00:00 2001 From: shenyining <shenyining@huawei.com> Date: Thu, 16 Apr 2020 17:13:24 +0800 Subject: [PATCH] sync patch, add new judgement and delete default sftp-put-check.cfg Signed-off-by: shenyining <shenyining@huawei.com> --- sftp-server.c | 702 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 690 insertions(+), 12 deletions(-) diff --git a/sftp-server.c b/sftp-server.c index 5677aa3..4eb06d1 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -30,6 +30,12 @@ #include <sys/statvfs.h> #endif +/* add begin sftp oom fix */ +#include <sys/sysinfo.h> +#include <sys/vfs.h> +#include <linux/magic.h> +/* add end sftp oom fix */ + #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -57,6 +63,17 @@ #include "sftp.h" #include "sftp-common.h" +static int storage_flag = 0; +/* add begin 2013/10/12 SR-0000287268 */ +#define RETURN_OK 0 +#define RETURN_ERROR -1 +#define FLAG_PROTECTDIR 0 +#define FLAG_PERMITOP 1 +/* add end 2013/10/12 SR-0000287268 */ +/*add for oom*/ +static int cflag = 0; +/*add for oom end*/ + char *sftp_realpath(const char *, char *); /* sftp-realpath.c */ /* Maximum data read that we are willing to accept */ @@ -98,6 +115,452 @@ struct Stat { Attrib attrib; }; +/* add begin 2013/10/12 SR-0000287268*/ +#define MAX_DIR_NUM 100 +/* sftppermit path array */ +char szPermitPath[MAX_DIR_NUM][MAXPATHLEN] = {0}; +char szDenyPath[MAX_DIR_NUM][MAXPATHLEN] = {0}; +const char *pszPermitPath = "/usr/local/etc/sftppermit.config"; +const char *pszDenyPath = "/usr/local/etc/sftpdeny.config"; +char szPermitPath_other[MAX_DIR_NUM][MAXPATHLEN] = {0}; +char szDenyPath_other[MAX_DIR_NUM][MAXPATHLEN] = {0}; +const char *pszPermitPath_other = "/usr/local/etc/other_sftppermit.config"; +const char *pszDenyPath_other= "/usr/local/etc/other_sftpdeny.config"; +static int +read_config_file(const char* pszPath, char(*szConfigPath)[MAXPATHLEN]) +{ + FILE *fd = NULL; + char *szBuffer = NULL; + size_t len = 0; + unsigned long linenum = 0; + + if (NULL == pszPath) + { + debug("[sftp-server]Config file %s is NULL.\n", pszPath); + return RETURN_ERROR; + } + + if (NULL == (fd = fopen(pszPath, "r"))) + { + debug("[sftp-server]Open config file %s failed.\n", pszPath); + return RETURN_ERROR; + } + + while (RETURN_ERROR != getline(&szBuffer, &len, fd)) + { + linenum++; + //Fix bug exceed max permit dir 2013-10-18 begin + if ( linenum > MAX_DIR_NUM ) + { + debug("[sftp-server]Exceed max number of config dir.\n"); + break; + } + //Fix bug exceed max permit dir 2013-10-18 end + memcpy(szConfigPath[linenum-1], szBuffer , strlen(szBuffer)); + if ( szConfigPath[linenum-1][strlen(szBuffer)-1] == '\n' ) + { + szConfigPath[linenum-1][strlen(szBuffer)-1] = '\0'; + if ( szConfigPath[linenum-1][strlen(szBuffer)-2] == '\r' ) + { + szConfigPath[linenum-1][strlen(szBuffer)-2] = '\0'; + } + } + } + + fclose(fd); + storage_flag = 1; + return RETURN_OK; +} + +static int +path_permition_check(const char *pszPath,int iflag) +{ + unsigned int iCount = 0; + char szResolvedname[MAXPATHLEN] = {0}; + gid_t server_user_gid, local_user_gid; + int path_len = 0; + + if(storage_flag != 1) + return RETURN_OK; + + if(NULL == pszPath) + { + debug("[sftp-server]Inputed param for check is NULL.\n"); + return RETURN_ERROR; + } + + realpath(pszPath, szResolvedname); + local_user_gid = pw->pw_gid; + server_user_gid = local_user_gid; + if(NULL != szResolvedname) + { + if (server_user_gid == 0) + { + for (iCount=0; iCount < MAX_DIR_NUM ; iCount++) + { + path_len = strlen(szDenyPath[iCount]); + if((0 != szDenyPath[iCount][0]) && (szResolvedname == strstr(szResolvedname,szDenyPath[iCount]))){ + if(szResolvedname[path_len] == '\0' || szResolvedname[path_len] == '/') + return RETURN_ERROR; + } + } + + for (iCount=0; iCount < MAX_DIR_NUM ; iCount++) + { + path_len = strlen(szPermitPath[iCount]); + if((0 != szPermitPath[iCount][0]) + && (szResolvedname == strstr(szResolvedname,szPermitPath[iCount])) + && (szResolvedname[path_len] == '\0' || szResolvedname[path_len] == '/')) + { + if ((FLAG_PROTECTDIR == iflag) && (0 == strcmp(szResolvedname,szPermitPath[iCount]))) + { + debug("[sftp-server]Can't operate protected dir.\n"); + return RETURN_ERROR; + } + return RETURN_OK; + } + } + } + else + { + for (iCount=0; iCount < MAX_DIR_NUM ; iCount++) + { + path_len = strlen(szDenyPath_other[iCount]); + if((0 != szDenyPath_other[iCount][0]) && (szResolvedname == strstr(szResolvedname,szDenyPath_other[iCount]))) + if(szResolvedname[path_len] == '\0' || szResolvedname[path_len] == '/') + return RETURN_ERROR; + } + + for (iCount=0; iCount < MAX_DIR_NUM ; iCount++) + { + path_len = strlen(szPermitPath_other[iCount]); + if((0 != szPermitPath_other[iCount][0]) + && (szResolvedname == strstr(szResolvedname,szPermitPath_other[iCount])) + && (szResolvedname[path_len] == '\0' || szResolvedname[path_len] == '/')) + { + if ((FLAG_PROTECTDIR == iflag) && (0 == strcmp(szResolvedname,szPermitPath_other[iCount]))) + { + debug("[sftp-server]Can't operate protected dir.\n"); + return RETURN_ERROR; + } + return RETURN_OK; + } + } + + } + } + + return RETURN_ERROR; +} +/* add end 2013/10/12 SR-0000287268 */ + +/* add begin sftp oom fix */ +#define BUF_MAX_LEN 4096 /*Max lenth*/ +#define MAX_LINE_LEN 80 /*Max line lenth*/ + +#define DEFAULT_FILESIZE 4096 +#define DEFAULT_MEMSIZE 0 + +const char *ck_config_file_name = "/usr/local/etc/sftp-put-check.cfg"; + +typedef struct { + int max_file_size; + int min_freemem_size; +}CheckOptions; + +static CheckOptions ckoptions; + +/* Keyword tokens. */ +typedef enum { + sBadOption, + sMaxFileSize, + sMinFreeMemSize +} checkOpCodes; + +static struct { + const char *name; + checkOpCodes opcode; +} keywords[] = { + { "MaxFileSize", sMaxFileSize }, + { "MinFreeMemSize", sMinFreeMemSize }, + { NULL, sBadOption } +}; + +static checkOpCodes +ck_parse_token(const char *cp, const char *filename, int linenum) +{ + int i; + for (i = 0; keywords[i].name; i++) + { + if (strcasecmp(cp, keywords[i].name) == 0) + { + return keywords[i].opcode; + } + } + + error("%s: line %d: Bad configuration option: %s", filename, linenum, cp); + + return sBadOption; +} +static int +ck_process_server_config_line(char *line, const char *filename, int linenum) +{ + char *cp, *arg, *endofnumber; + endofnumber = NULL; + cp = NULL; + arg = NULL; + int *intptr = NULL; + int value; + checkOpCodes opcode; + + cp = line; + if ((arg = strdelim(&cp)) == NULL) + { + return 1; + } + + /* Ignore leading whitespace */ + if (*arg == '\0') + { + arg = strdelim(&cp); + } + + if (!arg || !*arg || *arg == '#') + { + return 1; + } + + opcode = ck_parse_token(arg, filename, linenum); + + switch (opcode) + { + case sBadOption: + /* don't panic, but count bad ckoptions */ + return 0; + case sMaxFileSize: + intptr = &ckoptions.max_file_size; + goto parse_int; + + case sMinFreeMemSize: + intptr = &ckoptions.min_freemem_size; + goto parse_int; +parse_int: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + { + error("%.200s line %d: Missing argument.", filename, linenum); + return 0; + } + + if (arg[0] < '0' || arg[0] > '9') + { + error("%.200s line %d: Bad number.", filename, linenum); + return 0; + } + /* Octal, decimal, or hex format? */ + value = strtol(arg, &endofnumber, 0); + if (arg == endofnumber) + { + error("%.200s line %d: Bad number.", filename, linenum); + return 0; + } + + *intptr = value; + + break; + default: + error("%s line %d: Missing handler for opcode %s (%d) ", filename, linenum, arg, opcode); + break; + } + + if ((arg = strdelim(&cp)) != NULL && *arg != '\0') + { + error("%s line %d: garbage at end of line; \"%.200s\". ", filename, linenum, arg); + return 0; + } + + return 1; +} + +static int +ck_load_server_config(const char *filename, char *conf) +{ + char line[MAX_LINE_LEN + 1], *cp; + cp = NULL; + FILE *f; + int lineno = 0; + int lenth = 0; + + if ((f = fopen(filename, "r")) == NULL) + { + error("Failed to open config file: %s ,use default setting", filename); + return 2; + } + + while (fgets(line, sizeof(line), f)) + { + lineno++; + if (strlen(line) > MAX_LINE_LEN) + { + error("%s line %d too long, the max length is %d", filename, lineno, MAX_LINE_LEN); + fclose(f); + return 0; + } + /* + * * Trim out comments and strip whitespace + * * NB - preserve newlines, they are needed to reproduce + * * line numbers later for error messages + * */ + if ((cp = strchr(line, '#')) != NULL) + { + memcpy(cp, "\n", 2); + } + cp = line + strspn(line, " \t\r"); + + if(lenth + strlen(cp) > BUF_MAX_LEN) + { + error("%s too big, the max size is %d!", filename, BUF_MAX_LEN); + fclose(f); + return 0; + } + + memcpy(conf + lenth, cp, strlen(cp)); + + lenth += strlen(cp); + } + + memcpy(conf + lenth, "\0", 1); + + fclose(f); + + return 1; +} + +static int +ck_parse_server_config(const char *filename) +{ + int linenum, ret_load, bad_options = 0; + char *cp = NULL; + char *obuf = NULL; + char *cbuf = NULL; + + obuf = cbuf = malloc(BUF_MAX_LEN); + if (cbuf == NULL) + { + error("Malloc: out of memory (allocating %lu bytes)", BUF_MAX_LEN); + return 0; + } + + ret_load = ck_load_server_config(filename, cbuf); + + if(ret_load == 0) + { + error("Config file %s is not set properly", filename); + free(obuf); + return 0; + } + + if(ret_load == 2) + { + debug("Load config file %s error, use default setting", filename); + free(obuf); + return 1; + } + + linenum = 1; + while ((cp = strsep(&cbuf, "\n")) != NULL) + { + if (!ck_process_server_config_line(cp, filename, linenum++) ) + { + bad_options++; + } + } + + free(obuf); + + if (bad_options > 0) + { + error("%s: terminating, %d bad configuration ckoptions", filename, bad_options); + return 0; + } + + return 1; +} + +void +initialize_check_options(CheckOptions *ckoptions) +{ + memset(ckoptions, 0, sizeof(*ckoptions)); + + ckoptions->max_file_size = DEFAULT_FILESIZE; + + ckoptions->min_freemem_size = DEFAULT_MEMSIZE; +} + +static int +check_before_write(const char *path, u_int64_t size) +{ + struct sysinfo meminfo; + u_int64_t maxfilesize = 0; + u_int64_t minfreememsize = 0; + + if (storage_flag != 1) + return 1; + + if (NULL == path) + { + error("process_write: Upload file is NULL."); + return 0; + } + + if (cflag == 0) + { + debug3("not put file to tmpfs or ramfs, do not need check free memory"); + return 1; + } + + debug("check file size and free mem info before write"); + + sysinfo(&meminfo); + maxfilesize = (u_int64_t)(ckoptions.max_file_size)*1024*1024; + minfreememsize = (u_int64_t)(ckoptions.min_freemem_size)*1024*1024; + + logit("upload file :%s size %llu freeram %lu bytes MaxFileSize %lu bytes MinFreeMemSize %lu bytes.", + path, size, meminfo.freeram, maxfilesize, minfreememsize); + + /*check file size*/ + if (size >= maxfilesize){ + error("process_write: file %s exceed %d MB, upload failed.", path, ckoptions.max_file_size); + return 0; + } + + /*check free mem*/ + if (meminfo.freeram <= minfreememsize){ + error("process_write: Memory limit set to %d MB, no space(memeroy system) left, upload failed.", + ckoptions.min_freemem_size); + return 0; + } + + return 1; +} + +static void +check_fstype(const char *path) +{ + struct statfs buf; + + memset(&buf, 0, sizeof(buf)); + if (statfs(path, &buf) !=0) + { + error("fstype unkown, do not check free memeroy."); + } + else if (buf.f_type == TMPFS_MAGIC || buf.f_type == RAMFS_MAGIC) + { + cflag = 1; + } +} +/* add end sftp oom fix */ + /* Packet handlers */ static void process_open(u_int32_t id); static void process_close(u_int32_t id); @@ -755,6 +1218,15 @@ process_open(u_int32_t id) (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ (r = decode_attrib(iqueue, &a)) != 0) fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268 */ + if (RETURN_OK != path_permition_check(name,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(name); + + return; + } + /* add end 2013/10/12 SR-0000287268 */ debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); @@ -788,6 +1260,8 @@ process_open(u_int32_t id) (void) umask(old_umask); /* restore umask to something sane */ if (status != SSH2_FX_OK) send_status(id, status); + if (storage_flag == 1) + check_fstype(name); free(name); } @@ -820,6 +1294,17 @@ process_read(u_int32_t id) (r = sshbuf_get_u32(iqueue, &len)) != 0) fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268*/ + char *path = NULL; + path = handle_to_name(handle); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + + return; + } + /* add end 2013/10/12 SR-0000287268*/ + debug("request %u: read \"%s\" (handle %d) off %llu len %u", id, handle_to_name(handle), handle, (unsigned long long)off, len); if ((fd = handle_to_fd(handle)) == -1) @@ -874,6 +1359,18 @@ process_write(u_int32_t id) (r = sshbuf_get_string(iqueue, &data, &len)) != 0) fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268*/ + char *path = NULL; + path = handle_to_name(handle); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(data); + + return; + } + /* add end 2013/10/12 SR-0000287268*/ + debug("request %u: write \"%s\" (handle %d) off %llu len %zu", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); @@ -888,17 +1385,30 @@ process_write(u_int32_t id) strerror(errno)); } else { /* XXX ATOMICIO ? */ - ret = write(fd, data, len); - if (ret == -1) { - status = errno_to_portable(errno); - error_f("write \"%.100s\": %s", - handle_to_name(handle), strerror(errno)); - } else if ((size_t)ret == len) { - status = SSH2_FX_OK; - handle_update_write(handle, ret); - } else { - debug2_f("nothing at all written"); + /* add begin sftp oom fix */ + if (storage_flag == 1) + debug("cflag is %d",cflag); + if (!check_before_write(handle_to_name(handle), off)){ + error("check file size and free mem info before write failed"); + unlink(handle_to_name(handle)); status = SSH2_FX_FAILURE; + send_status(id, status); + free(data); + sftp_server_cleanup_exit(1); + /* add end sftp oom fix */ + } else { + + ret = write(fd, data, len); + if (ret < 0) { + error("process_write: write failed"); + status = errno_to_portable(errno); + } else if ((size_t)ret == len) { + status = SSH2_FX_OK; + handle_update_write(handle, ret); + } else { + debug2("nothing at all written"); + status = SSH2_FX_FAILURE; + } } } } @@ -917,6 +1427,16 @@ process_do_stat(u_int32_t id, int do_lstat) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal_fr(r, "parse"); + /* add begin 2013/10/12 SR-0000287268 */ + if (RETURN_OK != path_permition_check(name,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(name); + + return; + } + /* add end 2013/10/12 SR-0000287268 */ + debug3("request %u: %sstat", id, do_lstat ? "l" : ""); verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); r = do_lstat ? lstat(name, &st) : stat(name, &st); @@ -953,6 +1473,16 @@ process_fstat(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) fatal_fr(r, "parse"); + + char *path = NULL; + path = handle_to_name(handle); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + + return; + } + debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); fd = handle_to_fd(handle); @@ -1005,6 +1535,14 @@ process_setstat(u_int32_t id) (r = decode_attrib(iqueue, &a)) != 0) fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(name); + + return; + } + debug("request %u: setstat name \"%s\"", id, name); if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", @@ -1059,6 +1597,13 @@ process_fsetstat(u_int32_t id) else { char *name = handle_to_name(handle); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + + return; + } + if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a.size); @@ -1116,6 +1661,14 @@ process_opendir(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(path); + + return; + } + debug3("request %u: opendir", id); logit("opendir \"%s\"", path); dirp = opendir(path); @@ -1170,6 +1723,9 @@ process_readdir(u_int32_t id) strcmp(path, "/") ? "/" : "", dp->d_name); if (lstat(pathname, &st) == -1) continue; + if (RETURN_OK != path_permition_check(pathname,FLAG_PERMITOP)) { + continue; + } stat_to_attrib(&st, &(stats[count].attrib)); stats[count].name = xstrdup(dp->d_name); stats[count].long_name = ls_file(dp->d_name, &st, @@ -1202,6 +1758,14 @@ process_remove(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(name); + + return; + } + debug3("request %u: remove", id); logit("remove name \"%s\"", name); r = unlink(name); @@ -1221,6 +1785,14 @@ process_mkdir(u_int32_t id) (r = decode_attrib(iqueue, &a)) != 0) fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(name); + + return; + } + mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm & 07777 : 0777; debug3("request %u: mkdir", id); @@ -1240,6 +1812,14 @@ process_rmdir(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(name,FLAG_PROTECTDIR)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(name); + + return; + } + debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); r = rmdir(name); @@ -1264,8 +1844,12 @@ process_realpath(u_int32_t id) } debug3("request %u: realpath", id); verbose("realpath \"%s\"", path); - if (sftp_realpath(path, resolvedname) == NULL) { - send_status(id, errno_to_portable(errno)); + if ((sftp_realpath(path, resolvedname) == NULL) + || (RETURN_OK != path_permition_check(resolvedname,FLAG_PERMITOP))) { + if (storage_flag != 1) + send_status(id, errno_to_portable(errno)); + else + send_status(id, SSH2_FX_PERMISSION_DENIED); } else { Stat s; attrib_clear(&s.attrib); @@ -1286,6 +1870,16 @@ process_rename(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(oldpath); + free(newpath); + + return; + } + debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; @@ -1345,6 +1939,14 @@ process_readlink(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal_fr(r, "parse"); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(path); + + return; + } + debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) @@ -1370,6 +1972,16 @@ process_symlink(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(oldpath); + free(newpath); + + return; + } + debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ @@ -1390,6 +2002,16 @@ process_extended_posix_rename(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(oldpath); + free(newpath); + + return; + } + debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); r = rename(oldpath, newpath); @@ -1408,6 +2030,15 @@ process_extended_statvfs(u_int32_t id) if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal_fr(r, "parse"); + + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(path); + + return; + } + debug3("request %u: statvfs", id); logit("statvfs \"%s\"", path); @@ -1426,6 +2057,17 @@ process_extended_fstatvfs(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) fatal_fr(r, "parse"); + + char *path = NULL; + path = handle_to_name(handle); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(path); + + return; + } + debug("request %u: fstatvfs \"%s\" (handle %u)", id, handle_to_name(handle), handle); if ((fd = handle_to_fd(handle)) < 0) { @@ -1448,6 +2090,15 @@ process_extended_hardlink(u_int32_t id) (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal_fr(r, "parse"); + if ((RETURN_OK != path_permition_check(oldpath,FLAG_PROTECTDIR)) + || (RETURN_OK != path_permition_check(newpath,FLAG_PROTECTDIR))) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(oldpath); + free(newpath); + return; + } + debug3("request %u: hardlink", id); logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); r = link(oldpath, newpath); @@ -1464,6 +2115,17 @@ process_extended_fsync(u_int32_t id) if ((r = get_handle(iqueue, &handle)) != 0) fatal_fr(r, "parse"); + + char *path = NULL; + path = handle_to_name(handle); + if (RETURN_OK != path_permition_check(path,FLAG_PERMITOP)) + { + send_status(id, SSH2_FX_PERMISSION_DENIED); + free(path); + + return; + } + debug3("request %u: fsync (handle %u)", id, handle); verbose("fsync \"%s\"", handle_to_name(handle)); if ((fd = handle_to_fd(handle)) < 0) @@ -2006,6 +2668,22 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handle log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler); + read_config_file(pszPermitPath, szPermitPath); + read_config_file(pszDenyPath, szDenyPath); + read_config_file(pszPermitPath_other, szPermitPath_other); + read_config_file(pszDenyPath_other, szDenyPath_other); + + if (storage_flag == 1) + { + initialize_check_options(&ckoptions); + debug("Parse config file: %s", ck_config_file_name); + if(!ck_parse_server_config(ck_config_file_name)) + { + error("Failed to parse config file: %s!", ck_config_file_name); + sftp_server_cleanup_exit(1); + } + } + /* * On platforms where we can, avoid making /proc/self/{mem,maps} * available to the user so that sftp access doesn't automatically -- 2.27.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2