diff options
author | Gordon Sim <gsim@apache.org> | 2011-03-07 10:34:42 +0000 |
---|---|---|
committer | Gordon Sim <gsim@apache.org> | 2011-03-07 10:34:42 +0000 |
commit | 2c4d9c9f7687878ff6a61256a84dd043449d9d27 (patch) | |
tree | 50dbf6f0e073d0401df826deb9864bdece04cea8 | |
parent | 2122db7644ad41417ac83c51222f1c194b8acd71 (diff) | |
download | qpid-python-2c4d9c9f7687878ff6a61256a84dd043449d9d27.tar.gz |
QPID-3115: Recognise sasl_mechanisms (plural) and support a space separate list as does the python client (continue to recognise sasl-mechanism as well for backword compatibility)
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1078733 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | qpid/cpp/src/qpid/client/ConnectionHandler.cpp | 48 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp | 4 |
2 files changed, 35 insertions, 17 deletions
diff --git a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp index 8dc1e8338a..4fbf55aa60 100644 --- a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp +++ b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp @@ -22,6 +22,7 @@ #include "qpid/client/ConnectionHandler.h" #include "qpid/SaslFactory.h" +#include "qpid/StringUtils.h" #include "qpid/client/Bounds.h" #include "qpid/framing/amqp_framing.h" #include "qpid/framing/all_method_bodies.h" @@ -202,6 +203,24 @@ void ConnectionHandler::fail(const std::string& message) namespace { std::string SPACE(" "); + +std::string join(const std::vector<std::string>& in) +{ + std::string result; + for (std::vector<std::string>::const_iterator i = in.begin(); i != in.end(); ++i) { + if (result.size()) result += SPACE; + result += *i; + } + return result; +} + +void intersection(const std::vector<std::string>& a, const std::vector<std::string>& b, std::vector<std::string>& results) +{ + for (std::vector<std::string>::const_iterator i = a.begin(); i != a.end(); ++i) { + if (std::find(b.begin(), b.end(), *i) != b.end()) results.push_back(*i); + } +} + } void ConnectionHandler::start(const FieldTable& /*serverProps*/, const Array& mechanisms, const Array& /*locales*/) @@ -216,25 +235,24 @@ void ConnectionHandler::start(const FieldTable& /*serverProps*/, const Array& me maxSsf ); - std::string mechlist; - bool chosenMechanismSupported = mechanism.empty(); - for (Array::const_iterator i = mechanisms.begin(); i != mechanisms.end(); ++i) { - if (!mechanism.empty() && mechanism == (*i)->get<std::string>()) { - chosenMechanismSupported = true; - mechlist = (*i)->get<std::string>() + SPACE + mechlist; - } else { - if (i != mechanisms.begin()) mechlist += SPACE; - mechlist += (*i)->get<std::string>(); + std::vector<std::string> mechlist; + if (mechanism.empty()) { + //mechlist is simply what the server offers + mechanisms.collect(mechlist); + } else { + //mechlist is the intersection of those indicated by user and + //those supported by server, in the order listed by user + std::vector<std::string> allowed = split(mechanism, " "); + std::vector<std::string> supported; + mechanisms.collect(supported); + intersection(allowed, supported, mechlist); + if (mechlist.empty()) { + throw Exception(QPID_MSG("Desired mechanism(s) not valid: " << mechanism << " (supported: " << join(supported) << ")")); } } - if (!chosenMechanismSupported) { - fail("Selected mechanism not supported: " + mechanism); - } - if (sasl.get()) { - string response = sasl->start(mechanism.empty() ? mechlist : mechanism, - getSecuritySettings ? getSecuritySettings() : 0); + string response = sasl->start(join(mechlist), getSecuritySettings ? getSecuritySettings() : 0); proxy.startOk(properties, sasl->getMechanism(), response, locale); } else { //TODO: verify that desired mechanism and locale are supported diff --git a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp index ae99e01725..a87a8dea67 100644 --- a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp +++ b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp @@ -101,8 +101,8 @@ void ConnectionImpl::setOption(const std::string& name, const Variant& value) settings.username = value.asString(); } else if (name == "password") { settings.password = value.asString(); - } else if (name == "sasl-mechanism" || name == "sasl_mechanism") { - //TODO: handle space separate lists of mechanisms + } else if (name == "sasl-mechanism" || name == "sasl_mechanism" || + name == "sasl-mechanisms" || name == "sasl_mechanisms") { settings.mechanism = value.asString(); } else if (name == "sasl-service" || name == "sasl_service") { settings.service = value.asString(); |