From 9b6542cf04255be0d589e3c59ff3bb96db7e1594 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 3 May 2016 15:48:17 +0900 Subject: [PATCH] Make get scannable files credential-aware For files which are readable by server... - and removable by client -> list given to client - and unremovable by client -> list not given to client but scanning task of them is submitted to workqueue so as to perform in background Change-Id: I94d358f16d6781cc002e96c844b45e4d7fe59fd4 Signed-off-by: Kyungwook Tak --- src/framework/db/manager.cpp | 2 +- src/framework/db/manager.h | 2 +- src/framework/service/logic.cpp | 53 ++++++++++++++++++++++++++++---- src/framework/service/logic.h | 14 +++++++-- src/framework/service/server-service.cpp | 7 +++-- src/framework/service/server-service.h | 2 +- 6 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/framework/db/manager.cpp b/src/framework/db/manager.cpp index 784b5ca..4275c09 100644 --- a/src/framework/db/manager.cpp +++ b/src/framework/db/manager.cpp @@ -190,7 +190,7 @@ time_t Manager::getLastScanTime(const std::string &dir, return stmt.step() ? static_cast(stmt.getInt64()) : -1; } -void Manager::insertLastScanTime(const std::string &dir, long scanTime, +void Manager::insertLastScanTime(const std::string &dir, time_t scanTime, const std::string &dataVersion) { Statement stmt(m_conn, Query::INS_SCAN_REQUEST); diff --git a/src/framework/db/manager.h b/src/framework/db/manager.h index 4ad4c65..ae2fb75 100644 --- a/src/framework/db/manager.h +++ b/src/framework/db/manager.h @@ -46,7 +46,7 @@ public: // SCAN_REQUEST time_t getLastScanTime(const std::string &dir, const std::string &dataVersion); - void insertLastScanTime(const std::string &dir, long scanTime, + void insertLastScanTime(const std::string &dir, time_t scanTime, const std::string &dataVersion); void deleteLastScanTime(const std::string &dir); void cleanLastScanTime(); diff --git a/src/framework/service/logic.cpp b/src/framework/service/logic.cpp index fe025af..af0264a 100644 --- a/src/framework/service/logic.cpp +++ b/src/framework/service/logic.cpp @@ -24,18 +24,21 @@ #include #include #include +#include #include #include "common/audit/logger.h" #include "common/exception.h" #include "service/type-converter.h" #include "service/file-system.h" +#include "service/access-control.h" #include "ui/askuser.h" #include "csr/error.h" namespace Csr { -Logic::Logic() : +Logic::Logic(ThreadPool &pool) : + m_workqueue(pool), m_cs(new CsLoader(CS_ENGINE_PATH)), m_wp(new WpLoader(WP_ENGINE_PATH)), m_db(new Db::Manager(RW_DBSPACE "/.csr.db", RO_DBSPACE)) @@ -239,11 +242,12 @@ RawBuffer Logic::scanFile(const CsContext &context, const std::string &filepath) return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop(); } -RawBuffer Logic::getScannableFiles(const std::string &dir) +RawBuffer Logic::getScannableFiles(const Credential &cred, const std::string &dir) { auto lastScanTime = m_db->getLastScanTime(dir, m_csDataVersion); - StrSet fileset; + StrSet filesetForClient; + auto filesetForServer = std::make_shared(); try { auto visitor = FsVisitor::create(dir, lastScanTime); @@ -252,7 +256,10 @@ RawBuffer Logic::getScannableFiles(const std::string &dir) while (auto file = visitor->next()) { DEBUG("In dir[" << dir << "], Scannable file[" << file->getPath() << "]"); - fileset.insert(file->getPath()); + if (hasPermToRemove(cred, file->getPath())) + filesetForClient.insert(file->getPath()); + else + filesetForServer->insert(file->getPath()); } } catch (const FileDoNotExist &) { WARN("Directory isn't exist: " << dir << " return success with empty file set " @@ -267,10 +274,44 @@ RawBuffer Logic::getScannableFiles(const std::string &dir) if (lastScanTime != -1) { // for case: scan history exist and not modified. for (auto &row : m_db->getDetectedMalwares(dir)) - fileset.insert(row->targetName); + filesetForClient.insert(row->targetName); } - return BinaryQueue::Serialize(CSR_ERROR_NONE, fileset).pop(); + // no fileset for server-only or dir is scanning in background already.. just skip + if (filesetForServer->empty() || m_scanningDirs.count(dir) != 0) + return BinaryQueue::Serialize(CSR_ERROR_NONE, filesetForClient).pop(); + + // update last scan time before start. + // to set scan time early is safe because file which is modified between + // scan start time and end time will be traversed by FsVisitor and re-scanned + // being compared to start time as modified since. + m_db->insertLastScanTime(dir, time(nullptr), m_csDataVersion); + + m_workqueue.submit([this, dir, filesetForServer]() { + { + std::lock_guard l(this->m_mutex); + this->m_scanningDirs.insert(dir); + } + + // TODO: how to set default option of scan on cloud? + // ask user -> not ask user + // message -> none because not ask user + // core usage -> default + CsContext context; + + for (auto file : *filesetForServer) { + // results are registered to db automatically + // so need not to handle returned data + this->scanFileHelper(context, file); + } + + { + std::lock_guard l(this->m_mutex); + this->m_scanningDirs.erase(dir); + } + }); + + return BinaryQueue::Serialize(CSR_ERROR_NONE, filesetForClient).pop(); } RawBuffer Logic::judgeStatus(const std::string &filepath, csr_cs_action_e action) diff --git a/src/framework/service/logic.h b/src/framework/service/logic.h index 54159c5..a4264d5 100644 --- a/src/framework/service/logic.h +++ b/src/framework/service/logic.h @@ -24,13 +24,16 @@ #include #include #include +#include #include "common/types.h" +#include "common/credential.h" #include "common/cs-context.h" #include "common/wp-context.h" #include "common/cs-detected.h" #include "common/wp-result.h" #include "db/manager.h" +#include "service/thread-pool.h" #include "service/cs-loader.h" #include "service/wp-loader.h" @@ -40,12 +43,14 @@ namespace Csr { class Logic { public: - Logic(); + Logic(ThreadPool &); virtual ~Logic(); + void submit(std::function &&task); + RawBuffer scanData(const CsContext &context, const RawBuffer &data); RawBuffer scanFile(const CsContext &context, const std::string &filepath); - RawBuffer getScannableFiles(const std::string &dir); + RawBuffer getScannableFiles(const Credential &cred, const std::string &dir); RawBuffer judgeStatus(const std::string &filepath, csr_cs_action_e action); RawBuffer getDetected(const std::string &filepath); RawBuffer getDetectedList(const StrSet &dirSet); @@ -64,6 +69,11 @@ private: static csr_wp_user_response_e getUserResponse(const WpContext &, const std::string &url, const WpResult &); + // internal task submit to thread pool for background scanning + ThreadPool &m_workqueue; + std::mutex m_mutex; + StrSet m_scanningDirs; + std::shared_ptr m_cs; std::shared_ptr m_wp; std::unique_ptr m_db; diff --git a/src/framework/service/server-service.cpp b/src/framework/service/server-service.cpp index ef89551..9970371 100644 --- a/src/framework/service/server-service.cpp +++ b/src/framework/service/server-service.cpp @@ -36,7 +36,8 @@ namespace Csr { ServerService::ServerService(const std::string &address) : Service(address), - m_workqueue(2, 10) + m_workqueue(2, 10), + m_logic(m_workqueue) { } @@ -44,7 +45,7 @@ ServerService::~ServerService() { } -RawBuffer ServerService::process(const ConnShPtr &, RawBuffer &data) +RawBuffer ServerService::process(const ConnShPtr &conn, RawBuffer &data) { CommandId id; @@ -73,7 +74,7 @@ RawBuffer ServerService::process(const ConnShPtr &, RawBuffer &data) std::string dir; q.Deserialize(dir); - return m_logic.getScannableFiles(dir); + return m_logic.getScannableFiles(conn->getCredential(), dir); } case CommandId::JUDGE_STATUS: { diff --git a/src/framework/service/server-service.h b/src/framework/service/server-service.h index 8a99928..a7ad9ec 100644 --- a/src/framework/service/server-service.h +++ b/src/framework/service/server-service.h @@ -38,8 +38,8 @@ private: RawBuffer process(const ConnShPtr &, RawBuffer &); - Logic m_logic; ThreadPool m_workqueue; + Logic m_logic; }; } -- 2.7.4