From c81ac8cc24b35c0d9465b839936d5403d982b5c1 Mon Sep 17 00:00:00 2001 From: Michael Goulish Date: Tue, 30 Nov 2010 18:39:48 +0000 Subject: This patch was posted in JIRA QPID-2949. It provides a way to tell SaslFactory that console interaction is NOT ok. i.e. if the code is running as part of a broker, or a demonized client of some kind. Just tell it to never do interaction, and any patch attempt to interact will be treated as an error. This script demonstrates that all goes well if you supply enough info : rm -rf /tmp/data_1 /tmp/data_2 mkdir /tmp/data_1 /tmp/data_2 # in window 1: ../qpidd -p 5672 --data-dir /tmp/data_1 --auth=yes --mgmt-enable=yes \ --log-enable info+ ./qpidd_1.log --log-source yes \ --sasl-config=/home/mick/trunk/qpid/cpp/src/tests/sasl_config # in window 2: ../qpidd -p 10000 --data-dir /tmp/data_2 --auth=yes --mgmt-enable=yes \ --log-enable info+ ./qpidd_1.log --log-source yes \ --sasl-config=/home/mick/trunk/qpid/cpp/src/tests/sasl_config # in window 3 ( from qpid dir ) ./tools/src/py/qpid-route dynamic add zig/zig@localhost zig/zig@localhost:10000 qmf.default.direct # and now view the created route ./tools/src/py/qpid-route route list localhost:5672 If you say auth=no, that works fine also. HOWEVER PLEASE NOTE -- if you say auth=yes, but then do not supply enough into to avoid the need for interaction, the attempted interaction will result in the connection being closed. Then the originating broker will re-try the connection, and you will get a two-broker infinite loop until you fix it. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1040689 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/SaslFactory.cpp | 23 ++++++++++++++++++----- cpp/src/qpid/SaslFactory.h | 2 +- cpp/src/qpid/broker/Broker.h | 1 + cpp/src/qpid/broker/ConnectionHandler.cpp | 15 +++++++++------ 4 files changed, 29 insertions(+), 12 deletions(-) (limited to 'cpp') diff --git a/cpp/src/qpid/SaslFactory.cpp b/cpp/src/qpid/SaslFactory.cpp index 28c27f7529..664961e5d8 100644 --- a/cpp/src/qpid/SaslFactory.cpp +++ b/cpp/src/qpid/SaslFactory.cpp @@ -110,7 +110,7 @@ struct CyrusSaslSettings 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(const std::string & username, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction); ~CyrusSasl(); std::string start(const std::string& mechanisms, const SecuritySettings* externalSettings); std::string step(const std::string& challenge); @@ -125,6 +125,10 @@ class CyrusSasl : public Sasl std::string mechanism; char login[MAX_LOGIN_LENGTH]; + /* In some contexts, like running in the broker or as a daemon, console + * interaction is impossible. In those cases, we will treat the attempt + * to interact as an error. */ + bool allowInteraction; void interact(sasl_interact_t* client_interact); }; @@ -159,14 +163,14 @@ SaslFactory& SaslFactory::getInstance() return *instance; } -std::auto_ptr 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 SaslFactory::create(const std::string & username, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction) { - std::auto_ptr sasl(new CyrusSasl(username, password, serviceName, hostName, minSsf, maxSsf)); + std::auto_ptr sasl(new CyrusSasl(username, password, serviceName, hostName, minSsf, maxSsf, allowInteraction)); 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) +CyrusSasl::CyrusSasl(const std::string & username, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction) + : conn(0), settings(username, password, serviceName, hostName, minSsf, maxSsf), allowInteraction(allowInteraction) { size_t i = 0; @@ -330,6 +334,15 @@ std::string CyrusSasl::getUserId() void CyrusSasl::interact(sasl_interact_t* client_interact) { + /* + In some context console interaction cannot be allowed, such + as when this code run as part of a broker, or as a some other + daemon. In those cases we will treat the attempt to + */ + if ( ! allowInteraction ) { + throw InternalErrorException("interaction disallowed"); + } + if (client_interact->id == SASL_CB_PASS) { char* password = getpass(client_interact->prompt); input = std::string(password); diff --git a/cpp/src/qpid/SaslFactory.h b/cpp/src/qpid/SaslFactory.h index 450b70cd46..8554597147 100644 --- a/cpp/src/qpid/SaslFactory.h +++ b/cpp/src/qpid/SaslFactory.h @@ -34,7 +34,7 @@ namespace qpid { class SaslFactory { public: - QPID_COMMON_EXTERN std::auto_ptr create(const std::string & userName, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf ); + QPID_COMMON_EXTERN std::auto_ptr create(const std::string & userName, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool allowInteraction=true ); QPID_COMMON_EXTERN static SaslFactory& getInstance(); QPID_COMMON_EXTERN ~SaslFactory(); private: diff --git a/cpp/src/qpid/broker/Broker.h b/cpp/src/qpid/broker/Broker.h index 6636b5d912..4f089a1fca 100644 --- a/cpp/src/qpid/broker/Broker.h +++ b/cpp/src/qpid/broker/Broker.h @@ -286,6 +286,7 @@ public: boost::function& msg)> deferDelivery; + bool isAuthenticating ( ) { return config.auth; } }; }} diff --git a/cpp/src/qpid/broker/ConnectionHandler.cpp b/cpp/src/qpid/broker/ConnectionHandler.cpp index c812374d38..9843c16326 100644 --- a/cpp/src/qpid/broker/ConnectionHandler.cpp +++ b/cpp/src/qpid/broker/ConnectionHandler.cpp @@ -246,12 +246,15 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties, 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*/ ); + if ( connection.getBroker().isAuthenticating() ) { + sasl = SaslFactory::getInstance().create( username, + password, + service, + host, + 0, // TODO -- mgoulish Fri Sep 24 2010 + 256, + false ); // disallow interaction + } std::string supportedMechanismsList; bool requestedMechanismIsSupported = false; Array::const_iterator i; -- cgit v1.2.1