SSPCPP-616 - clean up concatenated string literals
[shibboleth/cpp-sp.git] / shibsp / attribute / resolver / impl / QueryAttributeResolver.cpp
index 6891fe0..05f63aa 100644 (file)
@@ -40,7 +40,6 @@
 #include "security/SecurityPolicyProvider.h"
 #include "util/SPConstants.h"
 
-#include <boost/scoped_ptr.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 #include <boost/ptr_container/ptr_vector.hpp>
 #include <saml/exceptions.h>
@@ -75,7 +74,7 @@ namespace shibsp {
     {
     public:
         QueryContext(const Application& application, const Session& session)
-                : m_query(true), m_app(application), m_session(&session), m_metadata(nullptr), m_entity(nullptr), m_nameid(nullptr) {
+                : m_query(true), m_app(application), m_request(nullptr), m_session(&session), m_metadata(nullptr), m_entity(nullptr), m_nameid(nullptr) {
             m_protocol = XMLString::transcode(session.getProtocol());
             m_class = XMLString::transcode(session.getAuthnContextClassRef());
             m_decl = XMLString::transcode(session.getAuthnContextDeclRef());
@@ -83,13 +82,14 @@ namespace shibsp {
 
         QueryContext(
             const Application& application,
+            const GenericRequest* request,
             const EntityDescriptor* issuer,
             const XMLCh* protocol,
             const NameID* nameid=nullptr,
             const XMLCh* authncontext_class=nullptr,
             const XMLCh* authncontext_decl=nullptr,
             const vector<const opensaml::Assertion*>* tokens=nullptr
-            ) : m_query(true), m_app(application), m_session(nullptr), m_metadata(nullptr), m_entity(issuer),
+            ) : m_query(true), m_app(application), m_request(request), m_session(nullptr), m_metadata(nullptr), m_entity(issuer),
                 m_protocol(protocol), m_nameid(nameid), m_class(authncontext_class), m_decl(authncontext_decl) {
 
             if (tokens) {
@@ -127,6 +127,9 @@ namespace shibsp {
         const Application& getApplication() const {
             return m_app;
         }
+        const GenericRequest* getRequest() const {
+            return m_request;
+        }
         const EntityDescriptor* getEntityDescriptor() const {
             if (m_entity)
                 return m_entity;
@@ -164,6 +167,7 @@ namespace shibsp {
     private:
         bool m_query;
         const Application& m_app;
+        const GenericRequest* m_request;
         const Session* m_session;
         mutable MetadataProvider* m_metadata;
         mutable const EntityDescriptor* m_entity;
@@ -184,8 +188,23 @@ namespace shibsp {
         Lockable* lock() {return this;}
         void unlock() {}
 
+        // deprecated method
+        ResolutionContext* createResolutionContext(
+            const Application& application,
+            const EntityDescriptor* issuer,
+            const XMLCh* protocol,
+            const NameID* nameid=nullptr,
+            const XMLCh* authncontext_class=nullptr,
+            const XMLCh* authncontext_decl=nullptr,
+            const vector<const opensaml::Assertion*>* tokens=nullptr,
+            const vector<shibsp::Attribute*>* attributes=nullptr
+            ) const {
+            return createResolutionContext(application, nullptr, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens);
+        }
+
         ResolutionContext* createResolutionContext(
             const Application& application,
+            const GenericRequest* request,
             const EntityDescriptor* issuer,
             const XMLCh* protocol,
             const NameID* nameid=nullptr,
@@ -194,7 +213,7 @@ namespace shibsp {
             const vector<const opensaml::Assertion*>* tokens=nullptr,
             const vector<shibsp::Attribute*>* attributes=nullptr
             ) const {
-            return new QueryContext(application,issuer,protocol,nameid,authncontext_class,authncontext_decl,tokens);
+            return new QueryContext(application, request, issuer, protocol, nameid, authncontext_class, authncontext_decl, tokens);
         }
 
         ResolutionContext* createResolutionContext(const Application& application, const Session& session) const {
@@ -230,7 +249,7 @@ namespace shibsp {
 };
 
 QueryResolver::QueryResolver(const DOMElement* e)
-    : m_log(Category::getInstance(SHIBSP_LOGCAT".AttributeResolver.Query")),
+    : m_log(Category::getInstance(SHIBSP_LOGCAT ".AttributeResolver.Query")),
         m_policyId(XMLHelper::getAttrString(e, nullptr, policyId)),
         m_subjectMatch(XMLHelper::getAttrBool(e, false, subjectMatch))
 {
@@ -405,7 +424,7 @@ void QueryResolver::SAML1Query(QueryContext& ctx) const
                         continue;
                     }
                 }
-                extractor->extractAttributes(application, AA, *s, ctx.getResolvedAttributes());
+                extractor->extractAttributes(application, ctx.getRequest(), AA, *s, ctx.getResolvedAttributes());
             }
         }
 
@@ -534,26 +553,36 @@ void QueryResolver::SAML2Query(QueryContext& ctx) const
             m_log.warn("simple resolver only supports one assertion in the query response");
         }
 
-        CredentialResolver* cr=application.getCredentialResolver();
+        CredentialResolver* cr = application.getCredentialResolver();
         if (!cr) {
             m_log.warn("found encrypted assertion, but no CredentialResolver was available");
             throw FatalProfileException("Assertion was encrypted, but no decryption credentials are available.");
         }
 
+        // With this flag on, we block unauthenticated ciphertext when decrypting,
+        // unless the protocol was authenticated.
+        pair<bool,bool> authenticatedCipher = application.getBool("requireAuthenticatedEncryption");
+        if (policy->isAuthenticated())
+            authenticatedCipher.second = false;
+
         // Attempt to decrypt it.
         try {
             Locker credlocker(cr);
-            auto_ptr<XMLObject> tokenwrapper(encassertions.front()->decrypt(*cr, relyingParty->getXMLString("entityID").second, &mcc));
+            auto_ptr<XMLObject> tokenwrapper(
+                encassertions.front()->decrypt(
+                    *cr, relyingParty->getXMLString("entityID").second, &mcc, authenticatedCipher.first && authenticatedCipher.second
+                    )
+                );
             newtoken = dynamic_cast<saml2::Assertion*>(tokenwrapper.get());
             if (newtoken) {
                 tokenwrapper.release();
                 newtokenwrapper.reset(newtoken);
                 if (m_log.isDebugEnabled())
-                    m_log.debugStream() << "decrypted Assertion: " << *newtoken << logging::eol;
+                    m_log.debugStream() << "decrypted assertion: " << *newtoken << logging::eol;
             }
         }
         catch (exception& ex) {
-            m_log.error(ex.what());
+            m_log.error("failed to decrypt assertion: %s", ex.what());
             throw;
         }
     }
@@ -638,7 +667,7 @@ void QueryResolver::SAML2Query(QueryContext& ctx) const
         AttributeExtractor* extractor = application.getAttributeExtractor();
         if (extractor) {
             Locker extlocker(extractor);
-            extractor->extractAttributes(application, AA, *newtoken, ctx.getResolvedAttributes());
+            extractor->extractAttributes(application, ctx.getRequest(), AA, *newtoken, ctx.getResolvedAttributes());
         }
 
         AttributeFilter* filter = application.getAttributeFilter();