[cpp-sp] branch main updated: Copy in extension lib support from xmltooling.
Scott Cantor
cantor.2 at osu.edu
Tue Dec 3 14:57:44 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=71fc57ddae3d2f40002cd4c060a6baaf94264d68
The following commit(s) were added to refs/heads/main by this push:
new 71fc57dd Copy in extension lib support from xmltooling.
71fc57dd is described below
commit 71fc57ddae3d2f40002cd4c060a6baaf94264d68
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Dec 3 09:57:36 2024 -0500
Copy in extension lib support from xmltooling.
---
configure.ac | 9 +++++
shibsp.pc.in | 2 +-
shibsp/AgentConfig.h | 15 ++++++++
shibsp/impl/AgentConfig.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 771c93c0..d126a9c9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,15 @@ AC_CHECK_HEADERS([sys/socket.h], [AC_DEFINE([SHIBSP_HAVE_SYS_SOCKET_H],[1],[Defi
AC_CHECK_FUNCS([strchr strdup strstr timegm gmtime_r localtime_r strtok_r strcasecmp getpwnam getgrnam initgroups])
AC_CHECK_TYPES([struct sockaddr_storage], [], [], [[#include <sys/socket.h>]])
AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], [[#include <sys/socket.h>]])
+AC_CHECK_HEADERS([dlfcn.h])
+
+# Check for dlopen.
+AX_SAVE_FLAGS
+LIBS=""
+AC_SEARCH_LIBS([dlopen],[dl],,[AC_MSG_ERROR([cannot find dlopen() function])])
+AC_SUBST([dlopen_LIBS],[$LIBS])
+AX_RESTORE_FLAGS
+
AC_CACHE_CHECK([for SOCK_CLOEXEC support], [shib_cv_sock_cloexec],
[AC_TRY_RUN([
diff --git a/shibsp.pc.in b/shibsp.pc.in
index 2c718bb1..1d1c25d1 100644
--- a/shibsp.pc.in
+++ b/shibsp.pc.in
@@ -7,7 +7,7 @@ Name: @PACKAGE_NAME@
Description: Shibboleth Service Provider library
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lshibsp
-Libs.private: @PTHREAD_LIBS@
+Libs.private: @dlopen_LIBS @PTHREAD_LIBS@
Cflags: -I${includedir} @BOOST_CPPFLAGS@ @PTHREAD_CFLAGS@
Requires: @SHIBSP_REQUIRES@
Requires.private: @SHIBSP_REQUIRES_PRIVATE@
diff --git a/shibsp/AgentConfig.h b/shibsp/AgentConfig.h
index 845987ca..f4dbff24 100644
--- a/shibsp/AgentConfig.h
+++ b/shibsp/AgentConfig.h
@@ -76,6 +76,21 @@ namespace shibsp {
*/
virtual void term()=0;
+ /**
+ * Loads a shared/dynamic library extension.
+ *
+ * <p>Extension libraries are managed using a pair of "C" linkage functions:<br>
+ * extern "C" int shibsp_extension_init(void* context);<br>
+ * extern "C" void shibsp_extension_term();
+ *
+ * <p>This method is internally synchronized.</p>
+ *
+ * @param path pathname of shared library to load into process
+ * @param context arbitrary data to pass to library initialization hook
+ * @return true iff library was loaded successfully
+ */
+ virtual bool load_library(const char* path, void* context=nullptr)=0;
+
/**
* Manages factories for LoggingService plugins.
*/
diff --git a/shibsp/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index beab11aa..89c33f42 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -30,9 +30,14 @@
#include <ctime>
#include <stdexcept>
#include <thread>
+#include <vector>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
using namespace shibsp;
using namespace xmltooling;
using namespace boost::property_tree;
@@ -48,6 +53,7 @@ namespace shibsp {
bool init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false);
void term();
+ bool load_library(const char* path, void* context=nullptr);
const PathResolver& getPathResolver() const {
return m_pathResolver;
@@ -71,6 +77,7 @@ namespace shibsp {
ptree m_config;
PathResolver m_pathResolver;
URLEncoder m_urlEncoder;
+ vector<void*> m_libhandles;
unique_ptr<LoggingService> m_logging;
//unique_ptr<Agent> m_agent;
};
@@ -278,6 +285,23 @@ void AgentInternalConfig::_term()
LoggingServiceManager.deregisterFactories();
+ for (vector<void*>::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) {
+#if defined(WIN32)
+ FARPROC fn=GetProcAddress(static_cast<HMODULE>(*i),"xmltooling_extension_term");
+ if (fn)
+ fn();
+ FreeLibrary(static_cast<HMODULE>(*i));
+#elif defined(HAVE_DLFCN_H)
+ void (*fn)()=(void (*)())dlsym(*i,"shibsp_extension_term");
+ if (fn)
+ fn();
+ dlclose(*i);
+#else
+# error "Don't know about dynamic loading on this platform!"
+#endif
+ }
+ m_libhandles.clear();
+
log.info("%s agent shutdown complete", PACKAGE_STRING);
m_logging->term();
@@ -311,3 +335,71 @@ void AgentInternalConfig::_term()
SessionCacheManager.deregisterFactories();
*/
}
+
+bool AgentInternalConfig::load_library(const char* path, void* context)
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("LoadLibrary");
+#endif
+ Category& log=Category::getInstance(SHIBSP_LOGCAT ".Config");
+ log.info("loading extension: %s", path);
+
+ lock_guard<mutex> locker(m_lock);
+
+ string resolved(path);
+ m_pathResolver.resolve(resolved, PathResolver::SHIBSP_LIB_FILE);
+
+#if defined(WIN32)
+ HMODULE handle=nullptr;
+ for (string::iterator i = resolved.begin(); i != resolved.end(); ++i)
+ if (*i == '/')
+ *i = '\\';
+
+ UINT em=SetErrorMode(SEM_FAILCRITICALERRORS);
+ try {
+ handle=LoadLibraryEx(resolved.c_str(),nullptr,LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (!handle)
+ handle=LoadLibraryEx(resolved.c_str(),nullptr,0);
+ if (!handle)
+ throw runtime_error(string("unable to load extension library: ") + resolved);
+ FARPROC fn=GetProcAddress(handle,"shibsp_extension_init");
+ if (!fn)
+ throw runtime_error(string("unable to locate shibsp_extension_init entry point: ") + resolved);
+ if (reinterpret_cast<int(*)(void*)>(fn)(context)!=0)
+ throw runtime_error(string("detected error in shibsp_extension_init: ") + resolved);
+ SetErrorMode(em);
+ }
+ catch(std::exception&) {
+ if (handle)
+ FreeLibrary(handle);
+ SetErrorMode(em);
+ throw;
+ }
+#elif defined(HAVE_DLFCN_H)
+ void* handle=dlopen(resolved.c_str(),RTLD_LAZY);
+ if (!handle)
+ throw runtime_error(string("unable to load extension library '") + resolved + "': " + dlerror());
+ int (*fn)(void*)=(int (*)(void*))(dlsym(handle,"shibsp_extension_init"));
+ if (!fn) {
+ dlclose(handle);
+ throw runtime_error(
+ string("unable to locate shibsp_extension_init entry point in '") + resolved + "': " +
+ (dlerror() ? dlerror() : "unknown error")
+ );
+ }
+ try {
+ if (fn(context)!=0)
+ throw runtime_error(string("detected error in shibsp_extension_init in ") + resolved);
+ }
+ catch(std::exception&) {
+ if (handle)
+ dlclose(handle);
+ throw;
+ }
+#else
+# error "Don't know about dynamic loading on this platform!"
+#endif
+ m_libhandles.push_back(handle);
+ log.info("loaded extension: %s", resolved.c_str());
+ return true;
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list