/*
- * 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 "binding/ArtifactMap.h"
#include "binding/SAMLArtifact.h"
-#include <log4cpp/Category.hh>
+#include <ctime>
#include <xercesc/util/XMLUniDefs.hpp>
+#include <xmltooling/logging.h>
#include <xmltooling/XMLObjectBuilder.h>
+#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
+#include <xmltooling/util/StorageService.h>
#include <xmltooling/util/XMLHelper.h>
+#include <xmltooling/util/Threads.h>
using namespace opensaml;
+using namespace xmltooling::logging;
using namespace xmltooling;
-using namespace log4cpp;
using namespace std;
namespace opensaml {
}
void storeContent(XMLObject* content, const SAMLArtifact* artifact, const char* relyingParty, int TTL);
XMLObject* retrieveContent(const SAMLArtifact* artifact, const char* relyingParty);
+ string getRelyingParty(const SAMLArtifact* artifact);
private:
struct SAML_DLLLOCAL Mapping {
map<string,Mapping> m_artMap;
multimap<time_t,string> m_expMap;
};
+
+ static const XMLCh artifactTTL[] = UNICODE_LITERAL_11(a,r,t,i,f,a,c,t,T,T,L);
+ static const XMLCh context[] = UNICODE_LITERAL_7(c,o,n,t,e,x,t);
+ static const XMLCh Mapping[] = UNICODE_LITERAL_7(M,a,p,p,i,n,g);
+ static const XMLCh _relyingParty[] = UNICODE_LITERAL_12(r,e,l,y,i,n,g,P,a,r,t,y);
};
void ArtifactMappings::removeMapping(const map<string,Mapping>::iterator& i)
if (relyingParty)
m.m_relying = relyingParty;
m.m_expires = now + TTL;
- m_expMap.insert(make_pair(m.m_expires,hexed));
+ m_expMap.insert(pair<const time_t,string>(m.m_expires,hexed));
}
XMLObject* ArtifactMappings::retrieveContent(const SAMLArtifact* artifact, const char* relyingParty)
return ret;
}
-ArtifactMap::ArtifactMap(xmltooling::StorageService* storage, const char* context, int artifactTTL)
- : m_storage(storage), m_context(context ? context : "opensaml::ArtifactMap"), m_mappings(NULL), m_artifactTTL(artifactTTL)
+string ArtifactMappings::getRelyingParty(const SAMLArtifact* artifact)
+{
+ map<string,Mapping>::iterator i=m_artMap.find(SAMLArtifact::toHex(artifact->getMessageHandle()));
+ if (i==m_artMap.end())
+ throw BindingException("Requested artifact not in map or may have expired.");
+ return i->second.m_relying;
+}
+
+ArtifactMap::ArtifactMap(xmltooling::StorageService* storage, const char* context, unsigned int artifactTTL)
+ : m_storage(storage), m_context((context && *context) ? context : "opensaml::ArtifactMap"), m_mappings(NULL), m_artifactTTL(artifactTTL)
{
if (!m_storage)
m_mappings = new ArtifactMappings();
}
+ArtifactMap::ArtifactMap(const DOMElement* e, xmltooling::StorageService* storage)
+ : m_storage(storage), m_mappings(NULL), m_artifactTTL(180)
+{
+ if (e) {
+ auto_ptr_char c(e->getAttributeNS(NULL, context));
+ if (c.get() && *c.get())
+ m_context = c.get();
+ else
+ m_context = "opensaml::ArtifactMap";
+
+ const XMLCh* TTL = e->getAttributeNS(NULL, artifactTTL);
+ if (TTL) {
+ m_artifactTTL = XMLString::parseInt(TTL);
+ if (!m_artifactTTL)
+ m_artifactTTL = 180;
+ }
+ }
+
+ if (!m_storage)
+ m_mappings = new ArtifactMappings();
+}
+
ArtifactMap::~ArtifactMap()
{
delete m_mappings;
}
-static const XMLCh M[] = UNICODE_LITERAL_7(M,a,p,p,i,n,g);
-static const XMLCh RP[] = UNICODE_LITERAL_12(r,e,l,y,i,n,g,P,a,r,t,y);
-
void ArtifactMap::storeContent(XMLObject* content, const SAMLArtifact* artifact, const char* relyingParty)
{
if (content->getParent())
// Build a DOM with the same document to store the relyingParty mapping.
if (relyingParty) {
auto_ptr_XMLCh temp(relyingParty);
- root = root->getOwnerDocument()->createElementNS(NULL,M);
- root->setAttributeNS(NULL,RP,temp.get());
+ root = root->getOwnerDocument()->createElementNS(NULL,Mapping);
+ root->setAttributeNS(NULL,_relyingParty,temp.get());
root->appendChild(content->getDOM());
}
// Serialize the root element, whatever it is, for storage.
string xmlbuf;
XMLHelper::serialize(root, xmlbuf);
- m_storage->createText(
- m_context.c_str(), SAMLArtifact::toHex(artifact->getMessageHandle()).c_str(), xmlbuf.c_str(), time(NULL) + m_artifactTTL
- );
+ if (!m_storage->createText(
+ m_context.c_str(),
+ SAMLArtifact::toHex(artifact->getMessageHandle()).c_str(),
+ xmlbuf.c_str(),
+ time(NULL) + m_artifactTTL
+ )) {
+ throw IOException("Attempt to insert duplicate artifact into map.");
+ }
// Cleanup by destroying XML.
delete content;
#ifdef _DEBUG
xmltooling::NDC ndc("retrieveContent");
#endif
+ Category& log=Category::getInstance(SAML_LOGCAT".ArtifactMap");
if (!m_storage)
return m_mappings->retrieveContent(artifact, relyingParty);
+ // Read the mapping and then delete it.
string xmlbuf;
string key = SAMLArtifact::toHex(artifact->getMessageHandle());
if (!m_storage->readText(m_context.c_str(), key.c_str(), &xmlbuf))
throw BindingException("Artifact not found in mapping database.");
+ m_storage->deleteText(m_context.c_str(), key.c_str());
+ // Parse the data back into XML.
istringstream is(xmlbuf);
DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(is);
XercesJanitor<DOMDocument> janitor(doc);
-
- Category& log=Category::getInstance(SAML_LOGCAT".ArtifactMap");
- m_storage->deleteText(m_context.c_str(), key.c_str());
// Check the root element.
DOMElement* messageRoot = doc->getDocumentElement();
- if (XMLHelper::isNodeNamed(messageRoot, NULL, M)) {
- auto_ptr_char temp(messageRoot->getAttributeNS(NULL,RP));
+ if (XMLHelper::isNodeNamed(messageRoot, NULL, Mapping)) {
+ auto_ptr_char temp(messageRoot->getAttributeNS(NULL,_relyingParty));
if (!relyingParty || strcmp(temp.get(),relyingParty)) {
log.warn("request from (%s) for artifact issued to (%s)", relyingParty ? relyingParty : "unknown", temp.get());
throw BindingException("Unauthorized artifact mapping request.");
log.debug("resolved artifact for (%s)", relyingParty ? relyingParty : "unknown");
return xmlObject;
}
+
+string ArtifactMap::getRelyingParty(const SAMLArtifact* artifact)
+{
+ if (!m_storage)
+ return m_mappings->getRelyingParty(artifact);
+
+ string xmlbuf;
+ if (!m_storage->readText(m_context.c_str(), SAMLArtifact::toHex(artifact->getMessageHandle()).c_str(), &xmlbuf))
+ throw BindingException("Artifact not found in mapping database.");
+
+ // Parse the data back into XML.
+ istringstream is(xmlbuf);
+ DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(is);
+ XercesJanitor<DOMDocument> janitor(doc);
+
+ // Check the root element.
+ DOMElement* messageRoot = doc->getDocumentElement();
+ if (XMLHelper::isNodeNamed(messageRoot, NULL, Mapping)) {
+ auto_ptr_char temp(messageRoot->getAttributeNS(NULL,_relyingParty));
+ return temp.get();
+ }
+ return string();
+}