content scanning scan_file logic 03/67803/4
authorKyungwook Tak <k.tak@samsung.com>
Thu, 28 Apr 2016 04:28:03 +0000 (13:28 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Fri, 29 Apr 2016 06:12:02 +0000 (15:12 +0900)
Change-Id: I3882be7afdff968460c70eae6cb9ccbda41effbf
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
packaging/csr.manifest.in
src/framework/service/logic.cpp
src/framework/service/logic.h
test/test-api-content-screening-async.cpp
test/test-api-content-screening.cpp

index d889c37..c785f42 100644 (file)
@@ -17,6 +17,8 @@
                        <smack request="pulseaudio" type="w" />
                        <smack request="sdbd" type="rx" />
                        <smack request="pkgmgr::db" type="rwx" />
+
+                       <smack request="csr-test" type="rwxat" />
                </request>
                <permit>
                        <smack permit="_" type="rx" />
index 03e5273..3b9d908 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "common/audit/logger.h"
 #include "service/type-converter.h"
+#include "service/file-system.h"
 #include "ui/askuser.h"
 #include "csr/error.h"
 
@@ -59,7 +60,8 @@ void printCsContext(const CsContext &context)
 
 Logic::Logic() :
        m_cs(new CsLoader(CS_ENGINE_PATH)),
-       m_wp(new WpLoader(WP_ENGINE_PATH))
+       m_wp(new WpLoader(WP_ENGINE_PATH)),
+       m_db(new Db::Manager(RW_DBSPACE "/.csr.db", RO_DBSPACE))
 {
        // TODO: Provide engine-specific res/working dirs
        int ret = m_cs->globalInit(SAMPLE_ENGINE_RO_RES_DIR,
@@ -68,11 +70,23 @@ Logic::Logic() :
        if (ret != CSRE_ERROR_NONE)
                throw std::runtime_error(FORMAT("global init cs engine. ret: " << ret));
 
+       CsEngineInfo csEngineInfo(m_cs);
+       ret = m_cs->getEngineDataVersion(csEngineInfo.get(), m_csDataVersion);
+
+       if (ret != CSRE_ERROR_NONE)
+               throw std::runtime_error(FORMAT("get cs engine data version. ret: " << ret));
+
        ret = m_wp->globalInit(SAMPLE_ENGINE_RO_RES_DIR, SAMPLE_ENGINE_RW_WORKING_DIR);
 
        if (ret != CSRE_ERROR_NONE)
                throw std::runtime_error(FORMAT("global init wp engine. ret: " << ret));
 
+       WpEngineInfo wpEngineInfo(m_wp);
+       ret = m_wp->getEngineDataVersion(wpEngineInfo.get(), m_wpDataVersion);
+
+       if (ret != CSRE_ERROR_NONE)
+               throw std::runtime_error(FORMAT("get wp engine data version. ret: " << ret));
+
        DEBUG("Service logic ctor done");
 }
 
@@ -234,11 +248,76 @@ RawBuffer Logic::scanData(const CsContext &context, const RawBuffer &data)
 
 RawBuffer Logic::scanFile(const CsContext &context, const std::string &filepath)
 {
-       INFO("Scan file[" << filepath << "] by engine");
+       auto history = m_db->getDetectedMalware(filepath);
+
+       if (history) {
+               // history exist of malware detected for the file.
+               // let's check file modified since the detected time.
+               auto file = createVisitor(filepath, static_cast<time_t>(history->ts))->next();
+
+               if (file == nullptr) {
+                       // file isn't modified since the detected time. history can be used.
+                       // TODO: case should be separated. (file isn't exist) and (not modified)
+                       if (context.askUser) {
+                               if (history->isIgnored) {
+                                       history->response = CSR_CS_IGNORE;
+                               } else {
+                                       if ((history->response = getUserResponse(context, *history))
+                                                       == CSR_CS_IGNORE)
+                                               m_db->setDetectedMalwareIgnored(filepath, true);
+                               }
+                       }
+
+                       return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop();
+               } else {
+                       // file is modified since the detected time. let's remove history!
+                       m_db->deleteDetectedMalware(filepath);
+               }
+       }
 
-       printCsContext(context);
+       CsEngineContext engineContext(m_cs);
+       auto &c = engineContext.get();
+
+       csre_cs_detected_h result;
+       int ret = CSR_ERROR_NONE;
+       int eret = m_cs->scanFile(c, filepath, &result);
+
+       if (eret != CSRE_ERROR_NONE) {
+               ERROR("Engine error. engine api ret: " << eret);
+               return BinaryQueue::Serialize(CSR_ERROR_ENGINE_INTERNAL, CsDetected()).pop();
+       }
+
+       // detected handle is null if it's safe
+       if (result == nullptr)
+               return BinaryQueue::Serialize(ret, CsDetected()).pop();
 
-       return BinaryQueue::Serialize(CSR_ERROR_NONE, CsDetected()).pop();
+       auto d = convert(result);
+
+       d.targetName = filepath;
+
+       switch (d.severity) {
+       case CSR_CS_SEVERITY_LOW:
+               INFO("severity low for file scanned!");
+               break;
+
+       case CSR_CS_SEVERITY_MEDIUM:
+               INFO("severity medium for file scanned!");
+               d.response = getUserResponse(context, d);
+               break;
+
+       case CSR_CS_SEVERITY_HIGH:
+               INFO("severity high for file scanned!");
+               d.response = getUserResponse(context, d);
+               break;
+
+       default:
+               throw std::logic_error(FORMAT("Invalid severity: " <<
+                                                                         static_cast<int>(d.severity)));
+       }
+
+       m_db->insertDetectedMalware(d, m_csDataVersion, d.response == CSR_CS_IGNORE);
+
+       return BinaryQueue::Serialize(ret, d).pop();
 }
 
 RawBuffer Logic::dirGetResults(const CsContext &context, const std::string &dir)
index 95ac5e4..6201177 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <string>
 #include <utility>
+#include <memory>
 
 #include "common/types.h"
 #include "common/cs-context.h"
@@ -31,6 +32,7 @@
 #include "common/wp-result.h"
 #include "common/command-id.h"
 #include "common/binary-queue.h"
+#include "db/manager.h"
 #include "service/cs-loader.h"
 #include "service/wp-loader.h"
 
@@ -68,6 +70,10 @@ private:
 
        std::shared_ptr<CsLoader> m_cs;
        std::shared_ptr<WpLoader> m_wp;
+       std::unique_ptr<Db::Manager> m_db;
+
+       std::string m_csDataVersion;
+       std::string m_wpDataVersion;
 };
 
 }
index 5623d11..df45cde 100644 (file)
@@ -162,8 +162,8 @@ BOOST_AUTO_TEST_CASE(scan_files_async_positive)
        std::unique_lock<std::mutex> l(testCtx.m);
        testCtx.cv.wait(l);
        l.unlock();
-       BOOST_REQUIRE_MESSAGE(testCtx.completedCnt == 1 && testCtx.scannedCnt == 3 &&
-                                                 testCtx.detectedCnt == 0 && testCtx.cancelledCnt == 0 && testCtx.errorCnt == 0,
+       BOOST_REQUIRE_MESSAGE(testCtx.completedCnt == 1 && testCtx.scannedCnt == 1 &&
+                                                 testCtx.detectedCnt == 2 && testCtx.cancelledCnt == 0 && testCtx.errorCnt == 0,
                                                  "Async request result isn't expected.");
 
        EXCEPTION_GUARD_END
index 12e18d5..8d6ac5b 100644 (file)
 
 #include "test-common.h"
 
+#define TEST_FILE_NORMAL   TEST_DIR "/test_normal_file"
+#define TEST_FILE_MALWARE  TEST_DIR "/test_malware_file"
+#define TEST_FILE_RISKY    TEST_DIR "/test_risky_file"
+#define TEST_APP_ROOT      TEST_DIR "/test_app"
+
 BOOST_AUTO_TEST_SUITE(API_CONTENT_SCREENING)
 
 BOOST_AUTO_TEST_CASE(context_create_destroy)
@@ -106,7 +111,7 @@ BOOST_AUTO_TEST_CASE(scan_data)
        EXCEPTION_GUARD_END
 }
 
-BOOST_AUTO_TEST_CASE(scan_file)
+BOOST_AUTO_TEST_CASE(scan_file_normal)
 {
        EXCEPTION_GUARD_START
 
@@ -114,7 +119,7 @@ BOOST_AUTO_TEST_CASE(scan_file)
        auto context = c.get();
        csr_cs_detected_h detected;
 
-       ASSERT_IF(csr_cs_scan_file(context, "dummy_file_path", &detected),
+       ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_NORMAL, &detected),
                          CSR_ERROR_NONE);
 
        // no malware detected
@@ -123,6 +128,38 @@ BOOST_AUTO_TEST_CASE(scan_file)
        EXCEPTION_GUARD_END
 }
 
+BOOST_AUTO_TEST_CASE(scan_file_malware)
+{
+       EXCEPTION_GUARD_START
+
+       auto c = Test::Context<csr_cs_context_h>();
+       auto context = c.get();
+       csr_cs_detected_h detected;
+
+       ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected),
+                         CSR_ERROR_NONE);
+
+       CHECK_IS_NOT_NULL(detected);
+
+       EXCEPTION_GUARD_END
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_risky)
+{
+       EXCEPTION_GUARD_START
+
+       auto c = Test::Context<csr_cs_context_h>();
+       auto context = c.get();
+       csr_cs_detected_h detected;
+
+       ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected),
+                         CSR_ERROR_NONE);
+
+       CHECK_IS_NOT_NULL(detected);
+
+       EXCEPTION_GUARD_END
+}
+
 BOOST_AUTO_TEST_CASE(get_detected_malware)
 {
        EXCEPTION_GUARD_START