#include <shibsp/handler/AssertionConsumerService.h>
#include <shibsp/handler/LogoutInitiator.h>
#include <shibsp/handler/SessionInitiator.h>
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/logging.h>
#include <xmltooling/util/DateTime.h>
#include <xmltooling/util/NDC.h>
using namespace xmltooling::logging;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
#define WSFED_NS "http://schemas.xmlsoap.org/ws/2003/07/secext"
{
// We have to know the IdP to function.
if (entityID.empty() || !checkCompatibility(request, isHandler))
- return make_pair(false,0L);
+ return make_pair(false, 0L);
string target;
pair<bool,const char*> prop;
pair<bool,const char*> acClass;
- const Handler* ACS=nullptr;
- const Application& app=request.getApplication();
+ const Handler* ACS = nullptr;
+ const Application& app = request.getApplication();
if (isHandler) {
prop.second = request.getParameter("acsIndex");
// Since we're not passing by index, we need to fully compute the return URL.
// Compute the ACS URL. We add the ACS location to the base handlerURL.
- string ACSloc=request.getHandlerURL(target.c_str());
+ string ACSloc = request.getHandlerURL(target.c_str());
prop = ACS->getString("Location");
if (prop.first)
ACSloc += prop.second;
void ADFSSessionInitiator::receive(DDF& in, ostream& out)
{
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) to generate ADFS request", aid ? aid : "(missing)");
DDFJanitor jout(ret);
// Wrap the outgoing object with a Response facade.
- auto_ptr<HTTPResponse> http(getResponse(ret));
+ scoped_ptr<HTTPResponse> http(getResponse(ret));
string relayState(in["RelayState"].string() ? in["RelayState"].string() : "");
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, nullptr, *http.get(), entityID, acsLocation, in["authnContextClassRef"].string(), relayState);
+ doRequest(*app, nullptr, *http, entityID, acsLocation, in["authnContextClassRef"].string(), relayState);
if (!ret.isstruct())
ret.structure();
ret.addmember("RelayState").unsafe_string(relayState.c_str());
{
#ifndef SHIBSP_LITE
// Use metadata to invoke the SSO service directly.
- MetadataProvider* m=app.getMetadataProvider();
+ MetadataProvider* m = app.getMetadataProvider();
Locker locker(m);
MetadataProviderCriteria mc(app, entityID, &IDPSSODescriptor::ELEMENT_QNAME, m_binding.get());
- pair<const EntityDescriptor*,const RoleDescriptor*> entity=m->getEntityDescriptor(mc);
+ pair<const EntityDescriptor*,const RoleDescriptor*> entity = m->getEntityDescriptor(mc);
if (!entity.first) {
m_log.warn("unable to locate metadata for provider (%s)", entityID);
throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID));
else if (!entity.second) {
m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate ADFS-aware identity provider role for provider (%s)", entityID);
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Unable to locate ADFS-aware identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID));
}
const EndpointType* ep = EndpointManager<SingleSignOnService>(
if (!ep) {
m_log.warn("unable to locate compatible SSO service for provider (%s)", entityID);
if (getParent())
- return make_pair(false,0L);
+ return make_pair(false, 0L);
throw MetadataException("Unable to locate compatible SSO service for provider ($entityID)", namedparams(1, "entityID", entityID));
}
preserveRelayState(app, httpResponse, relayState);
- auto_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));
+ scoped_ptr<AuthnRequestEvent> ar_event(newAuthnRequestEvent(app, httpRequest));
if (ar_event.get()) {
ar_event->m_binding = WSFED_NS;
ar_event->m_protocol = WSFED_NS;
return make_pair(true, httpResponse.sendRedirect(req.c_str()));
#else
- return make_pair(false,0L);
+ return make_pair(false, 0L);
#endif
}
const saml1::NameIdentifier* saml1name=nullptr;
const saml1::AuthenticationStatement* saml1statement=nullptr;
- saml2::NameID* saml2name=nullptr;
+ const saml2::NameID* saml2name=nullptr;
const saml2::AuthnStatement* saml2statement=nullptr;
const XMLCh* authMethod=nullptr;
const XMLCh* authInstant=nullptr;
// To complete processing, we need to extract and resolve attributes and then create the session.
// Normalize a SAML 1.x NameIdentifier...
- auto_ptr<saml2::NameID> nameid(saml1name ? saml2::NameIDBuilder::buildNameID() : nullptr);
+ scoped_ptr<saml2::NameID> nameid(saml1name ? saml2::NameIDBuilder::buildNameID() : nullptr);
if (saml1name) {
nameid->setName(saml1name->getName());
nameid->setFormat(saml1name->getFormat());
// The context will handle deleting attributes and new tokens.
vector<const Assertion*> tokens(1,token);
- auto_ptr<ResolutionContext> ctx(
+ scoped_ptr<ResolutionContext> ctx(
resolveAttributes(
application,
policy.getIssuerMetadata(),
authMethod,
nullptr,
&tokens,
- ctx.get() ? &ctx->getResolvedAttributes() : nullptr
+ ctx ? &ctx->getResolvedAttributes() : nullptr
);
- auto_ptr<LoginEvent> login_event(newLoginEvent(application, httpRequest));
- if (login_event.get()) {
+ scoped_ptr<LoginEvent> login_event(newLoginEvent(application, httpRequest));
+ if (login_event) {
login_event->m_sessionID = session_id.c_str();
login_event->m_peer = entity;
login_event->m_protocol = WSFED_NS;
login_event->m_saml1AuthnStatement = saml1statement;
login_event->m_nameID = (saml1name ? nameid.get() : saml2name);
login_event->m_saml2AuthnStatement = saml2statement;
- if (ctx.get())
+ if (ctx)
login_event->m_attributes = &ctx->getResolvedAttributes();
application.getServiceProvider().getTransactionLog()->write(*login_event);
}
try {
session = request.getSession(false, true, false); // don't cache it and ignore all checks
if (!session)
- return make_pair(false,0L);
+ return make_pair(false, 0L);
// We only handle ADFS sessions.
if (!XMLString::equals(session->getProtocol(), WSFED_NS) || !session->getEntityID()) {
session->unlock();
- return make_pair(false,0L);
+ return make_pair(false, 0L);
}
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
return make_pair(false,0L);
}
- session->unlock();
-
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively.
return doRequest(request.getApplication(), request, request, session);
session->unlock();
vector<string> headers(1,"Cookie");
headers.push_back("User-Agent");
- DDF out,in = wrap(request,&headers);
+ DDF out,in = wrap(request, &headers);
DDFJanitor jin(in), jout(out);
out=request.getServiceProvider().getListenerService()->send(in);
return unwrap(request, out);
return LogoutHandler::receive(in, out);
// Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
+ const char* aid = in["application_id"].string();
+ const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
if (!app) {
// Something's horribly wrong.
m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
}
// Unpack the request.
- auto_ptr<HTTPRequest> req(getRequest(in));
+ scoped_ptr<HTTPRequest> req(getRequest(in));
// Set up a response shim.
DDF ret(nullptr);
DDFJanitor jout(ret);
- auto_ptr<HTTPResponse> resp(getResponse(ret));
+ scoped_ptr<HTTPResponse> resp(getResponse(ret));
Session* session = nullptr;
try {
- session = app->getServiceProvider().getSessionCache()->find(*app, *req.get(), nullptr, nullptr);
+ session = app->getServiceProvider().getSessionCache()->find(*app, *req, nullptr, nullptr);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
}
// Since we're remoted, the result should either be a throw, which we pass on,
// a false/0 return, which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- doRequest(*app, *req.get(), *resp.get(), session);
+ doRequest(*app, *req, *resp, session);
}
else {
m_log.error("no issuing entityID found in session");
session->unlock();
- app->getServiceProvider().getSessionCache()->remove(*app, *req.get(), resp.get());
+ app->getServiceProvider().getSessionCache()->remove(*app, *req, resp.get());
}
}
out << ret;
const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse, Session* session
) const
{
+ Locker sessionLocker(session, false);
+
// Do back channel notification.
vector<string> sessions(1, session->getID());
if (!notifyBackChannel(application, httpRequest.getRequestURL(), sessions, false)) {
#ifndef SHIBSP_LITE
- auto_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
- if (logout_event.get()) {
+ scoped_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_PARTIAL;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
#endif
- session->unlock();
+ sessionLocker.assign();
+ session = nullptr;
application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
return sendLogoutPage(application, httpRequest, httpResponse, "partial");
}
#ifndef SHIBSP_LITE
- pair<bool,long> ret = make_pair(false,0L);
+ pair<bool,long> ret = make_pair(false, 0L);
try {
// With a session in hand, we can create a request message, if we can find a compatible endpoint.
- MetadataProvider* m=application.getMetadataProvider();
+ MetadataProvider* m = application.getMetadataProvider();
Locker metadataLocker(m);
MetadataProviderCriteria mc(application, session->getEntityID(), &IDPSSODescriptor::ELEMENT_QNAME, m_binding.get());
pair<const EntityDescriptor*,const RoleDescriptor*> entity=m->getEntityDescriptor(mc);
}
// Log the request.
- auto_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
- if (logout_event.get()) {
+ scoped_ptr<LogoutEvent> logout_event(newLogoutEvent(application, &httpRequest, session));
+ if (logout_event) {
logout_event->m_logoutType = LogoutEvent::LOGOUT_EVENT_UNKNOWN;
application.getServiceProvider().getTransactionLog()->write(*logout_event);
}
ret.first = true;
if (session) {
- session->unlock();
+ sessionLocker.assign();
session = nullptr;
application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse);
}
// Less noise for IdPs that don't support logout
m_log.info("unable to issue ADFS logout request: %s", mex.what());
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error issuing ADFS logout request: %s", ex.what());
}
- if (session)
- session->unlock();
-
return ret;
#else
throw ConfigurationException("Cannot perform logout using lite version of shibsp library.");
try {
app.getServiceProvider().getSessionCache()->remove(app, request, &request);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("error removing session (%s): %s", session_id.c_str(), ex.what());
}
}
#undef _XPG4_2
+#include <set>
+#include <memory>
+#include <fstream>
+#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.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()
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
using xercesc::RegularExpression;
using xercesc::XMLException;
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
{
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())) {
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);
// Although FastCGI supports writing before reading,
// many http clients (browsers) don't support it (so
// the connection deadlocks until a timeout expires!).
- char* content;
+ char* content = nullptr;
gstdin(&request, &content);
+ auto_arrayptr<char> wrapper(content);
try {
xmltooling::NDC ndc("FastCGI shibresponder");
print_error("<html><body>FastCGI Shibboleth responder caught an exception, check log for details.</body></html>");
}
- delete[] content;
-
// If the output streambufs had non-zero bufsizes and
// were constructed outside of the accept loop (i.e.
// their destructor won't be called here), they would
#include <shibsp/ServiceProvider.h>
#include <set>
-#include <sstream>
#include <fstream>
#include <stdexcept>
#include <process.h>
+#include <boost/lexical_cast.hpp>
#include <xmltooling/unicode.h>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
using namespace shibsp;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
// globals
struct site_t {
site_t(const DOMElement* e)
+ : m_name(XMLHelper::getAttrString(e, "", name)),
+ m_scheme(XMLHelper::getAttrString(e, "", scheme)),
+ m_port(XMLHelper::getAttrString(e, "", port)),
+ m_sslport(XMLHelper::getAttrString(e, "", sslport))
{
- auto_ptr_char n(e->getAttributeNS(nullptr,name));
- auto_ptr_char s(e->getAttributeNS(nullptr,scheme));
- auto_ptr_char p(e->getAttributeNS(nullptr,port));
- auto_ptr_char p2(e->getAttributeNS(nullptr,sslport));
- if (n.get()) m_name=n.get();
- if (s.get()) m_scheme=s.get();
- if (p.get()) m_port=p.get();
- if (p2.get()) m_sslport=p2.get();
e = XMLHelper::getFirstChildElement(e, Alias);
while (e) {
if (e->hasChildNodes()) {
- auto_ptr_char alias(e->getFirstChild()->getNodeValue());
+ auto_ptr_char alias(e->getTextContent());
m_aliases.insert(alias.get());
}
e = XMLHelper::getNextSiblingElement(e, Alias);
extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
{
- if (fdwReason==DLL_PROCESS_ATTACH)
- g_hinstDLL=hinstDLL;
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ g_hinstDLL = hinstDLL;
return TRUE;
}
return FALSE;
}
- pVer->dwExtensionVersion=HSE_VERSION;
+ pVer->dwExtensionVersion = HSE_VERSION;
strncpy(pVer->lpszExtensionDesc,"Shibboleth ISAPI Extension",HSE_MAX_EXT_DLL_NAME_LEN-1);
return TRUE;
}
return TRUE;
}
- g_Config=&SPConfig::getConfig();
+ g_Config = &SPConfig::getConfig();
g_Config->setFeatures(
SPConfig::Listener |
SPConfig::Caching |
SPConfig::Handlers
);
if (!g_Config->init()) {
- g_Config=nullptr;
+ g_Config = nullptr;
LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr,
"Filter startup failed during library initialization, check native log for help.");
return FALSE;
if (!g_Config->instantiate(nullptr, true))
throw runtime_error("unknown error");
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
g_Config->term();
g_Config=nullptr;
LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr, ex.what());
}
// Access implementation-specifics and site mappings.
- ServiceProvider* sp=g_Config->getServiceProvider();
+ ServiceProvider* sp = g_Config->getServiceProvider();
Locker locker(sp);
- const PropertySet* props=sp->getPropertySet("InProcess");
+ const PropertySet* props = sp->getPropertySet("InProcess");
if (props) {
- pair<bool,bool> flag=props->getBool("checkSpoofing");
+ pair<bool,bool> flag = props->getBool("checkSpoofing");
g_checkSpoofing = !flag.first || flag.second;
- flag=props->getBool("catchAll");
+ flag = props->getBool("catchAll");
g_catchAll = flag.first && flag.second;
- pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
+ pair<bool,const char*> unsetValue = props->getString("unsetHeaderValue");
if (unsetValue.first)
g_unsetHeaderValue = unsetValue.second;
if (g_checkSpoofing) {
unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
_set_invalid_parameter_handler(old);
- ostringstream keystr;
- keystr << randkey << randkey2 << randkey3 << randkey4;
- g_spoofKey = keystr.str();
+ g_spoofKey = lexical_cast<string>(randkey) + lexical_cast<string>(randkey2) +
+ lexical_cast<string>(randkey3) + lexical_cast<string>(randkey4);
}
else {
_set_invalid_parameter_handler(old);
"Filter failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually).");
locker.assign(); // pops lock on SP config
g_Config->term();
- g_Config=nullptr;
+ g_Config = nullptr;
return FALSE;
}
}
g_bNormalizeRequest = !flag.first || flag.second;
flag = props->getBool("safeHeaderNames");
g_bSafeHeaderNames = flag.first && flag.second;
- const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(),Site);
+ const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(), Site);
while (child) {
- auto_ptr_char id(child->getAttributeNS(nullptr,id));
- if (id.get())
- g_Sites.insert(pair<string,site_t>(id.get(),site_t(child)));
- child=XMLHelper::getNextSiblingElement(child,Site);
+ string id(XMLHelper::getAttrString(child, "", id));
+ if (!id.empty())
+ g_Sites.insert(make_pair(id, site_t(child)));
+ child = XMLHelper::getNextSiblingElement(child, Site);
}
}
}
- pVer->dwFilterVersion=HTTP_FILTER_REVISION;
- strncpy(pVer->lpszFilterDesc,"Shibboleth ISAPI Filter",SF_MAX_FILTER_DESC_LEN);
+ pVer->dwFilterVersion = HTTP_FILTER_REVISION;
+ strncpy(pVer->lpszFilterDesc, "Shibboleth ISAPI Filter", SF_MAX_FILTER_DESC_LEN);
pVer->dwFlags=(SF_NOTIFY_ORDER_HIGH |
SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT |
}
else {
m_hostname = var;
- if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
- m_hostname=site.m_name;
+ if (site.m_name != m_hostname && site.m_aliases.find(m_hostname) == site.m_aliases.end())
+ m_hostname = site.m_name;
}
if (!g_spoofKey.empty()) {
}
long sendResponse(istream& in, long status) {
string hdr = string("Connection: close\r\n");
- for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ for (multimap<string,string>::const_iterator i = m_headers.begin(); i != m_headers.end(); ++i)
hdr += i->first + ": " + i->second + "\r\n";
hdr += "\r\n";
const char* codestr="200 OK";
"Content-Length: 40\r\n"
"Expires: Wed, 01 Jan 1997 12:00:00 GMT\r\n"
"Cache-Control: private,no-store,no-cache,max-age=0\r\n";
- for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ for (multimap<string,string>::const_iterator i = m_headers.begin(); i != m_headers.end(); ++i)
hdr += i->first + ": " + i->second + "\r\n";
hdr += "\r\n";
m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, "302 Please Wait", (ULONG_PTR)hdr.c_str(), 0);
while (!m_pfc->GetServerVariable(m_pfc,lpszVariable,s,&size)) {
// Grumble. Check the error.
- DWORD e=GetLastError();
- if (e==ERROR_INSUFFICIENT_BUFFER)
+ DWORD e = GetLastError();
+ if (e == ERROR_INSUFFICIENT_BUFFER)
s.reserve(size);
else
break;
while (!m_pn->GetHeader(m_pfc,lpszName,s,&size)) {
// Grumble. Check the error.
- DWORD e=GetLastError();
- if (e==ERROR_INSUFFICIENT_BUFFER)
+ DWORD e = GetLastError();
+ if (e == ERROR_INSUFFICIENT_BUFFER)
s.reserve(size);
else
break;
extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)
{
// Is this a log notification?
- if (notificationType==SF_NOTIFY_LOG) {
+ if (notificationType == SF_NOTIFY_LOG) {
if (pfc->pFilterContext)
- ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=reinterpret_cast<char*>(pfc->pFilterContext);
+ ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName = reinterpret_cast<char*>(pfc->pFilterContext);
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
PHTTP_FILTER_PREPROC_HEADERS pn=(PHTTP_FILTER_PREPROC_HEADERS)pvNotification;
- try
- {
+ try {
// Determine web site number. This can't really fail, I don't think.
dynabuf buf(128);
GetServerVariable(pfc,"INSTANCE_ID",buf,10);
return WriteClientError(pfc, "Shibboleth Filter failed to obtain INSTANCE_ID server variable.");
// Match site instance to host name, skip if no match.
- map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
- if (map_i==g_Sites.end())
+ map<string,site_t>::const_iterator map_i = g_Sites.find(static_cast<char*>(buf));
+ if (map_i == g_Sites.end())
return SF_STATUS_REQ_NEXT_NOTIFICATION;
- ostringstream threadid;
- threadid << "[" << getpid() << "] isapi_shib" << '\0';
- xmltooling::NDC ndc(threadid.str().c_str());
+ string threadid("[");
+ threadid += lexical_cast<string>(getpid()) + "] isapi_shib";
+ xmltooling::NDC ndc(threadid.c_str());
ShibTargetIsapiF stf(pfc, pn, map_i->second);
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
catch(bad_alloc) {
- return WriteClientError(pfc,"Out of Memory");
+ return WriteClientError(pfc, "Out of Memory");
}
catch(long e) {
if (e==ERROR_NO_DATA)
- return WriteClientError(pfc,"A required variable or header was empty.");
+ return WriteClientError(pfc, "A required variable or header was empty.");
else
- return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error.");
+ return WriteClientError(pfc, "Shibboleth Filter detected unexpected IIS error.");
}
- catch (exception& e) {
+ catch (std::exception& e) {
LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr, e.what());
- return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details.");
+ return WriteClientError(pfc, "Shibboleth Filter caught an exception, check Event Log for details.");
}
catch(...) {
LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr, "Shibboleth Filter threw an unknown exception.");
if (g_catchAll)
- return WriteClientError(pfc,"Shibboleth Filter threw an unknown exception.");
+ return WriteClientError(pfc, "Shibboleth Filter threw an unknown exception.");
throw;
}
- return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");
+ return WriteClientError(pfc, "Shibboleth Filter reached unreachable code, save my walrus!");
}
bool SSL=(ssl=="on" || ssl=="ON");
// Scheme may come from site def or be derived from IIS.
- m_scheme=site.m_scheme;
+ m_scheme = site.m_scheme;
if (m_scheme.empty() || !g_bNormalizeRequest)
m_scheme = SSL ? "https" : "http";
else {
// Make sure SERVER_NAME is "authorized" for use on this site. If not, set to canonical name.
m_hostname=var;
- if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
- m_hostname=site.m_name;
+ if (site.m_name != m_hostname && site.m_aliases.find(m_hostname) == site.m_aliases.end())
+ m_hostname = site.m_name;
}
/*
setRequestURI(uri.c_str());
}
- ~ShibTargetIsapiE() { }
+ ~ShibTargetIsapiE() {}
const char* getScheme() const {
return m_scheme.c_str();
string getHeader(const char* name) const {
string hdr("HTTP_");
for (; *name; ++name) {
- if (*name=='-')
+ if (*name == '-')
hdr += '_';
else
hdr += toupper(*name);
}
long sendResponse(istream& in, long status) {
string hdr = string("Connection: close\r\n");
- for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ for (multimap<string,string>::const_iterator i = m_headers.begin(); i != m_headers.end(); ++i)
hdr += i->first + ": " + i->second + "\r\n";
hdr += "\r\n";
const char* codestr="200 OK";
"Content-Length: 40\r\n"
"Expires: Wed, 01 Jan 1997 12:00:00 GMT\r\n"
"Cache-Control: private,no-store,no-cache,max-age=0\r\n";
- for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+ for (multimap<string,string>::const_iterator i = m_headers.begin(); i != m_headers.end(); ++i)
hdr += i->first + ": " + i->second + "\r\n";
hdr += "\r\n";
m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, "302 Moved", 0, (LPDWORD)hdr.c_str());
m_lpECB->WriteClient(m_lpECB->ConnID, (LPVOID)redmsg, &resplen, HSE_IO_SYNC);
return HSE_STATUS_SUCCESS;
}
- // Decline happens in the POST processor if this isn't the shire url
+ // Decline happens in the POST processor if this isn't the handler url
// Note that it can also happen with HTAccess, but we don't support that, yet.
long returnDecline() {
return WriteClientError(
extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
{
try {
- ostringstream threadid;
- threadid << "[" << getpid() << "] isapi_shib_extension" << '\0';
- xmltooling::NDC ndc(threadid.str().c_str());
+ string threadid("[");
+ threadid += lexical_cast<string>(getpid()) + "] isapi_shib_extension";
+ xmltooling::NDC ndc(threadid.c_str());
// Determine web site number. This can't really fail, I don't think.
dynabuf buf(128);
return WriteClientError(lpECB, "Shibboleth Extension failed to obtain INSTANCE_ID server variable.");
// Match site instance to host name, skip if no match.
- map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
- if (map_i==g_Sites.end())
+ map<string,site_t>::const_iterator map_i = g_Sites.find(static_cast<char*>(buf));
+ if (map_i == g_Sites.end())
return WriteClientError(lpECB, "Shibboleth Extension not configured for web site (check ISAPI mappings in SP configuration).");
ShibTargetIsapiE ste(lpECB, map_i->second);
}
catch(bad_alloc) {
- return WriteClientError(lpECB,"Out of Memory");
+ return WriteClientError(lpECB, "Out of Memory");
}
catch(long e) {
if (e==ERROR_NO_DATA)
- return WriteClientError(lpECB,"A required variable or header was empty.");
+ return WriteClientError(lpECB, "A required variable or header was empty.");
else
- return WriteClientError(lpECB,"Server detected unexpected IIS error.");
+ return WriteClientError(lpECB, "Server detected unexpected IIS error.");
}
- catch (exception& e) {
+ catch (std::exception& e) {
LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr, e.what());
- return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details.");
+ return WriteClientError(lpECB, "Shibboleth Extension caught an exception, check Event Log for details.");
}
catch(...) {
LogEvent(nullptr, EVENTLOG_ERROR_TYPE, 2100, nullptr, "Shibboleth Extension threw an unknown exception.");
if (g_catchAll)
- return WriteClientError(lpECB,"Shibboleth Extension threw an unknown exception.");
+ return WriteClientError(lpECB, "Shibboleth Extension threw an unknown exception.");
throw;
}
#include <set>
#include <memory>
#include <fstream>
-#include <sstream>
#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/Threads.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace boost;
using namespace std;
// macros to output text to client
if (!g_Config->instantiate(pblock_findval("shib-config",pb), true))
throw runtime_error("unknown error");
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
pblock_nvinsert("error",ex.what(),pb);
g_Config->term();
g_Config=nullptr;
unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
_set_invalid_parameter_handler(old);
- ostringstream keystr;
- keystr << randkey << randkey2 << randkey3 << randkey4;
- g_spoofKey = keystr.str();
+ g_spoofKey = lexical_cast<string>(randkey) + lexical_cast<string>(randkey2) +
+ lexical_cast<string>(randkey3) + lexical_cast<string>(randkey4);
}
else {
_set_invalid_parameter_handler(old);
#define FUNC "shibboleth"
extern "C" NSAPI_PUBLIC int nsapi_shib(pblock* pb, ::Session* sn, Request* rq)
{
- ostringstream threadid;
- threadid << "[" << getpid() << "] nsapi_shib" << '\0';
- xmltooling::NDC ndc(threadid.str().c_str());
+ string threadid("[");
+ threadid += lexical_cast<string>(getpid()) + "] nsapi_shib";
+ xmltooling::NDC ndc(threadid.c_str());
try {
ShibTargetNSAPI stn(pb, sn, rq);
// this user is ok.
return REQ_PROCEED;
}
- catch (exception& e) {
+ catch (std::exception& e) {
log_error(LOG_FAILURE,FUNC,sn,rq,const_cast<char*>(e.what()));
return WriteClientError(sn, rq, FUNC, "Shibboleth module threw an exception, see web server log for error.");
}
#define FUNC "shib_handler"
extern "C" NSAPI_PUBLIC int shib_handler(pblock* pb, ::Session* sn, Request* rq)
{
- 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());
try {
ShibTargetNSAPI stn(pb, sn, rq);
return WriteClientError(sn, rq, FUNC, "Shibboleth handler did not do anything.");
}
- catch (exception& e) {
+ catch (std::exception& e) {
log_error(LOG_FAILURE,FUNC,sn,rq,const_cast<char*>(e.what()));
return WriteClientError(sn, rq, FUNC, "Shibboleth handler threw an exception, see web server log for error.");
}
{
public:
SunRequestMapper(const xercesc::DOMElement* e);
- ~SunRequestMapper() { delete m_mapper; delete m_stKey; delete m_propsKey; }
+ ~SunRequestMapper() {}
Lockable* lock() { return m_mapper->lock(); }
void unlock() { m_stKey->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_stKey;
- ThreadKey* m_propsKey;
+ scoped_ptr<RequestMapper> m_mapper;
+ scoped_ptr<ThreadKey> m_stKey, m_propsKey;
};
RequestMapper* SunRequestMapFactory(const xercesc::DOMElement* const & e)
return new SunRequestMapper(e);
}
-SunRequestMapper::SunRequestMapper(const xercesc::DOMElement* e) : m_mapper(nullptr), m_stKey(nullptr), m_propsKey(nullptr)
+SunRequestMapper::SunRequestMapper(const xercesc::DOMElement* e)
+ : m_mapper(SPConfig::getConfig().RequestMapperManager.newPlugin(XML_REQUEST_MAPPER,e)),
+ m_stKey(ThreadKey::create(nullptr)),
+ m_propsKey(ThreadKey::create(nullptr))
{
- m_mapper = SPConfig::getConfig().RequestMapperManager.newPlugin(XML_REQUEST_MAPPER,e);
- m_stKey=ThreadKey::create(nullptr);
- m_propsKey=ThreadKey::create(nullptr);
}
RequestMapper::Settings SunRequestMapper::getSettings(const HTTPRequest& request) const
if (stn && !ns && name) {
// Override int properties.
const char* param=pblock_findval(name,stn->m_pb);
- if (param)
- return pair<bool,unsigned int>(true,strtol(param,nullptr,10));
+ if (param) {
+ try {
+ return pair<bool,unsigned int>(true,lexical_cast<unsigned int>(param));
+ }
+ catch (bad_lexical_cast&) {
+ return pair<bool,unsigned int>(false,0);
+ }
+ }
}
return s ? s->getUnsignedInt(name,ns) : pair<bool,unsigned int>(false,0);
}
# define ODBCSTORE_EXPORTS
#endif
-#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/logging.h>
#include <xmltooling/unicode.h>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/StorageService.h>
#include <xmltooling/util/Threads.h>
#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
#include <sql.h>
#include <sqlext.h>
+#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string.hpp>
+
using namespace xmltooling::logging;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
#define PLUGIN_VER_MAJOR 1
SQLHDBC getHDBC();
SQLHSTMT getHSTMT(SQLHDBC);
- pair<int,int> getVersion(SQLHDBC);
+ pair<SQLINTEGER,SQLINTEGER> getVersion(SQLHDBC);
pair<bool,bool> log_error(SQLHANDLE handle, SQLSMALLINT htype, const char* checkfor=nullptr);
static void* cleanup_fn(void*);
Category& m_log;
Capabilities m_caps;
int m_cleanupInterval;
- CondWait* shutdown_wait;
+ scoped_ptr<CondWait> shutdown_wait;
Thread* cleanup_thread;
bool shutdown;
strftime(ret,32,"{ts '%Y-%m-%d %H:%M:%S'}",ptime);
}
- // make a string safe for SQL command
- // result to be free'd only if it isn't the input
- static char *makeSafeSQL(const char *src)
- {
- int ns = 0;
- int nc = 0;
- char *s;
-
- // see if any conversion needed
- for (s=(char*)src; *s; nc++,s++) if (*s=='\'') ns++;
- if (ns==0) return ((char*)src);
-
- char *safe = new char[(nc+2*ns+1)];
- for (s=safe; *src; src++) {
- if (*src=='\'') *s++ = '\'';
- *s++ = (char)*src;
- }
- *s = '\0';
- return (safe);
- }
+ class SQLString {
+ const char* m_src;
+ string m_copy;
+ public:
+ SQLString(const char* src) : m_src(src) {
+ if (strchr(src, '\'')) {
+ m_copy = src;
+ replace_all(m_copy, "'", "''");
+ }
+ }
- void freeSafeSQL(char *safe, const char *src)
- {
- if (safe!=src)
- delete[](safe);
- }
+ operator const char*() const {
+ return tostr();
+ }
+
+ const char* tostr() const {
+ return m_copy.empty() ? m_src : m_copy.c_str();
+ }
+ };
};
ODBCStorageService::ODBCStorageService(const DOMElement* e) : m_log(Category::getInstance("XMLTooling.StorageService")),
m_caps(XMLHelper::getAttrInt(e, 255, contextSize), XMLHelper::getAttrInt(e, 255, keySize), XMLHelper::getAttrInt(e, 255, stringSize)),
- m_cleanupInterval(900), shutdown_wait(nullptr), cleanup_thread(nullptr), shutdown(false), m_henv(SQL_NULL_HANDLE), m_isolation(SQL_TXN_SERIALIZABLE)
+ m_cleanupInterval(XMLHelper::getAttrInt(e, 900, cleanupInterval)),
+ cleanup_thread(nullptr), shutdown(false), m_henv(SQL_NULL_HANDLE), m_isolation(SQL_TXN_SERIALIZABLE)
{
#ifdef _DEBUG
xmltooling::NDC ndc("ODBCStorageService");
#endif
-
- const XMLCh* tag=e ? e->getAttributeNS(nullptr,cleanupInterval) : nullptr;
- if (tag && *tag)
- m_cleanupInterval = XMLString::parseInt(tag);
- if (!m_cleanupInterval)
- m_cleanupInterval = 900;
-
- auto_ptr_char iso(e ? e->getAttributeNS(nullptr,isolationLevel) : nullptr);
- if (iso.get() && *iso.get()) {
- if (!strcmp(iso.get(),"SERIALIZABLE"))
- m_isolation = SQL_TXN_SERIALIZABLE;
- else if (!strcmp(iso.get(),"REPEATABLE_READ"))
- m_isolation = SQL_TXN_REPEATABLE_READ;
- else if (!strcmp(iso.get(),"READ_COMMITTED"))
- m_isolation = SQL_TXN_READ_COMMITTED;
- else if (!strcmp(iso.get(),"READ_UNCOMMITTED"))
- m_isolation = SQL_TXN_READ_UNCOMMITTED;
- else
- throw XMLToolingException("Unknown transaction isolationLevel property.");
- }
+ string iso(XMLHelper::getAttrString(e, "SERIALIZABLE", isolationLevel));
+ if (iso == "SERIALIZABLE")
+ m_isolation = SQL_TXN_SERIALIZABLE;
+ else if (iso == "REPEATABLE_READ")
+ m_isolation = SQL_TXN_REPEATABLE_READ;
+ else if (iso == "READ_COMMITTED")
+ m_isolation = SQL_TXN_READ_COMMITTED;
+ else if (iso == "READ_UNCOMMITTED")
+ m_isolation = SQL_TXN_READ_UNCOMMITTED;
+ else
+ throw XMLToolingException("Unknown transaction isolationLevel property.");
if (m_henv == SQL_NULL_HANDLE) {
// Enable connection pooling.
}
// Grab connection string from the configuration.
- e = e ? XMLHelper::getFirstChildElement(e,ConnectionString) : nullptr;
- if (!e || !e->hasChildNodes()) {
+ e = e ? XMLHelper::getFirstChildElement(e, ConnectionString) : nullptr;
+ auto_ptr_char arg(e ? e->getTextContent() : nullptr);
+ if (!arg.get() || !*arg.get()) {
SQLFreeHandle(SQL_HANDLE_ENV, m_henv);
throw XMLToolingException("ODBC StorageService requires ConnectionString element in configuration.");
}
- auto_ptr_char arg(e->getFirstChild()->getNodeValue());
- m_connstring=arg.get();
+ m_connstring = arg.get();
// Connect and check version.
ODBCConn conn(getHDBC());
- pair<int,int> v=getVersion(conn);
+ pair<SQLINTEGER,SQLINTEGER> v = getVersion(conn);
// Make sure we've got the right version.
if (v.first != PLUGIN_VER_MAJOR) {
}
// Load any retry errors to check.
- e = XMLHelper::getNextSiblingElement(e,RetryOnError);
+ e = XMLHelper::getNextSiblingElement(e, RetryOnError);
while (e) {
if (e->hasChildNodes()) {
- m_retries.push_back(XMLString::parseInt(e->getFirstChild()->getNodeValue()));
+ m_retries.push_back(XMLString::parseInt(e->getTextContent()));
m_log.info("will retry operations when native ODBC error (%ld) is returned", m_retries.back());
}
- e = XMLHelper::getNextSiblingElement(e,RetryOnError);
+ e = XMLHelper::getNextSiblingElement(e, RetryOnError);
}
// Initialize the cleanup thread
- shutdown_wait = CondWait::create();
+ shutdown_wait.reset(CondWait::create());
cleanup_thread = Thread::create(&cleanup_fn, (void*)this);
}
shutdown = true;
shutdown_wait->signal();
cleanup_thread->join(nullptr);
- delete shutdown_wait;
if (m_henv != SQL_NULL_HANDLE)
SQLFreeHandle(SQL_HANDLE_ENV, m_henv);
}
SQLHSTMT ODBCStorageService::getHSTMT(SQLHDBC conn)
{
SQLHSTMT hstmt;
- SQLRETURN sr=SQLAllocHandle(SQL_HANDLE_STMT,conn,&hstmt);
+ SQLRETURN sr = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
if (!SQL_SUCCEEDED(sr)) {
m_log.error("failed to allocate statement handle");
log_error(conn, SQL_HANDLE_DBC);
return hstmt;
}
-pair<int,int> ODBCStorageService::getVersion(SQLHDBC conn)
+pair<SQLINTEGER,SQLINTEGER> ODBCStorageService::getVersion(SQLHDBC conn)
{
// Grab the version number from the database.
SQLHSTMT stmt = getHSTMT(conn);
- SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)"SELECT major,minor FROM version", SQL_NTS);
+ SQLRETURN sr = SQLExecDirect(stmt, (SQLCHAR*)"SELECT major,minor FROM version", SQL_NTS);
if (!SQL_SUCCEEDED(sr)) {
m_log.error("failed to read version from database");
log_error(stmt, SQL_HANDLE_STMT);
SQLINTEGER major;
SQLINTEGER minor;
- SQLBindCol(stmt,1,SQL_C_SLONG,&major,0,nullptr);
- SQLBindCol(stmt,2,SQL_C_SLONG,&minor,0,nullptr);
+ SQLBindCol(stmt, 1, SQL_C_SLONG, &major, 0, nullptr);
+ SQLBindCol(stmt, 2, SQL_C_SLONG, &minor, 0, nullptr);
- if ((sr=SQLFetch(stmt)) != SQL_NO_DATA)
- return pair<int,int>(major,minor);
+ if ((sr = SQLFetch(stmt)) != SQL_NO_DATA)
+ return make_pair(major,minor);
m_log.error("no rows returned in version query");
throw IOException("ODBC StorageService failed to read version from database.");
ODBCConn conn(getHDBC());
SQLHSTMT stmt = getHSTMT(conn);
- // Prepare and exectute insert statement.
- //char *scontext = makeSafeSQL(context);
- //char *skey = makeSafeSQL(key);
- //char *svalue = makeSafeSQL(value);
string q = string("INSERT INTO ") + table + " VALUES (?,?," + timebuf + ",1,?)";
SQLRETURN sr = SQLPrepare(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
}
m_log.debug("SQLBindParam succeeded (value = %s)", value);
- //freeSafeSQL(scontext, context);
- //freeSafeSQL(skey, key);
- //freeSafeSQL(svalue, value);
- //m_log.debug("SQL: %s", q.c_str());
-
int attempts = 3;
pair<bool,bool> logres;
do {
logres = make_pair(false,false);
attempts--;
- sr=SQLExecute(stmt);
+ sr = SQLExecute(stmt);
if (SQL_SUCCEEDED(sr)) {
m_log.debug("SQLExecute of insert succeeded");
return true;
// Prepare and exectute select statement.
char timebuf[32];
timestampFromTime(time(nullptr), timebuf);
- char *scontext = makeSafeSQL(context);
- char *skey = makeSafeSQL(key);
- ostringstream q;
- q << "SELECT version";
+ SQLString scontext(context);
+ SQLString skey(key);
+ string q("SELECT version");
if (pexpiration)
- q << ",expires";
+ q += ",expires";
if (pvalue)
- q << ",CASE version WHEN " << version << " THEN null ELSE value END";
- q << " FROM " << table << " WHERE context='" << scontext << "' AND id='" << skey << "' AND expires > " << timebuf;
- freeSafeSQL(scontext, context);
- freeSafeSQL(skey, key);
+ q = q + ",CASE version WHEN " + lexical_cast<string>(version) + " THEN null ELSE value END";
+ q = q + " FROM " + table + " WHERE context='" + scontext.tostr() + "' AND id='" + skey.tostr() + "' AND expires > " + timebuf;
if (m_log.isDebugEnabled())
- m_log.debug("SQL: %s", q.str().c_str());
+ m_log.debug("SQL: %s", q.c_str());
- SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)q.str().c_str(), SQL_NTS);
+ SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
if (!SQL_SUCCEEDED(sr)) {
m_log.error("error searching for (t=%s, c=%s, k=%s)", table, context, key);
log_error(stmt, SQL_HANDLE_STMT);
SQLSMALLINT ver;
SQL_TIMESTAMP_STRUCT expiration;
- SQLBindCol(stmt,1,SQL_C_SSHORT,&ver,0,nullptr);
+ SQLBindCol(stmt, 1, SQL_C_SSHORT, &ver, 0, nullptr);
if (pexpiration)
- SQLBindCol(stmt,2,SQL_C_TYPE_TIMESTAMP,&expiration,0,nullptr);
+ SQLBindCol(stmt, 2, SQL_C_TYPE_TIMESTAMP, &expiration, 0, nullptr);
- if ((sr=SQLFetch(stmt)) == SQL_NO_DATA)
+ if ((sr = SQLFetch(stmt)) == SQL_NO_DATA)
return 0;
if (pexpiration)
if (pvalue) {
SQLLEN len;
SQLCHAR buf[LONGDATA_BUFLEN];
- while ((sr=SQLGetData(stmt,pexpiration ? 3 : 2,SQL_C_CHAR,buf,sizeof(buf),&len)) != SQL_NO_DATA) {
+ while ((sr = SQLGetData(stmt, (pexpiration ? 3 : 2), SQL_C_CHAR, buf, sizeof(buf), &len)) != SQL_NO_DATA) {
if (!SQL_SUCCEEDED(sr)) {
m_log.error("error while reading text field from result set");
log_error(stmt, SQL_HANDLE_STMT);
// First, fetch the current version for later, which also ensures the record still exists.
char timebuf[32];
timestampFromTime(time(nullptr), timebuf);
- char *scontext = makeSafeSQL(context);
- char *skey = makeSafeSQL(key);
+ SQLString scontext(context);
+ SQLString skey(key);
string q("SELECT version FROM ");
- q = q + table + " WHERE context='" + scontext + "' AND id='" + skey + "' AND expires > " + timebuf;
+ q = q + table + " WHERE context='" + scontext.tostr() + "' AND id='" + skey.tostr() + "' AND expires > " + timebuf;
m_log.debug("SQL: %s", q.c_str());
- sr=SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
+ sr = SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
if (!SQL_SUCCEEDED(sr)) {
- freeSafeSQL(scontext, context);
- freeSafeSQL(skey, key);
m_log.error("error searching for (t=%s, c=%s, k=%s)", table, context, key);
log_error(stmt, SQL_HANDLE_STMT);
throw IOException("ODBC StorageService search failed.");
}
SQLSMALLINT ver;
- SQLBindCol(stmt,1,SQL_C_SSHORT,&ver,0,nullptr);
- if ((sr=SQLFetch(stmt)) == SQL_NO_DATA) {
- freeSafeSQL(scontext, context);
- freeSafeSQL(skey, key);
+ SQLBindCol(stmt, 1, SQL_C_SSHORT, &ver, 0, nullptr);
+ if ((sr = SQLFetch(stmt)) == SQL_NO_DATA) {
return 0;
}
// Check version?
if (version > 0 && version != ver) {
- freeSafeSQL(scontext, context);
- freeSafeSQL(skey, key);
return -1;
}
q = q + "expires = " + timebuf;
}
- q = q + " WHERE context='" + scontext + "' AND id='" + skey + "'";
- freeSafeSQL(scontext, context);
- freeSafeSQL(skey, key);
+ q = q + " WHERE context='" + scontext.tostr() + "' AND id='" + skey.tostr() + "'";
sr = SQLPrepare(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
if (!SQL_SUCCEEDED(sr)) {
do {
logres = make_pair(false,false);
attempts--;
- sr=SQLExecute(stmt);
- if (sr==SQL_NO_DATA)
+ sr = SQLExecute(stmt);
+ if (sr == SQL_NO_DATA)
return 0; // went missing?
else if (SQL_SUCCEEDED(sr)) {
m_log.debug("SQLExecute of update succeeded");
SQLHSTMT stmt = getHSTMT(conn);
// Prepare and execute delete statement.
- char *scontext = makeSafeSQL(context);
- char *skey = makeSafeSQL(key);
- string q = string("DELETE FROM ") + table + " WHERE context='" + scontext + "' AND id='" + skey + "'";
- freeSafeSQL(scontext, context);
- freeSafeSQL(skey, key);
+ SQLString scontext(context);
+ SQLString skey(key);
+ string q = string("DELETE FROM ") + table + " WHERE context='" + scontext.tostr() + "' AND id='" + skey.tostr() + "'";
m_log.debug("SQL: %s", q.c_str());
- SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
- if (sr==SQL_NO_DATA)
+ SQLRETURN sr = SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
+ if (sr == SQL_NO_DATA)
return false;
else if (!SQL_SUCCEEDED(sr)) {
m_log.error("error deleting record (t=%s, c=%s, k=%s)", table, context, key);
xmltooling::NDC ndc("cleanup");
#endif
- Mutex* mutex = Mutex::create();
+ scoped_ptr<Mutex> mutex(Mutex::create());
mutex->lock();
m_log.info("cleanup thread started... running every %d secs", m_cleanupInterval);
while (!shutdown) {
- shutdown_wait->timedwait(mutex, m_cleanupInterval);
+ shutdown_wait->timedwait(mutex.get(), m_cleanupInterval);
if (shutdown)
break;
try {
reap(nullptr);
}
- catch (exception& ex) {
+ catch (std::exception& ex) {
m_log.error("cleanup thread swallowed exception: %s", ex.what());
}
}
m_log.info("cleanup thread exiting...");
mutex->unlock();
- delete mutex;
Thread::exit(nullptr);
}
char nowbuf[32];
timestampFromTime(time(nullptr), nowbuf);
- char *scontext = makeSafeSQL(context);
- string q("UPDATE ");
- q = q + table + " SET expires = " + timebuf + " WHERE context='" + scontext + "' AND expires > " + nowbuf;
- freeSafeSQL(scontext, context);
+ SQLString scontext(context);
+ string q = string("UPDATE ") + table + " SET expires = " + timebuf + " WHERE context='" + scontext.tostr() + "' AND expires > " + nowbuf;
m_log.debug("SQL: %s", q.c_str());
- SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
- if ((sr!=SQL_NO_DATA) && !SQL_SUCCEEDED(sr)) {
+ SQLRETURN sr = SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
+ if ((sr != SQL_NO_DATA) && !SQL_SUCCEEDED(sr)) {
m_log.error("error updating records (t=%s, c=%s)", table, context ? context : "all");
log_error(stmt, SQL_HANDLE_STMT);
throw IOException("ODBC StorageService failed to update context expiration.");
timestampFromTime(time(nullptr), nowbuf);
string q;
if (context) {
- char *scontext = makeSafeSQL(context);
- q = string("DELETE FROM ") + table + " WHERE context='" + scontext + "' AND expires <= " + nowbuf;
- freeSafeSQL(scontext, context);
+ SQLString scontext(context);
+ q = string("DELETE FROM ") + table + " WHERE context='" + scontext.tostr() + "' AND expires <= " + nowbuf;
}
else {
q = string("DELETE FROM ") + table + " WHERE expires <= " + nowbuf;
}
m_log.debug("SQL: %s", q.c_str());
- SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
- if ((sr!=SQL_NO_DATA) && !SQL_SUCCEEDED(sr)) {
+ SQLRETURN sr = SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
+ if ((sr != SQL_NO_DATA) && !SQL_SUCCEEDED(sr)) {
m_log.error("error expiring records (t=%s, c=%s)", table, context ? context : "all");
log_error(stmt, SQL_HANDLE_STMT);
throw IOException("ODBC StorageService failed to purge expired records.");
SQLHSTMT stmt = getHSTMT(conn);
// Prepare and execute delete statement.
- char *scontext = makeSafeSQL(context);
- string q = string("DELETE FROM ") + table + " WHERE context='" + scontext + "'";
- freeSafeSQL(scontext, context);
+ SQLString scontext(context);
+ string q = string("DELETE FROM ") + table + " WHERE context='" + scontext.tostr() + "'";
m_log.debug("SQL: %s", q.c_str());
- SQLRETURN sr=SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
- if ((sr!=SQL_NO_DATA) && !SQL_SUCCEEDED(sr)) {
+ SQLRETURN sr = SQLExecDirect(stmt, (SQLCHAR*)q.c_str(), SQL_NTS);
+ if ((sr != SQL_NO_DATA) && !SQL_SUCCEEDED(sr)) {
m_log.error("error deleting context (t=%s, c=%s)", table, context);
log_error(stmt, SQL_HANDLE_STMT);
throw IOException("ODBC StorageService failed to delete context.");
#include <xmltooling/util/XMLHelper.h>
#include <xercesc/util/Base64.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string.hpp>
#ifdef SHIBSP_HAVE_GSSGNU
# include <gss.h>
using namespace opensaml;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
namespace shibsp {
{
public:
GSSAPIExtractor(const DOMElement* e)
- : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.GSSAPI")), m_impl(nullptr) {
+ : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AttributeExtractor.GSSAPI")) {
background_load();
}
~GSSAPIExtractor() {
pair<bool,DOMElement*> background_load();
private:
- GSSAPIExtractorImpl* m_impl;
+ scoped_ptr<GSSAPIExtractorImpl> m_impl;
};
#if defined (_MSC_VER)
name = child->getAttributeNS(nullptr, _aliases);
if (name && *name) {
auto_ptr_char aliases(name);
- char* pos;
- char* start = const_cast<char*>(aliases.get());
- while (start && *start) {
- while (*start && isspace(*start))
- start++;
- if (!*start)
- break;
- pos = strchr(start,' ');
- if (pos)
- *pos=0;
- if (strcmp(start, "REMOTE_USER")) {
- decl.ids.push_back(start);
- m_attributeIds.push_back(start);
- }
- else {
- m_log.warn("skipping alias, REMOTE_USER is a reserved name");
- }
- start = pos ? pos+1 : nullptr;
+ string dup(aliases.get());
+ set<string> new_aliases;
+ split(new_aliases, dup, is_space(), algorithm::token_compress_on);
+ set<string>::iterator ru = new_aliases.find("REMOTE_USER");
+ if (ru != new_aliases.end()) {
+ m_log.warn("skipping alias, REMOTE_USER is a reserved name");
+ new_aliases.erase(ru);
}
+ m_attributeIds.insert(m_attributeIds.end(), new_aliases.begin(), new_aliases.end());
}
decl.authenticated = XMLHelper::getAttrBool(child, true, _authenticated);
m_log.warn("ignoring unscoped value");
}
}
- if (!scoped->getValues().empty())
- attributes.push_back(scoped.release());
+ if (!scoped->getValues().empty()) {
+ attributes.push_back(scoped.get());
+ scoped.release();
+ }
}
else if (rule->second.binary) {
auto_ptr<BinaryAttribute> binary(new BinaryAttribute(rule->second.ids));
binary->getValues() = values;
- attributes.push_back(binary.release());
+ attributes.push_back(binary.get());
+ binary.release();
}
else {
auto_ptr<SimpleAttribute> simple(new SimpleAttribute(rule->second.ids));
simple->getValues() = values;
- attributes.push_back(simple.release());
+ attributes.push_back(simple.get());
+ simple.release();
}
}
// If we own it, wrap it.
XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr);
- GSSAPIExtractorImpl* impl = new GSSAPIExtractorImpl(raw.second, m_log);
+ scoped_ptr<GSSAPIExtractorImpl> impl(new GSSAPIExtractorImpl(raw.second, m_log));
// If we held the document, transfer it to the impl. If we didn't, it's a no-op.
impl->setDocument(docjanitor.release());
if (m_lock)
m_lock->wrlock();
SharedLock locker(m_lock, false);
- delete m_impl;
- m_impl = impl;
+ m_impl.swap(impl);
return make_pair(false,(DOMElement*)nullptr);
}
#include "util/DOMPropertySet.h"
#include <algorithm>
+#include <boost/lexical_cast.hpp>
#include <xmltooling/util/NDC.h>
#include <xmltooling/util/XMLConstants.h>
using namespace shibsp;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
PropertySet::PropertySet()
pair<bool,unsigned int> DOMPropertySet::getUnsignedInt(const char* name, const char* ns) const
{
- map<string,pair<char*,const XMLCh*> >::const_iterator i;
+ map< string,pair<char*,const XMLCh*> >::const_iterator i;
if (ns)
i=m_map.find(string("{") + ns + '}' + name);
else
i=m_map.find(name);
- if (i!=m_map.end())
- return pair<bool,unsigned int>(true,strtol(i->second.first,nullptr,10));
+ if (i!=m_map.end()) {
+ try {
+ return pair<bool,unsigned int>(true,lexical_cast<unsigned int>(i->second.first));
+ }
+ catch (bad_lexical_cast&) {
+ return pair<bool,unsigned int>(false,0);
+ }
+ }
else if (m_parent)
return m_parent->getUnsignedInt(name,ns);
return pair<bool,unsigned int>(false,0);
#include <saml/saml2/core/Assertions.h>
#include <saml/saml2/metadata/Metadata.h>
#include <saml/saml2/metadata/MetadataProvider.h>
-#include <xercesc/util/XMLUniDefs.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/ParserPool.h>
#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/iterator/indirect_iterator.hpp>
using namespace shibsp;
using namespace opensaml::saml2md;
using namespace xmltooling::logging;
using namespace xmltooling;
using namespace xercesc;
+using namespace boost;
using namespace std;
#if defined (_MSC_VER)
}
try {
- ResolutionContext* ctx;
+ scoped_ptr<ResolutionContext> ctx;
if (n_param) {
auto_ptr_XMLCh issuer(i_param);
auto_ptr_XMLCh name(n_param);
auto_ptr_XMLCh format(f_param);
- MetadataProvider* m=app->getMetadataProvider();
- xmltooling::Locker mlocker(m);
+ MetadataProvider* m = app->getMetadataProvider();
+ Locker mlocker(m);
MetadataProviderCriteria mc(*app, i_param, &IDPSSODescriptor::ELEMENT_QNAME, protocol);
- pair<const EntityDescriptor*,const RoleDescriptor*> site=m->getEntityDescriptor(mc);
+ pair<const EntityDescriptor*,const RoleDescriptor*> site = m->getEntityDescriptor(mc);
if (!site.first)
throw MetadataException("Unable to locate metadata for IdP ($1).", params(1,i_param));
// Build NameID(s).
- auto_ptr<saml2::NameID> v2name(saml2::NameIDBuilder::buildNameID());
+ scoped_ptr<saml1::NameIdentifier> v1name;
+ scoped_ptr<saml2::NameID> v2name(saml2::NameIDBuilder::buildNameID());
v2name->setName(name.get());
v2name->setFormat(format.get());
- saml1::NameIdentifier* v1name = nullptr;
if (!XMLString::equals(protocol, samlconstants::SAML20P_NS)) {
- v1name = saml1::NameIdentifierBuilder::buildNameIdentifier();
+ v1name.reset(saml1::NameIdentifierBuilder::buildNameIdentifier());
v1name->setName(name.get());
v1name->setFormat(format.get());
v1name->setNameQualifier(issuer.get());
}
ResolverTest rt(nullptr, a_param);
- try {
- ctx = rt.resolveAttributes(*app, site.second, protocol, v1name, v2name.get(), nullptr, nullptr, nullptr);
- }
- catch (...) {
- delete v1name;
- throw;
- }
+ ctx.reset(rt.resolveAttributes(*app, site.second, protocol, v1name.get(), v2name.get(), nullptr, nullptr, nullptr));
}
else {
// Try and load assertion from stdin.
DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(cin);
XercesJanitor<DOMDocument> docjan(doc);
- auto_ptr<XMLObject> token(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
+ scoped_ptr<XMLObject> token(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
docjan.release();
// Get the issuer and protocol and NameIDs.
throw FatalProfileException("Unknown assertion type.");
}
- auto_ptr<saml2::NameID> nameidwrapper(v1name ? v2name : nullptr);
+ scoped_ptr<saml2::NameID> nameidwrapper(v1name ? v2name : nullptr);
if (!issuer)
throw FatalProfileException("Unable to determine issuer.");
- MetadataProvider* m=app->getMetadataProvider();
- xmltooling::Locker mlocker(m);
+ MetadataProvider* m = app->getMetadataProvider();
+ Locker mlocker(m);
MetadataProviderCriteria mc(*app, issuer, &IDPSSODescriptor::ELEMENT_QNAME, protocol);
- pair<const EntityDescriptor*,const RoleDescriptor*> site=m->getEntityDescriptor(mc);
+ pair<const EntityDescriptor*,const RoleDescriptor*> site = m->getEntityDescriptor(mc);
if (!site.first) {
auto_ptr_char temp(issuer);
throw MetadataException("Unable to locate metadata for IdP ($1).", params(1,temp.get()));
vector<const Assertion*> tokens(1, dynamic_cast<Assertion*>(token.get()));
ResolverTest rt(nullptr, a_param);
- ctx = rt.resolveAttributes(*app, site.second, protocol, v1name, v2name, nullptr, nullptr, &tokens);
+ ctx.reset(rt.resolveAttributes(*app, site.second, protocol, v1name, v2name, nullptr, nullptr, &tokens));
}
- auto_ptr<ResolutionContext> wrapper(ctx);
- for (vector<Attribute*>::const_iterator a = ctx->getResolvedAttributes().begin(); a != ctx->getResolvedAttributes().end(); ++a) {
- for (vector<string>::const_iterator s = (*a)->getAliases().begin(); s != (*a)->getAliases().end(); ++s) {
+ for (indirect_iterator<vector<Attribute*>::const_iterator> a = make_indirect_iterator(ctx->getResolvedAttributes().begin());
+ a != make_indirect_iterator(ctx->getResolvedAttributes().end()); ++a) {
+ for (vector<string>::const_iterator s = a->getAliases().begin(); s != a->getAliases().end(); ++s) {
cout << *s << ": ";
- for (vector<string>::const_iterator v = (*a)->getSerializedValues().begin(); v != (*a)->getSerializedValues().end(); ++v) {
- if (v != (*a)->getSerializedValues().begin())
+ for (vector<string>::const_iterator v = a->getSerializedValues().begin(); v != a->getSerializedValues().end(); ++v) {
+ if (v != a->getSerializedValues().begin())
cout << ';';
cout << *v;
}
}
cout << endl;
}
- catch(exception& ex) {
+ catch (std::exception& ex) {
log.error(ex.what());
sp->unlock();
conf.term();