Implemented remote credential storage via qtkeychain
Imported qtkeychain FossilOrigin-Name: 7c068aa8acdae1b86dee004d2d4cd7fb42904186
This commit is contained in:
107
ext/qtkeychain/keychain_win.cpp
Normal file
107
ext/qtkeychain/keychain_win.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld@gmail.com> *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
|
||||
* details, check the accompanying file 'COPYING'. *
|
||||
*****************************************************************************/
|
||||
#include "keychain_p.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using namespace QKeychain;
|
||||
|
||||
void ReadPasswordJobPrivate::scheduledStart() {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
|
||||
QByteArray encrypted = actual->value( key ).toByteArray();
|
||||
if ( encrypted.isNull() ) {
|
||||
q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
|
||||
return;
|
||||
}
|
||||
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
|
||||
blob_in.pbData = reinterpret_cast<BYTE*>( encrypted.data() );
|
||||
blob_in.cbData = encrypted.size();
|
||||
|
||||
const BOOL ret = CryptUnprotectData( &blob_in,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !ret ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Could not decrypt data") );
|
||||
return;
|
||||
}
|
||||
|
||||
data = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
SecureZeroMemory( blob_out.pbData, blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
void WritePasswordJobPrivate::scheduledStart() {
|
||||
if ( mode == Delete ) {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
const QString err = actual->status() == QSettings::AccessError
|
||||
? tr("Could not delete encrypted data from settings: access error")
|
||||
: tr("Could not delete encrypted data from settings: format error");
|
||||
q->emitFinishedWithError( OtherError, err );
|
||||
} else {
|
||||
q->emitFinished();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = mode == Binary ? binaryData : textData.toUtf8();
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
blob_in.pbData = reinterpret_cast<BYTE*>( data.data() );
|
||||
blob_in.cbData = data.size();
|
||||
const BOOL res = CryptProtectData( &blob_in,
|
||||
L"QKeychain-encrypted data",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !res ) {
|
||||
q->emitFinishedWithError( OtherError, tr("Encryption failed") ); //TODO more details available?
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray encrypted( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
|
||||
QSettings* actual = q->settings() ? q->settings() : local.get();
|
||||
actual->setValue( key, encrypted );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
|
||||
const QString errorString = actual->status() == QSettings::AccessError
|
||||
? tr("Could not store encrypted data in settings: access error")
|
||||
: tr("Could not store encrypted data in settings: format error");
|
||||
q->emitFinishedWithError( OtherError, errorString );
|
||||
return;
|
||||
}
|
||||
|
||||
q->emitFinished();
|
||||
}
|
Reference in New Issue
Block a user