Imported Upstream version 2.4+dfsg
[shibboleth/sp.git] / shibsp / binding / impl / SOAPClient.cpp
index e12f4f0..dc15572 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2009 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.
@@ -43,7 +43,7 @@ using namespace xmltooling;
 using namespace std;
 
 SOAPClient::SOAPClient(SecurityPolicy& policy)
-    : opensaml::SOAPClient(policy), m_app(policy.getApplication()), m_relyingParty(NULL), m_credResolver(NULL)
+    : opensaml::SOAPClient(policy), m_app(policy.getApplication()), m_relyingParty(nullptr), m_credResolver(nullptr)
 {
 }
 
@@ -62,19 +62,31 @@ void SOAPClient::send(const soap11::Envelope& env, const char* from, MetadataCre
         m_credResolver=m_app.getCredentialResolver();
         if (m_credResolver) {
             m_credResolver->lock();
+            const Credential* cred = nullptr;
+
             // Fill in criteria to use.
             to.setUsage(Credential::SIGNING_CREDENTIAL);
             pair<bool,const char*> keyName = m_relyingParty->getString("keyName");
             if (keyName.first)
                 to.getKeyNames().insert(keyName.second);
+
+            // Check for an explicit algorithm, in which case resolve a credential directly.
             pair<bool,const XMLCh*> sigalg = m_relyingParty->getXMLString("signingAlg");
-            if (sigalg.first)
+            if (sigalg.first) {
                 to.setXMLAlgorithm(sigalg.second);
-            const Credential* cred = m_credResolver->resolve(&to);
+                cred = m_credResolver->resolve(&to);
+            }
+            else {
+                // Prefer credential based on peer's requirements.
+                pair<const SigningMethod*,const Credential*> p = to.getRole().getSigningMethod(*m_credResolver, to);
+                if (p.first)
+                    sigalg = make_pair(true, p.first->getAlgorithm());
+                if (p.second)
+                    cred = p.second;
+            }
+
             // Reset criteria back.
-            to.setKeyAlgorithm(NULL);
-            to.setKeySize(0);
-            to.getKeyNames().clear();
+            to.reset();
 
             if (cred) {
                 // Check for message.
@@ -88,21 +100,26 @@ void SOAPClient::send(const soap11::Envelope& env, const char* from, MetadataCre
                         if (sigalg.first)
                             sig->setSignatureAlgorithm(sigalg.second);
                         sigalg = m_relyingParty->getXMLString("digestAlg");
+                        if (!sigalg.first) {
+                            const DigestMethod* dm = to.getRole().getDigestMethod();
+                            if (dm)
+                                sigalg = make_pair(true, dm->getAlgorithm());
+                        }
                         if (sigalg.first)
                             dynamic_cast<opensaml::ContentReference*>(sig->getContentReference())->setDigestAlgorithm(sigalg.second);
 
                         // Sign it. The marshalling step in the base class should be a no-op.
                         vector<Signature*> sigs(1,sig);
-                        env.marshall((DOMDocument*)NULL,&sigs,cred);
+                        env.marshall((DOMDocument*)nullptr,&sigs,cred);
                     }
                 }
             }
             else {
-                Category::getInstance(SHIBSP_LOGCAT".SOAPClient").error("no signing credential supplied, leaving unsigned.");
+                Category::getInstance(SHIBSP_LOGCAT".SOAPClient").warn("no signing credential resolved, leaving message unsigned");
             }
         }
         else {
-            Category::getInstance(SHIBSP_LOGCAT".SOAPClient").error("no CredentialResolver available, leaving unsigned.");
+            Category::getInstance(SHIBSP_LOGCAT".SOAPClient").warn("no CredentialResolver available, leaving unsigned");
         }
     }
     
@@ -187,17 +204,16 @@ void SOAPClient::prepareTransport(SOAPTransport& transport)
     if (http) {
         flag = m_relyingParty->getBool("chunkedEncoding");
         http->useChunkedEncoding(flag.first && flag.second);
-        http->setRequestHeader("User-Agent", PACKAGE_NAME);
         http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION);
     }
 }
 
 void SOAPClient::reset()
 {
-    m_relyingParty = NULL;
+    m_relyingParty = nullptr;
     if (m_credResolver)
         m_credResolver->unlock();
-    m_credResolver = NULL;
+    m_credResolver = nullptr;
     opensaml::SOAPClient::reset();
 }