if (context == nullptr)
return CSRE_ERROR_INVALID_HANDLE;
- if (data.empty())
- return CSRE_ERROR_INVALID_PARAMETER;
-
if (g_virus_sig.empty())
return CSRE_ERROR_ENGINE_NOT_ACTIVATED;
AsyncLogic::Ending AsyncLogic::scanDir(const std::string &dir)
{
- // For in case of there's already detected malware for dir
- StrSet dirset;
- dirset.insert(dir);
-
- auto retResults =
- m_dispatcher->methodCall<std::pair<int, std::vector<CsDetected *>>>(
- CommandId::GET_DETECTED_LIST, dirset);
-
- if (retResults.first != CSR_ERROR_NONE) {
- ERROR("[Error] ret: " << retResults.first);
-
- for (auto r : retResults.second)
- delete r;
-
- auto ec = retResults.first;
- return std::make_pair(Callback::Id::OnError, [this, ec] {
- if (this->m_cb.onError)
- this->m_cb.onError(this->m_userdata, ec);
- });
- }
-
- // Register already detected malwares to context to be freed with context.
- for (auto r : retResults.second) {
- m_results.emplace_back(r);
-
- if (m_cb.onDetected)
- m_cb.onDetected(m_userdata, reinterpret_cast<csr_cs_detected_h>(r));
- }
-
- // Already scanned files are excluded according to history
+ // Already scanned files are included in history. it'll be skipped later
+ // on server side by every single scan_file request.
auto retFiles = m_dispatcher->methodCall<std::pair<int, StrSet *>>(
- CommandId::DIR_GET_FILES, m_ctx, dir);
+ CommandId::GET_SCANNABLE_FILES, dir);
if (retFiles.first != CSR_ERROR_NONE) {
ERROR("[Error] ret: " << retFiles.first);
CommandId::SCAN_FILE, m_ctx, file);
if (ret.first != CSR_ERROR_NONE) {
- ERROR("[Error] ret: " << ret.first);
+ ERROR("[Error] ret: " << ret.first << " while scan file: " << file);
delete ret.second;
auto ec = ret.first;
return std::make_pair(Callback::Id::OnError, [this, ec] {
GET_DETECTED_LIST = 0x1102,
GET_IGNORED = 0x1103,
GET_IGNORED_LIST = 0x1104,
- DIR_GET_FILES = 0x1105,
+ GET_SCANNABLE_FILES = 0x1105,
// handle result
JUDGE_STATUS = 0x1201,
bool hasValue(void) const noexcept;
- std::string targetName; // file path or app id which contains malware
+ std::string targetName; // file(app) path which contains malware
std::string malwareName;
std::string detailedUrl;
namespace Csr {
-namespace {
-
-// temporal function for debugging until modules integrated to logic.
-void printCsContext(const CsContext &context)
-{
- std::string popupMessage;
- int askUser;
- int coreUsage;
- bool scanOnCloud;
-
- context.get(static_cast<int>(CsContext::Key::PopupMessage), popupMessage);
- context.get(static_cast<int>(CsContext::Key::AskUser), askUser);
- context.get(static_cast<int>(CsContext::Key::CoreUsage), coreUsage);
- context.get(static_cast<int>(CsContext::Key::ScanOnCloud), scanOnCloud);
-
- INFO("Context info:"
- " PopupMessage: " << popupMessage <<
- " AskUser: " << askUser <<
- " CoreUsage: " << coreUsage <<
- " ScanOnCloud: " << scanOnCloud);
-}
-
-}
-
Logic::Logic() :
m_cs(new CsLoader(CS_ENGINE_PATH)),
m_wp(new WpLoader(WP_ENGINE_PATH)),
return scanFile(*cptr, filepath);
}
- case CommandId::DIR_GET_FILES: {
- CsContextShPtr cptr;
+ case CommandId::GET_SCANNABLE_FILES: {
std::string dir;
- info.second.Deserialize(cptr, dir);
- return dirGetFiles(*cptr, dir);
+ info.second.Deserialize(dir);
+ return getScannableFiles(dir);
}
case CommandId::JUDGE_STATUS: {
RawBuffer Logic::scanFile(const CsContext &context, const std::string &filepath)
{
+ DEBUG("Scan request on file: " << filepath);
auto history = m_db->getDetectedMalware(filepath);
if (!history)
return scanFileHelper(context, filepath);
- // history exist of malware detected for the file.
- // let's check file modified since the detected time.
- auto file = File::create(filepath, static_cast<time_t>(history->ts));
-
- // file is modified since the detected time. let's remove history!
- if (!file) {
+ DEBUG("Scan history exist on file: " << filepath);
+ if (File::create(filepath, static_cast<time_t>(history->ts))) {
+ DEBUG("file[" << filepath << "] is modified since the detected time. "
+ "let's remove history and re-scan");
m_db->deleteDetectedMalware(filepath);
return scanFileHelper(context, filepath);
}
- // file isn't modified since the detected time. history can be used.
- if (!context.askUser)
+ DEBUG("file[" << filepath << "] isn't modified since the detected time. "
+ "history can be used.");
+ if (!context.askUser) {
return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop();
-
- if (history->isIgnored) {
+ } else if (history->isIgnored) {
history->response = CSR_CS_IGNORE;
- } else {
- switch (history->response = getUserResponse(context, *history)) {
- case CSR_CS_IGNORE:
- m_db->setDetectedMalwareIgnored(filepath, true);
- break;
-
- case CSR_CS_REMOVE:
- if (!file->remove()) {
- ERROR("Failed to remove filepath: " << filepath);
- return BinaryQueue::Serialize(CSR_ERROR_REMOVE_FAILED, CsDetected()).pop();
- }
-
- m_db->deleteDetectedMalware(filepath);
- break;
-
- case CSR_CS_SKIP:
- break;
-
- default:
- ThrowExc(InternalError, "Invalid response from popup: " <<
- static_cast<int>(history->response));
+ return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop();
+ }
+
+ DEBUG("user response is needed.");
+
+ switch (history->response = getUserResponse(context, *history)) {
+ case CSR_CS_IGNORE:
+ m_db->setDetectedMalwareIgnored(filepath, true);
+ break;
+
+ case CSR_CS_REMOVE: {
+ auto file = File::create(filepath);
+ if (!file && !file->remove()) {
+ ERROR("Failed to remove filepath: " << filepath);
+ return BinaryQueue::Serialize(CSR_ERROR_REMOVE_FAILED, CsDetected()).pop();
}
+
+ m_db->deleteDetectedMalware(filepath);
+ break;
+ }
+
+ case CSR_CS_SKIP:
+ break;
+
+ default:
+ ThrowExc(InternalError, "Invalid response from popup: " <<
+ static_cast<int>(history->response));
}
+ DEBUG("file[" << filepath << "] user response: " << static_cast<int>(history->response));
+
return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop();
}
-RawBuffer Logic::dirGetFiles(const CsContext &context, const std::string &dir)
+RawBuffer Logic::getScannableFiles(const std::string &dir)
{
- INFO("Dir[" << dir << "] get files");
+ auto lastScanTime = m_db->getLastScanTime(dir, m_csDataVersion);
+ auto visitor = (lastScanTime == -1) ?
+ FsVisitor::create(dir) : FsVisitor::create(dir, lastScanTime);
+
+ StrSet fileset;
+ while (auto file = visitor->next()) {
+ DEBUG("In dir[" << dir << "], Scannable file[" << file->getPath() << "]");
+ fileset.insert(file->getPath());
+ }
- printCsContext(context);
+ if (lastScanTime != -1) {
+ // for case: scan history exist and not modified.
+ for (auto &row : m_db->getDetectedMalwares(dir))
+ fileset.insert(row->targetName);
+ }
- return BinaryQueue::Serialize(CSR_ERROR_NONE, StrSet()).pop();
+ return BinaryQueue::Serialize(CSR_ERROR_NONE, fileset).pop();
}
RawBuffer Logic::judgeStatus(const std::string &filepath,
return BinaryQueue::Serialize(CSR_ERROR_INVALID_PARAMETER).pop();
}
- auto file = File::create(filepath, static_cast<time_t>(history->ts));
-
- if (!file) {
- ERROR("Target doesn't exist on target path on filesystem or "
- "modified since db delta inserted. name: " << filepath);
+ if (File::create(filepath, static_cast<time_t>(history->ts))) {
+ ERROR("Target modified since db delta inserted. name: " << filepath);
m_db->deleteDetectedMalware(filepath);
// TODO: is it okay to just refresh db and return success?
return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
}
switch (action) {
- case CSR_CS_ACTION_REMOVE:
- if (!file->remove()) {
+ case CSR_CS_ACTION_REMOVE: {
+ auto file = File::create(filepath);
+ if (!file && !file->remove()) {
ERROR("Failed to remove filepath: " << filepath);
return BinaryQueue::Serialize(CSR_ERROR_REMOVE_FAILED).pop();
}
m_db->deleteDetectedMalware(filepath);
break;
+ }
case CSR_CS_ACTION_IGNORE:
m_db->setDetectedMalwareIgnored(filepath, true);
RawBuffer scanData(const CsContext &context, const RawBuffer &data);
RawBuffer scanFile(const CsContext &context, const std::string &filepath);
RawBuffer scanFileHelper(const CsContext &context, const std::string &filepath);
- RawBuffer dirGetFiles(const CsContext &context, const std::string &dir);
+ RawBuffer getScannableFiles(const std::string &dir);
RawBuffer judgeStatus(const std::string &filepath, csr_cs_action_e action);
RawBuffer getDetected(const std::string &filepath);
RawBuffer getDetectedList(const StrSet &dirSet);
ctx->scannedCnt++;
}
-void on_error(void *userdata, int ec)
-{
- BOOST_MESSAGE("on_error. async request done with error code[" << ec << "]");
- auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
- ctx->errorCnt++;
-}
-
void on_detected(void *userdata, csr_cs_detected_h detected)
{
(void) detected;
ctx->detectedCnt++;
}
+void on_error(void *userdata, int ec)
+{
+ BOOST_MESSAGE("on_error. async request done with error code[" << ec << "]");
+ auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
+ ctx->errorCnt++;
+ ctx->cv.notify_one();
+}
+
void on_completed(void *userdata)
{
BOOST_MESSAGE("on_completed. async request completed succesfully.");
BOOST_MESSAGE("on_cancelled. async request canceled!");
auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
ctx->cancelledCnt++;
+ ctx->cv.notify_one();
}
}
AsyncTestContext testCtx;
- ASSERT_IF(csr_cs_scan_dir_async(context, TEST_DIR, &testCtx), CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_dir_async(context, TEST_DIR "/test_dir", &testCtx), CSR_ERROR_NONE);
std::unique_lock<std::mutex> l(testCtx.m);
testCtx.cv.wait(l);
l.unlock();
ASSERT_IF(testCtx.completedCnt, 1);
- ASSERT_IF(testCtx.scannedCnt, 0); // should be 1 after dir_get_files implemented
- ASSERT_IF(testCtx.detectedCnt, 2);
+ ASSERT_IF(testCtx.scannedCnt + testCtx.detectedCnt, 8);
ASSERT_IF(testCtx.cancelledCnt, 0);
ASSERT_IF(testCtx.errorCnt, 0);
AsyncTestContext testCtx;
const char *dirs[1] = {
- TEST_DIR
+ TEST_DIR "/test_dir"
};
ASSERT_IF(
l.unlock();
ASSERT_IF(testCtx.completedCnt, 1);
- ASSERT_IF(testCtx.scannedCnt, 0); // should be 1 after dir_get_files implemented
- ASSERT_IF(testCtx.detectedCnt, 2);
+ ASSERT_IF(testCtx.scannedCnt + testCtx.detectedCnt, 8);
ASSERT_IF(testCtx.cancelledCnt, 0);
ASSERT_IF(testCtx.errorCnt, 0);
ASSERT_IF(csr_cs_set_ask_user(context, CSR_CS_NOT_ASK_USER), CSR_ERROR_NONE);
ASSERT_IF(csr_cs_set_ask_user(context, CSR_CS_ASK_USER), CSR_ERROR_NONE);
- ASSERT_IF(csr_cs_set_popup_message(context, "Test popup message"),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_set_popup_message(context, "Test popup message"), CSR_ERROR_NONE);
- ASSERT_IF(csr_cs_set_core_usage(context, CSR_CS_USE_CORE_DEFAULT),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_set_core_usage(context, CSR_CS_USE_CORE_DEFAULT), CSR_ERROR_NONE);
ASSERT_IF(csr_cs_set_core_usage(context, CSR_CS_USE_CORE_ALL), CSR_ERROR_NONE);
ASSERT_IF(csr_cs_set_core_usage(context, CSR_CS_USE_CORE_HALF), CSR_ERROR_NONE);
- ASSERT_IF(csr_cs_set_core_usage(context, CSR_CS_USE_CORE_SINGLE),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_set_core_usage(context, CSR_CS_USE_CORE_SINGLE), CSR_ERROR_NONE);
ASSERT_IF(csr_cs_set_scan_on_cloud(context), CSR_ERROR_NONE);
ASSERT_IF(csr_cs_set_ask_user(context, static_cast<csr_cs_ask_user_e>(0x926ce)),
CSR_ERROR_INVALID_PARAMETER);
- ASSERT_IF(csr_cs_set_popup_message(context, nullptr),
- CSR_ERROR_INVALID_PARAMETER);
+ ASSERT_IF(csr_cs_set_popup_message(context, nullptr), CSR_ERROR_INVALID_PARAMETER);
ASSERT_IF(csr_cs_set_popup_message(context, ""), CSR_ERROR_INVALID_PARAMETER);
ASSERT_IF(csr_cs_set_core_usage(context,
csr_cs_detected_h detected;
unsigned char data[100] = {0, };
- ASSERT_IF(csr_cs_scan_data(context, data, sizeof(data), &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_data(context, data, sizeof(data), &detected), CSR_ERROR_NONE);
// no malware detected
CHECK_IS_NULL(detected);
auto context = c.get();
csr_cs_detected_h detected;
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_NORMAL, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_NORMAL, &detected), CSR_ERROR_NONE);
// no malware detected
CHECK_IS_NULL(detected);
auto context = c.get();
csr_cs_detected_h detected;
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
auto context = c.get();
csr_cs_detected_h detected;
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
auto context = c.get();
csr_cs_detected_h detected;
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
ASSERT_IF(csr_cs_get_detected_malware(context, TEST_FILE_RISKY, &detected),
TEST_DIR
};
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
ASSERT_IF(csr_cs_get_detected_malwares(context, dirs,
sizeof(dirs) / sizeof(const char *),
&detected_list, &cnt), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected_list);
- ASSERT_IF(cnt, static_cast<size_t>(2));
+
+ BOOST_REQUIRE_MESSAGE(cnt >= 2, "Detected malware count is invalid. "
+ "expected: >= 2, cnt: " << cnt);
EXCEPTION_GUARD_END
}
auto context = c.get();
csr_cs_detected_h detected;
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
- ASSERT_IF(csr_cs_judge_detected_malware(context, detected,
- CSR_CS_ACTION_IGNORE), CSR_ERROR_NONE);
+
+ ASSERT_IF(csr_cs_judge_detected_malware(context, detected, CSR_CS_ACTION_IGNORE),
+ CSR_ERROR_NONE);
ASSERT_IF(csr_cs_get_ignored_malware(context, TEST_FILE_MALWARE, &detected),
CSR_ERROR_NONE);
ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected),
CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
- ASSERT_IF(csr_cs_judge_detected_malware(context, detected,
- CSR_CS_ACTION_IGNORE), CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_judge_detected_malware(context, detected, CSR_CS_ACTION_IGNORE),
+ CSR_ERROR_NONE);
ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_RISKY, &detected),
CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
- ASSERT_IF(csr_cs_judge_detected_malware(context, detected,
- CSR_CS_ACTION_IGNORE), CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_judge_detected_malware(context, detected, CSR_CS_ACTION_IGNORE),
+ CSR_ERROR_NONE);
ASSERT_IF(csr_cs_get_ignored_malwares(context, dirs,
sizeof(dirs) / sizeof(const char *),
auto context = c.get();
csr_cs_detected_h detected;
- ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected),
- CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_scan_file(context, TEST_FILE_MALWARE, &detected), CSR_ERROR_NONE);
CHECK_IS_NOT_NULL(detected);
- ASSERT_IF(csr_cs_judge_detected_malware(context, detected,
- CSR_CS_ACTION_UNIGNORE), CSR_ERROR_NONE);
+ ASSERT_IF(csr_cs_judge_detected_malware(context, detected, CSR_CS_ACTION_UNIGNORE),
+ CSR_ERROR_NONE);
EXCEPTION_GUARD_END
}