aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-08-25 17:52:43 +0000
committerlloyd <[email protected]>2010-08-25 17:52:43 +0000
commitd409bf8e3d7b50f61c19a0d05d3bdc364ff19f6e (patch)
tree404a88b470b5d1b6000bec9ddc9629be83103828
parent2114709a839a0663b177a5bd66aa5e77abdd3f11 (diff)
Add support for Windows-style dynamic loading with LoadLibrary. Not
yet tested.
-rw-r--r--src/build-data/os/windows.txt1
-rw-r--r--src/utils/dyn_load/dyn_load.cpp34
-rw-r--r--src/utils/dyn_load/dyn_load.h5
3 files changed, 32 insertions, 8 deletions
diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt
index 140eddeba..2f344e33c 100644
--- a/src/build-data/os/windows.txt
+++ b/src/build-data/os/windows.txt
@@ -14,6 +14,7 @@ install_cmd_exec "copy"
win32_virtual_lock
win32_get_systemtime
gmtime_s
+loadlibrary
</target_features>
<aliases>
diff --git a/src/utils/dyn_load/dyn_load.cpp b/src/utils/dyn_load/dyn_load.cpp
index 6d359bc01..5f3814778 100644
--- a/src/utils/dyn_load/dyn_load.cpp
+++ b/src/utils/dyn_load/dyn_load.cpp
@@ -11,10 +11,23 @@
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
#include <dlfcn.h>
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ #include <windows.h>
#endif
namespace Botan {
+namespace {
+
+void raise_runtime_loader_exception(const std::string& lib_name,
+ const char* msg)
+ {
+ throw std::runtime_error("Failed to load " + lib_name + ": " +
+ (msg ? msg : "Unknown error"));
+ }
+
+}
+
Dynamically_Loaded_Library::Dynamically_Loaded_Library(
const std::string& library) :
lib_name(library), lib(0)
@@ -23,22 +36,25 @@ Dynamically_Loaded_Library::Dynamically_Loaded_Library(
lib = ::dlopen(lib_name.c_str(), RTLD_LAZY);
if(!lib)
- {
- const char* dl_err = dlerror();
- if(!dl_err)
- dl_err = "Unknown error";
-
- throw std::runtime_error("Failed to load engine " + lib_name + ": " +
- dl_err);
- }
+ raise_runtime_loader_exception(lib_name, dlerror());
+
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ lib = ::LoadLibrary(lib_name.c_str());
+
+ if(!lib)
+ raise_runtime_loader_exception(lib_name, "LoadLibrary failed");
#endif
+ if(!lib)
+ raise_runtime_loader_exception(lib_name, "Dynamic load not supported");
}
Dynamically_Loaded_Library::~Dynamically_Loaded_Library()
{
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
::dlclose(lib);
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ ::FreeLibrary(lib);
#endif
}
@@ -48,6 +64,8 @@ void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol)
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
addr = ::dlsym(lib, symbol.c_str());
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ addr = ::GetProcAddress(lib, symbol.c_str());
#endif
if(!addr)
diff --git a/src/utils/dyn_load/dyn_load.h b/src/utils/dyn_load/dyn_load.h
index 56277d3e4..c8fb31cf0 100644
--- a/src/utils/dyn_load/dyn_load.h
+++ b/src/utils/dyn_load/dyn_load.h
@@ -18,6 +18,11 @@ class Dynamically_Loaded_Library
/**
* Load a DLL (or fail with an exception)
* @param lib_name name or path to a library
+ *
+ * If you don't use a full path, the search order will be defined
+ * by whatever the system linker does by default. Always using fully
+ * qualified pathnames can help prevent code injection attacks (eg
+ * via manipulation of LD_LIBRARY_PATH on Linux)
*/
Dynamically_Loaded_Library(const std::string& lib_name);