-CREATE TABLE IF NOT EXISTS SCHEMA_INFO(name TEXT PRIMARY KEY NOT NULL,
- value TEXT);
+CREATE TABLE IF NOT EXISTS SCHEMA_INFO(
+ name TEXT PRIMARY KEY NOT NULL,
+ value TEXT
+);
-CREATE TABLE IF NOT EXISTS ENGINE_STATE(id INTEGER PRIMARY KEY,
- state INTEGER NOT NULL);
+CREATE TABLE IF NOT EXISTS ENGINE_STATE(
+ id INTEGER PRIMARY KEY,
+ state INTEGER NOT NULL
+);
-CREATE TABLE IF NOT EXISTS SCAN_REQUEST(dir TEXT PRIMARY KEY,
- last_scan INTEGER NOT NULL,
- data_version TEXT NOT NULL);
+CREATE TABLE IF NOT EXISTS SCAN_REQUEST(
+ dir TEXT PRIMARY KEY,
+ last_scan INTEGER NOT NULL,
+ data_version TEXT NOT NULL
+);
-CREATE TABLE IF NOT EXISTS DETECTED_MALWARE_FILE(path TEXT PRIMARY KEY NOT NULL,
- data_version TEXT NOT NULL,
- severity INTEGER NOT NULL,
- malware_name TEXT NOT NULL,
- detailed_url TEXT NOT NULL,
- detected_time INTEGER NOT NULL,
- ignored INTEGER NOT NULL);
+CREATE TABLE IF NOT EXISTS NAMES(
+ name TEXT NOT NULL,
+ is_ignored INTEGER NOT NULL DEFAULT 0,
+ PRIMARY KEY(name)
+);
+
+CREATE TABLE IF NOT EXISTS DETECTED_MALWARE(
+ file_path TEXT NOT NULL,
+ name 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,
+
+ PRIMARY KEY(file_path),
+ FOREIGN KEY(name) REFERENCES NAMES(name) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS PACKAGE_INFO(
+ pkg_id TEXT NOT NULL,
+ name TEXT NOT NULL,
+ worst TEXT NOT NULL,
+
+ PRIMARY KEY(pkg_id),
+ FOREIGN KEY(worst) REFERENCES DETECTED_MALWARE(file_path) ON DELETE CASCADE,
+ FOREIGN KEY(name) REFERENCES NAMES(name) ON DELETE CASCADE
+);
+
+CREATE VIEW IF NOT EXISTS [join_p_d] AS
+ SELECT P.name, D.file_path, D.data_version, D.malware_name, D.detailed_url,
+ D.severity, D.detected_time, P.pkg_id
+ FROM PACKAGE_INFO AS P INNER JOIN DETECTED_MALWARE AS D ON P.worst = D.file_path;
+
+CREATE VIEW IF NOT EXISTS [join_detecteds_by_name] AS
+ SELECT J.*, N.is_ignored
+ FROM
+ (SELECT D.name, D.file_path, D.data_version, D.malware_name, D.detailed_url,
+ D.severity, D.detected_time, P.pkg_id
+ FROM DETECTED_MALWARE AS D LEFT JOIN PACKAGE_INFO AS P ON D.name = P.name
+ WHERE NOT EXISTS (SELECT * FROM join_p_d WHERE name = D.name)
+ UNION
+ SELECT name, file_path, data_version, malware_name, detailed_url,
+ severity, detected_time, pkg_id
+ FROM join_p_d)
+ AS J INNER JOIN NAMES AS N ON J.name = N.name;
+
+CREATE VIEW IF NOT EXISTS [join_detecteds_by_file_path] AS
+ SELECT D.file_path, D.data_version, D.malware_name, D.detailed_url, D.severity,
+ D.detected_time, P.pkg_id, N.is_ignored
+ FROM (DETECTED_MALWARE AS D LEFT JOIN PACKAGE_INFO AS P ON D.name = P.name)
+ AS J INNER JOIN NAMES AS N ON J.name = N.name;
-DROP TABLE IF EXISTS DETECTED_MALWARE_FILE;
+DROP VIEW IF EXISTS join_detecteds_abstracted;
+DROP VIEW IF EXISTS join_detecteds;
+DROP VIEW IF EXISTS join_p_d;
+
+DROP TABLE IF EXISTS PACKAGE_INFO;
+DROP TABLE IF EXISTS DETECTED_MALWARE;
+DROP TABLE IF EXISTS NAMES;
DROP TABLE IF EXISTS SCAN_REQUEST;
const std::string DB_VERSION_STR = "DB_VERSION";
const std::string SCHEMA_INFO_TABLE = "SCHEMA_INFO";
+RowShPtr extractRow(Statement &stmt)
+{
+ RowShPtr row = std::make_shared<Row>();
+
+ row->targetName = stmt.getText(); // name.
+ row->fileInAppPath = stmt.getText(); // file_path
+ row->dataVersion = stmt.getText(); // data_version
+ row->malwareName = stmt.getText(); // malware_name
+ row->detailedUrl = stmt.getText(); // detailed_url
+ row->severity = static_cast<csr_cs_severity_level_e>(stmt.getInt()); // severity
+ row->ts = static_cast<time_t>(stmt.getInt64()); // detected_time
+ row->pkgId = stmt.getText(); // pkg_id
+ row->isApp = !row->pkgId.empty();
+ row->isIgnored = static_cast<bool>(stmt.getInt());
+
+ return row;
+}
+
} // namespace anonymous
Manager::Manager(const std::string &dbfile, const std::string &scriptsDir) :
//===========================================================================
// DETECTED_MALWARE_FILE table
//===========================================================================
-RowShPtrs Manager::getDetectedMalwares(const std::string &dir)
+RowShPtr Manager::getDetectedByNameOnPath(const std::string &path)
+{
+ Statement stmt(m_conn, Query::SEL_DETECTED_BY_NAME_ON_PATH);
+ stmt.bind(path);
+
+ if (!stmt.step())
+ return nullptr;
+
+ return extractRow(stmt);
+}
+
+RowShPtrs Manager::getDetectedByNameOnDir(const std::string &dir)
{
- Statement stmt(m_conn, Query::SEL_DETECTED_BY_DIR);
+ Statement stmt(m_conn, Query::SEL_DETECTED_BY_NAME_ON_DIR);
stmt.bind(dir);
RowShPtrs rows;
- while (stmt.step()) {
- RowShPtr row = std::make_shared<Row>();
+ while (stmt.step())
+ rows.emplace_back(extractRow(stmt));
+
+ return rows;
+}
+
+RowShPtrs Manager::getDetectedByFilepathOnDir(const std::string &dir)
+{
+ Statement stmt(m_conn, Query::SEL_DETECTED_BY_FILEPATH_ON_DIR);
+ stmt.bind(dir);
- row->targetName = stmt.getText();
- row->dataVersion = stmt.getText();
- row->severity = static_cast<csr_cs_severity_level_e>(stmt.getInt());
- row->malwareName = stmt.getText();
- row->detailedUrl = stmt.getText();
- row->ts = static_cast<time_t>(stmt.getInt64());
- row->isIgnored = static_cast<bool>(stmt.getInt());
+ RowShPtrs rows;
- rows.emplace_back(std::move(row));
- }
+ while (stmt.step())
+ rows.emplace_back(extractRow(stmt));
return rows;
}
-RowShPtr Manager::getDetectedMalware(const std::string &path)
+RowShPtr Manager::getWorstByPkgId(const std::string &pkgId)
{
- Statement stmt(m_conn, Query::SEL_DETECTED_BY_PATH);
- stmt.bind(path);
+ Statement stmt(m_conn, Query::SEL_WORST_BY_PKGID);
+ stmt.bind(pkgId);
if (!stmt.step())
return nullptr;
RowShPtr row = std::make_shared<Row>();
- row->targetName = stmt.getText();
- row->dataVersion = stmt.getText();
- row->severity = static_cast<csr_cs_severity_level_e>(stmt.getInt());
- row->malwareName = stmt.getText();
- row->detailedUrl = stmt.getText();
- row->ts = static_cast<time_t>(stmt.getInt64());
- row->isIgnored = static_cast<bool>(stmt.getInt());
+ row->targetName = stmt.getText(); // name
+ row->fileInAppPath = stmt.getText(); // file_path
+ row->dataVersion = stmt.getText(); // data_version
+ row->malwareName = stmt.getText(); // malware_name
+ row->detailedUrl = stmt.getText(); // detailed_url
+ row->severity = static_cast<csr_cs_severity_level_e>(stmt.getInt()); // severity
+ row->ts = static_cast<time_t>(stmt.getInt64()); // detected_time
+ row->pkgId = pkgId;
+ row->isApp = true;
return row;
}
-void Manager::insertDetectedMalware(const CsDetected &d, const std::string &dataVersion)
+void Manager::insertName(const std::string &name)
+{
+ Statement stmt(m_conn, Query::INS_NAME);
+
+ stmt.bind(name);
+ stmt.exec();
+}
+
+void Manager::insertDetected(const CsDetected &d, const std::string &filepath,
+ const std::string &dataVersion)
{
Statement stmt(m_conn, Query::INS_DETECTED);
+ stmt.bind(filepath);
stmt.bind(d.targetName);
stmt.bind(dataVersion);
- stmt.bind(static_cast<int>(d.severity));
stmt.bind(d.malwareName);
stmt.bind(d.detailedUrl);
+ stmt.bind(static_cast<int>(d.severity));
stmt.bind(static_cast<sqlite3_int64>(d.ts));
- stmt.bind(static_cast<int>(false));
stmt.exec();
}
-void Manager::setDetectedMalwareIgnored(const std::string &path,
- bool flag)
+void Manager::insertWorst(const std::string &pkgId, const std::string &name,
+ const std::string &filepath)
{
- Statement stmt(m_conn, Query::UPD_DETECTED_INGNORED);
+ Statement stmt(m_conn, Query::INS_WORST);
+
+ stmt.bind(pkgId);
+ stmt.bind(name);
+ stmt.bind(filepath);
+ stmt.exec();
+}
+
+void Manager::updateIgnoreFlag(const std::string &name, bool flag)
+{
+ Statement stmt(m_conn, Query::UPD_IGNORE);
+
+ stmt.bind((flag ? 1 : 0));
+ stmt.bind(name);
+ stmt.exec();
+}
+
+void Manager::deleteDetectedByNameOnPath(const std::string &path)
+{
+ Statement stmt(m_conn, Query::DEL_DETECTED_BY_NAME_ON_PATH);
- stmt.bind(flag);
stmt.bind(path);
stmt.exec();
}
-void Manager::deleteDetectedMalware(const std::string &path)
+void Manager::deleteDetectedByFilepathOnPath(const std::string &path)
{
- Statement stmt(m_conn, Query::DEL_DETECTED_BY_PATH);
+ Statement stmt(m_conn, Query::DEL_DETECTED_BY_FILEPATH_ON_PATH);
stmt.bind(path);
stmt.exec();
}
-void Manager::deleteDeprecatedDetectedMalwares(const std::string &dir,
- const std::string &dataVersion)
+void Manager::deleteDetectedDeprecatedOnDir(const std::string &dir,
+ const std::string &dataVersion)
{
- Statement stmt(m_conn, Query::DEL_DETECTED_DEPRECATED);
+ Statement stmt(m_conn, Query::DEL_DETECTED_DEPRECATED_ON_DIR);
stmt.bind(dir);
stmt.bind(dataVersion);
-
stmt.exec();
}
void cleanLastScanTime();
// DETECTED_MALWARE_FILE & USER_RESPONSE
- RowShPtrs getDetectedMalwares(const std::string &dirpath);
- RowShPtr getDetectedMalware(const std::string &filepath);
- void insertDetectedMalware(const CsDetected &, const std::string &dataVersion);
- void setDetectedMalwareIgnored(const std::string &path, bool flag);
- void deleteDetectedMalware(const std::string &path);
- void deleteDeprecatedDetectedMalwares(const std::string &dir,
- const std::string &dataVersion);
+ RowShPtr getDetectedByNameOnPath(const std::string &path);
+ RowShPtrs getDetectedByNameOnDir(const std::string &dir);
+ RowShPtrs getDetectedByFilepathOnDir(const std::string &dir);
+ RowShPtr getWorstByPkgId(const std::string &pkgId);
+
+ void insertName(const std::string &name);
+ void insertDetected(const CsDetected &, const std::string &filename,
+ const std::string &dataVersion);
+ void insertWorst(const std::string &pkgId, const std::string &name,
+ const std::string &filepath);
+
+ void updateIgnoreFlag(const std::string &name, bool flag);
+ void deleteDetectedByNameOnPath(const std::string &path);
+ void deleteDetectedByFilepathOnPath(const std::string &path);
+ void deleteDetectedDeprecatedOnDir(const std::string &dir,
+ const std::string &dataVersion);
private:
void resetDatabase();
const std::string INS_SCAN_REQUEST =
"insert or replace into SCAN_REQUEST (dir, last_scan, data_version)"
- "values (?, ?, ?)";
+ " values (?, ?, ?)";
const std::string DEL_SCAN_REQUEST_BY_DIR =
"delete from SCAN_REQUEST where dir = ?";
const std::string DEL_SCAN_REQUEST =
"delete from SCAN_REQUEST";
+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_BY_NAME_ON_DIR =
+ "select name, file_path, data_version, malware_name, detailed_url, severity,"
+ " detected_time, pkg_id, is_ignored"
+ " from join_detecteds_by_name"
+ " where name like ? || '%'";
+
+const std::string SEL_DETECTED_BY_FILEPATH_ON_DIR =
+ "select name, file_path, data_version, malware_name, detailed_url, severity,"
+ " detected_time, pkg_id, is_ignored"
+ " from join_detecteds_by_file_path"
+ " where file_path like ? || '%'";
+
+const std::string SEL_WORST_BY_PKGID =
+ "select name, file_path, data_version, malware_name, detailed_url, severity,"
+ " detected_time"
+ " from join_p_d"
+ " where pkg_id = ?";
+
+const std::string INS_NAME =
+ "insert or replace into NAMES(name) values(?)";
-const std::string SEL_DETECTED_BY_DIR =
- "SELECT path, data_version, "
- "severity, malware_name, "
- "detailed_url, detected_time, ignored "
- "FROM detected_malware_file where path like ? || '%'";
+const std::string INS_DETECTED =
+ "insert or replace into DETECTED_MALWARE(file_path, name, data_version, malware_name,"
+ " detailed_url, severity, detected_time)"
+ " values(?, ?, ?, ?, ?, ?, ?)";
-const std::string SEL_DETECTED_BY_PATH =
- "SELECT path, data_version, "
- "severity, malware_name, "
- "detailed_url, detected_time, ignored "
- "FROM detected_malware_file where path = ?";
+const std::string INS_WORST =
+ "insert or replace into PACKAGE_INFO(pkg_id, name, worst) values(?, ?, ?)";
-const std::string INS_DETECTED =
- "insert or replace into DETECTED_MALWARE_FILE "
- "(path, data_version, severity, malware_name, "
- "detailed_url, detected_time, ignored) "
- "values (?, ?, ?, ?, ?, ?, ?)";
+const std::string UPD_IGNORE =
+ "update NAMES set is_ignored = ? where name = ?";
-const std::string UPD_DETECTED_INGNORED =
- "update DETECTED_MALWARE_FILE set ignored = ? where path = ?";
+const std::string DEL_DETECTED_BY_NAME_ON_PATH =
+ "delete from NAMES where name = ?";
-const std::string DEL_DETECTED_BY_PATH =
- "delete from DETECTED_MALWARE_FILE where path = ?";
+const std::string DEL_DETECTED_BY_FILEPATH_ON_PATH =
+ "delete from DETECTED_MALWARE where file_path = ?";
-const std::string DEL_DETECTED_DEPRECATED =
- "delete from DETECTED_MALWARE_FILE where path like ? || '%' "
- "and data_version != ?";
+const std::string DEL_DETECTED_DEPRECATED_ON_DIR =
+ "delete from DETECTED_MALWARE where file_path like ? || '%' "
+ " and data_version != ?";
} // namespace Query
} // namespace Db
using RowShPtrs = std::vector<RowShPtr>;
struct Row : public Csr::CsDetected {
+ std::string fileInAppPath; // for case of file in app
std::string dataVersion; // engine's data version
bool isIgnored;
default:
ThrowExc(DbFailed, db.getErrorMessage());
}
-
}
Statement::~Statement()
return sqlite3_column_int64(m_stmt, ++m_columnIndex);
}
-const char *Statement::getText() const
+std::string Statement::getText() const
{
if (!isColumnIndexValid())
ThrowExc(DbFailed, "index overflowed when getting text from row."
" query: " << m_query << " index: " << m_columnIndex);
- return reinterpret_cast<const char *>(sqlite3_column_text(m_stmt,
- ++m_columnIndex));
+ const char *text = reinterpret_cast<const char *>(sqlite3_column_text(m_stmt,
+ ++m_columnIndex));
+ std::string str = (text ? text : std::string());
+
+ return str;
}
} // namespace Db
// get column values. index of column auto-incremented
int getInt() const;
sqlite3_int64 getInt64() const;
- const char *getText() const;
+ std::string getText() const;
bool isNullColumn() const; // it's checking func. not auto incremented.
return this->handleUserResponse(detected);
}
-CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::string &pkgId)
+CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::string &pkgId,
+ std::string &riskiestPath)
{
auto starttime = time(nullptr);
CsEngineContext engineContext(this->m_loader);
auto &c = engineContext.get();
- // traverse files in app and take which is more danger than riskiest.
+ // traverse files in app and take which is more danger than riskiest
auto visitor = FsVisitor::create(
pkgPath,
this->m_db.getLastScanTime(pkgPath, this->m_dataVersion));
csre_cs_detected_h result;
toException(this->m_loader.scanFile(c, file->getPath(), &result));
- if (!result)
+ if (!result) {
+ this->m_db.deleteDetectedByFilepathOnPath(file->getPath());
continue;
+ }
INFO("New malware detected on file: " << file->getPath());
- auto candidate = this->convert(result, file->getPath());
+ auto candidate = this->convert(result, pkgPath);
candidate.isApp = true;
candidate.pkgId = pkgId;
- this->m_db.insertDetectedMalware(candidate, this->m_dataVersion);
- if (!riskiest)
+ this->m_db.insertName(pkgPath);
+ this->m_db.insertDetected(candidate, file->getPath(), this->m_dataVersion);
+
+ if (!riskiest) {
riskiest.reset(new CsDetected(std::move(candidate)));
- else if (*riskiest < candidate)
+ riskiestPath = file->getPath();
+ } else if (*riskiest < candidate) {
*riskiest = std::move(candidate);
+ riskiestPath = file->getPath();
+ }
}
this->m_db.insertLastScanTime(pkgPath, starttime, this->m_dataVersion);
- if (riskiest) {
- INFO("Riskiest malware selected in pkg: " << pkgPath);
- riskiest->targetName = pkgPath;
- }
-
return riskiest;
}
if (context.isScanOnCloud)
return this->scanAppOnCloud(context, pkgPath, pkgId);
- auto riskiest = this->scanAppDelta(pkgPath, pkgId);
- auto history = this->m_db.getDetectedMalware(pkgPath);
+ // old history
+ 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);
+ 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.insertWorst(pkgId, pkgPath, riskiestPath);
- if (riskiest && history) {
- if (*riskiest > *history) {
- INFO("new malware found and more risky! history should be updated.");
- this->m_db.insertDetectedMalware(*riskiest, this->m_dataVersion);
+ riskiest->response = this->getUserResponse(context, *riskiest);
+ return this->handleUserResponse(*riskiest);
} else {
- INFO("new malware is found but not riskier than history. history reusable.");
+ INFO("worst case is remained and can be re-used on pkg[" << pkgPath << "]");
if (history->isIgnored)
return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
history->response = this->getUserResponse(context, *history);
return this->handleUserResponse(*history);
}
- } else if (riskiest && !history) {
- INFO("new malware found and no history exist! history should be inserted.");
- this->m_db.insertDetectedMalware(*riskiest, this->m_dataVersion);
- } else if (!riskiest && history) {
- INFO("no malware found and history exist! history reusable.");
+ } else if (history && after && !riskiest) {
+ INFO("worst case is remained and NO new detected. history can be re-used. "
+ "on pkg[" << pkgPath << "]");
if (history->isIgnored)
return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
history->response = this->getUserResponse(context, *history);
return this->handleUserResponse(*history);
+ } else if (history && !after && riskiest) {
+ INFO("worst case is deleted but new detected. we have to find out "
+ "worse case in db and compare it with riskiest first. on pkg[" << pkgPath <<
+ "]");
+ Db::RowShPtr worse;
+ for (auto &row : this->m_db.getDetectedByFilepathOnDir(pkgPath))
+ if (!worse || *worse < *row)
+ worse = std::move(row);
+
+ if (*riskiest < *worse) {
+ INFO("worse case in db is worse than riskiest. on pkg[" << pkgPath << "]");
+ riskiestPath = worse->fileInAppPath;
+ *riskiest = std::move(*worse);
+ }
+
+ if (*history < *riskiest) {
+ 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.insertWorst(pkgId, pkgPath, riskiestPath);
+
+ riskiest->response = this->getUserResponse(context, *riskiest);
+ return this->handleUserResponse(*riskiest);
+ } else {
+ INFO("worst case is deleted but same or less level newly detected. on pkg[" <<
+ pkgPath << "]");
+ this->m_db.insertWorst(pkgId, pkgPath, riskiestPath);
+
+ if (history->isIgnored)
+ return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
+
+ riskiest->response = this->getUserResponse(context, *riskiest);
+ return this->handleUserResponse(*riskiest);
+ }
+ } else if (history && !after && !riskiest) {
+ auto rows = this->m_db.getDetectedByFilepathOnDir(pkgPath);
+ if (rows.empty()) {
+ INFO("worst case is deleted cascadingly and NO new detected and "
+ "NO worse case. the pkg[" << pkgPath << "] is clean.");
+ this->m_db.deleteDetectedByNameOnPath(pkgPath);
+ return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
+ } else {
+ INFO("worst case is deleted cascadingly and NO new detected and "
+ "worse case exist on pkg[" << pkgPath << "]. insert it to worst.");
+ Db::RowShPtr worse;
+ for (auto &row : rows)
+ if (!worse || *worse < *row)
+ worse = std::move(row);
+
+ this->m_db.insertWorst(pkgId, pkgPath, worse->fileInAppPath);
+
+ if (worse->isIgnored)
+ return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
+
+ worse->response = this->getUserResponse(context, *worse);
+ return this->handleUserResponse(*worse);
+ }
+ } else if (!history && riskiest) {
+ INFO("no history and new detected");
+ this->m_db.insertWorst(pkgId, pkgPath, riskiestPath);
+
+ riskiest->response = this->getUserResponse(context, *riskiest);
+ return this->handleUserResponse(*riskiest);
} else {
- INFO("no malware found and no history exist! it's clean!");
+ DEBUG("no history and no new detected");
return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
}
-
- // new and more risky malware found and db updated case only left.
- riskiest->response = this->getUserResponse(context, *riskiest);
- return this->handleUserResponse(*riskiest);
}
RawBuffer CsLogic::scanFileWithoutDelta(const CsContext &context,
auto d = this->convert(result, filepath);
- this->m_db.insertDetectedMalware(d, this->m_dataVersion);
+ this->m_db.insertName(d.targetName);
+ this->m_db.insertDetected(d, d.targetName, this->m_dataVersion);
d.response = this->getUserResponse(context, d);
return this->handleUserResponse(d, std::forward<FilePtr>(fileptr));
DEBUG("Scan request on file: " << filepath);
- auto history = this->m_db.getDetectedMalware(filepath);
+ auto history = this->m_db.getDetectedByNameOnPath(filepath);
FilePtr fileptr;
// OR there's no history at all.
if (fileptr) {
if (history)
- this->m_db.deleteDetectedMalware(filepath);
+ this->m_db.deleteDetectedByNameOnPath(filepath);
if (fileptr->isDir())
ThrowExc(FileSystemError, "file type shouldn't be directory: " << filepath);
if (lastScanTime != -1) {
// for case: scan history exist and not modified.
- for (auto &row : this->m_db.getDetectedMalwares(dir)) {
+ for (auto &row : this->m_db.getDetectedByNameOnDir(File::getPkgPath(dir))) {
try {
auto fileptr = File::create(row->targetName);
- if (fileptr->isInApp())
- fileset.insert(fileptr->getAppPkgPath());
- else
- fileset.insert(fileptr->getPath());
+ fileset.insert(fileptr->isInApp() ?
+ fileptr->getAppPkgPath() : fileptr->getPath());
} catch (const FileDoNotExist &) {
- this->m_db.deleteDetectedMalware(row->targetName);
+ this->m_db.deleteDetectedByNameOnPath(row->targetName);
} catch (const FileSystemError &) {
- this->m_db.deleteDetectedMalware(row->targetName);
+ this->m_db.deleteDetectedByNameOnPath(row->targetName);
}
}
}
file = File::create(filepath);
} catch (const Exception &e) {
ERROR("file system related exception occured on file: " << filepath <<
- " let's refresh detected malware history...");
-
- this->m_db.deleteDetectedMalware(filepath);
+ " This case might be file not exist or type invalid,"
+ " file has changed anyway... Don't refresh detected history to know that"
+ " it's changed since the time.");
throw;
}
- auto history = this->m_db.getDetectedMalware(filepath);
+ auto history = this->m_db.getDetectedByNameOnPath(File::getPkgPath(filepath));
if (!history) {
ERROR("Target to be judged doesn't exist in db. name: " << filepath);
// TODO: make isModifiedSince member function to File class
// not to regenerate like this.
- if (File::create(filepath, static_cast<time_t>(history->ts))) {
- this->m_db.deleteDetectedMalware(filepath);
-
- ThrowExc(FileSystemError, "Target modified since db delta inserted. "
- "name: " << filepath);
- }
+ if (File::create(filepath, static_cast<time_t>(history->ts)))
+ ThrowExc(FileSystemError, "File[" << filepath << "] modified since db delta "
+ "inserted. Don't refresh detected history to know that it's changed "
+ "since the time.");
switch (action) {
case CSR_CS_ACTION_REMOVE:
file->remove();
- this->m_db.deleteDetectedMalware(filepath);
+ this->m_db.deleteDetectedByNameOnPath(
+ (file->isInApp() ? file->getAppPkgPath() : file->getPath()));
break;
case CSR_CS_ACTION_IGNORE:
- this->m_db.setDetectedMalwareIgnored(filepath, true);
+ this->m_db.updateIgnoreFlag(File::getPkgPath(filepath), true);
break;
case CSR_CS_ACTION_UNIGNORE:
- this->m_db.setDetectedMalwareIgnored(filepath, false);
+ this->m_db.updateIgnoreFlag(File::getPkgPath(filepath), false);
break;
default:
{
EXCEPTION_GUARD_START
- auto row = this->m_db.getDetectedMalware(filepath);
+ auto row = this->m_db.getDetectedByNameOnPath(File::getPkgPath(filepath));
if (row && !row->isIgnored)
return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop();
Db::RowShPtrs rows;
std::for_each(dirSet.begin(), dirSet.end(),
[this, &rows](const std::string & dir) {
- for (auto &row : this->m_db.getDetectedMalwares(dir))
+ for (auto &row : this->m_db.getDetectedByNameOnDir(File::getPkgPath(dir)))
if (!row->isIgnored)
rows.emplace_back(std::move(row));
});
{
EXCEPTION_GUARD_START
- auto row = this->m_db.getDetectedMalware(filepath);
+ auto row = this->m_db.getDetectedByNameOnPath(File::getPkgPath(filepath));
if (row && row->isIgnored)
return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop();
Db::RowShPtrs rows;
std::for_each(dirSet.begin(), dirSet.end(),
[this, &rows](const std::string & dir) {
- for (auto &row : this->m_db.getDetectedMalwares(dir))
+ for (auto &row : this->m_db.getDetectedByNameOnDir(File::getPkgPath(dir)))
if (row->isIgnored)
rows.emplace_back(std::move(row));
});
{
switch (d.response) {
case CSR_CS_IGNORE:
- this->m_db.setDetectedMalwareIgnored(d.targetName, true);
+ this->m_db.updateIgnoreFlag(File::getPkgPath(d.targetName), true);
break;
case CSR_CS_REMOVE:
WARN("File type is changed, considered as different file: " << d.targetName);
}
- this->m_db.deleteDetectedMalware(d.targetName);
+ this->m_db.deleteDetectedByNameOnPath(File::getPkgPath(d.targetName));
break;
case CSR_CS_SKIP:
RawBuffer scanApp(const CsContext &context, const std::string &path);
RawBuffer scanAppOnCloud(const CsContext &context, const std::string &pkgPath,
const std::string &pkgId);
- CsDetectedPtr scanAppDelta(const std::string &pkgPath, const std::string &pkgId);
+ CsDetectedPtr scanAppDelta(const std::string &pkgPath, const std::string &pkgId,
+ std::string &riskiestPath);
RawBuffer scanFileWithoutDelta(const CsContext &context, const std::string &filepath,
FilePtr &&fileptr);
return false;
}
+std::string File::getPkgPath(const std::string &path)
+{
+ std::smatch matched;
+
+ for (const auto ®e : g_regexprs) {
+ if (!std::regex_search(path, matched, rege))
+ continue;
+
+ if (matched.size() == 3)
+ return matched[1];
+ else if (matched.size() == 4)
+ return matched[1];
+ }
+
+ return path;
+}
+
File::File(const std::string &fpath, bool isDir) : m_path(fpath), m_inApp(false), m_isDir(isDir)
{
std::smatch matched;
static FilePtr create(const std::string &fpath, time_t modifiedSince = -1);
static bool isInApp(const std::string &path);
+ static std::string getPkgPath(const std::string &path);
private:
explicit File(const std::string &fpath, bool isDir);
malware3.ts = 310;
// select test with vacant data
- auto detected = db.getDetectedMalware(malware1.targetName);
+ auto detected = db.getDetectedByNameOnPath(malware1.targetName);
CHECK_IS_NULL(detected);
- auto detectedList = db.getDetectedMalwares("/opt");
+ auto detectedList = db.getDetectedByNameOnDir("/opt");
ASSERT_IF(detectedList.empty(), true);
- db.insertDetectedMalware(malware1, initDataVersion);
- detected = db.getDetectedMalware(malware1.targetName);
+ db.insertName(malware1.targetName);
+ db.insertDetected(malware1, malware1.targetName, initDataVersion);
+ detected = db.getDetectedByNameOnPath(malware1.targetName);
checkSameMalware(malware1, *detected);
ASSERT_IF(detected->dataVersion, initDataVersion);
ASSERT_IF(detected->isIgnored, false);
- db.insertDetectedMalware(malware2, initDataVersion);
- db.setDetectedMalwareIgnored(malware2.targetName, true);
- detected = db.getDetectedMalware(malware2.targetName);
+ db.insertName(malware2.targetName);
+ db.insertDetected(malware2, malware2.targetName, initDataVersion);
+ db.updateIgnoreFlag(malware2.targetName, true);
+ detected = db.getDetectedByNameOnPath(malware2.targetName);
checkSameMalware(malware2, *detected);
ASSERT_IF(detected->dataVersion, initDataVersion);
ASSERT_IF(detected->isIgnored, true);
// getDetectedMalwares test
- detectedList = db.getDetectedMalwares("/opt");
+ detectedList = db.getDetectedByNameOnDir("/opt");
ASSERT_IF(detectedList.size(), static_cast<size_t>(2));
for (auto &item : detectedList) {
}
// setDetectedMalwareIgnored test
- db.setDetectedMalwareIgnored(malware1.targetName, true);
- detected = db.getDetectedMalware(malware1.targetName);
+ db.updateIgnoreFlag(malware1.targetName, true);
+ detected = db.getDetectedByNameOnPath(malware1.targetName);
checkSameMalware(malware1, *detected);
ASSERT_IF(detected->isIgnored, true);
// deleteDeprecatedDetectedMalwares test
- db.insertDetectedMalware(malware3, changedDataVersion);
- db.deleteDeprecatedDetectedMalwares("/opt", changedDataVersion);
- detected = db.getDetectedMalware(malware3.targetName);
+ db.insertName(malware3.targetName);
+ db.insertDetected(malware3, malware3.targetName, changedDataVersion);
+ db.deleteDetectedDeprecatedOnDir("/opt", changedDataVersion);
+ detected = db.getDetectedByNameOnPath(malware3.targetName);
checkSameMalware(malware3, *detected);
ASSERT_IF(detected->dataVersion, changedDataVersion);
ASSERT_IF(detected->isIgnored, false);
- CHECK_IS_NULL(db.getDetectedMalware(malware1.targetName));
- CHECK_IS_NULL(db.getDetectedMalware(malware2.targetName));
+ CHECK_IS_NULL(db.getDetectedByNameOnPath(malware1.targetName));
+ CHECK_IS_NULL(db.getDetectedByNameOnPath(malware2.targetName));
// deleteDetectedMalware test
- db.deleteDetectedMalware(malware3.targetName);
- CHECK_IS_NULL(db.getDetectedMalware(malware3.targetName));
+ db.deleteDetectedByNameOnPath(malware3.targetName);
+ CHECK_IS_NULL(db.getDetectedByNameOnPath(malware3.targetName));
EXCEPTION_GUARD_END
}
csre_wp_risk_level_e risk_level;
std::string detailed_url;
- Result(csre_wp_risk_level_e r, const char *durl) : risk_level(r),
- detailed_url(durl) {}
+ Result(csre_wp_risk_level_e r, const char *durl) :
+ risk_level(r),
+ detailed_url(durl ? durl : std::string()) {}
};
std::unordered_map<std::string, Result> ExpectedResult = {
- {"http://normal.test.com", Result(CSRE_WP_RISK_UNVERIFIED, "")},
+ {"http://normal.test.com", Result(CSRE_WP_RISK_UNVERIFIED, nullptr)},
{"http://highrisky.test.com", Result(CSRE_WP_RISK_HIGH, "http://high.risky.com")},
{"http://mediumrisky.test.com", Result(CSRE_WP_RISK_MEDIUM, "http://medium.risky.com")},
- {"http://lowrisky.test.com", Result(CSRE_WP_RISK_LOW, "")}
+ {"http://lowrisky.test.com", Result(CSRE_WP_RISK_LOW, "http://low.risky.com")}
};
inline void checkResult(Csr::WpLoader &loader,
ASSERT_IF(a_is_app, e_is_app);
ASSERT_IF(a_pkg_id, e_pkg_id);
- BOOST_CHECK_MESSAGE(e_timestamp <= a_timestamp,
- "Actual detected item's time stamp is later than expected time "
- "stamp (which is start time before scan_file maybe..). this case "
- "should be the returned detected item comes from history which is "
- "scanned in the past. actual time: " << a_timestamp <<
- " expected(started) time: " << e_timestamp);
+ BOOST_WARN_MESSAGE(e_timestamp <= a_timestamp,
+ "Actual detected item's time stamp is later than expected time "
+ "stamp (which is start time before scan_file maybe..). this case "
+ "should be the returned detected item comes from history which is "
+ "scanned in the past. actual time: " << a_timestamp <<
+ " expected(started) time: " << e_timestamp);
}
void ASSERT_DETECTED_HANDLE(csr_cs_detected_h expected, csr_cs_detected_h actual)