From 1d02e99e78e4e703f334eab18476c118e2a36ba5 Mon Sep 17 00:00:00 2001 From: Ulrich Telle Date: Thu, 21 Mar 2024 19:04:25 +0100 Subject: [PATCH] (#21354) Add recipe for sqlite3mc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add recipe for sqlite3mc * Adjust recipe Remove C++ compiler options, because this library is a C library * Add CMake version requirement * Add CMake requirement to test package * Add missing header in test * Adjust according to review * Fix conan v1 related issues * Apply suggestions from code review Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com> * Remove option SQLITE_ENABLE_JSON1, add FreeBSD to os list --------- Co-authored-by: Rubén Rincón Blanco Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com> --- recipes/sqlite3mc/all/conandata.yml | 4 + recipes/sqlite3mc/all/conanfile.py | 222 ++++++++++++++++++ .../sqlite3mc/all/test_package/CMakeLists.txt | 12 + .../sqlite3mc/all/test_package/conanfile.py | 25 ++ recipes/sqlite3mc/all/test_package/main.c | 73 ++++++ recipes/sqlite3mc/config.yml | 3 + 6 files changed, 339 insertions(+) create mode 100644 recipes/sqlite3mc/all/conandata.yml create mode 100644 recipes/sqlite3mc/all/conanfile.py create mode 100644 recipes/sqlite3mc/all/test_package/CMakeLists.txt create mode 100644 recipes/sqlite3mc/all/test_package/conanfile.py create mode 100644 recipes/sqlite3mc/all/test_package/main.c create mode 100644 recipes/sqlite3mc/config.yml diff --git a/recipes/sqlite3mc/all/conandata.yml b/recipes/sqlite3mc/all/conandata.yml new file mode 100644 index 0000000000000..462228eb46b29 --- /dev/null +++ b/recipes/sqlite3mc/all/conandata.yml @@ -0,0 +1,4 @@ +sources: + "1.8.0": + url: "https://github.com/utelle/SQLite3MultipleCiphers/archive/refs/tags/v1.8.0.tar.gz" + sha256: "13D9B939BEF7C7371D58A3874F83B18CF330EB2171205B3680ACDDB2215BE0E5" diff --git a/recipes/sqlite3mc/all/conanfile.py b/recipes/sqlite3mc/all/conanfile.py new file mode 100644 index 0000000000000..eddb5a88de890 --- /dev/null +++ b/recipes/sqlite3mc/all/conanfile.py @@ -0,0 +1,222 @@ +import os +from conan import ConanFile +from conan.tools.cmake import cmake_layout, CMakeDeps, CMakeToolchain, CMake +from conan.tools.files import get, copy + +required_conan_version = ">=1.53.0" + + +class sqlite3mc(ConanFile): + name = "sqlite3mc" + package_type = "library" + + license = "MIT" + homepage = "https://github.com/utelle/SQLite3MultipleCiphers" + url = "https://github.com/conan-io/conan-center-index" + description = "The project SQLite3 Multiple Ciphers implements an encryption extension for SQLite with support for multiple ciphers." + topics = ("sqlite", "sqlite3", "sqlite3-encryption", "database-encryption", "sqlite3-extension") + + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "fPIC": [True, False], + "require_zlib": [True, False], + "static_runtime_link": [True, False], + "build_shell": [True, False], + "with_icu": [True, False], + "enable_debug": [True, False], + "soundex": [True, False], + "enable_column_metadata": [True, False], + "secure_delete": [True, False], + "enable_fts3": [True, False], + "enable_fts3_paranthesis": [True, False], + "enable_fts4": [True, False], + "enable_fts5": [True, False], + "enable_carray": [True, False], + "enable_csv": [True, False], + "enable_extfunc": [True, False], + "enable_geopoly": [True, False], + "enable_rtree": [True, False], + "enable_uuid": [True, False], + "use_uri": [True, False], + "user_authentication": [True, False], + "enable_preupdate_hook": [True, False], + "enable_session": [True, False], + "shell_is_utf8": [True, False], + "enable_fileio": [True, False], + "enable_regexp": [True, False], + "enable_series": [True, False], + "enable_sha3": [True, False], + "enable_explain_comments": [True, False], + "enable_dbpage_vtab": [True, False], + "enable_dbstat_vtab": [True, False], + "enable_stmtvtab": [True, False], + "enable_unknown_sql_function": [True, False], + "use_miniz": [True, False], + "enable_compress": [True, False], + "enable_sqlar": [True, False], + "enable_zipfile": [True, False], + "use_sqleet_legacy": [True, False], + "use_sqlcipher_legacy": [True, False], + "secure_memory": [True, False], + "use_random_fill_memory": [True, False], + "omit_aes_hardware_support": [True, False] + } + default_options = { + "shared": False, + "fPIC": True, + "require_zlib": False, + "static_runtime_link": False, + "build_shell": False, + "with_icu": False, + "enable_debug": False, + "soundex": True, + "enable_column_metadata": True, + "secure_delete": True, + "enable_fts3": True, + "enable_fts3_paranthesis": True, + "enable_fts4": True, + "enable_fts5": True, + "enable_carray": True, + "enable_csv": True, + "enable_extfunc": True, + "enable_geopoly": True, + "enable_rtree": True, + "enable_uuid": True, + "use_uri": True, + "user_authentication": True, + "enable_preupdate_hook": False, + "enable_session": False, + "shell_is_utf8": True, + "enable_fileio": True, + "enable_regexp": True, + "enable_series": True, + "enable_sha3": True, + "enable_explain_comments": True, + "enable_dbpage_vtab": True, + "enable_dbstat_vtab": True, + "enable_stmtvtab": True, + "enable_unknown_sql_function": True, + "use_miniz": False, + "enable_compress": False, + "enable_sqlar": False, + "enable_zipfile": False, + "use_sqleet_legacy": False, + "use_sqlcipher_legacy": False, + "secure_memory": False, + "use_random_fill_memory": False, + "omit_aes_hardware_support": False + } + + def build_requirements(self): + self.tool_requires("cmake/[>=3.24 <4]") + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + if self.options.shared: + self.options.rm_safe("fPIC") + self.settings.rm_safe("compiler.cppstd") + self.settings.rm_safe("compiler.libcxx") + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def layout(self): + cmake_layout(self, src_folder="src") + + def requirements(self): + if self.options.require_zlib: + self.requires("zlib/[>=1.2.11 <2]") + if self.options.with_icu: + self.requires("icu/74.1") + + def generate(self): + deps = CMakeDeps(self) + deps.generate() + + tc = CMakeToolchain(self) + tc.variables["_SQLITE3MC_REQUIRE_ZLIB"] = self.options.require_zlib + tc.variables["SQLITE3MC_STATIC_RUNTIME_LINK"] = self.options.static_runtime_link + tc.variables["SQLITE3MC_STATIC"] = not self.options.shared + tc.variables["SQLITE3MC_BUILD_SHELL"] = self.options.build_shell + tc.variables["SQLITE3MC_WITH_ICU"] = self.options.with_icu + + tc.variables["SQLITE_ENABLE_DEBUG"] = self.options.enable_debug + tc.variables["SQLITE_SOUNDEX"] = self.options.soundex + tc.variables["SQLITE_ENABLE_COLUMN_METADATA"] = self.options.enable_column_metadata + tc.variables["SQLITE_SECURE_DELETE"] = self.options.secure_delete + tc.variables["SQLITE_ENABLE_FTS3"] = self.options.enable_fts3 + tc.variables["SQLITE_ENABLE_FTS3_PARENTHESIS"] = self.options.enable_fts3_paranthesis + tc.variables["SQLITE_ENABLE_FTS4"] = self.options.enable_fts4 + tc.variables["SQLITE_ENABLE_FTS5"] = self.options.enable_fts5 + + tc.variables["SQLITE_ENABLE_CARRAY"] = self.options.enable_carray + tc.variables["SQLITE_ENABLE_CSV"] = self.options.enable_csv + tc.variables["SQLITE_ENABLE_EXTFUNC"] = self.options.enable_extfunc + tc.variables["SQLITE_ENABLE_GEOPOLY"] = self.options.enable_geopoly + tc.variables["SQLITE_ENABLE_RTREE"] = self.options.enable_rtree + tc.variables["SQLITE_ENABLE_UUID"] = self.options.enable_uuid + tc.variables["SQLITE_USE_URI"] = self.options.use_uri + tc.variables["SQLITE_USER_AUTHENTICATION"] = self.options.user_authentication + tc.variables["SQLITE_ENABLE_PREUPDATE_HOOK"] = self.options.enable_preupdate_hook + tc.variables["SQLITE_ENABLE_SESSION"] = self.options.enable_session + tc.variables["SQLITE_SHELL_IS_UTF8"] = self.options.shell_is_utf8 + + # Options for library only + tc.variables["SQLITE_ENABLE_FILEIO"] = self.options.enable_fileio + tc.variables["SQLITE_ENABLE_REGEXP"] = self.options.enable_regexp + tc.variables["SQLITE_ENABLE_SERIES"] = self.options.enable_series + tc.variables["SQLITE_ENABLE_SHA3"] = self.options.enable_sha3 + + # Options for shell only (compatibility with official SQLite shell) + tc.variables["SQLITE_ENABLE_EXPLAIN_COMMENTS"] = self.options.enable_explain_comments + tc.variables["SQLITE_ENABLE_DBPAGE_VTAB"] = self.options.enable_dbpage_vtab + tc.variables["SQLITE_ENABLE_DBSTAT_VTAB"] = self.options.enable_dbstat_vtab + tc.variables["SQLITE_ENABLE_STMTVTAB"] = self.options.enable_stmtvtab + tc.variables["SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION"] = self.options.enable_unknown_sql_function + + # Embedded Compression + tc.variables["SQLITE3MC_USE_MINIZ"] = self.options.use_miniz + + # Compression/Options that require ZLIB + tc.variables["SQLITE_ENABLE_COMPRESS"] = self.options.enable_compress + tc.variables["SQLITE_ENABLE_SQLAR"] = self.options.enable_sqlar + tc.variables["SQLITE_ENABLE_ZIPFILE"] = self.options.enable_zipfile + + # Legacy Encryption Extensions + tc.variables["SQLITE3MC_USE_SQLEET_LEGACY"] = self.options.use_sqleet_legacy + tc.variables["SQLITE3MC_USE_SQLCIPHER_LEGACY"] = self.options.use_sqlcipher_legacy + + # Additional memory security (filling freed memory allocations with zeros or random data) + tc.variables["SQLITE3MC_SECURE_MEMORY"] = self.options.secure_memory + tc.variables["SQLITE3MC_USE_RANDOM_FILL_MEMORY"] = self.options.use_random_fill_memory + + # Omit AES hardware support + tc.variables["SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT"] = self.options.omit_aes_hardware_support + + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + cmake = CMake(self) + cmake.install() + copy(self, "LICENSE*", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"), keep_path=False) + + def package_info(self): + if self.options.shared: + self.cpp_info.libs = ["sqlite3mc"] + else: + self.cpp_info.libs = ["sqlite3mc_static"] + if self.settings.os in ("Linux", "FreeBSD", "Macos"): + self.cpp_info.system_libs.append("pthread") + self.cpp_info.system_libs.append("dl") + self.cpp_info.system_libs.append("m") + if self.settings.os == "Macos": + self.cpp_info.frameworks.append("Security") diff --git a/recipes/sqlite3mc/all/test_package/CMakeLists.txt b/recipes/sqlite3mc/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..79301e1094eb1 --- /dev/null +++ b/recipes/sqlite3mc/all/test_package/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.15) +project(test_sqlite3mc C) + +find_package(sqlite3mc REQUIRED) + +add_executable(${PROJECT_NAME} + main.c +) + +target_link_libraries(${PROJECT_NAME} + sqlite3mc::sqlite3mc +) diff --git a/recipes/sqlite3mc/all/test_package/conanfile.py b/recipes/sqlite3mc/all/test_package/conanfile.py new file mode 100644 index 0000000000000..1b70bb597a5da --- /dev/null +++ b/recipes/sqlite3mc/all/test_package/conanfile.py @@ -0,0 +1,25 @@ +import os +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import can_run + + +class sqlite3mcTest(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def layout(self): + cmake_layout(self) + + def test(self): + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "test_sqlite3mc") + self.run(cmd, env="conanrun") diff --git a/recipes/sqlite3mc/all/test_package/main.c b/recipes/sqlite3mc/all/test_package/main.c new file mode 100644 index 0000000000000..efb9f3b4c701d --- /dev/null +++ b/recipes/sqlite3mc/all/test_package/main.c @@ -0,0 +1,73 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + sqlite3 *db; + const char *key = "password"; + const char *wrongKey = "wrongPassword"; + + // Create database + int rc = sqlite3_open("test.db", &db); + if (rc != SQLITE_OK) + { + fprintf(stderr, "Failed to open database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + + // Encrypt + sqlite3_key(db, key, strlen(key)); + + // Fill db with some data and close it + rc = sqlite3_exec(db, "CREATE TABLE users (name TEXT NOT NULL, ID INTEGER PRIMARY KEY UNIQUE)", NULL, NULL, NULL); + if (rc != SQLITE_OK) + { + fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + rc = sqlite3_exec(db, "INSERT INTO users (name, ID) VALUES ('testUser', '12345')", NULL, NULL, NULL); + if (rc != SQLITE_OK) + { + fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + rc = sqlite3_close(db); + if (rc != SQLITE_OK) + { + fprintf(stderr, "Failed to close database: %s\n", sqlite3_errmsg(db)); + return 1; + } + + // Reopen and provide wrong key + rc = sqlite3_open("test.db", &db); + if (rc != SQLITE_OK) + { + fprintf(stderr, "Failed to open database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return 1; + } + sqlite3_key(db, wrongKey, strlen(wrongKey)); + + // Try to access the database, should fail + rc = sqlite3_exec(db, "SELECT name FROM users WHERE ID = '12345'", NULL, NULL, NULL); + if (rc == SQLITE_OK) + { + fprintf(stderr, "Access was provided without the proper key\n"); + sqlite3_close(db); + return 1; + } + rc = sqlite3_close(db); + if (rc != SQLITE_OK) + { + fprintf(stderr, "Failed to close database: %s\n", sqlite3_errmsg(db)); + return 1; + } + + + fprintf(stdout, "Test successful\n"); + return 0; +} diff --git a/recipes/sqlite3mc/config.yml b/recipes/sqlite3mc/config.yml new file mode 100644 index 0000000000000..4d72270a88048 --- /dev/null +++ b/recipes/sqlite3mc/config.yml @@ -0,0 +1,3 @@ +versions: + "1.8.0": + folder: all