From 8f918d5b8b2640d0166a75a91f1383640d79c866 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 14 May 2012 17:57:18 +0000 Subject: [PATCH] https://issues.shibboleth.net/jira/browse/SSPCPP-376 --- shibsp/attribute/NameIDAttribute.cpp | 38 +++++++++++++++++++--- shibsp/attribute/NameIDAttribute.h | 5 +-- shibsp/attribute/NameIDAttributeDecoder.cpp | 6 ++-- .../attribute/NameIDFromScopedAttributeDecoder.cpp | 4 +-- shibsp/remoting/impl/ListenerService.cpp | 21 ++++++++++-- 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/shibsp/attribute/NameIDAttribute.cpp b/shibsp/attribute/NameIDAttribute.cpp index 9cc59db..9f15c1e 100644 --- a/shibsp/attribute/NameIDAttribute.cpp +++ b/shibsp/attribute/NameIDAttribute.cpp @@ -25,11 +25,15 @@ */ #include "internal.h" +#include "ServiceProvider.h" #include "attribute/NameIDAttribute.h" +#include "remoting/ListenerService.h" #include +#include using namespace shibsp; +using namespace xmltooling::logging; using namespace xmltooling; using namespace std; @@ -39,17 +43,21 @@ namespace shibsp { } }; -NameIDAttribute::NameIDAttribute(const vector& ids, const char* formatter) : Attribute(ids), m_formatter(formatter) +NameIDAttribute::NameIDAttribute(const vector& 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& NameIDAttribute::getSerializedValues() const { if (m_serialized.empty()) { - for (vector::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) { + for (vector::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& 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::const_iterator i=m_values.begin(); i!=m_values.end(); ++i) { DDF val = DDF(i->m_Name.c_str()).structure(); diff --git a/shibsp/attribute/NameIDAttribute.h b/shibsp/attribute/NameIDAttribute.h index 176c9e7..e7f5d7e 100644 --- a/shibsp/attribute/NameIDAttribute.h +++ b/shibsp/attribute/NameIDAttribute.h @@ -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& ids, const char* formatter=DEFAULT_NAMEID_FORMATTER); + NameIDAttribute(const std::vector& 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 m_values; - std::string m_formatter; + std::string m_formatter,m_hashAlg; }; #if defined (_MSC_VER) diff --git a/shibsp/attribute/NameIDAttributeDecoder.cpp b/shibsp/attribute/NameIDAttributeDecoder.cpp index 8ff61e5..6adf938 100644 --- a/shibsp/attribute/NameIDAttributeDecoder.cpp +++ b/shibsp/attribute/NameIDAttributeDecoder.cpp @@ -84,7 +84,7 @@ shibsp::Attribute* NameIDAttributeDecoder::decode( ) const { auto_ptr 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& dest = nameid->getValues(); vector::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(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( diff --git a/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp b/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp index 8818962..e842d7f 100644 --- a/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp +++ b/shibsp/attribute/NameIDFromScopedAttributeDecoder.cpp @@ -93,7 +93,7 @@ shibsp::Attribute* NameIDFromScopedAttributeDecoder::decode( const XMLCh* xmlscope; xmltooling::QName scopeqname(nullptr,Scope); auto_ptr 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& dest = nameid->getValues(); pair::const_iterator,vector::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"); diff --git a/shibsp/remoting/impl/ListenerService.cpp b/shibsp/remoting/impl/ListenerService.cpp index 46da642..312f469 100644 --- a/shibsp/remoting/impl/ListenerService.cpp +++ b/shibsp/remoting/impl/ListenerService.cpp @@ -30,6 +30,7 @@ #include "remoting/ListenerService.h" #include +#include 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. -- 2.1.4