LCOV - code coverage report
Current view: top level - core/auth - qgsauthmanager.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 2 14 14.3 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsauthmanager.h
       3                 :            :     ---------------------
       4                 :            :     begin                : October 5, 2014
       5                 :            :     copyright            : (C) 2014 by Boundless Spatial, Inc. USA
       6                 :            :     author               : Larry Shaffer
       7                 :            :     email                : lshaffer at boundlessgeo dot com
       8                 :            :  ***************************************************************************
       9                 :            :  *                                                                         *
      10                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      11                 :            :  *   it under the terms of the GNU General Public License as published by  *
      12                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      13                 :            :  *   (at your option) any later version.                                   *
      14                 :            :  *                                                                         *
      15                 :            :  ***************************************************************************/
      16                 :            : 
      17                 :            : #ifndef QGSAUTHMANAGER_H
      18                 :            : #define QGSAUTHMANAGER_H
      19                 :            : 
      20                 :            : #include "qgis_core.h"
      21                 :            : #include "qgis_sip.h"
      22                 :            : #include <QObject>
      23                 :            : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
      24                 :            : #include <QMutex>
      25                 :            : #else
      26                 :            : #include <QRecursiveMutex>
      27                 :            : #endif
      28                 :            : #include <QNetworkReply>
      29                 :            : #include <QNetworkRequest>
      30                 :            : #include <QSqlDatabase>
      31                 :            : #include <QSqlError>
      32                 :            : #include <QSqlQuery>
      33                 :            : #include <QStringList>
      34                 :            : 
      35                 :            : #ifndef QT_NO_SSL
      36                 :            : #include <QSslCertificate>
      37                 :            : #include <QSslKey>
      38                 :            : #include <QtCrypto>
      39                 :            : #include "qgsauthcertutils.h"
      40                 :            : #endif
      41                 :            : 
      42                 :            : #include "qgsauthconfig.h"
      43                 :            : #include "qgsauthmethod.h"
      44                 :            : 
      45                 :            : // Qt5KeyChain library
      46                 :            : #include "keychain.h"
      47                 :            : 
      48                 :            : #ifndef SIP_RUN
      49                 :            : namespace QCA
      50                 :            : {
      51                 :            :   class Initializer;
      52                 :            : }
      53                 :            : #endif
      54                 :            : class QgsAuthMethod;
      55                 :            : class QgsAuthMethodEdit;
      56                 :            : class QgsAuthProvider;
      57                 :            : class QTimer;
      58                 :            : 
      59                 :            : 
      60                 :            : /**
      61                 :            :  * \ingroup core
      62                 :            :  * \brief Singleton offering an interface to manage the authentication configuration database
      63                 :            :  * and to utilize configurations through various authentication method plugins
      64                 :            :  *
      65                 :            :  * QgsAuthManager should not usually be directly created, but rather accessed through
      66                 :            :  * QgsApplication::authManager().
      67                 :            :  */
      68                 :            : class CORE_EXPORT QgsAuthManager : public QObject
      69                 :            : {
      70                 :          6 :     Q_OBJECT
      71                 :            : 
      72                 :            :   public:
      73                 :            : 
      74                 :            :     //! Message log level (mirrors that of QgsMessageLog, so it can also output there)
      75                 :            :     enum MessageLevel
      76                 :            :     {
      77                 :            :       INFO = 0,
      78                 :            :       WARNING = 1,
      79                 :            :       CRITICAL = 2
      80                 :            :     };
      81                 :         15 :     Q_ENUM( MessageLevel )
      82                 :            : 
      83                 :            :     /**
      84                 :            :      * \brief init initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database
      85                 :            :      * \param pluginPath the plugin path
      86                 :            :      * \param authDatabasePath the authentication DB path
      87                 :            :      * \return TRUE on success
      88                 :            :      * \see QgsApplication::pluginPath
      89                 :            :      * \see QgsApplication::qgisAuthDatabaseFilePath
      90                 :            :      */
      91                 :            :     bool init( const QString &pluginPath = QString(),  const QString &authDatabasePath = QString() );
      92                 :            : 
      93                 :            :     ~QgsAuthManager() override;
      94                 :            : 
      95                 :            :     //! Sets up the application instance of the authentication database connection
      96                 :            :     QSqlDatabase authDatabaseConnection() const;
      97                 :            : 
      98                 :            :     //! Name of the authentication database table that stores configs
      99                 :          0 :     const QString authDatabaseConfigTable() const { return AUTH_CONFIG_TABLE; }
     100                 :            : 
     101                 :            :     //! Name of the authentication database table that stores server exceptions/configs
     102                 :          0 :     const QString authDatabaseServersTable() const { return AUTH_SERVERS_TABLE; }
     103                 :            : 
     104                 :            : 
     105                 :            :     //! Whether QCA has the qca-ossl plugin, which a base run-time requirement
     106                 :            :     bool isDisabled() const;
     107                 :            : 
     108                 :            :     //! Standard message for when QCA's qca-ossl plugin is missing and system is disabled
     109                 :            :     const QString disabledMessage() const;
     110                 :            : 
     111                 :            :     /**
     112                 :            :      * The standard authentication database file in ~/.qgis3/ or defined location
     113                 :            :      * \see QgsApplication::qgisAuthDatabaseFilePath
     114                 :            :      */
     115                 :          0 :     const QString authenticationDatabasePath() const { return mAuthDbPath; }
     116                 :            : 
     117                 :            :     /**
     118                 :            :      * Main call to initially set or continually check master password is set
     119                 :            :      * \note If it is not set, the user is asked for its input
     120                 :            :      * \param verify Whether password's hash was saved in authentication database
     121                 :            :      */
     122                 :            :     bool setMasterPassword( bool verify = false );
     123                 :            : 
     124                 :            :     /**
     125                 :            :      * Overloaded call to reset master password or set it initially without user interaction
     126                 :            :      * \note Only use this in trusted reset functions, unit tests or user/app setup scripts!
     127                 :            :      * \param pass Password to use
     128                 :            :      * \param verify Whether password's hash was saved in authentication database
     129                 :            :      */
     130                 :            :     bool setMasterPassword( const QString &pass, bool verify = false );
     131                 :            : 
     132                 :            :     /**
     133                 :            :      * Verify the supplied master password against any existing hash in authentication database
     134                 :            :      * \note Do not emit verification signals when only comparing
     135                 :            :      * \param compare Password to compare against
     136                 :            :      */
     137                 :            :     bool verifyMasterPassword( const QString &compare = QString() );
     138                 :            : 
     139                 :            :     //! Whether master password has be input and verified, i.e. authentication database is accessible
     140                 :            :     bool masterPasswordIsSet() const;
     141                 :            : 
     142                 :            :     //! Verify a password hash existing in authentication database
     143                 :            :     bool masterPasswordHashInDatabase() const;
     144                 :            : 
     145                 :            :     /**
     146                 :            :      * Clear supplied master password
     147                 :            :      * \note This will not necessarily clear authenticated connections cached in network connection managers
     148                 :            :      */
     149                 :          0 :     void clearMasterPassword() { mMasterPass = QString(); }
     150                 :            : 
     151                 :            :     /**
     152                 :            :      * Check whether supplied password is the same as the one already set
     153                 :            :      * \param pass Password to verify
     154                 :            :      */
     155                 :            :     bool masterPasswordSame( const QString &pass ) const;
     156                 :            : 
     157                 :            :     /**
     158                 :            :      * Reset the master password to a new one, then re-encrypt all previous
     159                 :            :      * configs in a new database file, optionally backup curren database
     160                 :            :      * \param newpass New master password to replace existing
     161                 :            :      * \param oldpass Current master password to replace existing
     162                 :            :      * \param keepbackup Whether to keep the generated backup of current database
     163                 :            :      * \param backuppath Where the backup is located, if kept
     164                 :            :      */
     165                 :            :     bool resetMasterPassword( const QString &newpass, const QString &oldpass, bool keepbackup, QString *backuppath SIP_INOUT = nullptr );
     166                 :            : 
     167                 :            :     /**
     168                 :            :      * Whether there is a scheduled opitonal erase of authentication database.
     169                 :            :      * \note not available in Python bindings
     170                 :            :      */
     171                 :          0 :     bool scheduledAuthDatabaseErase() { return mScheduledDbErase; } SIP_SKIP
     172                 :            : 
     173                 :            :     /**
     174                 :            :      * Schedule an optional erase of authentication database, starting when mutex is lockable.
     175                 :            :      * \note When an erase is scheduled, any attempt to set the master password,
     176                 :            :      * e.g. password input dialog, is effectively canceled.
     177                 :            :      * For example: In a GUI app, this keeps excess password input dialogs from popping
     178                 :            :      * up when a user has initiated an erase, from a password input dialog, because
     179                 :            :      * they forgot their password.
     180                 :            :      * The created schedule timer will emit a request to gain access to the user,
     181                 :            :      * through the given application, to prompt the erase operation (e.g. via a dialog);
     182                 :            :      * if no access to user interaction occurs within 90 seconds, it cancels the schedule.
     183                 :            :      * \note not available in Python bindings
     184                 :            :      */
     185                 :            :     void setScheduledAuthDatabaseErase( bool scheduleErase ) SIP_SKIP;
     186                 :            : 
     187                 :            :     /**
     188                 :            :      * Re-emit a signal to schedule an optional erase of authentication database.
     189                 :            :      * \note This can be called from the slot connected to a previously emitted scheduling signal,
     190                 :            :      * so that the slot can ask for another emit later, if the slot noticies the current GUI
     191                 :            :      * processing state is not ready for interacting with the user, e.g. project is still loading
     192                 :            :      * \param emitted Setting to FALSE will cause signal to be emitted by the schedule timer.
     193                 :            :      * Setting to TRUE will stop any emitting, but will not stop the schedule timer.
     194                 :            :      */
     195                 :            :     void setScheduledAuthDatabaseEraseRequestEmitted( bool emitted ) { mScheduledDbEraseRequestEmitted = emitted; }
     196                 :            : 
     197                 :            :     //! Simple text tag describing authentication system for message logs
     198                 :          0 :     QString authManTag() const { return AUTH_MAN_TAG; }
     199                 :            : 
     200                 :            :     //! Instantiate and register existing C++ core authentication methods from plugins
     201                 :            :     bool registerCoreAuthMethods();
     202                 :            : 
     203                 :            :     //! Gets mapping of authentication config ids and their base configs (not decrypted data)
     204                 :            :     QgsAuthMethodConfigsMap availableAuthMethodConfigs( const QString &dataprovider = QString() );
     205                 :            : 
     206                 :            :     //! Sync the confg/authentication method cache with what is in database
     207                 :            :     void updateConfigAuthMethods();
     208                 :            : 
     209                 :            :     /**
     210                 :            :      * Gets authentication method from the config/provider cache
     211                 :            :      * \param authcfg Authentication config id
     212                 :            :      */
     213                 :            :     QgsAuthMethod *configAuthMethod( const QString &authcfg );
     214                 :            : 
     215                 :            :     /**
     216                 :            :      * Gets key of authentication method associated with config ID
     217                 :            :      * \param authcfg
     218                 :            :      */
     219                 :            :     QString configAuthMethodKey( const QString &authcfg ) const;
     220                 :            : 
     221                 :            :     /**
     222                 :            :      * Gets keys of supported authentication methods
     223                 :            :      */
     224                 :            :     QStringList authMethodsKeys( const QString &dataprovider = QString() );
     225                 :            : 
     226                 :            :     /**
     227                 :            :      * Gets authentication method from the config/provider cache via its key
     228                 :            :      * \param authMethodKey Authentication method key
     229                 :            :      */
     230                 :            :     QgsAuthMethod *authMethod( const QString &authMethodKey );
     231                 :            : 
     232                 :            :     /**
     233                 :            :      * Gets available authentication methods mapped to their key
     234                 :            :      * \param dataprovider Provider key filter, returning only methods that support a particular provider
     235                 :            :      * \note not available in Python bindings
     236                 :            :      */
     237                 :            :     QgsAuthMethodsMap authMethodsMap( const QString &dataprovider = QString() ) SIP_SKIP;
     238                 :            : 
     239                 :            :     /**
     240                 :            :      * Gets authentication method edit widget via its key
     241                 :            :      * \param authMethodKey Authentication method key
     242                 :            :      * \param parent Parent widget
     243                 :            :      */
     244                 :            :     QWidget *authMethodEditWidget( const QString &authMethodKey, QWidget *parent );
     245                 :            : 
     246                 :            :     /**
     247                 :            :      * Gets supported authentication method expansion(s), e.g. NetworkRequest | DataSourceURI, as flags
     248                 :            :      * \param authcfg
     249                 :            :      */
     250                 :            :     QgsAuthMethod::Expansions supportedAuthMethodExpansions( const QString &authcfg );
     251                 :            : 
     252                 :            :     //! Gets a unique generated 7-character string to assign to as config id
     253                 :            :     const QString uniqueConfigId() const;
     254                 :            : 
     255                 :            :     /**
     256                 :            :      * Verify if provided authentication id is unique
     257                 :            :      * \param id Id to check
     258                 :            :      */
     259                 :            :     bool configIdUnique( const QString &id ) const;
     260                 :            : 
     261                 :            :     /**
     262                 :            :      * Returns whether a string includes an authcfg ID token
     263                 :            :      * \param txt String to check
     264                 :            :      */
     265                 :            :     bool hasConfigId( const QString &txt ) const;
     266                 :            : 
     267                 :            :     //! Returns the regular expression for authcfg=.{7} key/value token for authentication ids
     268                 :            :     QString configIdRegex() const { return AUTH_CFG_REGEX;}
     269                 :            : 
     270                 :            :     //! Gets list of authentication ids from database
     271                 :            :     QStringList configIds() const;
     272                 :            : 
     273                 :            :     /**
     274                 :            :      * Store an authentication config in the database
     275                 :            :      * \param mconfig Associated authentication config id
     276                 :            :      * \returns Whether operation succeeded
     277                 :            :      */
     278                 :            :     bool storeAuthenticationConfig( QgsAuthMethodConfig &mconfig SIP_INOUT );
     279                 :            : 
     280                 :            :     /**
     281                 :            :      * Update an authentication config in the database
     282                 :            :      * \param config Associated authentication config id
     283                 :            :      * \returns Whether operation succeeded
     284                 :            :      */
     285                 :            :     bool updateAuthenticationConfig( const QgsAuthMethodConfig &config );
     286                 :            : 
     287                 :            :     /**
     288                 :            :      * Load an authentication config from the database into subclass
     289                 :            :      * \param authcfg Associated authentication config id
     290                 :            :      * \param mconfig Subclassed config to load into
     291                 :            :      * \param full Whether to decrypt and populate all sensitive data in subclass
     292                 :            :      * \returns Whether operation succeeded
     293                 :            :      */
     294                 :            :     bool loadAuthenticationConfig( const QString &authcfg, QgsAuthMethodConfig &mconfig SIP_INOUT, bool full = false );
     295                 :            : 
     296                 :            :     /**
     297                 :            :      * Remove an authentication config in the database
     298                 :            :      * \param authcfg Associated authentication config id
     299                 :            :      * \returns Whether operation succeeded
     300                 :            :      */
     301                 :            :     bool removeAuthenticationConfig( const QString &authcfg );
     302                 :            : 
     303                 :            :     /**
     304                 :            :      * Clear all authentication configs from table in database and from provider caches
     305                 :            :      * \returns Whether operation succeeded
     306                 :            :      */
     307                 :            :     bool removeAllAuthenticationConfigs();
     308                 :            : 
     309                 :            :     /**
     310                 :            :      * Close connection to current authentication database and back it up
     311                 :            :      * \returns Path to backup
     312                 :            :      */
     313                 :            :     bool backupAuthenticationDatabase( QString *backuppath SIP_INOUT = nullptr );
     314                 :            : 
     315                 :            :     /**
     316                 :            :      * Erase all rows from all tables in authentication database
     317                 :            :      * \param backup Whether to backup of current database
     318                 :            :      * \param backuppath Where the backup is locate
     319                 :            :      * \returns Whether operation succeeded
     320                 :            :      */
     321                 :            :     bool eraseAuthenticationDatabase( bool backup, QString *backuppath SIP_INOUT = nullptr );
     322                 :            : 
     323                 :            : 
     324                 :            :     ////////////////// Auth Method calls ///////////////////////
     325                 :            : 
     326                 :            :     /**
     327                 :            :      * Provider call to update a QNetworkRequest with an authentication config
     328                 :            :      * \param request The QNetworkRequest
     329                 :            :      * \param authcfg Associated authentication config id
     330                 :            :      * \param dataprovider Provider key filter, offering logic branching in authentication method
     331                 :            :      * \returns Whether operation succeeded
     332                 :            :      */
     333                 :            :     bool updateNetworkRequest( QNetworkRequest &request SIP_INOUT, const QString &authcfg,
     334                 :            :                                const QString &dataprovider = QString() );
     335                 :            : 
     336                 :            :     /**
     337                 :            :      * Provider call to update a QNetworkReply with an authentication config (used to skip known SSL errors, etc.)
     338                 :            :      * \param reply The QNetworkReply
     339                 :            :      * \param authcfg Associated authentication config id
     340                 :            :      * \param dataprovider Provider key filter, offering logic branching in authentication method
     341                 :            :      * \returns Whether operation succeeded
     342                 :            :      */
     343                 :            :     bool updateNetworkReply( QNetworkReply *reply, const QString &authcfg,
     344                 :            :                              const QString &dataprovider = QString() );
     345                 :            : 
     346                 :            :     /**
     347                 :            :      * Provider call to update a QgsDataSourceUri with an authentication config
     348                 :            :      * \param connectionItems The connection items, e.g. username=myname, of QgsDataSourceUri
     349                 :            :      * \param authcfg Associated authentication config id
     350                 :            :      * \param dataprovider Provider key filter, offering logic branching in authentication method
     351                 :            :      * \returns Whether operation succeeded
     352                 :            :      */
     353                 :            :     bool updateDataSourceUriItems( QStringList &connectionItems SIP_INOUT, const QString &authcfg,
     354                 :            :                                    const QString &dataprovider = QString() );
     355                 :            : 
     356                 :            :     /**
     357                 :            :      * Provider call to update a QNetworkProxy with an authentication config
     358                 :            :      * \param proxy the QNetworkProxy
     359                 :            :      * \param authcfg Associated authentication config id
     360                 :            :      * \param dataprovider Provider key filter, offering logic branching in authentication method
     361                 :            :      * \returns Whether operation succeeded
     362                 :            :      */
     363                 :            :     bool updateNetworkProxy( QNetworkProxy &proxy SIP_INOUT, const QString &authcfg,
     364                 :            :                              const QString &dataprovider = QString() );
     365                 :            : 
     366                 :            :     ////////////////// Generic settings ///////////////////////
     367                 :            : 
     368                 :            :     //! Store an authentication setting (stored as string via QVariant( value ).toString() )
     369                 :            :     bool storeAuthSetting( const QString &key, const QVariant &value, bool encrypt = false );
     370                 :            : 
     371                 :            :     /**
     372                 :            :      * \brief authSetting get an authentication setting (retrieved as string and returned as QVariant( QString ))
     373                 :            :      * \param key setting key
     374                 :            :      * \param defaultValue
     375                 :            :      * \param decrypt if the value needs decrypted
     376                 :            :      * \return QVariant( QString ) authentication setting
     377                 :            :      * \since QGIS 3.0
     378                 :            :      */
     379                 :            :     QVariant authSetting( const QString &key, const QVariant &defaultValue = QVariant(), bool decrypt = false );
     380                 :            : 
     381                 :            :     //! Check if an authentication setting exists
     382                 :            :     bool existsAuthSetting( const QString &key );
     383                 :            : 
     384                 :            :     //! Remove an authentication setting
     385                 :            :     bool removeAuthSetting( const QString &key );
     386                 :            : 
     387                 :            : #ifndef QT_NO_SSL
     388                 :            :     ////////////////// Certificate calls ///////////////////////
     389                 :            : 
     390                 :            :     //! Initialize various SSL authentication caches
     391                 :            :     bool initSslCaches();
     392                 :            : 
     393                 :            :     //! Store a certificate identity
     394                 :            :     bool storeCertIdentity( const QSslCertificate &cert, const QSslKey &key );
     395                 :            : 
     396                 :            :     /**
     397                 :            :      * \brief certIdentity get a certificate identity by \a id (sha hash)
     398                 :            :      * \param id sha hash of the cert
     399                 :            :      * \return the certificate
     400                 :            :      * \since QGIS 3.0
     401                 :            :      */
     402                 :            :     const QSslCertificate certIdentity( const QString &id );
     403                 :            : 
     404                 :            :     /**
     405                 :            :      * Gets a certificate identity bundle by \a id (sha hash).
     406                 :            :      * \param id sha shash
     407                 :            :      * \return a pair with the certificate and its SSL key
     408                 :            :      * \note not available in Python bindings
     409                 :            :      * \since QGIS 3.0
     410                 :            :      */
     411                 :            :     const QPair<QSslCertificate, QSslKey> certIdentityBundle( const QString &id ) SIP_SKIP;
     412                 :            : 
     413                 :            :     /**
     414                 :            :      * \brief certIdentityBundleToPem get a certificate identity bundle by \a id (sha hash) returned as PEM text
     415                 :            :      * \param id sha hash
     416                 :            :      * \return a list of strings
     417                 :            :      * \since QGIS 3.0
     418                 :            :      */
     419                 :            :     const QStringList certIdentityBundleToPem( const QString &id );
     420                 :            : 
     421                 :            :     /**
     422                 :            :      * \brief certIdentities get certificate identities
     423                 :            :      * \return list of certificates
     424                 :            :      * \since QGIS 3.0
     425                 :            :      */
     426                 :            :     const QList<QSslCertificate> certIdentities();
     427                 :            : 
     428                 :            :     //!
     429                 :            : 
     430                 :            :     /**
     431                 :            :      * \brief certIdentityIds get list of certificate identity ids from database
     432                 :            :      * \return list of certificate ids
     433                 :            :      * \since QGIS 3.0
     434                 :            :      */
     435                 :            :     QStringList certIdentityIds() const;
     436                 :            : 
     437                 :            :     //! Check if a certificate identity exists
     438                 :            :     bool existsCertIdentity( const QString &id );
     439                 :            : 
     440                 :            :     //! Remove a certificate identity
     441                 :            :     bool removeCertIdentity( const QString &id );
     442                 :            : 
     443                 :            : 
     444                 :            :     //! Store an SSL certificate custom config
     445                 :            :     bool storeSslCertCustomConfig( const QgsAuthConfigSslServer &config );
     446                 :            : 
     447                 :            :     /**
     448                 :            :      * \brief sslCertCustomConfig get an SSL certificate custom config by \a id (sha hash) and \a hostport (host:port)
     449                 :            :      * \param id sha hash
     450                 :            :      * \param hostport string host:port
     451                 :            :      * \return a SSL certificate custom config
     452                 :            :      * \since QGIS 3.0
     453                 :            :      */
     454                 :            :     const QgsAuthConfigSslServer sslCertCustomConfig( const QString &id, const QString &hostport );
     455                 :            : 
     456                 :            :     /**
     457                 :            :      * \brief sslCertCustomConfigByHost get an SSL certificate custom config by \a hostport (host:port)
     458                 :            :      * \param hostport host:port
     459                 :            :      * \return a SSL certificate custom config
     460                 :            :      * \since QGIS 3.0
     461                 :            :      */
     462                 :            :     const QgsAuthConfigSslServer sslCertCustomConfigByHost( const QString &hostport );
     463                 :            : 
     464                 :            :     /**
     465                 :            :      * \brief sslCertCustomConfigs get SSL certificate custom configs
     466                 :            :      * \return list of SSL certificate custom config
     467                 :            :      * \since QGIS 3.0
     468                 :            :      */
     469                 :            :     const QList<QgsAuthConfigSslServer> sslCertCustomConfigs();
     470                 :            : 
     471                 :            :     //! Check if SSL certificate custom config exists
     472                 :            :     bool existsSslCertCustomConfig( const QString &id, const QString &hostport );
     473                 :            : 
     474                 :            :     //! Remove an SSL certificate custom config
     475                 :            :     bool removeSslCertCustomConfig( const QString &id, const QString &hostport );
     476                 :            : 
     477                 :            :     /**
     478                 :            :      * \brief ignoredSslErrorCache Get ignored SSL error cache, keyed with cert/connection's sha:host:port.
     479                 :            :      * \return hash keyed with cert/connection's sha:host:port.
     480                 :            :      * \note not available in Python bindings
     481                 :            :      * \since QGIS 3.0
     482                 :            :      */
     483                 :            :     QHash<QString, QSet<QSslError::SslError> > ignoredSslErrorCache() { return mIgnoredSslErrorsCache; } SIP_SKIP
     484                 :            : 
     485                 :            :     //! Utility function to dump the cache for debug purposes
     486                 :            :     void dumpIgnoredSslErrorsCache_();
     487                 :            : 
     488                 :            :     //! Update ignored SSL error cache with possible ignored SSL errors, using server config
     489                 :            :     bool updateIgnoredSslErrorsCacheFromConfig( const QgsAuthConfigSslServer &config );
     490                 :            : 
     491                 :            :     //! Update ignored SSL error cache with possible ignored SSL errors, using sha:host:port key
     492                 :            :     bool updateIgnoredSslErrorsCache( const QString &shahostport, const QList<QSslError> &errors );
     493                 :            : 
     494                 :            :     //! Rebuild ignoredSSL error cache
     495                 :            :     bool rebuildIgnoredSslErrorCache();
     496                 :            : 
     497                 :            : 
     498                 :            :     //! Store multiple certificate authorities
     499                 :            :     bool storeCertAuthorities( const QList<QSslCertificate> &certs );
     500                 :            : 
     501                 :            :     //! Store a certificate authority
     502                 :            :     bool storeCertAuthority( const QSslCertificate &cert );
     503                 :            : 
     504                 :            :     //! Gets a certificate authority by id (sha hash)
     505                 :            : 
     506                 :            :     /**
     507                 :            :      * \brief certAuthority get a certificate authority by \a id (sha hash)
     508                 :            :      * \param id sha hash
     509                 :            :      * \return a certificate
     510                 :            :      * \since QGIS 3.0
     511                 :            :      */
     512                 :            :     const QSslCertificate certAuthority( const QString &id );
     513                 :            : 
     514                 :            :     //! Check if a certificate authority exists
     515                 :            :     bool existsCertAuthority( const QSslCertificate &cert );
     516                 :            : 
     517                 :            :     //! Remove a certificate authority
     518                 :            :     bool removeCertAuthority( const QSslCertificate &cert );
     519                 :            : 
     520                 :            :     /**
     521                 :            :      * \brief systemRootCAs get root system certificate authorities
     522                 :            :      * \return list of certificate authorities
     523                 :            :      * \since QGIS 3.0
     524                 :            :      */
     525                 :            :     const QList<QSslCertificate> systemRootCAs();
     526                 :            : 
     527                 :            :     /**
     528                 :            :      * \brief extraFileCAs extra file-based certificate authorities
     529                 :            :      * \return list of certificate authorities
     530                 :            :      * \since QGIS 3.0
     531                 :            :      */
     532                 :            :     const QList<QSslCertificate> extraFileCAs();
     533                 :            : 
     534                 :            :     /**
     535                 :            :      * \brief databaseCAs get database-stored certificate authorities
     536                 :            :      * \return list of certificate authorities
     537                 :            :      * \since QGIS 3.0
     538                 :            :      */
     539                 :            :     const QList<QSslCertificate> databaseCAs();
     540                 :            : 
     541                 :            :     /**
     542                 :            :      * \brief mappedDatabaseCAs get sha1-mapped database-stored certificate authorities
     543                 :            :      * \return sha1-mapped certificate authorities
     544                 :            :      * \since QGIS 3.0
     545                 :            :      */
     546                 :            :     const QMap<QString, QSslCertificate> mappedDatabaseCAs();
     547                 :            : 
     548                 :            :     /**
     549                 :            :      * \brief caCertsCache get all CA certs mapped to their sha1 from cache.
     550                 :            :      * \return map of sha1 <source, certificates>
     551                 :            :      * \note not available in Python bindings
     552                 :            :      * \since QGIS 3.0
     553                 :            :      */
     554                 :            :     const QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > caCertsCache() SIP_SKIP
     555                 :            :     {
     556                 :            :       return mCaCertsCache;
     557                 :            :     }
     558                 :            : 
     559                 :            :     //! Rebuild certificate authority cache
     560                 :            :     bool rebuildCaCertsCache();
     561                 :            : 
     562                 :            :     //! Store user trust value for a certificate
     563                 :            :     bool storeCertTrustPolicy( const QSslCertificate &cert, QgsAuthCertUtils::CertTrustPolicy policy );
     564                 :            : 
     565                 :            :     /**
     566                 :            :      * \brief certTrustPolicy get whether certificate \a cert is trusted by user
     567                 :            :      * \param cert
     568                 :            :      * \return DefaultTrust if certificate sha not in trust table, i.e. follows default trust policy
     569                 :            :      * \since QGIS 3.0
     570                 :            :      */
     571                 :            :     QgsAuthCertUtils::CertTrustPolicy certTrustPolicy( const QSslCertificate &cert );
     572                 :            : 
     573                 :            :     //! Remove a group certificate authorities
     574                 :            :     bool removeCertTrustPolicies( const QList<QSslCertificate> &certs );
     575                 :            : 
     576                 :            :     //! Remove a certificate authority
     577                 :            :     bool removeCertTrustPolicy( const QSslCertificate &cert );
     578                 :            : 
     579                 :            :     /**
     580                 :            :      * \brief certificateTrustPolicy get trust policy for a particular certificate \a cert
     581                 :            :      * \param cert
     582                 :            :      * \return DefaultTrust if certificate sha not in trust table, i.e. follows default trust policy
     583                 :            :      * \since QGIS 3.0
     584                 :            :      */
     585                 :            :     QgsAuthCertUtils::CertTrustPolicy certificateTrustPolicy( const QSslCertificate &cert );
     586                 :            : 
     587                 :            :     //! Sets the default certificate trust policy preferred by user
     588                 :            :     bool setDefaultCertTrustPolicy( QgsAuthCertUtils::CertTrustPolicy policy );
     589                 :            : 
     590                 :            :     //! Gets the default certificate trust policy preferred by user
     591                 :            :     QgsAuthCertUtils::CertTrustPolicy defaultCertTrustPolicy();
     592                 :            : 
     593                 :            :     /**
     594                 :            :      * \brief certTrustCache get cache of certificate sha1s, per trust policy
     595                 :            :      * \return trust-policy-mapped certificate sha1s
     596                 :            :      * \since QGIS 3.0
     597                 :            :      */
     598                 :            :     const QMap<QgsAuthCertUtils::CertTrustPolicy, QStringList > certTrustCache() { return mCertTrustCache; }
     599                 :            : 
     600                 :            :     //! Rebuild certificate authority cache
     601                 :            :     bool rebuildCertTrustCache();
     602                 :            : 
     603                 :            :     /**
     604                 :            :      * \brief trustedCaCerts get list of all trusted CA certificates
     605                 :            :      * \param includeinvalid whether invalid certs needs to be returned
     606                 :            :      * \return list of certificates
     607                 :            :      * \since QGIS 3.0
     608                 :            :      */
     609                 :            :     const QList<QSslCertificate> trustedCaCerts( bool includeinvalid = false );
     610                 :            : 
     611                 :            :     /**
     612                 :            :      * \brief untrustedCaCerts get list of untrusted certificate authorities
     613                 :            :      * \return list of certificates
     614                 :            :      * \since QGIS 3.0
     615                 :            :      */
     616                 :            :     const QList<QSslCertificate> untrustedCaCerts( QList<QSslCertificate> trustedCAs = QList<QSslCertificate>() );
     617                 :            : 
     618                 :            :     //! Rebuild trusted certificate authorities cache
     619                 :            :     bool rebuildTrustedCaCertsCache();
     620                 :            : 
     621                 :            :     /**
     622                 :            :      * \brief trustedCaCertsCache cache of trusted certificate authorities, ready for network connections
     623                 :            :      * \return list of certificates
     624                 :            :      * \since QGIS 3.0
     625                 :            :      */
     626                 :          0 :     const QList<QSslCertificate> trustedCaCertsCache() { return mTrustedCaCertsCache; }
     627                 :            : 
     628                 :            :     /**
     629                 :            :      * \brief trustedCaCertsPemText get concatenated string of all trusted CA certificates
     630                 :            :      * \return bye array with all PEM encoded trusted CAs
     631                 :            :      * \since QGIS 3.0
     632                 :            :      */
     633                 :            :     const QByteArray trustedCaCertsPemText();
     634                 :            : 
     635                 :            : #endif
     636                 :            : 
     637                 :            :     /**
     638                 :            :      * Error message getter
     639                 :            :      * \note not available in Python bindings
     640                 :            :      */
     641                 :            :     const QString passwordHelperErrorMessage() { return mPasswordHelperErrorMessage; } SIP_SKIP
     642                 :            : 
     643                 :            :     /**
     644                 :            :      * Delete master password from wallet
     645                 :            :      * \note not available in Python bindings
     646                 :            :      */
     647                 :            :     bool passwordHelperDelete() SIP_SKIP;
     648                 :            : 
     649                 :            :     /**
     650                 :            :      * Password helper enabled getter
     651                 :            :      * \note Available in Python bindings since QGIS 3.8.0
     652                 :            :      */
     653                 :            :     bool passwordHelperEnabled() const;
     654                 :            : 
     655                 :            :     /**
     656                 :            :      * Password helper enabled setter
     657                 :            :      * \note Available in Python bindings since QGIS 3.8.0
     658                 :            :      */
     659                 :            :     void setPasswordHelperEnabled( bool enabled );
     660                 :            : 
     661                 :            :     /**
     662                 :            :      * Password helper logging enabled getter
     663                 :            :      * \note not available in Python bindings
     664                 :            :      */
     665                 :            :     bool passwordHelperLoggingEnabled() const SIP_SKIP;
     666                 :            : 
     667                 :            :     /**
     668                 :            :      * Password helper logging enabled setter
     669                 :            :      * \note not available in Python bindings
     670                 :            :      */
     671                 :            :     void setPasswordHelperLoggingEnabled( bool enabled ) SIP_SKIP;
     672                 :            : 
     673                 :            :     /**
     674                 :            :      * Store the password manager into the wallet
     675                 :            :      * \note Available in Python bindings since QGIS 3.8.0
     676                 :            :      */
     677                 :            :     bool passwordHelperSync();
     678                 :            : 
     679                 :            :     //! The display name of the password helper (platform dependent)
     680                 :            :     static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME;
     681                 :            : 
     682                 :            :     //! The display name of the Authentication Manager
     683                 :            :     static const QString AUTH_MAN_TAG;
     684                 :            : 
     685                 :            :   signals:
     686                 :            : 
     687                 :            :     /**
     688                 :            :      * Signals emitted on password helper failure,
     689                 :            :      * mainly used in the tests to exit main application loop
     690                 :            :      */
     691                 :            :     void passwordHelperFailure();
     692                 :            : 
     693                 :            :     /**
     694                 :            :      * Signals emitted on password helper success,
     695                 :            :      * mainly used in the tests to exit main application loop
     696                 :            :      */
     697                 :            :     void passwordHelperSuccess();
     698                 :            : 
     699                 :            :     /**
     700                 :            :      * Custom logging signal to relay to console output and QgsMessageLog
     701                 :            :      * \param message Message to send
     702                 :            :      * \param tag Associated tag (title)
     703                 :            :      * \param level Message log level
     704                 :            :      * \see QgsMessageLog
     705                 :            :      */
     706                 :            :     void messageOut( const QString &message, const QString &tag = QgsAuthManager::AUTH_MAN_TAG, QgsAuthManager::MessageLevel level = QgsAuthManager::INFO ) const;
     707                 :            : 
     708                 :            :     /**
     709                 :            :      * Custom logging signal to inform the user about master password <-> password manager interactions
     710                 :            :      * \param message Message to send
     711                 :            :      * \param tag Associated tag (title)
     712                 :            :      * \param level Message log level
     713                 :            :      * \see QgsMessageLog
     714                 :            :      */
     715                 :            :     void passwordHelperMessageOut( const QString &message, const QString &tag = QgsAuthManager::AUTH_MAN_TAG, QgsAuthManager::MessageLevel level = QgsAuthManager::INFO );
     716                 :            : 
     717                 :            : 
     718                 :            :     /**
     719                 :            :      * Emitted when a password has been verify (or not)
     720                 :            :      * \param verified The state of password's verification
     721                 :            :      */
     722                 :            :     void masterPasswordVerified( bool verified );
     723                 :            : 
     724                 :            :     //! Emitted when a user has indicated they may want to erase the authentication db.
     725                 :            :     void authDatabaseEraseRequested();
     726                 :            : 
     727                 :            :     //! Emitted when the authentication db is significantly changed, e.g. large record removal, erased, etc.
     728                 :            :     void authDatabaseChanged();
     729                 :            : 
     730                 :            :   public slots:
     731                 :            :     //! Clear all authentication configs from authentication method caches
     732                 :            :     void clearAllCachedConfigs();
     733                 :            : 
     734                 :            :     //! Clear an authentication config from its associated authentication method cache
     735                 :            :     void clearCachedConfig( const QString &authcfg );
     736                 :            : 
     737                 :            :   private slots:
     738                 :            :     void writeToConsole( const QString &message, const QString &tag = QString(), QgsAuthManager::MessageLevel level = INFO );
     739                 :            : 
     740                 :            :     /**
     741                 :            :      * This slot emits the authDatabaseEraseRequested signal, instead of attempting
     742                 :            :      * the erase. It relies upon a slot connected to the signal in calling application
     743                 :            :      * (the one that initiated the erase) to initiate the erase, when it is ready.
     744                 :            :      * Upon activation, a receiving slot should get confimation from the user, then
     745                 :            :      * IMMEDIATELY call setScheduledAuthDatabaseErase( FALSE ) to stop the scheduling timer.
     746                 :            :      * If receiving slot is NOT ready to initiate the erase, e.g. project is still loading,
     747                 :            :      * it can skip the confirmation and request another signal emit from the scheduling timer.
     748                 :            :      */
     749                 :            :     void tryToStartDbErase();
     750                 :            : 
     751                 :            :   protected:
     752                 :            : 
     753                 :            :     /**
     754                 :            :      * Enforce singleton pattern
     755                 :            :      * \note To set up the manager instance and initialize everything use QgsAuthManager::instance()->init()
     756                 :            :      */
     757                 :            :     static QgsAuthManager *instance() SIP_SKIP;
     758                 :            : 
     759                 :            : 
     760                 :            : #ifdef Q_OS_WIN
     761                 :            :   public:
     762                 :            :     explicit QgsAuthManager() SIP_SKIP;
     763                 :            : #else
     764                 :            :   protected:
     765                 :            :     explicit QgsAuthManager() SIP_SKIP;
     766                 :            : #endif
     767                 :            : 
     768                 :            :   private:
     769                 :            : 
     770                 :            :     //////////////////////////////////////////////////////////////////////////////
     771                 :            :     // Password Helper methods
     772                 :            : 
     773                 :            :     //! Returns the name for logging
     774                 :            :     QString passwordHelperName() const;
     775                 :            : 
     776                 :            :     //! Print a debug message in QGIS
     777                 :            :     void passwordHelperLog( const QString &msg ) const;
     778                 :            : 
     779                 :            :     //! Read Master password from the wallet
     780                 :            :     QString passwordHelperRead();
     781                 :            : 
     782                 :            :     //! Store Master password in the wallet
     783                 :            :     bool passwordHelperWrite( const QString &password );
     784                 :            : 
     785                 :            :     //! Error message setter
     786                 :            :     void passwordHelperSetErrorMessage( const QString &errorMessage ) { mPasswordHelperErrorMessage = errorMessage; }
     787                 :            : 
     788                 :            :     //! Clear error code and message
     789                 :            :     void passwordHelperClearErrors();
     790                 :            : 
     791                 :            :     /**
     792                 :            :      * Process the error: show it and/or disable the password helper system in case of
     793                 :            :      * access denied or no backend, reset error flags at the end
     794                 :            :      */
     795                 :            :     void passwordHelperProcessError();
     796                 :            : 
     797                 :            :     bool createConfigTables();
     798                 :            : 
     799                 :            :     bool createCertTables();
     800                 :            : 
     801                 :            :     bool masterPasswordInput();
     802                 :            : 
     803                 :            :     bool masterPasswordRowsInDb( int *rows ) const;
     804                 :            : 
     805                 :            :     bool masterPasswordCheckAgainstDb( const QString &compare = QString() ) const;
     806                 :            : 
     807                 :            :     bool masterPasswordStoreInDb() const;
     808                 :            : 
     809                 :            :     bool masterPasswordClearDb();
     810                 :            : 
     811                 :            :     const QString masterPasswordCiv() const;
     812                 :            : 
     813                 :            :     bool verifyPasswordCanDecryptConfigs() const;
     814                 :            : 
     815                 :            :     bool reencryptAllAuthenticationConfigs( const QString &prevpass, const QString &prevciv );
     816                 :            : 
     817                 :            :     bool reencryptAuthenticationConfig( const QString &authcfg, const QString &prevpass, const QString &prevciv );
     818                 :            : 
     819                 :            :     bool reencryptAllAuthenticationSettings( const QString &prevpass, const QString &prevciv );
     820                 :            : 
     821                 :            :     bool reencryptAllAuthenticationIdentities( const QString &prevpass, const QString &prevciv );
     822                 :            : 
     823                 :            :     bool reencryptAuthenticationIdentity( const QString &identid, const QString &prevpass, const QString &prevciv );
     824                 :            : 
     825                 :            :     bool authDbOpen() const;
     826                 :            : 
     827                 :            :     bool authDbQuery( QSqlQuery *query ) const;
     828                 :            : 
     829                 :            :     bool authDbStartTransaction() const;
     830                 :            : 
     831                 :            :     bool authDbCommit() const;
     832                 :            : 
     833                 :            :     bool authDbTransactionQuery( QSqlQuery *query ) const;
     834                 :            : 
     835                 :            : #ifndef QT_NO_SSL
     836                 :            :     void insertCaCertInCache( QgsAuthCertUtils::CaCertSource source, const QList<QSslCertificate> &certs );
     837                 :            : #endif
     838                 :            : 
     839                 :          0 :     const QString authDbPassTable() const { return AUTH_PASS_TABLE; }
     840                 :            : 
     841                 :          0 :     const QString authDbSettingsTable() const { return AUTH_SETTINGS_TABLE; }
     842                 :            : 
     843                 :          0 :     const QString authDbIdentitiesTable() const { return AUTH_IDENTITIES_TABLE; }
     844                 :            : 
     845                 :          0 :     const QString authDbAuthoritiesTable() const { return AUTH_AUTHORITIES_TABLE; }
     846                 :            : 
     847                 :          0 :     const QString authDbTrustTable() const { return AUTH_TRUST_TABLE; }
     848                 :            : 
     849                 :            :     static QgsAuthManager *sInstance;
     850                 :            :     static const QString AUTH_CONFIG_TABLE;
     851                 :            :     static const QString AUTH_PASS_TABLE;
     852                 :            :     static const QString AUTH_SETTINGS_TABLE;
     853                 :            :     static const QString AUTH_IDENTITIES_TABLE;
     854                 :            :     static const QString AUTH_SERVERS_TABLE;
     855                 :            :     static const QString AUTH_AUTHORITIES_TABLE;
     856                 :            :     static const QString AUTH_TRUST_TABLE;
     857                 :            :     static const QString AUTH_CFG_REGEX;
     858                 :            : 
     859                 :            :     bool mAuthInit = false;
     860                 :            :     QString mAuthDbPath;
     861                 :            : 
     862                 :            :     std::unique_ptr<QCA::Initializer> mQcaInitializer;
     863                 :            : 
     864                 :            :     QHash<QString, QString> mConfigAuthMethods;
     865                 :            :     QHash<QString, QgsAuthMethod *> mAuthMethods;
     866                 :            : 
     867                 :            :     QString mMasterPass;
     868                 :            :     int mPassTries = 0;
     869                 :            :     bool mAuthDisabled = false;
     870                 :            :     QString mAuthDisabledMessage;
     871                 :            :     QTimer *mScheduledDbEraseTimer = nullptr;
     872                 :            :     bool mScheduledDbErase = false;
     873                 :            :     int mScheduledDbEraseRequestWait = 3 ; // in seconds
     874                 :            :     bool mScheduledDbEraseRequestEmitted = false;
     875                 :            :     int mScheduledDbEraseRequestCount = 0;
     876                 :            : 
     877                 :            : #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
     878                 :            :     std::unique_ptr<QMutex> mMutex;
     879                 :            :     std::unique_ptr<QMutex> mMasterPasswordMutex;
     880                 :            : #else
     881                 :            :     std::unique_ptr<QRecursiveMutex> mMutex;
     882                 :            :     std::unique_ptr<QRecursiveMutex> mMasterPasswordMutex;
     883                 :            : #endif
     884                 :            : #ifndef QT_NO_SSL
     885                 :            :     // mapping of sha1 digest and cert source and cert
     886                 :            :     // appending removes duplicates
     887                 :            :     QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > mCaCertsCache;
     888                 :            :     // list of sha1 digests per policy
     889                 :            :     QMap<QgsAuthCertUtils::CertTrustPolicy, QStringList > mCertTrustCache;
     890                 :            :     // cache of certs ready to be utilized in network connections
     891                 :            :     QList<QSslCertificate> mTrustedCaCertsCache;
     892                 :            :     // cache of SSL errors to be ignored in network connections, per sha-hostport
     893                 :            :     QHash<QString, QSet<QSslError::SslError> > mIgnoredSslErrorsCache;
     894                 :            : 
     895                 :            :     bool mHasCustomConfigByHost = false;
     896                 :            :     bool mHasCheckedIfCustomConfigByHostExists = false;
     897                 :            :     QMap< QString, QgsAuthConfigSslServer > mCustomConfigByHostCache;
     898                 :            : #endif
     899                 :            : 
     900                 :            :     //////////////////////////////////////////////////////////////////////////////
     901                 :            :     // Password Helper Variables
     902                 :            : 
     903                 :            :     //! Master password verification has failed
     904                 :            :     bool mPasswordHelperVerificationError = false;
     905                 :            : 
     906                 :            :     //! Store last error message
     907                 :            :     QString mPasswordHelperErrorMessage;
     908                 :            : 
     909                 :            :     //! Store last error code (enum)
     910                 :            :     QKeychain::Error mPasswordHelperErrorCode = QKeychain::NoError;
     911                 :            : 
     912                 :            :     //! Enable logging
     913                 :            :     bool mPasswordHelperLoggingEnabled = false;
     914                 :            : 
     915                 :            :     //! Whether the keychain bridge failed to initialize
     916                 :            :     bool mPasswordHelperFailedInit = false;
     917                 :            : 
     918                 :            :     //! Master password name in the wallets
     919                 :            :     static const QLatin1String AUTH_PASSWORD_HELPER_KEY_NAME;
     920                 :            : 
     921                 :            :     //! password helper folder in the wallets
     922                 :            :     static const QLatin1String AUTH_PASSWORD_HELPER_FOLDER_NAME;
     923                 :            : 
     924                 :            :     mutable QMap<QThread *, QMetaObject::Connection> mConnectedThreads;
     925                 :            : 
     926                 :            :     friend class QgsApplication;
     927                 :            : 
     928                 :            : };
     929                 :            : 
     930                 :            : #endif // QGSAUTHMANAGER_H

Generated by: LCOV version 1.14