https://issues.shibboleth.net/jira/browse/SSPCPP-376
authorScott Cantor <cantor.2@osu.edu>
Mon, 14 May 2012 17:57:18 +0000 (17:57 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 14 May 2012 17:57:18 +0000 (17:57 +0000)
shibsp/attribute/NameIDAttribute.cpp
shibsp/attribute/NameIDAttribute.h
shibsp/attribute/NameIDAttributeDecoder.cpp
shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp
shibsp/remoting/impl/ListenerService.cpp

index 9cc59db..9f15c1e 100644 (file)
  */
 
 #include "internal.h"
+#include "ServiceProvider.h"
 #include "attribute/NameIDAttribute.h"
+#include "remoting/ListenerService.h"
 
 #include <xmltooling/exceptions.h>
+#include <xmltooling/security/SecurityHelper.h>
 
 using namespace shibsp;
+using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
@@ -39,17 +43,21 @@ namespace shibsp {
     }
 };
 
-NameIDAttribute::NameIDAttribute(const vector<string>& ids, const char* formatter) : Attribute(ids), m_formatter(formatter)
+NameIDAttribute::NameIDAttribute(const vector<string>& ids, const char* formatter, const char* hashAlg)
+    : Attribute(ids), m_formatter(formatter), m_hashAlg(hashAlg ? hashAlg : "")
 {
 }
 
 NameIDAttribute::NameIDAttribute(DDF& in) : Attribute(in)
 {
     DDF val = in["_formatter"];
-    if (val.isstring())
+    if (val.isstring() && val.string())
         m_formatter = val.string();
     else
         m_formatter = DEFAULT_NAMEID_FORMATTER;
+    val = in["_hashalg"];
+    if (val.isstring() && val.string())
+        m_hashAlg = val.string();
     const char* pch;
     val = in.first().first();
     while (val.name()) {
@@ -116,7 +124,7 @@ void NameIDAttribute::removeValue(size_t index)
 const vector<string>& NameIDAttribute::getSerializedValues() const
 {
     if (m_serialized.empty()) {
-        for (vector<Value>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
+        for (vector<Value>::const_iterator i = m_values.begin(); i != m_values.end(); ++i) {
             // This is kind of a hack, but it's a good way to reuse some code.
             XMLToolingException e(
                 m_formatter,
@@ -129,7 +137,27 @@ const vector<string>& NameIDAttribute::getSerializedValues() const
                     "SPProvidedID", i->m_SPProvidedID.c_str()
                     )
                 );
-            m_serialized.push_back(e.what());
+            if (m_hashAlg.empty()) {
+                m_serialized.push_back(e.what());
+            }
+            else {
+#ifndef SHIBSP_LITE
+                m_serialized.push_back(SecurityHelper::doHash(m_hashAlg.c_str(), e.what(), strlen(e.what())));
+#else
+                try {
+                    DDF out, in("hash");
+                    DDFJanitor jin(in), jout(out);
+                    in.addmember("alg").string(m_hashAlg.c_str());
+                    in.addmember("data").unsafe_string(e.what());
+                    out = SPConfig::getConfig().getServiceProvider()->getListenerService()->send(in);
+                    if (out.isstring() && out.string())
+                        m_serialized.push_back(out.string());
+                }
+                catch (exception& ex) {
+                    Category::getInstance(SHIBSP_LOGCAT".Attribute.NameID").error("exception remoting hash operation: %s", ex.what());
+                }
+#endif
+            }
         }
     }
     return Attribute::getSerializedValues();
@@ -140,6 +168,8 @@ DDF NameIDAttribute::marshall() const
     DDF ddf = Attribute::marshall();
     ddf.name("NameID");
     ddf.addmember("_formatter").string(m_formatter.c_str());
+    if (!m_hashAlg.empty())
+        ddf.addmember("_hashalg").string(m_hashAlg.c_str());
     DDF vlist = ddf.first();
     for (vector<Value>::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) {
         DDF val = DDF(i->m_Name.c_str()).structure();
index 176c9e7..e7f5d7e 100644 (file)
@@ -50,8 +50,9 @@ namespace shibsp {
          * 
          * @param ids       array with primary identifier in first position, followed by any aliases
          * @param formatter template for serialization of tuple
+         * @param hashAlg   hash algorithm to apply in producing serialized values
          */
-        NameIDAttribute(const std::vector<std::string>& ids, const char* formatter=DEFAULT_NAMEID_FORMATTER);
+        NameIDAttribute(const std::vector<std::string>& ids, const char* formatter=DEFAULT_NAMEID_FORMATTER, const char* hashAlg=nullptr);
 
         /**
          * Constructs based on a remoted NameIDAttribute.
@@ -99,7 +100,7 @@ namespace shibsp {
     
     private:
         std::vector<Value> m_values;
-        std::string m_formatter;
+        std::string m_formatter,m_hashAlg;
     };
 
 #if defined (_MSC_VER)
index 8ff61e5..6adf938 100644 (file)
@@ -84,7 +84,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(
     ) const
 {
     auto_ptr<NameIDAttribute> nameid(
-        new NameIDAttribute(ids, (!m_formatter.empty()) ? m_formatter.c_str() : DEFAULT_NAMEID_FORMATTER)
+        new NameIDAttribute(ids, (!m_formatter.empty()) ? m_formatter.c_str() : DEFAULT_NAMEID_FORMATTER, m_hashAlg.c_str())
         );
     vector<NameIDAttribute::Value>& dest = nameid->getValues();
     vector<XMLObject*>::const_iterator v,stop;
@@ -159,7 +159,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(
             }
         }
 
-        return dest.empty() ? nullptr : _decode(nameid.release());
+        return dest.empty() ? nullptr : nameid.release();
     }
 
     const NameIDType* saml2name = dynamic_cast<const NameIDType*>(xmlObject);
@@ -188,7 +188,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode(
         }
     }
 
-    return dest.empty() ? nullptr : _decode(nameid.release());
+    return dest.empty() ? nullptr : nameid.release();
 }
 
 void NameIDAttributeDecoder::extract(
index 8818962..e842d7f 100644 (file)
@@ -93,7 +93,7 @@ shibsp::Attribute* NameIDFromScopedAttributeDecoder::decode(
     const XMLCh* xmlscope;
     xmltooling::QName scopeqname(nullptr,Scope);
     auto_ptr<NameIDAttribute> nameid(
-        new NameIDAttribute(ids, (!m_formatter.empty()) ? m_formatter.c_str() : DEFAULT_NAMEID_FORMATTER)
+        new NameIDAttribute(ids, (!m_formatter.empty()) ? m_formatter.c_str() : DEFAULT_NAMEID_FORMATTER, m_hashAlg.c_str())
         );
     vector<NameIDAttribute::Value>& dest = nameid->getValues();
     pair<vector<XMLObject*>::const_iterator,vector<XMLObject*>::const_iterator> valrange;
@@ -162,7 +162,7 @@ shibsp::Attribute* NameIDFromScopedAttributeDecoder::decode(
             }
         }
 
-        return dest.empty() ? nullptr : _decode(nameid.release());
+        return dest.empty() ? nullptr : nameid.release();
     }
 
     log.warn("XMLObject type not recognized by NameIDFromScopedAttributeDecoder, no values returned");
index 46da642..312f469 100644 (file)
@@ -30,6 +30,7 @@
 #include "remoting/ListenerService.h"
 
 #include <xercesc/dom/DOM.hpp>
+#include <xmltooling/security/SecurityHelper.h>
 
 using namespace shibsp;
 using namespace xmltooling;
@@ -103,10 +104,26 @@ void ListenerService::receive(DDF &in, ostream& out)
 {
     if (!in.name())
         throw ListenerException("Incoming message with no destination address rejected.");
-    else if (!strcmp("ping",in.name())) {
-        DDF outmsg=DDF(nullptr).integer(in.integer() + 1);
+    else if (!strcmp("ping", in.name())) {
+        DDF outmsg = DDF(nullptr).integer(in.integer() + 1);
         DDFJanitor jan(outmsg);
         out << outmsg;
+        return;
+    }
+    else if (!strcmp("hash", in.name())) {
+#ifndef SHIBSP_LITE
+        const char* hashAlg = in["alg"].string();
+        const char* data = in["data"].string();
+        if (!hashAlg || !*hashAlg || !data || !*data)
+            throw ListenerException("Hash request missing algorithm or data parameters.");
+        DDF outmsg(nullptr);
+        DDFJanitor jan(outmsg);
+        outmsg.string(SecurityHelper::doHash(hashAlg, data, strlen(data)).c_str());
+        out << outmsg;
+        return;
+#else
+        throw ListenerException("Hash algorithms unavailable in lite build of library.");
+#endif
     }
 
     // Two stage lookup, on the listener itself, and the SP interface.