diff options
author | lloyd <[email protected]> | 2010-08-25 17:52:43 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-08-25 17:52:43 +0000 |
commit | d409bf8e3d7b50f61c19a0d05d3bdc364ff19f6e (patch) | |
tree | 404a88b470b5d1b6000bec9ddc9629be83103828 | |
parent | 2114709a839a0663b177a5bd66aa5e77abdd3f11 (diff) |
Add support for Windows-style dynamic loading with LoadLibrary. Not
yet tested.
-rw-r--r-- | src/build-data/os/windows.txt | 1 | ||||
-rw-r--r-- | src/utils/dyn_load/dyn_load.cpp | 34 | ||||
-rw-r--r-- | src/utils/dyn_load/dyn_load.h | 5 |
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); |