-/*
- * Copyright 2001-2011 Internet2
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
*
- * 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
+ * UCAID licenses this file to you 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
+ * 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.
+ * 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.
*/
/**
#undef _XPG4_2
+#include <set>
+#include <memory>
+#include <fstream>
+#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+
// Apache specific header files
#include <httpd.h>
#include <http_config.h>
#include <apr_pools.h>
#endif
-#include <set>
-#include <memory>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-
+#include <cstddef>
#ifdef HAVE_UNISTD_H
#include <unistd.h> // for getpid()
#endif
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
using xercesc::RegularExpression;
using xercesc::XMLException;
int bExportAssertion; // export SAML assertion to the environment?
int bUseEnvVars; // use environment?
int bUseHeaders; // use headers?
+ int bExpireRedirects; // expire redirects?
};
// creates per-directory config structure
dc->bExportAssertion = -1;
dc->bUseEnvVars = -1;
dc->bUseHeaders = -1;
+ dc->bExpireRedirects = -1;
return dc;
}
dc->bAuthoritative=((child->bAuthoritative==-1) ? parent->bAuthoritative : child->bAuthoritative);
dc->bUseEnvVars=((child->bUseEnvVars==-1) ? parent->bUseEnvVars : child->bUseEnvVars);
dc->bUseHeaders=((child->bUseHeaders==-1) ? parent->bUseHeaders : child->bUseHeaders);
+ dc->bExpireRedirects=((child->bExpireRedirects==-1) ? parent->bExpireRedirects : child->bExpireRedirects);
return dc;
}
return nullptr;
}
+extern "C" const char* shib_set_acl_slot(cmd_parms* params, shib_dir_config* dc, char* arg)
+{
+ bool absolute;
+ switch (*arg) {
+ case 0:
+ absolute = false;
+ break;
+ case '/':
+ case '\\':
+ absolute = true;
+ break;
+ case '.':
+ absolute = (*(arg+1) == '.' || *(arg+1) == '/' || *(arg+1) == '\\');
+ break;
+ default:
+ absolute = *(arg+1) == ':';
+ }
+
+ if (absolute || !params->path)
+ dc->szAccessControl = ap_pstrdup(params->pool, arg);
+ else
+ dc->szAccessControl = ap_pstrcat(params->pool, params->path, arg);
+ return nullptr;
+}
class ShibTargetApache : public AbstractSPRequest
#if defined(SHIBSP_HAVE_GSSAPI) && !defined(SHIB_APACHE_13)
long sendRedirect(const char* url) {
HTTPResponse::sendRedirect(url);
ap_table_set(m_req->headers_out, "Location", url);
+ if (m_dc->bExpireRedirects != 0) {
+ ap_table_set(m_req->err_headers_out, "Expires", "Wed, 01 Jan 1997 12:00:00 GMT");
+ ap_table_set(m_req->err_headers_out, "Cache-Control", "private,no-store,no-cache,max-age=0");
+ }
return REDIRECT;
}
const vector<string>& getClientCertificates() const {
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_check_user(%d): ENTER", (int)getpid());
- ostringstream threadid;
- threadid << "[" << getpid() << "] shib_check_user" << '\0';
- xmltooling::NDC ndc(threadid.str().c_str());
+ string threadid("[");
+ threadid += lexical_cast<string>(getpid()) + "] shib_check_user";
+ xmltooling::NDC ndc(threadid.c_str());
try {
ShibTargetApache sta(r,false,true);
// export happened successfully.. this user is ok.
return OK;
}
- catch (exception& e) {
+ catch (std::exception& e) {
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_check_user threw an exception: %s", e.what());
return SERVER_ERROR;
}
if (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib))->bOff==1)
return DECLINED;
- ostringstream threadid;
- threadid << "[" << getpid() << "] shib_handler" << '\0';
- xmltooling::NDC ndc(threadid.str().c_str());
+ string threadid("[");
+ threadid += lexical_cast<string>(getpid()) + "] shib_handler";
+ xmltooling::NDC ndc(threadid.c_str());
#ifndef SHIB_APACHE_13
// With 2.x, this handler always runs, though last.
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "doHandler() did not do anything.");
return SERVER_ERROR;
}
- catch (exception& e) {
+ catch (std::exception& e) {
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_handler threw an exception: %s", e.what());
return SERVER_ERROR;
}
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_auth_checker(%d): ENTER", (int)getpid());
- ostringstream threadid;
- threadid << "[" << getpid() << "] shib_auth_checker" << '\0';
- xmltooling::NDC ndc(threadid.str().c_str());
+ string threadid("[");
+ threadid += lexical_cast<string>(getpid()) + "] shib_auth_checker";
+ xmltooling::NDC ndc(threadid.c_str());
try {
ShibTargetApache sta(r,false,false);
// Just let Apache (or some other module) decide what to do.
return DECLINED;
}
- catch (exception& e) {
+ catch (std::exception& e) {
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, SH_AP_R(r), "shib_auth_checker threw an exception: %s", e.what());
return SERVER_ERROR;
}
{
public:
ApacheRequestMapper(const xercesc::DOMElement* e);
- ~ApacheRequestMapper() { delete m_mapper; delete m_htaccess; delete m_staKey; delete m_propsKey; }
+ ~ApacheRequestMapper() {}
Lockable* lock() { return m_mapper->lock(); }
void unlock() { m_staKey->setData(nullptr); m_propsKey->setData(nullptr); m_mapper->unlock(); }
Settings getSettings(const HTTPRequest& request) const;
const xercesc::DOMElement* getElement() const;
private:
- RequestMapper* m_mapper;
- ThreadKey* m_staKey;
- ThreadKey* m_propsKey;
- AccessControl* m_htaccess;
+ scoped_ptr<RequestMapper> m_mapper;
+ scoped_ptr<ThreadKey> m_staKey,m_propsKey;
+ mutable htAccessControl m_htaccess;
};
RequestMapper* ApacheRequestMapFactory(const xercesc::DOMElement* const & e)
return new ApacheRequestMapper(e);
}
-ApacheRequestMapper::ApacheRequestMapper(const xercesc::DOMElement* e) : m_mapper(nullptr), m_staKey(nullptr), m_propsKey(nullptr), m_htaccess(nullptr)
+ApacheRequestMapper::ApacheRequestMapper(const xercesc::DOMElement* e)
+ : m_mapper(SPConfig::getConfig().RequestMapperManager.newPlugin(XML_REQUEST_MAPPER,e)),
+ m_staKey(ThreadKey::create(nullptr)), m_propsKey(ThreadKey::create(nullptr))
{
- m_mapper=SPConfig::getConfig().RequestMapperManager.newPlugin(XML_REQUEST_MAPPER,e);
- m_htaccess=new htAccessControl();
- m_staKey=ThreadKey::create(nullptr);
- m_propsKey=ThreadKey::create(nullptr);
}
RequestMapper::Settings ApacheRequestMapper::getSettings(const HTTPRequest& request) const
{
- Settings s=m_mapper->getSettings(request);
+ Settings s = m_mapper->getSettings(request);
m_staKey->setData((void*)dynamic_cast<const ShibTargetApache*>(&request));
m_propsKey->setData((void*)s.first);
- return pair<const PropertySet*,AccessControl*>(this,s.second ? s.second : m_htaccess);
+ return pair<const PropertySet*,AccessControl*>(this, s.second ? s.second : &m_htaccess);
}
pair<bool,bool> ApacheRequestMapper::getBool(const char* name, const char* ns) const
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, nullptr);
+ ap_table_do(_rm_get_all_table_walk, &properties, sta->m_dc->tSettings, NULL);
}
const PropertySet* ApacheRequestMapper::getPropertySet(const char* name, const char* ns) const
{
bool caseSensitive = attr->isCaseSensitive();
const vector<string>& vals = attr->getSerializedValues();
- for (vector<string>::const_iterator v=vals.begin(); v!=vals.end(); ++v) {
+ for (vector<string>::const_iterator v = vals.begin(); v != vals.end(); ++v) {
if (re) {
auto_arrayptr<XMLCh> trans(fromUTF8(v->c_str()));
if (re->matches(trans.get())) {
aclresult_t result = shib_acl_false;
try {
ifstream aclfile(sta->m_dc->szAccessControl);
+ if (!aclfile)
+ throw ConfigurationException("Unable to open access control file ($1).", params(1, sta->m_dc->szAccessControl));
xercesc::DOMDocument* acldoc = XMLToolingConfig::getConfig().getParser().parse(aclfile);
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.");
- auto_ptr<AccessControl> aclplugin(SPConfig::getConfig().AccessControlManager.newPlugin(t.c_str(), acldoc->getDocumentElement()));
+ scoped_ptr<AccessControl> aclplugin(SPConfig::getConfig().AccessControlManager.newPlugin(t.c_str(), acldoc->getDocumentElement()));
Locker acllock(aclplugin.get());
result = aclplugin->authorized(request, session);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
request.log(SPRequest::SPError, ex.what());
}
}
try {
- auto_ptr<RegularExpression> re;
+ scoped_ptr<RegularExpression> re;
if (regexp) {
- delete re.release();
auto_arrayptr<XMLCh> trans(fromUTF8(w));
- auto_ptr<xercesc::RegularExpression> temp(new xercesc::RegularExpression(trans.get()));
- re=temp;
+ re.reset(new xercesc::RegularExpression(trans.get()));
}
pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> attrs2(attrs);
if (!g_Config->instantiate(g_szSHIBConfig, true))
throw runtime_error("unknown error");
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),"%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);
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_out_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
// can't use overlap call because it will collapse Set-Cookie headers
//apr_table_overlap(r->headers_out, rc->hdr_out, APR_OVERLAP_TABLES_MERGE);
- apr_table_do(_table_add,r->headers_out, rc->hdr_out,nullptr);
+ apr_table_do(_table_add,r->headers_out, rc->hdr_out,NULL);
}
/* remove ourselves from the filter chain */
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r),"shib_err_filter: merging %d headers", apr_table_elts(rc->hdr_out)->nelts);
// can't use overlap call because it will collapse Set-Cookie headers
//apr_table_overlap(r->err_headers_out, rc->hdr_out, APR_OVERLAP_TABLES_MERGE);
- apr_table_do(_table_add,r->err_headers_out, rc->hdr_out,nullptr);
+ apr_table_do(_table_add,r->err_headers_out, rc->hdr_out,NULL);
}
/* remove ourselves from the filter chain */
{"ShibRequestSetting", (config_fn_t)shib_table_set, nullptr,
OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth request property for content"},
- {"ShibAccessControl", (config_fn_t)ap_set_string_slot,
- (void *) XtOffsetOf (shib_dir_config, szAccessControl),
+ {"ShibAccessControl", (config_fn_t)shib_set_acl_slot, nullptr,
OR_AUTHCFG, TAKE1, "Set arbitrary Shibboleth access control plugin for content"},
{"ShibDisable", (config_fn_t)ap_set_flag_slot,
{"ShibUseHeaders", (config_fn_t)ap_set_flag_slot,
(void *) XtOffsetOf (shib_dir_config, bUseHeaders),
OR_AUTHCFG, FLAG, "Export attributes using custom HTTP headers"},
+ {"ShibExpireRedirects", (config_fn_t)ap_set_flag_slot,
+ (void *) XtOffsetOf (shib_dir_config, bExpireRedirects),
+ OR_AUTHCFG, FLAG, "Expire SP-generated redirects"},
{nullptr}
};
AP_INIT_TAKE2("ShibRequestSetting", (config_fn_t)shib_table_set, nullptr,
OR_AUTHCFG, "Set arbitrary Shibboleth request property for content"),
- AP_INIT_TAKE1("ShibAccessControl", (config_fn_t)ap_set_string_slot,
- (void *) offsetof (shib_dir_config, szAccessControl),
+ AP_INIT_TAKE1("ShibAccessControl", (config_fn_t)shib_set_acl_slot, nullptr,
OR_AUTHCFG, "Set arbitrary Shibboleth access control plugin for content"),
AP_INIT_FLAG("ShibDisable", (config_fn_t)ap_set_flag_slot,
AP_INIT_FLAG("ShibUseHeaders", (config_fn_t)ap_set_flag_slot,
(void *) offsetof (shib_dir_config, bUseHeaders),
OR_AUTHCFG, "Export attributes using custom HTTP headers"),
+ AP_INIT_FLAG("ShibExpireRedirects", (config_fn_t)ap_set_flag_slot,
+ (void *) offsetof (shib_dir_config, bExpireRedirects),
+ OR_AUTHCFG, "Expire SP-generated redirects"),
{nullptr}
};