Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[auth] Ensure ident cert cache is used; move temp file creation to utils
  • Loading branch information
dakcarto authored and luipir committed Jan 13, 2016
1 parent e7a1e2c commit d5bf104
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 51 deletions.
1 change: 1 addition & 0 deletions python/core/auth/qgsauthcertutils.sip
Expand Up @@ -82,6 +82,7 @@ class QgsAuthCertUtils
const QString &bundlepass = QString(),
bool reencrypt = true );

static QString pemTextToTempFile( const QString &name, const QByteArray &pemtext );

static QString getCaSourceName( QgsAuthCertUtils::CaCertSource source , bool single = false );

Expand Down
75 changes: 24 additions & 51 deletions src/auth/identcert/qgsauthidentcertmethod.cpp
Expand Up @@ -111,72 +111,45 @@ bool QgsAuthIdentCertMethod::updateDataSourceUriItems( QStringList &connectionIt

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() )
QgsPkiConfigBundle * pkibundle = getPkiConfigBundle( authcfg );
if ( !pkibundle || !pkibundle->isValid() )
{
QgsDebugMsg( QString( "Update URI items: FAILED retrieved invalid Auth method for authcfg: %1" ).arg( authcfg ) );
QgsDebugMsg( "Update URI items FAILED: PKI bundle invalid" );
return false;
}
QgsDebugMsg( "Update URI items: PKI bundle valid" );

// 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();
QString pkiTempFileBase = "tmppki_%1.pem";

// 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
QString certFilePath = QgsAuthCertUtils::pemTextToTempFile(
pkiTempFileBase.arg( QUuid::createUuid().toString() ),
pkibundle->clientCert().toPem() );
if ( certFilePath.isEmpty() )
{
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
// save client cert key to temp file
QString keyFilePath = QgsAuthCertUtils::pemTextToTempFile(
pkiTempFileBase.arg( QUuid::createUuid().toString() ),
pkibundle->clientCertKey().toPem() );
if ( keyFilePath.isEmpty() )
{
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 ) )
// save CAs to temp file
QString caFilePath = QgsAuthCertUtils::pemTextToTempFile(
pkiTempFileBase.arg( QUuid::createUuid().toString() ),
QgsAuthManager::instance()->getTrustedCaCertsPemText() );
if ( caFilePath.isEmpty() )
{
caFile.write( caCert );
}
else
{
QgsDebugMsg( QString( "Update URI items: FAILED to save CAs to temporary file" ) );
return false;
}

caFile.setPermissions( QFile::ReadUser | QFile::WriteUser );
// get common name of the client certificate
QString commonName = QgsAuthCertUtils::resolvedCertName( pkibundle->clientCert(), false );

// add uri parameters
QString userparam = "user='" + commonName + "'";
Expand All @@ -190,7 +163,7 @@ bool QgsAuthIdentCertMethod::updateDataSourceUriItems( QStringList &connectionIt
connectionItems.append( userparam );
}

QString certparam = "sslcert='" + certFile.fileName() + "'";
QString certparam = "sslcert='" + certFilePath + "'";
int sslcertindx = connectionItems.indexOf( QRegExp( "^sslcert='.*" ) );
if ( sslcertindx != -1 )
{
Expand All @@ -201,7 +174,7 @@ bool QgsAuthIdentCertMethod::updateDataSourceUriItems( QStringList &connectionIt
connectionItems.append( certparam );
}

QString keyparam = "sslkey='" + keyFile.fileName() + "'";
QString keyparam = "sslkey='" + keyFilePath + "'";
int sslkeyindx = connectionItems.indexOf( QRegExp( "^sslkey='.*" ) );
if ( sslkeyindx != -1 )
{
Expand All @@ -212,7 +185,7 @@ bool QgsAuthIdentCertMethod::updateDataSourceUriItems( QStringList &connectionIt
connectionItems.append( keyparam );
}

QString caparam = "sslrootcert='" + caFile.fileName() + "'";
QString caparam = "sslrootcert='" + caFilePath + "'";
int sslcaindx = connectionItems.indexOf( QRegExp( "^sslrootcert='.*" ) );
if ( sslcaindx != -1 )
{
Expand Down
31 changes: 31 additions & 0 deletions src/core/auth/qgsauthcertutils.cpp
Expand Up @@ -17,9 +17,11 @@
#include "qgsauthcertutils.h"

#include <QColor>
#include <QDir>
#include <QFile>
#include <QObject>
#include <QSslCertificate>
#include <QUuid>

#include "qgsauthmanager.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -246,6 +248,35 @@ QStringList QgsAuthCertUtils::pkcs12BundleToPem( const QString &bundlepath,
return QStringList() << bundle.certificateChain().primary().toPEM() << bundle.privateKey().toPEM( passarray ) << algtype;
}

QString QgsAuthCertUtils::pemTextToTempFile( const QString &name, const QByteArray &pemtext )
{
QFile pemFile( QDir::tempPath() + QDir::separator() + name );
QString pemFilePath( pemFile.fileName() );

if ( pemFile.open( QIODevice::WriteOnly ) )
{
qint64 bytesWritten = pemFile.write( pemtext );
if ( bytesWritten == -1 )
{
QgsDebugMsg( QString( "FAILED to write to temp PEM file: %1" ).arg( pemFilePath ) );
pemFilePath.clear();
}
}
else
{
QgsDebugMsg( QString( "FAILED to open writing for temp PEM file: %1" ).arg( pemFilePath ) );
pemFilePath.clear();
}

if ( !pemFile.setPermissions( QFile::ReadUser ) )
{
QgsDebugMsg( QString( "FAILED to set permissions on temp PEM file: %1" ).arg( pemFilePath ) );
pemFilePath.clear();
}

return pemFilePath;
}

QString QgsAuthCertUtils::getCaSourceName( QgsAuthCertUtils::CaCertSource source, bool single )
{
switch ( source )
Expand Down
7 changes: 7 additions & 0 deletions src/core/auth/qgsauthcertutils.h
Expand Up @@ -144,6 +144,13 @@ class CORE_EXPORT QgsAuthCertUtils
const QString &bundlepass = QString(),
bool reencrypt = true );

/** Write a temporary file for a PEM text of cert/key/CAs bundle component
* @param pemtext Component content as PEM text
* @param name Name of file
* @return File path to temporary file
*/
static QString pemTextToTempFile( const QString &name, const QByteArray &pemtext );

/** Get the general name for CA source enum type
* @param source The enum source type for the CA
* @param single Whether to return singular or plural description
Expand Down

0 comments on commit d5bf104

Please sign in to comment.