Port Windows impl to the job API.
This commit is contained in:
parent
c612123cc5
commit
8b1a574f35
|
@ -36,12 +36,14 @@ if(UNIX AND NOT APPLE)
|
|||
list(APPEND qtkeychain_SOURCES keychain_dbus.cpp)
|
||||
endif()
|
||||
|
||||
QT4_WRAP_CPP(qtkeychain_MOC_OUTFILES keychain.h keychain_p.h)
|
||||
|
||||
if(NOT QTKEYCHAIN_STATIC)
|
||||
add_library(qtkeychain SHARED ${qtkeychain_SOURCES})
|
||||
add_library(qtkeychain SHARED ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES})
|
||||
set_target_properties(qtkeychain PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_BUILD_QKEYCHAIN_LIB)
|
||||
target_link_libraries(qtkeychain ${qtkeychain_LIBRARIES})
|
||||
else()
|
||||
add_library(qtkeychain STATIC ${qtkeychain_SOURCES})
|
||||
add_library(qtkeychain STATIC ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES})
|
||||
set_target_properties(qtkeychain PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_STATICLIB)
|
||||
endif()
|
||||
|
||||
|
|
68
keychain.cpp
68
keychain.cpp
|
@ -131,71 +131,3 @@ void WritePasswordJob::setTextData( const QString& data ) {
|
|||
void WritePasswordJob::doStart() {
|
||||
d->doStart();
|
||||
}
|
||||
|
||||
#if 0
|
||||
Keychain::Keychain( const QString& service, QSettings* settings )
|
||||
: d( new Private( service, settings ) ) {
|
||||
Q_ASSERT( !service.isEmpty() );
|
||||
}
|
||||
|
||||
Keychain::~Keychain() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
QString Keychain::service() const {
|
||||
return d->service;
|
||||
}
|
||||
|
||||
QKeychain::Error Keychain::error() const {
|
||||
return d->error;
|
||||
}
|
||||
|
||||
QString Keychain::errorString() const {
|
||||
return d->errorString;
|
||||
}
|
||||
|
||||
void Keychain::writePassword( const QString &key, const QString &password ) {
|
||||
writeEntry( key, password.toUtf8() );
|
||||
}
|
||||
|
||||
void Keychain::writeEntry( const QString& key, const QByteArray& ba ) {
|
||||
QString err;
|
||||
const Error ret = d->writeEntryImpl( key, ba, &err );
|
||||
d->error = ret;
|
||||
d->errorString = err;
|
||||
}
|
||||
|
||||
QString Keychain::readPassword( const QString& key ) {
|
||||
const QByteArray ba = readEntry( key );
|
||||
return QString::fromUtf8( ba.constData(), ba.size() );
|
||||
}
|
||||
|
||||
QByteArray Keychain::readEntry( const QString& key ) {
|
||||
QString err;
|
||||
QByteArray pw;
|
||||
const Error ret = d->readEntryImpl( &pw, key, &err );
|
||||
d->error = ret;
|
||||
d->errorString = err;
|
||||
if ( ret != NoError )
|
||||
return QByteArray();
|
||||
else
|
||||
return pw;
|
||||
}
|
||||
|
||||
bool Keychain::entryExists( const QString& key ) {
|
||||
QString err;
|
||||
bool exists = false;
|
||||
const Error ret = d->entryExistsImpl( &exists, key, &err );
|
||||
d->error = ret;
|
||||
d->errorString = err;
|
||||
return exists;
|
||||
}
|
||||
|
||||
void Keychain::deleteEntry( const QString& key ) {
|
||||
QString err;
|
||||
const Error ret = d->deleteEntryImpl( key, &err );
|
||||
d->error = ret;
|
||||
d->errorString = err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
130
keychain_p.h
130
keychain_p.h
|
@ -60,136 +60,6 @@ public:
|
|||
QString textData;
|
||||
};
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Provides access to platform-specific key stores for secure persistence of
|
||||
* passwords and other sensitive user data.
|
||||
*
|
||||
* On Windows, TODO
|
||||
* On Mac OS X, the OS X keychain is used.
|
||||
* On other Unixes, TODO
|
||||
*
|
||||
* TODO we don't guarantee anything
|
||||
*/
|
||||
class Keychain {
|
||||
public:
|
||||
/**
|
||||
* Creates a Keychain object.
|
||||
*
|
||||
* @param service The service name of your service/application. Used as identifier,
|
||||
* to disambiguate keys and avoid clashes with other applications.
|
||||
* Must not be empty.
|
||||
* @param settings An optional settings object that is used to store the encrypted data
|
||||
* if no keychain is available on the platform. Currently only used on Windows.
|
||||
* If 0, a default-constructed QSettings object will be used.
|
||||
*/
|
||||
explicit Keychain( const QString& service, QSettings* settings=0 );
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Keychain();
|
||||
|
||||
/**
|
||||
* The service name used as identifier.
|
||||
*/
|
||||
QString service() const;
|
||||
|
||||
/**
|
||||
* The error code of the last operation.
|
||||
*/
|
||||
Error error() const;
|
||||
|
||||
/**
|
||||
* Human-readable error description of the last operation.
|
||||
*/
|
||||
QString errorString() const;
|
||||
|
||||
/**
|
||||
* Stores a @p password in the keychain, for a given @p key.
|
||||
* error() and errorString() hold the result of the write operation.
|
||||
*
|
||||
* @param key the key to store a password for
|
||||
* @param password the password to store
|
||||
* @param om Whether to overwrite existing passwords
|
||||
*/
|
||||
void writePassword( const QString& key,
|
||||
const QString& password );
|
||||
|
||||
/**
|
||||
* Stores @p data in the keychain, for a given @p key.
|
||||
* error() and errorString() hold the result of the write operation.
|
||||
*
|
||||
* @param key the key to store a password for
|
||||
* @param data the data to store
|
||||
* @param om Whether to overwrite existing passwords
|
||||
*/
|
||||
void writeEntry( const QString& key,
|
||||
const QByteArray& data );
|
||||
|
||||
/**
|
||||
* Reads the password for a given @p key from the keychain.
|
||||
* error() and errorString() hold the result of the read operation.
|
||||
*
|
||||
* @param key the key to read the password for
|
||||
*/
|
||||
QString readPassword( const QString& key );
|
||||
|
||||
/**
|
||||
* Reads data for a given @p key from the keychain.
|
||||
* error() and errorString() hold the result of the read operation.
|
||||
*
|
||||
* @param key the key to read the password for
|
||||
*/
|
||||
QByteArray readEntry( const QString& key );
|
||||
|
||||
/**
|
||||
* Returns whether the keychain has an entry with key @p key
|
||||
* error() and errorString() hold the result of the read operation.
|
||||
*
|
||||
* @param key the key to check for
|
||||
*/
|
||||
bool entryExists( const QString& key );
|
||||
|
||||
/**
|
||||
* Deletes the data for a @p key from the keychain.
|
||||
* error() and errorString() hold the result of the delete operation.
|
||||
*
|
||||
* @param key The key to delete the data for
|
||||
*/
|
||||
void deleteEntry( const QString& key );
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private* const d;
|
||||
Q_DISABLE_COPY(Keychain)
|
||||
};
|
||||
|
||||
class Keychain::Private {
|
||||
Q_DECLARE_TR_FUNCTIONS(Keychain::Private)
|
||||
public:
|
||||
explicit Private( const QString& service_, QSettings* settings_ ) : service( service_ ), settings( settings_ ), error( NoError ) {}
|
||||
|
||||
QKeychain::Error writeEntryImpl( const QString& account,
|
||||
const QByteArray& data,
|
||||
QString* errorString );
|
||||
QKeychain::Error deleteEntryImpl( const QString& account,
|
||||
QString* errorString );
|
||||
QKeychain::Error readEntryImpl( QByteArray* password,
|
||||
const QString& account,
|
||||
QString* errorString );
|
||||
QKeychain::Error entryExistsImpl( bool* exists,
|
||||
const QString& key,
|
||||
QString* errorString );
|
||||
const QString service;
|
||||
QPointer<QSettings> settings;
|
||||
QKeychain::Error error;
|
||||
QString errorString;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif // KEYCHAIN_P_H
|
||||
|
|
109
keychain_win.cpp
109
keychain_win.cpp
|
@ -17,21 +17,15 @@
|
|||
|
||||
using namespace QKeychain;
|
||||
|
||||
QtKeychain::Error Keychain::Private::readEntryImpl( QByteArray* pw,
|
||||
const QString& key,
|
||||
QString* err ) {
|
||||
Q_ASSERT( pw );
|
||||
Q_ASSERT( err );
|
||||
err->clear();
|
||||
|
||||
void ReadPasswordJob::Private::doStart() {
|
||||
//Use settings member if there, create local settings object if not
|
||||
std::auto_ptr<QSettings> local( !settings ? new QSettings( service ) : 0 );
|
||||
QSettings* actual = settings ? settings.data() : local.get();
|
||||
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() ) {
|
||||
*err = tr("Entry not found");
|
||||
return EntryNotFound;
|
||||
q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
|
||||
return;
|
||||
}
|
||||
|
||||
DATA_BLOB blob_in, blob_out;
|
||||
|
@ -40,28 +34,43 @@ QtKeychain::Error Keychain::Private::readEntryImpl( QByteArray* pw,
|
|||
blob_in.cbData = encrypted.size();
|
||||
|
||||
const BOOL ret = CryptUnprotectData( &blob_in,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
&blob_out );
|
||||
if ( !ret ) {
|
||||
*err = tr("Could not decrypt data");
|
||||
return OtherError;
|
||||
q->emitFinishedWithError( OtherError, tr("Could not decrypt data") );
|
||||
return;
|
||||
}
|
||||
*pw = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
|
||||
data = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
|
||||
SecureZeroMemory( blob_out.pbData, blob_out.cbData );
|
||||
LocalFree( blob_out.pbData );
|
||||
return NoError;
|
||||
|
||||
q->emitFinished();
|
||||
}
|
||||
|
||||
QtKeychain::Error Keychain::Private::writeEntryImpl( const QString& key,
|
||||
const QByteArray& data_,
|
||||
QString* err ) {
|
||||
Q_ASSERT( err );
|
||||
err->clear();
|
||||
QByteArray data = data_;
|
||||
void WritePasswordJob::Private::doStart() {
|
||||
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();
|
||||
|
@ -73,64 +82,26 @@ QtKeychain::Error Keychain::Private::writeEntryImpl( const QString& key,
|
|||
0,
|
||||
&blob_out );
|
||||
if ( !res ) {
|
||||
*err = tr("Encryption failed"); //TODO more details available?
|
||||
return OtherError;
|
||||
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( !settings ? new QSettings( service ) : 0 );
|
||||
QSettings* actual = settings ? settings.data() : local.get();
|
||||
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 ) {
|
||||
*err = actual->status() == QSettings::AccessError
|
||||
|
||||
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");
|
||||
return OtherError;
|
||||
q->emitFinishedWithError( OtherError, errorString );
|
||||
return;
|
||||
}
|
||||
|
||||
return NoError;
|
||||
}
|
||||
|
||||
QtKeychain::Error Keychain::Private::deleteEntryImpl( const QString& key,
|
||||
QString* err ) {
|
||||
Q_ASSERT( err );
|
||||
err->clear();
|
||||
std::auto_ptr<QSettings> local( !settings ? new QSettings( service ) : 0 );
|
||||
QSettings* actual = settings ? settings.data() : local.get();
|
||||
actual->remove( key );
|
||||
actual->sync();
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
*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");
|
||||
return OtherError;
|
||||
}
|
||||
|
||||
return NoError;
|
||||
}
|
||||
|
||||
|
||||
QtKeychain::Error Keychain::Private::entryExistsImpl( bool* exists,
|
||||
const QString& key,
|
||||
QString* err ) {
|
||||
Q_ASSERT( exists );
|
||||
Q_ASSERT( err );
|
||||
err->clear();
|
||||
*exists = false;
|
||||
std::auto_ptr<QSettings> local( !settings ? new QSettings( service ) : 0 );
|
||||
QSettings* actual = settings ? settings.data() : local.get();
|
||||
const bool ex = actual->contains( key );
|
||||
if ( actual->status() != QSettings::NoError ) {
|
||||
*err = actual->status() == QSettings::AccessError
|
||||
? tr("Could not read settings: access error")
|
||||
: tr("Could not read settings: format error");
|
||||
return OtherError;
|
||||
}
|
||||
|
||||
*exists = ex;
|
||||
return NoError;
|
||||
q->emitFinished();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue