/*
- * Copyright 2001-2005 Internet2
+ * Copyright 2001-2007 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
# define _CRT_SECURE_NO_DEPRECATE 1
#endif
+#include <shibsp/AbstractSPRequest.h>
#include <shibsp/AccessControl.h>
#include <shibsp/exceptions.h>
#include <shibsp/RequestMapper.h>
#include <shibsp/SPConfig.h>
+#include <shibsp/ServiceProvider.h>
+#include <shibsp/SessionCache.h>
+#include <shibsp/attribute/Attribute.h>
-// SAML Runtime
-#include <saml/saml.h>
-#include <shib/shib.h>
-#include <shib-target/shib-target.h>
#include <xercesc/util/regx/RegularExpression.hpp>
+#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/Threads.h>
+#include <xmltooling/util/XMLHelper.h>
#ifdef WIN32
# include <winsock.h>
#endif
using namespace shibsp;
-using namespace shibtarget;
using namespace xmltooling;
using namespace std;
extern "C" module MODULE_VAR_EXPORT mod_shib;
namespace {
- char* g_szSHIBConfig = NULL;
- char* g_szSchemaDir = NULL;
- ShibTargetConfig* g_Config = NULL;
+ char* g_szSHIBConfig = SHIBSP_CONFIG;
+ char* g_szSchemaDir = SHIBSP_SCHEMAS;
+ SPConfig* g_Config = NULL;
string g_unsetHeaderValue;
static const char* g_UserDataKey = "_shib_check_user_";
+ static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
}
/* Apache 2.2.x headers must be accumulated and set in the output filter.
/********************************************************************************/
// Apache ShibTarget subclass(es) here.
-class ShibTargetApache : public ShibTarget
+class ShibTargetApache : public AbstractSPRequest
{
mutable string m_body;
mutable bool m_gotBody;
m_dc = (shib_dir_config*)ap_get_module_config(req->per_dir_config, &mod_shib);
m_rc = (shib_request_config*)ap_get_module_config(req->request_config, &mod_shib);
m_req = req;
-
- init(
- m_sc->szScheme ? m_sc->szScheme : ap_http_method(req),
- ap_get_server_name(req),
- (int)ap_get_server_port(req),
- req->unparsed_uri
- );
}
virtual ~ShibTargetApache() {}
ShibTargetApache sta(r);
// Check user authentication and export information, then set the handler bypass
- pair<bool,long> res = sta.doCheckAuthN(true);
+ pair<bool,long> res = sta.getServiceProvider().doAuthentication(sta,true);
apr_pool_userdata_setn((const void*)42,g_UserDataKey,NULL,r->pool);
if (res.first) return res.second;
// user auth was okay -- export the assertions now
- res = sta.doExportAssertions();
+ res = sta.getServiceProvider().doExport(sta);
if (res.first) return res.second;
// export happened successfully.. this user is ok.
try {
ShibTargetApache sta(r);
- pair<bool,long> res = sta.doHandler();
+ pair<bool,long> res = sta.getServiceProvider().doHandler(sta);
if (res.first) return res.second;
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "doHandler() did not do anything.");
try {
ShibTargetApache sta(r);
- pair<bool,long> res = sta.doCheckAuthZ();
+ pair<bool,long> res = sta.getServiceProvider().doAuthorization(sta);
if (res.first) return res.second;
// We're all okay.
~htAccessControl() {}
Lockable* lock() {return this;}
void unlock() {}
- bool authorized(SPRequest& request, Session* session) const;
+ bool authorized(const SPRequest& request, const Session* session) const;
};
AccessControl* htAccessFactory(const DOMElement* const & e)
return grps;
}
-bool htAccessControl::authorized(SPRequest& request, Session* session) const
+bool htAccessControl::authorized(const SPRequest& request, const Session* session) const
{
// Make sure the object is our type.
- ShibTargetApache* sta=dynamic_cast<ShibTargetApache*>(&request);
+ const ShibTargetApache* sta=dynamic_cast<const ShibTargetApache*>(&request);
if (!sta)
throw ConfigurationException("Request wrapper object was not of correct type.");
grpstatus=groups_for_user(sta->m_req,remote_user.c_str(),sta->m_dc->szAuthGrpFile);
}
if (!grpstatus)
- return false;
+ continue;
while (*t) {
w=ap_getword_conf(sta->m_req->pool,&t);
}
}
else {
- saml::Iterator<shibboleth::IAAP*> provs=dynamic_cast<const IApplication&>(request.getSPApplication()).getAAPProviders();
- shibboleth::AAP wrapper(provs,w);
- if (wrapper.fail()) {
- request.log(SPRequest::SPWarn, string("htAccessControl plugin didn't recognize require rule: ") + w);
+ // Map alias in rule to the attribute.
+ if (!session) {
+ request.log(SPRequest::SPError, "htAccessControl plugin not given a valid session to evaluate, are you using lazy sessions?");
+ continue;
+ }
+
+ // Find the attribute matching the require rule.
+ map<string,const Attribute*>::const_iterator attr = session->getAttributes().find(w);
+ if (attr == session->getAttributes().end()) {
+ request.log(SPRequest::SPWarn, string("htAccessControl rule requires attribute (") + w + "), not found in session");
continue;
}
bool regexp=false;
- const char* vals;
- if (!strcmp(wrapper->getHeader(),"REMOTE_USER"))
- vals=remote_user.c_str();
- else
- if (sta->m_dc->bUseEnvVars!=0) {
- if (sta->m_rc && sta->m_rc->env) vals=ap_table_get(sta->m_rc->env,wrapper->getHeader());
- else vals = NULL;
- } else {
- vals=ap_table_get(sta->m_req->headers_in,wrapper->getHeader());
- }
+ bool caseSensitive = attr->second->isCaseSensitive();
+ const vector<string>& vals = attr->second->getSerializedValues();
- while (*t && vals && *vals) {
+ while (!auth_OK[x] && *t) {
w=ap_getword_conf(sta->m_req->pool,&t);
if (*w=='~') {
regexp=true;
re=temp;
}
- string vals_str(vals);
- int j = 0;
- for (unsigned int i = 0; i < vals_str.length(); i++) {
- if (vals_str.at(i) == ';') {
- if (i == 0) {
- request.log(SPRequest::SPError, string("htAccessControl plugin found invalid header encoding (") +
- vals + "): starts with a semicolon");
- throw saml::SAMLException("Invalid information supplied to authorization plugin.");
- }
-
- if (vals_str.at(i-1) == '\\') {
- vals_str.erase(i-1, 1);
- i--;
- continue;
- }
-
- string val = vals_str.substr(j, i-j);
- j = i+1;
- if (regexp) {
- auto_ptr<XMLCh> trans(fromUTF8(val.c_str()));
- if (re->matches(trans.get())) {
- request.log(SPRequest::SPDebug, string("htAccessControl plugin expecting ") + w +
- ", got " + val + ": authorization granted");
- SHIB_AP_CHECK_IS_OK;
- }
- }
- else if ((wrapper->getCaseSensitive() && val==w) || (!wrapper->getCaseSensitive() && !strcasecmp(val.c_str(),w))) {
- request.log(SPRequest::SPDebug, string("htAccessControl plugin expecting ") + w +
- ", got " + val + ": authorization granted.");
+ for (vector<string>::const_iterator v=vals.begin(); !auth_OK[x] && v!=vals.end(); ++v) {
+ if (regexp) {
+ auto_ptr<XMLCh> trans(fromUTF8(v->c_str()));
+ if (re->matches(trans.get())) {
+ request.log(SPRequest::SPDebug,
+ string("htAccessControl plugin expecting ") + w + ", got " + *v + ": authorization granted"
+ );
SHIB_AP_CHECK_IS_OK;
}
- else {
- request.log(SPRequest::SPDebug, string("htAccessControl plugin expecting ") + w +
- ", got " + val + ": authoritzation not granted.");
- }
}
- }
-
- string val = vals_str.substr(j, vals_str.length()-j);
- if (regexp) {
- auto_ptr<XMLCh> trans(fromUTF8(val.c_str()));
- if (re->matches(trans.get())) {
- request.log(SPRequest::SPDebug, string("htAccessControl plugin expecting ") + w +
- ", got " + val + ": authorization granted.");
+ else if ((caseSensitive && *v == w) || (!caseSensitive && !strcasecmp(v->c_str(),w))) {
+ request.log(SPRequest::SPDebug,
+ string("htAccessControl plugin expecting ") + w + ", got " + *v + ": authorization granted."
+ );
SHIB_AP_CHECK_IS_OK;
}
- }
- else if ((wrapper->getCaseSensitive() && val==w) || (!wrapper->getCaseSensitive() && !strcasecmp(val.c_str(),w))) {
- request.log(SPRequest::SPDebug, string("htAccessControl plugin expecting ") + w +
- ", got " + val + ": authorization granted");
- SHIB_AP_CHECK_IS_OK;
- }
- else {
- request.log(SPRequest::SPDebug, string("htAccessControl plugin expecting ") + w +
- ", got " + val + ": authorization not granted");
+ else {
+ request.log(SPRequest::SPDebug,
+ string("htAccessControl plugin expecting ") + w + ", got " + *v + ": authorization not granted."
+ );
+ }
}
}
catch (XMLException& ex) {
auto_ptr_char tmp(ex.getMessage());
- request.log(SPRequest::SPError, string("htAccessControl plugin caught exception while parsing regular expression (")
- + w + "): " + tmp.get());
+ request.log(SPRequest::SPError,
+ string("htAccessControl plugin caught exception while parsing regular expression (") + w + "): " + tmp.get()
+ );
}
}
}
extern "C" apr_status_t shib_exit(void* data)
{
if (g_Config) {
- g_Config->shutdown();
+ g_Config->term();
g_Config = NULL;
}
ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,NULL,"shib_exit() done");
#endif
ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(s),"shib_child_exit(%d) dealing with g_Config..", (int)getpid());
- g_Config->shutdown();
+ g_Config->term();
g_Config = NULL;
ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(s),"shib_child_exit() done");
exit(1);
}
+ g_Config=&SPConfig::getConfig();
+ g_Config->setFeatures(
+ SPConfig::Caching |
+ SPConfig::Listener |
+ SPConfig::Metadata |
+ SPConfig::RequestMapping |
+ SPConfig::InProcess |
+ SPConfig::Logging
+ );
+ if (!g_Config->init(g_szSchemaDir)) {
+ ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize libraries");
+ exit(1);
+ }
+ g_Config->AccessControlManager.registerFactory(HT_ACCESS_CONTROL,&htAccessFactory);
+ g_Config->RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER,&ApacheRequestMapFactory);
+
try {
- g_Config=&ShibTargetConfig::getConfig();
- SPConfig::getConfig().setFeatures(
- SPConfig::Caching |
- SPConfig::Listener |
- SPConfig::Metadata |
- SPConfig::AAP |
- SPConfig::RequestMapping |
- SPConfig::InProcess |
- SPConfig::Logging
- );
- if (!g_Config->init(g_szSchemaDir)) {
- ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize libraries");
- exit(1);
- }
- SPConfig::getConfig().AccessControlManager.registerFactory(HT_ACCESS_CONTROL,&htAccessFactory);
- SPConfig::getConfig().RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER,&ApacheRequestMapFactory);
-
- if (!g_Config->load(g_szSHIBConfig)) {
- ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to load configuration");
- exit(1);
- }
-
- IConfig* conf=g_Config->getINI();
- xmltooling::Locker locker(conf);
- const PropertySet* props=conf->getPropertySet("Local");
- if (props) {
- pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
- if (unsetValue.first)
- g_unsetHeaderValue = unsetValue.second;
- }
+ DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
+ XercesJanitor<DOMDocument> docjanitor(dummydoc);
+ DOMElement* dummy = dummydoc->createElementNS(NULL,path);
+ auto_ptr_XMLCh src(g_szSHIBConfig);
+ dummy->setAttributeNS(NULL,path,src.get());
+
+ g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
+ g_Config->getServiceProvider()->init();
}
- catch (...) {
- ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to initialize system");
+ catch (exception& ex) {
+ ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),ex.what());
+ ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"shib_child_init() failed to load configuration");
exit(1);
}
+ ServiceProvider* sp=g_Config->getServiceProvider();
+ xmltooling::Locker locker(sp);
+ const PropertySet* props=sp->getPropertySet("Local");
+ if (props) {
+ pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ if (unsetValue.first)
+ g_unsetHeaderValue = unsetValue.second;
+ }
+
// Set the cleanup handler
apr_pool_cleanup_register(p, NULL, &shib_exit, &shib_child_exit);