diff options
| author | Gordon Sim <gsim@apache.org> | 2014-06-24 16:15:34 +0000 |
|---|---|---|
| committer | Gordon Sim <gsim@apache.org> | 2014-06-24 16:15:34 +0000 |
| commit | 68845de60abe21ad102ed3e094a3674bd4b377a0 (patch) | |
| tree | 48cd42dcd24eef32868201a96fa3cb13af4388e2 /qpid/cpp/src | |
| parent | 1cb67f36e63353d19e4b397b6a64f01c3833813b (diff) | |
| download | qpid-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.cpp | 3 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/client/ConnectionSettings.h | 5 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/client/SslConnector.cpp | 3 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/client/amqp0_10/ConnectionImpl.cpp | 2 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/messaging/ConnectionOptions.cpp | 2 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/messaging/amqp/SslTransport.cpp | 3 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp | 23 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/sys/ssl/SslSocket.h | 4 |
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 |
