Add cache to database for consistent 99/76999/1
authorsangwan.kwon <sangwan.kwon@samsung.com>
Wed, 22 Jun 2016 08:45:33 +0000 (17:45 +0900)
committersangwan.kwon <sangwan.kwon@samsung.com>
Tue, 28 Jun 2016 08:18:20 +0000 (17:18 +0900)
Change-Id: I75e5ecb82d0165210e48e35825f3812426e57c0c
Signed-off-by: sangwan.kwon <sangwan.kwon@samsung.com>
src/CMakeLists.txt
src/framework/common/cs-detected.cpp
src/framework/common/cs-detected.h
src/framework/db/cache.cpp [new file with mode: 0644]
src/framework/db/cache.h [new file with mode: 0644]
src/framework/db/manager.cpp
src/framework/db/manager.h
src/framework/service/cs-logic.cpp
src/framework/service/cs-logic.h

index 788787a..8470339 100755 (executable)
@@ -63,6 +63,7 @@ SET(${TARGET_CSR_SERVER}_SRCS
        framework/db/connection.cpp
        framework/db/statement.cpp
        framework/db/manager.cpp
+       framework/db/cache.cpp
 
        ${AC_BACKEND_SRCS}
 )
index 2871f2f..21d7397 100644 (file)
@@ -63,6 +63,35 @@ void CsDetected::Serialize(IStream &stream) const
                this->isApp, ts64);
 }
 
+CsDetected::CsDetected(const CsDetected &other) noexcept :
+       targetName(other.targetName),
+       malwareName(other.malwareName),
+       detailedUrl(other.detailedUrl),
+       pkgId(other.pkgId),
+       severity(other.severity),
+       response(other.response),
+       isApp(other.isApp),
+       ts(other.ts)
+{
+}
+
+CsDetected &CsDetected::operator=(const CsDetected &other) noexcept
+{
+       if (this == &other)
+               return *this;
+
+       this->targetName = other.targetName;
+       this->malwareName = other.malwareName;
+       this->detailedUrl = other.detailedUrl;
+       this->pkgId = other.pkgId;
+       this->severity = other.severity;
+       this->response = other.response;
+       this->isApp = other.isApp;
+       this->ts = other.ts;
+
+       return *this;
+}
+
 CsDetected::CsDetected(CsDetected &&other) noexcept :
        targetName(std::move(other.targetName)),
        malwareName(std::move(other.malwareName)),
index 587a3b9..7826dcf 100644 (file)
@@ -41,6 +41,8 @@ struct API CsDetected : public IResult {
        CsDetected(IStream &);
        virtual void Serialize(IStream &) const override;
 
+       CsDetected(const CsDetected &) noexcept;
+       CsDetected &operator=(const CsDetected &) noexcept;
        CsDetected(CsDetected &&) noexcept;
        CsDetected &operator=(CsDetected &&) noexcept;
 
diff --git a/src/framework/db/cache.cpp b/src/framework/db/cache.cpp
new file mode 100644 (file)
index 0000000..9374bf2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        cache.cpp
+ * @author      Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version     1.0
+ * @brief       Cache for hold the data temporally before insert to DB
+ */
+#include "db/cache.h"
+#include "common/audit/logger.h"
+
+namespace Csr {
+namespace Db {
+
+Cache::Cache(Cache &&rhs) noexcept :
+       pkgPath(std::move(rhs.pkgPath)),
+       pkgId(std::move(rhs.pkgId)),
+       dataVersion(std::move(rhs.dataVersion)),
+       riskiestPath(std::move(rhs.riskiestPath)),
+       filePaths(std::move(rhs.filePaths)),
+       detecteds(std::move(rhs.detecteds)),
+       riskiest(std::move(rhs.riskiest)),
+       scanTime(rhs.scanTime)
+{
+}
+
+Cache &Cache::operator=(Cache &&rhs) noexcept
+{
+       if (this == &rhs)
+               return *this;
+
+       this->pkgPath = std::move(rhs.pkgPath);
+       this->pkgId = std::move(rhs.pkgId);
+       this->dataVersion = std::move(rhs.dataVersion);
+       this->riskiestPath = std::move(rhs.riskiestPath);
+       this->filePaths = std::move(rhs.filePaths);
+       this->detecteds = std::move(rhs.detecteds);
+       this->riskiest = std::move(rhs.riskiest);
+       this->scanTime = rhs.scanTime;
+
+       return *this;
+}
+
+} // namespace Db
+} // namespace Csr
diff --git a/src/framework/db/cache.h b/src/framework/db/cache.h
new file mode 100644 (file)
index 0000000..20fc5b2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        cache.h
+ * @author      Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version     1.0
+ * @brief       Cache for hold the data temporally before insert to DB
+ */
+#pragma once
+
+#include <string>
+#include <vector>
+#include <ctime>
+
+#include "common/cs-detected.h"
+
+namespace Csr {
+namespace Db {
+
+struct Cache {
+public:
+       Cache() = default;
+       virtual ~Cache() = default;
+
+       Cache(const Cache &) = delete;
+       Cache &operator=(const Cache &) = delete;
+       Cache(Cache &&) noexcept;
+       Cache &operator=(Cache &&) noexcept;
+
+       std::string pkgPath;
+       std::string pkgId;
+       std::string dataVersion;
+       std::string riskiestPath;
+       std::vector<std::string> filePaths;
+       std::vector<CsDetected> detecteds;
+       CsDetectedPtr riskiest;
+       time_t scanTime;
+};
+
+} // namespace Db
+} // namespace Csr
index f2b81ba..90f26e0 100644 (file)
@@ -469,8 +469,6 @@ void Manager::insertDetectedFile(const std::string &filepath, const CsDetected &
 void Manager::insertDetectedFileInApp(const std::string &pkgpath, const std::string &filepath,
                                                                          const CsDetected &d, const std::string &dataVersion)
 {
-       std::lock_guard<std::mutex> l(this->m_mutex);
-
        this->insertName(pkgpath);
        this->insertDetected(d, filepath, dataVersion);
 }
@@ -484,6 +482,15 @@ void Manager::insertDetectedAppByCloud(const std::string &name, const std::strin
        this->insertDetectedCloud(d, pkgId, name, dataVersion);
 }
 
+void Manager::insertCache(const Cache &c)
+{
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
+       for(std::vector<int>::size_type i = 0; i < c.detecteds.size(); i++)
+               this->insertDetectedFileInApp(
+                       c.pkgPath, c.filePaths[i], c.detecteds[i], c.dataVersion);
+}
+
 void Manager::insertName(const std::string &name)
 {
        Statement stmt(this->m_conn, Query::INS_NAME);
index d63e05b..2ec4bdf 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "db/connection.h"
 #include "db/row.h"
+#include "db/cache.h"
 #include "common/cs-detected.h"
 
 #include <csr-engine-manager.h>
@@ -66,10 +67,9 @@ public:
        RowShPtrs getDetectedByFilepathOnDir(const std::string &dir, time_t since);
        RowShPtr getWorstByPkgPath(const std::string &pkgPath, time_t since);
 
+       void insertCache(const Cache &c);
        void insertDetectedFile(const std::string &filepath, const CsDetected &d,
                                                        const std::string &dataVersion);
-       void insertDetectedFileInApp(const std::string &pkgpath, const std::string &filepath,
-                                                                const CsDetected &d, const std::string &dataVersion);
        void insertDetectedAppByCloud(const std::string &name, const std::string &pkgId,
                                                         const CsDetected &d, const std::string &dataVersion);
        void insertWorst(const std::string &pkgId, const std::string &name,
@@ -91,6 +91,8 @@ private:
                                                const std::string &dataVersion);
        void insertDetectedCloud(const CsDetected &d, const std::string &pkgId,
                                                         const std::string &name, const std::string &dataVersion);
+       void insertDetectedFileInApp(const std::string &pkgpath, const std::string &filepath,
+                                                                const CsDetected &d, const std::string &dataVersion);
 
        void resetDatabase();
        bool isTableExist(const std::string &name);
index 1d24873..1687ac3 100644 (file)
@@ -192,11 +192,8 @@ RawBuffer CsLogic::scanAppOnCloud(const CsContext &context,
        return this->handleAskUser(context, detected);
 }
 
-CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::string &pkgId,
-                                                                       std::string &riskiestPath)
+Db::Cache CsLogic::scanAppDelta(const std::string &pkgPath, const std::string &pkgId)
 {
-       auto starttime = ::time(nullptr);
-
        CsEngineContext engineContext(this->m_loader);
        auto &c = engineContext.get();
 
@@ -205,8 +202,11 @@ CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::strin
 
        // traverse files in app and take which is more danger than riskiest
        auto visitor = FsVisitor::create(pkgPath, lastScanTime);
-
-       CsDetectedPtr riskiest;
+       Db::Cache cache;
+       cache.pkgPath = pkgPath;
+       cache.pkgId = pkgId;
+       cache.scanTime = ::time(nullptr);
+       cache.dataVersion = this->m_dataVersion;
 
        while (auto file = visitor->next()) {
                DEBUG("Scan file by engine: " << file->getPath());
@@ -229,21 +229,19 @@ CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::strin
                candidate.isApp = true;
                candidate.pkgId = pkgId;
 
-               this->m_db->insertDetectedFileInApp(pkgPath, file->getPath(), candidate,
-                                                                                       this->m_dataVersion);
+               cache.filePaths.push_back(file->getPath());
+               cache.detecteds.push_back(candidate);
 
-               if (!riskiest) {
-                       riskiest.reset(new CsDetected(std::move(candidate)));
-                       riskiestPath = file->getPath();
-               } else if (*riskiest < candidate) {
-                       *riskiest = std::move(candidate);
-                       riskiestPath = file->getPath();
+               if (!cache.riskiest) {
+                       cache.riskiest.reset(new CsDetected(std::move(candidate)));
+                       cache.riskiestPath = file->getPath();
+               } else if (*(cache.riskiest) < candidate) {
+                       *(cache.riskiest) = std::move(candidate);
+                       cache.riskiestPath = file->getPath();
                }
        }
 
-       this->m_db->insertLastScanTime(pkgPath, this->m_dataVersion, starttime);
-
-       return riskiest;
+       return cache;
 }
 
 RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
@@ -265,9 +263,13 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
 
        // old history
        auto history = this->m_db->getWorstByPkgPath(pkgPath, since);
+
        // riskiest detected among newly scanned files
-       std::string riskiestPath;
-       auto riskiest = this->scanAppDelta(pkgPath, pkgId, riskiestPath);
+       auto cache = this->scanAppDelta(pkgPath, pkgId);
+       this->m_db->insertLastScanTime(pkgPath, cache.dataVersion, cache.scanTime);
+       CsDetectedPtr &riskiest = cache.riskiest;
+       auto riskiestPath = cache.riskiestPath;
+
        // history after delta scan. if worst file is changed, it's rescanned in scanAppDelta
        // and deleted from db if it's cured. if history != nullptr && after == nullptr,
        // it means worst detected item is cured anyway.
@@ -276,14 +278,17 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
                if (*history < *riskiest) {
                        INFO("worst case is remained but the more worst newly detected. on pkg[" <<
                                 pkgPath << "]");
-                       if (history->isIgnored)
-                               this->m_db->updateIgnoreFlag(pkgPath, false);
 
+                       this->m_db->insertCache(cache);
                        this->m_db->insertWorst(pkgId, pkgPath, riskiestPath);
+                       this->m_db->updateIgnoreFlag(pkgPath, false);
 
                        return this->handleAskUser(context, *riskiest);
                } else {
                        INFO("worst case is remained and can be re-used on pkg[" << pkgPath << "]");
+
+                       this->m_db->insertCache(cache);
+
                        if (history->isIgnored)
                                return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
 
@@ -292,6 +297,7 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
        } else if (history && after && !riskiest) {
                INFO("worst case is remained and NO new detected. history can be re-used. "
                         "on pkg[" << pkgPath << "]");
+
                if (history->isIgnored)
                        return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
 
@@ -309,28 +315,27 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
                if (!worse) {
                        INFO("No detected malware found in db.... Newly detected malware is removed by "
                                 "other client. Handle it as fully clean case.");
+
+                       this->m_db->insertCache(cache);
+
                        return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
                }
 
                if (*riskiest < *worse) {
                        INFO("worse case in db is worse than riskiest. on pkg[" << pkgPath << "]");
-                       riskiestPath = worse->fileInAppPath;
-                       *riskiest = std::move(*worse);
-               }
-
-               if (*history < *riskiest) {
-                       INFO("worst case is deleted but the more worst newly detected. on pkg[" <<
-                                pkgPath << "]");
-                       if (history->isIgnored)
-                               this->m_db->updateIgnoreFlag(pkgPath, false);
 
-                       this->m_db->insertWorst(pkgId, pkgPath, riskiestPath);
+                       this->m_db->insertCache(cache);
+                       this->m_db->insertWorst(pkgId, pkgPath, worse->fileInAppPath);
+                       this->m_db->updateIgnoreFlag(pkgPath, false);
 
-                       return this->handleAskUser(context, *riskiest);
+                       return this->handleAskUser(context, *worse);
                } else {
-                       INFO("worst case is deleted but same or less level newly detected. on pkg[" <<
+                       INFO("worst case is deleted but newly detected malware is more risky. on pkg[" <<
                                 pkgPath << "]");
+
+                       this->m_db->insertCache(cache);
                        this->m_db->insertWorst(pkgId, pkgPath, riskiestPath);
+                       this->m_db->updateIgnoreFlag(pkgPath, false);
 
                        if (history->isIgnored)
                                return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
@@ -363,10 +368,13 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &pkgPath)
                         "NO worse case. the pkg[" << pkgPath << "] is clean.");
 
                this->m_db->deleteDetectedByNameOnPath(pkgPath);
+
                return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
        } else if (!history && riskiest) {
                INFO("no history and new detected");
+               this->m_db->insertCache(cache);
                this->m_db->insertWorst(pkgId, pkgPath, riskiestPath);
+               this->m_db->updateIgnoreFlag(pkgPath, false);
 
                return this->handleAskUser(context, *riskiest);
        } else {
index ca9ef58..41ea9db 100644 (file)
@@ -30,6 +30,7 @@
 #include "common/cs-context.h"
 #include "common/cs-detected.h"
 #include "db/manager.h"
+#include "db/cache.h"
 #include "service/cs-loader.h"
 #include "service/file-system.h"
 #include "service/logic.h"
@@ -59,8 +60,7 @@ private:
        RawBuffer scanApp(const CsContext &context, const std::string &pkgPath);
        RawBuffer scanAppOnCloud(const CsContext &context, const std::string &pkgPath,
                                                         const std::string &pkgId);
-       CsDetectedPtr scanAppDelta(const std::string &pkgPath, const std::string &pkgId,
-                                                          std::string &riskiestPath);
+       Db::Cache scanAppDelta(const std::string &pkgPath, const std::string &pkgId);
 
        RawBuffer scanFileWithoutDelta(const CsContext &context, const std::string &filepath,
                                                                   FilePtr &&fileptr);