Just makes things easier than using the individual mdb_env_set APIs.
# $(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
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
* @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
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
#include <stdlib.h>
#include <signal.h>
#include "lmdb.h"
-#include "module.h"
static void
sighandle(int sig)
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);
}
progname, act, rc, mdb_strerror(rc));
mdb_env_close(env);
if (mlm)
- mlm_unload(mlm);
+ mdb_modunload(mlm);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
#include <unistd.h>
#include <signal.h>
#include "lmdb.h"
-#include "module.h"
static volatile sig_atomic_t gotsig;
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);
env_close:
mdb_env_close(env);
if (mlm)
- mlm_unload(mlm);
+ mdb_modunload(mlm);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
#include <unistd.h>
#include <signal.h>
#include "lmdb.h"
-#include "module.h"
#define Yu MDB_PRIy(u)
}
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) {
env_close:
mdb_env_close(env);
if (mlm)
- mlm_unload(mlm);
+ mdb_modunload(mlm);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
#include <ctype.h>
#include <unistd.h>
#include "lmdb.h"
-#include "module.h"
#define PRINT 1
#define NOHDR 2
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);
env_close:
mdb_env_close(env);
if (mlm)
- mlm_unload(mlm);
+ mdb_modunload(mlm);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
#include <string.h>
#include <unistd.h>
#include "lmdb.h"
-#include "module.h"
#define Z MDB_FMT_Z
#define Yu MDB_PRIy(u)
}
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) {
env_close:
mdb_env_close(env);
if (mlm)
- mlm_unload(mlm);
+ mdb_modunload(mlm);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}
#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))
char password[] = "This is my passphrase for now...";
void *mlm;
char *errmsg;
+ MDB_crypto_funcs *mcf;
srand(time(NULL));
}
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));
mdb_dbi_close(env, dbi);
mdb_env_close(env);
- mlm_unload(mlm);
+ mdb_modunload(mlm);
return 0;
}