From f7f2690bdc5b23883be3bc5902d16e815e27a699 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Tue, 14 Jun 2016 11:16:18 +0900 Subject: [PATCH] Handling history detected by scan on cloud Add table to db schema to manage separately to ordinary app scanning. It's for giving detected/ignored/judge malwares because those work based on history in db. Change-Id: I78fec4b61ed7838298ec156dc2452ed7c4e64c6c Signed-off-by: Kyungwook Tak --- data/scripts/create_schema.sql | 18 ++++ data/scripts/drop_all.sql | 3 + src/framework/db/manager.cpp | 91 ++++++++++++++++++++ src/framework/db/manager.h | 7 +- src/framework/db/query.h | 18 ++++ src/framework/service/cs-logic.cpp | 32 +++++-- src/framework/service/iloader.cpp | 16 +++- test/engine/content-screening/sample-engine.cpp | 15 ++-- test/test-api-content-screening-async.cpp | 106 +++++++++++++++++++++--- 9 files changed, 277 insertions(+), 29 deletions(-) diff --git a/data/scripts/create_schema.sql b/data/scripts/create_schema.sql index 453bc64..f690928 100644 --- a/data/scripts/create_schema.sql +++ b/data/scripts/create_schema.sql @@ -63,6 +63,18 @@ CREATE TABLE IF NOT EXISTS DETECTED_MALWARE ( UNIQUE(file_path) ); +CREATE TABLE IF NOT EXISTS DETECTED_MALWARE_CLOUD ( + idx INTEGER NOT NULL, + pkg_id TEXT NOT NULL, + data_version TEXT NOT NULL, + malware_name TEXT NOT NULL, + detailed_url TEXT NOT NULL, + severity INTEGER NOT NULL, + detected_time INTEGER NOT NULL, + + FOREIGN KEY(idx) REFERENCES NAMES(idx) ON DELETE CASCADE +); + CREATE TABLE IF NOT EXISTS PACKAGE_INFO ( pkg_id TEXT NOT NULL, idx INTEGER NOT NULL, @@ -73,6 +85,11 @@ CREATE TABLE IF NOT EXISTS PACKAGE_INFO ( FOREIGN KEY(worst_filepath_idx) REFERENCES DETECTED_MALWARE(filepath_idx) ON DELETE CASCADE ); +CREATE VIEW IF NOT EXISTS [join_detecteds_cloud_by_name] AS + SELECT N.name, D.data_version, D.malware_name, D.detailed_url, D.severity, + D.detected_time, D.pkg_id, N.is_ignored + FROM NAMES AS N INNER JOIN DETECTED_MALWARE_CLOUD AS D ON N.idx = D.idx; + CREATE VIEW IF NOT EXISTS [join_p_d] AS SELECT N.idx, N.name, D.file_path, D.data_version, D.malware_name, D.detailed_url, D.severity, D.detected_time, P.pkg_id @@ -100,5 +117,6 @@ CREATE VIEW IF NOT EXISTS [join_detecteds_by_file_path] AS AS J INNER JOIN NAMES AS N ON J.idx = N.idx; CREATE INDEX IF NOT EXISTS d_name_index ON DETECTED_MALWARE(idx); +CREATE INDEX IF NOT EXISTS c_name_index ON DETECTED_MALWARE_CLOUD(idx); CREATE INDEX IF NOT EXISTS p_name_index ON PACKAGE_INFO(idx); CREATE INDEX IF NOT EXISTS p_filepath_index ON PACKAGE_INFO(worst_filepath_idx); diff --git a/data/scripts/drop_all.sql b/data/scripts/drop_all.sql index de854d4..ea2a355 100644 --- a/data/scripts/drop_all.sql +++ b/data/scripts/drop_all.sql @@ -1,12 +1,15 @@ DROP INDEX IF EXISTS d_name_index; +DROP INDEX IF EXISTS c_name_index; DROP INDEX IF EXISTS p_name_index; DROP INDEX IF EXISTS p_filepath_index; +DROP VIEW IF EXISTS join_detecteds_cloud_by_name; DROP VIEW IF EXISTS join_detecteds_by_file_path; DROP VIEW IF EXISTS join_detecteds_by_name; DROP VIEW IF EXISTS join_p_d; DROP TABLE IF EXISTS PACKAGE_INFO; +DROP TABLE IF EXISTS DETECTED_MALWARE_CLOUD; DROP TABLE IF EXISTS DETECTED_MALWARE; DROP TABLE IF EXISTS NAMES; DROP TABLE IF EXISTS SCAN_REQUEST; diff --git a/src/framework/db/manager.cpp b/src/framework/db/manager.cpp index d8aa1a5..5c64e01 100644 --- a/src/framework/db/manager.cpp +++ b/src/framework/db/manager.cpp @@ -65,6 +65,24 @@ RowShPtr extractRow(Statement &stmt) return row; } +RowShPtr extractRowCloud(Statement &stmt) +{ + RowShPtr row = std::make_shared(); + + row->targetName = stmt.getText(); // name. + row->fileInAppPath.clear(); + row->dataVersion = stmt.getText(); // data_version + row->malwareName = stmt.getText(); // malware_name + row->detailedUrl = stmt.getText(); // detailed_url + row->severity = static_cast(stmt.getInt()); // severity + row->ts = static_cast(stmt.getInt64()); // detected_time + row->pkgId = stmt.getText(); // pkg_id + row->isApp = true; + row->isIgnored = static_cast(stmt.getInt()); + + return row; +} + } // namespace anonymous Manager::Manager(const std::string &dbfile, const std::string &scriptsDir) : @@ -278,6 +296,17 @@ RowShPtr Manager::getDetectedByNameOnPath(const std::string &path) return extractRow(stmt); } +RowShPtr Manager::getDetectedCloudByNameOnPath(const std::string &path) +{ + Statement stmt(this->m_conn, Query::SEL_DETECTED_CLOUD_BY_NAME_ON_PATH); + stmt.bind(path); + + if (!stmt.step()) + return nullptr; + + return extractRowCloud(stmt); +} + RowShPtrs Manager::getDetectedByNameOnDir(const std::string &dir) { Statement stmt(this->m_conn, Query::SEL_DETECTED_BY_NAME_ON_DIR); @@ -291,6 +320,53 @@ RowShPtrs Manager::getDetectedByNameOnDir(const std::string &dir) return rows; } +RowShPtrs Manager::getDetectedCloudByNameOnDir(const std::string &dir) +{ + Statement stmt(this->m_conn, Query::SEL_DETECTED_CLOUD_BY_NAME_ON_DIR); + stmt.bind(dir); + + RowShPtrs rows; + while (stmt.step()) + rows.emplace_back(extractRowCloud(stmt)); + + return rows; +} + +RowShPtrs Manager::getDetectedAllByNameOnDir(const std::string &dir) +{ + auto normals = this->getDetectedByNameOnDir(dir); + auto clouds = this->getDetectedCloudByNameOnDir(dir); + + if (clouds.empty()) + return normals; + + RowShPtrs rows; + + for (const auto &cloud : clouds) { + bool found = false; + auto it = normals.begin(); + + while (it != normals.end()) { + if ((*it)->targetName == cloud->targetName) { + rows.emplace_back(std::move(*it)); + it = normals.erase(it); + found = true; + break; + } else { + ++it; + } + } + + if (!found) + rows.push_back(cloud); + } + + for (auto &&normal : normals) + rows.emplace_back(std::move(normal)); + + return rows; +} + RowShPtrs Manager::getDetectedByFilepathOnDir(const std::string &dir) { Statement stmt(this->m_conn, Query::SEL_DETECTED_BY_FILEPATH_ON_DIR); @@ -350,6 +426,21 @@ void Manager::insertDetected(const CsDetected &d, const std::string &filepath, stmt.exec(); } +void Manager::insertDetectedCloud(const CsDetected &d, const std::string &pkgId, + const std::string &name, const std::string &dataVersion) +{ + Statement stmt(this->m_conn, Query::INS_DETECTED_CLOUD); + + stmt.bind(name); + stmt.bind(pkgId); + stmt.bind(dataVersion); + stmt.bind(d.malwareName); + stmt.bind(d.detailedUrl); + stmt.bind(static_cast(d.severity)); + stmt.bind(static_cast(d.ts)); + stmt.exec(); +} + void Manager::insertWorst(const std::string &pkgId, const std::string &name, const std::string &filepath) { diff --git a/src/framework/db/manager.h b/src/framework/db/manager.h index 4fbc0ba..5cd8cf7 100644 --- a/src/framework/db/manager.h +++ b/src/framework/db/manager.h @@ -62,13 +62,18 @@ public: // DETECTED_MALWARE_FILE & USER_RESPONSE RowShPtr getDetectedByNameOnPath(const std::string &path); + RowShPtr getDetectedCloudByNameOnPath(const std::string &path); RowShPtrs getDetectedByNameOnDir(const std::string &dir); + RowShPtrs getDetectedCloudByNameOnDir(const std::string &dir); + RowShPtrs getDetectedAllByNameOnDir(const std::string &dir); RowShPtrs getDetectedByFilepathOnDir(const std::string &dir); RowShPtr getWorstByPkgPath(const std::string &pkgPath); void insertName(const std::string &name); - void insertDetected(const CsDetected &, const std::string &filename, + void insertDetected(const CsDetected &d, const std::string &filename, const std::string &dataVersion); + void insertDetectedCloud(const CsDetected &d, const std::string &pkgId, + const std::string &name, const std::string &dataVersion); void insertWorst(const std::string &pkgId, const std::string &name, const std::string &filepath); diff --git a/src/framework/db/query.h b/src/framework/db/query.h index 524c6ee..bab73b1 100644 --- a/src/framework/db/query.h +++ b/src/framework/db/query.h @@ -50,12 +50,24 @@ const std::string DEL_SCAN_REQUEST_BY_DIR = const std::string DEL_SCAN_REQUEST = "delete from SCAN_REQUEST"; +const std::string SEL_DETECTED_CLOUD_BY_NAME_ON_PATH = + "select name, data_version, malware_name, detailed_url, severity, detected_time," + " pkg_id, is_ignored" + " from join_detecteds_cloud_by_name" + " where name = ?"; + const std::string SEL_DETECTED_BY_NAME_ON_PATH = "select name, file_path, data_version, malware_name, detailed_url, severity," " detected_time, pkg_id, is_ignored" " from join_detecteds_by_name" " where name = ?"; +const std::string SEL_DETECTED_CLOUD_BY_NAME_ON_DIR = + "select name, data_version, malware_name, detailed_url, severity, detected_time," + " pkg_id, is_ignored" + " from join_detecteds_cloud_by_name" + " where name like ? || '%'"; + const std::string SEL_DETECTED_BY_NAME_ON_DIR = "select name, file_path, data_version, malware_name, detailed_url, severity," " detected_time, pkg_id, is_ignored" @@ -77,6 +89,12 @@ const std::string SEL_WORST_BY_PKGPATH = const std::string INS_NAME = "insert or replace into NAMES(name) values(?)"; +const std::string INS_DETECTED_CLOUD = + "insert or replace into DETECTED_MALWARE_CLOUD(idx, pkg_id, data_version," + " malware_name, detailed_url, severity," + " detected_time)" + " values((select idx from NAMES where name = ?), ?, ?, ?, ?, ?, ?)"; + const std::string INS_DETECTED = "insert or replace into DETECTED_MALWARE(file_path, idx, data_version, malware_name," " detailed_url, severity, detected_time)" diff --git a/src/framework/service/cs-logic.cpp b/src/framework/service/cs-logic.cpp index 3a7e541..bd38f22 100644 --- a/src/framework/service/cs-logic.cpp +++ b/src/framework/service/cs-logic.cpp @@ -186,6 +186,9 @@ RawBuffer CsLogic::scanAppOnCloud(const CsContext &context, detected.isApp = true; detected.pkgId = pkgId; + this->m_db->insertName(pkgPath); + this->m_db->insertDetectedCloud(detected, pkgId, pkgPath, this->m_dataVersion); + return this->handleAskUser(context, detected); } @@ -499,7 +502,7 @@ RawBuffer CsLogic::getScannableFiles(const std::string &dir) if (lastScanTime != -1) { // for case: scan history exist and not modified. - for (auto &row : this->m_db->getDetectedByNameOnDir(File::getPkgPath(dir))) { + for (auto &row : this->m_db->getDetectedAllByNameOnDir(File::getPkgPath(dir))) { try { auto fileptr = File::create(row->targetName); @@ -563,13 +566,22 @@ RawBuffer CsLogic::judgeStatus(const std::string &filepath, csr_cs_action_e acti auto history = this->m_db->getDetectedByNameOnPath(targetName); + bool isCloudHistory = false; + if (!history) { - ERROR("Target to be judged doesn't exist in db. name: " << targetName); - return BinaryQueue::Serialize(CSR_ERROR_INVALID_PARAMETER).pop(); + history = this->m_db->getDetectedCloudByNameOnPath(targetName); + + if (!history) { + ERROR("Target to be judged doesn't exist in db. name: " << targetName); + return BinaryQueue::Serialize(CSR_ERROR_INVALID_PARAMETER).pop(); + } + + isCloudHistory = true; } // file create based on fileInAppPath(for app target, it is worst detected) - if (File::createIfModified(history->fileInAppPath, static_cast(history->ts))) + if (!isCloudHistory && File::createIfModified(history->fileInAppPath, + static_cast(history->ts))) ThrowExc(CSR_ERROR_FILE_CHANGED, "File[" << history->fileInAppPath << "] modified since db delta inserted." " Don't refresh detected history to know that it's changed since the" @@ -611,6 +623,8 @@ RawBuffer CsLogic::getDetected(const std::string &filepath) } auto row = this->m_db->getDetectedByNameOnPath(target); + if (!row) + row = this->m_db->getDetectedCloudByNameOnPath(target); if (row && !row->isIgnored) return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop(); @@ -626,8 +640,8 @@ RawBuffer CsLogic::getDetectedList(const StrSet &_dirSet) Db::RowShPtrs rows; for (const auto &dir : dirSet) { - for (auto &row : this->m_db->getDetectedByNameOnDir(dir)) { - if (!isReadable(row->targetName)) { + for (auto &row : this->m_db->getDetectedAllByNameOnDir(dir)) { + if (!row->fileInAppPath.empty() && !isReadable(row->targetName)) { WARN("Exclude not-accessable malware detected file from the list: " << row->targetName); this->m_db->deleteDetectedByNameOnPath(row->targetName); @@ -656,6 +670,8 @@ RawBuffer CsLogic::getIgnored(const std::string &filepath) } auto row = this->m_db->getDetectedByNameOnPath(target); + if (!row) + row = this->m_db->getDetectedCloudByNameOnPath(target); if (row && row->isIgnored) return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop(); @@ -671,8 +687,8 @@ RawBuffer CsLogic::getIgnoredList(const StrSet &_dirSet) Db::RowShPtrs rows; for (const auto &dir : dirSet) { - for (auto &row : this->m_db->getDetectedByNameOnDir(dir)) { - if (!isReadable(row->targetName)) { + for (auto &row : this->m_db->getDetectedAllByNameOnDir(dir)) { + if (!row->fileInAppPath.empty() && !isReadable(row->targetName)) { WARN("Exclude not-accessable malware detected file from the list: " << row->targetName); this->m_db->deleteDetectedByNameOnPath(row->targetName); diff --git a/src/framework/service/iloader.cpp b/src/framework/service/iloader.cpp index 534a6d2..ec778c4 100644 --- a/src/framework/service/iloader.cpp +++ b/src/framework/service/iloader.cpp @@ -35,17 +35,29 @@ void ILoader::toException(int ee, bool internalErrorToString) case CSRE_ERROR_NONE: return; + case CSRE_ERROR_INVALID_PARAMETER: + ThrowExc(CSR_ERROR_ENGINE_INTERNAL, "CSRE_ERROR_INVALID_PARAMETER!"); + case CSRE_ERROR_OUT_OF_MEMORY: throw std::bad_alloc(); + case CSRE_ERROR_INVALID_HANDLE: + ThrowExc(CSR_ERROR_ENGINE_INTERNAL, "CSRE_ERROR_INVALID_HANDLE!"); + + case CSRE_ERROR_ENGINE_NOT_ACTIVATED: + ThrowExc(CSR_ERROR_ENGINE_NOT_ACTIVATED, "engine is not activated yet"); + case CSRE_ERROR_PERMISSION_DENIED: ThrowExc(CSR_ERROR_ENGINE_PERMISSION, "access denied related to engine"); case CSRE_ERROR_FILE_NOT_FOUND: ThrowExc(CSR_ERROR_FILE_DO_NOT_EXIST, "file not found."); - case CSRE_ERROR_ENGINE_NOT_ACTIVATED: - ThrowExc(CSR_ERROR_ENGINE_NOT_ACTIVATED, "engine is not activated yet"); + case CSRE_ERROR_NO_DATA: + ThrowExc(CSR_ERROR_ENGINE_INTERNAL, "CSRE_ERROR_NO_DATA!"); + + case CSRE_ERROR_UNKNOWN: + ThrowExc(CSR_ERROR_ENGINE_INTERNAL, "CSRE_ERROR_UNKNOWN!"); default: if (internalErrorToString) { diff --git a/test/engine/content-screening/sample-engine.cpp b/test/engine/content-screening/sample-engine.cpp index 0964fa3..a97b5b4 100644 --- a/test/engine/content-screening/sample-engine.cpp +++ b/test/engine/content-screening/sample-engine.cpp @@ -445,7 +445,6 @@ int csre_cs_scan_app_on_cloud(csre_cs_context_h handle, if (handle == nullptr || app_root_dir == nullptr || pdetected == nullptr) return CSRE_ERROR_INVALID_PARAMETER; - int ret; csre_cs_detected_h detected = nullptr; csre_cs_detected_h most_detected = nullptr; csre_cs_severity_level_e most = CSRE_CS_SEVERITY_LOW; @@ -453,8 +452,12 @@ int csre_cs_scan_app_on_cloud(csre_cs_context_h handle, std::unique_ptr> dirp(opendir(app_root_dir), closedir); - if (!dirp) - return CSRE_ERROR_FILE_NOT_FOUND; + if (!dirp) { + // silently skip the subdirectory in app_root_dir that unable to open because of + // having no permission + *pdetected = nullptr; + return CSRE_ERROR_NONE; + } struct dirent entry; struct dirent *result; @@ -465,6 +468,8 @@ int csre_cs_scan_app_on_cloud(csre_cs_context_h handle, fullpath += "/"; fullpath += filename; + int ret = CSRE_ERROR_NONE; + if (entry.d_type & (DT_REG | DT_LNK)) ret = csre_cs_scan_file(handle, fullpath.c_str(), &detected); else if ((entry.d_type & DT_DIR) @@ -492,9 +497,9 @@ int csre_cs_scan_app_on_cloud(csre_cs_context_h handle, } } - *pdetected = reinterpret_cast(detected); + *pdetected = most_detected; - return ret; + return CSRE_ERROR_NONE; } //============================================================================== diff --git a/test/test-api-content-screening-async.cpp b/test/test-api-content-screening-async.cpp index 95467f1..dfc02f4 100644 --- a/test/test-api-content-screening-async.cpp +++ b/test/test-api-content-screening-async.cpp @@ -252,12 +252,12 @@ BOOST_AUTO_TEST_CASE(scan_files_async_positive) TEST_FILE_HIGH, MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_HIGH, false, ""); - ASSERT_DETECTED_IN_LIST(testCtx.detectedList, - TEST_FILE_MEDIUM, MALWARE_MEDIUM_NAME, MALWARE_MEDIUM_SEVERITY, MALWARE_MEDIUM_DETAILED_URL); + ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_MEDIUM, MALWARE_MEDIUM_NAME, + MALWARE_MEDIUM_SEVERITY, MALWARE_MEDIUM_DETAILED_URL); ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_MEDIUM, false, ""); - ASSERT_DETECTED_IN_LIST(testCtx.detectedList, - TEST_FILE_LOW, MALWARE_LOW_NAME, MALWARE_LOW_SEVERITY, MALWARE_LOW_DETAILED_URL); + ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_LOW, MALWARE_LOW_NAME, + MALWARE_LOW_SEVERITY, MALWARE_LOW_DETAILED_URL); ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_LOW, false, ""); EXCEPTION_GUARD_END @@ -793,17 +793,23 @@ BOOST_AUTO_TEST_CASE(delta_scan_changed_after_scan) BOOST_REQUIRE_MESSAGE(testRescanCtx.scannedCnt >= 1, "reinstalled app(non-malicious wgt) should be counted in scanned."); - ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, - TEST_WGT_APP_ROOT(), MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); - ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(), true, TEST_WGT_PKG_ID); + ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(), + MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, + MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(), true, + TEST_WGT_PKG_ID); - ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, - TEST_TPK_APP_ROOT(), MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); - ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(), true, TEST_TPK_PKG_ID); + ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(), + MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, + MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(), true, + TEST_TPK_PKG_ID); - ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, - TEST_FAKE_APP_FILE(), MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); - ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(), false, ""); + ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(), + MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, + MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(), false, + ""); uninstall_test_apps(); @@ -1000,4 +1006,78 @@ BOOST_AUTO_TEST_CASE(async_api_returning_and_callback_race) EXCEPTION_GUARD_END } +BOOST_AUTO_TEST_CASE(scan_app_on_cloud) +{ + EXCEPTION_GUARD_START + + BOOST_MESSAGE("Only valid for engines which supports scan on cloud feature"); + + auto c = Test::Context(); + auto context = c.get(); + + install_test_files(); + install_test_apps(); + + set_default_callback(context); + ASSERT_SUCCESS(csr_cs_set_scan_on_cloud(context, true)); + + AsyncTestContext testCtx; + + ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testCtx)); + + std::unique_lock l(testCtx.m); + testCtx.cv.wait(l); + l.unlock(); + + ASSERT_CALLBACK(testCtx, -1, -1, 1, 0, 0); + + ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_WGT_APP_ROOT(), + MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, + MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_WGT_APP_ROOT(), true, + TEST_WGT_PKG_ID); + + ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_TPK_APP_ROOT(), + MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, + MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_TPK_APP_ROOT(), true, + TEST_TPK_PKG_ID); + + ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FAKE_APP_FILE(), + MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, + MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FAKE_APP_FILE(), false, ""); + + const char *dirs[1] = { + TEST_DIR_APPS() + }; + csr_cs_malware_list_h malwares = nullptr; + size_t count = 0; + + ASSERT_SUCCESS(csr_cs_get_detected_malwares(context, dirs, 1, &malwares, &count)); + CHECK_IS_NOT_NULL(malwares); + + std::vector malware_vec; + for (size_t i = 0; i < count; ++i) { + csr_cs_malware_h malware = nullptr; + ASSERT_SUCCESS(csr_cs_malware_list_get_malware(malwares, i, &malware)); + + malware_vec.push_back(malware); + } + + ASSERT_DETECTED_IN_LIST(malware_vec, TEST_WGT_APP_ROOT(), MALWARE_HIGH_NAME, + MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(malware_vec, TEST_WGT_APP_ROOT(), true, TEST_WGT_PKG_ID); + + ASSERT_DETECTED_IN_LIST(malware_vec, TEST_TPK_APP_ROOT(), MALWARE_HIGH_NAME, + MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(malware_vec, TEST_TPK_APP_ROOT(), true, TEST_TPK_PKG_ID); + + ASSERT_DETECTED_IN_LIST(malware_vec, TEST_FAKE_APP_FILE(), MALWARE_HIGH_NAME, + MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL); + ASSERT_DETECTED_IN_LIST_EXT(malware_vec, TEST_FAKE_APP_FILE(), false, ""); + + EXCEPTION_GUARD_END +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4