From 97b9af1519ad3809a7900f0ac1f5710a439c87c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 6 Sep 2019 13:51:37 +0200 Subject: Schannel: unbreak renegotiation (and likely gracious shutdown) The reason it wasn't working before was a couple of things: 1. Due to an extra 'else' it would not process the SEC_I_RENEGOTIATE or SEC_I_CONTEXT_EXPIRED branch. 2. The peerCertVerified boolean was not only wrong, but also broke renegotiation even if the 'else' wasn't there. My previous attempt to fix it ended up being a noop, so: Reverts e21fa577dde32849fdaa744f30ad3b23d63b7214 Change-Id: Ifbad55d4bb066b7566bb88cead48e329cbd574f9 Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_schannel.cpp | 19 ++++--------------- src/network/ssl/qsslsocket_schannel_p.h | 1 - 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index 88f66ac4ea..37705b03a1 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -1069,7 +1069,6 @@ bool QSslSocketBackendPrivate::verifyHandshake() } schannelState = SchannelState::Done; - peerCertVerified = true; return true; } @@ -1152,7 +1151,6 @@ void QSslSocketBackendPrivate::reset() connectionEncrypted = false; shutdown = false; - peerCertVerified = false; renegotiating = false; } @@ -1315,7 +1313,9 @@ void QSslSocketBackendPrivate::transmit() #endif intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer)); } - } else if (status == SEC_E_INCOMPLETE_MESSAGE) { + } + + if (status == SEC_E_INCOMPLETE_MESSAGE) { // Need more data before we can decrypt.. to the buffer it goes! #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!"); @@ -1361,17 +1361,6 @@ void QSslSocketBackendPrivate::transmit() schannelState = SchannelState::Renegotiate; renegotiating = true; - if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) { - // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel - // dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed, - // the rest need to be stored. -#ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:" - << dataBuffer[3].cbBuffer << "bytes"; -#endif - intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer)); - } - // We need to call 'continueHandshake' or else there's no guarantee it ever gets called continueHandshake(); break; @@ -1537,7 +1526,7 @@ void QSslSocketBackendPrivate::continueHandshake() case SchannelState::VerifyHandshake: // if we're in shutdown or renegotiating then we might not need to verify // (since we already did) - if (!peerCertVerified && !verifyHandshake()) { + if (!verifyHandshake()) { shutdown = true; // Skip sending shutdown alert q->abort(); // We don't want to send buffered data disconnectFromHost(); diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h index 9879e2fc60..6ab200e1f9 100644 --- a/src/network/ssl/qsslsocket_schannel_p.h +++ b/src/network/ssl/qsslsocket_schannel_p.h @@ -147,7 +147,6 @@ private: ULONG contextAttributes = 0; bool renegotiating = false; - bool peerCertVerified = false; }; QT_END_NAMESPACE -- cgit v1.2.3 From e5e8f1d67ce5f74ccb345086667933266543fd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 6 Sep 2019 13:01:43 +0200 Subject: Schannel: handle SEC_E_INCOMPLETE_DATA in acceptContext It's not a failure state, we just need more data. It is handled properly in other functions. Change-Id: I9450a78c71a3f4fe9506a7a79de6efa2db08697c Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_schannel.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index 37705b03a1..339ecf4da2 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -828,12 +828,17 @@ bool QSslSocketBackendPrivate::acceptContext() &expiry // ptsTimeStamp ); + if (status == SEC_E_INCOMPLETE_MESSAGE) { + // Need more data + return true; + } + if (inBuffers[1].BufferType == SECBUFFER_EXTRA) { // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel // inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to // be stored. intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer)); - } else if (status != SEC_E_INCOMPLETE_MESSAGE) { + } else { /* No 'extra' data, message not incomplete */ intermediateBuffer.clear(); } -- cgit v1.2.3 From 0fd6595d5e63fe1db429a0f242c7e98c6d2855f7 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 10 Sep 2019 09:39:59 +0200 Subject: Add a missing ConnectionTypeHttp2Direct in several if statements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while preparing SPDY retirement. Change-Id: I30f923fdeb0f6f0b5e808a3e7b7d81ddb9c4ef12 Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/access/qhttpnetworkconnection.cpp | 3 ++- src/network/access/qhttpnetworkconnectionchannel.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 9b1e63520d..294273d751 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1232,7 +1232,8 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info) emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError); networkLayerState = QHttpNetworkConnectionPrivate::Unknown; } else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY - || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2) { + || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 + || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) { // emit error for all replies QHttpNetworkReply *currentReply = spdyPair.second; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index d91fd8d2e6..8f94cef32b 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -1096,6 +1096,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket || !connection->d_func()->lowPriorityQueue.isEmpty()); if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 + || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct #ifndef QT_NO_SSL || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY #endif -- cgit v1.2.3 From 447ee95d5e050c5db1636c5d3bd0edbf59f26108 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 11 Sep 2019 09:25:51 +0200 Subject: QHttpThreadDelegate - remove unneeded code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found while cleaning up SPDY remains: I've noticed that for H2 case I never check if incomingSslConfiguration is nullptr or not, but the code several lines below - does it, which looks kind of moronic. This configuration is initialized when the delegate is created, so no need to have this if-statement. Instead, assert, making this behavior a requirement. Change-Id: I90fb84337be925a3288252aa2491b4c23d6c6cbb Reviewed-by: Mårten Nordheim --- src/network/access/qhttpthreaddelegate.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 3d1849010b..46a6615f4d 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -297,6 +297,11 @@ void QHttpThreadDelegate::startRequest() connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct; } +#if QT_CONFIG(ssl) + // See qnetworkreplyhttpimpl, delegate's initialization code. + Q_ASSERT(!ssl || incomingSslConfiguration.data()); +#endif // QT_CONFIG(ssl) + const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct(); if (isH2) { #if QT_CONFIG(ssl) @@ -316,9 +321,6 @@ void QHttpThreadDelegate::startRequest() } #ifndef QT_NO_SSL - if (ssl && !incomingSslConfiguration.data()) - incomingSslConfiguration.reset(new QSslConfiguration); - if (!isH2 && httpRequest.isSPDYAllowed() && ssl) { connectionType = QHttpNetworkConnection::ConnectionTypeSPDY; urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests -- cgit v1.2.3 From af1c3bf884c896e42fd2a8b7847ae86743b2c4ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 5 Sep 2019 12:22:13 +0200 Subject: qnetconmonitor_win: Mark destructors virtual After these two classes were no longer marked final clang started complaining because their dtor is not marked virtual. Amends 9dc594b2bf3572aa5df3ec3ad2b9842c96e8290d Change-Id: I42b78c0b444935d3e0cb4d476d3881fd5fb5c3cb Reviewed-by: Timur Pocheptsov Reviewed-by: Friedemann Kleint --- src/network/kernel/qnetconmonitor_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp index a010df8e3a..1566e7f914 100644 --- a/src/network/kernel/qnetconmonitor_win.cpp +++ b/src/network/kernel/qnetconmonitor_win.cpp @@ -103,7 +103,7 @@ class QNetworkConnectionEvents : public INetworkConnectionEvents { public: QNetworkConnectionEvents(QNetworkConnectionMonitorPrivate *monitor); - ~QNetworkConnectionEvents(); + virtual ~QNetworkConnectionEvents(); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; @@ -471,7 +471,7 @@ class QNetworkListManagerEvents : public INetworkListManagerEvents { public: QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor); - ~QNetworkListManagerEvents(); + virtual ~QNetworkListManagerEvents(); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; -- cgit v1.2.3