Inserts detected history per file when scan app 49/69649/1
authorKyungwook Tak <k.tak@samsung.com>
Mon, 16 May 2016 08:48:09 +0000 (17:48 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Mon, 16 May 2016 08:48:09 +0000 (17:48 +0900)
Change-Id: I060421272f7ddc14bcca6942356b2e8979ed5e04
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
src/framework/common/cs-detected.cpp
src/framework/common/cs-detected.h
src/framework/db/manager.cpp
src/framework/db/manager.h
src/framework/service/cs-logic.cpp
src/framework/service/cs-logic.h
test/internals/test-db.cpp

index cb75916..b95c74a 100644 (file)
@@ -90,4 +90,14 @@ CsDetected &CsDetected::operator=(CsDetected &&other)
        return *this;
 }
 
+bool CsDetected::operator>(const CsDetected &other) const noexcept
+{
+       return this->severity > other.severity;
+}
+
+bool CsDetected::operator<(const CsDetected &other) const noexcept
+{
+       return this->severity < other.severity;
+}
+
 }
index 3264ec1..1cad8e3 100644 (file)
@@ -42,6 +42,9 @@ struct CsDetected : public IResult {
        CsDetected(CsDetected &&);
        CsDetected &operator=(CsDetected &&);
 
+       bool operator>(const CsDetected &other) const noexcept;
+       bool operator<(const CsDetected &other) const noexcept;
+
        std::string targetName; // file(app) path which contains malware
 
        std::string malwareName;
index 755c00d..0faf2c8 100644 (file)
@@ -282,9 +282,7 @@ RowShPtr Manager::getDetectedMalware(const std::string &path)
        return row;
 }
 
-void Manager::insertDetectedMalware(const CsDetected &d,
-                                                                       const std::string &dataVersion,
-                                                                       bool isIgnored)
+void Manager::insertDetectedMalware(const CsDetected &d, const std::string &dataVersion)
 {
        Statement stmt(m_conn, Query::INS_DETECTED);
 
@@ -294,7 +292,7 @@ void Manager::insertDetectedMalware(const CsDetected &d,
        stmt.bind(d.malwareName);
        stmt.bind(d.detailedUrl);
        stmt.bind(static_cast<sqlite3_int64>(d.ts));
-       stmt.bind(static_cast<int>(isIgnored));
+       stmt.bind(static_cast<int>(false));
        stmt.exec();
 }
 
index ae2fb75..2f8a568 100644 (file)
@@ -54,8 +54,7 @@ public:
        // DETECTED_MALWARE_FILE & USER_RESPONSE
        RowShPtrs getDetectedMalwares(const std::string &dirpath);
        RowShPtr getDetectedMalware(const std::string &filepath);
-       void insertDetectedMalware(const CsDetected &, const std::string &dataVersion,
-                                                          bool isIgnored);
+       void insertDetectedMalware(const CsDetected &, const std::string &dataVersion);
        void setDetectedMalwareIgnored(const std::string &path, bool flag);
        void deleteDetectedMalware(const std::string &path);
        void deleteDeprecatedDetectedMalwares(const std::string &dir,
index 6c9e25a..57311dd 100644 (file)
@@ -104,64 +104,70 @@ RawBuffer CsLogic::scanData(const CsContext &context, const RawBuffer &data)
        EXCEPTION_GUARD_END
 }
 
-RawBuffer CsLogic::scanAppWithoutDelta(const CsContext &context, const FilePtr &appDirPtr)
+RawBuffer CsLogic::scanAppOnCloud(const CsContext &context,
+                                                                 const std::string &pkgPath,
+                                                                 const std::string &pkgId)
 {
-       const auto &pkgPath = appDirPtr->getAppPkgPath();
+       CsEngineContext engineContext(*m_loader);
+       auto &c = engineContext.get();
+
+       csre_cs_detected_h result;
+       toException(m_loader->scanAppOnCloud(c, pkgPath, &result));
+
+       if (!result)
+               return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
+
+       auto detected = convert(result, pkgPath);
+       detected.isApp = true;
+       detected.pkgId = pkgId;
+       detected.response = getUserResponse(context, detected);
+
+       return handleUserResponse(detected);
+}
 
+CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::string &pkgId)
+{
        auto starttime = time(nullptr);
 
-       CsEngineContext engineContext(*m_loader);
+       CsEngineContext engineContext(*this->m_loader);
        auto &c = engineContext.get();
 
-       bool isDetected = false;
-       CsDetected detected;
-
-       if (context.isScanOnCloud) {
-               csre_cs_detected_h result;
-               toException(m_loader->scanAppOnCloud(c, pkgPath, &result));
+       // traverse files in app and take which is more danger than riskiest.
+       auto visitor = FsVisitor::create(
+                       pkgPath,
+                       this->m_db->getLastScanTime(pkgPath, this->m_dataVersion));
 
-               if (result) {
-                       isDetected = true;
-                       detected = convert(result, pkgPath);
-               }
-       } else {
-               // traverse files in app. take which is more danger than detected.
-               auto visitor = FsVisitor::create(pkgPath,
-                                                                                m_db->getLastScanTime(pkgPath, m_dataVersion));
+       CsDetectedPtr riskiest;
 
-               while (auto file = visitor->next()) {
-                       csre_cs_detected_h result;
-                       toException(m_loader->scanFile(c, file->getPath(), &result));
+       while (auto file = visitor->next()) {
+               csre_cs_detected_h result;
+               toException(this->m_loader->scanFile(c, file->getPath(), &result));
 
-                       if (result) {
-                               auto d = convert(result, pkgPath);
+               if (!result)
+                       continue;
 
-                               if (!isDetected || detected.severity < d.severity)
-                                       detected = std::move(d);
+               auto candidate = convert(result, pkgPath);
+               candidate.isApp = true;
+               candidate.pkgId = pkgId;
+               this->m_db->insertDetectedMalware(candidate, this->m_dataVersion);
 
-                               isDetected = true;
-                       }
-               }
+               if (!riskiest)
+                       riskiest.reset(new CsDetected(std::move(candidate)));
+               else if (*riskiest < candidate)
+                       *riskiest = std::move(candidate);
        }
 
-       m_db->insertLastScanTime(pkgPath, starttime, m_dataVersion);
+       this->m_db->insertLastScanTime(pkgPath, starttime, this->m_dataVersion);
 
-       if (isDetected) {
-               detected.isApp = true;
-               detected.pkgId = appDirPtr->getAppPkgId();
+       if (riskiest)
+               riskiest->targetName = pkgPath;
 
-               // cloud scan detected history inserted by targetname = app base directory path
-               m_db->insertDetectedMalware(detected, m_dataVersion, false);
-               detected.response = getUserResponse(context, detected);
-               return handleUserResponse(detected);
-       } else {
-               return BinaryQueue::Serialize(CSR_ERROR_NONE, detected).pop();
-       }
+       return riskiest;
 }
 
 RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path)
 {
-       FilePtr fileptr = File::create(path);
+       auto fileptr = File::create(path);
 
        if (!fileptr)
                ThrowExc(InternalError, "fileptr shouldn't be null because no modified since.");
@@ -170,26 +176,40 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path)
                ThrowExc(InternalError, "fileptr should be in app.");
 
        const auto &pkgPath = fileptr->getAppPkgPath();
-
-       auto lastScanTime = m_db->getLastScanTime(pkgPath, m_dataVersion);
-
-       auto visitor = FsVisitor::create(pkgPath, lastScanTime);
-
-       // visitor with the last scan time has at least a file to traverse
-       // which means there's file which is modified since the last scan time.
-       // if there's no scan history so lastScanTime is -1, all existing files in path
-       // are traversable. visitor class isn't reusable because it already wasted a
-       // file to check.
-       if (visitor->next())
-               return scanAppWithoutDelta(context, fileptr);
-
-       auto history = m_db->getDetectedMalware(pkgPath);
-       if (!history)
+       const auto &pkgId = fileptr->getAppPkgId();
+
+       if (context.isScanOnCloud)
+               return this->scanAppOnCloud(context, pkgPath, pkgId);
+
+       auto riskiest = this->scanAppDelta(pkgPath, pkgId);
+       auto history = this->m_db->getDetectedMalware(pkgPath);
+
+       if (riskiest && history) {
+               if (*riskiest > *history) {
+                       // new malware found and more risky! history should be updated.
+                       this->m_db->insertDetectedMalware(*riskiest, this->m_dataVersion);
+               } else {
+                       // history is reusable...
+                       history->response = history->isIgnored
+                                       ? CSR_CS_IGNORE : this->getUserResponse(context, *history);
+                       return this->handleUserResponse(*history);
+               }
+       } else if (riskiest && !history) {
+               // new malware found! history should be updated.
+               this->m_db->insertDetectedMalware(*riskiest, this->m_dataVersion);
+       } else if (!riskiest && history) {
+               // history is reusable...
+               history->response = history->isIgnored
+                               ? CSR_CS_IGNORE : this->getUserResponse(context, *history);
+               return this->handleUserResponse(*history);
+       } else {
+               // no history and no malware detected newly...
                return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
+       }
 
-       history->response = history->isIgnored
-                       ? CSR_CS_IGNORE : getUserResponse(context, *history);
-       return handleUserResponse(*history);
+       // new and more risky malware found and db updated case only left.
+       riskiest->response = this->getUserResponse(context, *riskiest);
+       return this->handleUserResponse(*riskiest);
 }
 
 RawBuffer CsLogic::scanFileWithoutDelta(const CsContext &context,
@@ -207,7 +227,7 @@ RawBuffer CsLogic::scanFileWithoutDelta(const CsContext &context,
 
        auto d = convert(result, filepath);
 
-       m_db->insertDetectedMalware(d, m_dataVersion, false);
+       m_db->insertDetectedMalware(d, m_dataVersion);
 
        d.response = getUserResponse(context, d);
        return handleUserResponse(d, std::forward<FilePtr>(fileptr));
index 4a502e0..2cd599c 100644 (file)
@@ -52,11 +52,15 @@ public:
 
 private:
        RawBuffer scanApp(const CsContext &context, const std::string &path);
-       RawBuffer scanAppWithoutDelta(const CsContext &context, const FilePtr &appDirPtr);
+       RawBuffer scanAppOnCloud(const CsContext &context, const std::string &pkgPath,
+                                                        const std::string &pkgId);
+       CsDetectedPtr scanAppDelta(const std::string &pkgPath, const std::string &pkgId);
+
        RawBuffer scanFileWithoutDelta(const CsContext &context, const std::string &filepath,
                                                                   FilePtr &&fileptr);
-       RawBuffer handleUserResponse(const CsDetected &d, FilePtr &&fileptr = nullptr);
+
        CsDetected convert(csre_cs_detected_h &result, const std::string &targetName);
+       RawBuffer handleUserResponse(const CsDetected &d, FilePtr &&fileptr = nullptr);
 
        static csr_cs_user_response_e getUserResponse(const CsContext &,
                        const CsDetected &);
index da45c02..30f4742 100644 (file)
@@ -139,13 +139,14 @@ BOOST_AUTO_TEST_CASE(detected_malware_file)
        auto detectedList = db.getDetectedMalwares("/opt");
        ASSERT_IF(detectedList.empty(), true);
 
-       db.insertDetectedMalware(malware1, initDataVersion, false);
+       db.insertDetectedMalware(malware1, initDataVersion);
        detected = db.getDetectedMalware(malware1.targetName);
        checkSameMalware(malware1, *detected);
        ASSERT_IF(detected->dataVersion, initDataVersion);
        ASSERT_IF(detected->isIgnored, false);
 
-       db.insertDetectedMalware(malware2, initDataVersion, true);
+       db.insertDetectedMalware(malware2, initDataVersion);
+       db.setDetectedMalwareIgnored(malware2.targetName, true);
        detected = db.getDetectedMalware(malware2.targetName);
        checkSameMalware(malware2, *detected);
        ASSERT_IF(detected->dataVersion, initDataVersion);
@@ -171,7 +172,7 @@ BOOST_AUTO_TEST_CASE(detected_malware_file)
        ASSERT_IF(detected->isIgnored, true);
 
        // deleteDeprecatedDetectedMalwares test
-       db.insertDetectedMalware(malware3, changedDataVersion, false);
+       db.insertDetectedMalware(malware3, changedDataVersion);
        db.deleteDeprecatedDetectedMalwares("/opt", changedDataVersion);
        detected = db.getDetectedMalware(malware3.targetName);
        checkSameMalware(malware3, *detected);