Move credential usage enum to Credential class.
[shibboleth/xmltooling.git] / xmltooling / soap / impl / CURLSOAPTransport.cpp
index 423a3ba..6f8f11f 100644 (file)
@@ -49,8 +49,8 @@ namespace xmltooling {
             m_log(Category::getInstance(XMLTOOLING_LOGCAT".SOAPTransport.CURLPool")) {}
         ~CURLPool();
         
-        CURL* get(const char* to, const char* endpoint);
-        void put(const char* to, const char* endpoint, CURL* handle);
+        CURL* get(const SOAPTransport::Address& addr);
+        void put(const char* from, const char* to, const char* endpoint, CURL* handle);
     
     private:    
         typedef map<string,vector<CURL*> > poolmap_t;
@@ -66,14 +66,15 @@ namespace xmltooling {
     class XMLTOOL_DLLLOCAL CURLSOAPTransport : public HTTPSOAPTransport, public OpenSSLSOAPTransport
     {
     public:
-        CURLSOAPTransport(const char* peerName, const char* endpoint)
-                : m_peerName(peerName ? peerName : ""), m_endpoint(endpoint), m_handle(NULL), m_headers(NULL),
+        CURLSOAPTransport(const Address& addr)
+            : m_sender(addr.m_from ? addr.m_from : ""), m_peerName(addr.m_to ? addr.m_to : ""), m_endpoint(addr.m_endpoint),
+                m_handle(NULL), m_headers(NULL),
 #ifndef XMLTOOLING_NO_XMLSEC
                     m_cred(NULL), m_trustEngine(NULL), m_peerResolver(NULL), m_mandatory(false),
 #endif
-                    m_ssl_callback(NULL), m_ssl_userptr(NULL), m_chunked(true), m_secure(false) {
-            m_handle = g_CURLPool->get(peerName, endpoint);
-            curl_easy_setopt(m_handle,CURLOPT_URL,endpoint);
+                    m_ssl_callback(NULL), m_ssl_userptr(NULL), m_chunked(true), m_authenticated(false) {
+            m_handle = g_CURLPool->get(addr);
+            curl_easy_setopt(m_handle,CURLOPT_URL,addr.m_endpoint);
             curl_easy_setopt(m_handle,CURLOPT_CONNECTTIMEOUT,15);
             curl_easy_setopt(m_handle,CURLOPT_TIMEOUT,30);
             curl_easy_setopt(m_handle,CURLOPT_HTTPAUTH,0);
@@ -86,8 +87,8 @@ namespace xmltooling {
         virtual ~CURLSOAPTransport() {
             curl_slist_free_all(m_headers);
             curl_easy_setopt(m_handle,CURLOPT_ERRORBUFFER,NULL);
-            curl_easy_setopt(m_handle,CURLOPT_PRIVATE,m_secure ? "secure" : NULL); // Save off security "state".
-            g_CURLPool->put(m_peerName.c_str(), m_endpoint.c_str(), m_handle);
+            curl_easy_setopt(m_handle,CURLOPT_PRIVATE,m_authenticated ? "secure" : NULL); // Save off security "state".
+            g_CURLPool->put(m_sender.c_str(), m_peerName.c_str(), m_endpoint.c_str(), m_handle);
         }
 
         bool isConfidential() const {
@@ -146,17 +147,17 @@ namespace xmltooling {
             return true;
         }
 
-        bool setProviderOption(const char* provider, void* option, void* value) {
+        bool setProviderOption(const char* provider, const char* option, const char* value) {
             if (!provider || strcmp(provider, "CURL"))
                 return false;
             // For libcurl, the option is an enum and the value type depends on the option.
-            CURLoption opt = static_cast<CURLoption>(reinterpret_cast<long>(option));
+            CURLoption opt = static_cast<CURLoption>(strtol(option, NULL, 10));
             if (opt < CURLOPTTYPE_OBJECTPOINT)
-                return (curl_easy_setopt(m_handle, opt, reinterpret_cast<long>(value))==CURLE_OK);
+                return (curl_easy_setopt(m_handle, opt, strtol(value, NULL, 10)) == CURLE_OK);
             else if (opt < CURLOPTTYPE_OFF_T)
-                return (curl_easy_setopt(m_handle, opt, value)==CURLE_OK);
-            else if (sizeof(void*) == sizeof(curl_off_t))
-                return (curl_easy_setopt(m_handle, opt, reinterpret_cast<curl_off_t>(value))==CURLE_OK);
+                return (curl_easy_setopt(m_handle, opt, value) == CURLE_OK);
+            else if (sizeof(curl_off_t) == sizeof(long))
+                return (curl_easy_setopt(m_handle, opt, strtol(value, NULL, 10)) == CURLE_OK);
             return false;
         }
         
@@ -166,12 +167,12 @@ namespace xmltooling {
             return m_stream;
         }
         
-        bool isSecure() const {
-            return m_secure;
+        bool isAuthenticated() const {
+            return m_authenticated;
         }
 
-        void setSecure(bool secure) {
-            m_secure = secure;
+        void setAuthenticated(bool auth) {
+            m_authenticated = auth;
         }
 
         string getContentType() const;
@@ -193,7 +194,7 @@ namespace xmltooling {
 
     private:        
         // per-call state
-        string m_peerName,m_endpoint,m_simplecreds;
+        string m_sender,m_peerName,m_endpoint,m_simplecreds;
         CURL* m_handle;
         stringstream m_stream;
         struct curl_slist* m_headers;
@@ -208,7 +209,7 @@ namespace xmltooling {
         ssl_ctx_callback_fn m_ssl_callback;
         void* m_ssl_userptr;
         bool m_chunked;
-        bool m_secure;
+        bool m_authenticated;
         
         friend size_t XMLTOOL_DLLLOCAL curl_header_hook(void* ptr, size_t size, size_t nmemb, void* stream);
         friend CURLcode XMLTOOL_DLLLOCAL xml_ssl_ctx_callback(CURL* curl, SSL_CTX* ssl_ctx, void* userptr);
@@ -225,9 +226,9 @@ namespace xmltooling {
     int XMLTOOL_DLLLOCAL verify_callback(X509_STORE_CTX* x509_ctx, void* arg);
 #endif
 
-    SOAPTransport* CURLSOAPTransportFactory(const pair<const char*,const char*>& dest)
+    SOAPTransport* CURLSOAPTransportFactory(const SOAPTransport::Address& addr)
     {
-        return new CURLSOAPTransport(dest.first, dest.second);
+        return new CURLSOAPTransport(addr);
     }
 };
 
@@ -258,14 +259,19 @@ CURLPool::~CURLPool()
     delete m_lock;
 }
 
-CURL* CURLPool::get(const char* to, const char* endpoint)
+CURL* CURLPool::get(const SOAPTransport::Address& addr)
 {
 #ifdef _DEBUG
     xmltooling::NDC("get");
 #endif
-    m_log.debug("getting connection handle to %s", endpoint);
+    m_log.debug("getting connection handle to %s", addr.m_endpoint);
+    string key(addr.m_endpoint);
+    if (addr.m_from)
+        key = key + '|' + addr.m_from;
+    if (addr.m_to)
+        key = key + '|' + addr.m_to;
     m_lock->lock();
-    poolmap_t::iterator i=m_bindingMap.find(string(to) + "|" + endpoint);
+    poolmap_t::iterator i=m_bindingMap.find(key);
     
     if (i!=m_bindingMap.end()) {
         // Move this pool to the front of the list.
@@ -293,7 +299,8 @@ CURL* CURLPool::get(const char* to, const char* endpoint)
     curl_easy_setopt(handle,CURLOPT_NOPROGRESS,1);
     curl_easy_setopt(handle,CURLOPT_NOSIGNAL,1);
     curl_easy_setopt(handle,CURLOPT_FAILONERROR,1);
-    curl_easy_setopt(handle,CURLOPT_SSLVERSION,3);
+    curl_easy_setopt(handle,CURLOPT_SSLVERSION,CURL_SSLVERSION_SSLv3);
+    curl_easy_setopt(handle,CURLOPT_SSL_CIPHER_LIST,"ALL:!aNULL:!LOW:!EXPORT:!SSLv2");
     // Verification of the peer is via TrustEngine only.
     curl_easy_setopt(handle,CURLOPT_SSL_VERIFYPEER,0);
     curl_easy_setopt(handle,CURLOPT_HEADERFUNCTION,&curl_header_hook);
@@ -303,9 +310,13 @@ CURL* CURLPool::get(const char* to, const char* endpoint)
     return handle;
 }
 
-void CURLPool::put(const char* to, const char* endpoint, CURL* handle)
+void CURLPool::put(const char* from, const char* to, const char* endpoint, CURL* handle)
 {
-    string key = string(to) + "|" + endpoint;
+    string key(endpoint);
+    if (from)
+        key = key + '|' + from;
+    if (to)
+        key = key + '|' + to;
     m_lock->lock();
     poolmap_t::iterator i=m_bindingMap.find(key);
     if (i==m_bindingMap.end())
@@ -443,7 +454,7 @@ void CURLSOAPTransport::send(istream& in)
         char* priv=NULL;
         curl_easy_getinfo(m_handle,CURLINFO_PRIVATE,&priv);
         if (priv)
-            m_secure=true;
+            m_authenticated=true;
     }
     else {
         curl_easy_setopt(m_handle,CURLOPT_SSL_CTX_FUNCTION,NULL);
@@ -535,7 +546,7 @@ int xmltooling::verify_callback(X509_STORE_CTX* x509_ctx, void* arg)
 
     bool success=false;
     if (ctx->m_criteria) {
-        ctx->m_criteria->setUsage(CredentialCriteria::TLS_CREDENTIAL);
+        ctx->m_criteria->setUsage(Credential::TLS_CREDENTIAL);
         // Bypass name check (handled for us by curl).
         ctx->m_criteria->setPeerName(NULL);
         success = ctx->m_trustEngine->validate(x509_ctx->cert,x509_ctx->untrusted,*(ctx->m_peerResolver),ctx->m_criteria);
@@ -543,19 +554,19 @@ int xmltooling::verify_callback(X509_STORE_CTX* x509_ctx, void* arg)
     else {
         // Bypass name check (handled for us by curl).
         CredentialCriteria cc;
-        cc.setUsage(CredentialCriteria::TLS_CREDENTIAL);
+        cc.setUsage(Credential::TLS_CREDENTIAL);
         success = ctx->m_trustEngine->validate(x509_ctx->cert,x509_ctx->untrusted,*(ctx->m_peerResolver),&cc);
     }
     
     if (!success) {
         log.error("supplied TrustEngine failed to validate SSL/TLS server certificate");
         x509_ctx->error=X509_V_ERR_APPLICATION_VERIFICATION;     // generic error, check log for plugin specifics
-        ctx->setSecure(false);
+        ctx->setAuthenticated(false);
         return ctx->m_mandatory ? 0 : 1;
     }
     
     // Signal success. Hopefully it doesn't matter what's actually in the structure now.
-    ctx->setSecure(true);
+    ctx->setAuthenticated(true);
     return 1;
 }
 #endif