Package: src:kio Version: 5.49.0-1 Severity: important Tags: patch Control: found -1 5.28.0-2 Hi, Until recently KDE kio had a custom TLS version fall-back mechanism which made it possible to downgrade a TLS connection to TLSv1.0 even if the server and client support a higher TLS version. This has been fixed upstream in [1], [2] and is also included in KDE Frameworks 5.52.0 [3]. Please consider backporting the patch from [2] or shipping a newer KDE Frameworks version, so this fix can be included in buster. Attached you also find a backported version of [2] for the version in stretch. Please consider also fixing this in stretch. [1] https://phabricator.kde.org/D16344 [2] https://cgit.kde.org/kio.git/commit/src/core/tcpslavebase.cpp? id=e11d4d18f66ad1c6927b058be84e11d46d9de55a [3] https://www.kde.org/announcements/kde-frameworks-5.52.0.php Thanks for your work on Debian!
backport https://cgit.kde.org/kio.git/commit/src/core/tcpslavebase.cpp?id=e11d4d18f66ad1c6927b058be84e11d46d9de55a
to stretch.
--- a/src/core/tcpslavebase.cpp
+++ b/src/core/tcpslavebase.cpp
@@ -335,111 +335,51 @@
}
}
- /*
- SSL handshake is attempted in the following order:
+ const int timeout = (connectTimeout() * 1000); // 20 sec timeout value
- 1.) KTcpSocket::SecureProtocols
- 2.) KTcpSocket::TlsV1_2
- 3.) KTcpSocket::TlsV1_1
- 4.) KTcpSocket::TlsV1_0
-
- Note that we indivially attempt connection with each TLS version
- because some sites don't support SSL negotiation. #275524
-
- The version used to successfully make encrypted connection with the
- remote server is cached within the process to make subsequent
- connection requests to the same server faster.
- */
-
- const int lastSslVerson = config()->readEntry("LastUsedSslVersion", static_cast<int>(KTcpSocket::SecureProtocols));
- KTcpSocket::SslVersion trySslVersion = static_cast<KTcpSocket::SslVersion>(lastSslVerson);
- KTcpSocket::SslVersions alreadyTriedSslVersions = trySslVersion;
+ disconnectFromHost(); //Reset some state, even if we are already disconnected
+ d->host = host;
- const int timeout = (connectTimeout() * 1000); // 20 sec timeout value
- while (true) {
- disconnectFromHost(); //Reset some state, even if we are already disconnected
- d->host = host;
-
- d->socket.connectToHost(host, port);
- /*const bool connectOk = */d->socket.waitForConnected(timeout > -1 ? timeout : -1);
-
- /*qDebug() << "Socket: state=" << d->socket.state()
- << ", error=" << d->socket.error()
- << ", connected?" << connectOk;*/
+ d->socket.connectToHost(host, port);
+ /*const bool connectOk = */d->socket.waitForConnected(timeout > -1 ? timeout : -1);
- if (d->socket.state() != KTcpSocket::ConnectedState) {
- if (errorString) {
- *errorString = host + QLatin1String(": ") + d->socket.errorString();
- }
- switch (d->socket.error()) {
- case KTcpSocket::UnsupportedSocketOperationError:
- return ERR_UNSUPPORTED_ACTION;
- case KTcpSocket::RemoteHostClosedError:
- return ERR_CONNECTION_BROKEN;
- case KTcpSocket::SocketTimeoutError:
- return ERR_SERVER_TIMEOUT;
- case KTcpSocket::HostNotFoundError:
- return ERR_UNKNOWN_HOST;
- default:
- return ERR_CANNOT_CONNECT;
- }
+ /*qDebug() << "Socket: state=" << d->socket.state()
+ << ", error=" << d->socket.error()
+ << ", connected?" << connectOk;*/
+
+ if (d->socket.state() != KTcpSocket::ConnectedState) {
+ if (errorString) {
+ *errorString = host + QLatin1String(": ") + d->socket.errorString();
}
+ switch (d->socket.error()) {
+ case KTcpSocket::UnsupportedSocketOperationError:
+ return ERR_UNSUPPORTED_ACTION;
+ case KTcpSocket::RemoteHostClosedError:
+ return ERR_CONNECTION_BROKEN;
+ case KTcpSocket::SocketTimeoutError:
+ return ERR_SERVER_TIMEOUT;
+ case KTcpSocket::HostNotFoundError:
+ return ERR_UNKNOWN_HOST;
+ default:
+ return ERR_CANNOT_CONNECT;
+ }
+ }
- //### check for proxyAuthenticationRequiredError
+ //### check for proxyAuthenticationRequiredError
- d->ip = d->socket.peerAddress().toString();
- d->port = d->socket.peerPort();
+ d->ip = d->socket.peerAddress().toString();
+ d->port = d->socket.peerPort();
- if (d->autoSSL) {
- SslResult res = d->startTLSInternal(trySslVersion, timeout);
- if ((res & ResultFailed) && (res & ResultFailedEarly)) {
- if (!(alreadyTriedSslVersions & KTcpSocket::SecureProtocols)) {
- trySslVersion = KTcpSocket::SecureProtocols;
- alreadyTriedSslVersions |= trySslVersion;
- continue;
- }
-
- if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_2)) {
- trySslVersion = KTcpSocket::TlsV1;
- alreadyTriedSslVersions |= trySslVersion;
- continue;
- }
-
- if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_1)) {
- trySslVersion = KTcpSocket::TlsV1;
- alreadyTriedSslVersions |= trySslVersion;
- continue;
- }
-
- if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_0)) {
- trySslVersion = KTcpSocket::TlsV1_0;
- alreadyTriedSslVersions |= trySslVersion;
- continue;
- }
- }
+ if (d->autoSSL) {
+ const SslResult res = d->startTLSInternal(KTcpSocket::SecureProtocols, timeout);
- //### SSL 2.0 is (close to) dead and it's a good thing, too.
- if (res & ResultFailed) {
- if (errorString) {
- *errorString = i18nc("%1 is a host name", "%1: SSL negotiation failed", host);
- }
- return ERR_CANNOT_CONNECT;
+ if (res & ResultFailed) {
+ if (errorString) {
+ *errorString = i18nc("%1 is a host name", "%1: SSL negotiation failed", host);
}
+ return ERR_CANNOT_CONNECT;
}
- // If the SSL handshake was done with anything protocol other than the default,
- // save that information so that any subsequent requests do not have to do thesame thing.
- if (trySslVersion != KTcpSocket::SecureProtocols && lastSslVerson == KTcpSocket::SecureProtocols) {
- setMetaData(QStringLiteral("{internal~currenthost}LastUsedSslVersion"),
- QString::number(trySslVersion));
- }
- return 0;
}
- Q_ASSERT(false);
- // Code flow never gets here but let's make the compiler happy.
- // More: the stack allocation of QSslSettings seems to be confusing the compiler;
- // in fact, any non-POD allocation does.
- // even a 'return 0;' directly after the allocation (so before the while(true))
- // is ignored. definitely seems to be a compiler bug? - aseigo
return 0;
}
Attachment:
signature.asc
Description: This is a digitally signed message part.