23 #include <QCryptographicHash> 33 const QString QgsAuthMethodConfig::CONFIG_SEP = QStringLiteral(
"|||" );
34 const QString QgsAuthMethodConfig::CONFIG_KEY_SEP = QStringLiteral(
":::" );
35 const QString QgsAuthMethodConfig::CONFIG_LIST_SEP = QStringLiteral(
"```" );
37 const int QgsAuthMethodConfig::CONFIG_VERSION = 1;
52 return ( other.
id() ==
id()
62 return !( *
this == other );
67 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 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 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() );
167 const QSslKey &clientKey,
168 const QList<QSslCertificate> &caChain )
169 : mCert( QSslCertificate() )
170 , mCertKey( QSslKey() )
171 , mCaChain( caChain )
178 const QString &keyPath,
179 const QString &keyPass,
180 const QList<QSslCertificate> &
caChain )
183 if ( !certPath.isEmpty() && !keyPath.isEmpty()
184 && ( certPath.endsWith( QLatin1String(
".pem" ), Qt::CaseInsensitive )
185 || certPath.endsWith( QLatin1String(
".der" ), Qt::CaseInsensitive ) )
186 && QFile::exists( certPath ) && QFile::exists( keyPath )
190 bool pem = certPath.endsWith( QLatin1String(
".pem" ), Qt::CaseInsensitive );
197 if ( !caChain.isEmpty() )
206 const QString &bundlepass )
209 if ( QCA::isSupported(
"pkcs12" )
210 && !bundlepath.isEmpty()
211 && ( bundlepath.endsWith( QLatin1String(
".p12" ), Qt::CaseInsensitive )
212 || bundlepath.endsWith( QLatin1String(
".pfx" ), Qt::CaseInsensitive ) )
213 && QFile::exists( bundlepath ) )
215 QCA::SecureArray passarray;
216 if ( !bundlepass.isNull() )
217 passarray = QCA::SecureArray( bundlepass.toUtf8() );
218 QCA::ConvertResult res;
219 QCA::KeyBundle bundle( QCA::KeyBundle::fromFile( bundlepath, passarray, &res, QStringLiteral(
"qca-ossl" ) ) );
220 if ( res == QCA::ConvertGood && !bundle.isNull() )
222 const QCA::CertificateChain cert_chain( bundle.certificateChain() );
223 QSslCertificate cert( cert_chain.primary().toPEM().toLatin1() );
224 if ( !cert.isNull() )
228 QSslKey cert_key( bundle.privateKey().toPEM().toLatin1(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, QByteArray() );
229 if ( !cert_key.isNull() )
234 if ( cert_chain.size() > 1 )
236 QList<QSslCertificate> ca_chain;
237 for (
const auto &ca_cert : cert_chain )
239 if ( ca_cert != cert_chain.primary() )
241 ca_chain << QSslCertificate( ca_cert.toPEM().toLatin1() );
254 return ( mCert.isNull() || mCertKey.isNull() );
264 if ( mCert.isNull() )
268 return QString( mCert.digest( QCryptographicHash::Sha1 ).toHex() );
274 if ( !cert.isNull() )
283 if ( !certkey.isNull() && certkey.type() == QSsl::PrivateKey )
295 const QSslCertificate &cert,
296 const QSslKey &certkey,
297 const QList<QSslCertificate> &cachain )
300 , mCertKey( certkey )
301 , mCaChain( cachain )
307 return ( !mCert.isNull() && !mCertKey.isNull() );
315 const QString QgsAuthConfigSslServer::CONF_SEP = QStringLiteral(
"|||" );
318 : mSslHostPort( QString() )
319 , mSslCert( QSslCertificate() )
320 , mSslIgnoredErrors( QList<QSslError::SslError>() )
326 mSslProtocol = QSsl::SecureProtocols;
331 QList<QSslError> errors;
333 for ( QSslError::SslError errenum : ignoredErrors )
335 errors << QSslError( errenum );
342 QStringList configlist;
343 configlist << QString::number( mVersion ) << QString::number( mQtVersion );
345 configlist << QString::number( static_cast< int >( mSslProtocol ) );
348 for (
auto err : mSslIgnoredErrors )
350 errs << QString::number( static_cast< int >( err ) );
352 configlist << errs.join( QStringLiteral(
"~~" ) );
354 configlist << QStringLiteral(
"%1~~%2" ).arg( static_cast< int >( mSslPeerVerifyMode ) ).arg( mSslPeerVerifyDepth );
356 return configlist.join( CONF_SEP );
361 if ( config.isEmpty() )
365 QStringList configlist( config.split( CONF_SEP ) );
367 mVersion = configlist.at( 0 ).toInt();
368 mQtVersion = configlist.at( 1 ).toInt();
372 mSslProtocol =
static_cast< QSsl::SslProtocol
>( configlist.at( 2 ).toInt() );
374 mSslIgnoredErrors.clear();
375 const QStringList errs( configlist.at( 3 ).split( QStringLiteral(
"~~" ) ) );
376 for (
const auto &err : errs )
378 mSslIgnoredErrors.append( static_cast< QSslError::SslError >( err.toInt() ) );
381 QStringList peerverify( configlist.at( 4 ).split( QStringLiteral(
"~~" ) ) );
382 mSslPeerVerifyMode =
static_cast< QSslSocket::PeerVerifyMode
>( peerverify.at( 0 ).toInt() );
383 mSslPeerVerifyDepth = peerverify.at( 1 ).toInt();
388 return mSslCert.isNull() && mSslHostPort.isEmpty();
void setConfig(const QString &key, const QString &value)
Set a single config value per key in the map.
const QString configString() const
The extended configuration, as stored and retrieved from the authentication database.
void setCaChain(const QList< QSslCertificate > &cachain)
Sets chain of Certificate Authorities for client certificate.
static QSslKey keyFromFile(const QString &keypath, const QString &keypass=QString(), QString *algtype=nullptr)
Returns non-encrypted key from a PEM or DER formatted file.
bool isNull() const
Whether configuration is null (missing components)
bool isNull() const
Whether the bundle, either its certificate or private key, is null.
void setConfigList(const QString &key, const QStringList &value)
Set a multiple config values per key in the map.
QMap< QString, QString > QgsStringMap
const QString name() const
Gets name of configuration.
Storage set for PKI bundle: SSL certificate, key, optional CA cert chain.
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
static const QgsPkiBundle fromPkcs12Paths(const QString &bundlepath, const QString &bundlepass=QString())
Construct a bundle of PKI components from a PKCS#12 file path.
static QByteArray fileData(const QString &path)
Returns data from a local file via a read-only operation.
const QString uri() const
A URI to auto-select a config when connecting to a resource.
void setClientCert(const QSslCertificate &cert)
Sets client certificate object.
const QString configString() const
Configuration as a concatenated string.
QgsStringMap configMap() const
Gets extended configuration, mapped to key/value pairs of QStrings.
const QString certId() const
The sha hash of the client certificate.
bool operator!=(const QgsAuthMethodConfig &other) const
Operator used to compare configs' inequality.
Configuration storage class for authentication method configurations.
QgsAuthConfigSslServer()
Construct a default SSL server configuration.
void loadConfigString(const QString &configstr)
Load existing extended configuration.
bool isValid()
Whether the bundle is valid.
const QString id() const
Gets 'authcfg' 7-character alphanumeric ID of the config.
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.
QStringList configList(const QString &key) const
Returns a config's list of values.
QString config(const QString &key, const QString &defaultvalue=QString()) const
Returns a config's value.
void setClientKey(const QSslKey &certkey)
Sets private key object.
QgsAuthMethodConfig(const QString &method=QString(), int version=0)
Construct a configuration for an authentication method.
const QList< QSslCertificate > caChain() const
Chain of Certificate Authorities for client certificate.
bool isValid() const
Whether the bundle is valid.
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...
void loadConfigString(const QString &config=QString())
Load concatenated string into configuration, e.g. from auth database.
int removeConfig(const QString &key)
Remove a config from map.
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.
bool hasConfig(const QString &key) const
Whether a config key exists in config map.
bool isValid(bool validateid=false) const
Whether the configuration is valid.
void clearConfigMap()
Clear all configs.
bool operator==(const QgsAuthMethodConfig &other) const
Operator used to compare configs' equality.
int version() const
Gets version of the configuration.
QString method() const
Textual key of the associated authentication method.
QgsPkiBundle(const QSslCertificate &clientCert=QSslCertificate(), const QSslKey &clientKey=QSslKey(), const QList< QSslCertificate > &caChain=QList< QSslCertificate >())
Construct a bundle from existing PKI components.
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
const QList< QSslError > sslIgnoredErrors() const
SSL server errors to ignore in connections.