[cpp-sp] branch main updated: Implement fuzzy address matching for sessions.
Scott Cantor
cantor.2 at osu.edu
Tue Sep 16 20:15:11 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=cbd25269a0613916d83632ed49a9176777b43c4c
The following commit(s) were added to refs/heads/main by this push:
new cbd25269 Implement fuzzy address matching for sessions.
cbd25269 is described below
commit cbd25269a0613916d83632ed49a9176777b43c4c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Sep 16 16:15:02 2025 -0400
Implement fuzzy address matching for sessions.
---
shibsp/session/AbstractSessionCache.h | 30 +++++++++++++++++++-
shibsp/session/impl/AbstractSessionCache.cpp | 39 ++++++++++++++++++++++++--
shibsp/session/impl/FilesystemSessionCache.cpp | 5 ++--
shibsp/session/impl/MemorySessionCache.cpp | 5 ++--
4 files changed, 70 insertions(+), 9 deletions(-)
diff --git a/shibsp/session/AbstractSessionCache.h b/shibsp/session/AbstractSessionCache.h
index b73529ae..4fecf852 100644
--- a/shibsp/session/AbstractSessionCache.h
+++ b/shibsp/session/AbstractSessionCache.h
@@ -28,11 +28,14 @@
#include <util/BoostPropertySet.h>
#include <condition_variable>
+#include <memory>
#include <mutex>
#ifdef HAVE_CXX14
# include <shared_mutex>
#endif
#include <thread>
+#include <vector>
+
#include <boost/property_tree/ptree_fwd.hpp>
namespace shibsp {
@@ -40,6 +43,7 @@ namespace shibsp {
class SHIBSP_API AbstractSessionCache;
class SHIBSP_API Attribute;
class SHIBSP_API CookieManager;
+ class SHIBSP_API IPRange;
#if defined (_MSC_VER)
#pragma warning( push )
@@ -137,8 +141,31 @@ namespace shibsp {
static bool isSessionDataValid(DDF& sessionData);
protected:
- // Classifies addresses for unique binding to each family.
+ /**
+ * Compares two addresses, allowing for the unreliableNetworks fuzzy match option.
+ *
+ * @param one first address
+ * @param two second address
+ *
+ * @return true iff the addresses are "equivalent" for session purposes
+ */
+ bool isAddressMatch(const char* one, const char* two) const;
+
+ /**
+ * Returns a string signifying the network address family of the input address.
+ *
+ * @param addr address to evaluate
+ *
+ * @return the address family (or a default value, so null is never returned)
+ */
static const char* getAddressFamily(const std::string& addr);
+
+ /**
+ * Generates version-specific filenames and cookie values by modifying a string in place.
+ *
+ * @param path base string to append version to
+ * @param version version to append
+ */
static void computeVersionedFilename(std::string& path, unsigned int version);
private:
@@ -168,6 +195,7 @@ namespace shibsp {
#endif
std::map<std::string,std::unique_ptr<BasicSession>> m_hashtable;
std::unique_ptr<CookieManager> m_cookieManager;
+ std::vector<IPRange> m_unreliableNetworks;
std::condition_variable m_shutdown_wait;
std::thread m_cleanup_thread;
std::string m_issuerAttribute;
diff --git a/shibsp/session/impl/AbstractSessionCache.cpp b/shibsp/session/impl/AbstractSessionCache.cpp
index ab21f06f..5aa2c344 100644
--- a/shibsp/session/impl/AbstractSessionCache.cpp
+++ b/shibsp/session/impl/AbstractSessionCache.cpp
@@ -28,6 +28,8 @@
#include "logging/Category.h"
#include "session/AbstractSessionCache.h"
#include "util/Date.h"
+#include "util/IPRange.h"
+#include "util/Misc.h"
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
@@ -55,6 +57,7 @@ static const char CLEANUP_INTERVAL_PROP_NAME[] = "cleanupInterval";
static const char STORAGE_ACCESS_INTERVAL_PROP_NAME[] = "storageAccessInterval";
static const char INPROC_TIMEOUT_PROP_NAME[] = "inprocTimeout";
static const char ISSUER_ATTRIBUTE_PROP_NAME[] = "issuerAttribute";
+static const char UNRELIABLE_NETWORKS_PROP_NAME[] = "unreliableNetworks";
static const char COOKIE_NAME_PROP_NAME[] = "cookieName";
static const char COOKIE_SECURE_PROP_NAME[] = "cookieSecure";
static const char COOKIE_HTTPONLY_PROP_NAME[] = "cookieHttpOnly";
@@ -205,6 +208,20 @@ AbstractSessionCache::AbstractSessionCache(const ptree& pt)
m_cookieManager->setMaxAge(getInt(COOKIE_MAXAGE_PROP_NAME, COOKIE_MAXAGE_PROP_DEFAULT));
m_cookieManager->setDomain(getString(COOKIE_DOMAIN_PROP_NAME));
m_cookieManager->setSameSite(getString(COOKIE_SAMESITE_PROP_NAME));
+
+ const char* unreliableNetworks = getString(UNRELIABLE_NETWORKS_PROP_NAME);
+ if (unreliableNetworks) {
+ vector<string> tokenized;
+ split_to_container(tokenized, unreliableNetworks);
+ for (const string& s : tokenized) {
+ try {
+ m_unreliableNetworks.push_back(IPRange::parseCIDRBlock(s.c_str()));
+ }
+ catch (const ConfigurationException& e) {
+ m_log.error("error parsing CIDR expressioon (%s): %s", s.c_str(), e.what());
+ }
+ }
+ }
}
AbstractSessionCache::~AbstractSessionCache()
@@ -251,6 +268,25 @@ const char* AbstractSessionCache::getAddressFamily(const std::string& addr)
return "4";
}
+bool AbstractSessionCache::isAddressMatch(const char* one, const char* two) const
+{
+ if (!one || !two) {
+ return false;
+ }
+
+ if (!strcmp(one, two)) {
+ return true;
+ }
+
+ for (const IPRange& cidr : m_unreliableNetworks) {
+ if (cidr.contains(one) && cidr.contains(two)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void AbstractSessionCache::computeVersionedFilename(string& path, unsigned int version)
{
try {
@@ -457,8 +493,7 @@ unique_lock<Session> AbstractSessionCache::_find(
const char* family = AbstractSessionCache::getAddressFamily(client_addr);
const char* bound_addr = dynamic_cast<BasicSession*>(session.mutex())->getClientAddress(family);
if (bound_addr) {
- // TODO: Implement the fuzzy address matching
- if (strcmp(client_addr, bound_addr)) {
+ if (!isAddressMatch(client_addr, bound_addr)) {
m_log.warn("session (%s) access invalid, bound to (%s), accessed from (%s)", key, bound_addr, client_addr);
session.unlock();
}
diff --git a/shibsp/session/impl/FilesystemSessionCache.cpp b/shibsp/session/impl/FilesystemSessionCache.cpp
index c04a61a0..62135fe2 100644
--- a/shibsp/session/impl/FilesystemSessionCache.cpp
+++ b/shibsp/session/impl/FilesystemSessionCache.cpp
@@ -328,13 +328,12 @@ DDF FilesystemSessionCache::cache_read(
bool updateTimestamp = true;
- // TODO: Implement the fuzzy address matching.
if (client_addr) {
const char* family = getAddressFamily(client_addr);
const char* addr = obj[family].string();
if (addr) {
- if (strcmp(client_addr, addr)) {
- m_spilog.info("session (%s) invalid, bound to address (%s), accessed from (%s)", key, addr, client_addr);
+ if (!isAddressMatch(client_addr, addr)) {
+ m_spilog.info("session (%s) use invalid, bound to address (%s), accessed from (%s)", key, addr, client_addr);
return obj.destroy();
}
}
diff --git a/shibsp/session/impl/MemorySessionCache.cpp b/shibsp/session/impl/MemorySessionCache.cpp
index 626f23ee..5233aa3f 100644
--- a/shibsp/session/impl/MemorySessionCache.cpp
+++ b/shibsp/session/impl/MemorySessionCache.cpp
@@ -206,13 +206,12 @@ DDF MemorySessionCache::cache_read(
}
}
- // TODO: Implement the fuzzy address matching.
if (client_addr) {
const char* family = getAddressFamily(client_addr);
const char* addr = entry->second.first[family].string();
if (addr) {
- if (strcmp(client_addr, addr)) {
- m_spilog.info("session (%s) invalid, bound to address (%s), accessed from (%s)", key, addr, client_addr);
+ if (!isAddressMatch(client_addr, addr)) {
+ m_spilog.info("session (%s) use invalid, bound to address (%s), accessed from (%s)", key, addr, client_addr);
m_lock.unlock();
return DDF();
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list