From 45725c79866d020a657a80a04ac698b7c7bb501b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 12 Jan 2016 12:55:25 +0100 Subject: [PATCH] Added binary / text mode password support. Added binary password write function. --- gnomekeyring.cpp | 31 +++++++++++++++++++++++-------- gnomekeyring_p.h | 10 +++++++--- keychain_unix.cpp | 43 ++++++++++++++++++++++++++++++++++++------- testclient.cpp | 23 +++++++++++++++++++++++ 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/gnomekeyring.cpp b/gnomekeyring.cpp index 9cef00f..bf4741b 100644 --- a/gnomekeyring.cpp +++ b/gnomekeyring.cpp @@ -14,25 +14,39 @@ bool GnomeKeyring::isAvailable() keyring.is_available(); } -GnomeKeyring::gpointer GnomeKeyring::store_network_password( const gchar* keyring, const gchar* display_name, - const gchar* user, const gchar* server, const gchar* password, - OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ) +GnomeKeyring::gpointer GnomeKeyring::store_network_password( + const gchar* keyring, + const gchar* display_name, + const gchar* user, + const gchar* server, + const gchar* type, + const gchar* password, + OperationDoneCallback callback, + gpointer data, + GDestroyNotify destroy_data ) { if ( !isAvailable() ) return 0; return instance().store_password( instance().NETWORK_PASSWORD, - keyring, display_name, password, callback, data, destroy_data, - "user", user, "server", server, static_cast(0) ); + keyring, display_name, password, callback, + data, destroy_data, + "user", user, + "server", server, + "type", type, + static_cast(0) ); } -GnomeKeyring::gpointer GnomeKeyring::find_network_password( const gchar* user, const gchar* server, - OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ) +GnomeKeyring::gpointer GnomeKeyring::find_network_password( + const gchar* user, const gchar* server, const gchar* type, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ) { if ( !isAvailable() ) return 0; + return instance().find_password( instance().NETWORK_PASSWORD, callback, data, destroy_data, - "user", user, "server", server, static_cast(0) ); + "user", user, "server", server, "type", type, + static_cast(0) ); } GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user, @@ -55,6 +69,7 @@ GnomeKeyring::GnomeKeyring() ITEM_NETWORK_PASSWORD, {{ "user", ATTRIBUTE_TYPE_STRING }, { "server", ATTRIBUTE_TYPE_STRING }, + { "type", ATTRIBUTE_TYPE_STRING }, { 0, static_cast( 0 ) }} }; diff --git a/gnomekeyring_p.h b/gnomekeyring_p.h index 6d150ba..3f6869b 100644 --- a/gnomekeyring_p.h +++ b/gnomekeyring_p.h @@ -43,7 +43,8 @@ public: } attributes[32]; } PasswordSchema; - typedef void ( *OperationGetStringCallback )( Result result, const char* string, gpointer data ); + typedef void ( *OperationGetStringCallback )( Result result, bool binary, + const char* string, gpointer data ); typedef void ( *OperationDoneCallback )( Result result, gpointer data ); typedef void ( *GDestroyNotify )( gpointer data ); @@ -52,11 +53,14 @@ public: static bool isAvailable(); static gpointer store_network_password( const gchar* keyring, const gchar* display_name, - const gchar* user, const gchar* server, const gchar* password, + const gchar* user, const gchar* server, + const gchar* type, const gchar* password, OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); static gpointer find_network_password( const gchar* user, const gchar* server, - OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ); + const gchar* type, + OperationGetStringCallback callback, + gpointer data, GDestroyNotify destroy_data ); static gpointer delete_network_password( const gchar* user, const gchar* server, OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); diff --git a/keychain_unix.cpp b/keychain_unix.cpp index 9fa9f24..e83f33f 100644 --- a/keychain_unix.cpp +++ b/keychain_unix.cpp @@ -134,7 +134,10 @@ static void kwalletReadPasswordScheduledStartImpl(const char * service, const ch void ReadPasswordJobPrivate::scheduledStart() { switch ( getKeyringBackend() ) { case Backend_GnomeKeyring: - if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(), + this->mode = JobPrivate::Text; + if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), + q->service().toUtf8().constData(), + "plaintext", reinterpret_cast( &JobPrivate::gnomeKeyring_readCb ), this, 0 ) ) q->emitFinishedWithError( OtherError, tr("Unknown error") ); @@ -192,11 +195,20 @@ static QPair mapGnomeKeyringError( int result ) void JobPrivate::gnomeKeyring_readCb( int result, const char* string, JobPrivate* self ) { if ( result == GnomeKeyring::RESULT_OK ) { - if ( self->mode == JobPrivate::Text ) - self->data = string; + if (self->mode == JobPrivate::Text) + self->data = QByteArray(string); else - self->data = QByteArray::fromBase64( string ); + self->data = QByteArray::fromBase64(string); + self->q->emitFinished(); + } else if (self->mode == JobPrivate::Text) { + self->mode = JobPrivate::Binary; + if ( !GnomeKeyring::find_network_password( self->key.toUtf8().constData(), + self->q->service().toUtf8().constData(), + "base64", + reinterpret_cast( &JobPrivate::gnomeKeyring_readCb ), + self, 0 ) ) + self->q->emitFinishedWithError( OtherError, tr("Unknown error") ); } else { const QPair errorResult = mapGnomeKeyringError( result ); self->q->emitFinishedWithError( errorResult.first, errorResult.second ); @@ -350,10 +362,27 @@ static void kwalletWritePasswordScheduledStart( const char * service, const char void WritePasswordJobPrivate::scheduledStart() { switch ( getKeyringBackend() ) { case Backend_GnomeKeyring: { - QByteArray password = (mode == JobPrivate::Text) ? data : data.toBase64(); + QString type; + QByteArray password; + + switch(mode) { + case JobPrivate::Text: + type = "plaintext"; + password = data; + break; + default: + type = "base64"; + password = data.toBase64(); + break; + } + QByteArray service = q->service().toUtf8(); - if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, service.constData(), - key.toUtf8().constData(), service.constData(), password.constData(), + if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, + service.constData(), + key.toUtf8().constData(), + service.constData(), + type.toUtf8().constData(), + password.constData(), reinterpret_cast( &JobPrivate::gnomeKeyring_writeCb ), this, 0 ) ) q->emitFinishedWithError( OtherError, tr("Unknown error") ); diff --git a/testclient.cpp b/testclient.cpp index a9d9bad..94189cf 100644 --- a/testclient.cpp +++ b/testclient.cpp @@ -52,6 +52,29 @@ int main( int argc, char** argv ) { return 1; } std::cout << "Password stored successfully" << std::endl; + } else if ( *it == QLatin1String("bstore") ) { + if ( ++it == args.constEnd() ) + return printUsage(); + const QString acc = *it; + if ( ++it == args.constEnd() ) + return printUsage(); + const QString pass = *it; + if ( ++it != args.constEnd() ) + return printUsage(); + WritePasswordJob job( QLatin1String("qtkeychain-testclient") ); + job.setAutoDelete( false ); + job.setKey( acc ); + job.setBinaryData( pass.toUtf8() ); + QEventLoop loop; + job.connect( &job, SIGNAL(finished(QKeychain::Job*)), &loop, SLOT(quit()) ); + job.start(); + loop.exec(); + if ( job.error() ) { + std::cerr << "Storing binary password failed: " + << qPrintable(job.errorString()) << std::endl; + return 1; + } + std::cout << "Password stored successfully" << std::endl; } else if ( *it == QLatin1String("restore") ) { if ( ++it == args.constEnd() ) return printUsage();