diff --git a/src/libsync/creds/httpcredentials.cpp b/src/libsync/creds/httpcredentials.cpp index ca2a1982a9..6d0899aeab 100644 --- a/src/libsync/creds/httpcredentials.cpp +++ b/src/libsync/creds/httpcredentials.cpp @@ -117,6 +117,7 @@ HttpCredentials::HttpCredentials(const QString &user, const QString &password, c , _clientSslKey(key) , _clientSslCertificate(certificate) , _keychainMigration(false) + , _retryOnKeyChainError(false) { } @@ -219,6 +220,21 @@ void HttpCredentials::deleteOldKeychainEntries() void HttpCredentials::slotReadClientCertPEMJobDone(QKeychain::Job *incoming) { +#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) + Q_ASSERT(!incoming->insecureFallback()); // If insecureFallback is set, the next test would be pointless + if (_retryOnKeyChainError && (incoming->error() == QKeychain::NoBackendAvailable + || incoming->error() == QKeychain::OtherError)) { + // Could be that the backend was not yet available. Wait some extra seconds. + // (Issues #4274 and #6522) + // (For kwallet, the error is OtherError instead of NoBackendAvailable, maybe a bug in QtKeychain) + qCInfo(lcHttpCredentials) << "Backend unavailable (yet?) Retrying in a few seconds." << incoming->errorString(); + QTimer::singleShot(10000, this, &HttpCredentials::fetchFromKeychainHelper); + _retryOnKeyChainError = false; + return; + } + _retryOnKeyChainError = false; +#endif + // Store PEM in memory ReadPasswordJob *readJob = static_cast(incoming); if (readJob->error() == NoError && readJob->binaryData().length() > 0) { diff --git a/src/libsync/creds/httpcredentials.h b/src/libsync/creds/httpcredentials.h index 4ed8c114be..b71edf6ca8 100644 --- a/src/libsync/creds/httpcredentials.h +++ b/src/libsync/creds/httpcredentials.h @@ -141,6 +141,7 @@ protected: QSslKey _clientSslKey; QSslCertificate _clientSslCertificate; bool _keychainMigration; + bool _retryOnKeyChainError = true; // true if we haven't done yet any reading from keychain };