summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-12-02 23:33:06 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-12-02 23:33:06 +0100
commit72f5867f144cec8fc7848cbcc772683fe845652d (patch)
tree7513af27b59332bf111f406d304977adc8c8612e /src/network
parent13777097118c496391d4b9656b95097ac25e4a40 (diff)
parentbf0af8b5a24de7e595929a64948a3548936aaaee (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/corelib/kernel/qcoreapplication.cpp src/corelib/kernel/qeventdispatcher_blackberry.cpp src/network/bearer/qnetworkconfiguration.cpp src/plugins/bearer/blackberry/qbbengine.cpp src/plugins/platforms/android/androidjnimain.cpp src/plugins/platforms/android/qandroidplatformtheme.cpp src/plugins/platforms/qnx/qqnxbpseventfilter.cpp src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp src/plugins/platforms/qnx/qqnxintegration.cpp src/plugins/platforms/qnx/qqnxnavigatorbps.cpp src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp src/plugins/platforms/qnx/qqnxwindow.cpp src/widgets/kernel/qwidgetwindow.cpp src/widgets/styles/qwindowsvistastyle.cpp src/widgets/styles/qwindowsxpstyle.cpp src/widgets/widgets/qtoolbararealayout.cpp tests/auto/corelib/global/qflags/qflags.pro tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp tests/auto/corelib/tools/qversionnumber/qversionnumber.pro tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp Change-Id: I37be88c6c185bb85404823353e027a0a6acdbce4
Diffstat (limited to 'src/network')
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp4
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp6
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp22
-rw-r--r--src/network/kernel/qdnslookup_android.cpp2
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp2
-rw-r--r--src/network/kernel/qdnslookup_win.cpp4
-rw-r--r--src/network/socket/qnativesocketengine.cpp36
-rw-r--r--src/network/socket/qnativesocketengine_p.h12
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp35
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp379
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h22
11 files changed, 385 insertions, 139 deletions
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index c07064fd94..b0e366d2f8 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -492,7 +492,7 @@ void QHttpThreadDelegate::finishedSlot()
if (httpReply->statusCode() >= 400) {
// it's an error reply
QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
- "Error downloading %1 - server replied: %2"));
+ "Error transferring %1 - server replied: %2"));
msg = msg.arg(httpRequest.url().toString(), httpReply->reasonPhrase());
emit error(statusCodeFromHttp(httpReply->statusCode(), httpRequest.url()), msg);
}
@@ -518,7 +518,7 @@ void QHttpThreadDelegate::synchronousFinishedSlot()
if (httpReply->statusCode() >= 400) {
// it's an error reply
QString msg = QLatin1String(QT_TRANSLATE_NOOP("QNetworkReply",
- "Error downloading %1 - server replied: %2"));
+ "Error transferring %1 - server replied: %2"));
incomingErrorDetail = msg.arg(httpRequest.url().toString(), httpReply->reasonPhrase());
incomingErrorCode = statusCodeFromHttp(httpReply->statusCode(), httpRequest.url());
}
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 12ecad5ff7..681c88e87b 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -127,8 +127,10 @@ void QNetworkReplyImplPrivate::_q_startOperation()
return;
} else {
#ifndef QT_NO_BEARERMANAGEMENT
- QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
- q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
+ if (session) {
+ QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
+ q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)), Qt::QueuedConnection);
+ }
#endif
}
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index 7d2c0dfef2..5f9697ab92 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -452,7 +452,7 @@ bool QSpdyProtocolHandler::uncompressHeader(const QByteArray &input, QByteArray
break;
}
default: {
- qWarning() << Q_FUNC_INFO << "got unexpected zlib return value:" << zlibRet;
+ qWarning() << "got unexpected zlib return value:" << zlibRet;
return false;
}
}
@@ -688,7 +688,7 @@ bool QSpdyProtocolHandler::uploadData(qint32 streamID)
Q_ASSERT(replyPrivate);
if (reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYHalfClosed || reply->d_func()->state == QHttpNetworkReplyPrivate::SPDYClosed) {
- qWarning() << Q_FUNC_INFO << "Trying to upload to closed stream";
+ qWarning("Trying to upload to closed stream");
return false;
}
@@ -843,7 +843,7 @@ void QSpdyProtocolHandler::handleControlFrame(const QByteArray &frameHeaders) //
break;
}
default:
- qWarning() << Q_FUNC_INFO << "cannot handle frame of type" << type;
+ qWarning() << "cannot handle frame of type" << type;
}
}
@@ -887,13 +887,13 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
QByteArray uncompressedHeader;
if (!uncompressHeader(headerValuePairs, &uncompressedHeader)) {
- qWarning() << Q_FUNC_INFO << "error reading header from SYN_REPLY message";
+ qWarning("error reading header from SYN_REPLY message");
return;
}
qint32 headerCount = fourBytesToInt(uncompressedHeader.constData());
if (headerCount * 8 > uncompressedHeader.size()) {
- qWarning() << Q_FUNC_INFO << "error parsing header from SYN_REPLY message";
+ qWarning("error parsing header from SYN_REPLY message");
sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
return;
}
@@ -904,7 +904,7 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
QByteArray name = uncompressedHeader.mid(readPointer, count);
readPointer += count;
if (readPointer > uncompressedHeader.size()) {
- qWarning() << Q_FUNC_INFO << "error parsing header from SYN_REPLY message";
+ qWarning("error parsing header from SYN_REPLY message");
sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
return;
}
@@ -913,7 +913,7 @@ void QSpdyProtocolHandler::parseHttpHeaders(char flags, const QByteArray &frameD
QByteArray value = uncompressedHeader.mid(readPointer, count);
readPointer += count;
if (readPointer > uncompressedHeader.size()) {
- qWarning() << Q_FUNC_INFO << "error parsing header from SYN_REPLY message";
+ qWarning("error parsing header from SYN_REPLY message");
sendRST_STREAM(streamID, RST_STREAM_PROTOCOL_ERROR);
return;
}
@@ -1014,7 +1014,7 @@ void QSpdyProtocolHandler::handleRST_STREAM(char /*flags*/, quint32 length,
errorMessage = "server cannot process the frame because it is too large";
break;
default:
- qWarning() << Q_FUNC_INFO << "could not understand servers RST_STREAM status code";
+ qWarning("could not understand servers RST_STREAM status code");
errorCode = QNetworkReply::ProtocolFailure;
errorMessage = "got SPDY RST_STREAM message with unknown error code";
}
@@ -1078,7 +1078,7 @@ void QSpdyProtocolHandler::handleSETTINGS(char flags, quint32 /*length*/, const
break;
}
default:
- qWarning() << Q_FUNC_INFO << "found unknown settings value" << value;
+ qWarning() << "found unknown settings value" << value;
}
}
}
@@ -1117,7 +1117,7 @@ void QSpdyProtocolHandler::handleGOAWAY(char /*flags*/, quint32 /*length*/,
break;
}
default:
- qWarning() << Q_FUNC_INFO << "unexpected status code" << statusCode;
+ qWarning() << "unexpected status code" << statusCode;
errorCode = QNetworkReply::ProtocolUnknownError;
}
@@ -1252,7 +1252,7 @@ void QSpdyProtocolHandler::handleDataFrame(const QByteArray &frameHeaders)
}
if (flag_compress) {
- qWarning() << Q_FUNC_INFO << "SPDY level compression is not supported";
+ qWarning("SPDY level compression is not supported");
}
if (flag_fin) {
diff --git a/src/network/kernel/qdnslookup_android.cpp b/src/network/kernel/qdnslookup_android.cpp
index b03c63c320..978da57609 100644
--- a/src/network/kernel/qdnslookup_android.cpp
+++ b/src/network/kernel/qdnslookup_android.cpp
@@ -41,7 +41,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
Q_UNUSED(requestName);
Q_UNUSED(nameserver);
Q_UNUSED(reply);
- qWarning() << Q_FUNC_INFO << "Not yet supported on Android";
+ qWarning("Not yet supported on Android");
reply->error = QDnsLookup::ResolverError;
reply->errorString = tr("Not yet supported on Android");
return;
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index fa782dadf7..a5e97c4a93 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -166,7 +166,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
ns->sin6_addr.s6_addr[i] = ipv6Address[i];
}
#else
- qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported";
+ qWarning("IPv6 addresses for nameservers is currently not supported");
reply->error = QDnsLookup::ResolverError;
reply->errorString = tr("IPv6 addresses for nameservers is currently not supported");
return;
diff --git a/src/network/kernel/qdnslookup_win.cpp b/src/network/kernel/qdnslookup_win.cpp
index 056a9c7a62..4a6c631983 100644
--- a/src/network/kernel/qdnslookup_win.cpp
+++ b/src/network/kernel/qdnslookup_win.cpp
@@ -60,9 +60,9 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
// For supoprting IPv6 nameserver addresses, we'll need to switch
// from DnsQuey() to DnsQueryEx() as it supports passing an IPv6
// address in the nameserver list
- qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported";
+ qWarning("IPv6 addresses for nameservers are currently not supported");
reply->error = QDnsLookup::ResolverError;
- reply->errorString = tr("IPv6 addresses for nameservers is currently not supported");
+ reply->errorString = tr("IPv6 addresses for nameservers are currently not supported");
return;
}
}
diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp
index c11b889220..e86d3ad76e 100644
--- a/src/network/socket/qnativesocketengine.cpp
+++ b/src/network/socket/qnativesocketengine.cpp
@@ -672,6 +672,24 @@ int QNativeSocketEngine::accept()
return d->nativeAccept();
}
+/*!
+ Returns the number of bytes that are currently available for
+ reading. On error, -1 is returned.
+
+ For UDP sockets, this function returns the accumulated size of all
+ pending datagrams, and it is therefore more useful for UDP sockets
+ to call hasPendingDatagrams() and pendingDatagramSize().
+*/
+qint64 QNativeSocketEngine::bytesAvailable() const
+{
+ Q_D(const QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bytesAvailable(), -1);
+ Q_CHECK_NOT_STATE(QNativeSocketEngine::bytesAvailable(), QAbstractSocket::UnconnectedState, -1);
+
+ return d->nativeBytesAvailable();
+}
+
+#ifndef QT_NO_UDPSOCKET
#ifndef QT_NO_NETWORKINTERFACE
/*!
@@ -734,23 +752,6 @@ bool QNativeSocketEngine::setMulticastInterface(const QNetworkInterface &iface)
#endif // QT_NO_NETWORKINTERFACE
/*!
- Returns the number of bytes that are currently available for
- reading. On error, -1 is returned.
-
- For UDP sockets, this function returns the accumulated size of all
- pending datagrams, and it is therefore more useful for UDP sockets
- to call hasPendingDatagrams() and pendingDatagramSize().
-*/
-qint64 QNativeSocketEngine::bytesAvailable() const
-{
- Q_D(const QNativeSocketEngine);
- Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bytesAvailable(), -1);
- Q_CHECK_NOT_STATE(QNativeSocketEngine::bytesAvailable(), QAbstractSocket::UnconnectedState, -1);
-
- return d->nativeBytesAvailable();
-}
-
-/*!
Returns \c true if there is at least one datagram pending. This
function is only called by UDP sockets, where a datagram can have
a size of 0. TCP sockets call bytesAvailable().
@@ -834,6 +835,7 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size, const Q
return d->nativeSendDatagram(data, size, header);
}
+#endif // QT_NO_UDPSOCKET
/*!
Writes a block of \a size bytes from \a data to the socket.
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index 5cc5e529fc..39e4d5e457 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -125,6 +125,12 @@ public:
int accept() Q_DECL_OVERRIDE;
void close() Q_DECL_OVERRIDE;
+ qint64 bytesAvailable() const Q_DECL_OVERRIDE;
+
+ qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
+ qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
+
+#ifndef QT_NO_UDPSOCKET
#ifndef QT_NO_NETWORKINTERFACE
bool joinMulticastGroup(const QHostAddress &groupAddress,
const QNetworkInterface &iface) Q_DECL_OVERRIDE;
@@ -134,16 +140,12 @@ public:
bool setMulticastInterface(const QNetworkInterface &iface) Q_DECL_OVERRIDE;
#endif
- qint64 bytesAvailable() const Q_DECL_OVERRIDE;
-
- qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
- qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
-
qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0,
PacketHeaderOptions = WantNone) Q_DECL_OVERRIDE;
qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
+#endif // QT_NO_UDPSOCKET
qint64 bytesToWrite() const Q_DECL_OVERRIDE;
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index e9fa227733..173221dec0 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -78,6 +78,21 @@ typedef IAsyncOperationWithProgress<IBuffer *, UINT32> IAsyncBufferOperation;
QT_BEGIN_NAMESPACE
+static QByteArray socketDescription(const QAbstractSocketEngine *s)
+{
+ QByteArray result;
+ if (const QObject *o = s->parent()) {
+ const QString name = o->objectName();
+ if (!name.isEmpty()) {
+ result += '"';
+ result += name.toLocal8Bit();
+ result += "\"/";
+ }
+ result += o->metaObject()->className();
+ }
+ return result;
+}
+
// Common constructs
#define Q_CHECK_VALID_SOCKETLAYER(function, returnValue) do { \
if (!isValid()) { \
@@ -275,8 +290,9 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
else if (d->socketType == QAbstractSocket::UdpSocket)
hr = d->udpSocket()->ConnectAsync(remoteHost.Get(), portReference.Get(), &d->connectOp);
if (hr == E_ACCESSDENIED) {
- qErrnoWarning(hr, "QNativeSocketEngine::connectToHostByName: Unable to connect to host. \
- Please check your manifest capabilities.");
+ qErrnoWarning(hr, "QNativeSocketEngine::connectToHostByName: Unable to connect to host (%s:%hu/%s). "
+ "Please check your manifest capabilities.",
+ qPrintable(name), port, socketDescription(this).constData());
return false;
}
Q_ASSERT_SUCCEEDED(hr);
@@ -328,7 +344,8 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op);
}
if (hr == E_ACCESSDENIED) {
- qErrnoWarning(hr, "Unable to bind socket. Please check your manifest capabilities.");
+ qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.",
+ qPrintable(address.toString()), port, socketDescription(this).constData());
return false;
}
Q_ASSERT_SUCCEEDED(hr);
@@ -381,12 +398,14 @@ int QNativeSocketEngine::accept()
ComPtr<IAsyncBufferOperation> op;
hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op);
if (FAILED(hr)) {
- qErrnoWarning(hr, "Faild to read from the socket buffer.");
+ qErrnoWarning(hr, "accept(): Failed to read from the socket buffer (%s).",
+ socketDescription(this).constData());
return -1;
}
hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get());
if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to set socket read callback.");
+ qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).",
+ socketDescription(this).constData());
return -1;
}
d->currentConnections.append(socket);
@@ -1272,12 +1291,14 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async
ComPtr<IAsyncBufferOperation> op;
hr = stream->ReadAsync(buffer.Get(), bufferLength, InputStreamOptions_Partial, &op);
if (FAILED(hr)) {
- qErrnoWarning(hr, "Could not read into socket stream buffer.");
+ qErrnoWarning(hr, "handleReadyRead(): Could not read into socket stream buffer (%s).",
+ socketDescription(q).constData());
return S_OK;
}
hr = op->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get());
if (FAILED(hr)) {
- qErrnoWarning(hr, "Failed to set socket read callback.");
+ qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).",
+ socketDescription(q).constData());
return S_OK;
}
return S_OK;
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 2af0264116..326686fad0 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -51,12 +51,291 @@
#include <algorithm>
#include <cstddef>
+#include <QtCore/private/qcore_mac_p.h>
+
#ifdef Q_OS_OSX
#include <CoreServices/CoreServices.h>
#endif
QT_BEGIN_NAMESPACE
+static SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode)
+{
+ const bool isServer = mode == QSslSocket::SslServerMode;
+ SSLContextRef context = Q_NULLPTR;
+
+#ifndef Q_OS_OSX
+ const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
+ // We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
+ context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ if (!context)
+ qCWarning(lcSsl) << "SSLCreateContext failed";
+#else // Q_OS_OSX
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ const SSLProtocolSide side = isServer ? kSSLServerSide : kSSLClientSide;
+ // We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
+ context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ if (!context)
+ qCWarning(lcSsl) << "SSLCreateContext failed";
+ } else {
+#else
+ {
+#endif
+ const OSStatus errCode = SSLNewContext(isServer, &context);
+ if (errCode != noErr || !context)
+ qCWarning(lcSsl) << "SSLNewContext failed with error:" << errCode;
+ }
+#endif // !Q_OS_OSX
+
+ return context;
+}
+
+static void qt_releaseSecureTransportContext(SSLContextRef context)
+{
+ if (!context)
+ return;
+
+#ifndef Q_OS_OSX
+ CFRelease(context);
+#else
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ CFRelease(context);
+ } else {
+#else
+ {
+#endif // QT_MAC_PLATFORM_...
+ const OSStatus errCode = SSLDisposeContext(context);
+ if (errCode != noErr)
+ qCWarning(lcSsl) << "SSLDisposeContext failed with error:" << errCode;
+ }
+#endif // !Q_OS_OSX
+}
+
+static bool qt_setSessionProtocol(SSLContextRef context, const QSslConfigurationPrivate &configuration,
+ QTcpSocket *plainSocket)
+{
+ Q_ASSERT(context);
+
+#ifndef QSSLSOCKET_DEBUG
+ Q_UNUSED(plainSocket)
+#endif
+
+ OSStatus err = noErr;
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_5_0)
+ if (configuration.protocol == QSsl::SslV3) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kSSLProtocol3);
+ } else if (configuration.protocol == QSsl::TlsV1_0) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol1);
+ } else if (configuration.protocol == QSsl::TlsV1_1) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol11);
+ } else if (configuration.protocol == QSsl::TlsV1_2) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else if (configuration.protocol == QSsl::AnyProtocol) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : any";
+ #endif
+ // kSSLProtocol3, since kSSLProtocol2 is disabled:
+ err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else if (configuration.protocol == QSsl::TlsV1SslV3) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else if (configuration.protocol == QSsl::SecureProtocols) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else if (configuration.protocol == QSsl::TlsV1_0OrLater) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else if (configuration.protocol == QSsl::TlsV1_1OrLater) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else if (configuration.protocol == QSsl::TlsV1_2OrLater) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
+ if (err == noErr)
+ err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+ } else {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "no protocol version found in the configuration";
+ #endif
+ return false;
+ }
+#endif
+
+ return err == noErr;
+}
+
+#ifdef Q_OS_OSX
+
+static bool qt_setSessionProtocolOSX(SSLContextRef context, const QSslConfigurationPrivate &configuration,
+ QTcpSocket *plainSocket)
+{
+ // This function works with (now) deprecated API that does not even exist on
+ // iOS but is the only API we have on OS X below 10.8
+
+ // Without SSLSetProtocolVersionMin/Max functions it's quite difficult
+ // to have the required result:
+ // If we use SSLSetProtocolVersion - any constant except the ones with 'Only' suffix -
+ // allows a negotiation and we can not set the lower limit.
+ // SSLSetProtocolVersionEnabled supports only a limited subset of constants, if you believe their docs:
+ // kSSLProtocol2
+ // kSSLProtocol3
+ // kTLSProtocol1
+ // kSSLProtocolAll
+ // Here we can only have a look into the SecureTransport's code and hope that what we see there
+ // and what we have on 10.7 is similar:
+ // SSLSetProtocoLVersionEnabled actually accepts other constants also,
+ // called twice with two different protocols it sets a range,
+ // called once with a protocol (when all protocols were disabled)
+ // - only this protocol is enabled (without a lower limit negotiation).
+
+ Q_ASSERT(context);
+
+#ifndef QSSLSOCKET_DEBUG
+ Q_UNUSED(plainSocket)
+#endif
+
+ OSStatus err = noErr;
+
+ // First, disable ALL:
+ if (SSLSetProtocolVersionEnabled(context, kSSLProtocolAll, false) != noErr)
+ return false;
+
+ if (configuration.protocol == QSsl::SslV3) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
+ #endif
+ err = SSLSetProtocolVersion(context, kSSLProtocol3Only);
+ } else if (configuration.protocol == QSsl::TlsV1_0) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0";
+ #endif
+ err = SSLSetProtocolVersion(context, kTLSProtocol1Only);
+ } else if (configuration.protocol == QSsl::TlsV1_1) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol11, true);
+ } else if (configuration.protocol == QSsl::TlsV1_2) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
+ } else if (configuration.protocol == QSsl::AnyProtocol) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : any";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kSSLProtocolAll, true);
+ } else if (configuration.protocol == QSsl::TlsV1SslV3) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
+ if (err == noErr)
+ err = SSLSetProtocolVersionEnabled(context, kSSLProtocol3, true);
+ } else if (configuration.protocol == QSsl::SecureProtocols) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
+ if (err == noErr)
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol1, true);
+ } else if (configuration.protocol == QSsl::TlsV1_0OrLater) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
+ if (err == noErr)
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol1, true);
+ } else if (configuration.protocol == QSsl::TlsV1_1OrLater) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1 - TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
+ if (err == noErr)
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol11, true);
+ } else if (configuration.protocol == QSsl::TlsV1_2OrLater) {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
+ #endif
+ err = SSLSetProtocolVersionEnabled(context, kTLSProtocol12, true);
+ } else {
+ #ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl) << plainSocket << "no protocol version found in the configuration";
+ #endif
+ return false;
+ }
+
+ return err == noErr;
+}
+
+#endif // Q_OS_OSX
+
+QSecureTransportContext::QSecureTransportContext(SSLContextRef c)
+ : context(c)
+{
+}
+
+QSecureTransportContext::~QSecureTransportContext()
+{
+ qt_releaseSecureTransportContext(context);
+}
+
+QSecureTransportContext::operator SSLContextRef()const
+{
+ return context;
+}
+
+void QSecureTransportContext::reset(SSLContextRef newContext)
+{
+ qt_releaseSecureTransportContext(context);
+ context = newContext;
+}
+
Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_securetransport_mutex, (QMutex::Recursive))
//#define QSSLSOCKET_DEBUG
@@ -144,7 +423,7 @@ void QSslSocketPrivate::ensureInitialized()
// from QSslCertificatePrivate's ctor.
s_loadedCiphersAndCerts = true;
- QCFType<SSLContextRef> context(SSLCreateContext(Q_NULLPTR, kSSLClientSide, kSSLStreamType));
+ const QSecureTransportContext context(qt_createSecureTransportContext(QSslSocket::SslClientMode));
if (context) {
QList<QSslCipher> ciphers;
QList<QSslCipher> defaultCiphers;
@@ -171,7 +450,6 @@ void QSslSocketPrivate::ensureInitialized()
if (!s_loadRootCertsOnDemand)
setDefaultCaCertificates(systemCaCertificates());
} else {
- qCWarning(lcSsl) << "SSLCreateContext failed";
s_loadedCiphersAndCerts = false;
}
@@ -640,11 +918,7 @@ bool QSslSocketBackendPrivate::initSslContext()
Q_ASSERT_X(!context, Q_FUNC_INFO, "invalid socket state, context is not null");
Q_ASSERT(plainSocket);
- SSLProtocolSide side = kSSLClientSide;
- if (mode == QSslSocket::SslServerMode)
- side = kSSLServerSide;
-
- context = SSLCreateContext(Q_NULLPTR, side, kSSLStreamType);
+ context.reset(qt_createSecureTransportContext(mode));
if (!context) {
setErrorAndEmit(QAbstractSocket::SslInternalError, "SSLCreateContext failed");
return false;
@@ -740,7 +1014,7 @@ bool QSslSocketBackendPrivate::initSslContext()
void QSslSocketBackendPrivate::destroySslContext()
{
- context = Q_NULLPTR;
+ context.reset(Q_NULLPTR);
}
static QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key, const QString &passPhrase);
@@ -837,8 +1111,6 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
{
Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)");
- OSStatus err = noErr;
-
// QSsl::SslV2 == kSSLProtocol2 is disabled in secure transport and
// always fails with errSSLIllegalParam:
// if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
@@ -849,85 +1121,20 @@ bool QSslSocketBackendPrivate::setSessionProtocol()
return false;
}
- if (configuration.protocol == QSsl::SslV3) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : SSLv3";
-#endif
- err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kSSLProtocol3);
- } else if (configuration.protocol == QSsl::TlsV1_0) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol1);
- } else if (configuration.protocol == QSsl::TlsV1_1) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol11);
- } else if (configuration.protocol == QSsl::TlsV1_2) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::AnyProtocol) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : any";
-#endif
- // kSSLProtocol3, since kSSLProtocol2 is disabled:
- err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::TlsV1SslV3) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2";
-#endif
- err = SSLSetProtocolVersionMin(context, kSSLProtocol3);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::SecureProtocols) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::TlsV1_0OrLater) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol1);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::TlsV1_1OrLater) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.1 - TLSv1.2";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol11);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
- } else if (configuration.protocol == QSsl::TlsV1_2OrLater) {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.2";
-#endif
- err = SSLSetProtocolVersionMin(context, kTLSProtocol12);
- if (err == noErr)
- err = SSLSetProtocolVersionMax(context, kTLSProtocol12);
+#ifndef Q_OS_OSX
+ return qt_setSessionProtocol(context, configuration, plainSocket);
+#else
+
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ return qt_setSessionProtocol(context, configuration, plainSocket);
} else {
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << plainSocket << "no protocol version found in the configuration";
+#else
+ {
#endif
- return false;
+ return qt_setSessionProtocolOSX(context, configuration, plainSocket);
}
-
- return err == noErr;
+#endif
}
bool QSslSocketBackendPrivate::canIgnoreTrustVerificationFailure() const
diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h
index 414c155882..7a622db185 100644
--- a/src/network/ssl/qsslsocket_mac_p.h
+++ b/src/network/ssl/qsslsocket_mac_p.h
@@ -45,8 +45,6 @@
// We mean it.
//
-#include <QtCore/private/qcore_mac_p.h>
-
#include <QtCore/qstring.h>
#include <QtCore/qglobal.h>
#include <QtCore/qlist.h>
@@ -59,6 +57,20 @@
QT_BEGIN_NAMESPACE
+class QSecureTransportContext
+{
+public:
+ explicit QSecureTransportContext(SSLContextRef context);
+ ~QSecureTransportContext();
+
+ operator SSLContextRef () const;
+ void reset(SSLContextRef newContext);
+private:
+ SSLContextRef context;
+
+ Q_DISABLE_COPY(QSecureTransportContext);
+};
+
class QSslSocketBackendPrivate : public QSslSocketPrivate
{
Q_DECLARE_PUBLIC(QSslSocket)
@@ -76,8 +88,8 @@ public:
void startServerEncryption() Q_DECL_OVERRIDE;
void transmit() Q_DECL_OVERRIDE;
- static QList<QSslError> (verify)(QList<QSslCertificate> certificateChain,
- const QString &hostName);
+ static QList<QSslError> verify(QList<QSslCertificate> certificateChain,
+ const QString &hostName);
static bool importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
@@ -101,7 +113,7 @@ private:
bool checkSslErrors();
bool startHandshake();
- mutable QCFType<SSLContextRef> context;
+ QSecureTransportContext context;
Q_DISABLE_COPY(QSslSocketBackendPrivate);
};