X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fbinding%2Fimpl%2FArtifactMap.cpp;h=8b755b30aef409cde120b3cb69cfaa751c65b745;hb=c072b75e6f6e05e24a1c35b952008b38d0d375c1;hp=6866c6b98053dbcfe074213bb81d6f74d5e96505;hpb=54bc3fd9396935d92c53bbb69d003e8d121720c2;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/binding/impl/ArtifactMap.cpp b/saml/binding/impl/ArtifactMap.cpp index 6866c6b..8b755b3 100644 --- a/saml/binding/impl/ArtifactMap.cpp +++ b/saml/binding/impl/ArtifactMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 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. @@ -25,15 +25,19 @@ #include "binding/ArtifactMap.h" #include "binding/SAMLArtifact.h" -#include +#include #include +#include #include +#include #include +#include #include +#include using namespace opensaml; +using namespace xmltooling::logging; using namespace xmltooling; -using namespace log4cpp; using namespace std; namespace opensaml { @@ -49,6 +53,7 @@ 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 { @@ -64,6 +69,11 @@ namespace opensaml { map m_artMap; multimap 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::iterator& i) @@ -100,7 +110,7 @@ void ArtifactMappings::storeContent(XMLObject* content, const SAMLArtifact* arti if (relyingParty) m.m_relying = relyingParty; m.m_expires = now + TTL; - m_expMap.insert(make_pair(m.m_expires,hexed)); + m_expMap.insert(pair(m.m_expires,hexed)); } XMLObject* ArtifactMappings::retrieveContent(const SAMLArtifact* artifact, const char* relyingParty) @@ -135,21 +145,48 @@ XMLObject* ArtifactMappings::retrieveContent(const SAMLArtifact* artifact, const 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::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()) @@ -163,17 +200,22 @@ void ArtifactMap::storeContent(XMLObject* content, const SAMLArtifact* artifact, // 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; @@ -184,26 +226,27 @@ XMLObject* ArtifactMap::retrieveContent(const SAMLArtifact* artifact, const char #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 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."); @@ -218,3 +261,26 @@ XMLObject* ArtifactMap::retrieveContent(const SAMLArtifact* artifact, const char 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 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(); +}