17#include <QCoreApplication>
19#include <QDomDocument>
24#include <QMutexLocker>
26#include <QRandomGenerator>
27#include <QRegularExpression>
29#include <QSqlDatabase>
40#include <QSslConfiguration>
53#include "moc_qgsauthmanager.cpp"
64const QString QgsAuthManager::AUTH_CONFIG_TABLE = QStringLiteral(
"auth_configs" );
65const QString QgsAuthManager::AUTH_SERVERS_TABLE = QStringLiteral(
"auth_servers" );
67const QString QgsAuthManager::AUTH_CFG_REGEX = QStringLiteral(
"authcfg=([a-z]|[A-Z]|[0-9]){7}" );
70const QLatin1String QgsAuthManager::AUTH_PASSWORD_HELPER_KEY_NAME_BASE(
"QGIS-Master-Password" );
71const QLatin1String QgsAuthManager::AUTH_PASSWORD_HELPER_FOLDER_NAME(
"QGIS" );
79#elif defined(Q_OS_WIN)
81#elif defined(Q_OS_LINUX)
91 QMutexLocker locker( &sMutex );
102 mMutex = std::make_unique<QRecursiveMutex>();
103 mMasterPasswordMutex = std::make_unique<QRecursiveMutex>();
105 this, &QgsAuthManager::writeToConsole );
119 QMutexLocker locker( mMutex.get() );
124 return storage->authDatabaseConnection();
138 const QList<QgsAuthConfigurationStorage *> storages { storageRegistry->
readyStorages() };
141 if (
auto dbStorage = qobject_cast<QgsAuthConfigurationStorageDb *>( storage ) )
145 return dbStorage->quotedQualifiedIdentifier( dbStorage->methodConfigTableName() );
158 const auto drivers { QSqlDatabase::drivers() };
159 for (
const QString &driver : std::as_const( drivers ) )
161 if ( driver != ( QStringLiteral(
"QSQLITE" ) ) && driver != ( QStringLiteral(
"QSPATIALITE" ) ) && uri.startsWith( driver ) )
171 return mAuthDatabaseConnectionUri;
176 QRegularExpression re( QStringLiteral(
"password=(.*)" ) );
177 QString uri = mAuthDatabaseConnectionUri;
178 return uri.replace( re, QStringLiteral(
"password=*****" ) );
184 mAuthDatabaseConnectionUri = authDatabasePath.startsWith( QLatin1String(
"QSQLITE://" ) ) ? authDatabasePath : QStringLiteral(
"QSQLITE://" ) + authDatabasePath;
185 return initPrivate( pluginPath );
190 static QRecursiveMutex sInitializationMutex;
191 static bool sInitialized =
false;
193 sInitializationMutex.lock();
196 sInitializationMutex.unlock();
197 return mLazyInitResult;
200 mLazyInitResult =
const_cast< QgsAuthManager *
>( this )->initPrivate( mPluginPath );
202 sInitializationMutex.unlock();
204 return mLazyInitResult;
207static char *sPassFileEnv =
nullptr;
209bool QgsAuthManager::initPrivate(
const QString &pluginPath )
218 mQcaInitializer = std::make_unique<QCA::Initializer>( QCA::Practical, 256 );
221 QCA::scanForPlugins();
223 QgsDebugMsgLevel( QStringLiteral(
"QCA Plugin Diagnostics Context: %1" ).arg( QCA::pluginDiagnosticText() ), 2 );
224 QStringList capabilities;
226 capabilities = QCA::supportedFeatures();
227 QgsDebugMsgLevel( QStringLiteral(
"QCA supports: %1" ).arg( capabilities.join(
"," ) ), 2 );
230 if ( !QCA::isSupported(
"cert", QStringLiteral(
"qca-ossl" ) ) )
232 mAuthDisabled =
true;
233 mAuthDisabledMessage = tr(
"QCA's OpenSSL plugin (qca-ossl) is missing" );
237 QgsDebugMsgLevel( QStringLiteral(
"Prioritizing qca-ossl over all other QCA providers..." ), 2 );
238 const QCA::ProviderList provds = QCA::providers();
240 for ( QCA::Provider *p : provds )
242 QString pn = p->name();
244 if ( pn != QLatin1String(
"qca-ossl" ) )
246 pr = QCA::providerPriority( pn ) + 1;
248 QCA::setProviderPriority( pn, pr );
249 prlist << QStringLiteral(
"%1:%2" ).arg( pn ).arg( QCA::providerPriority( pn ) );
251 QgsDebugMsgLevel( QStringLiteral(
"QCA provider priorities: %1" ).arg( prlist.join(
", " ) ), 2 );
258 QgsDebugMsgLevel( QStringLiteral(
"Authentication methods found: %1" ).arg( methods.join(
", " ) ), 2 );
260 if ( methods.isEmpty() )
262 mAuthDisabled =
true;
263 mAuthDisabledMessage = tr(
"No authentication method plugins found" );
269 mAuthDisabled =
true;
270 mAuthDisabledMessage = tr(
"No authentication method plugins could be loaded" );
274 QgsDebugMsgLevel( QStringLiteral(
"Auth database URI: %1" ).arg( mAuthDatabaseConnectionUri ), 2 );
278 if ( ! sqliteDbPath.isEmpty() )
282 else if ( ! mAuthDatabaseConnectionUri.isEmpty() )
286 QgsAuthConfigurationStorageDb *storage =
new QgsAuthConfigurationStorageDb( mAuthDatabaseConnectionUri );
296 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
305 const QString err = tr(
"Failed to initialize storage %1: %2" ).arg( storage->
name(), storage->
lastError() );
325 QString passpath( sPassFileEnv );
326 free( sPassFileEnv );
327 sPassFileEnv =
nullptr;
330 QFile passfile( passpath );
331 if ( passfile.exists() && passfile.open( QIODevice::ReadOnly | QIODevice::Text ) )
333 QTextStream passin( &passfile );
334 while ( !passin.atEnd() )
336 masterpass = passin.readLine();
341 if ( !masterpass.isEmpty() )
345 QgsDebugMsgLevel( QStringLiteral(
"Authentication master password set from QGIS_AUTH_PASSWORD_FILE" ), 2 );
349 QgsDebugError(
"QGIS_AUTH_PASSWORD_FILE set, but FAILED to set password using: " + passpath );
355 QgsDebugError(
"QGIS_AUTH_PASSWORD_FILE set, but FAILED to read password from: " + passpath );
369 mPluginPath = pluginPath;
370 mAuthDatabaseConnectionUri = authDatabasePath;
372 const char *p = getenv(
"QGIS_AUTH_PASSWORD_FILE" );
375 sPassFileEnv = qstrdup( p );
380 putenv(
"QGIS_AUTH_PASSWORD_FILE" );
382 unsetenv(
"QGIS_AUTH_PASSWORD_FILE" );
387QString QgsAuthManager::generatePassword()
389 QRandomGenerator generator = QRandomGenerator::securelySeeded();
392 static const QString sPwChars = QStringLiteral(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-{}[]" );
393 for (
int i = 0; i < pw.size(); ++i )
395 pw[i] = sPwChars.at( generator.bounded( 0, sPwChars.length() ) );
406 QgsDebugError( QStringLiteral(
"Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing" ) );
408 return mAuthDisabled;
415 return tr(
"Authentication system is DISABLED:\n%1" ).arg( mAuthDisabledMessage );
420 QMutexLocker locker( mMasterPasswordMutex.get() );
424 if ( mScheduledDbErase )
430 if ( !mMasterPass.isEmpty() )
432 QgsDebugError( QStringLiteral(
"Master password is already set!" ) );
436 const QString newPassword = generatePassword();
437 if ( passwordHelperWrite( newPassword ) )
439 mMasterPass = newPassword;
453 QgsDebugMsgLevel( QStringLiteral(
"Master password is set and verified" ), 2 );
467 QString path = mAuthDatabaseConnectionUri;
468 if ( path.startsWith( QStringLiteral(
"QSQLITE://" ), Qt::CaseSensitivity::CaseInsensitive ) )
470 path = path.mid( 10 );
472 else if ( path.startsWith( QStringLiteral(
"QSPATIALITE://" ), Qt::CaseSensitivity::CaseInsensitive ) )
474 path = path.mid( 14 );
477 return QDir::cleanPath( path );
489 QMutexLocker locker( mMasterPasswordMutex.get() );
493 if ( mScheduledDbErase )
496 if ( mMasterPass.isEmpty() )
498 QgsDebugMsgLevel( QStringLiteral(
"Master password is not yet set by user" ), 2 );
499 if ( !masterPasswordInput() )
501 QgsDebugMsgLevel( QStringLiteral(
"Master password input canceled by user" ), 2 );
515 QgsDebugMsgLevel( QStringLiteral(
"Master password is set and verified" ), 2 );
523 QMutexLocker locker( mMutex.get() );
527 if ( mScheduledDbErase )
531 QString prevpass = QString( mMasterPass );
535 mMasterPass = prevpass;
536 const char *err = QT_TR_NOOP(
"Master password set: FAILED to verify, reset to previous" );
542 QgsDebugMsgLevel( QStringLiteral(
"Master password set: SUCCESS%1" ).arg( verify ?
" and verified" :
"" ), 2 );
554 if ( !masterPasswordRowsInDb( rows ) )
556 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
564 QgsDebugMsgLevel( QStringLiteral(
"Master password: %1 rows in database" ).arg( rows ), 2 );
568 const char *err = QT_TR_NOOP(
"Master password: FAILED to find just one master password record in database" );
575 else if ( rows == 1 )
577 if ( !masterPasswordCheckAgainstDb( compare ) )
579 if ( compare.isNull() )
581 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
590 if ( mPassTries >= 5 )
592 mAuthDisabled =
true;
593 const char *err = QT_TR_NOOP(
"Master password: failed 5 times authentication system DISABLED" );
601 QgsDebugMsgLevel( QStringLiteral(
"Master password: verified against hash in database" ), 2 );
602 if ( compare.isNull() )
606 else if ( compare.isNull() )
608 if ( !masterPasswordStoreInDb() )
610 const char *err = QT_TR_NOOP(
"Master password: hash FAILED to be stored in database" );
619 QgsDebugMsgLevel( QStringLiteral(
"Master password: hash stored in database" ), 2 );
622 if ( !masterPasswordCheckAgainstDb() )
624 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
634 QgsDebugMsgLevel( QStringLiteral(
"Master password: verified against hash in database" ), 2 );
646 return !mMasterPass.isEmpty();
653 return mMasterPass == pass;
657 bool keepbackup, QString *backuppath )
673 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: backed up current database" ), 2 );
676 QString prevpass = QString( mMasterPass );
677 QString prevciv = QString( masterPasswordCiv() );
683 if ( ok && !masterPasswordClearDb() )
686 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not clear current password from database" );
692 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: cleared current password from database" ), 2 );
699 if ( ok && !masterPasswordStoreInDb() )
702 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not store new password in database" );
708 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: stored new password in database" ), 2 );
715 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify new password in database" );
721 if ( ok && !reencryptAllAuthenticationConfigs( prevpass, prevciv ) )
724 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt configs in database" );
730 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: re-encrypted configs in database" ), 2 );
734 if ( ok && !verifyPasswordCanDecryptConfigs() )
737 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify password can decrypt re-encrypted configs" );
742 if ( ok && !reencryptAllAuthenticationSettings( prevpass, prevciv ) )
745 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt settings in database" );
750 if ( ok && !reencryptAllAuthenticationIdentities( prevpass, prevciv ) )
753 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt identities in database" );
761 const QString err = tr(
"Master password reset FAILED: could not sync password helper: %1" ).arg(
passwordHelperErrorMessage() );
770 QString errdbbackup( dbbackup );
771 errdbbackup.replace( QLatin1String(
".db" ), QLatin1String(
"_ERROR.db" ) );
773 QgsDebugError( QStringLiteral(
"Master password reset FAILED: backed up failed db at %1" ).arg( errdbbackup ) );
776 mMasterPass = prevpass;
777 QgsDebugError( QStringLiteral(
"Master password reset FAILED: reinstated previous password and database" ) );
781 *backuppath = errdbbackup;
786 if ( !keepbackup && !QFile::remove( dbbackup ) )
788 const char *err = QT_TR_NOOP(
"Master password reset: could not remove old database backup" );
796 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: backed up previous db at %1" ).arg( dbbackup ), 2 );
798 *backuppath = dbbackup;
817 const QString existingPassword = passwordHelperRead( readOk );
831 mScheduledDbErase = scheduleErase;
833 mScheduledDbEraseRequestEmitted =
false;
834 mScheduledDbEraseRequestCount = 0;
838 if ( !mScheduledDbEraseTimer )
840 mScheduledDbEraseTimer = std::make_unique<QTimer>(
this );
841 connect( mScheduledDbEraseTimer.get(), &QTimer::timeout,
this, &QgsAuthManager::tryToStartDbErase );
842 mScheduledDbEraseTimer->start( mScheduledDbEraseRequestWait * 1000 );
844 else if ( !mScheduledDbEraseTimer->isActive() )
846 mScheduledDbEraseTimer->start();
851 if ( mScheduledDbEraseTimer && mScheduledDbEraseTimer->isActive() )
852 mScheduledDbEraseTimer->stop();
861 qDeleteAll( mAuthMethods );
862 mAuthMethods.clear();
864 for (
const auto &authMethodKey : methods )
869 return !mAuthMethods.isEmpty();
881#ifndef __clang_analyzer__
884 QTimer::singleShot( 3, &loop, &QEventLoop::quit );
891 for (
int i = 0; i < len; i++ )
893 switch ( QRandomGenerator::system()->generate() % 2 )
896 id +=
static_cast<char>(
'0' + QRandomGenerator::system()->generate() % 10 );
899 id +=
static_cast<char>(
'a' + QRandomGenerator::system()->generate() % 26 );
903 if ( !configids.contains(
id ) )
908 QgsDebugMsgLevel( QStringLiteral(
"Generated unique ID: %1" ).arg(
id ), 2 );
921 const char *err = QT_TR_NOOP(
"Config ID is empty" );
927 return !configids.contains(
id );
932 const thread_local QRegularExpression authCfgRegExp( AUTH_CFG_REGEX );
933 return txt.indexOf( authCfgRegExp ) != -1;
940 QMutexLocker locker( mMutex.get() );
941 QStringList providerAuthMethodsKeys;
942 if ( !dataprovider.isEmpty() )
959 if ( providerAuthMethodsKeys.isEmpty() || providerAuthMethodsKeys.contains( config.method() ) )
962 if ( baseConfigs.contains( config.id() ) )
969 baseConfigs.insert( config.id(), config );
975 if ( storages.empty() )
978 QgsDebugError( QStringLiteral(
"No credentials storages found" ) );
997 if ( !
configIds.contains( config.id() ) )
999 mConfigAuthMethods.insert( config.id(), config.method() );
1000 QgsDebugMsgLevel( QStringLiteral(
"Stored auth config/methods:\n%1 %2" ).arg( config.id(), config.method() ), 2 );
1006 QgsDebugMsgLevel( QStringLiteral(
"A config with same id %1 was already added, skipping from %2" ).arg( config.id(), storage->
name() ), 2 );
1019 if ( !mConfigAuthMethods.contains( authcfg ) )
1021 QgsDebugError( QStringLiteral(
"No config auth method found in database for authcfg: %1" ).arg( authcfg ) );
1025 QString authMethodKey = mConfigAuthMethods.value( authcfg );
1037 return mConfigAuthMethods.value( authcfg, QString() );
1052 if ( !mAuthMethods.contains( authMethodKey ) )
1054 QgsDebugError( QStringLiteral(
"No auth method registered for auth method key: %1" ).arg( authMethodKey ) );
1058 return mAuthMethods.value( authMethodKey );
1065 if ( !mAuthMethods.contains( authMethodKey ) )
1067 QgsDebugError( QStringLiteral(
"No auth method registered for auth method key: %1" ).arg( authMethodKey ) );
1079 if ( dataprovider.isEmpty() )
1081 return mAuthMethods;
1085 QgsAuthMethodsMap::const_iterator i = mAuthMethods.constBegin();
1086 while ( i != mAuthMethods.constEnd() )
1089 && ( i.value()->supportedDataProviders().contains( QStringLiteral(
"all" ) )
1090 || i.value()->supportedDataProviders().contains( dataprovider ) ) )
1092 filteredmap.insert( i.key(), i.value() );
1100QWidget *QgsAuthManager::authMethodEditWidget(
const QString &authMethodKey, QWidget *parent )
1106 return method->editWidget( parent );
1131 QMutexLocker locker( mMutex.get() );
1138 const char *err = QT_TR_NOOP(
"Store config: FAILED because config is invalid" );
1144 QString uid = config.
id();
1145 bool passedinID = !uid.isEmpty();
1146 if ( uid.isEmpty() )
1154 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 is not unique" );
1162 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 could not be removed" );
1171 if ( configstring.isEmpty() )
1173 const char *err = QT_TR_NOOP(
"Store config: FAILED because config string is empty" );
1181 if ( defaultStorage->isEncrypted() )
1188 configCopy.
setId( uid );
1189 if ( !defaultStorage->storeMethodConfig( configCopy, configstring ) )
1203 config.
setId( uid );
1207 QgsDebugMsgLevel( QStringLiteral(
"Store config SUCCESS for authcfg: %1" ).arg( uid ), 2 );
1215 QMutexLocker locker( mMutex.get() );
1220 if ( !config.
isValid(
true ) )
1222 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is invalid" );
1229 if ( configstring.isEmpty() )
1231 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is empty" );
1262 if ( storages.empty() )
1273 QgsDebugMsgLevel( QStringLiteral(
"Update config SUCCESS for authcfg: %1" ).arg( config.
id() ), 2 );
1288 QMutexLocker locker( mMutex.get() );
1300 if ( ! config.
isValid(
true ) || ( full && payload.isEmpty() ) )
1323 QgsDebugError( QStringLiteral(
"Update of authcfg %1 FAILED for auth method %2" ).arg( authcfg, authMethodKey ) );
1326 QgsDebugMsgLevel( QStringLiteral(
"Load %1 config SUCCESS for authcfg: %2" ).arg( full ?
"full" :
"base", authcfg ), 2 );
1331 if ( storages.empty() )
1347 QMutexLocker locker( mMutex.get() );
1351 if ( authcfg.isEmpty() )
1370 QgsDebugMsgLevel( QStringLiteral(
"REMOVED config for authcfg: %1" ).arg( authcfg ), 2 );
1377 if ( storages.empty() )
1394 if ( filename.isEmpty() )
1397 QDomDocument document( QStringLiteral(
"qgis_authentication" ) );
1398 QDomElement root = document.createElement( QStringLiteral(
"qgis_authentication" ) );
1399 document.appendChild( root );
1402 if ( !password.isEmpty() )
1407 root.setAttribute( QStringLiteral(
"salt" ), salt );
1408 root.setAttribute( QStringLiteral(
"hash" ), hash );
1409 root.setAttribute( QStringLiteral(
"civ" ), civ );
1412 QDomElement configurations = document.createElement( QStringLiteral(
"configurations" ) );
1413 for (
const QString &authcfg : authcfgs )
1420 authMethodConfig.
writeXml( configurations, document );
1423 if ( !password.isEmpty() )
1425 QString configurationsString;
1426 QTextStream ts( &configurationsString );
1427#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1428 ts.setCodec(
"UTF-8" );
1430 configurations.save( ts, 2 );
1431 root.appendChild( document.createTextNode(
QgsAuthCrypto::encrypt( password, civ, configurationsString ) ) );
1435 root.appendChild( configurations );
1438 QFile file( filename );
1439 if ( !file.open( QFile::WriteOnly | QIODevice::Truncate ) )
1442 QTextStream ts( &file );
1443#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1444 ts.setCodec(
"UTF-8" );
1446 document.save( ts, 2 );
1455 QFile file( filename );
1456 if ( !file.open( QFile::ReadOnly ) )
1461 QDomDocument document( QStringLiteral(
"qgis_authentication" ) );
1462 if ( !document.setContent( &file ) )
1469 QDomElement root = document.documentElement();
1470 if ( root.tagName() != QLatin1String(
"qgis_authentication" ) )
1475 QDomElement configurations;
1476 if ( root.hasAttribute( QStringLiteral(
"salt" ) ) )
1478 QString salt = root.attribute( QStringLiteral(
"salt" ) );
1479 QString hash = root.attribute( QStringLiteral(
"hash" ) );
1480 QString civ = root.attribute( QStringLiteral(
"civ" ) );
1485 configurations = document.firstChild().toElement();
1489 configurations = root.firstChildElement( QStringLiteral(
"configurations" ) );
1492 QDomElement configuration = configurations.firstChildElement();
1493 while ( !configuration.isNull() )
1496 ( void )authMethodConfig.
readXml( configuration );
1499 configuration = configuration.nextSiblingElement();
1508 QMutexLocker locker( mMutex.get() );
1514 if ( defaultStorage->clearMethodConfigs() )
1518 QgsDebugMsgLevel( QStringLiteral(
"REMOVED all configs from the default storage" ), 2 );
1523 QgsDebugMsgLevel( QStringLiteral(
"FAILED to remove all configs from the default storage" ), 2 );
1539 QMutexLocker locker( mMutex.get() );
1543 const char *err = QT_TR_NOOP(
"The authentication storage is not filesystem-based" );
1551 const char *err = QT_TR_NOOP(
"No authentication database file found" );
1561 if ( authConn.isValid() && authConn.isOpen() )
1565 QString datestamp( QDateTime::currentDateTime().toString( QStringLiteral(
"yyyy-MM-dd-hhmmss" ) ) );
1567 dbbackup.replace( QLatin1String(
".db" ), QStringLiteral(
"_%1.db" ).arg( datestamp ) );
1571 const char *err = QT_TR_NOOP(
"Could not back up authentication database" );
1578 *backuppath = dbbackup;
1580 QgsDebugMsgLevel( QStringLiteral(
"Backed up auth database at %1" ).arg( dbbackup ), 2 );
1588 QMutexLocker locker( mMutex.get() );
1599 if ( backuppath && !dbbackup.isEmpty() )
1600 *backuppath = dbbackup;
1604 if ( defaultStorage->erase() )
1606 mMasterPass = QString();
1634 const QString &dataprovider )
1646 QgsDebugError( QStringLiteral(
"Network request updating not supported by authcfg: %1" ).arg( authcfg ) );
1661 const QString &dataprovider )
1673 QgsDebugMsgLevel( QStringLiteral(
"Network reply updating not supported by authcfg: %1" ).arg( authcfg ), 3 );
1689 const QString &dataprovider )
1701 QgsDebugError( QStringLiteral(
"Data source URI updating not supported by authcfg: %1" ).arg( authcfg ) );
1728 QgsDebugError( QStringLiteral(
"Proxy updating not supported by authcfg: %1" ).arg( authcfg ) );
1737 QgsDebugMsgLevel( QStringLiteral(
"Proxy updated successfully from authcfg: %1" ).arg( authcfg ), 2 );
1748 QMutexLocker locker( mMutex.get() );
1749 if ( key.isEmpty() )
1752 QString storeval( value.toString() );
1775 if ( !defaultStorage->storeAuthSetting( key, storeval ) )
1793 QMutexLocker locker( mMutex.get() );
1794 if ( key.isEmpty() )
1800 QVariant value = defaultValue;
1808 if ( !storeval.isEmpty() )
1819 if ( storages.empty() )
1831 QMutexLocker locker( mMutex.get() );
1832 if ( key.isEmpty() )
1846 if ( storages.empty() )
1858 QMutexLocker locker( mMutex.get() );
1859 if ( key.isEmpty() )
1886 if ( storages.empty() )
1901 QMutexLocker locker( mMutex.get() );
1907 mCustomConfigByHostCache.clear();
1908 mHasCheckedIfCustomConfigByHostExists =
false;
1911 QgsDebugError( QStringLiteral(
"Init of SSL caches FAILED" ) );
1919 QMutexLocker locker( mMutex.get() );
1920 if ( cert.isNull() )
1922 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
1927 QgsDebugError( QStringLiteral(
"Passed private key is null" ) );
1939 QgsDebugError( QStringLiteral(
"Store certificate identity: FAILED to remove pre-existing certificate identity %1" ).arg(
id ) );
1947 if ( !defaultStorage->storeCertIdentity( cert, keypem ) )
1965 QMutexLocker locker( mMutex.get() );
1967 QSslCertificate cert;
1978 if ( !cert.isNull() )
1984 if ( storages.empty() )
1996 QMutexLocker locker( mMutex.get() );
1997 QPair<QSslCertificate, QSslKey> bundle;
2012 if ( encryptedBundle.first.isNull() )
2014 QgsDebugError( QStringLiteral(
"Certificate identity bundle is null for id: %1" ).arg(
id ) );
2017 QSslKey key(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), encryptedBundle.second ).toLatin1(),
2018 QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey );
2021 QgsDebugError( QStringLiteral(
"Certificate identity bundle: FAILED to create private key" ) );
2024 bundle = qMakePair( encryptedBundle.first, key );
2029 if ( storages.empty() )
2042 QMutexLocker locker( mMutex.get() );
2046 return QStringList() << QString( bundle.first.toPem() ) << QString( bundle.second.toPem() );
2048 return QStringList();
2055 QMutexLocker locker( mMutex.get() );
2056 QList<QSslCertificate> certs;
2063 const QList<QSslCertificate> storageCerts = storage->
certIdentities();
2065 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
2067 if ( !certs.contains( cert ) )
2069 certs.append( cert );
2078 if ( storages.empty() )
2090 QMutexLocker locker( mMutex.get() );
2104 for (
const QString &
id : std::as_const( storageIds ) )
2106 if ( !ids.contains(
id ) )
2124 QMutexLocker locker( mMutex.get() );
2139 if ( storages.empty() )
2151 QMutexLocker locker( mMutex.get() );
2154 QgsDebugError( QStringLiteral(
"Passed bundle ID is empty" ) );
2174 if ( storages.empty() )
2187 QMutexLocker locker( mMutex.get() );
2199 QgsDebugError( QStringLiteral(
"Store SSL certificate custom config: FAILED to remove pre-existing config %1" ).arg(
id ) );
2205 if ( !defaultStorage->storeSslCertCustomConfig( config ) )
2218 mCustomConfigByHostCache.clear();
2227 QMutexLocker locker( mMutex.get() );
2230 if (
id.isEmpty() || hostport.isEmpty() )
2232 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2256 if ( storages.empty() )
2270 if ( hostport.isEmpty() )
2275 QMutexLocker locker( mMutex.get() );
2277 if ( mCustomConfigByHostCache.contains( hostport ) )
2278 return mCustomConfigByHostCache.value( hostport );
2288 mCustomConfigByHostCache.insert( hostport, config );
2293 if ( storages.empty() )
2305 QMutexLocker locker( mMutex.get() );
2306 QList<QgsAuthConfigSslServer> configs;
2317 for (
const auto &config : std::as_const( storageConfigs ) )
2320 const QString hostPort = config.sslHostPort();
2321 const QString shaHostPort( QStringLiteral(
"%1:%2" ).arg(
id, hostPort ) );
2322 if ( ! ids.contains( shaHostPort ) )
2324 ids.append( shaHostPort );
2325 configs.append( config );
2334 if ( storages.empty() )
2346 QMutexLocker locker( mMutex.get() );
2347 if (
id.isEmpty() || hostPort.isEmpty() )
2349 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2364 if ( storages.empty() )
2376 QMutexLocker locker( mMutex.get() );
2377 if (
id.isEmpty() || hostport.isEmpty() )
2379 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2383 mCustomConfigByHostCache.clear();
2397 const QString shaHostPort( QStringLiteral(
"%1:%2" ).arg(
id, hostport ) );
2398 if ( mIgnoredSslErrorsCache.contains( shaHostPort ) )
2400 mIgnoredSslErrorsCache.remove( shaHostPort );
2406 if ( storages.empty() )
2419 QMutexLocker locker( mMutex.get() );
2420 if ( !mIgnoredSslErrorsCache.isEmpty() )
2422 QgsDebugMsgLevel( QStringLiteral(
"Ignored SSL errors cache items:" ), 1 );
2423 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = mIgnoredSslErrorsCache.constBegin();
2424 while ( i != mIgnoredSslErrorsCache.constEnd() )
2427 for (
auto err : i.value() )
2431 QgsDebugMsgLevel( QStringLiteral(
"%1 = %2" ).arg( i.key(), errs.join(
", " ) ), 1 );
2445 QMutexLocker locker( mMutex.get() );
2452 QString shahostport( QStringLiteral(
"%1:%2" )
2455 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2457 mIgnoredSslErrorsCache.remove( shahostport );
2460 if ( !errenums.isEmpty() )
2462 mIgnoredSslErrorsCache.insert( shahostport, QSet<QSslError::SslError>( errenums.begin(), errenums.end() ) );
2463 QgsDebugMsgLevel( QStringLiteral(
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1" ).arg( shahostport ), 2 );
2468 QgsDebugMsgLevel( QStringLiteral(
"No ignored SSL errors to cache for sha:host:port = %1" ).arg( shahostport ), 2 );
2476 QMutexLocker locker( mMutex.get() );
2477 const thread_local QRegularExpression rx( QRegularExpression::anchoredPattern(
"\\S+:\\S+:\\d+" ) );
2478 if ( !rx.match( shahostport ).hasMatch() )
2480 QgsDebugError(
"Passed shahostport does not match \\S+:\\S+:\\d+, "
2481 "e.g. 74a4ef5ea94512a43769b744cda0ca5049a72491:www.example.com:443" );
2485 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2487 mIgnoredSslErrorsCache.remove( shahostport );
2490 if ( errors.isEmpty() )
2492 QgsDebugError( QStringLiteral(
"Passed errors list empty" ) );
2496 QSet<QSslError::SslError> errs;
2497 for (
const auto &error : errors )
2499 if ( error.error() == QSslError::NoError )
2502 errs.insert( error.error() );
2505 if ( errs.isEmpty() )
2507 QgsDebugError( QStringLiteral(
"Passed errors list does not contain errors" ) );
2511 mIgnoredSslErrorsCache.insert( shahostport, errs );
2513 QgsDebugMsgLevel( QStringLiteral(
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1" ).arg( shahostport ), 2 );
2522 QMutexLocker locker( mMutex.get() );
2523 QHash<QString, QSet<QSslError::SslError> > prevcache( mIgnoredSslErrorsCache );
2524 QHash<QString, QSet<QSslError::SslError> > nextcache;
2534 for (
const auto &config : std::as_const( customConfigs ) )
2537 if ( ! ids.contains( shaHostPort ) )
2539 ids.append( shaHostPort );
2540 if ( !config.sslIgnoredErrorEnums().isEmpty() )
2542 nextcache.insert( shaHostPort, QSet<QSslError::SslError>( config.sslIgnoredErrorEnums().cbegin(), config.sslIgnoredErrorEnums().cend() ) );
2544 if ( prevcache.contains( shaHostPort ) )
2546 prevcache.remove( shaHostPort );
2556 if ( !prevcache.isEmpty() )
2559 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = prevcache.constBegin();
2560 while ( i != prevcache.constEnd() )
2562 nextcache.insert( i.key(), i.value() );
2567 if ( nextcache != mIgnoredSslErrorsCache )
2569 mIgnoredSslErrorsCache.clear();
2570 mIgnoredSslErrorsCache = nextcache;
2571 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of ignored SSL errors cache SUCCEEDED" ), 2 );
2576 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of ignored SSL errors cache SAME AS BEFORE" ), 2 );
2585 QMutexLocker locker( mMutex.get() );
2586 if ( certs.isEmpty() )
2588 QgsDebugError( QStringLiteral(
"Passed certificate list has no certs" ) );
2592 for (
const auto &cert : certs )
2604 QMutexLocker locker( mMutex.get() );
2607 if ( cert.isNull() )
2609 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2615 QgsDebugError( QStringLiteral(
"Store certificate authority: FAILED to remove pre-existing certificate authority" ) );
2621 return defaultStorage->storeCertAuthority( cert );
2636 QMutexLocker locker( mMutex.get() );
2637 QSslCertificate emptycert;
2638 QSslCertificate cert;
2648 if ( !cert.isNull() )
2654 if ( storages.empty() )
2667 QMutexLocker locker( mMutex.get() );
2668 if ( cert.isNull() )
2670 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2685 if ( storages.empty() )
2697 QMutexLocker locker( mMutex.get() );
2698 if ( cert.isNull() )
2700 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2727 if ( storages.empty() )
2737 return QSslConfiguration::systemCaCertificates();
2744 QMutexLocker locker( mMutex.get() );
2745 QList<QSslCertificate> certs;
2746 QList<QSslCertificate> filecerts;
2755 QString cafile( cafileval.toString() );
2756 if ( !cafile.isEmpty() && QFile::exists( cafile ) )
2761 for (
const auto &cert : std::as_const( filecerts ) )
2763 if ( !allowinvalid.toBool() && ( cert.isBlacklisted()
2765 || cert.expiryDate() <= QDateTime::currentDateTime()
2766 || cert.effectiveDate() > QDateTime::currentDateTime() ) )
2783 QMutexLocker locker( mMutex.get() );
2788 QList<QSslCertificate> certs;
2792 const QList<QSslCertificate> storageCerts = storage->
caCerts();
2794 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
2796 if ( !certs.contains( cert ) )
2798 certs.append( cert );
2807 if ( storages.empty() )
2819 QMutexLocker locker( mMutex.get() );
2827 QMutexLocker locker( mMutex.get() );
2828 mCaCertsCache.clear();
2834 bool res = !mCaCertsCache.isEmpty();
2836 QgsDebugError( QStringLiteral(
"Rebuild of CA certs cache FAILED" ) );
2844 QMutexLocker locker( mMutex.get() );
2845 if ( cert.isNull() )
2847 QgsDebugError( QStringLiteral(
"Passed certificate is null." ) );
2864 return defaultStorage->storeCertTrustPolicy( cert, policy );
2877 QMutexLocker locker( mMutex.get() );
2878 if ( cert.isNull() )
2880 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2896 if ( storages.empty() )
2908 QMutexLocker locker( mMutex.get() );
2909 if ( certs.empty() )
2911 QgsDebugError( QStringLiteral(
"Passed certificate list has no certs" ) );
2915 for (
const auto &cert : certs )
2927 QMutexLocker locker( mMutex.get() );
2928 if ( cert.isNull() )
2930 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2956 if ( storages.empty() )
2968 QMutexLocker locker( mMutex.get() );
2969 if ( cert.isNull() )
2979 if ( trustedids.contains(
id ) )
2983 else if ( untrustedids.contains(
id ) )
2999 return storeAuthSetting( QStringLiteral(
"certdefaulttrust" ),
static_cast< int >( policy ) );
3006 QMutexLocker locker( mMutex.get() );
3007 QVariant policy(
authSetting( QStringLiteral(
"certdefaulttrust" ) ) );
3019 QMutexLocker locker( mMutex.get() );
3020 mCertTrustCache.clear();
3031 for (
auto it = trustedCerts.cbegin(); it != trustedCerts.cend(); ++it )
3033 const QString
id { it.key( )};
3034 if ( ! ids.contains(
id ) )
3055 if ( ! storages.empty() )
3057 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of cert trust policy cache SUCCEEDED" ), 2 );
3071 QMutexLocker locker( mMutex.get() );
3075 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
3077 QList<QSslCertificate> trustedcerts;
3078 for (
int i = 0; i < certpairs.size(); ++i )
3080 QSslCertificate cert( certpairs.at( i ).second );
3082 if ( trustedids.contains( certid ) )
3085 trustedcerts.append( cert );
3091 trustedcerts.append( cert );
3096 QSslConfiguration sslconfig( QSslConfiguration::defaultConfiguration() );
3097 sslconfig.setCaCertificates( trustedcerts );
3098 QSslConfiguration::setDefaultConfiguration( sslconfig );
3100 return trustedcerts;
3107 QMutexLocker locker( mMutex.get() );
3108 if ( trustedCAs.isEmpty() )
3110 if ( mTrustedCaCertsCache.isEmpty() )
3117 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
3119 QList<QSslCertificate> untrustedCAs;
3120 for (
int i = 0; i < certpairs.size(); ++i )
3122 QSslCertificate cert( certpairs.at( i ).second );
3123 if ( !trustedCAs.contains( cert ) )
3125 untrustedCAs.append( cert );
3128 return untrustedCAs;
3135 QMutexLocker locker( mMutex.get() );
3137 QgsDebugMsgLevel( QStringLiteral(
"Rebuilt trusted cert authorities cache" ), 2 );
3146 QMutexLocker locker( mMutex.get() );
3154 QMutexLocker locker( mMutex.get() );
3157 return passwordHelperWrite( mMasterPass );
3167 bool readOk =
false;
3168 const QString currentPass = passwordHelperRead( readOk );
3172 if ( !currentPass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
3181#if defined(Q_OS_MAC)
3182 return titleCase ? QObject::tr(
"Keychain" ) : QObject::tr(
"keychain" );
3183#elif defined(Q_OS_WIN)
3184 return titleCase ? QObject::tr(
"Password Manager" ) : QObject::tr(
"password manager" );
3185#elif defined(Q_OS_LINUX)
3187 const QString desktopSession = qgetenv(
"DESKTOP_SESSION" );
3188 const QString currentDesktop = qgetenv(
"XDG_CURRENT_DESKTOP" );
3189 const QString gdmSession = qgetenv(
"GDMSESSION" );
3191 if ( desktopSession.contains( QLatin1String(
"kde" ), Qt::CaseInsensitive ) || currentDesktop.contains( QLatin1String(
"kde" ), Qt::CaseInsensitive ) || gdmSession.contains( QLatin1String(
"kde" ), Qt::CaseInsensitive ) )
3193 return titleCase ? QObject::tr(
"Wallet" ) : QObject::tr(
"wallet" );
3196 return titleCase ? QObject::tr(
"Wallet/Key Ring" ) : QObject::tr(
"wallet/key ring" );
3198 return titleCase ? QObject::tr(
"Password Manager" ) : QObject::tr(
"password manager" );
3215 for (
const auto &authcfg : ids )
3235void QgsAuthManager::writeToConsole(
const QString &message,
3251 msg += QLatin1String(
"WARNING: " );
3254 msg += QLatin1String(
"ERROR: " );
3261 QTextStream out( stdout, QIODevice::WriteOnly );
3262 out << msg << Qt::endl;
3265void QgsAuthManager::tryToStartDbErase()
3269 ++mScheduledDbEraseRequestCount;
3271 int trycutoff = 90 / ( mScheduledDbEraseRequestWait ? mScheduledDbEraseRequestWait : 3 );
3272 if ( mScheduledDbEraseRequestCount >= trycutoff )
3275 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emitting/scheduling canceled" ), 2 );
3280 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest attempt (%1 of %2)" )
3281 .arg( mScheduledDbEraseRequestCount ).arg( trycutoff ), 2 );
3287 mScheduledDbEraseRequestEmitted =
true;
3292 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emitted" ), 2 );
3295 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emit skipped" ), 2 );
3301 QMutexLocker locker( mMutex.get() );
3303 QMapIterator<QThread *, QMetaObject::Connection> iterator( mConnectedThreads );
3304 while ( iterator.hasNext() )
3307 QThread::disconnect( iterator.value() );
3318 qDeleteAll( mAuthMethods );
3323 if ( authConn.isValid() && authConn.isOpen() )
3327 QSqlDatabase::removeDatabase( QStringLiteral(
"authentication.configs" ) );
3332 QMutexLocker locker( mMutex.get() );
3333 if ( ! mAuthConfigurationStorageRegistry )
3335 mAuthConfigurationStorageRegistry = std::make_unique<QgsAuthConfigurationStorageRegistry>();
3337 return mAuthConfigurationStorageRegistry.get();
3341QString QgsAuthManager::passwordHelperName()
const
3343 return tr(
"Password Helper" );
3347void QgsAuthManager::passwordHelperLog(
const QString &msg )
const
3363 QKeychain::DeletePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3366 job.setAutoDelete(
false );
3367 job.setKey( authPasswordHelperKeyName() );
3369 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3374 mPasswordHelperErrorCode = job.error();
3375 mPasswordHelperErrorMessage = tr(
"Delete password failed: %1." ).arg( job.errorString() );
3386 passwordHelperProcessError();
3390QString QgsAuthManager::passwordHelperRead(
bool &ok )
3398 QKeychain::ReadPasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3401 job.setAutoDelete(
false );
3402 job.setKey( authPasswordHelperKeyName() );
3404 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3409 mPasswordHelperErrorCode = job.error();
3410 mPasswordHelperErrorMessage = tr(
"Retrieving password from the %1 failed: %2." ).arg(
passwordHelperDisplayName(), job.errorString() );
3416 password = job.textData();
3418 if ( password.isEmpty() )
3420 mPasswordHelperErrorCode = QKeychain::EntryNotFound;
3432 passwordHelperProcessError();
3436bool QgsAuthManager::passwordHelperWrite(
const QString &password )
3440 Q_ASSERT( !password.isEmpty() );
3443 QKeychain::WritePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3444 QgsSettings settings;
3446 job.setAutoDelete(
false );
3447 job.setKey( authPasswordHelperKeyName() );
3448 job.setTextData( password );
3450 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3455 mPasswordHelperErrorCode = job.error();
3456 mPasswordHelperErrorMessage = tr(
"Storing password in the %1 failed: %2." ).arg(
passwordHelperDisplayName(), job.errorString() );
3463 passwordHelperClearErrors();
3468 passwordHelperProcessError();
3483 emit
messageLog( enabled ? tr(
"Your %1 will be <b>used from now</b> on to store and retrieve the master password." )
3485 tr(
"Your %1 will <b>not be used anymore</b> to store and retrieve the master password." )
3502void QgsAuthManager::passwordHelperClearErrors()
3504 mPasswordHelperErrorCode = QKeychain::NoError;
3505 mPasswordHelperErrorMessage.clear();
3508void QgsAuthManager::passwordHelperProcessError()
3512 if ( mPasswordHelperErrorCode == QKeychain::AccessDenied ||
3513 mPasswordHelperErrorCode == QKeychain::AccessDeniedByUser ||
3514 mPasswordHelperErrorCode == QKeychain::NoBackendAvailable ||
3515 mPasswordHelperErrorCode == QKeychain::NotImplemented )
3521 mPasswordHelperErrorMessage = tr(
"There was an error and integration with your %1 has been disabled. "
3522 "You can re-enable it at any time through the \"Utilities\" menu "
3523 "in the Authentication pane of the options dialog. %2" )
3526 if ( mPasswordHelperErrorCode != QKeychain::NoError )
3532 passwordHelperClearErrors();
3536bool QgsAuthManager::masterPasswordInput()
3544 bool storedPasswordIsValid =
false;
3550 bool readOk =
false;
3551 pass = passwordHelperRead( readOk );
3552 if ( readOk && ! pass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
3558 storedPasswordIsValid =
true;
3573 if ( ok && !pass.isEmpty() && mMasterPass != pass )
3578 if ( !passwordHelperWrite( pass ) )
3588bool QgsAuthManager::masterPasswordRowsInDb(
int &rows )
const
3598 QMutexLocker locker( mMutex.get() );
3603 if ( storages.empty() )
3609 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
3617 catch (
const QgsNotSupportedException &e )
3636 if ( !masterPasswordRowsInDb( rows ) )
3638 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
3644 return ( rows == 1 );
3647bool QgsAuthManager::masterPasswordCheckAgainstDb(
const QString &compare )
const
3659 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords( ) };
3660 if ( passwords.size() == 0 )
3665 const QgsAuthConfigurationStorage::MasterPasswordConfig storedPassword { passwords.first() };
3668 catch (
const QgsNotSupportedException &e )
3683bool QgsAuthManager::masterPasswordStoreInDb()
const
3690 QString salt, hash, civ;
3698 return defaultStorage->storeMasterPassword( { salt, civ, hash } );
3700 catch (
const QgsNotSupportedException &e )
3714bool QgsAuthManager::masterPasswordClearDb()
3726 return defaultStorage->clearMasterPasswords();
3728 catch (
const QgsNotSupportedException &e )
3743const QString QgsAuthManager::masterPasswordCiv()
const
3754 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords( ) };
3755 if ( passwords.size() == 0 )
3760 return passwords.first().civ;
3762 catch (
const QgsNotSupportedException &e )
3780 QStringList configKeys = QStringList();
3794 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
3796 if ( !configKeys.contains( it.key() ) )
3798 configKeys.append( it.key() );
3816bool QgsAuthManager::verifyPasswordCanDecryptConfigs()
const
3828 for (
const QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
3839 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
3841 QString configstring(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), it.value().config( QStringLiteral(
"encrypted_payload" ) ) ) );
3842 if ( configstring.isEmpty() )
3844 QgsDebugError( QStringLiteral(
"Verify password can decrypt configs FAILED, could not decrypt a config (id: %1) from storage %2" )
3845 .arg( it.key(), storage->
name() ) );
3850 catch (
const QgsNotSupportedException &e )
3859 if ( storages.empty() )
3868bool QgsAuthManager::reencryptAllAuthenticationConfigs(
const QString &prevpass,
const QString &prevciv )
3877 for (
const auto &configid : ids )
3879 res = res && reencryptAuthenticationConfig( configid, prevpass, prevciv );
3884bool QgsAuthManager::reencryptAuthenticationConfig(
const QString &authcfg,
const QString &prevpass,
const QString &prevciv )
3896 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
3908 const QgsAuthMethodConfig config = storage->
loadMethodConfig( authcfg, payload,
true );
3909 if ( payload.isEmpty() || ! config.
isValid(
true ) )
3911 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not find config (id: %1)" ).arg( authcfg ) );
3916 if ( configstring.isEmpty() )
3918 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not decrypt config (id: %1)" ).arg( authcfg ) );
3932 catch (
const QgsNotSupportedException &e )
3940 if ( storages.empty() )
3952bool QgsAuthManager::reencryptAllAuthenticationSettings(
const QString &prevpass,
const QString &prevciv )
3957 Q_UNUSED( prevpass )
3970 QStringList encryptedsettings;
3971 encryptedsettings <<
"";
3973 for (
const auto & sett, std::as_const( encryptedsettings ) )
3980 QSqlQuery query( authDbConnection() );
3982 query.prepare( QStringLiteral(
"SELECT value FROM %1 "
3983 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
3985 query.bindValue(
":setting", sett );
3987 if ( !authDbQuery( &query ) )
3990 if ( !query.isActive() || !query.isSelect() )
3992 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, query not active or a select operation for setting: %2" ).arg( sett ) );
3996 if ( query.first() )
4002 query.prepare( QStringLiteral(
"UPDATE %1 "
4003 "SET value = :value "
4004 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
4006 query.bindValue(
":setting", sett );
4009 if ( !authDbStartTransaction() )
4012 if ( !authDbQuery( &query ) )
4015 if ( !authDbCommit() )
4018 QgsDebugMsgLevel( QStringLiteral(
"Reencrypt SUCCESS for setting: %2" ).arg( sett ), 2 );
4023 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not find in db setting: %2" ).arg( sett ) );
4029 QgsDebugError( QStringLiteral(
"Select contains more than one for setting: %1" ).arg( sett ) );
4040bool QgsAuthManager::reencryptAllAuthenticationIdentities(
const QString &prevpass,
const QString &prevciv )
4049 for (
const auto &identid : ids )
4051 res = res && reencryptAuthenticationIdentity( identid, prevpass, prevciv );
4056bool QgsAuthManager::reencryptAuthenticationIdentity(
4057 const QString &identid,
4058 const QString &prevpass,
4059 const QString &prevciv )
4072 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
4087 if ( keystring.isEmpty() )
4089 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not decrypt identity id: %1" ).arg( identid ) );
4097 catch (
const QgsNotSupportedException &e )
4105 if ( storages.empty() )
4121 for (
const auto &cert : certs )
4124 QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>( source, cert ) );
4128QString QgsAuthManager::authPasswordHelperKeyName()
const
4132 QString dbProfilePath;
4138 const QFileInfo info( mAuthDatabaseConnectionUri );
4139 dbProfilePath = info.dir().dirName();
4143 dbProfilePath = QCryptographicHash::hash( ( mAuthDatabaseConnectionUri.toUtf8() ), QCryptographicHash::Md5 ).toHex();
4147 return AUTH_PASSWORD_HELPER_KEY_NAME_BASE + ( dbProfilePath.compare( QLatin1String(
"default" ), Qt::CaseInsensitive ) == 0 ? QString() : dbProfilePath );
4156 if ( qobject_cast<QgsAuthConfigurationStorageDb *>( storage ) )
MessageLevel
Level for messages This will be used both for message log and message bar in application.
@ Warning
Warning message.
@ Critical
Critical/error message.
@ Info
Information message.
AuthConfigurationStorageCapability
Authentication configuration storage capabilities.
@ CreateSetting
Can create a new authentication setting.
@ CreateConfiguration
Can create a new authentication configuration.
@ ClearStorage
Can clear all configurations from storage.
@ DeleteCertificateAuthority
Can delete a certificate authority.
@ DeleteSslCertificateCustomConfig
Can delete a SSL certificate custom config.
@ DeleteSetting
Can delete the authentication setting.
@ ReadSslCertificateCustomConfig
Can read a SSL certificate custom config.
@ DeleteMasterPassword
Can delete the master password.
@ CreateSslCertificateCustomConfig
Can create a new SSL certificate custom config.
@ ReadCertificateTrustPolicy
Can read a certificate trust policy.
@ ReadConfiguration
Can read an authentication configuration.
@ UpdateConfiguration
Can update an authentication configuration.
@ ReadCertificateAuthority
Can read a certificate authority.
@ CreateCertificateAuthority
Can create a new certificate authority.
@ DeleteConfiguration
Can deleet an authentication configuration.
@ ReadSetting
Can read the authentication settings.
@ CreateCertificateIdentity
Can create a new certificate identity.
@ ReadCertificateIdentity
Can read a certificate identity.
@ CreateCertificateTrustPolicy
Can create a new certificate trust policy.
@ ReadMasterPassword
Can read the master password.
@ CreateMasterPassword
Can create a new master password.
@ DeleteCertificateTrustPolicy
Can delete a certificate trust policy.
static QString sslErrorEnumString(QSslError::SslError errenum)
Gets short strings describing an SSL error.
static QString shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Gets the sha1 hash for certificate.
CertTrustPolicy
Type of certificate trust policy.
static QMap< QString, QSslCertificate > mapDigestToCerts(const QList< QSslCertificate > &certs)
Map certificate sha1 to certificate as simple cache.
static QByteArray certsToPemText(const QList< QSslCertificate > &certs)
certsToPemText dump a list of QSslCertificates to PEM text
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Returns a list of concatenated certs from a PEM or DER formatted file.
static bool certificateIsAuthorityOrIssuer(const QSslCertificate &cert)
Gets whether a certificate is an Authority or can at least sign other certificates.
CaCertSource
Type of CA certificate source.
Configuration container for SSL server connection exceptions or overrides.
bool isNull() const
Whether configuration is null (missing components).
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
const QSslCertificate sslCertificate() const
Server certificate object.
const QString sslHostPort() const
Server host:port string.
QSqlDatabase based implementation of QgsAuthConfigurationStorage.
bool removeCertTrustPolicy(const QSslCertificate &cert) override
Remove certificate trust policy.
const QgsAuthConfigSslServer loadSslCertCustomConfigByHost(const QString &hostport) const override
Loads an SSL certificate custom config by hostport (host:port).
QString loadAuthSetting(const QString &key) const override
Load an authentication setting from the storage.
bool removeAuthSetting(const QString &key) override
Remove an authentication setting from the storage.
const QMap< QString, QgsAuthCertUtils::CertTrustPolicy > caCertsPolicy() const override
Returns the map of CA certificates hashes in the storages and their trust policy.
QgsAuthCertUtils::CertTrustPolicy loadCertTrustPolicy(const QSslCertificate &cert) const override
Load certificate trust policy.
bool sslCertCustomConfigExists(const QString &id, const QString &hostport) override
Check if SSL certificate custom config exists.
bool removeCertIdentity(const QSslCertificate &cert) override
Remove a certificate identity from the storage.
const QPair< QSslCertificate, QString > loadCertIdentityBundle(const QString &id) const override
Returns a certificate identity bundle by id (sha hash).
const QList< QgsAuthConfigurationStorage::MasterPasswordConfig > masterPasswords() const override
Returns the list of (encrypted) master passwords stored in the database.
bool methodConfigExists(const QString &id) const override
Check if an authentication configuration exists in the storage.
QStringList certIdentityIds() const override
certIdentityIds get list of certificate identity ids from database
bool initialize() override
Initializes the storage.
bool storeMethodConfig(const QgsAuthMethodConfig &mconfig, const QString &payload) override
Store an authentication config in the database.
bool removeCertAuthority(const QSslCertificate &cert) override
Remove a certificate authority.
const QSslCertificate loadCertIdentity(const QString &id) const override
certIdentity get a certificate identity by id (sha hash)
const QList< QgsAuthConfigSslServer > sslCertCustomConfigs() const override
sslCertCustomConfigs get SSL certificate custom configs
QgsAuthMethodConfigsMap authMethodConfigs(const QStringList &allowedMethods=QStringList()) const override
Returns a mapping of authentication configurations available from this storage.
const QList< QSslCertificate > caCerts() const override
Returns the list of CA certificates in the storage.
bool certTrustPolicyExists(const QSslCertificate &cert) const override
Check if certificate trust policy exists.
const QSslCertificate loadCertAuthority(const QString &id) const override
certAuthority get a certificate authority by id (sha hash)
bool removeMethodConfig(const QString &id) override
Removes the authentication configuration with the specified id.
QgsAuthMethodConfigsMap authMethodConfigsWithPayload() const override
Returns a mapping of authentication configurations available from this storage.
bool certIdentityExists(const QString &id) const override
Check if the certificate identity exists.
bool certAuthorityExists(const QSslCertificate &cert) const override
Check if a certificate authority exists.
QgsAuthMethodConfig loadMethodConfig(const QString &id, QString &payload, bool full=false) const override
Load an authentication configuration from the database.
bool storeCertIdentity(const QSslCertificate &cert, const QString &keyPem) override
Store a certificate identity in the storage.
bool removeSslCertCustomConfig(const QString &id, const QString &hostport) override
Remove an SSL certificate custom config.
const QList< QSslCertificate > certIdentities() const override
certIdentities get certificate identities
QString name() const override
Returns a human readable localized short name of the storage implementation (e.g "SQLite").
bool authSettingExists(const QString &key) const override
Check if an authentication setting exists in the storage.
const QgsAuthConfigSslServer loadSslCertCustomConfig(const QString &id, const QString &hostport) const override
Loads an SSL certificate custom config by id (sha hash) and hostport (host:port).
Registry for authentication configuration storages.
QgsAuthConfigurationStorage * firstReadyStorageWithCapability(Qgis::AuthConfigurationStorageCapability capability) const
Returns the first ready (and enabled) authentication configuration storage which has the required cap...
QList< QgsAuthConfigurationStorage * > storages() const
Returns the list of all registered authentication configuration storages.
QList< QgsAuthConfigurationStorage * > readyStoragesWithCapability(Qgis::AuthConfigurationStorageCapability capability) const
Returns the list of all ready (and enabled) authentication configuration storage with the required ca...
QList< QgsAuthConfigurationStorage * > readyStorages() const
Returns the list of all ready (and enabled) authentication configuration storage.
bool addStorage(QgsAuthConfigurationStorage *storage)
Add an authentication configuration storage to the registry.
Abstract class that defines the interface for all authentication configuration storage implementation...
virtual void setReadOnly(bool readOnly)
Utility method to unset all editing capabilities.
void methodConfigChanged()
Emitted when the storage method config table was changed.
Qgis::AuthConfigurationStorageCapabilities capabilities() const
Returns the capabilities of the storage.
bool isEnabled() const
Returns true if the storage is enabled.
bool isEncrypted() const
Returns true if the storage is encrypted.
void messageLog(const QString &message, const QString &tag=QStringLiteral("Authentication"), Qgis::MessageLevel level=Qgis::MessageLevel::Info)
Custom logging signal to relay to console output and QgsMessageLog.
virtual QString lastError() const
Returns the last error message.
static void passwordKeyHash(const QString &pass, QString *salt, QString *hash, QString *cipheriv=nullptr)
Generate SHA256 hash for master password, with iterations and salt.
static const QString encrypt(const QString &pass, const QString &cipheriv, const QString &text)
Encrypt data using master password.
static bool verifyPasswordKeyHash(const QString &pass, const QString &salt, const QString &hash, QString *hashderived=nullptr)
Verify existing master password hash to a re-generated one.
static const QString decrypt(const QString &pass, const QString &cipheriv, const QString &text)
Decrypt data using master password.
Singleton which offers an interface to manage the authentication configuration database and to utiliz...
bool storeAuthSetting(const QString &key, const QVariant &value, bool encrypt=false)
Stores an authentication setting.
bool setDefaultCertTrustPolicy(QgsAuthCertUtils::CertTrustPolicy policy)
Sets the default certificate trust policy preferred by user.
void clearAllCachedConfigs()
Clear all authentication configs from authentication method caches.
const QSslCertificate certIdentity(const QString &id)
certIdentity get a certificate identity by id (sha hash)
const QStringList certIdentityBundleToPem(const QString &id)
certIdentityBundleToPem get a certificate identity bundle by id (sha hash) returned as PEM text
bool updateIgnoredSslErrorsCache(const QString &shahostport, const QList< QSslError > &errors)
Update ignored SSL error cache with possible ignored SSL errors, using sha:host:port key.
bool verifyMasterPassword(const QString &compare=QString())
Verify the supplied master password against any existing hash in authentication database.
bool updateIgnoredSslErrorsCacheFromConfig(const QgsAuthConfigSslServer &config)
Update ignored SSL error cache with possible ignored SSL errors, using server config.
const QString disabledMessage() const
Standard message for when QCA's qca-ossl plugin is missing and system is disabled.
const QList< QSslCertificate > trustedCaCertsCache()
trustedCaCertsCache cache of trusted certificate authorities, ready for network connections
QgsAuthMethod * configAuthMethod(const QString &authcfg)
Gets authentication method from the config/provider cache.
static bool isFilesystemBasedDatabase(const QString &uri)
Returns the true if the uri is a filesystem-based database (SQLite).
bool storeCertIdentity(const QSslCertificate &cert, const QSslKey &key)
Store a certificate identity.
QgsAuthMethodsMap authMethodsMap(const QString &dataprovider=QString())
Gets available authentication methods mapped to their key.
bool rebuildIgnoredSslErrorCache()
Rebuild ignoredSSL error cache.
bool initSslCaches()
Initialize various SSL authentication caches.
const QList< QSslCertificate > extraFileCAs()
extraFileCAs extra file-based certificate authorities
bool removeAuthSetting(const QString &key)
Remove an authentication setting.
bool storeCertTrustPolicy(const QSslCertificate &cert, QgsAuthCertUtils::CertTrustPolicy policy)
Store user trust value for a certificate.
bool rebuildCaCertsCache()
Rebuild certificate authority cache.
bool scheduledAuthDatabaseErase()
Whether there is a scheduled opitonal erase of authentication database.
bool eraseAuthenticationDatabase(bool backup, QString *backuppath=nullptr)
Erase all rows from all tables in authentication database.
static bool passwordHelperEnabled()
Password helper enabled getter.
void passwordHelperMessageLog(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, Qgis::MessageLevel level=Qgis::MessageLevel::Info)
Custom logging signal to inform the user about master password <-> password manager interactions.
bool exportAuthenticationConfigsToXml(const QString &filename, const QStringList &authcfgs, const QString &password=QString())
Export authentication configurations to an XML file.
QString sqliteDatabasePath() const
Returns the path to the authentication database file or an empty string if the database is not SQLite...
Q_DECL_DEPRECATED bool init(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
init initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database
void authDatabaseChanged()
Emitted when the authentication db is significantly changed, e.g. large record removal,...
void setPasswordHelperEnabled(bool enabled)
Password helper enabled setter.
void setScheduledAuthDatabaseErase(bool scheduleErase)
Schedule an optional erase of authentication database, starting when mutex is lockable.
const QList< QgsAuthConfigSslServer > sslCertCustomConfigs()
sslCertCustomConfigs get SSL certificate custom configs
const QList< QSslCertificate > untrustedCaCerts(QList< QSslCertificate > trustedCAs=QList< QSslCertificate >())
untrustedCaCerts get list of untrusted certificate authorities
const QString uniqueConfigId() const
Gets a unique generated 7-character string to assign to as config id.
const QPair< QSslCertificate, QSslKey > certIdentityBundle(const QString &id)
Gets a certificate identity bundle by id (sha hash).
bool isDisabled() const
Whether QCA has the qca-ossl plugin, which a base run-time requirement.
QVariant authSetting(const QString &key, const QVariant &defaultValue=QVariant(), bool decrypt=false)
Returns a previously set authentication setting.
static const QString AUTH_MAN_TAG
The display name of the Authentication Manager.
QgsAuthCertUtils::CertTrustPolicy defaultCertTrustPolicy()
Gets the default certificate trust policy preferred by user.
const QByteArray trustedCaCertsPemText()
trustedCaCertsPemText get concatenated string of all trusted CA certificates
static bool hasConfigId(const QString &txt)
Returns whether a string includes an authcfg ID token.
bool removeAllAuthenticationConfigs()
Clear all authentication configs from table in database and from provider caches.
QgsAuthCertUtils::CertTrustPolicy certificateTrustPolicy(const QSslCertificate &cert)
certificateTrustPolicy get trust policy for a particular certificate cert
static bool passwordHelperLoggingEnabled()
Password helper logging enabled getter.
QgsAuthConfigurationStorageRegistry * authConfigurationStorageRegistry() const
Returns the authentication configuration storage registry.
bool rebuildCertTrustCache()
Rebuild certificate authority cache.
Q_DECL_DEPRECATED const QString authenticationDatabasePath() const
The standard authentication database file in ~/.qgis3/ or defined location.
static const QList< QSslCertificate > systemRootCAs()
systemRootCAs get root system certificate authorities
bool removeCertAuthority(const QSslCertificate &cert)
Remove a certificate authority.
const QList< QSslCertificate > trustedCaCerts(bool includeinvalid=false)
trustedCaCerts get list of all trusted CA certificates
bool existsCertAuthority(const QSslCertificate &cert)
Check if a certificate authority exists.
const QMap< QString, QSslCertificate > mappedDatabaseCAs()
mappedDatabaseCAs get sha1-mapped database-stored certificate authorities
bool importAuthenticationConfigsFromXml(const QString &filename, const QString &password=QString(), bool overwrite=false)
Import authentication configurations from an XML file.
bool configIdUnique(const QString &id) const
Verify if provided authentication id is unique.
static const QgsSettingsEntryBool * settingsGenerateRandomPasswordForPasswordHelper
QStringList configIds() const
Gets list of authentication ids from database.
QString authManTag() const
Simple text tag describing authentication system for message logs.
bool loadAuthenticationConfig(const QString &authcfg, QgsAuthMethodConfig &mconfig, bool full=false)
Load an authentication config from the database into subclass.
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy(const QSslCertificate &cert)
certTrustPolicy get whether certificate cert is trusted by user
bool masterPasswordHashInDatabase() const
Verify a password hash existing in authentication database.
Q_DECL_DEPRECATED void messageOut(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, QgsAuthManager::MessageLevel level=QgsAuthManager::INFO) const
Custom logging signal to relay to console output and QgsMessageLog.
QgsAuthConfigurationStorageDb * defaultDbStorage() const
Transitional proxy to the first ready storage of database type.
bool updateNetworkProxy(QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkProxy with an authentication config.
const QSslCertificate certAuthority(const QString &id)
Gets a certificate authority by id (sha hash).
void passwordHelperSuccess()
Signals emitted on password helper success, mainly used in the tests to exit main application loop.
bool registerCoreAuthMethods()
Instantiate and register existing C++ core authentication methods from plugins.
bool passwordHelperDelete()
Delete master password from wallet.
~QgsAuthManager() override
void dumpIgnoredSslErrorsCache_()
Utility function to dump the cache for debug purposes.
const QList< QSslCertificate > databaseCAs()
databaseCAs get database-stored certificate authorities
void messageLog(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, Qgis::MessageLevel level=Qgis::MessageLevel::Info) const
Custom logging signal to relay to console output and QgsMessageLog.
bool backupAuthenticationDatabase(QString *backuppath=nullptr)
Close connection to current authentication database and back it up.
void authDatabaseEraseRequested()
Emitted when a user has indicated they may want to erase the authentication db.
void passwordHelperFailure()
Signals emitted on password helper failure, mainly used in the tests to exit main application loop.
bool existsSslCertCustomConfig(const QString &id, const QString &hostport)
Check if SSL certificate custom config exists.
bool existsAuthSetting(const QString &key)
Check if an authentication setting exists.
void clearCachedConfig(const QString &authcfg)
Clear an authentication config from its associated authentication method cache.
void clearMasterPassword()
Clear supplied master password.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
bool createAndStoreRandomMasterPasswordInKeyChain()
Creates a new securely seeded random password and stores it in the system keychain as the new master ...
const QList< QSslCertificate > certIdentities()
certIdentities get certificate identities
bool storeCertAuthority(const QSslCertificate &cert)
Store a certificate authority.
QStringList certIdentityIds() const
certIdentityIds get list of certificate identity ids from database
bool removeCertTrustPolicies(const QList< QSslCertificate > &certs)
Remove a group certificate authorities.
QgsAuthMethod * authMethod(const QString &authMethodKey)
Gets authentication method from the config/provider cache via its key.
bool updateDataSourceUriItems(QStringList &connectionItems, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QgsDataSourceUri with an authentication config.
void setup(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
Sets up the authentication manager configuration.
const QString passwordHelperErrorMessage()
Error message getter.
Q_DECL_DEPRECATED QSqlDatabase authDatabaseConnection() const
Sets up the application instance of the authentication database connection.
void updateConfigAuthMethods()
Sync the confg/authentication method cache with what is in database.
bool storeSslCertCustomConfig(const QgsAuthConfigSslServer &config)
Store an SSL certificate custom config.
static void setPasswordHelperLoggingEnabled(bool enabled)
Password helper logging enabled setter.
bool ensureInitialized() const
Performs lazy initialization of the authentication framework, if it has not already been done.
const QgsAuthConfigSslServer sslCertCustomConfigByHost(const QString &hostport)
sslCertCustomConfigByHost get an SSL certificate custom config by hostport (host:port)
bool updateAuthenticationConfig(const QgsAuthMethodConfig &config)
Update an authentication config in the database.
bool existsCertIdentity(const QString &id)
Check if a certificate identity exists.
const QString authenticationDatabaseUri() const
Returns the authentication database connection URI.
static const QgsSettingsEntryBool * settingsUsingGeneratedRandomPassword
bool resetMasterPassword(const QString &newpass, const QString &oldpass, bool keepbackup, QString *backuppath=nullptr)
Reset the master password to a new one, then re-encrypts all previous configs with the new password.
QStringList authMethodsKeys(const QString &dataprovider=QString())
Gets keys of supported authentication methods.
bool passwordHelperSync()
Store the password manager into the wallet.
bool masterPasswordIsSet() const
Whether master password has be input and verified, i.e. authentication database is accessible.
const QString methodConfigTableName() const
Returns the database table from the first ready storage that stores authentication configs,...
static QgsAuthManager * instance()
Enforce singleton pattern.
void masterPasswordVerified(bool verified)
Emitted when a password has been verify (or not).
bool setMasterPassword(bool verify=false)
Main call to initially set or continually check master password is set.
bool storeCertAuthorities(const QList< QSslCertificate > &certs)
Store multiple certificate authorities.
bool removeSslCertCustomConfig(const QString &id, const QString &hostport)
Remove an SSL certificate custom config.
bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkReply with an authentication config (used to skip known SSL errors,...
bool rebuildTrustedCaCertsCache()
Rebuild trusted certificate authorities cache.
const QgsAuthMethodMetadata * authMethodMetadata(const QString &authMethodKey)
Gets authentication method metadata via its key.
bool removeAuthenticationConfig(const QString &authcfg)
Remove an authentication config in the database.
bool removeCertTrustPolicy(const QSslCertificate &cert)
Remove a certificate authority.
const QString authenticationDatabaseUriStripped() const
Returns the authentication database connection URI with the password stripped.
QgsAuthMethod::Expansions supportedAuthMethodExpansions(const QString &authcfg)
Gets supported authentication method expansion(s), e.g.
const QgsAuthConfigSslServer sslCertCustomConfig(const QString &id, const QString &hostport)
sslCertCustomConfig get an SSL certificate custom config by id (sha hash) and hostport (host:port)
QgsAuthMethodConfigsMap availableAuthMethodConfigs(const QString &dataprovider=QString())
Gets mapping of authentication config ids and their base configs (not decrypted data).
bool masterPasswordSame(const QString &password) const
Check whether supplied password is the same as the one already set.
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME
The display name of the password helper (platform dependent).
bool storeAuthenticationConfig(QgsAuthMethodConfig &mconfig, bool overwrite=false)
Store an authentication config in the database.
bool verifyStoredPasswordHelperPassword()
Verify the password stored in the password helper.
bool removeCertIdentity(const QString &id)
Remove a certificate identity.
static QString passwordHelperDisplayName(bool titleCase=false)
Returns a translated display name of the password helper (platform dependent).
bool resetMasterPasswordUsingStoredPasswordHelper(const QString &newPassword, bool keepBackup, QString *backupPath=nullptr)
Reset the master password to a new one, hen re-encrypts all previous configs with the new password.
QString configAuthMethodKey(const QString &authcfg) const
Gets key of authentication method associated with config ID.
Configuration storage class for authentication method configurations.
bool isValid(bool validateid=false) const
Whether the configuration is valid.
bool readXml(const QDomElement &element)
from a DOM element.
const QString configString() const
The extended configuration, as stored and retrieved from the authentication database.
const QString id() const
Gets 'authcfg' 7-character alphanumeric ID of the config.
void loadConfigString(const QString &configstr)
Load existing extended configuration.
bool writeXml(QDomElement &parentElement, QDomDocument &document)
Stores the configuration in a DOM.
void setId(const QString &id)
Sets auth config ID.
const QgsAuthMethodMetadata * authMethodMetadata(const QString &authMethodKey) const
Returns metadata of the auth method or nullptr if not found.
static QgsAuthMethodRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QStringList authMethodList() const
Returns list of available auth methods by their keys.
Abstract base class for authentication method plugins.
virtual bool updateNetworkProxy(QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider=QString())
Update proxy settings with authentication components.
virtual bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Update a network request with authentication components.
QgsAuthMethod::Expansions supportedExpansions() const
Flags that represent the update points (where authentication configurations are expanded) supported b...
virtual void clearCachedConfig(const QString &authcfg)=0
Clear any cached configuration.
virtual void updateMethodConfig(QgsAuthMethodConfig &mconfig)=0
Update an authentication configuration in place.
virtual bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Update a network reply with authentication components.
virtual bool updateDataSourceUriItems(QStringList &connectionItems, const QString &authcfg, const QString &dataprovider=QString())
Update data source connection items with authentication components.
QFlags< Expansion > Expansions
static QgsCredentials * instance()
retrieves instance
bool getMasterPassword(QString &password, bool stored=false)
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
Custom exception class which is raised when an operation is not supported.
Scoped object for logging of the runtime for a single operation or group of operations.
A boolean settings entry.
static QgsSettingsTreeNode * sTreeAuthentication
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
QHash< QString, QgsAuthMethodConfig > QgsAuthMethodConfigsMap
QHash< QString, QgsAuthMethod * > QgsAuthMethodsMap
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)