加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
feature-openssh-7.4-hima-sftpserver-oom-and-fix.patch 24.82 KB
一键复制 编辑 原始数据 按行查看 历史
renmingshuai 提交于 2023-02-02 16:09 . update to 9.1p1
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
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
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化