Move the crypto module helpers into main liblmdb.

Just makes things easier than using the individual mdb_env_set APIs.
This commit is contained in:
Howard Chu 2024-10-16 22:47:42 +01:00
parent 1e7891c016
commit 14c7ff3347
9 changed files with 144 additions and 25 deletions

View file

@ -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

View file

@ -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

View file

@ -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 <windows.h>
#else
#include <dlfcn.h>
#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

View file

@ -21,7 +21,6 @@
#include <stdlib.h>
#include <signal.h>
#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;
}

View file

@ -19,7 +19,6 @@
#include <unistd.h>
#include <signal.h>
#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;
}

View file

@ -19,7 +19,6 @@
#include <unistd.h>
#include <signal.h>
#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;
}

View file

@ -18,7 +18,6 @@
#include <ctype.h>
#include <unistd.h>
#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;
}

View file

@ -16,7 +16,6 @@
#include <string.h>
#include <unistd.h>
#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;
}

View file

@ -15,7 +15,6 @@
#include <stdlib.h>
#include <time.h>
#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;
}