From: Howard Chu Date: Wed, 16 Oct 2024 21:47:42 +0000 (+0100) Subject: Move the crypto module helpers into main liblmdb. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14c7ff334759278d12db0aa5a8a3930a2cba3736;p=thirdparty%2Fopenldap.git Move the crypto module helpers into main liblmdb. Just makes things easier than using the individual mdb_env_set APIs. --- diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile index 01d6536604..e598afb8e2 100644 --- a/libraries/liblmdb/Makefile +++ b/libraries/liblmdb/Makefile @@ -74,15 +74,15 @@ liblmdb$(SOEXT): mdb.lo midl.lo # $(CC) $(LDFLAGS) -pthread -shared -Wl,-Bsymbolic -o $@ mdb.o midl.o $(SOLIBS) $(CC) $(LDFLAGS) -pthread -shared -o $@ mdb.lo midl.lo $(SOLIBS) -mdb_stat: mdb_stat.o module.o liblmdb.a +mdb_stat: mdb_stat.o liblmdb.a $(CC) $(LDFLAGS) -o $@ $^ $(LDL) -mdb_copy: mdb_copy.o module.o liblmdb.a +mdb_copy: mdb_copy.o liblmdb.a $(CC) $(LDFLAGS) -o $@ $^ $(LDL) -mdb_dump: mdb_dump.o module.o liblmdb.a +mdb_dump: mdb_dump.o liblmdb.a $(CC) $(LDFLAGS) -o $@ $^ $(LDL) -mdb_load: mdb_load.o module.o liblmdb.a +mdb_load: mdb_load.o liblmdb.a $(CC) $(LDFLAGS) -o $@ $^ $(LDL) -mdb_drop: mdb_drop.o module.o liblmdb.a +mdb_drop: mdb_drop.o liblmdb.a $(CC) $(LDFLAGS) -o $@ $^ $(LDL) mtest: mtest.o liblmdb.a mtest2: mtest2.o liblmdb.a @@ -92,8 +92,8 @@ mtest5: mtest5.o liblmdb.a mtest6: mtest6.o liblmdb.a mtest_remap: mtest_remap.o liblmdb.a mtest_enc: mtest_enc.o chacha8.o liblmdb.a -mtest_enc2: mtest_enc2.o module.o liblmdb.a crypto.lm - $(CC) $(LDFLAGS) -pthread -o $@ mtest_enc2.o module.o liblmdb.a $(LDL) +mtest_enc2: mtest_enc2.o liblmdb.a crypto.lm + $(CC) $(LDFLAGS) -pthread -o $@ mtest_enc2.o liblmdb.a $(LDL) mplay: mplay.o liblmdb.a diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h index 155bb2a3f6..4ab108116b 100644 --- a/libraries/liblmdb/lmdb.h +++ b/libraries/liblmdb/lmdb.h @@ -1760,6 +1760,37 @@ typedef struct MDB_crypto_funcs { * @return A pointer to a #MDB_crypto_funcs structure. */ typedef MDB_crypto_funcs *(MDB_crypto_hooks)(void); + + /** @brief Load a dynamically loadable module. + * + * @param[in] file The pathname of the module to load. + * @param[in] symname The name of a symbol to resolve in the module. + * @param[out] mcf_ptr The crypto hooks returned from the module. + * @param[out] errmsg Messages for any errors from trying to load the module. + * @return The handle to the loadable module that can be unloaded by #mdb_modunload(), + * or NULL if loading failed. + */ +void *mdb_modload(const char *file, const char *symname, + MDB_crypto_funcs **mcf_ptr, char **errmsg); + + /** @brief Unload a dynamically loaded module. + * + * All environments that used the functions in the module must be closed + * before unloading the module. + * @param[in] handle The handle returned by #mdb_modload(). + */ +void mdb_modunload(void *handle); + + /** @brief Set an environment to use the given crypto functions. + * + * This is just a wrapper around #mdb_env_set_encrypt() to ease use of + * dynamically loaded crypto functions. + * @param[in] env An environment handle returned by #mdb_env_create() + * @param[in] funcs The crypto hooks retrieved by #mdb_modload(). + * @param[in] passphrase The secret used to generate the encryption key for the environment. + */ +void mdb_modsetup(MDB_env *env, MDB_crypto_funcs *cf, const char *passphrase); + /** @} */ #ifdef __cplusplus diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 0dea5c63f4..a5cada1e22 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -11510,6 +11510,88 @@ mdb_env_set_checksum(MDB_env *env, MDB_sum_func *func, unsigned int size) env->me_sumsize = size; return MDB_SUCCESS; } + +#ifdef _WIN32 +#include +#else +#include +#endif + +void * ESECT +mdb_modload(const char *file, const char *name, MDB_crypto_funcs **mcf_ptr, char **errmsg) +{ + MDB_crypto_hooks *hookfunc; + void *ret = NULL; + if (!name) + name = "MDB_crypto"; + +#ifdef _WIN32 + { + HINSTANCE mlm = LoadLibrary(file); + if (mlm) { + hookfunc = GetProcAddress(mlm, name); + if (hookfunc) + *mcf_ptr = hookfunc(); + else { + *errmsg = "Crypto hook function not found"; + FreeLibrary(mlm); + mlm = NULL; + } + } else { + *errmsg = GetLastError(); + } + ret = (void *)mlm; + } +#else + { + void *mlm = dlopen(file, RTLD_NOW); + if (mlm) { + hookfunc = dlsym(mlm, name); + if (hookfunc) + *mcf_ptr = hookfunc(); + else { + *errmsg = "Crypto hook function not found"; + dlclose(mlm); + mlm = NULL; + } + } else { + *errmsg = dlerror(); + } + ret = mlm; + } +#endif + return ret; +} + +void ESECT +mdb_modunload(void *mlm) +{ +#ifdef _WIN32 + FreeLibrary((HINSTANCE)mlm); +#else + dlclose(mlm); +#endif +} + +void ESECT +mdb_modsetup(MDB_env *env, MDB_crypto_funcs *cf, const char *password) +{ + MDB_val enckey = {0}; + if (cf->mcf_sumfunc) { + mdb_env_set_checksum(env, cf->mcf_sumfunc, cf->mcf_sumsize); + } + if (cf->mcf_encfunc && password) { + char keybuf[2048]; + enckey.mv_data = keybuf; + enckey.mv_size = cf->mcf_keysize; + if (cf->mcf_str2key) + cf->mcf_str2key(password, &enckey); + else + strncpy(enckey.mv_data, password, enckey.mv_size); + mdb_env_set_encrypt(env, cf->mcf_encfunc, &enckey, cf->mcf_esumsize); + memset(enckey.mv_data, 0, enckey.mv_size); + } +} #endif int ESECT diff --git a/libraries/liblmdb/mdb_copy.c b/libraries/liblmdb/mdb_copy.c index c230caa2cb..522d315cf9 100644 --- a/libraries/liblmdb/mdb_copy.c +++ b/libraries/liblmdb/mdb_copy.c @@ -21,7 +21,6 @@ #include #include #include "lmdb.h" -#include "module.h" static void sighandle(int sig) @@ -80,11 +79,13 @@ int main(int argc,char * argv[]) rc = mdb_env_create(&env); if (rc == MDB_SUCCESS) { if (module) { - mlm = mlm_setup(env, module, password, &errmsg); + MDB_crypto_funcs *mcf; + mlm = mdb_modload(module, NULL, &mcf, &errmsg); if (!mlm) { fprintf(stderr, "Failed to load crypto module: %s\n", errmsg); exit(EXIT_FAILURE); } + mdb_modsetup(env, mcf, password); } rc = mdb_env_open(env, argv[1], flags, 0600); } @@ -100,7 +101,7 @@ int main(int argc,char * argv[]) progname, act, rc, mdb_strerror(rc)); mdb_env_close(env); if (mlm) - mlm_unload(mlm); + mdb_modunload(mlm); return rc ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/libraries/liblmdb/mdb_drop.c b/libraries/liblmdb/mdb_drop.c index 54e91332f0..2707e7b0f4 100644 --- a/libraries/liblmdb/mdb_drop.c +++ b/libraries/liblmdb/mdb_drop.c @@ -19,7 +19,6 @@ #include #include #include "lmdb.h" -#include "module.h" static volatile sig_atomic_t gotsig; @@ -103,11 +102,13 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } if (module) { - mlm = mlm_setup(env, module, password, &errmsg); + MDB_crypto_funcs *mcf; + mlm = mdb_modload(module, NULL, &mcf, &errmsg); if (!mlm) { fprintf(stderr, "Failed to load crypto module: %s\n", errmsg); goto env_close; } + mdb_modsetup(env, mcf, password); } mdb_env_set_maxdbs(env, 2); @@ -148,7 +149,7 @@ txn_abort: env_close: mdb_env_close(env); if (mlm) - mlm_unload(mlm); + mdb_modunload(mlm); return rc ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/libraries/liblmdb/mdb_dump.c b/libraries/liblmdb/mdb_dump.c index a3af117e02..8ccd04833d 100644 --- a/libraries/liblmdb/mdb_dump.c +++ b/libraries/liblmdb/mdb_dump.c @@ -19,7 +19,6 @@ #include #include #include "lmdb.h" -#include "module.h" #define Yu MDB_PRIy(u) @@ -250,11 +249,13 @@ int main(int argc, char *argv[]) } if (module) { - mlm = mlm_setup(env, module, password, &errmsg); + MDB_crypto_funcs *mcf; + mlm = mdb_modload(module, NULL, &mcf, &errmsg); if (!mlm) { fprintf(stderr, "Failed to load crypto module: %s\n", errmsg); goto env_close; } + mdb_modsetup(env, mcf, password); } if (alldbs || subname) { @@ -327,7 +328,7 @@ txn_abort: env_close: mdb_env_close(env); if (mlm) - mlm_unload(mlm); + mdb_modunload(mlm); return rc ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/libraries/liblmdb/mdb_load.c b/libraries/liblmdb/mdb_load.c index 19dd272c57..337c12463a 100644 --- a/libraries/liblmdb/mdb_load.c +++ b/libraries/liblmdb/mdb_load.c @@ -18,7 +18,6 @@ #include #include #include "lmdb.h" -#include "module.h" #define PRINT 1 #define NOHDR 2 @@ -382,11 +381,13 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } if (module) { - mlm = mlm_setup(env, module, password, &errmsg); + MDB_crypto_funcs *mcf; + mlm = mdb_modload(module, NULL, &mcf, &errmsg); if (!mlm) { fprintf(stderr, "Failed to load crypto module: %s\n", errmsg); goto env_close; } + mdb_modsetup(env, mcf, password); } mdb_env_set_maxdbs(env, 2); @@ -526,7 +527,7 @@ txn_abort: env_close: mdb_env_close(env); if (mlm) - mlm_unload(mlm); + mdb_modunload(mlm); return rc ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/libraries/liblmdb/mdb_stat.c b/libraries/liblmdb/mdb_stat.c index caf519b341..9ae31861b8 100644 --- a/libraries/liblmdb/mdb_stat.c +++ b/libraries/liblmdb/mdb_stat.c @@ -16,7 +16,6 @@ #include #include #include "lmdb.h" -#include "module.h" #define Z MDB_FMT_Z #define Yu MDB_PRIy(u) @@ -119,11 +118,13 @@ int main(int argc, char *argv[]) } if (module) { - mlm = mlm_setup(env, module, password, &errmsg); + MDB_crypto_funcs *mcf; + mlm = mdb_modload(module, NULL, &mcf, &errmsg); if (!mlm) { fprintf(stderr, "Failed to load crypto module: %s\n", errmsg); goto env_close; } + mdb_modsetup(env, mcf, password); } if (alldbs || subname) { @@ -270,7 +271,7 @@ txn_abort: env_close: mdb_env_close(env); if (mlm) - mlm_unload(mlm); + mdb_modunload(mlm); return rc ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/libraries/liblmdb/mtest_enc2.c b/libraries/liblmdb/mtest_enc2.c index 853960ab52..ea144e3f0f 100644 --- a/libraries/liblmdb/mtest_enc2.c +++ b/libraries/liblmdb/mtest_enc2.c @@ -15,7 +15,6 @@ #include #include #include "lmdb.h" -#include "module.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) @@ -40,6 +39,7 @@ int main(int argc,char * argv[]) char password[] = "This is my passphrase for now..."; void *mlm; char *errmsg; + MDB_crypto_funcs *mcf; srand(time(NULL)); @@ -51,11 +51,12 @@ int main(int argc,char * argv[]) } E(mdb_env_create(&env)); - mlm = mlm_setup(env, "./crypto.lm", password, &errmsg); + mlm = mdb_modload("./crypto.lm", NULL, &mcf, &errmsg); if (!mlm) { fprintf(stderr,"Failed to load crypto module: %s\n", errmsg); exit(1); } + mdb_modsetup(env, mcf, password); E(mdb_env_set_maxreaders(env, 1)); E(mdb_env_set_mapsize(env, 10485760)); E(mdb_env_open(env, "./testdb", 0 /*|MDB_NOSYNC*/, 0664)); @@ -183,7 +184,7 @@ int main(int argc,char * argv[]) mdb_dbi_close(env, dbi); mdb_env_close(env); - mlm_unload(mlm); + mdb_modunload(mlm); return 0; }