Skip to content
Permalink
Browse files

[auth] PKI support to postgres provider

  • Loading branch information
luipir committed Jan 7, 2016
1 parent ef91882 commit 68478a736302c138300886273cb50640f844c72b
@@ -36,7 +36,7 @@ QgsAuthBasicMethod::QgsAuthBasicMethod()
<< "ows"
<< "wfs" // convert to lowercase
<< "wcs"
<< "wms" );
<< "wms");
}

QgsAuthBasicMethod::~QgsAuthBasicMethod()
@@ -17,6 +17,9 @@
#include "qgsauthidentcertmethod.h"
#include "qgsauthidentcertedit.h"

#include <QDir>
#include <QFile>
#include <QUuid>
#ifndef QT_NO_OPENSSL
#include <QtCrypto>
#include <QSslConfiguration>
@@ -27,7 +30,6 @@
#include "qgsauthmanager.h"
#include "qgslogger.h"


static const QString AUTH_METHOD_KEY = "Identity-Cert";
static const QString AUTH_METHOD_DESCRIPTION = "Identity certificate authentication";

@@ -38,12 +40,13 @@ QgsAuthIdentCertMethod::QgsAuthIdentCertMethod()
: QgsAuthMethod()
{
setVersion( 2 );
setExpansions( QgsAuthMethod::NetworkRequest );
setExpansions( QgsAuthMethod::NetworkRequest | QgsAuthMethod::DataSourceURI );
setDataProviders( QStringList()
<< "ows"
<< "wfs" // convert to lowercase
<< "wcs"
<< "wms" );
<< "wms"
<< "postgres" );
}

QgsAuthIdentCertMethod::~QgsAuthIdentCertMethod()
@@ -101,6 +104,128 @@ bool QgsAuthIdentCertMethod::updateNetworkRequest( QNetworkRequest &request, con
return true;
}

bool QgsAuthIdentCertMethod::updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider )
{
Q_UNUSED( dataprovider )

QgsDebugMsg( QString( "Update URI items for authcfg: %1" ).arg( authcfg ) );

QString pkiTempFilePrefix = "tmppki_";

QgsAuthMethodConfig amConfig;
if ( !QgsAuthManager::instance()->loadAuthenticationConfig( authcfg, amConfig, true ) )
{
QgsDebugMsg( QString( "Update URI items: FAILED to retrieve config for authcfg: %1" ).arg( authcfg ) );
return false;
}

if ( !amConfig.isValid() )
{
QgsDebugMsg( QString( "Update URI items: FAILED retrieved invalid Auth method for authcfg: %1" ).arg( authcfg ) );
return false;
}

// get client cent and key
QSslCertificate clientCert = QgsAuthManager::instance()->getCertIdentityBundle( amConfig.config( "certid" ) ).first;
QSslKey clientKey = QgsAuthManager::instance()->getCertIdentityBundle( amConfig.config( "certid" ) ).second;

// get common name of the client certificate
QString commonName = QgsAuthCertUtils::resolvedCertName( clientCert, false);

// get CA
QByteArray caCert = QgsAuthManager::instance()->getTrustedCaCertsPemText();

// save client cert to temp file
QFile certFile( QDir::tempPath() + QDir::separator() + pkiTempFilePrefix + QUuid::createUuid() + ".pem" );
if( certFile.open( QIODevice::WriteOnly ) )
{
certFile.write( clientCert.toPem() );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save client cert temporary file" ) );
return false;
}

certFile.setPermissions( QFile::ReadUser | QFile::WriteUser );

// save key cert to temp file setting it's permission only read to the current user
QFile keyFile( QDir::tempPath() + QDir::separator() + pkiTempFilePrefix + QUuid::createUuid() + ".pem" );
if( keyFile.open( QIODevice::WriteOnly ) )
{
keyFile.write( clientKey.toPem() );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save client key temporary file" ) );
return false;
}

keyFile.setPermissions( QFile::ReadUser );

// save CA to tempo file
QFile caFile( QDir::tempPath() + QDir::separator() + pkiTempFilePrefix + QUuid::createUuid() + ".pem" );
if( caFile.open( QIODevice::WriteOnly ) )
{
caFile.write( caCert );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save CAs to temporary file" ) );
return false;
}

caFile.setPermissions( QFile::ReadUser | QFile::WriteUser );

// add uri parameters
QString userparam = "user='" + commonName + "'";
int userindx = connectionItems.indexOf( QRegExp( "^user='.*" ) );
if ( userindx != -1 )
{
connectionItems.replace( userindx, userparam );
}
else
{
connectionItems.append( userparam );
}

QString certparam = "sslcert='" + certFile.fileName() + "'";
int sslcertindx = connectionItems.indexOf( QRegExp( "^sslcert='.*" ) );
if ( sslcertindx != -1 )
{
connectionItems.replace( sslcertindx, certparam );
}
else
{
connectionItems.append( certparam );
}

QString keyparam = "sslkey='" + keyFile.fileName() + "'";
int sslkeyindx = connectionItems.indexOf( QRegExp( "^sslkey='.*" ) );
if ( sslkeyindx != -1 )
{
connectionItems.replace( sslkeyindx, keyparam );
}
else
{
connectionItems.append( keyparam );
}

QString caparam = "sslrootcert='" + caFile.fileName() + "'";
int sslcaindx = connectionItems.indexOf( QRegExp( "^sslrootcert='.*" ) );
if ( sslcaindx != -1 )
{
connectionItems.replace( sslcaindx, caparam );
}
else
{
connectionItems.append( caparam );
}

return true;
}

void QgsAuthIdentCertMethod::clearCachedConfig( const QString &authcfg )
{
removePkiConfigBundle( authcfg );
@@ -41,6 +41,9 @@ class QgsAuthIdentCertMethod : public QgsAuthMethod
bool updateNetworkRequest( QNetworkRequest &request, const QString &authcfg,
const QString &dataprovider = QString() ) override;

bool updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider = QString() ) override;

void clearCachedConfig( const QString &authcfg ) override;

void updateMethodConfig( QgsAuthMethodConfig &mconfig ) override;
@@ -17,6 +17,9 @@
#include "qgsauthpkipathsmethod.h"
#include "qgsauthpkipathsedit.h"

#include <QDir>
#include <QFile>
#include <QUuid>
#ifndef QT_NO_OPENSSL
#include <QtCrypto>
#include <QSslConfiguration>
@@ -38,12 +41,13 @@ QgsAuthPkiPathsMethod::QgsAuthPkiPathsMethod()
: QgsAuthMethod()
{
setVersion( 2 );
setExpansions( QgsAuthMethod::NetworkRequest );
setExpansions( QgsAuthMethod::NetworkRequest | QgsAuthMethod::DataSourceURI );
setDataProviders( QStringList()
<< "ows"
<< "wfs" // convert to lowercase
<< "wcs"
<< "wms" );
<< "wms"
<< "postgres" );
}

QgsAuthPkiPathsMethod::~QgsAuthPkiPathsMethod()
@@ -101,6 +105,117 @@ bool QgsAuthPkiPathsMethod::updateNetworkRequest( QNetworkRequest &request, cons
return true;
}

bool QgsAuthPkiPathsMethod::updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider )
{
Q_UNUSED( dataprovider )

QgsDebugMsg( QString( "Update URI items for authcfg: %1" ).arg( authcfg ) );

QString pkiTempFilePrefix = "tmppki_";

QgsAuthMethodConfig amConfig;
if ( !QgsAuthManager::instance()->loadAuthenticationConfig( authcfg, amConfig, true ) )
{
QgsDebugMsg( QString( "Update URI items: FAILED to retrieve config for authcfg: %1" ).arg( authcfg ) );
return false;
}

if ( !amConfig.isValid() )
{
QgsDebugMsg( QString( "Update URI items: FAILED retrieved invalid Auth method for authcfg: %1" ).arg( authcfg ) );
return false;
}

// get client cent and key
QSslCertificate clientCert = QgsAuthManager::instance()->getCertIdentityBundle( amConfig.config( "certid" ) ).first;
QSslKey clientKey = QgsAuthManager::instance()->getCertIdentityBundle( amConfig.config( "certid" ) ).second;

// get common name of the client certificate
QString commonName = QgsAuthCertUtils::resolvedCertName( clientCert, false);

// get CA
QByteArray caCert = QgsAuthManager::instance()->getTrustedCaCertsPemText();

// save client cert to temp file
QFile certFile( QDir::tempPath() + QDir::separator() + pkiTempFilePrefix + QUuid::createUuid() + ".pem" );
if( certFile.open( QIODevice::WriteOnly ) )
{
certFile.write( clientCert.toPem() );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save client cert temporary file" ) );
return false;
}

certFile.setPermissions( QFile::ReadUser | QFile::WriteUser );

// save key cert to temp file setting it's permission only read to the current user
QFile keyFile( QDir::tempPath() + QDir::separator() + pkiTempFilePrefix + QUuid::createUuid() + ".pem" );
if( keyFile.open( QIODevice::WriteOnly ) )
{
keyFile.write( clientKey.toPem() );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save client key temporary file" ) );
return false;
}

keyFile.setPermissions( QFile::ReadUser );

// save CA to tempo file
QFile caFile( QDir::tempPath() + QDir::separator() + pkiTempFilePrefix + QUuid::createUuid() + ".pem" );
if( caFile.open( QIODevice::WriteOnly ) )
{
caFile.write( caCert );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save CAs to temporary file" ) );
return false;
}

caFile.setPermissions( QFile::ReadUser | QFile::WriteUser );

// add uri parameters
QString certparam = "sslcert='" + certFile.fileName() + "'";
int sslcertindx = connectionItems.indexOf( QRegExp( "^sslcert='.*" ) );
if ( sslcertindx != -1 )
{
connectionItems.replace( sslcertindx, certparam );
}
else
{
connectionItems.append( certparam );
}

QString keyparam = "sslkey='" + keyFile.fileName() + "'";
int sslkeyindx = connectionItems.indexOf( QRegExp( "^sslkey='.*" ) );
if ( sslkeyindx != -1 )
{
connectionItems.replace( sslkeyindx, keyparam );
}
else
{
connectionItems.append( keyparam );
}

QString caparam = "sslrootcert='" + caFile.fileName() + "'";
int sslcaindx = connectionItems.indexOf( QRegExp( "^sslrootcert='.*" ) );
if ( sslcaindx != -1 )
{
connectionItems.replace( sslcaindx, caparam );
}
else
{
connectionItems.append( caparam );
}

return true;
}

void QgsAuthPkiPathsMethod::clearCachedConfig( const QString &authcfg )
{
removePkiConfigBundle( authcfg );
@@ -41,6 +41,9 @@ class QgsAuthPkiPathsMethod : public QgsAuthMethod
bool updateNetworkRequest( QNetworkRequest &request, const QString &authcfg,
const QString &dataprovider = QString() ) override;

bool updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider = QString() ) override;

void clearCachedConfig( const QString &authcfg ) override;

void updateMethodConfig( QgsAuthMethodConfig &mconfig ) override;

0 comments on commit 68478a7

Please sign in to comment.
You can’t perform that action at this time.