diff --git a/CMakeLists.txt b/CMakeLists.txt index 120714b..3d955e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9 FATAL_ERROR) +cmake_minimum_required(VERSION 3.24 FATAL_ERROR) # cmake setup begin project(solanaceae_clamav) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 1c00676..bc28eaf 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -12,15 +12,15 @@ add_subdirectory(./solanaceae_message3) # TODO: move to clamav.cmake find_package(PkgConfig QUIET) if (PKG_CONFIG_FOUND) - pkg_check_modules(PKGC_CLAMAV QUIET IMPORTED_TARGET libclamav) + pkg_check_modules(PKGC_CLAMAV QUIET IMPORTED_TARGET GLOBAL libclamav) if (PKGC_CLAMAV_FOUND) - add_library(libclamav ALIAS PkgConfig::PKGC_CLAMAV) - message("II libclamav found using pkg-config") + add_library(EXT_SOL::libclamav ALIAS PkgConfig::PKGC_CLAMAV) + message("II clamav found using pkg-config") endif() endif() -if (NOT TARGET libclamav) +if (NOT TARGET EXT_SOL::libclamav) include(FetchContent) set(ENABLE_LIBCLAMAV_ONLY ON) set(ENABLE_APP OFF) @@ -30,9 +30,11 @@ if (NOT TARGET libclamav) GIT_TAG clamav-1.2.0 # find_package is tried first - FIND_PACKAGE_ARGS NAMES libclamav + FIND_PACKAGE_ARGS NAMES clamav ClamAV libclamav libClamAV ) FetchContent_MakeAvailable(clamav) + + add_library(EXT_SOL::libclamav ALIAS clamav) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87b9b8a..d0daff2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9 FATAL_ERROR) +cmake_minimum_required(VERSION 3.24 FATAL_ERROR) add_library(solanaceae_clamav ./solanaceae/clamav/test_lib.cpp @@ -6,7 +6,17 @@ add_library(solanaceae_clamav target_include_directories(solanaceae_clamav PUBLIC .) target_compile_features(solanaceae_clamav PUBLIC cxx_std_17) target_link_libraries(solanaceae_clamav PUBLIC - libclamav + EXT_SOL::libclamav + #solanaceae_util +) + +add_executable(solanaceae_clamav_test + ./solanaceae/clamav/test_exe.cpp +) +target_include_directories(solanaceae_clamav_test PUBLIC .) +target_compile_features(solanaceae_clamav_test PUBLIC cxx_std_17) +target_link_libraries(solanaceae_clamav_test PUBLIC + EXT_SOL::libclamav #solanaceae_util ) diff --git a/src/solanaceae/clamav/test_exe.cpp b/src/solanaceae/clamav/test_exe.cpp new file mode 100644 index 0000000..31320f3 --- /dev/null +++ b/src/solanaceae/clamav/test_exe.cpp @@ -0,0 +1,79 @@ +#include + +#include + +int main(void) { + if (cl_init(CL_INIT_DEFAULT) != CL_SUCCESS) { + return 1; + } + + auto* clamav_engine = cl_engine_new(); + if (clamav_engine == nullptr) { + return 2; + } + + std::string db_dir; + // TODO: load from config + + unsigned int signo = 0; + + if (db_dir.empty()) { + std::cout << "default db dir: " << cl_retdbdir() << "\n"; + if (cl_load(cl_retdbdir(), clamav_engine, &signo, CL_DB_STDOPT) != CL_SUCCESS) { + std::cerr << "default db dir load failed, falling back to '/var/lib/clamav'\n"; + if (cl_load("/var/lib/clamav", clamav_engine, &signo, CL_DB_STDOPT) != CL_SUCCESS) { + std::cerr << "db dir load failed, exiting\n"; + return 3; + } else { + db_dir = "/var/lib/clamav"; + } + } else { + db_dir = cl_retdbdir(); + } + // if db_dir changed, save to config? + } else { + if (cl_load(db_dir.c_str(), clamav_engine, &signo, CL_DB_STDOPT) != CL_SUCCESS) { + std::cerr << "config db dir load failed, exiting (" << db_dir << ")\n"; + return 3; + } + } + + std::cout << "signatures loaded: " << signo << "\n"; + + if (cl_engine_compile(clamav_engine) != CL_SUCCESS) { + cl_engine_free(clamav_engine); + return 4; + } + + // TODO: database update watcher + + const char* filename = "~/Downloads/cubic-paper.pdf"; + const char* virname = nullptr; + unsigned long int scanned = 0; + + struct cl_scan_options scan_opts { + /*CL_SCAN_GENERAL_ALLMATCHES |*/ CL_SCAN_GENERAL_HEURISTICS | CL_SCAN_GENERAL_HEURISTIC_PRECEDENCE, + ~0u, + ~0u, + 0u, + 0u + }; + + if (auto ret = cl_scanfile( + filename, + &virname, + &scanned, + clamav_engine, + &scan_opts + ); ret != CL_CLEAN && ret != CL_VIRUS) { + // error + } else if (ret == CL_VIRUS) { + std::cout << "file virus\n"; + } else { // clean + std::cout << "file clean\n"; + } + + cl_engine_free(clamav_engine); + return 0; +} +