From fb1c2b85869cb9de22e2875e886d147ff22d4c26 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Wed, 10 Nov 2010 17:54:27 +0000 Subject: [PATCH] https://issues.shibboleth.net/jira/browse/SSPCPP-315 --- apache/mod_apache.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/apache/mod_apache.cpp b/apache/mod_apache.cpp index 0f0a770..c6a6279 100644 --- a/apache/mod_apache.cpp +++ b/apache/mod_apache.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -160,6 +161,8 @@ struct shib_dir_config char* szApplicationId; // Shib applicationId value char* szRequireWith; // require a session using a specific initiator? char* szRedirectToSSL; // redirect non-SSL requests to SSL port + char* szAccessControlType; // type of "external" AccessControl plugin + char* szAccessControlPath; // path to AccessControl content int bOff; // flat-out disable all Shib processing int bBasicHijack; // activate for AuthType Basic? int bRequireSession; // require a session? @@ -179,6 +182,8 @@ extern "C" void* create_shib_dir_config (SH_AP_POOL* p, char* d) dc->szApplicationId = nullptr; dc->szRequireWith = nullptr; dc->szRedirectToSSL = nullptr; + dc->szAccessControlType = nullptr; + dc->szAccessControlPath = nullptr; dc->bOff = -1; dc->bBasicHijack = -1; dc->bRequireSession = -1; @@ -234,6 +239,20 @@ extern "C" void* merge_shib_dir_config (SH_AP_POOL* p, void* base, void* sub) else dc->szRedirectToSSL=nullptr; + if (child->szAccessControlType) + dc->szAccessControlType=ap_pstrdup(p,child->szAccessControlType); + else if (parent->szAccessControlType) + dc->szAccessControlType=ap_pstrdup(p,parent->szAccessControlType); + else + dc->szAccessControlType=nullptr; + + if (child->szAccessControlPath) + dc->szAccessControlPath=ap_pstrdup(p,child->szAccessControlPath); + else if (parent->szAccessControlPath) + dc->szAccessControlPath=ap_pstrdup(p,parent->szAccessControlPath); + else + dc->szAccessControlPath=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); @@ -299,6 +318,13 @@ extern "C" const char* shib_table_set(cmd_parms* parms, shib_dir_config* dc, con return nullptr; } +extern "C" const char* shib_acl_set(cmd_parms* parms, shib_dir_config* dc, const char* arg1, const char* arg2) +{ + dc->szAccessControlType = ap_pstrdup(parms->pool, arg1); + dc->szAccessControlPath = ap_pstrdup(parms->pool, arg2); + return nullptr; +} + class ShibTargetApache : public AbstractSPRequest #if defined(HAVE_GSSAPI) && !defined(SHIB_APACHE_13) @@ -1003,8 +1029,6 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request, if (!sta) throw ConfigurationException("Request wrapper object was not of correct type."); - // mod_auth clone - int m=sta->m_req->method_number; bool method_restricted=false; const char *t, *w; @@ -1013,6 +1037,46 @@ 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->szAccessControlType && sta->m_dc->szAccessControlPath) { + xercesc::DOMDocument* acldoc = XMLToolingConfig::getConfig().getParser().newDocument(); + XercesJanitor docjanitor(acldoc); + static XMLCh ACL[] = UNICODE_LITERAL_3(A,C,L); + static XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h); + static XMLCh _reloadChanges[] = UNICODE_LITERAL_13(r,e,l,o,a,d,C,h,a,n,g,e,s); + static XMLCh _false[] = { xercesc::chDigit_0, xercesc::chNull }; + xercesc::DOMElement* acldom = acldoc->createElementNS(nullptr, ACL); + auto_ptr_XMLCh aclpath(sta->m_dc->szAccessControlPath); + acldom->setAttributeNS(nullptr, _path, aclpath.get()); + acldom->setAttributeNS(nullptr, _reloadChanges, _false); + aclresult_t result = shib_acl_false; + try { + auto_ptr aclplugin(SPConfig::getConfig().AccessControlManager.newPlugin(sta->m_dc->szAccessControlType, acldom)); + Locker acllock(aclplugin.get()); + result = aclplugin->authorized(request, session); + } + catch (exception& ex) { + request.log(SPRequest::SPError, ex.what()); + } + + if (result == shib_acl_true && sta->m_dc->bRequireAll != 1) { + // If we're not insisting that all rules be met, then we're done. + request.log(SPRequest::SPDebug, "htaccess: embedded AccessControl plugin was successful, granting access"); + return shib_acl_true; + } + else if (result != shib_acl_true && sta->m_dc->bRequireAll == 1) { + // If we're insisting that all rules be met, which is not something Apache really handles well, + // then we either return false or indeterminate based on the authoritative option, which defaults on. + if (sta->m_dc->bAuthoritative != 0) { + request.log(SPRequest::SPDebug, "htaccess: embedded AccessControl plugin was unsuccessful, denying access"); + return shib_acl_false; + } + + request.log(SPRequest::SPDebug, "htaccess: embedded AccessControl plugin was unsuccessful but not authoritative, leaving it up to Apache"); + return shib_acl_indeterminate; + } + } + require_line* reqs=(require_line*)reqs_arr->elts; for (int x=0; xnelts; x++) { @@ -1451,6 +1515,9 @@ static command_rec shire_cmds[] = { {"ShibRequestSetting", (config_fn_t)shib_table_set, nullptr, OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth request property for content"}, + {"ShibAccessControl", (config_fn_t)shib_acl_set, nullptr, + OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth access control plugin for content"}, + {"ShibDisable", (config_fn_t)ap_set_flag_slot, (void *) XtOffsetOf (shib_dir_config, bOff), OR_AUTHCFG, FLAG, "Disable all Shib module activity here to save processing effort"}, @@ -1566,6 +1633,9 @@ 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_TAKE2("ShibAccessControl", (config_fn_t)shib_acl_set, nullptr, + OR_AUTHCFG, "Set arbitrary Shibboleth access control plugin for content"), + 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"), -- 2.1.4