Author: mgoulish
Date: Wed Oct 20 08:03:36 2010
New Revision: 1024541
URL: http://svn.apache.org/viewvc?rev=1024541&view=rev
Log:
SASLizing Interbroker Links
-------------------------------------------------------------
1. Brokers already knew how to handle the server side of SASLized
links, but not the client side. So we promoted the client-side
SASL code from the client library to the common library so that
the broker could also use it. This affected SaslFactory.{h,cpp}
and Sasl.h
TODO -- can the server-side and client-side code be unified here?
2. Some of the SASL verbs in broker/ConnectionHandler.cpp are
expanded: start, secure, tune.
3. broker/SecureConnection is altered to get the client-broker and
the server-broker to agree on when the security layer should be
inserted.
4. the python tool qpid-route is modified so that, in the "route add"
command, you can specify the security mechanism for SASL to use.
TODO -- should we also pass in {min,max}SSF ?
5. Changes in broker/LinkRegistry to allow the information input by
qpid-route to be passed up to where it is needed.
6. A bash script test run by "make check" that creates a SASLized
federation link and sends some messages down it.
TODO - write a python unit test instead of a bash script. I
think I uncovered a bug in the python code when I tried.
7. NOTE - testing for this feature does not work with versions of
SASL earlier than 2.1.22, becuase I can't tell SASL to use a
SASL database file in a nonstandard location. The test is
disabled for earlier versions.
Added:
qpid/trunk/qpid/cpp/src/qpid/Sasl.h
qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp
qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h
qpid/trunk/qpid/cpp/src/tests/sasl_fed (with props)
Removed:
qpid/trunk/qpid/cpp/src/qpid/client/Sasl.h
qpid/trunk/qpid/cpp/src/qpid/client/SaslFactory.cpp
qpid/trunk/qpid/cpp/src/qpid/client/SaslFactory.h
Modified:
qpid/trunk/qpid/cpp/src/CMakeLists.txt
qpid/trunk/qpid/cpp/src/Makefile.am
qpid/trunk/qpid/cpp/src/qpid/broker/Connection.cpp
qpid/trunk/qpid/cpp/src/qpid/broker/Connection.h
qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.h
qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.h
qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.cpp
qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.h
qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.h
qpid/trunk/qpid/cpp/src/tests/sasl.mk
qpid/trunk/qpid/tools/src/py/qpid-route
Modified: qpid/trunk/qpid/cpp/src/CMakeLists.txt
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/CMakeLists.txt?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/CMakeLists.txt (original)
+++ qpid/trunk/qpid/cpp/src/CMakeLists.txt Wed Oct 20 08:03:36 2010
@@ -712,7 +712,6 @@ else (CMAKE_SYSTEM_NAME STREQUAL Windows
)
set (qpidclient_platform_SOURCES
- qpid/client/SaslFactory.cpp
)
set (qpidd_platform_SOURCES
@@ -732,6 +731,7 @@ set (qpidcommon_SOURCES
qpid/Options.cpp
qpid/Plugin.cpp
qpid/RefCountedBuffer.cpp
+ qpid/SaslFactory.cpp
qpid/SessionState.cpp
qpid/SessionId.cpp
qpid/StringUtils.cpp
Modified: qpid/trunk/qpid/cpp/src/Makefile.am
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/Makefile.am?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ qpid/trunk/qpid/cpp/src/Makefile.am Wed Oct 20 08:03:36 2010
@@ -331,6 +331,9 @@ libqpidcommon_la_SOURCES += \
qpid/RefCounted.h \
qpid/RefCountedBuffer.cpp \
qpid/RefCountedBuffer.h \
+ qpid/Sasl.h \
+ qpid/SaslFactory.cpp \
+ qpid/SaslFactory.h \
qpid/Serializer.h \
qpid/SessionId.cpp \
qpid/SessionState.cpp \
@@ -692,9 +695,6 @@ libqpidclient_la_SOURCES = \
qpid/client/QueueOptions.cpp \
qpid/client/Results.cpp \
qpid/client/Results.h \
- qpid/client/Sasl.h \
- qpid/client/SaslFactory.cpp \
- qpid/client/SaslFactory.h \
qpid/client/SessionBase_0_10.cpp \
qpid/client/SessionBase_0_10Access.h \
qpid/client/SessionImpl.cpp \
Added: qpid/trunk/qpid/cpp/src/qpid/Sasl.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/Sasl.h?rev=1024541&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/Sasl.h (added)
+++ qpid/trunk/qpid/cpp/src/qpid/Sasl.h Wed Oct 20 08:03:36 2010
@@ -0,0 +1,60 @@
+#ifndef QPID_SASL_H
+#define QPID_SASL_H
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include <memory>
+#include <string>
+#include "qpid/sys/IntegerTypes.h"
+
+namespace qpid {
+
+namespace sys {
+class SecurityLayer;
+struct SecuritySettings;
+}
+
+/**
+ * Interface to SASL support. This class is implemented by platform-specific
+ * SASL providers.
+ */
+class Sasl
+{
+ public:
+ /**
+ * Start SASL negotiation with the broker.
+ *
+ * @param mechanisms Comma-separated list of the SASL mechanism the
+ * client supports.
+ * @param externalSecuritySettings security related details from the
underlying transport
+ */
+ virtual std::string start(const std::string& mechanisms,
+ const qpid::sys::SecuritySettings*
externalSecuritySettings = 0) = 0;
+ virtual std::string step(const std::string& challenge) = 0;
+ virtual std::string getMechanism() = 0;
+ virtual std::string getUserId() = 0;
+ virtual std::auto_ptr<qpid::sys::SecurityLayer> getSecurityLayer(uint16_t
maxFrameSize) = 0;
+ virtual ~Sasl() {}
+};
+} // namespace qpid
+
+#endif /*!QPID_SASL_H*/
Added: qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp?rev=1024541&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp (added)
+++ qpid/trunk/qpid/cpp/src/qpid/SaslFactory.cpp Wed Oct 20 08:03:36 2010
@@ -0,0 +1,415 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#include "qpid//SaslFactory.h"
+#include <map>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef HAVE_SASL
+
+namespace qpid {
+
+//Null implementation
+
+SaslFactory::SaslFactory() {}
+
+SaslFactory::~SaslFactory() {}
+
+SaslFactory& SaslFactory::getInstance()
+{
+ qpid::sys::Mutex::ScopedLock l(lock);
+ if (!instance.get()) {
+ instance = std::auto_ptr<SaslFactory>(new SaslFactory());
+ }
+ return *instance;
+}
+
+std::auto_ptr<Sasl> SaslFactory::create( const std::string &, const
std::string &, const std::string &, const std::string &, int, int )
+{
+ return std::auto_ptr<Sasl>();
+}
+
+qpid::sys::Mutex SaslFactory::lock;
+std::auto_ptr<SaslFactory> SaslFactory::instance;
+
+} // namespace qpid
+
+#else
+
+#include "qpid/Exception.h"
+#include "qpid/framing/reply_exceptions.h"
+#include "qpid/sys/SecurityLayer.h"
+#include "qpid/sys/SecuritySettings.h"
+#include "qpid/sys/cyrus/CyrusSecurityLayer.h"
+#include "qpid/log/Statement.h"
+#include <sasl/sasl.h>
+#include <strings.h>
+
+namespace qpid {
+
+using qpid::sys::SecurityLayer;
+using qpid::sys::SecuritySettings;
+using qpid::sys::cyrus::CyrusSecurityLayer;
+using qpid::framing::InternalErrorException;
+
+const size_t MAX_LOGIN_LENGTH = 50;
+
+struct CyrusSaslSettings
+{
+ CyrusSaslSettings ( ) :
+ username ( std::string(0) ),
+ password ( std::string(0) ),
+ service ( std::string(0) ),
+ host ( std::string(0) ),
+ minSsf ( 0 ),
+ maxSsf ( 0 )
+ {
+ }
+
+ CyrusSaslSettings ( const std::string & user, const std::string &
password, const std::string & service, const std::string & host, int minSsf,
int maxSsf ) :
+ username(user),
+ password(password),
+ service(service),
+ host(host),
+ minSsf(minSsf),
+ maxSsf(maxSsf)
+ {
+ }
+
+ std::string username,
+ password,
+ service,
+ host;
+
+ int minSsf,
+ maxSsf;
+};
+
+
+class CyrusSasl : public Sasl
+{
+ public:
+ CyrusSasl(const std::string & username, const std::string & password,
const std::string & serviceName, const std::string & hostName, int minSsf, int
maxSsf);
+ ~CyrusSasl();
+ std::string start(const std::string& mechanisms, const SecuritySettings*
externalSettings);
+ std::string step(const std::string& challenge);
+ std::string getMechanism();
+ std::string getUserId();
+ std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
+ private:
+ sasl_conn_t* conn;
+ sasl_callback_t callbacks[5];//realm, user, authname, password, end-of-list
+ CyrusSaslSettings settings;
+ std::string input;
+ std::string mechanism;
+ char login[MAX_LOGIN_LENGTH];
+
+ void interact(sasl_interact_t* client_interact);
+};
+
+//sasl callback functions
+int getUserFromSettings(void *context, int id, const char **result, unsigned
*len);
+int getPasswordFromSettings(sasl_conn_t *conn, void *context, int id,
sasl_secret_t **psecret);
+typedef int CallbackProc();
+
+qpid::sys::Mutex SaslFactory::lock;
+std::auto_ptr<SaslFactory> SaslFactory::instance;
+
+SaslFactory::SaslFactory()
+{
+ sasl_callback_t* callbacks = 0;
+ int result = sasl_client_init(callbacks);
+ if (result != SASL_OK) {
+ throw InternalErrorException(QPID_MSG("Sasl error: " <<
sasl_errstring(result, 0, 0)));
+ }
+}
+
+SaslFactory::~SaslFactory()
+{
+ sasl_done();
+}
+
+SaslFactory& SaslFactory::getInstance()
+{
+ qpid::sys::Mutex::ScopedLock l(lock);
+ if (!instance.get()) {
+ instance = std::auto_ptr<SaslFactory>(new SaslFactory());
+ }
+ return *instance;
+}
+
+std::auto_ptr<Sasl> SaslFactory::create(const std::string & username, const
std::string & password, const std::string & serviceName, const std::string &
hostName, int minSsf, int maxSsf)
+{
+ std::auto_ptr<Sasl> sasl(new CyrusSasl(username, password, serviceName,
hostName, minSsf, maxSsf));
+ return sasl;
+}
+
+CyrusSasl::CyrusSasl(const std::string & username, const std::string &
password, const std::string & serviceName, const std::string & hostName, int
minSsf, int maxSsf)
+ : conn(0), settings(username, password, serviceName, hostName, minSsf,
maxSsf)
+{
+ size_t i = 0;
+
+ callbacks[i].id = SASL_CB_GETREALM;
+ callbacks[i].proc = 0;
+ callbacks[i++].context = 0;
+
+ if (!settings.username.empty()) {
+ callbacks[i].id = SASL_CB_AUTHNAME;
+ callbacks[i].proc = (CallbackProc*) &getUserFromSettings;
+ callbacks[i++].context = &settings;
+ }
+
+ callbacks[i].id = SASL_CB_PASS;
+ if (settings.password.empty()) {
+ callbacks[i].proc = 0;
+ callbacks[i++].context = 0;
+ } else {
+ callbacks[i].proc = (CallbackProc*) &getPasswordFromSettings;
+ callbacks[i++].context = &settings;
+ }
+
+ callbacks[i].id = SASL_CB_LIST_END;
+ callbacks[i].proc = 0;
+ callbacks[i++].context = 0;
+}
+
+CyrusSasl::~CyrusSasl()
+{
+ if (conn) {
+ sasl_dispose(&conn);
+ }
+}
+
+namespace {
+ const std::string SSL("ssl");
+}
+
+std::string CyrusSasl::start(const std::string& mechanisms, const
SecuritySettings* externalSettings)
+{
+ QPID_LOG(debug, "CyrusSasl::start(" << mechanisms << ")");
+ int result = sasl_client_new(settings.service.c_str(),
+ settings.host.c_str(),
+ 0, 0, /* Local and remote IP address strings
*/
+ callbacks,
+ 0, /* security flags */
+ &conn);
+
+ if (result != SASL_OK) throw InternalErrorException(QPID_MSG("Sasl error:
" << sasl_errdetail(conn)));
+
+ sasl_security_properties_t secprops;
+
+ if (externalSettings) {
+ sasl_ssf_t external_ssf = (sasl_ssf_t) externalSettings->ssf;
+ if (external_ssf) {
+ int result = sasl_setprop(conn, SASL_SSF_EXTERNAL, &external_ssf);
+ if (result != SASL_OK) {
+ throw framing::InternalErrorException(QPID_MSG("SASL error:
unable to set external SSF: " << result));
+ }
+ QPID_LOG(debug, "external SSF detected and set to " <<
external_ssf);
+ }
+ if (externalSettings->authid.size()) {
+ const char* external_authid = externalSettings->authid.c_str();
+ result = sasl_setprop(conn, SASL_AUTH_EXTERNAL, external_authid);
+ if (result != SASL_OK) {
+ throw framing::InternalErrorException(QPID_MSG("SASL error:
unable to set external auth: " << result));
+ }
+ QPID_LOG(debug, "external auth detected and set to " <<
external_authid);
+ }
+ }
+
+ secprops.min_ssf = settings.minSsf;
+ secprops.max_ssf = settings.maxSsf;
+ secprops.maxbufsize = 65535;
+
+ QPID_LOG(debug, "min_ssf: " << secprops.min_ssf << ", max_ssf: " <<
secprops.max_ssf);
+
+ secprops.property_names = 0;
+ secprops.property_values = 0;
+ secprops.security_flags = 0;//TODO: provide means for application to
configure these
+
+ result = sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
+ if (result != SASL_OK) {
+ throw framing::InternalErrorException(QPID_MSG("SASL error: " <<
sasl_errdetail(conn)));
+ }
+
+ sasl_interact_t* client_interact = 0;
+ const char *out = 0;
+ unsigned outlen = 0;
+ const char *chosenMechanism = 0;
+
+ do {
+ result = sasl_client_start(conn,
+ mechanisms.c_str(),
+ &client_interact,
+ &out,
+ &outlen,
+ &chosenMechanism);
+
+ if (result == SASL_INTERACT) {
+ interact(client_interact);
+ }
+ } while (result == SASL_INTERACT);
+
+ if (result != SASL_CONTINUE && result != SASL_OK) {
+ throw InternalErrorException(QPID_MSG("Sasl error: " <<
sasl_errdetail(conn)));
+ }
+
+ mechanism = std::string(chosenMechanism);
+ QPID_LOG(debug, "CyrusSasl::start(" << mechanisms << "): selected "
+ << mechanism << " response: '" << std::string(out, outlen) <<
"'");
+ return std::string(out, outlen);
+}
+
+std::string CyrusSasl::step(const std::string& challenge)
+{
+ sasl_interact_t* client_interact = 0;
+ const char *out = 0;
+ unsigned outlen = 0;
+ int result = 0;
+ do {
+ result = sasl_client_step(conn, /* our context */
+ challenge.data(), /* the data from the
server */
+ challenge.size(), /* it's length */
+ &client_interact, /* this should be
+ unallocated and NULL */
+ &out, /* filled in on success */
+ &outlen); /* filled in on success */
+
+ if (result == SASL_INTERACT) {
+ interact(client_interact);
+ }
+ } while (result == SASL_INTERACT);
+
+ std::string response;
+ if (result == SASL_CONTINUE || result == SASL_OK) response =
std::string(out, outlen);
+ else if (result != SASL_OK) {
+ throw InternalErrorException(QPID_MSG("Sasl error: " <<
sasl_errdetail(conn)));
+ }
+ QPID_LOG(debug, "CyrusSasl::step(" << challenge << "): " << response);
+ return response;
+}
+
+std::string CyrusSasl::getMechanism()
+{
+ return mechanism;
+}
+
+std::string CyrusSasl::getUserId()
+{
+ int propResult;
+ const void* operName;
+
+ propResult = sasl_getprop(conn, SASL_USERNAME, &operName);
+ if (propResult == SASL_OK)
+ return std::string((const char*) operName);
+
+ return std::string();
+}
+
+void CyrusSasl::interact(sasl_interact_t* client_interact)
+{
+
+ if (client_interact->id == SASL_CB_PASS) {
+ char* password = getpass(client_interact->prompt);
+ input = std::string(password);
+ client_interact->result = input.data();
+ client_interact->len = input.size();
+ } else {
+ std::cout << client_interact->prompt;
+ if (client_interact->defresult) std::cout << " (" <<
client_interact->defresult << ")";
+ std::cout << ": ";
+ if (std::cin >> input) {
+ client_interact->result = input.data();
+ client_interact->len = input.size();
+ }
+ }
+
+}
+
+std::auto_ptr<SecurityLayer> CyrusSasl::getSecurityLayer(uint16_t maxFrameSize)
+{
+ const void* value(0);
+ int result = sasl_getprop(conn, SASL_SSF, &value);
+ if (result != SASL_OK) {
+ throw framing::InternalErrorException(QPID_MSG("SASL error: " <<
sasl_errdetail(conn)));
+ }
+ uint ssf = *(reinterpret_cast<const unsigned*>(value));
+ std::auto_ptr<SecurityLayer> securityLayer;
+ if (ssf) {
+ QPID_LOG(info, "Installing security layer, SSF: "<< ssf);
+ securityLayer = std::auto_ptr<SecurityLayer>(new
CyrusSecurityLayer(conn, maxFrameSize));
+ }
+ return securityLayer;
+}
+
+int getUserFromSettings(void* context, int /*id*/, const char** result,
unsigned* /*len*/)
+{
+ if (context) {
+ *result = ((CyrusSaslSettings*) context)->username.c_str();
+ QPID_LOG(debug, "getUserFromSettings(): " << (*result));
+ return SASL_OK;
+ } else {
+ return SASL_FAIL;
+ }
+}
+
+namespace {
+// Global map of secrets allocated for SASL connections via callback
+// to getPasswordFromSettings. Ensures secrets are freed.
+class SecretsMap {
+ typedef std::map<sasl_conn_t*, void*> Map;
+ Map map;
+ public:
+ void keep(sasl_conn_t* conn, void* secret) {
+ Map::iterator i = map.find(conn);
+ if (i != map.end()) free(i->second);
+ map[conn] = secret;
+ }
+
+ ~SecretsMap() {
+ for (Map::iterator i = map.begin(); i != map.end(); ++i)
+ free(i->second);
+ }
+};
+SecretsMap getPasswordFromSettingsSecrets;
+}
+
+int getPasswordFromSettings(sasl_conn_t* conn, void* context, int /*id*/,
sasl_secret_t** psecret)
+{
+ if (context) {
+ size_t length = ((CyrusSaslSettings*) context)->password.size();
+ sasl_secret_t* secret = (sasl_secret_t*) malloc(sizeof(sasl_secret_t)
+ length);
+ getPasswordFromSettingsSecrets.keep(conn, secret);
+ secret->len = length;
+ memcpy(secret->data, ((CyrusSaslSettings*) context)->password.data(),
length);
+ *psecret = secret;
+ return SASL_OK;
+ } else {
+ return SASL_FAIL;
+ }
+}
+
+} // namespace qpid
+
+#endif
Added: qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h?rev=1024541&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h (added)
+++ qpid/trunk/qpid/cpp/src/qpid/SaslFactory.h Wed Oct 20 08:03:36 2010
@@ -0,0 +1,47 @@
+#ifndef QPID_SASLFACTORY_H
+#define QPID_SASLFACTORY_H
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#include "qpid/Sasl.h"
+#include "qpid/sys/Mutex.h"
+#include <memory>
+
+namespace qpid {
+
+/**
+ * Factory for instances of the Sasl interface through which Sasl
+ * support is provided to a ConnectionHandler.
+ */
+class SaslFactory
+{
+ public:
+ std::auto_ptr<Sasl> create(const std::string & userName, const std::string
& password, const std::string & serviceName, const std::string & hostName, int
minSsf, int maxSsf );
+ static SaslFactory& getInstance();
+ ~SaslFactory();
+ private:
+ SaslFactory();
+ static qpid::sys::Mutex lock;
+ static std::auto_ptr<SaslFactory> instance;
+};
+} // namespace qpid
+
+#endif /*!QPID_SASLFACTORY_H*/
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Connection.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Connection.cpp?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/Connection.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/Connection.cpp Wed Oct 20 08:03:36 2010
@@ -192,6 +192,38 @@ string Connection::getAuthMechanism()
return links.getAuthMechanism(mgmtId);
}
+string Connection::getUsername ( )
+{
+ if (!isLink)
+ return string("anonymous");
+
+ return links.getUsername(mgmtId);
+}
+
+string Connection::getPassword ( )
+{
+ if (!isLink)
+ return string("");
+
+ return links.getPassword(mgmtId);
+}
+
+string Connection::getHost ( )
+{
+ if (!isLink)
+ return string("");
+
+ return links.getHost(mgmtId);
+}
+
+uint16_t Connection::getPort ( )
+{
+ if (!isLink)
+ return 0;
+
+ return links.getPort(mgmtId);
+}
+
string Connection::getAuthCredentials()
{
if (!isLink)
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Connection.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Connection.h?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/Connection.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/Connection.h Wed Oct 20 08:03:36 2010
@@ -115,6 +115,10 @@ class Connection : public sys::Connectio
void recordFromClient (framing::AMQFrame& frame);
std::string getAuthMechanism();
std::string getAuthCredentials();
+ std::string getUsername();
+ std::string getPassword();
+ std::string getHost();
+ uint16_t getPort();
void notifyConnectionForced(const std::string& text);
void setUserId(const std::string& uid);
void raiseConnectEvent();
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp Wed Oct 20
08:03:36 2010
@@ -20,6 +20,7 @@
*
*/
+#include "qpid/SaslFactory.h"
#include "qpid/broker/ConnectionHandler.h"
#include "qpid/broker/Connection.h"
#include "qpid/broker/SecureConnection.h"
@@ -49,6 +50,7 @@ const std::string CLIENT_PROCESS_NAME("q
const std::string CLIENT_PID("qpid.client_pid");
const std::string CLIENT_PPID("qpid.client_ppid");
const int SESSION_FLOW_CONTROL_VER = 1;
+const std::string SPACE(" ");
}
void ConnectionHandler::close(connection::CloseCode code, const string& text)
@@ -106,7 +108,10 @@ ConnectionHandler::Handler::Handler(Conn
boost::shared_ptr<FieldValue> l(new Str16Value(en_US));
locales.add(l);
proxy.start(properties, mechanisms, locales);
+
}
+
+ maxFrameSize = (64 * 1024) - 1;
}
@@ -230,33 +235,105 @@ void ConnectionHandler::Handler::heartbe
}
void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
- const framing::Array& /*mechanisms*/,
+ const framing::Array&
supportedMechanisms,
const framing::Array& /*locales*/)
{
- string mechanism = connection.getAuthMechanism();
+ string requestedMechanism = connection.getAuthMechanism();
string response = connection.getAuthCredentials();
+ std::string username = connection.getUsername();
+ std::string password = connection.getPassword();
+ std::string host = connection.getHost();
+ std::string service("qpidd");
+
+ sasl = SaslFactory::getInstance().create( username,
+ password,
+ service,
+ host,
+ 0, // TODO -- mgoulish Fri Sep
24 06:41:26 EDT 2010
+ 256 /* TODO -- mgoulish*/ );
+ std::string supportedMechanismsList;
+ bool requestedMechanismIsSupported = false;
+ Array::const_iterator i;
+
+ /*
+ If no specific mechanism has been requested, just make
+ a list of all of them, and assert that the one the caller
+ requested is there. ( If *any* are supported! )
+ */
+ if ( requestedMechanism.empty() ) {
+ for ( i = supportedMechanisms.begin(); i != supportedMechanisms.end();
++i) {
+ if (i != supportedMechanisms.begin())
+ supportedMechanismsList += SPACE;
+ supportedMechanismsList += (*i)->get<std::string>();
+ requestedMechanismIsSupported = true;
+ }
+ }
+ else {
+ requestedMechanismIsSupported = false;
+ /*
+ The caller has requested a mechanism. If it's available,
+ make sure it ends up at the head of the list.
+ */
+ for ( i = supportedMechanisms.begin(); i != supportedMechanisms.end();
++i) {
+ string currentMechanism = (*i)->get<std::string>();
+
+ if ( requestedMechanism == currentMechanism ) {
+ requestedMechanismIsSupported = true;
+ supportedMechanismsList = currentMechanism + SPACE +
supportedMechanismsList;
+ } else {
+ if (i != supportedMechanisms.begin())
+ supportedMechanismsList += SPACE;
+ supportedMechanismsList += currentMechanism;
+ }
+ }
+ }
+
connection.setFederationPeerTag(serverProperties.getAsString(QPID_FED_TAG));
FieldTable ft;
ft.setInt(QPID_FED_LINK,1);
ft.setString(QPID_FED_TAG, connection.getBroker().getFederationTag());
- proxy.startOk(ft, mechanism, response, en_US);
+
+ if (sasl.get()) {
+ string response =
+ sasl->start ( requestedMechanism.empty()
+ ? supportedMechanismsList
+ : requestedMechanism,
+ getSecuritySettings
+ ? getSecuritySettings()
+ : 0
+ );
+ proxy.startOk ( ft, sasl->getMechanism(), response, en_US );
+ }
+ else {
+ string response = ((char)0) + username + ((char)0) + password;
+ proxy.startOk ( ft, requestedMechanism, response, en_US );
+ }
+
}
-void ConnectionHandler::Handler::secure(const string& /*challenge*/)
+void ConnectionHandler::Handler::secure(const string& challenge )
{
- proxy.secureOk("");
+ if (sasl.get()) {
+ string response = sasl->step(challenge);
+ proxy.secureOk(response);
+ }
+ else {
+ proxy.secureOk("");
+ }
}
void ConnectionHandler::Handler::tune(uint16_t channelMax,
- uint16_t frameMax,
+ uint16_t maxFrameSizeProposed,
uint16_t /*heartbeatMin*/,
uint16_t heartbeatMax)
{
- connection.setFrameMax(frameMax);
+ maxFrameSize = std::min(maxFrameSize, maxFrameSizeProposed);
+ connection.setFrameMax(maxFrameSize);
+
connection.setHeartbeat(heartbeatMax);
- proxy.tuneOk(channelMax, frameMax, heartbeatMax);
+ proxy.tuneOk(channelMax, maxFrameSize, heartbeatMax);
proxy.open("/", Array(), true);
}
@@ -266,6 +343,17 @@ void ConnectionHandler::Handler::openOk(
Url url((*i)->get<std::string>());
connection.getKnownHosts().push_back(url);
}
+
+ if (sasl.get()) {
+ std::auto_ptr<qpid::sys::SecurityLayer> securityLayer =
sasl->getSecurityLayer(maxFrameSize);
+
+ if ( securityLayer.get() ) {
+ secured->activateSecurityLayer(securityLayer, true);
+ }
+
+ saslUserId = sasl->getUserId();
+ }
+
isOpen = true;
}
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.h?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/ConnectionHandler.h Wed Oct 20 08:03:36
2010
@@ -22,6 +22,7 @@
#define _ConnectionAdapter_
#include <memory>
+#include "qpid/Sasl.h"
#include "qpid/broker/SaslAuthenticator.h"
#include "qpid/framing/amqp_types.h"
#include "qpid/framing/AMQFrame.h"
@@ -33,8 +34,16 @@
#include "qpid/framing/ProtocolVersion.h"
#include "qpid/Exception.h"
#include "qpid/broker/AclModule.h"
+#include "qpid/sys/SecurityLayer.h"
+
namespace qpid {
+
+namespace sys {
+struct SecuritySettings;
+}
+
+
namespace broker {
class Connection;
@@ -79,6 +88,12 @@ class ConnectionHandler : public framing
void openOk(const framing::Array& knownHosts);
void redirect(const std::string& host, const framing::Array&
knownHosts);
+
+ std::auto_ptr<Sasl> sasl;
+ typedef boost::function<const qpid::sys::SecuritySettings*()>
GetSecuritySettings;
+ GetSecuritySettings getSecuritySettings; /* query the transport
for its security details */
+ std::string saslUserId;
+ uint16_t maxFrameSize;
};
std::auto_ptr<Handler> handler;
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.cpp?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.cpp Wed Oct 20 08:03:36
2010
@@ -312,6 +312,42 @@ std::string LinkRegistry::getAuthCredent
return result;
}
+std::string LinkRegistry::getUsername(const std::string& key)
+{
+ Link::shared_ptr link = findLink(key);
+ if (!link)
+ return string();
+
+ return link->getUsername();
+}
+
+std::string LinkRegistry::getHost(const std::string& key)
+{
+ Link::shared_ptr link = findLink(key);
+ if (!link)
+ return string();
+
+ return link->getHost();
+}
+
+uint16_t LinkRegistry::getPort(const std::string& key)
+{
+ Link::shared_ptr link = findLink(key);
+ if (!link)
+ return 0;
+
+ return link->getPort();
+}
+
+std::string LinkRegistry::getPassword(const std::string& key)
+{
+ Link::shared_ptr link = findLink(key);
+ if (!link)
+ return string();
+
+ return link->getPassword();
+}
+
std::string LinkRegistry::getAuthIdentity(const std::string& key)
{
Link::shared_ptr link = findLink(key);
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.h?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/LinkRegistry.h Wed Oct 20 08:03:36 2010
@@ -132,6 +132,10 @@ namespace broker {
std::string getAuthMechanism (const std::string& key);
std::string getAuthCredentials (const std::string& key);
std::string getAuthIdentity (const std::string& key);
+ std::string getUsername (const std::string& key);
+ std::string getPassword (const std::string& key);
+ std::string getHost (const std::string& key);
+ uint16_t getPort (const std::string& key);
/**
* Called by links failing over to new address
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.cpp?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.cpp Wed Oct 20
08:03:36 2010
@@ -78,10 +78,13 @@ void SecureConnection:: setCodec(std::au
codec = c;
}
-void SecureConnection::activateSecurityLayer(std::auto_ptr<SecurityLayer> sl)
+void SecureConnection::activateSecurityLayer(std::auto_ptr<SecurityLayer> sl,
bool secureImmediately)
{
securityLayer = sl;
securityLayer->init(codec.get());
+
+ if ( secureImmediately )
+ secured = true;
}
}} // namespace qpid::broker
Modified: qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.h?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/SecureConnection.h Wed Oct 20 08:03:36
2010
@@ -49,7 +49,7 @@ class SecureConnection : public qpid::sy
bool isClosed() const;
framing::ProtocolVersion getVersion() const;
void setCodec(std::auto_ptr<ConnectionCodec>);
- void activateSecurityLayer(std::auto_ptr<qpid::sys::SecurityLayer>);
+ void activateSecurityLayer(std::auto_ptr<qpid::sys::SecurityLayer>, bool
secureImmediately=false);
private:
std::auto_ptr<ConnectionCodec> codec;
std::auto_ptr<qpid::sys::SecurityLayer> securityLayer;
Modified: qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.cpp Wed Oct 20
08:03:36 2010
@@ -21,7 +21,7 @@
#include "qpid/client/ConnectionHandler.h"
-#include "qpid/client/SaslFactory.h"
+#include "qpid/SaslFactory.h"
#include "qpid/client/Bounds.h"
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/all_method_bodies.h"
@@ -208,7 +208,13 @@ void ConnectionHandler::start(const Fiel
{
checkState(NOT_STARTED, INVALID_STATE_START);
setState(NEGOTIATING);
- sasl = SaslFactory::getInstance().create(*this);
+ sasl = SaslFactory::getInstance().create( username,
+ password,
+ service,
+ host,
+ minSsf,
+ maxSsf
+ );
std::string mechlist;
bool chosenMechanismSupported = mechanism.empty();
Modified: qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.h
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.h?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/ConnectionHandler.h Wed Oct 20 08:03:36
2010
@@ -23,7 +23,7 @@
#include "qpid/client/ChainableFrameHandler.h"
#include "qpid/client/ConnectionSettings.h"
-#include "qpid/client/Sasl.h"
+#include "qpid/Sasl.h"
#include "qpid/client/StateManager.h"
#include "qpid/framing/AMQMethodBody.h"
#include "qpid/framing/AMQP_HighestVersion.h"
Modified: qpid/trunk/qpid/cpp/src/tests/sasl.mk
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/sasl.mk?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/sasl.mk (original)
+++ qpid/trunk/qpid/cpp/src/tests/sasl.mk Wed Oct 20 08:03:36 2010
@@ -26,6 +26,7 @@ cluster_authentication_soak_SOURCES=clus
cluster_authentication_soak_LDADD=$(lib_client) $(lib_broker)
TESTS += run_cluster_authentication_test
+TESTS += sasl_fed
LONG_TESTS += run_cluster_authentication_soak
endif # HAVE_SASL
Added: qpid/trunk/qpid/cpp/src/tests/sasl_fed
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/sasl_fed?rev=1024541&view=auto
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/sasl_fed (added)
+++ qpid/trunk/qpid/cpp/src/tests/sasl_fed Wed Oct 20 08:03:36 2010
@@ -0,0 +1,152 @@
+#! /bin/bash
+
+source test_env.sh
+
+minimum_sasl_version="2.1.22"
+if [ ! `pkg-config --atleast-version $minimum_sasl_version cyrus-sasl`]; then
+ echo "sasl_fed requires at least $minimum_sasl_version"
+ exit 0
+fi
+
+let minimum_sasl_version=$((2 * 65536 + 1 * 256 + 22))
+sasl_version_numbers=(`rpm -q cyrus-sasl-devel | head -1 | tr '-' ' ' | awk
'{print $4}' | tr '.' ' '`)
+let sasl_version=$((${sasl_version_numbers[0]} * 65536 +
${sasl_version_numbers[1]} * 256 + ${sasl_version_numbers[2]}))
+
+if [ "$sasl_version" -lt "$minimum_sasl_version" ]; then
+ echo "sasl_fed requires version 2.1.22 or later"
+ exit 0
+fi
+
+exit
+
+QPID_SRC=$top_srcdir/src
+QPIDD=$QPID_SRC/.libs/qpidd
+PY_TOOLS=$QPID_TOOLS/src/py
+
+sasl_config_file=$QPID_SRC/tests/sasl_config
+
+my_random_number=$RANDOM
+tmp_root=/tmp/sasl_fed/$my_random_number
+mkdir -p $tmp_root
+
+
+#--------------------------------------------------
+#echo " Starting broker 1"
+#--------------------------------------------------
+$QPIDD \
+ -p 0 \
+ --data-dir $tmp_root/data_1 \
+ --auth=yes \
+ --mgmt-enable=yes \
+ --log-enable info+ \
+ --log-source yes \
+ --log-to-file $tmp_root/qpidd_1.log \
+ --sasl-config=$sasl_config_file \
+ -d > $tmp_root/broker_1_port
+
+broker_1_port=`cat $tmp_root/broker_1_port`
+
+
+#--------------------------------------------------
+#echo " Starting broker 2"
+#--------------------------------------------------
+$QPIDD \
+ -p 0 \
+ --data-dir $tmp_root/data_2 \
+ --auth=yes \
+ --mgmt-enable=yes \
+ --log-enable info+ \
+ --log-source yes \
+ --log-to-file $tmp_root/qpidd_2.log \
+ --sasl-config=$sasl_config_file \
+ -d > $tmp_root/broker_2_port
+
+broker_2_port=`cat $tmp_root/broker_2_port`
+
+
+# Now find the PIDs so I can kill them later.
+#pids=`ps -aef | grep -v grep | grep sasl_fed | grep $my_random_number | awk
'{print $2}'`
+
+
+# I am not randomizing these names, because the test creates its own brokers.
+QUEUE_NAME=sasl_fed_queue
+ROUTING_KEY=sasl_fed_queue
+EXCHANGE_NAME=sasl_fedex
+
+#--------------------------------------------------
+#echo " add exchanges"
+#--------------------------------------------------
+$PY_TOOLS/qpid-config -a localhost:$broker_1_port add exchange direct
$EXCHANGE_NAME
+$PY_TOOLS/qpid-config -a localhost:$broker_2_port add exchange direct
$EXCHANGE_NAME
+
+
+#--------------------------------------------------
+#echo " add queues"
+#--------------------------------------------------
+$PY_TOOLS/qpid-config -a localhost:$broker_1_port add queue $QUEUE_NAME
+$PY_TOOLS/qpid-config -a localhost:$broker_2_port add queue $QUEUE_NAME
+
+sleep 5
+
+#--------------------------------------------------
+#echo " create bindings"
+#--------------------------------------------------
+$PY_TOOLS/qpid-config -a localhost:$broker_1_port bind $EXCHANGE_NAME
$QUEUE_NAME $ROUTING_KEY
+$PY_TOOLS/qpid-config -a localhost:$broker_2_port bind $EXCHANGE_NAME
$QUEUE_NAME $ROUTING_KEY
+
+sleep 5
+
+
+#--------------------------------------------------
+#echo " qpid-route route add"
+#--------------------------------------------------
+$PY_TOOLS/qpid-route route add zag/z...@localhost:$broker_2_port
zag/z...@localhost:$broker_1_port $EXCHANGE_NAME $ROUTING_KEY "" "" DIGEST-MD5
+
+sleep 5
+
+
+n_messages=100
+#--------------------------------------------------
+#echo " Sending 100 messages to $broker_1_port "
+#--------------------------------------------------
+$QPID_SRC/tests/datagen --count $n_messages | $QPID_SRC/tests/sender
--username zag --password zag --exchange $EXCHANGE_NAME --routing-key
$ROUTING_KEY --port $broker_1_port
+
+sleep 5
+
+#--------------------------------------------------
+#echo " Examine Broker $broker_1_port"
+#--------------------------------------------------
+broker_1_message_count=`$PY_TOOLS/qpid-stat -q localhost:$broker_1_port | grep
sasl_fed_queue | awk '{print $2}'`
+#echo " "
+
+#--------------------------------------------------
+#echo " Examine Broker $broker_2_port"
+#--------------------------------------------------
+broker_2_message_count=`$PY_TOOLS/qpid-stat -q localhost:$broker_2_port | grep
sasl_fed_queue | awk '{print $2}'`
+#echo " "
+
+#--------------------------------------------------
+#echo " Asking brokers to quit."
+#--------------------------------------------------
+$QPIDD --port $broker_1_port --quit
+$QPIDD --port $broker_2_port --quit
+
+
+#--------------------------------------------------
+#echo "Removing temporary directory $tmp_root"
+#--------------------------------------------------
+rm -rf $tmp_root
+
+if [ "$broker_2_message_count" = "$n_messages" ]; then
+ echo "good: $broker_2_message_count"
+ exit 0
+else
+ echo "not ideal: $broker_1_message_count != $n_messages"
+ exit 1
+fi
+
+
+
+
+
+
Propchange: qpid/trunk/qpid/cpp/src/tests/sasl_fed
------------------------------------------------------------------------------
svn:executable = *
Modified: qpid/trunk/qpid/tools/src/py/qpid-route
URL:
http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/py/qpid-route?rev=1024541&r1=1024540&r2=1024541&view=diff
==============================================================================
--- qpid/trunk/qpid/tools/src/py/qpid-route (original)
+++ qpid/trunk/qpid/tools/src/py/qpid-route Wed Oct 20 08:03:36 2010
@@ -30,7 +30,7 @@ def Usage(short=False):
print "Usage: qpid-route [OPTIONS] dynamic add <dest-broker> <src-broker>
<exchange> [tag] [exclude-list]"
print " qpid-route [OPTIONS] dynamic del <dest-broker> <src-broker>
<exchange>"
print
- print " qpid-route [OPTIONS] route add <dest-broker> <src-broker>
<exchange> <routing-key> [tag] [exclude-list]"
+ print " qpid-route [OPTIONS] route add <dest-broker> <src-broker>
<exchange> <routing-key> [tag] [exclude-list] [mechanism]"
print " qpid-route [OPTIONS] route del <dest-broker> <src-broker>
<exchange> <routing-key>"
print " qpid-route [OPTIONS] queue add <dest-broker> <src-broker>
<exchange> <queue>"
print " qpid-route [OPTIONS] queue del <dest-broker> <src-broker>
<exchange> <queue>"
@@ -98,7 +98,7 @@ class RouteManager:
return link
return None
- def addLink(self, remoteBroker):
+ def addLink(self, remoteBroker, mech="PLAIN"):
self.remote = BrokerURL(remoteBroker)
if self.local.match(self.remote.host, self.remote.port):
raise Exception("Linking broker to itself is not permitted")
@@ -107,10 +107,6 @@ class RouteManager:
broker = brokers[0]
link = self.getLink()
if link == None:
- if not self.remote.authName or self.remote.authName == "anonymous":
- mech = "ANONYMOUS"
- else:
- mech = "PLAIN"
res = broker.connect(self.remote.host, self.remote.port, _durable,
mech, self.remote.authName or "",
self.remote.authPass or "",
_transport)
@@ -231,11 +227,11 @@ class RouteManager:
if b[0] != self.local.name():
self.qmf.delBroker(b[1])
- def addRoute(self, remoteBroker, exchange, routingKey, tag, excludes,
dynamic=False):
+ def addRoute(self, remoteBroker, exchange, routingKey, tag, excludes,
mech="PLAIN", dynamic=False):
if dynamic and _srclocal:
raise Exception("--src-local is not permitted on dynamic routes")
- self.addLink(remoteBroker)
+ self.addLink(remoteBroker, mech)
link = self.getLink()
if link == None:
raise Exception("Link failed to create")
@@ -494,9 +490,10 @@ try:
tag = ""
excludes = ""
+ mech = "PLAIN"
if nargs > 5: tag = cargs[5]
if nargs > 6: excludes = cargs[6]
- rm.addRoute(remoteBroker, cargs[4], "", tag, excludes,
dynamic=True)
+ rm.addRoute(remoteBroker, cargs[4], "", tag, excludes, mech,
dynamic=True)
elif cmd == "del":
if nargs != 5:
Usage()
@@ -505,14 +502,16 @@ try:
elif group == "route":
if cmd == "add":
- if nargs < 6 or nargs > 8:
+ if nargs < 6 or nargs > 9:
Usage()
tag = ""
excludes = ""
+ mech = "PLAIN"
if nargs > 6: tag = cargs[6]
if nargs > 7: excludes = cargs[7]
- rm.addRoute(remoteBroker, cargs[4], cargs[5], tag, excludes,
dynamic=False)
+ if nargs > 8: mech = cargs[8]
+ rm.addRoute(remoteBroker, cargs[4], cargs[5], tag, excludes, mech,
dynamic=False)
elif cmd == "del":
if nargs != 6:
Usage()
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:[email protected]