diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/socket/qnativesocketengine_unix.cpp | 33 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate.cpp | 6 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate.h | 6 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate_openssl.cpp | 13 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate_qt.cpp | 6 | ||||
-rw-r--r-- | src/network/ssl/qsslcontext_openssl.cpp | 17 | ||||
-rw-r--r-- | src/network/ssl/qsslerror.cpp | 13 | ||||
-rw-r--r-- | src/network/ssl/qsslerror.h | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_winrt.cpp | 10 |
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; |