diff options
Diffstat (limited to 'qpid/cpp/src/qpid/broker/ConnectionHandler.cpp')
-rw-r--r-- | qpid/cpp/src/qpid/broker/ConnectionHandler.cpp | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp index 015002a70c..7cd91ae539 100644 --- a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp +++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp @@ -26,6 +26,7 @@ #include "qpid/broker/SecureConnection.h" #include "qpid/Url.h" #include "qpid/framing/AllInvoker.h" +#include "qpid/framing/ConnectionStartOkBody.h" #include "qpid/framing/enum.h" #include "qpid/log/Statement.h" #include "qpid/sys/SecurityLayer.h" @@ -63,13 +64,24 @@ void ConnectionHandler::heartbeat() handler->proxy.heartbeat(); } +bool ConnectionHandler::handle(const framing::AMQMethodBody& method) +{ + //Need special handling for start-ok, in order to distinguish + //between null and empty response + if (method.isA<ConnectionStartOkBody>()) { + handler->startOk(dynamic_cast<const ConnectionStartOkBody&>(method)); + return true; + } else { + return invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler), method); + } +} + void ConnectionHandler::handle(framing::AMQFrame& frame) { AMQMethodBody* method=frame.getBody()->getMethod(); Connection::ErrorListener* errorListener = handler->connection.getErrorListener(); try{ - if (method && invoke( - static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler), *method)) { + if (method && handle(*method)) { // This is a connection control frame, nothing more to do. } else if (isOpen()) { handler->connection.getChannel(frame.getChannel()).in(frame); @@ -96,13 +108,10 @@ ConnectionHandler::ConnectionHandler(Connection& connection, bool isClient, bool ConnectionHandler::Handler::Handler(Connection& c, bool isClient, bool isShadow) : proxy(c.getOutput()), - connection(c), serverMode(!isClient), acl(0), secured(0), + connection(c), serverMode(!isClient), secured(0), isOpen(false) { if (serverMode) { - - acl = connection.getBroker().getAcl(); - FieldTable properties; Array mechanisms(0x95); @@ -125,13 +134,20 @@ ConnectionHandler::Handler::Handler(Connection& c, bool isClient, bool isShadow) ConnectionHandler::Handler::~Handler() {} -void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProperties, - const string& mechanism, - const string& response, +void ConnectionHandler::Handler::startOk(const framing::FieldTable& /*clientProperties*/, + const string& /*mechanism*/, + const string& /*response*/, const string& /*locale*/) { + //Need special handling for start-ok, in order to distinguish + //between null and empty response -> should never use this method + assert(false); +} + +void ConnectionHandler::Handler::startOk(const ConnectionStartOkBody& body) +{ try { - authenticator->start(mechanism, response); + authenticator->start(body.getMechanism(), body.hasResponse() ? &body.getResponse() : 0); } catch (std::exception& /*e*/) { management::ManagementAgent* agent = connection.getAgent(); if (agent) { @@ -143,11 +159,14 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper } throw; } + const framing::FieldTable& clientProperties = body.getClientProperties(); connection.setFederationLink(clientProperties.get(QPID_FED_LINK)); if (clientProperties.isSet(QPID_FED_TAG)) { connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG)); } if (connection.isFederationLink()) { + AclModule* acl = connection.getBroker().getAcl(); + FieldTable properties; if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){ proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link"); return; @@ -308,11 +327,21 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, string response; if (sasl.get()) { const qpid::sys::SecuritySettings& ss = connection.getExternalSecuritySettings(); - response = sasl->start ( requestedMechanism.empty() - ? supportedMechanismsList - : requestedMechanism, - & ss ); - proxy.startOk ( ft, sasl->getMechanism(), response, en_US ); + if (sasl->start ( requestedMechanism.empty() + ? supportedMechanismsList + : requestedMechanism, + response, + & ss )) { + proxy.startOk ( ft, sasl->getMechanism(), response, en_US ); + } else { + //response was null + ConnectionStartOkBody body; + body.setClientProperties(ft); + body.setMechanism(sasl->getMechanism()); + //Don't set response, as none was given + body.setLocale(en_US); + proxy.send(body); + } } else { response = ((char)0) + username + ((char)0) + password; |