summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/client
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2010-03-05 16:51:22 +0000
committerGordon Sim <gsim@apache.org>2010-03-05 16:51:22 +0000
commitf5e41be93bec9b5556a65292516db07ff845f7d4 (patch)
treed26b9519d281dbb36fd6717205462399292896dd /cpp/src/qpid/client
parent74d838068a2a24423c0c5af1e33b612e132291fb (diff)
downloadqpid-python-f5e41be93bec9b5556a65292516db07ff845f7d4.tar.gz
QPID-2412: Support for EXTERNAL mechanism on client-authenticated SSL connections.
On SSL connection where the clients certificate is authenticated (requires the --ssl-require-client-authentication option at present), the clients identity will be taken from that certificate (it will be the CN with any DCs present appended as the domain, e.g. CN=bob,DC=acme,DC=com would result in an identity of bob@acme.com). This will enable the EXTERNAL mechanism when cyrus sasl is in use. The client can still negotiate their desired mechanism. There is a new option on the ssl module (--ssl-sasl-no-dict) that allows the options on ssl connections to be restricted to those that are not vulnerable to dictionary attacks (EXTERNAL being the primary example). git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@919487 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/client')
-rw-r--r--cpp/src/qpid/client/ConnectionHandler.cpp2
-rw-r--r--cpp/src/qpid/client/ConnectionHandler.h9
-rw-r--r--cpp/src/qpid/client/ConnectionImpl.cpp2
-rw-r--r--cpp/src/qpid/client/Connector.h3
-rw-r--r--cpp/src/qpid/client/RdmaConnector.cpp2
-rw-r--r--cpp/src/qpid/client/Sasl.h14
-rw-r--r--cpp/src/qpid/client/SaslFactory.cpp21
-rw-r--r--cpp/src/qpid/client/SslConnector.cpp11
-rw-r--r--cpp/src/qpid/client/TCPConnector.h2
-rw-r--r--cpp/src/qpid/client/windows/SaslFactory.cpp6
10 files changed, 46 insertions, 26 deletions
diff --git a/cpp/src/qpid/client/ConnectionHandler.cpp b/cpp/src/qpid/client/ConnectionHandler.cpp
index 8f1cc7b03f..9d68448d9d 100644
--- a/cpp/src/qpid/client/ConnectionHandler.cpp
+++ b/cpp/src/qpid/client/ConnectionHandler.cpp
@@ -213,7 +213,7 @@ void ConnectionHandler::start(const FieldTable& /*serverProps*/, const Array& me
if (sasl.get()) {
string response = sasl->start(mechanism.empty() ? mechlist : mechanism,
- getSSF ? getSSF() : 0);
+ getSecuritySettings ? getSecuritySettings() : 0);
proxy.startOk(properties, sasl->getMechanism(), response, locale);
} else {
//TODO: verify that desired mechanism and locale are supported
diff --git a/cpp/src/qpid/client/ConnectionHandler.h b/cpp/src/qpid/client/ConnectionHandler.h
index ed1e385dcf..5f4b454f53 100644
--- a/cpp/src/qpid/client/ConnectionHandler.h
+++ b/cpp/src/qpid/client/ConnectionHandler.h
@@ -40,6 +40,11 @@
#include <memory>
namespace qpid {
+
+namespace sys {
+struct SecuritySettings;
+}
+
namespace client {
class ConnectionHandler : private StateManager,
@@ -95,7 +100,7 @@ public:
using InputHandler::handle;
typedef boost::function<void()> CloseListener;
typedef boost::function<void(uint16_t, const std::string&)> ErrorListener;
- typedef boost::function<unsigned int()> GetConnSSF;
+ typedef boost::function<const qpid::sys::SecuritySettings*()> GetSecuritySettings;
ConnectionHandler(const ConnectionSettings&, framing::ProtocolVersion&);
@@ -123,7 +128,7 @@ public:
static framing::connection::CloseCode convert(uint16_t replyCode);
const std::string& getUserId() const { return operUserId; }
- GetConnSSF getSSF; /** query the connection for its security strength factor */
+ GetSecuritySettings getSecuritySettings; /** query the transport for its security details */
};
}}
diff --git a/cpp/src/qpid/client/ConnectionImpl.cpp b/cpp/src/qpid/client/ConnectionImpl.cpp
index 80cd510886..280d3da924 100644
--- a/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -165,7 +165,7 @@ ConnectionImpl::ConnectionImpl(framing::ProtocolVersion v, const ConnectionSetti
CLOSE_CODE_NORMAL, std::string());
//only set error handler once open
handler.onError = boost::bind(&ConnectionImpl::closed, this, _1, _2);
- handler.getSSF = boost::bind(&Connector::getSSF, boost::ref(connector));
+ handler.getSecuritySettings = boost::bind(&Connector::getSecuritySettings, boost::ref(connector));
}
const uint16_t ConnectionImpl::NEXT_CHANNEL = std::numeric_limits<uint16_t>::max();
diff --git a/cpp/src/qpid/client/Connector.h b/cpp/src/qpid/client/Connector.h
index 0203895b00..586012f9d6 100644
--- a/cpp/src/qpid/client/Connector.h
+++ b/cpp/src/qpid/client/Connector.h
@@ -35,6 +35,7 @@ namespace sys {
class ShutdownHandler;
class SecurityLayer;
class Poller;
+struct SecuritySettings;
}
namespace framing {
@@ -74,7 +75,7 @@ class Connector : public framing::OutputHandler
virtual void activateSecurityLayer(std::auto_ptr<qpid::sys::SecurityLayer>);
- virtual unsigned int getSSF() = 0;
+ virtual const qpid::sys::SecuritySettings* getSecuritySettings() = 0;
};
}}
diff --git a/cpp/src/qpid/client/RdmaConnector.cpp b/cpp/src/qpid/client/RdmaConnector.cpp
index 2bdfb8d68f..42b4649203 100644
--- a/cpp/src/qpid/client/RdmaConnector.cpp
+++ b/cpp/src/qpid/client/RdmaConnector.cpp
@@ -109,7 +109,7 @@ class RdmaConnector : public Connector, public sys::Codec
framing::OutputHandler* getOutputHandler();
const std::string& getIdentifier() const;
void activateSecurityLayer(std::auto_ptr<qpid::sys::SecurityLayer>);
- unsigned int getSSF() { return 0; }
+ const qpid::sys::SecuritySettings* getSecuritySettings() { return 0; }
size_t decode(const char* buffer, size_t size);
size_t encode(const char* buffer, size_t size);
diff --git a/cpp/src/qpid/client/Sasl.h b/cpp/src/qpid/client/Sasl.h
index 63da37fcb1..56735a5fc3 100644
--- a/cpp/src/qpid/client/Sasl.h
+++ b/cpp/src/qpid/client/Sasl.h
@@ -30,6 +30,7 @@ namespace qpid {
namespace sys {
class SecurityLayer;
+struct SecuritySettings;
}
namespace client {
@@ -48,17 +49,10 @@ class Sasl
*
* @param mechanisms Comma-separated list of the SASL mechanism the
* client supports.
- * @param ssf Security Strength Factor (SSF). SSF is used to negotiate
- * a SASL security layer on top of the connection should both
- * parties require and support it. The value indicates the
- * required level of security for communication. Possible
- * values are:
- * @li 0 No security
- * @li 1 Integrity checking only
- * @li >1 Integrity and confidentiality with the number
- * giving the encryption key length.
+ * @param externalSecuritySettings security related details from the underlying transport
*/
- virtual std::string start(const std::string& mechanisms, unsigned int ssf) = 0;
+ 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;
diff --git a/cpp/src/qpid/client/SaslFactory.cpp b/cpp/src/qpid/client/SaslFactory.cpp
index 5012b75c94..ec5680c8d8 100644
--- a/cpp/src/qpid/client/SaslFactory.cpp
+++ b/cpp/src/qpid/client/SaslFactory.cpp
@@ -61,6 +61,7 @@ std::auto_ptr<SaslFactory> SaslFactory::instance;
#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>
@@ -70,6 +71,7 @@ namespace qpid {
namespace client {
using qpid::sys::SecurityLayer;
+using qpid::sys::SecuritySettings;
using qpid::sys::cyrus::CyrusSecurityLayer;
using qpid::framing::InternalErrorException;
@@ -80,7 +82,7 @@ class CyrusSasl : public Sasl
public:
CyrusSasl(const ConnectionSettings&);
~CyrusSasl();
- std::string start(const std::string& mechanisms, unsigned int ssf);
+ std::string start(const std::string& mechanisms, const SecuritySettings* externalSettings);
std::string step(const std::string& challenge);
std::string getMechanism();
std::string getUserId();
@@ -176,7 +178,7 @@ namespace {
const std::string SSL("ssl");
}
-std::string CyrusSasl::start(const std::string& mechanisms, unsigned int ssf)
+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(),
@@ -190,14 +192,22 @@ std::string CyrusSasl::start(const std::string& mechanisms, unsigned int ssf)
sasl_security_properties_t secprops;
- if (ssf) {
- sasl_ssf_t external_ssf = (sasl_ssf_t) ssf;
+ 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 " << ssf);
+ 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);
}
}
@@ -216,7 +226,6 @@ std::string CyrusSasl::start(const std::string& mechanisms, unsigned int ssf)
throw framing::InternalErrorException(QPID_MSG("SASL error: " << sasl_errdetail(conn)));
}
-
sasl_interact_t* client_interact = 0;
const char *out = 0;
unsigned outlen = 0;
diff --git a/cpp/src/qpid/client/SslConnector.cpp b/cpp/src/qpid/client/SslConnector.cpp
index cf6d54d261..0c794145db 100644
--- a/cpp/src/qpid/client/SslConnector.cpp
+++ b/cpp/src/qpid/client/SslConnector.cpp
@@ -34,6 +34,7 @@
#include "qpid/sys/ssl/SslSocket.h"
#include "qpid/sys/Dispatcher.h"
#include "qpid/sys/Poller.h"
+#include "qpid/sys/SecuritySettings.h"
#include "qpid/Msg.h"
#include <iostream>
@@ -86,6 +87,7 @@ class SslConnector : public Connector
const uint16_t maxFrameSize;
framing::ProtocolVersion version;
bool initiated;
+ SecuritySettings securitySettings;
sys::Mutex closedLock;
bool closed;
@@ -125,7 +127,7 @@ class SslConnector : public Connector
sys::ShutdownHandler* getShutdownHandler() const;
framing::OutputHandler* getOutputHandler();
const std::string& getIdentifier() const;
- unsigned int getSSF() { return socket.getKeyLen(); }
+ const SecuritySettings* getSecuritySettings();
public:
SslConnector(Poller::shared_ptr p, framing::ProtocolVersion pVersion,
@@ -366,4 +368,11 @@ void SslConnector::eof(SslIO&) {
handleClosed();
}
+const SecuritySettings* SslConnector::getSecuritySettings()
+{
+ securitySettings.ssf = socket.getKeyLen();
+ securitySettings.authid = "dummy";//set to non-empty string to enable external authentication
+ return &securitySettings;
+}
+
}} // namespace qpid::client
diff --git a/cpp/src/qpid/client/TCPConnector.h b/cpp/src/qpid/client/TCPConnector.h
index 6ca750f52f..6d447def2e 100644
--- a/cpp/src/qpid/client/TCPConnector.h
+++ b/cpp/src/qpid/client/TCPConnector.h
@@ -92,7 +92,7 @@ class TCPConnector : public Connector, public sys::Codec
framing::OutputHandler* getOutputHandler();
const std::string& getIdentifier() const;
void activateSecurityLayer(std::auto_ptr<qpid::sys::SecurityLayer>);
- unsigned int getSSF() { return 0; }
+ const qpid::sys::SecuritySettings* getSecuritySettings() { return 0; }
size_t decode(const char* buffer, size_t size);
size_t encode(const char* buffer, size_t size);
diff --git a/cpp/src/qpid/client/windows/SaslFactory.cpp b/cpp/src/qpid/client/windows/SaslFactory.cpp
index 87df187ab2..40c112f534 100644
--- a/cpp/src/qpid/client/windows/SaslFactory.cpp
+++ b/cpp/src/qpid/client/windows/SaslFactory.cpp
@@ -25,6 +25,7 @@
#include "qpid/Exception.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/sys/SecurityLayer.h"
+#include "qpid/sys/SecuritySettings.h"
#include "qpid/log/Statement.h"
#include "boost/tokenizer.hpp"
@@ -33,6 +34,7 @@ namespace qpid {
namespace client {
using qpid::sys::SecurityLayer;
+using qpid::sys::SecuritySettings;
using qpid::framing::InternalErrorException;
class WindowsSasl : public Sasl
@@ -40,7 +42,7 @@ class WindowsSasl : public Sasl
public:
WindowsSasl(const ConnectionSettings&);
~WindowsSasl();
- std::string start(const std::string& mechanisms, unsigned int ssf);
+ std::string start(const std::string& mechanisms, const SecuritySettings* externalSettings);
std::string step(const std::string& challenge);
std::string getMechanism();
std::string getUserId();
@@ -91,7 +93,7 @@ WindowsSasl::~WindowsSasl()
}
std::string WindowsSasl::start(const std::string& mechanisms,
- unsigned int /*ssf*/)
+ const SecuritySettings* /*externalSettings*/)
{
QPID_LOG(debug, "WindowsSasl::start(" << mechanisms << ")");