/*
- * Copyright 2001-2007 Internet2
+ * Copyright 2001-2009 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <fstream>
#include <sstream>
+#ifndef SHIBSP_LITE
+# include <saml/exceptions.h>
+# include <saml/saml2/metadata/MetadataProvider.h>
+#endif
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/PathResolver.h>
{
// The properties we need can be set in the RequestMap, or the Errors element.
bool mderror = dynamic_cast<const opensaml::saml2md::MetadataException*>(tp.getRichException())!=NULL;
+ bool accesserror = (strcmp(page, "access")==0);
pair<bool,const char*> redirectErrors = pair<bool,const char*>(false,NULL);
pair<bool,const char*> pathname = pair<bool,const char*>(false,NULL);
- const PropertySet* props=app ? app->getPropertySet("Errors") : NULL;
+ // Strictly for error handling, detect a NULL application and point at the default.
+ if (!app)
+ app = request.getServiceProvider().getApplication("default");
+
+ const PropertySet* props=app->getPropertySet("Errors");
+
+ // First look for settings in the request map of the form pageError.
try {
RequestMapper::Settings settings = request.getRequestSettings();
if (mderror)
log.error(ex.what());
}
+ // Check for redirection on errors instead of template.
if (mayRedirect) {
- // Check for redirection on errors instead of template.
if (!redirectErrors.first && props)
redirectErrors = props->getString("redirectErrors");
if (redirectErrors.first) {
request.setResponseHeader("Expires","01-Jan-1997 12:00:00 GMT");
request.setResponseHeader("Cache-Control","private,no-store,no-cache");
+ // Nothing in the request map, so check for a property named "page" in the Errors property set.
if (!pathname.first && props) {
if (mderror)
pathname=props->getString("metadata");
if (!pathname.first)
pathname=props->getString(page);
}
- if (pathname.first) {
- string fname(pathname.second);
+
+ // If there's still no template to use, just use pageError.html unless it's an access issue.
+ string fname;
+ if (!pathname.first) {
+ if (!accesserror) {
+ fname = string(page) + "Error.html";
+ pathname.second = fname.c_str();
+ }
+ }
+ else {
+ fname = pathname.second;
+ }
+
+ // If we have a template to use, use it.
+ if (!fname.empty()) {
ifstream infile(XMLToolingConfig::getConfig().getPathResolver()->resolve(fname, PathResolver::XMLTOOLING_CFG_FILE).c_str());
if (infile) {
tp.setPropertySet(props);
stringstream str;
XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp, tp.getRichException());
- return request.sendResponse(str);
+ return request.sendError(str);
}
}
- if (!strcmp(page,"access")) {
+ // If we got here, then either it's an access error or a template failed.
+ if (accesserror) {
istringstream msg("Access Denied");
return request.sendResponse(msg, HTTPResponse::XMLTOOLING_HTTP_STATUS_FORBIDDEN);
}
- log.error("sendError could not process error template (%s)", page);
+ log.error("sendError could not process error template (%s)", pathname.second);
istringstream msg("Internal Server Error. Please contact the site administrator.");
return request.sendError(msg);
}
SPConfig::getConfig().ServiceProviderManager.registerFactory(XML_SERVICE_PROVIDER, XMLServiceProviderFactory);
}
+ServiceProvider::ServiceProvider()
+{
+}
+
+ServiceProvider::~ServiceProvider()
+{
+}
+
pair<bool,long> ServiceProvider::doAuthentication(SPRequest& request, bool handler) const
{
#ifdef _DEBUG
return initiator->run(request,false);
}
+ request.setAuthType("shibboleth");
+
// We're done. Everything is okay. Nothing to report. Nothing to do..
// Let the caller decide how to proceed.
log.debug("doAuthentication succeeded");
return make_pair(false,0L);
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
return make_pair(true,sendError(log, request, app, "session", tp));
}
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
return make_pair(true,sendError(log, request, app, "access", tp));
// Export the attributes.
const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
+ if (a->second->isInternal())
+ continue;
string header(app->getSecureHeader(request, a->first.c_str()));
const vector<string>& vals = a->second->getSerializedValues();
for (vector<string>::const_iterator v = vals.begin(); v!=vals.end(); ++v) {
for (vector<string>::const_iterator rmid = rmids.begin(); !remoteUserSet && rmid != rmids.end(); ++rmid) {
pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> matches =
attributes.equal_range(*rmid);
- while (matches.first != matches.second) {
+ for (; matches.first != matches.second; ++matches.first) {
const vector<string>& vals = matches.first->second->getSerializedValues();
if (!vals.empty()) {
request.setRemoteUser(vals.front().c_str());
return make_pair(false,0L);
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
return make_pair(true,sendError(log, request, app, "session", tp));
throw ConfigurationException("Configured Shibboleth handler failed to process the request.");
}
catch (exception& e) {
+ request.log(SPRequest::SPError, e.what());
TemplateParameters tp(&e);
tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
tp.m_request = &request;