Commit dbcedd5a authored by Fabian Vogt's avatar Fabian Vogt
Browse files

Handle pure SSL/TLS negotation in Session instead of LoginJob

Previously, LoginJob started the SSL negotiation and immediately sent the
CAPABILITY command once it completed, without waiting for the server greeting
first. Some servers don't like this any close the connection with
* BYE out-of-sync data before server greeting

Avoid this by starting the encryption in Session directly, which then starts
LoginJob after the server greeting arrived. Adjust LoginJob for this by
treating an already encrypted connection like a successful negotation, and
avoid handling the encryptionNegotiationResult signal before the job was
started.

BUG: 449184
parent 02d87190
Pipeline #132449 skipped
......@@ -129,7 +129,6 @@ LoginJob::LoginJob(Session *session)
: Job(*new LoginJobPrivate(this, session, i18n("Login")))
{
Q_D(LoginJob);
connect(d->sessionInternal(), SIGNAL(encryptionNegotiationResult(bool)), this, SLOT(sslResponse(bool)));
qCDebug(KIMAP_LOG) << this;
}
......@@ -187,18 +186,21 @@ void LoginJob::doStart()
return;
}
// Get notified once encryption is successfully negotiated
connect(d->sessionInternal(), SIGNAL(encryptionNegotiationResult(bool)), this, SLOT(sslResponse(bool)));
// Trigger encryption negotiation only if needed
EncryptionMode encryptionMode = d->encryptionMode;
const auto negotiatedEncryption = d->sessionInternal()->negotiatedEncryption();
if (negotiatedEncryption != QSsl::UnknownProtocol) {
// If the socket is already encrypted, pretend we did not want any
// encryption
encryptionMode = Unencrypted;
// If the socket is already encrypted, proceed to the next state
d->sslResponse(true);
return;
}
if (encryptionMode == SSLorTLS) {
d->sessionInternal()->startSsl(QSsl::SecureProtocols);
// Negotiation got started by Session, but didn't complete yet. Continue in sslResponse.
} else if (encryptionMode == STARTTLS) {
// Check if STARTTLS is supported
d->authState = LoginJobPrivate::PreStartTlsCapability;
......
......@@ -353,7 +353,7 @@ void SessionPrivate::socketConnected()
}
if (state == Session::Disconnected && willUseSsl) {
startNext();
startSsl(QSsl::SecureProtocols);
} else {
startSocketTimer();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment