25 #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 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() );
359 const 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.
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
bool isNull() const
Whether configuration is null (missing components)
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