From cf8d24ce2fa6032bb39a42b3e9d1bef613161153 Mon Sep 17 00:00:00 2001 From: Kyungwook Tak Date: Thu, 2 Jun 2016 14:46:31 +0900 Subject: [PATCH] Handle the case of engine not exist Change-Id: Ic9312ec7afb571e2f78a4a3382ef56527fb65344 Signed-off-by: Kyungwook Tak --- src/framework/service/cs-loader.cpp | 45 +++++------ src/framework/service/cs-loader.h | 27 ++++--- src/framework/service/cs-logic.cpp | 109 +++++++++++++------------- src/framework/service/cs-logic.h | 8 +- src/framework/service/em-logic.cpp | 34 +++++---- src/framework/service/em-logic.h | 9 ++- src/framework/service/exception.h | 1 + src/framework/service/iloader.h | 43 +++++++++++ src/framework/service/server-service.cpp | 126 ++++++++++++++++++------------- src/framework/service/server-service.h | 12 +-- src/framework/service/wp-loader.cpp | 69 +++++++++++------ src/framework/service/wp-loader.h | 21 +++--- src/framework/service/wp-logic.cpp | 23 ++++-- src/framework/service/wp-logic.h | 8 +- test/test-main.cpp | 15 +++- 15 files changed, 335 insertions(+), 215 deletions(-) create mode 100644 src/framework/service/iloader.h diff --git a/src/framework/service/cs-loader.cpp b/src/framework/service/cs-loader.cpp index e4389cd..50cd496 100644 --- a/src/framework/service/cs-loader.cpp +++ b/src/framework/service/cs-loader.cpp @@ -258,7 +258,7 @@ void CsLoader::init(const std::string &enginePath, const std::string &roResDir, this->m_pc.fpDestroyEngine = reinterpret_cast(dlsym(handle, "csre_cs_engine_destroy")); this->m_pc.fpGetEngineApiVersion = reinterpret_cast(dlsym( - handle, "csre_cs_engine_get_api_version")); + handle, "csre_cs_engine_get_api_version")); this->m_pc.fpGetEngineVendor = reinterpret_cast(dlsym(handle, "csre_cs_engine_get_vendor")); this->m_pc.fpGetEngineName = reinterpret_cast(dlsym(handle, @@ -266,14 +266,14 @@ void CsLoader::init(const std::string &enginePath, const std::string &roResDir, this->m_pc.fpGetEngineVersion = reinterpret_cast(dlsym(handle, "csre_cs_engine_get_version")); this->m_pc.fpGetEngineDataVersion = reinterpret_cast(dlsym( - handle, "csre_cs_engine_get_data_version")); + handle, "csre_cs_engine_get_data_version")); this->m_pc.fpGetEngineLatestUpdateTime = reinterpret_cast(dlsym(handle, "csre_cs_engine_get_latest_update_time")); - this->m_pc.fpGetEngineActivated = reinterpret_cast(dlsym(handle, - "csre_cs_engine_get_activated")); + this->m_pc.fpGetEngineActivated = reinterpret_cast(dlsym( + handle, "csre_cs_engine_get_activated")); this->m_pc.fpGetEngineVendorLogo = reinterpret_cast(dlsym( - handle, "csre_cs_engine_get_vendor_logo")); + handle, "csre_cs_engine_get_vendor_logo")); if (this->m_pc.fpGlobalInit == nullptr || this->m_pc.fpGlobalDeinit == nullptr || this->m_pc.fpContextCreate == nullptr || @@ -308,8 +308,7 @@ void CsLoader::init(const std::string &enginePath, const std::string &roResDir, } } -void CsLoader::reset(const std::string &enginePath, const std::string &roResDir, - const std::string &rwWorkingDir) +void CsLoader::deinit() { // ignore return value this->m_pc.fpGlobalDeinit(); @@ -318,8 +317,6 @@ void CsLoader::reset(const std::string &enginePath, const std::string &roResDir, dlclose(this->m_pc.dlhandle); this->m_pc.dlhandle = nullptr; } - - this->init(enginePath, roResDir, rwWorkingDir); } CsLoader::CsLoader(const std::string &enginePath, const std::string &roResDir, @@ -330,23 +327,22 @@ CsLoader::CsLoader(const std::string &enginePath, const std::string &roResDir, CsLoader::~CsLoader() { - // ignore return value - this->m_pc.fpGlobalDeinit(); - - if (this->m_pc.dlhandle) { - dlclose(this->m_pc.dlhandle); - this->m_pc.dlhandle = nullptr; - } + this->deinit(); } -CsEngineContext::CsEngineContext(CsLoader &loader) : m_loader(loader), m_context(nullptr) + +CsEngineContext::CsEngineContext(const std::shared_ptr &loader) : + m_loader(loader), m_context(nullptr) { - toException(this->m_loader.contextCreate(this->m_context)); + if (!this->m_loader) + ThrowExc(EngineNotExist, "null loader means engine not exist!"); + + toException(this->m_loader->contextCreate(this->m_context)); } CsEngineContext::~CsEngineContext() { - toException(this->m_loader.contextDestroy(this->m_context)); + toException(this->m_loader->contextDestroy(this->m_context)); } csre_cs_context_h &CsEngineContext::get(void) @@ -354,14 +350,19 @@ csre_cs_context_h &CsEngineContext::get(void) return this->m_context; } -CsEngineInfo::CsEngineInfo(CsLoader &loader) : m_loader(loader), m_info(nullptr) + +CsEngineInfo::CsEngineInfo(const std::shared_ptr &loader) : + m_loader(loader), m_info(nullptr) { - toException(this->m_loader.getEngineInfo(this->m_info)); + if (!this->m_loader) + ThrowExc(EngineNotExist, "null loader means engine not exist!"); + + toException(this->m_loader->getEngineInfo(this->m_info)); } CsEngineInfo::~CsEngineInfo() { - toException(this->m_loader.destroyEngine(this->m_info)); + toException(this->m_loader->destroyEngine(this->m_info)); } csre_cs_engine_h &CsEngineInfo::get(void) diff --git a/src/framework/service/cs-loader.h b/src/framework/service/cs-loader.h index 89b16f5..abba72b 100644 --- a/src/framework/service/cs-loader.h +++ b/src/framework/service/cs-loader.h @@ -21,31 +21,30 @@ */ #pragma once -#include +#include #include #include +#include #include #include +#include "service/iloader.h" + namespace Csr { -class CsLoader { +class CsLoader : public ILoader { public: CsLoader(const std::string &enginePath, const std::string &roResDir, const std::string &rwWorkingDir); virtual ~CsLoader(); - void reset(const std::string &enginePath, const std::string &roResDir, - const std::string &rwWorkingDir); - int contextCreate(csre_cs_context_h &); int contextDestroy(csre_cs_context_h); int scanData(csre_cs_context_h, const std::vector &, csre_cs_detected_h *); int scanFile(csre_cs_context_h, const std::string &, csre_cs_detected_h *); - int scanAppOnCloud(csre_cs_context_h, const std::string &, - csre_cs_detected_h *); + int scanAppOnCloud(csre_cs_context_h, const std::string &, csre_cs_detected_h *); int getSeverity(csre_cs_detected_h, csre_cs_severity_level_e *); int getMalwareName(csre_cs_detected_h, std::string &); @@ -73,8 +72,7 @@ private: csre_cs_detected_h *); using FpScanFile = int(*)(csre_cs_context_h, const char *, csre_cs_detected_h *); - using FpScanAppOnCloud = int(*)(csre_cs_context_h, const char *, - csre_cs_detected_h *); + using FpScanAppOnCloud = int(*)(csre_cs_context_h, const char *, csre_cs_detected_h *); using FpGetSeverity = int(*)(csre_cs_detected_h, csre_cs_severity_level_e *); using FpGetMalwareName = int(*)(csre_cs_detected_h, const char **); using FpGetDetailedUrl = int(*)(csre_cs_detected_h, const char **); @@ -117,30 +115,31 @@ private: FpGetEngineVendorLogo fpGetEngineVendorLogo; }; - void init(const std::string &, const std::string &, const std::string &); + virtual void init(const std::string &, const std::string &, const std::string &) override; + virtual void deinit(void) override; PluginContext m_pc; }; class CsEngineContext { public: - CsEngineContext(CsLoader &); + CsEngineContext(const std::shared_ptr &); ~CsEngineContext(); csre_cs_context_h &get(void); private: - CsLoader &m_loader; + std::shared_ptr m_loader; csre_cs_context_h m_context; }; class CsEngineInfo { public: - CsEngineInfo(CsLoader &); + CsEngineInfo(const std::shared_ptr &); ~CsEngineInfo(); csre_cs_engine_h &get(void); private: - CsLoader &m_loader; + std::shared_ptr m_loader; csre_cs_engine_h m_info; }; diff --git a/src/framework/service/cs-logic.cpp b/src/framework/service/cs-logic.cpp index fa8123a..13a5d27 100644 --- a/src/framework/service/cs-logic.cpp +++ b/src/framework/service/cs-logic.cpp @@ -54,18 +54,25 @@ void setCoreUsage(const csr_cs_core_usage_e &cu) } // namespace anonymous -CsLogic::CsLogic(CsLoader &loader, Db::Manager &db) : m_loader(loader), m_db(db) +CsLogic::CsLogic(const std::shared_ptr &loader, + const std::shared_ptr &db) : + m_loader(loader), m_db(db) { - CsEngineInfo csEngineInfo(this->m_loader); - toException(this->m_loader.getEngineDataVersion(csEngineInfo.get(), - this->m_dataVersion)); + if (!this->m_db) + ThrowExc(DbFailed, "Failed to init db"); + + if (this->m_loader) { + CsEngineInfo csEngineInfo(this->m_loader); + toException(this->m_loader->getEngineDataVersion(csEngineInfo.get(), + this->m_dataVersion)); + } } RawBuffer CsLogic::scanData(const CsContext &context, const RawBuffer &data) { EXCEPTION_GUARD_START - if (this->m_db.getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) + if (this->m_db->getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) ThrowExc(EngineDisabled, "engine is disabled"); setCoreUsage(context.coreUsage); @@ -77,7 +84,7 @@ RawBuffer CsLogic::scanData(const CsContext &context, const RawBuffer &data) auto timestamp = ::time(nullptr); - toException(this->m_loader.scanData(c, data, &result)); + toException(this->m_loader->scanData(c, data, &result)); // detected handle is null if it's safe if (result == nullptr) @@ -100,7 +107,7 @@ RawBuffer CsLogic::scanAppOnCloud(const CsContext &context, auto timestamp = ::time(nullptr); csre_cs_detected_h result; - toException(this->m_loader.scanAppOnCloud(c, pkgPath, &result)); + toException(this->m_loader->scanAppOnCloud(c, pkgPath, &result)); if (!result) return BinaryQueue::Serialize(CSR_ERROR_NONE).pop(); @@ -115,12 +122,12 @@ RawBuffer CsLogic::scanAppOnCloud(const CsContext &context, CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::string &pkgId, std::string &riskiestPath) { - auto starttime = time(nullptr); + auto starttime = ::time(nullptr); CsEngineContext engineContext(this->m_loader); auto &c = engineContext.get(); - auto lastScanTime = this->m_db.getLastScanTime(pkgPath, this->m_dataVersion); + auto lastScanTime = this->m_db->getLastScanTime(pkgPath, this->m_dataVersion); // traverse files in app and take which is more danger than riskiest auto visitor = FsVisitor::create(pkgPath, lastScanTime); @@ -133,11 +140,11 @@ CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::strin auto timestamp = ::time(nullptr); csre_cs_detected_h result; - toException(this->m_loader.scanFile(c, file->getPath(), &result)); + toException(this->m_loader->scanFile(c, file->getPath(), &result)); if (!result) { if (lastScanTime != -1) - this->m_db.deleteDetectedByFilepathOnPath(file->getPath()); + this->m_db->deleteDetectedByFilepathOnPath(file->getPath()); continue; } @@ -148,8 +155,8 @@ CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::strin candidate.isApp = true; candidate.pkgId = pkgId; - this->m_db.insertName(pkgPath); - this->m_db.insertDetected(candidate, file->getPath(), this->m_dataVersion); + this->m_db->insertName(pkgPath); + this->m_db->insertDetected(candidate, file->getPath(), this->m_dataVersion); if (!riskiest) { riskiest.reset(new CsDetected(std::move(candidate))); @@ -160,7 +167,7 @@ CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::strin } } - this->m_db.insertLastScanTime(pkgPath, starttime, this->m_dataVersion); + this->m_db->insertLastScanTime(pkgPath, starttime, this->m_dataVersion); return riskiest; } @@ -200,22 +207,22 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path) return this->scanAppOnCloud(context, pkgPath, pkgId); // old history - auto history = this->m_db.getWorstByPkgId(pkgId); + auto history = this->m_db->getWorstByPkgId(pkgId); // riskiest detected among newly scanned files std::string riskiestPath; auto riskiest = this->scanAppDelta(pkgPath, pkgId, 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. - auto after = this->m_db.getWorstByPkgId(pkgId); + auto after = this->m_db->getWorstByPkgId(pkgId); if (history && after && riskiest) { 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->updateIgnoreFlag(pkgPath, false); - this->m_db.insertWorst(pkgId, pkgPath, riskiestPath); + this->m_db->insertWorst(pkgId, pkgPath, riskiestPath); return this->handleAskUser(context, *riskiest); } else { @@ -237,7 +244,7 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path) "worse case in db and compare it with riskiest first. on pkg[" << pkgPath << "]"); Db::RowShPtr worse; - for (auto &row : this->m_db.getDetectedByFilepathOnDir(pkgPath)) + for (auto &row : this->m_db->getDetectedByFilepathOnDir(pkgPath)) if (!worse || *worse < *row) worse = std::move(row); @@ -257,15 +264,15 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path) 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->updateIgnoreFlag(pkgPath, false); - this->m_db.insertWorst(pkgId, pkgPath, riskiestPath); + this->m_db->insertWorst(pkgId, pkgPath, riskiestPath); return this->handleAskUser(context, *riskiest); } else { INFO("worst case is deleted but same or less level newly detected. on pkg[" << pkgPath << "]"); - this->m_db.insertWorst(pkgId, pkgPath, riskiestPath); + this->m_db->insertWorst(pkgId, pkgPath, riskiestPath); if (history->isIgnored) return BinaryQueue::Serialize(CSR_ERROR_NONE).pop(); @@ -273,7 +280,7 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path) return this->handleAskUser(context, *riskiest); } } else if (history && !after && !riskiest) { - auto rows = this->m_db.getDetectedByFilepathOnDir(pkgPath); + auto rows = this->m_db->getDetectedByFilepathOnDir(pkgPath); if (!rows.empty()) { INFO("worst case is deleted cascadingly and NO new detected and " @@ -284,7 +291,7 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path) worse = std::move(row); if (worse) { - this->m_db.insertWorst(pkgId, pkgPath, worse->fileInAppPath); + this->m_db->insertWorst(pkgId, pkgPath, worse->fileInAppPath); if (worse->isIgnored) return BinaryQueue::Serialize(CSR_ERROR_NONE).pop(); @@ -296,11 +303,11 @@ RawBuffer CsLogic::scanApp(const CsContext &context, const std::string &path) INFO("worst case is deleted cascadingly and NO new detected and " "NO worse case. the pkg[" << pkgPath << "] is clean."); - this->m_db.deleteDetectedByNameOnPath(pkgPath); + 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.insertWorst(pkgId, pkgPath, riskiestPath); + this->m_db->insertWorst(pkgId, pkgPath, riskiestPath); return this->handleAskUser(context, *riskiest); } else { @@ -318,7 +325,7 @@ RawBuffer CsLogic::scanFileWithoutDelta(const CsContext &context, auto timestamp = ::time(nullptr); csre_cs_detected_h result; - toException(this->m_loader.scanFile(c, filepath, &result)); + toException(this->m_loader->scanFile(c, filepath, &result)); // detected handle is null if it's safe if (result == nullptr) @@ -326,8 +333,8 @@ RawBuffer CsLogic::scanFileWithoutDelta(const CsContext &context, auto d = this->convert(result, filepath, timestamp); - this->m_db.insertName(d.targetName); - this->m_db.insertDetected(d, d.targetName, this->m_dataVersion); + this->m_db->insertName(d.targetName); + this->m_db->insertDetected(d, d.targetName, this->m_dataVersion); return this->handleAskUser(context, d, std::forward(fileptr)); } @@ -336,7 +343,7 @@ RawBuffer CsLogic::scanFile(const CsContext &context, const std::string &filepat { EXCEPTION_GUARD_START - if (this->m_db.getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) + if (this->m_db->getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) ThrowExc(EngineDisabled, "engine is disabled"); setCoreUsage(context.coreUsage); @@ -346,7 +353,7 @@ RawBuffer CsLogic::scanFile(const CsContext &context, const std::string &filepat DEBUG("Scan request on file: " << filepath); - auto history = this->m_db.getDetectedByNameOnPath(filepath); + auto history = this->m_db->getDetectedByNameOnPath(filepath); FilePtr fileptr; @@ -361,7 +368,7 @@ RawBuffer CsLogic::scanFile(const CsContext &context, const std::string &filepat // OR there's no history at all. if (fileptr) { if (history) - this->m_db.deleteDetectedByNameOnPath(filepath); + this->m_db->deleteDetectedByNameOnPath(filepath); if (fileptr->isDir()) ThrowExc(FileSystemError, "file type shouldn't be directory: " << filepath); @@ -411,10 +418,10 @@ RawBuffer CsLogic::getScannableFiles(const std::string &dir) { EXCEPTION_GUARD_START - if (this->m_db.getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) + if (this->m_db->getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) ThrowExc(EngineDisabled, "engine is disabled"); - auto lastScanTime = this->m_db.getLastScanTime(dir, this->m_dataVersion); + auto lastScanTime = this->m_db->getLastScanTime(dir, this->m_dataVersion); auto visitor = FsVisitor::create(dir, lastScanTime); @@ -435,16 +442,16 @@ 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->getDetectedByNameOnDir(File::getPkgPath(dir))) { try { auto fileptr = File::create(row->targetName); fileset.insert(fileptr->isInApp() ? fileptr->getAppPkgPath() : fileptr->getPath()); } catch (const FileDoNotExist &) { - this->m_db.deleteDetectedByNameOnPath(row->targetName); + this->m_db->deleteDetectedByNameOnPath(row->targetName); } catch (const FileSystemError &) { - this->m_db.deleteDetectedByNameOnPath(row->targetName); + this->m_db->deleteDetectedByNameOnPath(row->targetName); } } } @@ -458,7 +465,7 @@ RawBuffer CsLogic::canonicalizePaths(const StrSet &paths) { EXCEPTION_GUARD_START - if (this->m_db.getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) + if (this->m_db->getEngineState(CSR_ENGINE_CS) != CSR_STATE_ENABLE) ThrowExc(EngineDisabled, "engine is disabled"); StrSet canonicalized; @@ -496,7 +503,7 @@ RawBuffer CsLogic::setDirTimestamp(const std::string &dir, time_t ts) { EXCEPTION_GUARD_START - this->m_db.insertLastScanTime(dir, ts, this->m_dataVersion); + this->m_db->insertLastScanTime(dir, ts, this->m_dataVersion); return BinaryQueue::Serialize(CSR_ERROR_NONE).pop(); @@ -522,7 +529,7 @@ RawBuffer CsLogic::judgeStatus(const std::string &filepath, csr_cs_action_e acti const auto &targetName = (file->isInApp() ? file->getAppPkgPath() : filepath); - auto history = this->m_db.getDetectedByNameOnPath(targetName); + auto history = this->m_db->getDetectedByNameOnPath(targetName); if (!history) { ERROR("Target to be judged doesn't exist in db. name: " << targetName); @@ -539,15 +546,15 @@ RawBuffer CsLogic::judgeStatus(const std::string &filepath, csr_cs_action_e acti case CSR_CS_ACTION_REMOVE: file->remove(); - this->m_db.deleteDetectedByNameOnPath(targetName); + this->m_db->deleteDetectedByNameOnPath(targetName); break; case CSR_CS_ACTION_IGNORE: - this->m_db.updateIgnoreFlag(targetName, true); + this->m_db->updateIgnoreFlag(targetName, true); break; case CSR_CS_ACTION_UNIGNORE: - this->m_db.updateIgnoreFlag(targetName, false); + this->m_db->updateIgnoreFlag(targetName, false); break; default: @@ -564,7 +571,7 @@ RawBuffer CsLogic::getDetected(const std::string &filepath) { EXCEPTION_GUARD_START - auto row = this->m_db.getDetectedByNameOnPath(File::getPkgPath(filepath)); + auto row = this->m_db->getDetectedByNameOnPath(File::getPkgPath(filepath)); if (row && !row->isIgnored) return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop(); @@ -581,7 +588,7 @@ RawBuffer CsLogic::getDetectedList(const StrSet &dirSet) Db::RowShPtrs rows; std::for_each(dirSet.begin(), dirSet.end(), [this, &rows](const std::string & dir) { - for (auto &row : this->m_db.getDetectedByNameOnDir(File::getPkgPath(dir))) + for (auto &row : this->m_db->getDetectedByNameOnDir(File::getPkgPath(dir))) if (!row->isIgnored) rows.emplace_back(std::move(row)); }); @@ -599,7 +606,7 @@ RawBuffer CsLogic::getIgnored(const std::string &filepath) { EXCEPTION_GUARD_START - auto row = this->m_db.getDetectedByNameOnPath(File::getPkgPath(filepath)); + auto row = this->m_db->getDetectedByNameOnPath(File::getPkgPath(filepath)); if (row && row->isIgnored) return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop(); @@ -616,7 +623,7 @@ RawBuffer CsLogic::getIgnoredList(const StrSet &dirSet) Db::RowShPtrs rows; std::for_each(dirSet.begin(), dirSet.end(), [this, &rows](const std::string & dir) { - for (auto &row : this->m_db.getDetectedByNameOnDir(File::getPkgPath(dir))) + for (auto &row : this->m_db->getDetectedByNameOnDir(File::getPkgPath(dir))) if (row->isIgnored) rows.emplace_back(std::move(row)); }); @@ -683,7 +690,7 @@ RawBuffer CsLogic::handleAskUser(const CsContext &c, CsDetected &d, FilePtr &&fi WARN("File type is changed, considered as different file: " << d.targetName); } - this->m_db.deleteDetectedByNameOnPath(File::getPkgPath(d.targetName)); + this->m_db->deleteDetectedByNameOnPath(File::getPkgPath(d.targetName)); } return BinaryQueue::Serialize(CSR_ERROR_NONE, d).pop(); @@ -700,9 +707,9 @@ CsDetected CsLogic::convert(csre_cs_detected_h &result, const std::string &targe csre_cs_severity_level_e eseverity = CSRE_CS_SEVERITY_LOW; - toException(this->m_loader.getSeverity(result, &eseverity)); - toException(this->m_loader.getMalwareName(result, d.malwareName)); - toException(this->m_loader.getDetailedUrl(result, d.detailedUrl)); + toException(this->m_loader->getSeverity(result, &eseverity)); + toException(this->m_loader->getMalwareName(result, d.malwareName)); + toException(this->m_loader->getDetailedUrl(result, d.detailedUrl)); d.ts = timestamp; d.severity = Csr::convert(eseverity); diff --git a/src/framework/service/cs-logic.h b/src/framework/service/cs-logic.h index 3201075..ee1cea5 100644 --- a/src/framework/service/cs-logic.h +++ b/src/framework/service/cs-logic.h @@ -21,6 +21,7 @@ */ #pragma once +#include #include #include @@ -38,7 +39,8 @@ namespace Csr { class CsLogic : public Logic { public: - CsLogic(CsLoader &loader, Db::Manager &db); + CsLogic(const std::shared_ptr &loader, + const std::shared_ptr &db); virtual ~CsLogic() = default; RawBuffer scanData(const CsContext &context, const RawBuffer &data); @@ -67,8 +69,8 @@ private: RawBuffer handleAskUser(const CsContext &c, CsDetected &d, FilePtr &&fileptr = nullptr); - CsLoader &m_loader; - Db::Manager &m_db; + std::shared_ptr m_loader; + std::shared_ptr m_db; std::string m_dataVersion; }; diff --git a/src/framework/service/em-logic.cpp b/src/framework/service/em-logic.cpp index 5f6e77e..5561e11 100644 --- a/src/framework/service/em-logic.cpp +++ b/src/framework/service/em-logic.cpp @@ -60,9 +60,11 @@ bool _isValid(const csr_state_e &state) } // namespace anonymous -EmLogic::EmLogic(CsLoader &cs, WpLoader &wp, Db::Manager &db) : - m_cs(cs), m_wp(wp), m_db(db) +EmLogic::EmLogic(const std::shared_ptr &cs, const std::shared_ptr &wp, + const std::shared_ptr &db) : m_cs(cs), m_wp(wp), m_db(db) { + if (!this->m_db) + ThrowExc(DbFailed, "DB init failed"); } RawBuffer EmLogic::getEngineName(const EmContext &context) @@ -74,7 +76,7 @@ RawBuffer EmLogic::getEngineName(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_cs.getEngineName(c, value)); + toException(this->m_cs->getEngineName(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } else { @@ -82,7 +84,7 @@ RawBuffer EmLogic::getEngineName(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_wp.getEngineName(c, value)); + toException(this->m_wp->getEngineName(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } @@ -99,7 +101,7 @@ RawBuffer EmLogic::getEngineVendor(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_cs.getEngineVendor(c, value)); + toException(this->m_cs->getEngineVendor(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } else { @@ -107,7 +109,7 @@ RawBuffer EmLogic::getEngineVendor(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_wp.getEngineVendor(c, value)); + toException(this->m_wp->getEngineVendor(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } @@ -124,7 +126,7 @@ RawBuffer EmLogic::getEngineVersion(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_cs.getEngineVersion(c, value)); + toException(this->m_cs->getEngineVersion(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } else { @@ -132,7 +134,7 @@ RawBuffer EmLogic::getEngineVersion(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_wp.getEngineVersion(c, value)); + toException(this->m_wp->getEngineVersion(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } @@ -149,7 +151,7 @@ RawBuffer EmLogic::getEngineDataVersion(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_cs.getEngineDataVersion(c, value)); + toException(this->m_cs->getEngineDataVersion(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } else { @@ -157,7 +159,7 @@ RawBuffer EmLogic::getEngineDataVersion(const EmContext &context) auto &c = engineInfo.get(); std::string value; - toException(this->m_wp.getEngineDataVersion(c, value)); + toException(this->m_wp->getEngineDataVersion(c, value)); return BinaryQueue::Serialize(CSR_ERROR_NONE, value).pop(); } @@ -174,7 +176,7 @@ RawBuffer EmLogic::getEngineUpdatedTime(const EmContext &context) auto &c = engineInfo.get(); time_t value; - toException(this->m_cs.getEngineLatestUpdateTime(c, &value)); + toException(this->m_cs->getEngineLatestUpdateTime(c, &value)); int64_t ts64 = static_cast(value); @@ -184,7 +186,7 @@ RawBuffer EmLogic::getEngineUpdatedTime(const EmContext &context) auto &c = engineInfo.get(); time_t value; - toException(this->m_wp.getEngineLatestUpdateTime(c, &value)); + toException(this->m_wp->getEngineLatestUpdateTime(c, &value)); int64_t ts64 = static_cast(value); @@ -205,7 +207,7 @@ RawBuffer EmLogic::getEngineActivated(const EmContext &context) auto &c = engineInfo.get(); csre_cs_activated_e value; - toException(this->m_cs.getEngineActivated(c, &value)); + toException(this->m_cs->getEngineActivated(c, &value)); if (value == CSRE_CS_ACTIVATED) activated = CSR_ACTIVATED; @@ -219,7 +221,7 @@ RawBuffer EmLogic::getEngineActivated(const EmContext &context) auto &c = engineInfo.get(); csre_wp_activated_e value; - toException(this->m_wp.getEngineActivated(c, &value)); + toException(this->m_wp->getEngineActivated(c, &value)); if (value == CSRE_WP_ACTIVATED) activated = CSR_ACTIVATED; @@ -242,7 +244,7 @@ RawBuffer EmLogic::getEngineState(const EmContext &context) if (!_isValid(context.engineId)) ThrowExc(InternalError, "invalid engine id comes to get engine state."); - auto state = this->m_db.getEngineState(context.engineId); + auto state = this->m_db->getEngineState(context.engineId); return BinaryQueue::Serialize(CSR_ERROR_NONE, static_cast(state) == -1 ? static_cast(CSR_STATE_DISABLE) : @@ -258,7 +260,7 @@ RawBuffer EmLogic::setEngineState(const EmContext &context, csr_state_e state) if (!_isValid(context.engineId) || !_isValid(state)) ThrowExc(InternalError, "invalid argument comes to set engine state."); - this->m_db.setEngineState(context.engineId, state); + this->m_db->setEngineState(context.engineId, state); return BinaryQueue::Serialize(CSR_ERROR_NONE).pop(); diff --git a/src/framework/service/em-logic.h b/src/framework/service/em-logic.h index 97e44fb..4d34b3e 100644 --- a/src/framework/service/em-logic.h +++ b/src/framework/service/em-logic.h @@ -35,7 +35,8 @@ namespace Csr { class EmLogic : public Logic { public: - EmLogic(CsLoader &cs, WpLoader &wp, Db::Manager &db); + EmLogic(const std::shared_ptr &cs, const std::shared_ptr &wp, + const std::shared_ptr &db); virtual ~EmLogic() = default; RawBuffer getEngineName(const EmContext &context); @@ -48,9 +49,9 @@ public: RawBuffer setEngineState(const EmContext &context, csr_state_e state); private: - CsLoader &m_cs; - WpLoader &m_wp; - Db::Manager &m_db; + std::shared_ptr m_cs; + std::shared_ptr m_wp; + std::shared_ptr m_db; }; } diff --git a/src/framework/service/exception.h b/src/framework/service/exception.h index f2965f8..a116ba9 100644 --- a/src/framework/service/exception.h +++ b/src/framework/service/exception.h @@ -37,6 +37,7 @@ using PermDenied = DerivedException; using DbFailed = DerivedException; using RemoveFailed = DerivedException; using FileChanged = DerivedException; +using EngineNotExist = DerivedException; using EngineError = DerivedException; using EngineNotActivated = DerivedException; using EngineDisabled = DerivedException; diff --git a/src/framework/service/iloader.h b/src/framework/service/iloader.h new file mode 100644 index 0000000..d851bbd --- /dev/null +++ b/src/framework/service/iloader.h @@ -0,0 +1,43 @@ +/* + * 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 iloader.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief engine loader abstract class + */ +#pragma once + +namespace Csr { + +class ILoader { +public: + void reset(const std::string &enginePath, const std::string &roResDir, + const std::string &rwWorkingDir) + { + this->deinit(); + this->init(enginePath, roResDir, rwWorkingDir); + } + +protected: + virtual ~ILoader() = default; + + virtual void deinit() = 0; + virtual void init(const std::string &enginePath, const std::string &roResDir, + const std::string &rwWorkingDir) = 0; +}; + +} diff --git a/src/framework/service/server-service.cpp b/src/framework/service/server-service.cpp index e425e5e..b6ae206 100644 --- a/src/framework/service/server-service.cpp +++ b/src/framework/service/server-service.cpp @@ -84,14 +84,30 @@ inline CommandId extractCommandId(BinaryQueue &q) ServerService::ServerService() : Service(), - m_workqueue(2, 10), - m_cs(new CsLoader(CS_ENGINE_PATH, ENGINE_DIR, ENGINE_RW_WORKING_DIR)), - m_wp(new WpLoader(WP_ENGINE_PATH, ENGINE_DIR, ENGINE_RW_WORKING_DIR)), - m_db(new Db::Manager(RW_DBSPACE "/.csr.db", RO_DBSPACE)), - m_cslogic(*m_cs, *m_db), - m_wplogic(*m_wp, *m_db), - m_emlogic(*m_cs, *m_wp, *m_db) + m_workqueue(2, 10) { + this->m_db = std::make_shared(RW_DBSPACE "/.csr.db", RO_DBSPACE); + + try { + this->m_cs = std::make_shared(CS_ENGINE_PATH, ENGINE_DIR, + ENGINE_RW_WORKING_DIR); + } catch (const Exception &e) { + ERROR("Excetpion in content screening loader: " << e.what() << + " error: " << e.error() << " treat it as ENGINE_NOT_EXIST."); + } + + try { + this->m_wp = std::make_shared(WP_ENGINE_PATH, ENGINE_DIR, + ENGINE_RW_WORKING_DIR); + } catch (const Exception &e) { + ERROR("Exception in web protection loader: " << e.what() << + " error: " << e.error() << " treat it as ENGINE_NOT_EXIST."); + } + + this->m_cslogic.reset(new CsLogic(this->m_cs, this->m_db)); + this->m_wplogic.reset(new WpLogic(this->m_wp, this->m_db)); + this->m_emlogic.reset(new EmLogic(this->m_cs, this->m_wp, this->m_db)); + this->add(SockId::CS); this->add(SockId::WP); this->add(SockId::ADMIN); @@ -104,6 +120,11 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) { EXCEPTION_GUARD_START + // need not to try resetting engine because the engine is pre-loaded (RO) and it + // cannot be fixed in dynamically except platform-development time. + if (!this->m_cs) + ThrowExc(EngineNotExist, "Content screening engine is not exist!"); + BinaryQueue q; q.push(data); @@ -119,7 +140,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) RawBuffer data; q.Deserialize(cptr, data); - return m_cslogic.scanData(*cptr, data); + return this->m_cslogic->scanData(*cptr, data); } case CommandId::SCAN_FILE: { @@ -129,7 +150,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) std::string filepath; q.Deserialize(cptr, filepath); - return m_cslogic.scanFile(*cptr, filepath); + return this->m_cslogic->scanFile(*cptr, filepath); } case CommandId::GET_SCANNABLE_FILES: { @@ -138,7 +159,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) std::string dir; q.Deserialize(dir); - return m_cslogic.getScannableFiles(dir); + return this->m_cslogic->getScannableFiles(dir); } case CommandId::CANONICALIZE_PATHS: { @@ -147,7 +168,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) StrSet paths; q.Deserialize(paths); - return m_cslogic.canonicalizePaths(paths); + return this->m_cslogic->canonicalizePaths(paths); } case CommandId::SET_DIR_TIMESTAMP: { @@ -157,7 +178,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) int64_t ts64 = 0; q.Deserialize(dir, ts64); - return m_cslogic.setDirTimestamp(dir, static_cast(ts64)); + return this->m_cslogic->setDirTimestamp(dir, static_cast(ts64)); } case CommandId::JUDGE_STATUS: { @@ -168,7 +189,8 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) int intAction; q.Deserialize(filepath, intAction); - return m_cslogic.judgeStatus(filepath, static_cast(intAction)); + return this->m_cslogic->judgeStatus(filepath, + static_cast(intAction)); } case CommandId::GET_DETECTED: { @@ -177,7 +199,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) std::string filepath; q.Deserialize(filepath); - return m_cslogic.getDetected(filepath); + return this->m_cslogic->getDetected(filepath); } case CommandId::GET_DETECTED_LIST: { @@ -186,7 +208,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) StrSet dirSet; q.Deserialize(dirSet); - return m_cslogic.getDetectedList(dirSet); + return this->m_cslogic->getDetectedList(dirSet); } case CommandId::GET_IGNORED: { @@ -195,7 +217,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) std::string filepath; q.Deserialize(filepath); - return m_cslogic.getIgnored(filepath); + return this->m_cslogic->getIgnored(filepath); } case CommandId::GET_IGNORED_LIST: { @@ -204,7 +226,7 @@ RawBuffer ServerService::processCs(const ConnShPtr &conn, RawBuffer &data) StrSet dirSet; q.Deserialize(dirSet); - return m_cslogic.getIgnoredList(dirSet); + return this->m_cslogic->getIgnoredList(dirSet); } default: @@ -218,6 +240,9 @@ RawBuffer ServerService::processWp(const ConnShPtr &conn, RawBuffer &data) { EXCEPTION_GUARD_START + if (!this->m_wp) + ThrowExc(EngineNotExist, "Web protection engine is not exist!"); + hasPermission(conn); BinaryQueue q; @@ -233,7 +258,7 @@ RawBuffer ServerService::processWp(const ConnShPtr &conn, RawBuffer &data) std::string url; q.Deserialize(cptr, url); - return m_wplogic.checkUrl(*cptr, url); + return this->m_wplogic->checkUrl(*cptr, url); } default: @@ -247,71 +272,68 @@ RawBuffer ServerService::processAdmin(const ConnShPtr &conn, RawBuffer &data) { EXCEPTION_GUARD_START - hasPermission(conn); - BinaryQueue q; q.push(data); auto cid = extractCommandId(q); + EmContextShPtr cptr; + q.Deserialize(cptr); + + if (!cptr) + ThrowExc(SocketError, "engine context for processAdmin should be exist!"); + + switch (cptr->engineId) { + case CSR_ENGINE_CS: + if (!this->m_cs) + ThrowExc(EngineNotExist, "Content screening engine is not exist!"); + break; + case CSR_ENGINE_WP: + if (!this->m_wp) + ThrowExc(EngineNotExist, "Web protection engine is not exist!"); + break; + default: + throw std::invalid_argument("context engine Id is invalid for processAdmin!"); + } + + hasPermission(conn); + INFO("Admin request process. command id: " << cidToString(cid)); switch (cid) { case CommandId::EM_GET_NAME: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineName(*cptr); + return this->m_emlogic->getEngineName(*cptr); } case CommandId::EM_GET_VENDOR: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineVendor(*cptr); + return this->m_emlogic->getEngineVendor(*cptr); } case CommandId::EM_GET_VERSION: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineVersion(*cptr); + return this->m_emlogic->getEngineVersion(*cptr); } case CommandId::EM_GET_DATA_VERSION: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineDataVersion(*cptr); + return this->m_emlogic->getEngineDataVersion(*cptr); } case CommandId::EM_GET_UPDATED_TIME: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineUpdatedTime(*cptr); + return this->m_emlogic->getEngineUpdatedTime(*cptr); } case CommandId::EM_GET_ACTIVATED: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineActivated(*cptr); + return this->m_emlogic->getEngineActivated(*cptr); } case CommandId::EM_GET_STATE: { - EmContextShPtr cptr; - q.Deserialize(cptr); - - return m_emlogic.getEngineState(*cptr); + return this->m_emlogic->getEngineState(*cptr); } case CommandId::EM_SET_STATE: { - EmContextShPtr cptr; int intState; - q.Deserialize(cptr, intState); + q.Deserialize(intState); - return m_emlogic.setEngineState(*cptr, static_cast(intState)); + return this->m_emlogic->setEngineState(*cptr, static_cast(intState)); } default: @@ -354,7 +376,7 @@ void ServerService::onMessageProcess(const ConnShPtr &connection) auto inbufPtr = std::make_shared(connection->receive()); - m_workqueue.submit([this, &connection, process, inbufPtr]() { + this->m_workqueue.submit([this, &connection, process, inbufPtr]() { auto outbuf = (*process)(connection, *inbufPtr); connection->send(outbuf); diff --git a/src/framework/service/server-service.h b/src/framework/service/server-service.h index 4d208a8..23679ae 100644 --- a/src/framework/service/server-service.h +++ b/src/framework/service/server-service.h @@ -49,13 +49,13 @@ private: ThreadPool m_workqueue; - std::unique_ptr m_cs; - std::unique_ptr m_wp; - std::unique_ptr m_db; + std::shared_ptr m_cs; + std::shared_ptr m_wp; + std::shared_ptr m_db; - CsLogic m_cslogic; - WpLogic m_wplogic; - EmLogic m_emlogic; + std::unique_ptr m_cslogic; + std::unique_ptr m_wplogic; + std::unique_ptr m_emlogic; }; diff --git a/src/framework/service/wp-loader.cpp b/src/framework/service/wp-loader.cpp index 2d1228d..a0eac40 100644 --- a/src/framework/service/wp-loader.cpp +++ b/src/framework/service/wp-loader.cpp @@ -194,6 +194,8 @@ void WpLoader::init(const std::string &enginePath, const std::string &roResDir, if (enginePath.empty() || roResDir.empty() || rwWorkingDir.empty()) ThrowExc(InternalError, "empty string comes in to loader init"); + INFO("Load WP-Engine plugin start. engine path: " << enginePath); + void *handle = dlopen(enginePath.c_str(), RTLD_LAZY); if (handle == nullptr) @@ -223,7 +225,7 @@ void WpLoader::init(const std::string &enginePath, const std::string &roResDir, this->m_pc.fpDestroyEngine = reinterpret_cast(dlsym(handle, "csre_wp_engine_destroy")); this->m_pc.fpGetEngineApiVersion = reinterpret_cast(dlsym( - handle, "csre_wp_engine_get_api_version")); + handle, "csre_wp_engine_get_api_version")); this->m_pc.fpGetEngineVendor = reinterpret_cast(dlsym(handle, "csre_wp_engine_get_vendor")); this->m_pc.fpGetEngineName = reinterpret_cast(dlsym(handle, @@ -231,25 +233,31 @@ void WpLoader::init(const std::string &enginePath, const std::string &roResDir, this->m_pc.fpGetEngineVersion = reinterpret_cast(dlsym(handle, "csre_wp_engine_get_version")); this->m_pc.fpGetEngineDataVersion = reinterpret_cast(dlsym( - handle, "csre_wp_engine_get_data_version")); + handle, "csre_wp_engine_get_data_version")); this->m_pc.fpGetEngineLatestUpdateTime = reinterpret_cast(dlsym(handle, "csre_wp_engine_get_latest_update_time")); - this->m_pc.fpGetEngineActivated = reinterpret_cast(dlsym(handle, - "csre_wp_engine_get_activated")); + this->m_pc.fpGetEngineActivated = reinterpret_cast(dlsym( + handle, "csre_wp_engine_get_activated")); this->m_pc.fpGetEngineVendorLogo = reinterpret_cast(dlsym( - handle, "csre_wp_engine_get_vendor_logo")); + handle, "csre_wp_engine_get_vendor_logo")); if (this->m_pc.fpGlobalInit == nullptr || this->m_pc.fpGlobalDeinit == nullptr || - this->m_pc.fpContextCreate == nullptr || this->m_pc.fpContextDestroy == nullptr || + this->m_pc.fpContextCreate == nullptr || + this->m_pc.fpContextDestroy == nullptr || this->m_pc.fpCheckUrl == nullptr || this->m_pc.fpGetRiskLevel == nullptr || - this->m_pc.fpGetDetailedUrl == nullptr || this->m_pc.fpGetErrorString == nullptr || - this->m_pc.fpGetEngineInfo == nullptr || this->m_pc.fpDestroyEngine == nullptr || - this->m_pc.fpGetEngineApiVersion == nullptr || this->m_pc.fpGetEngineVendor == nullptr || - this->m_pc.fpGetEngineName == nullptr || this->m_pc.fpGetEngineVersion == nullptr || + this->m_pc.fpGetDetailedUrl == nullptr || + this->m_pc.fpGetErrorString == nullptr || + this->m_pc.fpGetEngineInfo == nullptr || + this->m_pc.fpDestroyEngine == nullptr || + this->m_pc.fpGetEngineApiVersion == nullptr || + this->m_pc.fpGetEngineVendor == nullptr || + this->m_pc.fpGetEngineName == nullptr || + this->m_pc.fpGetEngineVersion == nullptr || this->m_pc.fpGetEngineDataVersion == nullptr || this->m_pc.fpGetEngineLatestUpdateTime == nullptr || - this->m_pc.fpGetEngineActivated == nullptr || this->m_pc.fpGetEngineVendorLogo == nullptr) { + this->m_pc.fpGetEngineActivated == nullptr || + this->m_pc.fpGetEngineVendorLogo == nullptr) { dlclose(this->m_pc.dlhandle); this->m_pc.dlhandle = nullptr; ThrowExc(EngineError, "Failed to load funcs from engine library. " @@ -265,13 +273,7 @@ void WpLoader::init(const std::string &enginePath, const std::string &roResDir, } } -WpLoader::WpLoader(const std::string &enginePath, const std::string &roResDir, - const std::string &rwWorkingDir) -{ - this->init(enginePath, roResDir, rwWorkingDir); -} - -WpLoader::~WpLoader() +void WpLoader::deinit() { // ignore return value this->m_pc.fpGlobalDeinit(); @@ -282,15 +284,30 @@ WpLoader::~WpLoader() } } -WpEngineContext::WpEngineContext(WpLoader &loader) : +WpLoader::WpLoader(const std::string &enginePath, const std::string &roResDir, + const std::string &rwWorkingDir) +{ + this->init(enginePath, roResDir, rwWorkingDir); +} + +WpLoader::~WpLoader() +{ + this->deinit(); +} + + +WpEngineContext::WpEngineContext(const std::shared_ptr &loader) : m_loader(loader), m_context(nullptr) { - toException(this->m_loader.contextCreate(this->m_context)); + if (!this->m_loader) + ThrowExc(EngineNotExist, "null loader means engine not exist!"); + + toException(this->m_loader->contextCreate(this->m_context)); } WpEngineContext::~WpEngineContext() { - toException(this->m_loader.contextDestroy(this->m_context)); + toException(this->m_loader->contextDestroy(this->m_context)); } csre_wp_context_h &WpEngineContext::get(void) @@ -298,15 +315,19 @@ csre_wp_context_h &WpEngineContext::get(void) return this->m_context; } -WpEngineInfo::WpEngineInfo(WpLoader &loader) : + +WpEngineInfo::WpEngineInfo(const std::shared_ptr &loader) : m_loader(loader), m_info(nullptr) { - toException(this->m_loader.getEngineInfo(this->m_info)); + if (!this->m_loader) + ThrowExc(EngineNotExist, "null loader means engine not exist!"); + + toException(this->m_loader->getEngineInfo(this->m_info)); } WpEngineInfo::~WpEngineInfo() { - toException(this->m_loader.destroyEngine(this->m_info)); + toException(this->m_loader->destroyEngine(this->m_info)); } csre_wp_engine_h &WpEngineInfo::get(void) diff --git a/src/framework/service/wp-loader.h b/src/framework/service/wp-loader.h index a868a88..c722214 100644 --- a/src/framework/service/wp-loader.h +++ b/src/framework/service/wp-loader.h @@ -21,24 +21,24 @@ */ #pragma once -#include +#include #include #include +#include #include #include +#include "service/iloader.h" + namespace Csr { -class WpLoader { +class WpLoader : public ILoader { public: WpLoader(const std::string &enginePath, const std::string &roResDir, const std::string &rwWorkingDir); virtual ~WpLoader(); - void reset(const std::string &enginePath, const std::string &roResDir, - const std::string &rwWorkingDir); - int contextCreate(csre_wp_context_h &); int contextDestroy(csre_wp_context_h); int checkUrl(csre_wp_context_h handle, const std::string &, @@ -102,30 +102,31 @@ private: FpGetEngineVendorLogo fpGetEngineVendorLogo; }; - void init(const std::string &, const std::string &, const std::string &); + virtual void init(const std::string &, const std::string &, const std::string &) override; + virtual void deinit(void) override; PluginContext m_pc; }; class WpEngineContext { public: - WpEngineContext(WpLoader &); + WpEngineContext(const std::shared_ptr &); ~WpEngineContext(); csre_wp_context_h &get(void); private: - WpLoader &m_loader; + std::shared_ptr m_loader; csre_wp_context_h m_context; }; class WpEngineInfo { public: - WpEngineInfo(WpLoader &); + WpEngineInfo(const std::shared_ptr &); ~WpEngineInfo(); csre_wp_engine_h &get(void); private: - WpLoader &m_loader; + std::shared_ptr m_loader; csre_wp_engine_h m_info; }; diff --git a/src/framework/service/wp-logic.cpp b/src/framework/service/wp-logic.cpp index c4b707f..f94b093 100644 --- a/src/framework/service/wp-logic.cpp +++ b/src/framework/service/wp-logic.cpp @@ -32,25 +32,32 @@ namespace Csr { -WpLogic::WpLogic(WpLoader &loader, Db::Manager &db) : m_loader(loader), m_db(db) +WpLogic::WpLogic(const std::shared_ptr &loader, + const std::shared_ptr &db) : + m_loader(loader), m_db(db) { - WpEngineInfo wpEngineInfo(this->m_loader); - toException(this->m_loader.getEngineDataVersion(wpEngineInfo.get(), - this->m_dataVersion)); + if (!this->m_db) + ThrowExc(DbFailed, "DB init failed."); + + if (this->m_loader) { + WpEngineInfo wpEngineInfo(this->m_loader); + toException(this->m_loader->getEngineDataVersion(wpEngineInfo.get(), + this->m_dataVersion)); + } } RawBuffer WpLogic::checkUrl(const WpContext &context, const std::string &url) { EXCEPTION_GUARD_START - if (this->m_db.getEngineState(CSR_ENGINE_WP) != CSR_STATE_ENABLE) + if (this->m_db->getEngineState(CSR_ENGINE_WP) != CSR_STATE_ENABLE) ThrowExc(EngineDisabled, "engine is disabled"); WpEngineContext engineContext(this->m_loader); auto &c = engineContext.get(); csre_wp_check_result_h result; - toException(this->m_loader.checkUrl(c, url.c_str(), &result)); + toException(this->m_loader->checkUrl(c, url.c_str(), &result)); auto wr = convert(result); @@ -112,8 +119,8 @@ WpResult WpLogic::convert(csre_wp_check_result_h &r) WpResult wr; csre_wp_risk_level_e elevel; - toException(this->m_loader.getDetailedUrl(r, wr.detailedUrl)); - toException(this->m_loader.getRiskLevel(r, &elevel)); + toException(this->m_loader->getDetailedUrl(r, wr.detailedUrl)); + toException(this->m_loader->getRiskLevel(r, &elevel)); wr.riskLevel = Csr::convert(elevel); return wr; diff --git a/src/framework/service/wp-logic.h b/src/framework/service/wp-logic.h index 4aaf385..0c51408 100644 --- a/src/framework/service/wp-logic.h +++ b/src/framework/service/wp-logic.h @@ -21,6 +21,7 @@ */ #pragma once +#include #include #include "common/types.h" @@ -34,7 +35,8 @@ namespace Csr { class WpLogic : public Logic { public: - WpLogic(WpLoader &loader, Db::Manager &db); + WpLogic(const std::shared_ptr &loader, + const std::shared_ptr &db); virtual ~WpLogic() = default; RawBuffer checkUrl(const WpContext &context, const std::string &url); @@ -46,8 +48,8 @@ private: const std::string &url, const WpResult &result); - WpLoader &m_loader; - Db::Manager &m_db; + std::shared_ptr m_loader; + std::shared_ptr m_db; std::string m_dataVersion; }; diff --git a/test/test-main.cpp b/test/test-main.cpp index d7da009..9623b46 100644 --- a/test/test-main.cpp +++ b/test/test-main.cpp @@ -19,6 +19,9 @@ * @version 1.0 */ #define BOOST_TEST_MODULE CSR_API_TEST + +#include + #include #include #include @@ -32,13 +35,21 @@ csr_state_e setEngineState(csr_engine_id_e id, csr_state_e state) { csr_engine_h handle; auto ret = csr_get_current_engine(id, &handle); - if (ret != CSR_ERROR_NONE) + if (ret == CSR_ERROR_ENGINE_NOT_EXIST) { + std::cerr << "Engine not exist! engine id: " << static_cast(id) << std::endl; + return CSR_STATE_DISABLE; + } else if (ret != CSR_ERROR_NONE) { throw std::logic_error("Failed to csr_get_current_engine."); + } csr_state_e current; ret = csr_engine_get_state(handle, ¤t); - if (ret != CSR_ERROR_NONE) + if (ret == CSR_ERROR_ENGINE_NOT_EXIST) { + std::cerr << "Engine not exist! engine id: " << static_cast(id) << std::endl; + return CSR_STATE_DISABLE; + } else if (ret != CSR_ERROR_NONE) { throw std::logic_error("Failed to csr_get_state."); + } if (current == state) return current; -- 2.7.4