summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-20 19:12:23 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-20 19:12:25 +0200
commit3361fcbc28be96262d22fd2b024c85fbcbc61462 (patch)
tree48976f337b3885971dc1976b9a27cec5e7dfa2ec /src/network
parentdc612acdc6577594c8f61345cea2de549d7aae34 (diff)
parent5e342f6f041208d142d97202f61179d7163eb773 (diff)
Merge remote-tracking branch 'origin/5.4' into dev
Diffstat (limited to 'src/network')
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp33
-rw-r--r--src/network/ssl/qsslcertificate.cpp6
-rw-r--r--src/network/ssl/qsslcertificate.h6
-rw-r--r--src/network/ssl/qsslcertificate_openssl.cpp13
-rw-r--r--src/network/ssl/qsslcertificate_qt.cpp6
-rw-r--r--src/network/ssl/qsslcontext_openssl.cpp17
-rw-r--r--src/network/ssl/qsslerror.cpp13
-rw-r--r--src/network/ssl/qsslerror.h2
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp10
9 files changed, 80 insertions, 26 deletions
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 60f971a2fb..ad170e187c 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -384,12 +384,15 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16
sockAddrIPv6.sin6_port = htons(port);
QString scopeid = addr.scopeId();
- bool ok;
- sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
+
+ if (!scopeid.isEmpty()) {
+ bool ok;
+ sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
#ifndef QT_NO_IPV6IFNAME
- if (!ok)
- sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
+ if (!ok)
+ sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
#endif
+ }
Q_IPV6ADDR ip6 = addr.toIPv6Address();
memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6));
@@ -498,11 +501,16 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16
memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6));
sockAddrIPv6.sin6_family = AF_INET6;
sockAddrIPv6.sin6_port = htons(port);
+ QString scopeid = address.scopeId();
+
+ if (!scopeid.isEmpty()) {
+ bool ok;
+ sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
#ifndef QT_NO_IPV6IFNAME
- sockAddrIPv6.sin6_scope_id = ::if_nametoindex(address.scopeId().toLatin1().data());
-#else
- sockAddrIPv6.sin6_scope_id = address.scopeId().toInt();
+ if (!ok)
+ sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
#endif
+ }
Q_IPV6ADDR tmp = address.toIPv6Address();
memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));
sockAddrSize = sizeof(sockAddrIPv6);
@@ -917,12 +925,15 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
Q_IPV6ADDR tmp = host.toIPv6Address();
memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp));
QString scopeid = host.scopeId();
- bool ok;
- sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
+
+ if (!scopeid.isEmpty()) {
+ bool ok;
+ sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok);
#ifndef QT_NO_IPV6IFNAME
- if (!ok)
- sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
+ if (!ok)
+ sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1());
#endif
+ }
sockAddrSize = sizeof(sockAddrIPv6);
sockAddrPtr = (struct sockaddr *)&sockAddrIPv6;
} else if (host.protocol() == QAbstractSocket::IPv4Protocol) {
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 8d38a5fd54..13bddcb3ea 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -662,7 +662,13 @@ QByteArray QSslCertificatePrivate::subjectInfoToString(QSslCertificate::SubjectI
return str;
}
+/*!
+ \fn uint qHash(const QSslCertificate &key, uint seed)
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+ \since 5.4
+ \relates QHash
+*/
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QSslCertificate &certificate)
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index d1290b1d42..e34ea97fc4 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -59,6 +59,10 @@ class QSslKey;
class QSslCertificateExtension;
class QStringList;
+class QSslCertificate;
+// qHash is a friend, but we can't use default arguments for friends (ยง8.3.6.4)
+Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed = 0) Q_DECL_NOTHROW;
+
class QSslCertificatePrivate;
class Q_NETWORK_EXPORT QSslCertificate
{
@@ -145,6 +149,8 @@ private:
QExplicitlySharedDataPointer<QSslCertificatePrivate> d;
friend class QSslCertificatePrivate;
friend class QSslSocketBackendPrivate;
+
+ friend Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW;
};
Q_DECLARE_SHARED(QSslCertificate)
diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp
index 664f5eba08..1906c72ff8 100644
--- a/src/network/ssl/qsslcertificate_openssl.cpp
+++ b/src/network/ssl/qsslcertificate_openssl.cpp
@@ -62,6 +62,17 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const
return false;
}
+uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW
+{
+ if (X509 * const x509 = key.d->x509) {
+ (void)q_X509_cmp(x509, x509); // populate x509->sha1_hash
+ // (if someone knows a better way...)
+ return qHashBits(x509->sha1_hash, SHA_DIGEST_LENGTH, seed);
+ } else {
+ return seed;
+ }
+}
+
bool QSslCertificate::isNull() const
{
return d->null;
@@ -683,7 +694,7 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr
#endif
int size = der.size();
- while (count == -1 || certificates.size() < count) {
+ while (size > 0 && (count == -1 || certificates.size() < count)) {
if (X509 *x509 = q_d2i_X509(0, &data, size)) {
certificates << QSslCertificate_from_X509(x509);
q_X509_free(x509);
diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp
index 16df4a8f73..d74042a95f 100644
--- a/src/network/ssl/qsslcertificate_qt.cpp
+++ b/src/network/ssl/qsslcertificate_qt.cpp
@@ -67,6 +67,12 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const
return d->derData == other.d->derData;
}
+uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW
+{
+ // DER is the native encoding here, so toDer() is just "return d->derData":
+ return qHash(key.toDer(), seed);
+}
+
bool QSslCertificate::isNull() const
{
return d->null;
diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp
index 26be1d56e6..f4c6b21598 100644
--- a/src/network/ssl/qsslcontext_openssl.cpp
+++ b/src/network/ssl/qsslcontext_openssl.cpp
@@ -124,13 +124,16 @@ QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSsl
bool client = (mode == QSslSocket::SslClientMode);
bool reinitialized = false;
+ bool unsupportedProtocol = false;
init_context:
switch (sslContext->sslConfiguration.protocol()) {
case QSsl::SslV2:
#ifndef OPENSSL_NO_SSL2
sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
#else
- sslContext->ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error
+ // SSL 2 not supported by the system, but chosen deliberately -> error
+ sslContext->ctx = 0;
+ unsupportedProtocol = true;
#endif
break;
case QSsl::SslV3:
@@ -149,14 +152,18 @@ init_context:
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
#else
- sslContext->ctx = 0; // TLS 1.1 not supported by the system, but chosen deliberately -> error
+ // TLS 1.1 not supported by the system, but chosen deliberately -> error
+ sslContext->ctx = 0;
+ unsupportedProtocol = true;
#endif
break;
case QSsl::TlsV1_2:
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
#else
- sslContext->ctx = 0; // TLS 1.2 not supported by the system, but chosen deliberately -> error
+ // TLS 1.2 not supported by the system, but chosen deliberately -> error
+ sslContext->ctx = 0;
+ unsupportedProtocol = true;
#endif
break;
}
@@ -169,7 +176,9 @@ init_context:
goto init_context;
}
- sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
+ sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
+ unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
+ );
sslContext->errorCode = QSslError::UnspecifiedError;
return sslContext;
}
diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp
index ff30098347..5004e561a8 100644
--- a/src/network/ssl/qsslerror.cpp
+++ b/src/network/ssl/qsslerror.cpp
@@ -305,6 +305,19 @@ QSslCertificate QSslError::certificate() const
return d->certificate;
}
+/*!
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+ \since 5.4
+ \relates QHash
+*/
+uint qHash(const QSslError &key, uint seed) Q_DECL_NOTHROW
+{
+ // 2x boost::hash_combine inlined:
+ seed ^= qHash(key.error()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ seed ^= qHash(key.certificate()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ return seed;
+}
+
#ifndef QT_NO_DEBUG_STREAM
//class QDebug;
QDebug operator<<(QDebug debug, const QSslError &error)
diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h
index d25546b68b..c00532e294 100644
--- a/src/network/ssl/qsslerror.h
+++ b/src/network/ssl/qsslerror.h
@@ -102,6 +102,8 @@ private:
};
Q_DECLARE_SHARED(QSslError)
+Q_NETWORK_EXPORT uint qHash(const QSslError &key, uint seed = 0) Q_DECL_NOTHROW;
+
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError &error);
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index c9ddd9ec1b..da4c72be01 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -65,16 +65,6 @@ using namespace ABI::Windows::Storage::Streams;
QT_BEGIN_NAMESPACE
-// For QSet<QSslError>
-inline uint qHash(const QSslError &error, uint seed)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(error)))
-{ return (qHash(error.error()) ^ seed); }
-
-// For QSet<QSslCertificate>
-inline uint qHash(const QSslCertificate &certificate, uint seed)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(certificate)))
-{ return (qHash(certificate.handle()) ^ seed); }
-
bool QSslSocketPrivate::s_libraryLoaded = true;
bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;