summaryrefslogtreecommitdiff
path: root/qpid/cpp/src
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2014-06-24 16:15:34 +0000
committerGordon Sim <gsim@apache.org>2014-06-24 16:15:34 +0000
commit68845de60abe21ad102ed3e094a3674bd4b377a0 (patch)
tree48cd42dcd24eef32868201a96fa3cb13af4388e2 /qpid/cpp/src
parent1cb67f36e63353d19e4b397b6a64f01c3833813b (diff)
downloadqpid-python-68845de60abe21ad102ed3e094a3674bd4b377a0.tar.gz
QPID-5841: allow SSL hostname verification failure to be ignored (with NSS)
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1605127 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionSettings.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionSettings.h5
-rw-r--r--qpid/cpp/src/qpid/client/SslConnector.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp2
-rw-r--r--qpid/cpp/src/qpid/messaging/ConnectionOptions.cpp2
-rw-r--r--qpid/cpp/src/qpid/messaging/amqp/SslTransport.cpp3
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp23
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.h4
8 files changed, 43 insertions, 2 deletions
diff --git a/qpid/cpp/src/qpid/client/ConnectionSettings.cpp b/qpid/cpp/src/qpid/client/ConnectionSettings.cpp
index 20804572a4..7d41b48abd 100644
--- a/qpid/cpp/src/qpid/client/ConnectionSettings.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionSettings.cpp
@@ -41,7 +41,8 @@ ConnectionSettings::ConnectionSettings() :
service(qpid::saslName),
minSsf(0),
maxSsf(256),
- sslCertName("")
+ sslCertName(""),
+ sslIgnoreHostnameVerificationFailure(false)
{}
ConnectionSettings::~ConnectionSettings() {}
diff --git a/qpid/cpp/src/qpid/client/ConnectionSettings.h b/qpid/cpp/src/qpid/client/ConnectionSettings.h
index a0c209badf..a4b2b59ff7 100644
--- a/qpid/cpp/src/qpid/client/ConnectionSettings.h
+++ b/qpid/cpp/src/qpid/client/ConnectionSettings.h
@@ -133,6 +133,11 @@ struct QPID_CLIENT_CLASS_EXTERN ConnectionSettings {
* Passed as client-propreties on opening the connecction.
*/
framing::FieldTable clientProperties;
+
+ /**
+ * If using SSL, connect regardless of hostname verification failure.
+ */
+ bool sslIgnoreHostnameVerificationFailure;
};
}} // namespace qpid::client
diff --git a/qpid/cpp/src/qpid/client/SslConnector.cpp b/qpid/cpp/src/qpid/client/SslConnector.cpp
index 9f8d31cfda..ffe751ab65 100644
--- a/qpid/cpp/src/qpid/client/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/SslConnector.cpp
@@ -183,6 +183,9 @@ SslConnector::SslConnector(Poller::shared_ptr p,
QPID_LOG(debug, "ssl-cert-name = " << settings.sslCertName);
socket.setCertName(settings.sslCertName);
}
+ if (settings.sslIgnoreHostnameVerificationFailure) {
+ socket.ignoreHostnameVerificationFailure();
+ }
}
SslConnector::~SslConnector() {
diff --git a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
index b229d23851..02a8a27a4e 100644
--- a/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp
@@ -155,6 +155,8 @@ void ConnectionImpl::setOption(const std::string& name, const Variant& value)
settings.protocol = value.asString();
} else if (name == "ssl-cert-name" || name == "ssl_cert_name") {
settings.sslCertName = value.asString();
+ } else if (name == "ssl-ignore-hostname-verification-failure" || name == "ssl_ignore_hostname_verification_failure") {
+ settings.sslIgnoreHostnameVerificationFailure = value;
} else if (name == "x-reconnect-on-limit-exceeded" || name == "x_reconnect_on_limit_exceeded") {
reconnectOnLimitExceeded = value;
} else if (name == "client-properties" || name == "client_properties") {
diff --git a/qpid/cpp/src/qpid/messaging/ConnectionOptions.cpp b/qpid/cpp/src/qpid/messaging/ConnectionOptions.cpp
index e5712288dd..10c131c22f 100644
--- a/qpid/cpp/src/qpid/messaging/ConnectionOptions.cpp
+++ b/qpid/cpp/src/qpid/messaging/ConnectionOptions.cpp
@@ -111,6 +111,8 @@ void ConnectionOptions::set(const std::string& name, const qpid::types::Variant&
protocol = value.asString();
} else if (name == "ssl-cert-name" || name == "ssl_cert_name") {
sslCertName = value.asString();
+ } else if (name == "ssl-ignore-hostname-verification-failure" || name == "ssl_ignore_hostname_verification_failure") {
+ sslIgnoreHostnameVerificationFailure = value;
} else if (name == "x-reconnect-on-limit-exceeded" || name == "x_reconnect_on_limit_exceeded") {
reconnectOnLimitExceeded = value;
} else if (name == "container-id" || name == "container_id") {
diff --git a/qpid/cpp/src/qpid/messaging/amqp/SslTransport.cpp b/qpid/cpp/src/qpid/messaging/amqp/SslTransport.cpp
index 953e989f5f..30ff636636 100644
--- a/qpid/cpp/src/qpid/messaging/amqp/SslTransport.cpp
+++ b/qpid/cpp/src/qpid/messaging/amqp/SslTransport.cpp
@@ -60,6 +60,9 @@ SslTransport::SslTransport(TransportContext& c, boost::shared_ptr<Poller> p) : c
QPID_LOG(debug, "ssl-cert-name = " << options->sslCertName);
socket.setCertName(options->sslCertName);
}
+ if (options->sslIgnoreHostnameVerificationFailure) {
+ socket.ignoreHostnameVerificationFailure();
+ }
}
void SslTransport::connect(const std::string& host, const std::string& port)
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
index a721918f57..32bc78d22d 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
@@ -45,6 +45,7 @@
#include <pk11pub.h>
#include <ssl.h>
#include <key.h>
+#include <sslerr.h>
#include <boost/format.hpp>
@@ -83,7 +84,7 @@ std::string getDomainFromSubject(std::string subject)
}
SslSocket::SslSocket(const std::string& certName, bool clientAuth) :
- nssSocket(0), certname(certName), prototype(0)
+ nssSocket(0), certname(certName), prototype(0), hostnameVerification(true)
{
//configure prototype socket:
prototype = SSL_ImportFD(0, PR_NewTCPSocket());
@@ -105,6 +106,11 @@ SslSocket::SslSocket(int fd, PRFileDesc* model) : BSDSocket(fd), nssSocket(0), p
NSS_CHECK(SSL_ResetHandshake(nssSocket, PR_TRUE));
}
+void SslSocket::ignoreHostnameVerificationFailure()
+{
+ hostnameVerification = false;
+}
+
void SslSocket::setNonblocking() const
{
if (!nssSocket) {
@@ -134,6 +140,18 @@ void SslSocket::connect(const SocketAddress& addr) const
BSDSocket::connect(addr);
}
+namespace {
+SECStatus bad_certificate(void* arg, PRFileDesc* /*fd*/) {
+ switch (PR_GetError()) {
+ case SSL_ERROR_BAD_CERT_DOMAIN:
+ QPID_LOG(info, "Ignoring hostname verification failure for " << (const char*) arg);
+ return SECSuccess;
+ default:
+ return SECFailure;
+ }
+}
+}
+
void SslSocket::finishConnect(const SocketAddress& addr) const
{
nssSocket = SSL_ImportFD(0, PR_ImportTCPSocket(fd));
@@ -150,6 +168,9 @@ void SslSocket::finishConnect(const SocketAddress& addr) const
NSS_CHECK(SSL_GetClientAuthDataHook(nssSocket, NSS_GetClientAuthData, arg));
url = addr.getHost();
+ if (!hostnameVerification) {
+ NSS_CHECK(SSL_BadCertHook(nssSocket, bad_certificate, const_cast<char*>(url.data())));
+ }
NSS_CHECK(SSL_SetURL(nssSocket, url.data()));
NSS_CHECK(SSL_ResetHandshake(nssSocket, PR_FALSE));
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
index fc97059cfd..2407a1bf4b 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
@@ -45,6 +45,9 @@ public:
*/
SslSocket(const std::string& certName = "", bool clientAuth = false);
+ /** Proceed with connect inspite of hostname verifcation failures*/
+ void ignoreHostnameVerificationFailure();
+
/** Set socket non blocking */
void setNonblocking() const;
@@ -92,6 +95,7 @@ protected:
* in accept to pass through to newly created socket instances.
*/
mutable PRFileDesc* prototype;
+ bool hostnameVerification;
SslSocket(int fd, PRFileDesc* model);
friend class SslMuxSocket; // Needed for this constructor