25#include <QCryptographicHash> 
   33const QString QgsAuthMethodConfig::CONFIG_SEP = QStringLiteral( 
"|||" );
 
   34const QString QgsAuthMethodConfig::CONFIG_KEY_SEP = QStringLiteral( 
":::" );
 
   35const QString QgsAuthMethodConfig::CONFIG_LIST_SEP = QStringLiteral( 
"```" );
 
   37const int QgsAuthMethodConfig::CONFIG_VERSION = 1;
 
   52  return ( other.
id() == 
id()
 
 
   62  return  !( *
this == other );
 
 
   67  const bool idvalid = validateid ? !mId.isEmpty() : 
true;
 
 
   79  QgsStringMap::const_iterator i = mConfigMap.constBegin();
 
   80  while ( i != mConfigMap.constEnd() )
 
   82    confstrs << i.key() + CONFIG_KEY_SEP + i.value();
 
   85  return confstrs.join( CONFIG_SEP );
 
 
   91  if ( configstr.isEmpty() )
 
   96  const QStringList confs( configstr.split( CONFIG_SEP ) );
 
   98  for ( 
const auto &conf : confs )
 
  100    if ( conf.contains( CONFIG_KEY_SEP ) )
 
  102      const QStringList keyval( conf.split( CONFIG_KEY_SEP ) );
 
  103      setConfig( keyval.at( 0 ), keyval.at( 1 ) );
 
  109    setConfig( QStringLiteral( 
"oldconfigstyle" ), configstr );
 
 
  115  mConfigMap.insert( key, value );
 
 
  120  setConfig( key, value.join( CONFIG_LIST_SEP ) );
 
 
  125  return mConfigMap.remove( key );
 
 
  130  return mConfigMap.value( key, defaultvalue );
 
 
  135  return config( key ).split( CONFIG_LIST_SEP );
 
 
  140  return mConfigMap.contains( key );
 
 
  145  QString res = QString();
 
  146  if ( !accessurl.isEmpty() )
 
  148    const QUrl url( accessurl );
 
  151      res = QStringLiteral( 
"%1://%2:%3%4" ).arg( url.scheme(), url.host() )
 
  152            .arg( url.port() ).arg( withpath ? url.path() : QString() );
 
  156  return ( !res.isEmpty() );
 
 
  162  QDomElement element = document.createElement( QStringLiteral( 
"AuthMethodConfig" ) );
 
  163  element.setAttribute( QStringLiteral( 
"method" ), mMethod );
 
  164  element.setAttribute( QStringLiteral( 
"id" ), mId );
 
  165  element.setAttribute( QStringLiteral( 
"name" ), mName );
 
  166  element.setAttribute( QStringLiteral( 
"version" ), QString::number( mVersion ) );
 
  167  element.setAttribute( QStringLiteral( 
"uri" ), mUri );
 
  169  QDomElement configElements = document.createElement( QStringLiteral( 
"Config" ) );
 
  170  QgsStringMap::const_iterator i = mConfigMap.constBegin();
 
  171  while ( i != mConfigMap.constEnd() )
 
  173    configElements.setAttribute( i.key(), i.value() );
 
  176  element.appendChild( configElements );
 
  178  parentElement.appendChild( element );
 
 
  184  if ( element.nodeName() != QLatin1String( 
"AuthMethodConfig" ) )
 
  187  mMethod = element.attribute( QStringLiteral( 
"method" ) );
 
  188  mId = element.attribute( QStringLiteral( 
"id" ) );
 
  189  mName = element.attribute( QStringLiteral( 
"name" ) );
 
  190  mVersion = element.attribute( QStringLiteral( 
"version" ) ).toInt();
 
  191  mUri = element.attribute( QStringLiteral( 
"uri" ) );
 
  194  const QDomNamedNodeMap configAttributes = element.firstChildElement().attributes();
 
  195  for ( 
int i = 0; i < configAttributes.length(); i++ )
 
  197    const QDomAttr configAttribute = configAttributes.item( i ).toAttr();
 
  198    setConfig( configAttribute.name(), configAttribute.value() );
 
 
  211                            const QSslKey &clientKey,
 
  212                            const QList<QSslCertificate> &caChain )
 
  213  : mCert( QSslCertificate() )
 
  214  , mCertKey( QSslKey() )
 
  215  , mCaChain( caChain )
 
 
  222    const QString &keyPath,
 
  223    const QString &keyPass,
 
  224    const QList<QSslCertificate> &caChain )
 
  227  if ( !certPath.isEmpty() && !keyPath.isEmpty()
 
  228       && ( certPath.endsWith( QLatin1String( 
".pem" ), Qt::CaseInsensitive )
 
  229            || certPath.endsWith( QLatin1String( 
".der" ), Qt::CaseInsensitive ) )
 
  230       && QFile::exists( certPath ) && QFile::exists( keyPath )
 
  234    const bool pem = certPath.endsWith( QLatin1String( 
".pem" ), Qt::CaseInsensitive );
 
 
  250    const QString &bundlepass )
 
  253  if ( QCA::isSupported( 
"pkcs12" )
 
  254       && !bundlepath.isEmpty()
 
  255       && ( bundlepath.endsWith( QLatin1String( 
".p12" ), Qt::CaseInsensitive )
 
  256            || bundlepath.endsWith( QLatin1String( 
".pfx" ), Qt::CaseInsensitive ) )
 
  257       && QFile::exists( bundlepath ) )
 
  259    QCA::SecureArray passarray;
 
  260    if ( !bundlepass.isNull() )
 
  261      passarray = QCA::SecureArray( bundlepass.toUtf8() );
 
  262    QCA::ConvertResult res;
 
  263    const QCA::KeyBundle bundle( QCA::KeyBundle::fromFile( bundlepath, passarray, &res, QStringLiteral( 
"qca-ossl" ) ) );
 
  264    if ( res == QCA::ConvertGood && !bundle.isNull() )
 
  266      const QCA::CertificateChain cert_chain( bundle.certificateChain() );
 
  267      const QSslCertificate cert( cert_chain.primary().toPEM().toLatin1() );
 
  268      if ( !cert.isNull() )
 
  272      const QSslKey cert_key( bundle.privateKey().toPEM().toLatin1(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, QByteArray() );
 
  273      if ( !cert_key.isNull() )
 
  278      if ( cert_chain.size() > 1 )
 
  280        QList<QSslCertificate> ca_chain;
 
  281        for ( 
const auto &ca_cert : cert_chain )
 
  283          if ( ca_cert != cert_chain.primary() )
 
  285            ca_chain << QSslCertificate( ca_cert.toPEM().toLatin1() );
 
 
  298  return ( mCert.isNull() || mCertKey.isNull() );
 
 
  308  if ( mCert.isNull() )
 
  312  return QString( mCert.digest( QCryptographicHash::Sha1 ).toHex() );
 
 
  318  if ( !cert.isNull() )
 
 
  327  if ( !certkey.isNull() && certkey.type() == QSsl::PrivateKey )
 
 
  339                                        const QSslCertificate &cert,
 
  340                                        const QSslKey &certkey,
 
  341                                        const QList<QSslCertificate> &cachain )
 
  344  , mCertKey( certkey )
 
  345  , mCaChain( cachain )
 
 
  351  return ( !mCert.isNull() && !mCertKey.isNull() );
 
 
  359const QString QgsAuthConfigSslServer::CONF_SEP = QStringLiteral( 
"|||" );
 
  362  : mSslHostPort( QString() )
 
  363  , mSslCert( QSslCertificate() )
 
  364  , mSslIgnoredErrors( QList<QSslError::SslError>() )
 
  370  mSslProtocol = QSsl::SecureProtocols;
 
 
  375  QList<QSslError> errors;
 
  377  for ( 
const QSslError::SslError errenum : ignoredErrors )
 
  379    errors << QSslError( errenum );
 
 
  386  QStringList configlist;
 
  387  configlist << QString::number( mVersion ) << QString::number( mQtVersion );
 
  389  configlist << QString::number( static_cast< int >( mSslProtocol ) );
 
  392  for ( 
const auto err : mSslIgnoredErrors )
 
  394    errs << QString::number( static_cast< int >( err ) );
 
  396  configlist << errs.join( QLatin1String( 
"~~" ) );
 
  398  configlist << QStringLiteral( 
"%1~~%2" ).arg( 
static_cast< int >( mSslPeerVerifyMode ) ).arg( mSslPeerVerifyDepth );
 
  400  return configlist.join( CONF_SEP );
 
 
  405  if ( config.isEmpty() )
 
  409  const QStringList configlist( config.split( CONF_SEP ) );
 
  411  mVersion = configlist.at( 0 ).toInt();
 
  412  mQtVersion = configlist.at( 1 ).toInt();
 
  416  mSslProtocol = 
static_cast< QSsl::SslProtocol 
>( configlist.at( 2 ).toInt() );
 
  418  mSslIgnoredErrors.clear();
 
  419  const QStringList errs( configlist.at( 3 ).split( QStringLiteral( 
"~~" ) ) );
 
  420  for ( 
const auto &err : errs )
 
  422    mSslIgnoredErrors.append( 
static_cast< QSslError::SslError 
>( err.toInt() ) );
 
  425  const QStringList peerverify( configlist.at( 4 ).split( QStringLiteral( 
"~~" ) ) );
 
  426  mSslPeerVerifyMode = 
static_cast< QSslSocket::PeerVerifyMode 
>( peerverify.at( 0 ).toInt() );
 
  427  mSslPeerVerifyDepth = peerverify.at( 1 ).toInt();
 
 
  432  return mSslCert.isNull() && mSslHostPort.isEmpty();
 
 
static QByteArray fileData(const QString &path)
Returns data from a local file via a read-only operation.
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
static QSslKey keyFromFile(const QString &keypath, const QString &keypass=QString(), QString *algtype=nullptr)
Returns non-encrypted key from a PEM or DER formatted file.
const QList< QSslError > sslIgnoredErrors() const
SSL server errors to ignore in connections.
bool isNull() const
Whether configuration is null (missing components)
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
const QString configString() const
Configuration as a concatenated string.
QgsAuthConfigSslServer()
Construct a default SSL server configuration.
void loadConfigString(const QString &config=QString())
Load concatenated string into configuration, e.g. from auth database.
Configuration storage class for authentication method configurations.
QString config(const QString &key, const QString &defaultvalue=QString()) const
Returns a config's value.
bool isValid(bool validateid=false) const
Whether the configuration is valid.
QString method() const
Textual key of the associated authentication method.
const QString uri() const
A URI to auto-select a config when connecting to a resource.
int removeConfig(const QString &key)
Remove a config from map.
bool readXml(const QDomElement &element)
from a DOM element.
const QString configString() const
The extended configuration, as stored and retrieved from the authentication database.
const QString name() const
Gets name of configuration.
bool operator==(const QgsAuthMethodConfig &other) const
Operator used to compare configs' equality.
const QString id() const
Gets 'authcfg' 7-character alphanumeric ID of the config.
void loadConfigString(const QString &configstr)
Load existing extended configuration.
void clearConfigMap()
Clear all configs.
bool writeXml(QDomElement &parentElement, QDomDocument &document)
Stores the configuration in a DOM.
void setConfig(const QString &key, const QString &value)
Set a single config value per key in the map.
QStringList configList(const QString &key) const
Returns a config's list of values.
int version() const
Gets version of the configuration.
QgsStringMap configMap() const
Gets extended configuration, mapped to key/value pairs of QStrings.
bool operator!=(const QgsAuthMethodConfig &other) const
Operator used to compare configs' inequality.
bool hasConfig(const QString &key) const
Whether a config key exists in config map.
QgsAuthMethodConfig(const QString &method=QString(), int version=0)
Construct a configuration for an authentication method.
void setConfigList(const QString &key, const QStringList &value)
Set a multiple config values per key in the map.
static bool uriToResource(const QString &accessurl, QString *resource, bool withpath=false)
A utility function for generating a resource from a URL to be compared against the config's uri() for...
Storage set for PKI bundle: SSL certificate, key, optional CA cert chain.
const QString certId() const
The sha hash of the client certificate.
bool isNull() const
Whether the bundle, either its certificate or private key, is null.
QgsPkiBundle(const QSslCertificate &clientCert=QSslCertificate(), const QSslKey &clientKey=QSslKey(), const QList< QSslCertificate > &caChain=QList< QSslCertificate >())
Construct a bundle from existing PKI components.
void setClientKey(const QSslKey &certkey)
Sets private key object.
void setClientCert(const QSslCertificate &cert)
Sets client certificate object.
static const QgsPkiBundle fromPkcs12Paths(const QString &bundlepath, const QString &bundlepass=QString())
Construct a bundle of PKI components from a PKCS#12 file path.
const QSslKey clientKey() const
Private key object.
void setCaChain(const QList< QSslCertificate > &cachain)
Sets chain of Certificate Authorities for client certificate.
const QList< QSslCertificate > caChain() const
Chain of Certificate Authorities for client certificate.
static const QgsPkiBundle fromPemPaths(const QString &certPath, const QString &keyPath, const QString &keyPass=QString(), const QList< QSslCertificate > &caChain=QList< QSslCertificate >())
Construct a bundle of PKI components from PEM-formatted file paths.
const QSslCertificate clientCert() const
Client certificate object.
bool isValid() const
Whether the bundle is valid.
QgsPkiConfigBundle(const QgsAuthMethodConfig &config, const QSslCertificate &cert, const QSslKey &certkey, const QList< QSslCertificate > &cachain=QList< QSslCertificate >())
Construct a bundle from existing PKI components and authentication method configuration.
bool isValid()
Whether the bundle is valid.
QMap< QString, QString > QgsStringMap