qtkeychain/keychain_win.cpp

108 lines
4.3 KiB
C++
Raw Normal View History

2011-10-27 16:15:46 +00:00
/******************************************************************************
2013-07-22 18:22:39 +00:00
* Copyright (C) 2011-2013 Frank Osterfeld <frank.osterfeld@gmail.com> *
2011-10-27 16:15:46 +00:00
* *
* 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'. *
*****************************************************************************/
2011-10-27 16:14:37 +00:00
#include "keychain_p.h"
2011-10-28 23:21:07 +00:00
#include <QSettings>
2012-04-06 15:02:13 +00:00
#include <windows.h>
#include <wincrypt.h>
2011-10-28 23:21:07 +00:00
#include <memory>
2011-10-28 07:38:02 +00:00
using namespace QKeychain;
void ReadPasswordJobPrivate::scheduledStart() {
//Use settings member if there, create local settings object if not
2012-05-05 08:37:48 +00:00
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();
2011-10-28 23:21:07 +00:00
if ( encrypted.isNull() ) {
2012-05-05 08:37:48 +00:00
q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
return;
2011-10-28 23:21:07 +00:00
}
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,
2012-05-05 08:37:48 +00:00
NULL,
2011-10-28 23:21:07 +00:00
NULL,
NULL,
NULL,
0,
&blob_out );
if ( !ret ) {
2012-05-05 08:37:48 +00:00
q->emitFinishedWithError( OtherError, tr("Could not decrypt data") );
return;
2011-10-28 23:21:07 +00:00
}
2012-05-05 08:37:48 +00:00
data = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
2011-10-28 23:21:07 +00:00
SecureZeroMemory( blob_out.pbData, blob_out.cbData );
LocalFree( blob_out.pbData );
2012-05-05 08:37:48 +00:00
q->emitFinished();
2011-10-28 07:38:02 +00:00
}
void WritePasswordJobPrivate::scheduledStart() {
2012-05-05 08:37:48 +00:00
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();
2011-10-28 23:21:07 +00:00
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 ) {
2012-05-05 08:37:48 +00:00
q->emitFinishedWithError( OtherError, tr("Encryption failed") ); //TODO more details available?
return;
2011-10-28 23:21:07 +00:00
}
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
2012-05-05 08:37:48 +00:00
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 ) {
2012-05-05 08:37:48 +00:00
const QString errorString = actual->status() == QSettings::AccessError
2011-10-28 23:21:07 +00:00
? tr("Could not store encrypted data in settings: access error")
: tr("Could not store encrypted data in settings: format error");
2012-05-05 08:37:48 +00:00
q->emitFinishedWithError( OtherError, errorString );
return;
2011-10-28 23:21:07 +00:00
}
2012-05-05 08:37:48 +00:00
q->emitFinished();
2011-10-28 07:38:02 +00:00
}