X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fbinding%2Fimpl%2FSAML2SOAPClient.cpp;h=1435de12674963ca73289dfacb83a9bcfb09dc9a;hb=e9554c255ad3c91c7c4976e7a1a54905903e66a2;hp=626b6070372c48f5155260492f8ca6a9d0f277cf;hpb=d46f52f440aa8225cc9d3a4608567c54d06d357e;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/binding/impl/SAML2SOAPClient.cpp b/saml/saml2/binding/impl/SAML2SOAPClient.cpp index 626b607..1435de1 100644 --- a/saml/saml2/binding/impl/SAML2SOAPClient.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Internet2 + * Copyright 2001-2010 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,17 @@ #include "internal.h" #include "exceptions.h" +#include "binding/SecurityPolicy.h" +#include "binding/SOAPClient.h" #include "saml2/binding/SAML2SOAPClient.h" #include "saml2/core/Protocols.h" #include "saml2/metadata/Metadata.h" +#include "saml2/metadata/MetadataProvider.h" #include #include +using namespace opensaml::saml2; using namespace opensaml::saml2p; using namespace opensaml::saml2md; using namespace opensaml; @@ -37,6 +41,16 @@ using namespace xmltooling::logging; using namespace xmltooling; using namespace std; +SAML2SOAPClient::SAML2SOAPClient(opensaml::SOAPClient& soaper, bool fatalSAMLErrors) + : m_soaper(soaper), m_fatal(fatalSAMLErrors), m_correlate(nullptr) +{ +} + +SAML2SOAPClient::~SAML2SOAPClient() +{ + XMLString::release(&m_correlate); +} + void SAML2SOAPClient::sendSAML(RequestAbstractType* request, const char* from, MetadataCredentialCriteria& to, const char* endpoint) { auto_ptr env(EnvelopeBuilder::buildEnvelope()); @@ -56,25 +70,32 @@ StatusResponseType* SAML2SOAPClient::receiveSAML() // Check for SAML Response. StatusResponseType* response = dynamic_cast(body->getUnknownXMLObjects().front()); if (response) { - // Check InResponseTo. if (m_correlate && response->getInResponseTo() && !XMLString::equals(m_correlate, response->getInResponseTo())) throw SecurityPolicyException("InResponseTo attribute did not correlate with the Request ID."); - m_soaper.getPolicy().reset(true); - m_soaper.getPolicy().evaluate(*response, NULL, samlconstants::SAML20P_NS); - if (!m_soaper.getPolicy().isSecure()) { - SecurityPolicyException ex("Security policy could not authenticate the message."); - annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata(), response->getStatus()); // throws it - } + SecurityPolicy& policy = m_soaper.getPolicy(); + policy.reset(true); + + // Extract Response details. + policy.setMessageID(response->getID()); + policy.setIssueInstant(response->getIssueInstantEpoch()); + + // Extract and re-verify Issuer if present. + const Issuer* issuer = response->getIssuer(); + if (issuer) + policy.setIssuer(issuer); // This will throw if it conflicts with the known peer identity. + + // Now run the policy. + policy.evaluate(*response); // Check Status. Status* status = response->getStatus(); if (status) { - const XMLCh* code = status->getStatusCode() ? status->getStatusCode()->getValue() : NULL; + const XMLCh* code = status->getStatusCode() ? status->getStatusCode()->getValue() : nullptr; if (code && !XMLString::equals(code,StatusCode::SUCCESS) && handleError(*status)) { BindingException ex("SAML response contained an error."); - annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata(), status); // throws it + annotateException(&ex, policy.getIssuerMetadata(), status); // throws it } } @@ -91,13 +112,13 @@ StatusResponseType* SAML2SOAPClient::receiveSAML() else ex.raise(); } - return NULL; + return nullptr; } bool SAML2SOAPClient::handleError(const Status& status) { - auto_ptr_char code((status.getStatusCode() ? status.getStatusCode()->getValue() : NULL)); - auto_ptr_char str((status.getStatusMessage() ? status.getStatusMessage()->getMessage() : NULL)); + auto_ptr_char code((status.getStatusCode() ? status.getStatusCode()->getValue() : nullptr)); + auto_ptr_char str((status.getStatusMessage() ? status.getStatusMessage()->getMessage() : nullptr)); Category::getInstance(SAML_LOGCAT".SOAPClient").error( "SOAP client detected a SAML error: (%s) (%s)", (code.get() ? code.get() : "no code"),