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

Generated by: LCOV version 1.14