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() : QLatin1String(
"" ) );
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();
bool isValid() const
Whether the bundle is valid.
bool isNull() const
Whether configuration is null (missing components)
QgsStringMap configMap() const
Get extended configuration, mapped to key/value pairs of QStrings.
bool isNull() const
Whether the bundle, either its certificate or private key, is null.
bool isValid(bool validateid=false) const
Whether the configuration is valid.
void setConfig(const QString &key, const QString &value)
Set a single config value per key in the map.
QString config(const QString &key, const QString &defaultvalue=QString()) const
Return a config's value.
void setCaChain(const QList< QSslCertificate > &cachain)
Set chain of Certificate Authorities for client certificate.
static QSslKey keyFromFile(const QString &keypath, const QString &keypass=QString(), QString *algtype=nullptr)
Return non-encrypted key from a PEM or DER formatted file.
void setConfigList(const QString &key, const QStringList &value)
Set a multiple config values per key in the map.
QMap< QString, QString > QgsStringMap
QStringList configList(const QString &key) const
Return a config's list of values.
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)
Return data from a local file via a read-only operation.
void setClientCert(const QSslCertificate &cert)
Set client certificate object.
Configuration storage class for authentication method configurations.
const QList< QSslError > sslIgnoredErrors() const
SSL server errors to ignore in connections.
const QString configString() const
Configuration as a concatenated string.
const QString certId() const
The sha hash of the client certificate.
QgsAuthConfigSslServer()
Construct a default SSL server configuration.
void loadConfigString(const QString &configstr)
Load existing extended configuration.
const QString name() const
Get name of configuration.
bool isValid()
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.
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
int version() const
Get version of the configuration.
void setClientKey(const QSslKey &certkey)
Set private key object.
QgsAuthMethodConfig(const QString &method=QString(), int version=0)
Construct a configuration for an authentication method.
bool operator!=(const QgsAuthMethodConfig &other) const
Operator used to compare configs' inequality.
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...
const QList< QSslCertificate > caChain() const
Chain of Certificate Authorities for client certificate.
bool hasConfig(const QString &key) const
Whether a config key exists in config map.
QString method() const
Textual key of the associated authentication method.
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.
const QString uri() const
A URI to auto-select a config when connecting to a resource.
void clearConfigMap()
Clear all configs.
bool operator==(const QgsAuthMethodConfig &other) const
Operator used to compare configs' equality.
const QString configString() const
The extended configuration, as stored and retrieved from the authentication database.
QgsPkiBundle(const QSslCertificate &clientCert=QSslCertificate(), const QSslKey &clientKey=QSslKey(), const QList< QSslCertificate > &caChain=QList< QSslCertificate >())
Construct a bundle from existing PKI components.
const QString id() const
Get 'authcfg' 7-character alphanumeric ID of the config.