[cpp-sp] branch main updated: Start adjusting (and reverting) some SessionCache APIs.
Scott Cantor
cantor.2 at osu.edu
Wed Apr 16 19:23:54 UTC 2025
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=520667cd11b7f4145535f37cde7600b0e9f10534
The following commit(s) were added to refs/heads/main by this push:
new 520667cd Start adjusting (and reverting) some SessionCache APIs.
520667cd is described below
commit 520667cd11b7f4145535f37cde7600b0e9f10534
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Apr 16 15:23:45 2025 -0400
Start adjusting (and reverting) some SessionCache APIs.
---
Projects/vc22/shibsp.vcxproj | 3 +-
Projects/vc22/shibsp.vcxproj.filters | 5 ++-
apache/mod_shib_24.cpp | 18 ++++++---
shibsp/Agent.cpp | 30 +++-----------
shibsp/AgentConfig.h | 13 +++++-
shibsp/Makefile.am | 1 +
shibsp/handler/impl/SessionHandler.cpp | 48 ----------------------
shibsp/handler/impl/SessionInitiator.cpp | 1 +
shibsp/impl/AgentConfig.cpp | 10 +++++
shibsp/impl/XMLAccessControl.cpp | 28 ++++++-------
shibsp/session/AbstractSessionCache.h | 35 ++++++++++++++++
shibsp/session/SessionCache.h | 56 +++++---------------------
shibsp/session/impl/AbstractSessionCache.cpp | 14 ++++++-
shibsp/session/impl/FilesystemSessionCache.cpp | 4 +-
14 files changed, 119 insertions(+), 147 deletions(-)
diff --git a/Projects/vc22/shibsp.vcxproj b/Projects/vc22/shibsp.vcxproj
index dcc64a78..4d286c22 100644
--- a/Projects/vc22/shibsp.vcxproj
+++ b/Projects/vc22/shibsp.vcxproj
@@ -66,6 +66,7 @@
<ClInclude Include="..\..\shibsp\remoting\RemotingService.h" />
<ClInclude Include="..\..\shibsp\remoting\SecretSource.h" />
<ClInclude Include="..\..\shibsp\RequestMapper.h" />
+ <ClInclude Include="..\..\shibsp\session\AbstractSessionCache.h" />
<ClInclude Include="..\..\shibsp\session\SessionCache.h" />
<ClInclude Include="..\..\shibsp\SPRequest.h" />
<ClInclude Include="..\..\shibsp\util\BoostPropertySet.h" />
@@ -453,4 +454,4 @@ rc.exe /D _UNICODE /D UNICODE /l"0x0409" /nologo /fo"$(IntDir)\%(Filename).res"
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/Projects/vc22/shibsp.vcxproj.filters b/Projects/vc22/shibsp.vcxproj.filters
index 97a42443..42830301 100644
--- a/Projects/vc22/shibsp.vcxproj.filters
+++ b/Projects/vc22/shibsp.vcxproj.filters
@@ -228,6 +228,9 @@
<ClInclude Include="..\..\shibsp\session\SessionCache.h">
<Filter>Header Files\Session</Filter>
</ClInclude>
+ <ClInclude Include="..\..\shibsp\session\AbstractSessionCache.h">
+ <Filter>Header Files\Session</Filter>
+ </ClInclude>
<ClInclude Include="..\..\shibsp\remoting\SecretSource.h">
<Filter>Header Files\Remoting</Filter>
</ClInclude>
@@ -409,4 +412,4 @@
<Filter>Resource Files</Filter>
</CustomBuild>
</ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/apache/mod_shib_24.cpp b/apache/mod_shib_24.cpp
index 199c2c5e..08b7bd8b 100644
--- a/apache/mod_shib_24.cpp
+++ b/apache/mod_shib_24.cpp
@@ -1281,7 +1281,9 @@ extern "C" authz_status shib_acclass_check_authz(request_rec* r, const char* req
try {
Session* session = sta.first->getSession(false, true, false);
lock_guard<Session> slocker(*session, adopt_lock);
- if (session && hta.doAuthnContext(*sta.first, session->getAuthnContextClassRef(), require_line) == AccessControl::shib_acl_true)
+ if (session && hta.doShibAttr(*sta.first, session,
+ sta.first->getAgent().getString("legacy-classref-attribute", "Shib-AuthnContext-Class"),
+ require_line) == AccessControl::shib_acl_true)
return AUTHZ_GRANTED;
return session ? AUTHZ_DENIED : AUTHZ_DENIED_NO_USER;
}
@@ -1442,10 +1444,8 @@ apr_status_t shib_post_config(apr_pool_t* p, apr_pool_t*, apr_pool_t*, server_re
/*
* shib_child_init()
- * Things to do when the child process is initialized.
- * For now, we have no background threads, but if we introduce any, we'd have to switch
- * back to deferring their creation until this step because only the forking thread shows
- * up in the child, losing any internal threads spun up by plugins in the agent library.
+
+ * Things to do when the child process is initialized.
*/
extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
{
@@ -1466,7 +1466,13 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
// Set the cleanup handler, passing in the server_rec for logging.
apr_pool_cleanup_register(p, s, &shib_exit, apr_pool_cleanup_null);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, s, "child_init: shib_module config initialized");
+ if (g_Config->start()) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, s, "child_init: shib_module config initialized");
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, "child_init: shib_module start method failed");
+ }
+
}
// Output filters
diff --git a/shibsp/Agent.cpp b/shibsp/Agent.cpp
index 079fc08f..23a788b2 100644
--- a/shibsp/Agent.cpp
+++ b/shibsp/Agent.cpp
@@ -484,33 +484,13 @@ pair<bool,long> Agent::doExport(SPRequest& request, bool requireSession) const
}
request.setHeader("Shib-Session-ID", session->getID());
- request.setHeader("Shib-Bucket-ID", session->getBucketID());
+ request.setHeader("Shib-Application-ID", session->getApplicationID());
// Check for export of "standard" variables.
- bool stdvars = settings.first->getBool("exportStdVars", false);
- if (stdvars) {
- const char* hval = session->getEntityID();
- if (hval) {
- request.setHeader("Shib-Identity-Provider", hval);
- }
- time_t ts = session->getAuthnInstant();
- if (ts > 0) {
- // TODO: Need to see what the output format of this really is.
- ostringstream os;
- os << date::format("%FT%TZ", chrono::system_clock::from_time_t(ts));
- request.setHeader("Shib-Authentication-Instant", os.str().c_str());
- }
- hval = session->getAuthnContextClassRef();
- if (hval) {
- request.setHeader("Shib-Authentication-Method", hval);
- request.setHeader("Shib-AuthnContext-Class", hval);
- }
-
- request.setHeader( "Shib-Session-Expires", boost::lexical_cast<string>(session->getExpiration()).c_str());
- unsigned int timeout = settings.first->getUnsignedInt("timeout", 3600);
- if (timeout > 0) {
- request.setHeader( "Shib-Session-Inactivity", boost::lexical_cast<string>(session->getLastAccess() + timeout).c_str());
- }
+ request.setHeader( "Shib-Session-Expires", boost::lexical_cast<string>(session->getExpiration()).c_str());
+ unsigned int timeout = settings.first->getUnsignedInt("timeout", 3600);
+ if (timeout > 0) {
+ request.setHeader( "Shib-Session-Inactivity", boost::lexical_cast<string>(session->getLastAccess() + timeout).c_str());
}
// Check for export of algorithmically-derived portion of cookie names.
diff --git a/shibsp/AgentConfig.h b/shibsp/AgentConfig.h
index 367261ef..d80ff911 100644
--- a/shibsp/AgentConfig.h
+++ b/shibsp/AgentConfig.h
@@ -72,8 +72,8 @@ namespace shibsp {
/**
* Initializes agent/library.
*
- * Each process using the library MUST call this function exactly once
- * before using any library classes.
+ * <p>Each process using the library MUST call this function exactly once
+ * before using any library classes.</p>
*
* @param catalog_path delimited set of schema catalog files to load
* @param inst_prefix installation prefix for software
@@ -81,6 +81,15 @@ namespace shibsp {
*/
virtual bool init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false)=0;
+ /**
+ * Tells the agent it may start background threads or tasks.
+ *
+ * <p>Should only be called once per child process but the implememntation will
+ * ensure that subsequent calls are ignored. Must be called only after init()
+ * is successful, failure to do so resulting in unspecified behavior.</p>
+ */
+ virtual bool start()=0;
+
/**
* Shuts down agent/library
*
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index b868e719..1bb36701 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -70,6 +70,7 @@ reminclude_HEADERS = \
remoting/SecretSource.h
sessioninclude_HEADERS = \
+ session/AbstractSessionCache.h \
session/SessionCache.h
utilinclude_HEADERS = \
diff --git a/shibsp/handler/impl/SessionHandler.cpp b/shibsp/handler/impl/SessionHandler.cpp
index dddede3f..57feedb2 100644
--- a/shibsp/handler/impl/SessionHandler.cpp
+++ b/shibsp/handler/impl/SessionHandler.cpp
@@ -156,38 +156,6 @@ pair<bool,long> SessionHandler::doJSON(SPRequest& request) const
else
s << 0;
- if (session->getClientAddress()) {
- s << ", \"client_address\": ";
- json_safe(s, session->getClientAddress());
- }
-
- if (session->getProtocol()) {
- s << ", \"protocol\": ";
- json_safe(s, session->getProtocol());
- }
-
- bool stdvars = request.getRequestSettings().first->getBool("exportStdVars", true);
- if (stdvars) {
- if (session->getEntityID()) {
- s << ", \"identity_provider\": ";
- json_safe(s, session->getEntityID());
- }
-
- if (session->getAuthnInstant()) {
- s << ", \"authn_instant\": ";
- time_t ts = session->getAuthnInstant();
- // TODO: Need to see what the output format of this really is.
- ostringstream os;
- os << date::format("%FT%TZ", chrono::system_clock::from_time_t(ts));
- json_safe(s, os.str().c_str());
- }
-
- if (session->getAuthnContextClassRef()) {
- s << ", \"authncontext_class\": ";
- json_safe(s, session->getAuthnContextClassRef());
- }
- }
-
/*
attributes: [ { "name": "foo", "values" : count } ]
@@ -274,22 +242,6 @@ pair<bool,long> SessionHandler::doHTML(SPRequest& request) const
else
s << "Infinite" << endl;
- s << "<strong>Client Address:</strong> " << (session->getClientAddress() ? session->getClientAddress() : "(none)") << endl;
- s << "<strong>SSO Protocol:</strong> " << (session->getProtocol() ? session->getProtocol() : "(none)") << endl;
-
- bool stdvars = request.getRequestSettings().first->getBool("exportStdVars", true);
- if (stdvars) {
- s << "<strong>Identity Provider:</strong> " << (session->getEntityID() ? session->getEntityID() : "(none)") << endl;
- time_t ts = session->getAuthnInstant();
- if (ts > 0) {
- // TODO: Need to see what the output format of this really is.
- ostringstream os;
- os << date::format("%FT%TZ", chrono::system_clock::from_time_t(ts));
- s << "<strong>Authentication Time:</strong> " << os.str() << endl;
- }
- s << "<strong>Authentication Context Class:</strong> " << (session->getAuthnContextClassRef() ? session->getAuthnContextClassRef() : "(none)") << endl;
- }
-
s << endl << "<u>Attributes</u>" << endl;
string key;
diff --git a/shibsp/handler/impl/SessionInitiator.cpp b/shibsp/handler/impl/SessionInitiator.cpp
index 313d6ce0..d049b0ea 100644
--- a/shibsp/handler/impl/SessionInitiator.cpp
+++ b/shibsp/handler/impl/SessionInitiator.cpp
@@ -106,6 +106,7 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
}
else {
// target will come from query string, map, or handler or fall back to this request.
+ // TODO: shouldm't this fall back to homeURL?
target = getString("target", request, request.getRequestURL());
// handler is derived from the target resource.
handlerBaseURL = request.getHandlerURL(target.c_str());
diff --git a/shibsp/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index 3ae0dcb6..6cfbeffb 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -68,6 +68,9 @@ namespace shibsp {
}
bool init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false);
+ bool start() {
+ call_once(m_startonce, &AgentInternalConfig::_start, this);
+ }
void term();
const PathResolver& getPathResolver() const {
@@ -83,6 +86,7 @@ namespace shibsp {
private:
bool _init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false);
+ bool _start();
void _term();
bool initLogging();
@@ -90,6 +94,7 @@ namespace shibsp {
void loadExtensions(Category& log);
unsigned int m_initCount;
+ once_flag m_startonce;
mutex m_lock;
ptree m_config;
bool m_cli;
@@ -307,6 +312,11 @@ void AgentInternalConfig::term()
_term();
}
+bool AgentInternalConfig::_start()
+{
+ return true;
+}
+
void AgentInternalConfig::_term()
{
Category& log=Category::getInstance(SHIBSP_LOGCAT ".AgentConfig");
diff --git a/shibsp/impl/XMLAccessControl.cpp b/shibsp/impl/XMLAccessControl.cpp
index 380b1cc2..bdf78628 100644
--- a/shibsp/impl/XMLAccessControl.cpp
+++ b/shibsp/impl/XMLAccessControl.cpp
@@ -22,6 +22,7 @@
#include "exceptions.h"
#include "AccessControl.h"
+#include "Agent.h"
#include "SPRequest.h"
#include "attribute/Attribute.h"
#include "logging/Category.h"
@@ -166,6 +167,8 @@ AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Sess
// We can make this more complex later using pluggable comparison functions,
// but for now, just a straight port to the new Attribute API.
+ string actual_alias(m_alias);
+
// Map alias in rule to the attribute.
if (!session) {
request.log(Priority::SHIB_WARN, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");
@@ -187,23 +190,18 @@ AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Sess
return shib_acl_false;
}
else if (m_alias == "authnContextClassRef") {
- const char* ref = session->getAuthnContextClassRef();
- if (ref && m_vals.find(ref) != m_vals.end()) {
- request.log(Priority::SHIB_DEBUG, string("AccessControl rule expecting authnContextClassRef (") + ref + "), authz granted");
- return shib_acl_true;
- }
- return shib_acl_false;
+ actual_alias = request.getAgent().getString("legacy-classref-attribute", "Shib-AuthnContext-Class");
}
// Find the attribute(s) matching the require rule.
pair<multimap<string,const Attribute*>::const_iterator, multimap<string,const Attribute*>::const_iterator> attrs =
- session->getIndexedAttributes().equal_range(m_alias);
+ session->getIndexedAttributes().equal_range(actual_alias);
if (attrs.first == attrs.second) {
- request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + m_alias + "), not found in session");
+ request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + actual_alias + "), not found in session");
return shib_acl_false;
}
else if (m_vals.empty()) {
- request.log(Priority::SHIB_DEBUG, string("AccessControl rule requires presence of attribute (") + m_alias + "), authz granted");
+ request.log(Priority::SHIB_DEBUG, string("AccessControl rule requires presence of attribute (") + actual_alias + "), authz granted");
return shib_acl_true;
}
@@ -251,6 +249,8 @@ AccessControl::aclresult_t RuleRegex::authorized(const SPRequest& request, const
static regexp::regex_constants::match_flag_type match_flags = regexp::regex_constants::match_any | regexp::regex_constants::match_not_null;
+ string actual_alias(m_alias);
+
if (!session) {
request.log(Priority::SHIB_WARN, "AccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");
return shib_acl_false;
@@ -272,17 +272,13 @@ AccessControl::aclresult_t RuleRegex::authorized(const SPRequest& request, const
return shib_acl_false;
}
else if (m_alias == "authnContextClassRef") {
- if (session->getAuthnContextClassRef() && regexp::regex_match(session->getAuthnContextClassRef(), m_re, match_flags)) {
- request.log(Priority::SHIB_DEBUG, string("AccessControl rule expecting authnContextClassRef regex (") + m_exp + "), authz granted");
- return shib_acl_true;
- }
- return shib_acl_false;
+ actual_alias = request.getAgent().getString("legacy-classref-attribute", "Shib-AuthnContext-Class");
}
// Find the attribute(s) matching the require rule.
- auto attrs = session->getIndexedAttributes().equal_range(m_alias);
+ auto attrs = session->getIndexedAttributes().equal_range(actual_alias);
if (attrs.first == attrs.second) {
- request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + m_alias + "), not found in session");
+ request.log(Priority::SHIB_WARN, string("AccessControl rule requires attribute (") + actual_alias + "), not found in session");
return shib_acl_false;
}
diff --git a/shibsp/session/AbstractSessionCache.h b/shibsp/session/AbstractSessionCache.h
new file mode 100644
index 00000000..3e2d0f5f
--- /dev/null
+++ b/shibsp/session/AbstractSessionCache.h
@@ -0,0 +1,35 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file session/AbstractSessionCache.h
+ *
+ * Base class for SessionCache implementations.
+ */
+
+#include <session/SessionCache.h>
+
+namespace shibsp {
+
+ class SHIBSP_API AbstractSessionCache : public virtual SessionCache {
+ protected:
+ /** Constructor. */
+ AbstractSessionCache();
+ virtual ~AbstractSessionCache();
+
+ public:
+ bool start();
+ };
+
+};
diff --git a/shibsp/session/SessionCache.h b/shibsp/session/SessionCache.h
index 916ec84f..769402f8 100644
--- a/shibsp/session/SessionCache.h
+++ b/shibsp/session/SessionCache.h
@@ -36,11 +36,6 @@ namespace shibsp {
/**
* Encapsulates access to a user's security session.
- *
- * <p>The SessionCache does not itself require locking to manage
- * concurrency, but access to each Session is generally exclusive
- * or at least controlled, and the caller must unlock a Session
- * to dispose of it.</p>
*/
class SHIBSP_API Session : public virtual BasicLockable
{
@@ -57,12 +52,12 @@ namespace shibsp {
virtual const char* getID() const=0;
/**
- * Returns the session's "bucket" ID, i.e., a value separating sessions into
+ * Returns the session's "application" ID, i.e., a value separating sessions into
* specific buckets based on resources.
*
- * @return unique ID of session bucket
+ * @return unique ID of application/bucket
*/
- virtual const char* getBucketID() const=0;
+ virtual const char* getApplicationID() const=0;
/**
* Returns the session expiration.
@@ -78,43 +73,6 @@ namespace shibsp {
*/
virtual time_t getLastAccess() const=0;
- /**
- * Returns the address of the client associated with the session.
- *
- * @return the client's network address
- */
- virtual const char* getClientAddress() const=0;
-
- /**
- * Returns the entityID of the IdP that initiated the session.
- *
- * @return the IdP's entityID
- */
- virtual const char* getEntityID() const=0;
-
- /**
- * Returns the protocol family used to initiate the session.
- *
- * @return the protocol constant that represents the general SSO protocol used
- */
- virtual const char* getProtocol() const=0;
-
- /**
- * Returns the timestamp of the authentication event at the IdP.
- *
- * @return the authentication timestamp
- */
- virtual time_t getAuthnInstant() const=0;
-
- /**
- * Returns a URI containing an AuthnContextClassRef provided with the session.
- *
- * <p>SAML 1.x AuthenticationMethods will be returned as class references.</p>
- *
- * @return a URI identifying the authentication context class
- */
- virtual const char* getAuthnContextClassRef() const=0;
-
/**
* Returns the resolved attributes associated with the session.
*
@@ -147,6 +105,14 @@ namespace shibsp {
public:
virtual ~SessionCache();
+ /**
+ * Signals the implementation it may start any background tasks or do any
+ * additional once-per-process work.
+ *
+ * <p>This method is guaranteed to be called only once per process.</p>
+ */
+ virtual bool start()=0;
+
#ifndef SHIBSP_LITE
/**
* Inserts a new session into the cache and binds the session to the outgoing
diff --git a/shibsp/session/impl/AbstractSessionCache.cpp b/shibsp/session/impl/AbstractSessionCache.cpp
index 3a012c11..ee9ca01d 100644
--- a/shibsp/session/impl/AbstractSessionCache.cpp
+++ b/shibsp/session/impl/AbstractSessionCache.cpp
@@ -21,7 +21,7 @@
#include "internal.h"
#include "exceptions.h"
#include "AgentConfig.h"
-#include "session/SessionCache.h"
+#include "session/AbstractSessionCache.h"
#include "logging/Category.h"
#include <boost/property_tree/ptree.hpp>
@@ -56,3 +56,15 @@ SessionCache::SessionCache()
SessionCache::~SessionCache()
{
}
+
+AbstractSessionCache::AbstractSessionCache()
+{
+}
+
+AbstractSessionCache::~AbstractSessionCache()
+{
+}
+
+bool AbstractSessionCache::start()
+{
+}
diff --git a/shibsp/session/impl/FilesystemSessionCache.cpp b/shibsp/session/impl/FilesystemSessionCache.cpp
index 8874f749..c2932274 100644
--- a/shibsp/session/impl/FilesystemSessionCache.cpp
+++ b/shibsp/session/impl/FilesystemSessionCache.cpp
@@ -20,7 +20,7 @@
#include "internal.h"
#include "exceptions.h"
-#include "session/SessionCache.h"
+#include "session/AbstractSessionCache.h"
#include "logging/Category.h"
#include <boost/property_tree/ptree.hpp>
@@ -30,7 +30,7 @@ using namespace boost::property_tree;
using namespace std;
namespace {
- class FilesystemSessionCache : public virtual SessionCache {
+ class FilesystemSessionCache : public virtual AbstractSessionCache {
public:
FilesystemSessionCache(const ptree& pt);
~FilesystemSessionCache();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list