[cpp-sp] branch master updated: SSPCPP-614 - requireSessionWith cannot be disabled in sub location / path
Scott Cantor
cantor.2 at osu.edu
Fri Mar 23 17:10:15 EDT 2018
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=9ed8e21768f446b1a1a2f90cbeb54ff575036460
The following commit(s) were added to refs/heads/master by this push:
new 9ed8e21 SSPCPP-614 - requireSessionWith cannot be disabled in sub location / path
9ed8e21 is described below
commit 9ed8e21768f446b1a1a2f90cbeb54ff575036460
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Mar 23 17:09:18 2018 -0400
SSPCPP-614 - requireSessionWith cannot be disabled in sub location / path
https://issues.shibboleth.net/jira/browse/SSPCPP-614
---
apache/mod_shib.cpp | 228 +++++++++++++++-------------
apache/mod_shib_20.cpp | 1 +
apache/mod_shib_22.cpp | 1 +
apache/mod_shib_24.cpp | 1 +
nsapi_shib/nsapi_shib.cpp | 24 +--
schemas/shibboleth-3.0-native-sp-config.xsd | 1 +
shibsp/ServiceProvider.cpp | 2 +-
shibsp/handler/impl/StatusHandler.cpp | 15 +-
shibsp/impl/XMLRequestMapper.cpp | 6 +-
shibsp/impl/XMLServiceProvider.cpp | 27 ++--
shibsp/util/DOMPropertySet.cpp | 37 +++--
shibsp/util/DOMPropertySet.h | 10 +-
shibsp/util/PropertySet.h | 7 -
13 files changed, 185 insertions(+), 175 deletions(-)
diff --git a/apache/mod_shib.cpp b/apache/mod_shib.cpp
index 61e084e..0a1fd16 100644
--- a/apache/mod_shib.cpp
+++ b/apache/mod_shib.cpp
@@ -89,7 +89,7 @@
#include <cstddef>
#ifdef HAVE_UNISTD_H
-#include <unistd.h> // for getpid()
+#include <unistd.h> // for getpid()
#endif
using namespace shibsp;
@@ -171,13 +171,14 @@ extern "C" void* merge_shib_server_config (SH_AP_POOL* p, void* base, void* sub)
struct shib_dir_config
{
SH_AP_TABLE* tSettings; // generic table of extensible settings
+ SH_AP_TABLE* tUnsettings; // generic table of settings to "unset", i.e. default and block inheritance
// RM Configuration
#ifdef SHIB_APACHE_24
int bRequestMapperAuthz;// support RequestMapper AccessControl plugins
#else
char* szAuthGrpFile; // Auth GroupFile name
- char* szAccessControl; // path to "external" AccessControl plugin file
+ char* szAccessControl; // path to "external" AccessControl plugin file
int bRequireAll; // all "known" require directives must match, otherwise OR logic
int bAuthoritative; // allow htaccess plugin to DECLINE when authz fails
int bCompatWith24; // support 2.4-reserved require logic for compatibility
@@ -201,11 +202,12 @@ extern "C" void* create_shib_dir_config (SH_AP_POOL* p, char* d)
{
shib_dir_config* dc=(shib_dir_config*)ap_pcalloc(p,sizeof(shib_dir_config));
dc->tSettings = nullptr;
+ dc->tUnsettings = nullptr;
#ifdef SHIB_APACHE_24
dc->bRequestMapperAuthz = -1;
#else
dc->szAuthGrpFile = nullptr;
- dc->szAccessControl = nullptr;
+ dc->szAccessControl = nullptr;
dc->bRequireAll = -1;
dc->bAuthoritative = -1;
dc->bCompatWith24 = -1;
@@ -230,10 +232,25 @@ extern "C" void* merge_shib_dir_config (SH_AP_POOL* p, void* base, void* sub)
shib_dir_config* parent=(shib_dir_config*)base;
shib_dir_config* child=(shib_dir_config*)sub;
- // The child supersedes any matching table settings in the parent.
+ // The child supersedes any matching table settings in the parent,
+ // and only parent settings not "unset" by the child are copied in.
dc->tSettings = nullptr;
- if (parent->tSettings)
- dc->tSettings = ap_copy_table(p, parent->tSettings);
+ if (parent->tSettings) {
+ if (child->tUnsettings) {
+ const array_header* thdr = ap_table_elts(parent->tSettings);
+ const table_entry* tent = (const table_entry*)thdr->elts;
+ for (int i = 0; i < thdr->nelts; ++i) {
+ if (!ap_table_get(child->tUnsettings, tent[i].key)) {
+ if (!dc->tSettings)
+ dc->tSettings = ap_make_table(p, thdr->nelts);
+ ap_table_set(dc->tSettings, tent[i].key, tent[i].val);
+ }
+ }
+ }
+ else {
+ dc->tSettings = ap_copy_table(p, parent->tSettings);
+ }
+ }
if (child->tSettings) {
if (dc->tSettings)
ap_overlap_tables(dc->tSettings, child->tSettings, AP_OVERLAP_TABLES_SET);
@@ -241,19 +258,37 @@ extern "C" void* merge_shib_dir_config (SH_AP_POOL* p, void* base, void* sub)
dc->tSettings = ap_copy_table(p, child->tSettings);
}
+ // Unsetting is weird. We don't need to carry forward either the parent's
+ // or child's table for our own use because its only relevance is to block
+ // inheritance of the parent's settings during this specific merge. If another
+ // child is merged in, then *its* unset table will be applied to that merge, and
+ // so forth. So the merged result contains no explicit unsetters. Weird.
+ // EXCEPT: we need to merge and track all the unsets done as a group in order
+ // to block inheritance from the RequestMap, which is the "parent" for all
+ // settings.
+ dc->tUnsettings = nullptr;
+ if (parent->tUnsettings)
+ dc->tUnsettings = ap_copy_table(p, parent->tUnsettings);
+ if (child->tUnsettings) {
+ if (dc->tUnsettings)
+ ap_overlap_tables(dc->tUnsettings, child->tUnsettings, AP_OVERLAP_TABLES_SET);
+ else
+ dc->tUnsettings = ap_copy_table(p, child->tUnsettings);
+ }
+
#ifdef SHIB_APACHE_24
dc->bRequestMapperAuthz = ((child->bRequestMapperAuthz==-1) ? parent->bRequestMapperAuthz : child->bRequestMapperAuthz);
#else
if (child->szAuthGrpFile)
dc->szAuthGrpFile=ap_pstrdup(p,child->szAuthGrpFile);
- else if (parent->szAuthGrpFile)
+ else if (parent->szAuthGrpFile && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "AuthGroupFile")))
dc->szAuthGrpFile=ap_pstrdup(p,parent->szAuthGrpFile);
else
dc->szAuthGrpFile=nullptr;
- if (child->szAccessControl)
+ if (child->szAccessControl)
dc->szAccessControl=ap_pstrdup(p,child->szAccessControl);
- else if (parent->szAccessControl)
+ else if (parent->szAccessControl && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "ShibAccessControl")))
dc->szAccessControl=ap_pstrdup(p,parent->szAccessControl);
else
dc->szAccessControl=nullptr;
@@ -261,29 +296,41 @@ extern "C" void* merge_shib_dir_config (SH_AP_POOL* p, void* base, void* sub)
if (child->szApplicationId)
dc->szApplicationId=ap_pstrdup(p,child->szApplicationId);
- else if (parent->szApplicationId)
+ else if (parent->szApplicationId && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "applicationId")))
dc->szApplicationId=ap_pstrdup(p,parent->szApplicationId);
else
dc->szApplicationId=nullptr;
if (child->szRequireWith)
dc->szRequireWith=ap_pstrdup(p,child->szRequireWith);
- else if (parent->szRequireWith)
+ else if (parent->szRequireWith && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "requireSessionWith")))
dc->szRequireWith=ap_pstrdup(p,parent->szRequireWith);
else
dc->szRequireWith=nullptr;
if (child->szRedirectToSSL)
dc->szRedirectToSSL=ap_pstrdup(p,child->szRedirectToSSL);
- else if (parent->szRedirectToSSL)
+ else if (parent->szRedirectToSSL && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "redirectToSSL")))
dc->szRedirectToSSL=ap_pstrdup(p,parent->szRedirectToSSL);
else
dc->szRedirectToSSL=nullptr;
- dc->bOff = ((child->bOff==-1) ? parent->bOff : child->bOff);
- dc->bBasicHijack = ((child->bBasicHijack==-1) ? parent->bBasicHijack : child->bBasicHijack);
- dc->bRequireSession = ((child->bRequireSession==-1) ? parent->bRequireSession : child->bRequireSession);
- dc->bExportAssertion = ((child->bExportAssertion==-1) ? parent->bExportAssertion : child->bExportAssertion);
+ if (child->bRequireSession != -1)
+ dc->bRequireSession = child->bRequireSession;
+ else if (parent->bRequireSession != -1 && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "requireSession")))
+ dc->bRequireSession = parent->bRequireSession;
+ else
+ dc->bRequireSession = -1;
+
+ if (child->bExportAssertion != -1)
+ dc->bExportAssertion = child->bExportAssertion;
+ else if (parent->bExportAssertion != -1 && (!child->tUnsettings || !apr_table_get(child->tUnsettings, "exportAssertion")))
+ dc->bExportAssertion = parent->bExportAssertion;
+ else
+ dc->bExportAssertion = -1;
+
+ dc->bOff = ((child->bOff == -1) ? parent->bOff : child->bOff);
+ dc->bBasicHijack = ((child->bBasicHijack == -1) ? parent->bBasicHijack : child->bBasicHijack);
#ifndef SHIB_APACHE_24
dc->bRequireAll = ((child->bRequireAll==-1) ? parent->bRequireAll : child->bRequireAll);
dc->bAuthoritative = ((child->bAuthoritative==-1) ? parent->bAuthoritative : child->bAuthoritative);
@@ -963,24 +1010,24 @@ AccessControl* htAccessFactory(const xercesc::DOMElement* const & e)
AccessControl::aclresult_t htAccessControl::doAccessControl(const ShibTargetApache& sta, const Session* session, const char* plugin) const
{
- aclresult_t result = shib_acl_false;
- try {
+ aclresult_t result = shib_acl_false;
+ try {
ifstream aclfile(plugin);
if (!aclfile)
throw ConfigurationException("Unable to open access control file ($1).", params(1, plugin));
xercesc::DOMDocument* acldoc = XMLToolingConfig::getConfig().getParser().parse(aclfile);
- XercesJanitor<xercesc::DOMDocument> docjanitor(acldoc);
- static XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
+ XercesJanitor<xercesc::DOMDocument> docjanitor(acldoc);
+ static XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
string t(XMLHelper::getAttrString(acldoc ? acldoc->getDocumentElement() : nullptr, nullptr, _type));
if (t.empty())
throw ConfigurationException("Missing type attribute in AccessControl plugin configuration.");
scoped_ptr<AccessControl> aclplugin(SPConfig::getConfig().AccessControlManager.newPlugin(t.c_str(), acldoc->getDocumentElement()));
- Locker acllock(aclplugin.get());
- result = aclplugin->authorized(sta, session);
- }
- catch (std::exception& ex) {
- sta.log(SPRequest::SPError, ex.what());
- }
+ Locker acllock(aclplugin.get());
+ result = aclplugin->authorized(sta, session);
+ }
+ catch (std::exception& ex) {
+ sta.log(SPRequest::SPError, ex.what());
+ }
return result;
}
@@ -1247,8 +1294,8 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
if (!reqs_arr)
return shib_acl_indeterminate; // should never happen
- // Check for an "embedded" AccessControl plugin.
- if (sta->m_dc->szAccessControl) {
+ // Check for an "embedded" AccessControl plugin.
+ if (sta->m_dc->szAccessControl) {
aclresult_t result = doAccessControl(*sta, session, sta->m_dc->szAccessControl);
if (result == shib_acl_true && sta->m_dc->bRequireAll != 1) {
// If we're not insisting that all rules be met, then we're done.
@@ -1394,7 +1441,6 @@ public:
pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=nullptr) const;
pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=nullptr) const;
pair<bool,int> getInt(const char* name, const char* ns=nullptr) const;
- void getAll(map<string,const char*>& properties) const;
const PropertySet* getPropertySet(const char* name, const char* ns=shibspconstants::ASCII_SHIBSPCONFIG_NS) const;
const xercesc::DOMElement* getElement() const;
@@ -1446,7 +1492,7 @@ pair<bool,bool> ApacheRequestMapper::getBool(const char* name, const char* ns) c
return make_pair(true, !strcmp(prop, "true") || !strcmp(prop, "1") || !strcmp(prop, "On"));
}
}
- return s ? s->getBool(name,ns) : make_pair(false,false);
+ return s && (!sta->m_dc->tUnsettings || !ap_table_get(sta->m_dc->tUnsettings, name)) ? s->getBool(name,ns) : make_pair(false,false);
}
pair<bool,const char*> ApacheRequestMapper::getString(const char* name, const char* ns) const
@@ -1476,13 +1522,14 @@ pair<bool,const char*> ApacheRequestMapper::getString(const char* name, const ch
return make_pair(true, prop);
}
}
- return s ? s->getString(name,ns) : pair<bool,const char*>(false,nullptr);
+ return s && (!sta->m_dc->tUnsettings || !ap_table_get(sta->m_dc->tUnsettings, name)) ? s->getString(name,ns) : pair<bool,const char*>(false,nullptr);
}
pair<bool,const XMLCh*> ApacheRequestMapper::getXMLString(const char* name, const char* ns) const
{
+ const ShibTargetApache* sta = reinterpret_cast<const ShibTargetApache*>(m_staKey->getData());
const PropertySet* s=reinterpret_cast<const PropertySet*>(m_propsKey->getData());
- return s ? s->getXMLString(name,ns) : pair<bool,const XMLCh*>(false,nullptr);
+ return s && (!sta->m_dc->tUnsettings || !ap_table_get(sta->m_dc->tUnsettings, name)) ? s->getXMLString(name,ns) : pair<bool,const XMLCh*>(false,nullptr);
}
pair<bool,unsigned int> ApacheRequestMapper::getUnsignedInt(const char* name, const char* ns) const
@@ -1499,7 +1546,7 @@ pair<bool,unsigned int> ApacheRequestMapper::getUnsignedInt(const char* name, co
return pair<bool,unsigned int>(true, atoi(prop));
}
}
- return s ? s->getUnsignedInt(name,ns) : pair<bool,unsigned int>(false,0);
+ return s && (!sta->m_dc->tUnsettings || !ap_table_get(sta->m_dc->tUnsettings, name)) ? s->getUnsignedInt(name,ns) : pair<bool,unsigned int>(false,0);
}
pair<bool,int> ApacheRequestMapper::getInt(const char* name, const char* ns) const
@@ -1516,46 +1563,7 @@ pair<bool,int> ApacheRequestMapper::getInt(const char* name, const char* ns) con
return make_pair(true, atoi(prop));
}
}
- return s ? s->getInt(name,ns) : pair<bool,int>(false,0);
-}
-
-static int _rm_get_all_table_walk(void *v, const char *key, const char *value)
-{
- reinterpret_cast<map<string,const char*>*>(v)->insert(pair<string,const char*>(key, value));
- return 1;
-}
-
-void ApacheRequestMapper::getAll(map<string,const char*>& properties) const
-{
- const ShibTargetApache* sta=reinterpret_cast<const ShibTargetApache*>(m_staKey->getData());
- const PropertySet* s=reinterpret_cast<const PropertySet*>(m_propsKey->getData());
-
- if (s)
- s->getAll(properties);
- if (!sta)
- return;
-
- const char* auth_type=ap_auth_type(sta->m_req);
- if (auth_type) {
- // Check for Basic Hijack
- if (!strcasecmp(auth_type, "basic") && sta->m_dc->bBasicHijack == 1)
- auth_type = "shibboleth";
- properties["authType"] = auth_type;
- }
-
- if (sta->m_dc->szApplicationId)
- properties["applicationId"] = sta->m_dc->szApplicationId;
- if (sta->m_dc->szRequireWith)
- properties["requireSessionWith"] = sta->m_dc->szRequireWith;
- if (sta->m_dc->szRedirectToSSL)
- properties["redirectToSSL"] = sta->m_dc->szRedirectToSSL;
- if (sta->m_dc->bRequireSession != 0)
- properties["requireSession"] = (sta->m_dc->bRequireSession==1) ? "true" : "false";
- if (sta->m_dc->bExportAssertion != 0)
- properties["exportAssertion"] = (sta->m_dc->bExportAssertion==1) ? "true" : "false";
-
- if (sta->m_dc->tSettings)
- ap_table_do(_rm_get_all_table_walk, &properties, sta->m_dc->tSettings, NULL);
+ return s && (!sta->m_dc->tUnsettings || !ap_table_get(sta->m_dc->tUnsettings, name)) ? s->getInt(name,ns) : pair<bool,int>(false,0);
}
const PropertySet* ApacheRequestMapper::getPropertySet(const char* name, const char* ns) const
@@ -1677,7 +1685,7 @@ extern "C" authz_status shib_user_check_authz(request_rec* r, const char* requir
if (!r->user) {
return AUTHZ_DENIED_NO_USER;
}
-
+
const char* t = require_line;
const char *w;
while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
@@ -1685,12 +1693,12 @@ extern "C" authz_status shib_user_check_authz(request_rec* r, const char* requir
return AUTHZ_GRANTED;
}
}
-
+
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01663)
"access to %s failed, reason: user '%s' does not meet "
"'require'ments for user to be allowed access",
r->uri, r->user);
-
+
return AUTHZ_DENIED;
}
@@ -1815,11 +1823,11 @@ extern "C" const char* shib_set_server_flag_slot(cmd_parms* parms, void*, int ar
extern "C" const char* shib_ap_set_file_slot(cmd_parms* parms,
#ifdef SHIB_APACHE_13
- char* arg1, char* arg2
+ char* arg1, char* arg2
#else
- void* arg1, const char* arg2
+ void* arg1, const char* arg2
#endif
- )
+ )
{
ap_set_file_slot(parms, arg1, arg2);
return DECLINE_CMD;
@@ -1833,6 +1841,14 @@ extern "C" const char* shib_table_set(cmd_parms* parms, shib_dir_config* dc, con
return nullptr;
}
+extern "C" const char* shib_table_unset(cmd_parms* parms, shib_dir_config* dc, const char* arg1)
+{
+ if (!dc->tUnsettings)
+ dc->tUnsettings = ap_make_table(parms->pool, 4);
+ ap_table_set(dc->tUnsettings, arg1, "");
+ return nullptr;
+}
+
#ifndef SHIB_APACHE_24
extern "C" const char* shib_set_acl_slot(cmd_parms* params, shib_dir_config* dc, char* arg)
{
@@ -2083,6 +2099,8 @@ static command_rec shire_cmds[] = {
{"ShibRequestSetting", (config_fn_t)shib_table_set, nullptr,
OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth request property for content"},
+ {"ShibRequestUnset", (config_fn_t)shib_table_unset, nullptr,
+ OR_AUTHCFG, TAKE1, "Unset an arbitrary Shibboleth request property (blocking inheritance)" },
{"ShibAccessControl", (config_fn_t)shib_set_acl_slot, nullptr,
OR_AUTHCFG, TAKE1, "Set arbitrary Shibboleth access control plugin for content"},
@@ -2092,22 +2110,22 @@ static command_rec shire_cmds[] = {
OR_AUTHCFG, FLAG, "Disable all Shib module activity here to save processing effort"},
{"ShibApplicationId", (config_fn_t)ap_set_string_slot,
(void *) XtOffsetOf (shib_dir_config, szApplicationId),
- OR_AUTHCFG, TAKE1, "Set Shibboleth applicationId property for content"},
+ OR_AUTHCFG, TAKE1, "(DEPRECATED) Set Shibboleth applicationId property for content"},
{"ShibBasicHijack", (config_fn_t)ap_set_flag_slot,
(void *) XtOffsetOf (shib_dir_config, bBasicHijack),
OR_AUTHCFG, FLAG, "(DEPRECATED) Respond to AuthType Basic and convert to shibboleth"},
{"ShibRequireSession", (config_fn_t)ap_set_flag_slot,
(void *) XtOffsetOf (shib_dir_config, bRequireSession),
- OR_AUTHCFG, FLAG, "Initiates a new session if one does not exist"},
+ OR_AUTHCFG, FLAG, "(DEPRECATED) Initiates a new session if one does not exist"},
{"ShibRequireSessionWith", (config_fn_t)ap_set_string_slot,
(void *) XtOffsetOf (shib_dir_config, szRequireWith),
- OR_AUTHCFG, TAKE1, "Initiates a new session if one does not exist using a specific SessionInitiator"},
+ OR_AUTHCFG, TAKE1, "(DEPRECATED) Initiates a new session if one does not exist using a specific SessionInitiator"},
{"ShibExportAssertion", (config_fn_t)ap_set_flag_slot,
(void *) XtOffsetOf (shib_dir_config, bExportAssertion),
- OR_AUTHCFG, FLAG, "Export SAML attribute assertion(s) to Shib-Attributes header"},
+ OR_AUTHCFG, FLAG, "(DEPRECATED) Export SAML attribute assertion(s) to Shib-Attributes header"},
{"ShibRedirectToSSL", (config_fn_t)ap_set_string_slot,
(void *) XtOffsetOf (shib_dir_config, szRedirectToSSL),
- OR_AUTHCFG, TAKE1, "Redirect non-SSL requests to designated port" },
+ OR_AUTHCFG, TAKE1, "(DEPRECATED) Redirect non-SSL requests to designated port" },
{"AuthGroupFile", (config_fn_t)shib_ap_set_file_slot,
(void *) XtOffsetOf (shib_dir_config, szAuthGrpFile),
OR_AUTHCFG, TAKE1, "text file containing group names and member user IDs"},
@@ -2142,23 +2160,23 @@ handler_rec shib_handlers[] = {
module MODULE_VAR_EXPORT mod_shib = {
STANDARD_MODULE_STUFF,
nullptr, /* initializer */
- create_shib_dir_config, /* dir config creater */
- merge_shib_dir_config, /* dir merger --- default is to override */
+ create_shib_dir_config, /* dir config creater */
+ merge_shib_dir_config, /* dir merger --- default is to override */
create_shib_server_config, /* server config */
merge_shib_server_config, /* merge server config */
- shire_cmds, /* command table */
- shib_handlers, /* handlers */
- nullptr, /* filename translation */
- shib_check_user, /* check_user_id */
- shib_auth_checker, /* check auth */
- nullptr, /* check access */
- nullptr, /* type_checker */
- shib_fixups, /* fixups */
- nullptr, /* logger */
- nullptr, /* header parser */
- shib_child_init, /* child_init */
- shib_child_exit, /* child_exit */
- shib_post_read /* post read-request */
+ shire_cmds, /* command table */
+ shib_handlers, /* handlers */
+ nullptr, /* filename translation */
+ shib_check_user, /* check_user_id */
+ shib_auth_checker, /* check auth */
+ nullptr, /* check access */
+ nullptr, /* type_checker */
+ shib_fixups, /* fixups */
+ nullptr, /* logger */
+ nullptr, /* header parser */
+ shib_child_init, /* child_init */
+ shib_child_exit, /* child_exit */
+ shib_post_read /* post read-request */
};
#else
@@ -2241,28 +2259,30 @@ static command_rec shib_cmds[] = {
AP_INIT_TAKE2("ShibRequestSetting", (config_fn_t)shib_table_set, nullptr,
OR_AUTHCFG, "Set arbitrary Shibboleth request property for content"),
+ AP_INIT_TAKE1("ShibRequestUnset", (config_fn_t)shib_table_unset, nullptr,
+ OR_AUTHCFG, "Unset an arbitrary Shibboleth request property (blocking inheritance)"),
AP_INIT_FLAG("ShibDisable", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bOff),
OR_AUTHCFG, "Disable all Shib module activity here to save processing effort"),
AP_INIT_TAKE1("ShibApplicationId", (config_fn_t)ap_set_string_slot,
(void *) offsetof (shib_dir_config, szApplicationId),
- OR_AUTHCFG, "Set Shibboleth applicationId property for content"),
+ OR_AUTHCFG, "(DEPRECATED) Set Shibboleth applicationId property for content"),
AP_INIT_FLAG("ShibBasicHijack", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bBasicHijack),
OR_AUTHCFG, "(DEPRECATED) Respond to AuthType Basic and convert to shibboleth"),
AP_INIT_FLAG("ShibRequireSession", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bRequireSession),
- OR_AUTHCFG, "Initiates a new session if one does not exist"),
+ OR_AUTHCFG, "(DEPRECATED) Initiates a new session if one does not exist"),
AP_INIT_TAKE1("ShibRequireSessionWith", (config_fn_t)ap_set_string_slot,
(void *) offsetof (shib_dir_config, szRequireWith),
- OR_AUTHCFG, "Initiates a new session if one does not exist using a specific SessionInitiator"),
+ OR_AUTHCFG, "(DEPRECATED) Initiates a new session if one does not exist using a specific SessionInitiator"),
AP_INIT_FLAG("ShibExportAssertion", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bExportAssertion),
- OR_AUTHCFG, "Export SAML attribute assertion(s) to Shib-Attributes header"),
+ OR_AUTHCFG, "(DEPRECATED) Export SAML attribute assertion(s) to Shib-Attributes header"),
AP_INIT_TAKE1("ShibRedirectToSSL", (config_fn_t)ap_set_string_slot,
(void *) offsetof (shib_dir_config, szRedirectToSSL),
- OR_AUTHCFG, "Redirect non-SSL requests to designated port"),
+ OR_AUTHCFG, "(DEPRECATED) Redirect non-SSL requests to designated port"),
#ifdef SHIB_APACHE_24
AP_INIT_FLAG("ShibRequestMapperAuthz", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bRequestMapperAuthz),
diff --git a/apache/mod_shib_20.cpp b/apache/mod_shib_20.cpp
index a9b38de..9f25e7a 100644
--- a/apache/mod_shib_20.cpp
+++ b/apache/mod_shib_20.cpp
@@ -32,6 +32,7 @@
#define SH_AP_TABLE apr_table_t
#define SH_AP_CONFIGFILE ap_configfile_t
#define array_header apr_array_header_t
+#define table_entry apr_table_entry_t
#define SH_AP_R(r) 0,r
#define SH_AP_USER(r) r->user
diff --git a/apache/mod_shib_22.cpp b/apache/mod_shib_22.cpp
index e6e25e0..7e7ea23 100644
--- a/apache/mod_shib_22.cpp
+++ b/apache/mod_shib_22.cpp
@@ -32,6 +32,7 @@
#define SH_AP_TABLE apr_table_t
#define SH_AP_CONFIGFILE ap_configfile_t
#define array_header apr_array_header_t
+#define table_entry apr_table_entry_t
#define SH_AP_R(r) 0,r
#define SH_AP_USER(r) r->user
diff --git a/apache/mod_shib_24.cpp b/apache/mod_shib_24.cpp
index ddd5c65..73cd070 100644
--- a/apache/mod_shib_24.cpp
+++ b/apache/mod_shib_24.cpp
@@ -32,6 +32,7 @@
#define SH_AP_TABLE apr_table_t
#define SH_AP_CONFIGFILE ap_configfile_t
#define array_header apr_array_header_t
+#define table_entry apr_table_entry_t
#define SH_AP_R(r) 0,r
#define SH_AP_USER(r) r->user
diff --git a/nsapi_shib/nsapi_shib.cpp b/nsapi_shib/nsapi_shib.cpp
index 200fd07..b07cb01 100644
--- a/nsapi_shib/nsapi_shib.cpp
+++ b/nsapi_shib/nsapi_shib.cpp
@@ -570,7 +570,6 @@ public:
pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=nullptr) const;
pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=nullptr) const;
pair<bool,int> getInt(const char* name, const char* ns=nullptr) const;
- void getAll(map<string,const char*>& properties) const;
const PropertySet* getPropertySet(const char* name, const char* ns=shibspconstants::ASCII_SHIBSPCONFIG_NS) const;
const xercesc::DOMElement* getElement() const;
@@ -606,8 +605,8 @@ pair<bool,bool> SunRequestMapper::getBool(const char* name, const char* ns) cons
if (stn && !ns && name) {
// Override boolean properties.
const char* param=pblock_findval(name,stn->m_pb);
- if (param && (!strcmp(param,"1") || !strcasecmp(param,"true")))
- return make_pair(true,true);
+ if (param)
+ return make_pair(true, !strcmp(param, "1") || !strcasecmp(param, "true"));
}
return s ? s->getBool(name,ns) : make_pair(false,false);
}
@@ -667,25 +666,6 @@ pair<bool,int> SunRequestMapper::getInt(const char* name, const char* ns) const
return s ? s->getInt(name,ns) : pair<bool,int>(false,0);
}
-void SunRequestMapper::getAll(map<string,const char*>& properties) const
-{
- const ShibTargetNSAPI* stn=reinterpret_cast<const ShibTargetNSAPI*>(m_stKey->getData());
- const PropertySet* s=reinterpret_cast<const PropertySet*>(m_propsKey->getData());
- if (s)
- s->getAll(properties);
- if (!stn)
- return;
- properties["authType"] = "shibboleth";
- const pb_entry* entry;
- for (int i=0; i<stn->m_pb->hsize; ++i) {
- entry = stn->m_pb->ht[i];
- while (entry) {
- properties[entry->param->name] = entry->param->value;
- entry = entry->next;
- }
- }
-}
-
const PropertySet* SunRequestMapper::getPropertySet(const char* name, const char* ns) const
{
const PropertySet* s=reinterpret_cast<const PropertySet*>(m_propsKey->getData());
diff --git a/schemas/shibboleth-3.0-native-sp-config.xsd b/schemas/shibboleth-3.0-native-sp-config.xsd
index d874c13..ae0473a 100644
--- a/schemas/shibboleth-3.0-native-sp-config.xsd
+++ b/schemas/shibboleth-3.0-native-sp-config.xsd
@@ -292,6 +292,7 @@
<attribute name="acsIndex" type="unsignedShort"/>
<attribute name="REMOTE_ADDR" type="conf:string"/>
<attribute name="encoding" type="conf:string"/>
+ <attribute name="unset" type="conf:listOfStrings"/>
<anyAttribute namespace="##other" processContents="lax"/>
</attributeGroup>
diff --git a/shibsp/ServiceProvider.cpp b/shibsp/ServiceProvider.cpp
index 2d07614..bc975fe 100644
--- a/shibsp/ServiceProvider.cpp
+++ b/shibsp/ServiceProvider.cpp
@@ -429,7 +429,7 @@ pair<bool,long> ServiceProvider::doAuthentication(SPRequest& request, bool handl
initiator=app->getSessionInitiatorById(requireSessionWith.second);
if (!initiator) {
throw ConfigurationException(
- "No session initiator found with id ($1), check requireSessionWith command.", params(1, requireSessionWith.second)
+ "No session initiator found with id ($1), check requireSessionWith setting.", params(1, requireSessionWith.second)
);
}
}
diff --git a/shibsp/handler/impl/StatusHandler.cpp b/shibsp/handler/impl/StatusHandler.cpp
index bdb56c0..2128636 100644
--- a/shibsp/handler/impl/StatusHandler.cpp
+++ b/shibsp/handler/impl/StatusHandler.cpp
@@ -270,9 +270,6 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
// RequestMap query, so handle it inproc.
DummyRequest dummy(target);
RequestMapper::Settings settings = request.getApplication().getServiceProvider().getRequestMapper()->getSettings(dummy);
- map<string,const char*> props;
- settings.first->getAll(props);
-
XMLDateTime now(time(nullptr), false);
now.parseDateTime();
auto_ptr_char timestamp(now.getFormattedString());
@@ -286,10 +283,14 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
<< "' OpenSAML-C='" << gOpenSAMLDotVersionStr
#endif
<< "' Shibboleth='" << PACKAGE_VERSION << "'/>";
- systemInfo(msg) << "<RequestSettings";
- for (map<string,const char*>::const_iterator p = props.begin(); p != props.end(); ++p)
- msg << ' ' << p->first << "='" << p->second << "'";
- msg << '>' << target << "</RequestSettings>";
+ const char* setting = request.getParameter("setting");
+ systemInfo(msg) << "<RequestSettings";
+ if (setting) {
+ pair<bool, const char*> prop = settings.first->getString(setting);
+ if (prop.first)
+ msg << ' ' << setting << "='" << prop.second << "'";
+ }
+ msg << '>' << target << "</RequestSettings>";
msg << "<Status><OK/></Status>";
msg << "</StatusHandler>";
return make_pair(true, request.sendResponse(msg));
diff --git a/shibsp/impl/XMLRequestMapper.cpp b/shibsp/impl/XMLRequestMapper.cpp
index ae3dae0..1ba6e29 100644
--- a/shibsp/impl/XMLRequestMapper.cpp
+++ b/shibsp/impl/XMLRequestMapper.cpp
@@ -217,7 +217,8 @@ Override::Override(bool unicodeAware, const DOMElement* e, Category& log, const
: m_unicodeAware(unicodeAware)
{
// Load the property set.
- load(e, nullptr, this);
+ xmltooling::QName unsetter(nullptr, "unset");
+ load(e, nullptr, this, nullptr, &unsetter);
setParent(base);
// Load any AccessControl provider.
@@ -475,7 +476,8 @@ XMLRequestMapperImpl::XMLRequestMapperImpl(const DOMElement* e, Category& log) :
}
// Load the property set.
- load(e, nullptr, this);
+ xmltooling::QName unsetter(nullptr, "unset");
+ load(e, nullptr, this, nullptr, &unsetter);
// Inject "default" app ID if not explicit.
if (!getString("applicationId").first)
diff --git a/shibsp/impl/XMLServiceProvider.cpp b/shibsp/impl/XMLServiceProvider.cpp
index 3882fc6..96b3824 100644
--- a/shibsp/impl/XMLServiceProvider.cpp
+++ b/shibsp/impl/XMLServiceProvider.cpp
@@ -368,7 +368,6 @@ namespace {
pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=nullptr) const {return m_impl->getXMLString(name,ns);}
pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=nullptr) const {return m_impl->getUnsignedInt(name,ns);}
pair<bool,int> getInt(const char* name, const char* ns=nullptr) const {return m_impl->getInt(name,ns);}
- void getAll(map<string,const char*>& properties) const {return m_impl->getAll(properties);}
const PropertySet* getPropertySet(const char* name, const char* ns=shibspconstants::ASCII_SHIBSPCONFIG_NS) const {return m_impl->getPropertySet(name,ns);}
const DOMElement* getElement() const {return m_impl->getElement();}
@@ -471,7 +470,7 @@ namespace {
static const XMLCh Binding[] = UNICODE_LITERAL_7(B,i,n,d,i,n,g);
static const XMLCh Channel[]= UNICODE_LITERAL_7(C,h,a,n,n,e,l);
static const XMLCh _CredentialResolver[] = UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
- static const XMLCh _DataSealer[] = UNICODE_LITERAL_10(D,a,t,a,S,e,a,l,e,r);
+ static const XMLCh _DataSealer[] = UNICODE_LITERAL_10(D,a,t,a,S,e,a,l,e,r);
static const XMLCh _default[] = UNICODE_LITERAL_7(d,e,f,a,u,l,t);
static const XMLCh _Extensions[] = UNICODE_LITERAL_10(E,x,t,e,n,s,i,o,n,s);
static const XMLCh _fatal[] = UNICODE_LITERAL_5(f,a,t,a,l);
@@ -1829,7 +1828,7 @@ DOMNodeFilter::FilterAction XMLConfigImpl::acceptNode(const DOMNode* node) const
const XMLCh* name=node->getLocalName();
if (XMLString::equals(name,ApplicationDefaults) ||
XMLString::equals(name,_ArtifactMap) ||
- XMLString::equals(name, _DataSealer) ||
+ XMLString::equals(name, _DataSealer) ||
XMLString::equals(name,_Extensions) ||
XMLString::equals(name,Listener) ||
XMLString::equals(name,_ProtocolProvider) ||
@@ -2127,17 +2126,17 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, XMLConfig* outer,
outer->m_listener->regListener("get::PostData", outer);
}
- if (child = XMLHelper::getFirstChildElement(e, _DataSealer)) {
- string t(XMLHelper::getAttrString(child, nullptr, _type));
- if (!t.empty()) {
- log.info("building DataSealer of type %s...", t.c_str());
- auto_ptr<DataSealerKeyStrategy> strategy(XMLToolingConfig::getConfig().DataSealerKeyStrategyManager.newPlugin(t, child));
- auto_ptr<DataSealer> sealer(new DataSealer(strategy.get()));
- strategy.release();
- XMLToolingConfig::getConfig().setDataSealer(sealer.get());
- sealer.release();
- }
- }
+ if (child = XMLHelper::getFirstChildElement(e, _DataSealer)) {
+ string t(XMLHelper::getAttrString(child, nullptr, _type));
+ if (!t.empty()) {
+ log.info("building DataSealer of type %s...", t.c_str());
+ auto_ptr<DataSealerKeyStrategy> strategy(XMLToolingConfig::getConfig().DataSealerKeyStrategyManager.newPlugin(t, child));
+ auto_ptr<DataSealer> sealer(new DataSealer(strategy.get()));
+ strategy.release();
+ XMLToolingConfig::getConfig().setDataSealer(sealer.get());
+ sealer.release();
+ }
+ }
#endif
if (conf.isEnabled(SPConfig::Caching))
doCaching(e, outer, log);
diff --git a/shibsp/util/DOMPropertySet.cpp b/shibsp/util/DOMPropertySet.cpp
index 58d9f4e..d51fb9c 100644
--- a/shibsp/util/DOMPropertySet.cpp
+++ b/shibsp/util/DOMPropertySet.cpp
@@ -29,8 +29,10 @@
#include <algorithm>
#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/XMLConstants.h>
+#include <xmltooling/util/XMLHelper.h>
using namespace shibsp;
using namespace xmltooling;
@@ -103,7 +105,8 @@ void DOMPropertySet::load(
const DOMElement* e,
Category* log,
DOMNodeFilter* filter,
- const Remapper* remapper
+ const Remapper* remapper,
+ const xmltooling::QName* unsetter
)
{
#ifdef _DEBUG
@@ -119,8 +122,16 @@ void DOMPropertySet::load(
DOMNamedNodeMap* attrs=m_root->getAttributes();
for (XMLSize_t i=0; i<attrs->getLength(); i++) {
DOMNode* a=attrs->item(i);
- if (!XMLString::compareString(a->getNamespaceURI(),xmlconstants::XMLNS_NS))
+ if (!XMLString::compareString(a->getNamespaceURI(), xmlconstants::XMLNS_NS)) {
continue;
+ }
+ else if (unsetter && XMLHelper::isNodeNamed(a, unsetter->getNamespaceURI(), unsetter->getLocalPart())) {
+ auto_ptr_char val(a->getNodeValue());
+ string dup(val.get());
+ split(m_unset, dup, is_space(), algorithm::token_compress_on);
+ continue;
+ }
+
char* val=XMLString::transcode(a->getNodeValue());
if (val && *val) {
auto_ptr_char ns(a->getNamespaceURI());
@@ -196,10 +207,12 @@ pair<bool,bool> DOMPropertySet::getBool(const char* name, const char* ns) const
else
i=m_map.find(name);
+
if (i!=m_map.end())
return make_pair(true,(!strcmp(i->second.first,"true") || !strcmp(i->second.first,"1")));
- else if (m_parent)
- return m_parent->getBool(name,ns);
+ else if (m_parent && m_unset.find(ns ? (string("{") + ns + '}' + name) : name) == m_unset.end()) {
+ return m_parent->getBool(name, ns);
+ }
return make_pair(false,false);
}
@@ -215,7 +228,7 @@ pair<bool,const char*> DOMPropertySet::getString(const char* name, const char* n
if (i!=m_map.end())
return pair<bool,const char*>(true,i->second.first);
- else if (m_parent)
+ else if (m_parent && m_unset.find(ns ? (string("{") + ns + '}' + name) : name) == m_unset.end())
return m_parent->getString(name,ns);
return pair<bool,const char*>(false,nullptr);
}
@@ -231,7 +244,7 @@ pair<bool,const XMLCh*> DOMPropertySet::getXMLString(const char* name, const cha
if (i!=m_map.end())
return make_pair(true,i->second.second);
- else if (m_parent)
+ else if (m_parent && m_unset.find(ns ? (string("{") + ns + '}' + name) : name) == m_unset.end())
return m_parent->getXMLString(name,ns);
return pair<bool,const XMLCh*>(false,nullptr);
}
@@ -253,7 +266,7 @@ pair<bool,unsigned int> DOMPropertySet::getUnsignedInt(const char* name, const c
return pair<bool,unsigned int>(false,0);
}
}
- else if (m_parent)
+ else if (m_parent && m_unset.find(ns ? (string("{") + ns + '}' + name) : name) == m_unset.end())
return m_parent->getUnsignedInt(name,ns);
return pair<bool,unsigned int>(false,0);
}
@@ -269,19 +282,11 @@ pair<bool,int> DOMPropertySet::getInt(const char* name, const char* ns) const
if (i!=m_map.end())
return pair<bool,int>(true,atoi(i->second.first));
- else if (m_parent)
+ else if (m_parent && m_unset.find(ns ? (string("{") + ns + '}' + name) : name) == m_unset.end())
return m_parent->getInt(name,ns);
return pair<bool,int>(false,0);
}
-void DOMPropertySet::getAll(std::map<std::string,const char*>& properties) const
-{
- if (m_parent)
- m_parent->getAll(properties);
- for (map< string,pair<char*,const XMLCh*> >::const_iterator i = m_map.begin(); i != m_map.end(); ++i)
- properties[i->first] = i->second.first;
-}
-
const PropertySet* DOMPropertySet::getPropertySet(const char* name, const char* ns) const
{
map< string,boost::shared_ptr<DOMPropertySet> >::const_iterator i;
diff --git a/shibsp/util/DOMPropertySet.h b/shibsp/util/DOMPropertySet.h
index 016e65c..748a87a 100644
--- a/shibsp/util/DOMPropertySet.h
+++ b/shibsp/util/DOMPropertySet.h
@@ -32,6 +32,10 @@
#include <boost/shared_ptr.hpp>
#include <xmltooling/logging.h>
+namespace xmltooling {
+ class QName;
+}
+
namespace shibsp {
/**
@@ -51,7 +55,6 @@ namespace shibsp {
std::pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=nullptr) const;
std::pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=nullptr) const;
std::pair<bool,int> getInt(const char* name, const char* ns=nullptr) const;
- void getAll(std::map<std::string,const char*>& properties) const;
const PropertySet* getPropertySet(const char* name, const char* ns=shibspconstants::ASCII_SHIBSPCONFIG_NS) const;
const xercesc::DOMElement* getElement() const;
@@ -105,12 +108,14 @@ namespace shibsp {
* @param log optional log object for tracing
* @param filter optional filter controls what child elements to include as nested PropertySets
* @param remapper optional mapper of property rename rules for legacy property support
+ * @param unsetter optional name of a property containing a list of property names to "unset"
*/
void load(
const xercesc::DOMElement* e,
xmltooling::logging::Category* log=nullptr,
xercesc::DOMNodeFilter* filter=nullptr,
- const Remapper* remapper=nullptr
+ const Remapper* remapper=nullptr,
+ const xmltooling::QName* unsetter=nullptr
);
protected:
@@ -128,6 +133,7 @@ namespace shibsp {
const PropertySet* m_parent;
const xercesc::DOMElement* m_root;
std::map<std::string,std::pair<char*,const XMLCh*> > m_map;
+ std::set<std::string> m_unset;
std::map< std::string,boost::shared_ptr<DOMPropertySet> > m_nested;
std::vector<xmltooling::xstring> m_injected;
};
diff --git a/shibsp/util/PropertySet.h b/shibsp/util/PropertySet.h
index 68cee60..c6562d6 100644
--- a/shibsp/util/PropertySet.h
+++ b/shibsp/util/PropertySet.h
@@ -106,13 +106,6 @@ namespace shibsp {
virtual std::pair<bool,int> getInt(const char* name, const char* ns=nullptr) const=0;
/**
- * Returns a map of all known properties in string form.
- *
- * @param properties map to populate
- */
- virtual void getAll(std::map<std::string,const char*>& properties) const=0;
-
- /**
* Returns a nested property set.
*
* @param name nested property set name
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list