[Pkg-owncloud-commits] [qtkeychain] 60/115: Gnome keyring support.
Sandro Knauß
hefee-guest at moszumanska.debian.org
Sat Mar 15 19:25:45 UTC 2014
This is an automated email from the git hooks/post-receive script.
hefee-guest pushed a commit to branch master
in repository qtkeychain.
commit 863c75af92654aac0edb3bb2bf206d55a24c0b2a
Author: Francois Ferrand <thetypz at gmail.com>
Date: Tue Mar 19 12:24:15 2013 +0100
Gnome keyring support.
---
keychain_dbus.cpp | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
keychain_p.h | 3 +-
2 files changed, 221 insertions(+), 9 deletions(-)
diff --git a/keychain_dbus.cpp b/keychain_dbus.cpp
index f0ca244..3fab944 100644
--- a/keychain_dbus.cpp
+++ b/keychain_dbus.cpp
@@ -14,11 +14,184 @@
using namespace QKeychain;
+class GnomeKeyring: private QLibrary {
+public:
+ typedef enum {
+ RESULT_OK,
+ RESULT_DENIED,
+ RESULT_NO_KEYRING_DAEMON,
+ RESULT_ALREADY_UNLOCKED,
+ RESULT_NO_SUCH_KEYRING,
+ RESULT_BAD_ARGUMENTS,
+ RESULT_IO_ERROR,
+ RESULT_CANCELLED,
+ RESULT_KEYRING_ALREADY_EXISTS,
+ RESULT_NO_MATCH
+ } Result;
+ typedef enum {
+ ITEM_GENERIC_SECRET = 0,
+ ITEM_NETWORK_PASSWORD,
+ ITEM_NOTE,
+ ITEM_CHAINED_KEYRING_PASSWORD,
+ ITEM_ENCRYPTION_KEY_PASSWORD,
+ ITEM_PK_STORAGE = 0x100
+ } ItemType;
+ typedef enum {
+ ATTRIBUTE_TYPE_STRING,
+ ATTRIBUTE_TYPE_UINT32
+ } AttributeType;
+ typedef char gchar;
+ typedef void* gpointer;
+ typedef struct {
+ ItemType item_type;
+ struct {
+ const gchar* name;
+ AttributeType type;
+ } attributes[32];
+ } PasswordSchema;
+ typedef void ( *OperationGetStringCallback )( Result result, const char* string, gpointer data );
+ typedef void ( *OperationDoneCallback )( Result result, gpointer data );
+ typedef void ( *GDestroyNotify )( gpointer data );
+
+ static const char* GNOME_KEYRING_DEFAULT;
+ static const char* GNOME_KEYRING_SESSION;
+
+ static bool isSupported()
+ {
+ GnomeKeyring& keyring = instance();
+ return keyring.isLoaded() &&
+ keyring.NETWORK_PASSWORD &&
+ keyring.find_password &&
+ keyring.store_password &&
+ keyring.delete_password;
+ }
+
+ static gpointer 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 )
+ {
+ if ( !isSupported() )
+ return NULL;
+ return instance().store_password( instance().NETWORK_PASSWORD,
+ keyring, display_name, password, callback, data, destroy_data,
+ "user", user, "server", server, NULL );
+ }
+
+ static gpointer find_network_password( const gchar* user, const gchar* server,
+ OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data )
+ {
+ if ( !isSupported() )
+ return NULL;
+ return instance().find_password( instance().NETWORK_PASSWORD,
+ callback, data, destroy_data,
+ "user", user, "server", server, NULL );
+ }
+
+ static gpointer delete_network_password( const gchar* user, const gchar* server,
+ OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data )
+ {
+ if ( !isSupported() )
+ return NULL;
+ return instance().delete_password( instance().NETWORK_PASSWORD,
+ callback, data, destroy_data,
+ "user", user, "server", server, NULL );
+ }
+
+private:
+ GnomeKeyring(): QLibrary("gnome-keyring", 0) {
+ static const PasswordSchema schema = {
+ ITEM_NETWORK_PASSWORD,
+ {{ "user", ATTRIBUTE_TYPE_STRING },
+ { "server", ATTRIBUTE_TYPE_STRING },
+ { NULL, ( AttributeType )0 }}
+ };
+ NETWORK_PASSWORD = &schema;
+ find_password = reinterpret_cast<find_password_fn*>( resolve( "gnome_keyring_find_password" ) );
+ store_password = reinterpret_cast<store_password_fn*>(resolve( "gnome_keyring_store_password" ) );
+ delete_password = reinterpret_cast<delete_password_fn*>( resolve( "gnome_keyring_delete_password" ) );
+ }
+
+ static GnomeKeyring& instance() {
+ static GnomeKeyring keyring;
+ return keyring;
+ }
+
+ const PasswordSchema* NETWORK_PASSWORD;
+ typedef gpointer ( store_password_fn )( const PasswordSchema* schema, const gchar* keyring,
+ const gchar* display_name, const gchar* password,
+ OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data,
+ ... );
+ typedef gpointer ( find_password_fn )( const PasswordSchema* schema,
+ OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data,
+ ... );
+ typedef gpointer ( delete_password_fn )( const PasswordSchema* schema,
+ OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data,
+ ... );
+ find_password_fn* find_password;
+ store_password_fn* store_password;
+ delete_password_fn* delete_password;
+};
+const char* GnomeKeyring::GNOME_KEYRING_DEFAULT = NULL;
+const char* GnomeKeyring::GNOME_KEYRING_SESSION = "session";
+
+namespace QKeychain {
+enum KeyringBackend {
+ Backend_GnomeKeyring,
+ Backend_Kwallet
+};
+static KeyringBackend detectKeyringBackend()
+{
+ if ( getenv( "GNOME_KEYRING_CONTROL" ) && GnomeKeyring::isSupported() )
+ return Backend_GnomeKeyring;
+ return Backend_Kwallet;
+}
+static KeyringBackend getKeyringBackend()
+{
+ static KeyringBackend backend = detectKeyringBackend();
+ return backend;
+}
+}
+
void ReadPasswordJobPrivate::scheduledStart() {
- iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this );
- const QDBusPendingReply<int> reply = iface->open( QLatin1String("kdewallet"), 0, q->service() );
- QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
- connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
+ switch ( getKeyringBackend() ) {
+ case Backend_GnomeKeyring:
+ if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(),
+ reinterpret_cast<GnomeKeyring::OperationGetStringCallback>( &ReadPasswordJobPrivate::gnomeKeyring_cb ),
+ this, NULL ) )
+ q->emitFinishedWithError( OtherError, tr("Unknown error") );
+ break;
+
+ case Backend_Kwallet:
+ iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this );
+ const QDBusPendingReply<int> reply = iface->open( QLatin1String("kdewallet"), 0, q->service() );
+ QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
+ connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
+ break;
+ }
+}
+
+void ReadPasswordJobPrivate::gnomeKeyring_cb( int result, const char* string, ReadPasswordJobPrivate* self )
+{
+ switch ( (GnomeKeyring::Result)result ) {
+ case GnomeKeyring::RESULT_OK:
+ if ( self->dataType == ReadPasswordJobPrivate::Text )
+ self->data = string;
+ else
+ self->data = QByteArray::fromBase64( string );
+ self->q->emitFinished();
+ break;
+
+ case GnomeKeyring::RESULT_DENIED: self->q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); break;
+ case GnomeKeyring::RESULT_NO_KEYRING_DAEMON: self->q->emitFinishedWithError( NoBackendAvailable, tr("No keyring daemon") ); break;
+ case GnomeKeyring::RESULT_ALREADY_UNLOCKED: self->q->emitFinishedWithError( OtherError, tr("Already unlocked") ); break;
+ case GnomeKeyring::RESULT_NO_SUCH_KEYRING: self->q->emitFinishedWithError( OtherError, tr("No such keyring") ); break;
+ case GnomeKeyring::RESULT_BAD_ARGUMENTS: self->q->emitFinishedWithError( OtherError, tr("Bad arguments") ); break;
+ case GnomeKeyring::RESULT_IO_ERROR: self->q->emitFinishedWithError( OtherError, tr("I/O error") ); break;
+ case GnomeKeyring::RESULT_CANCELLED: self->q->emitFinishedWithError( OtherError, tr("Cancelled") ); break;
+ case GnomeKeyring::RESULT_KEYRING_ALREADY_EXISTS: self->q->emitFinishedWithError( OtherError, tr("Keyring already exists") ); break;
+ case GnomeKeyring::RESULT_NO_MATCH: self->q->emitFinishedWithError( EntryNotFound, tr("No match") ); break;
+ default: self->q->emitFinishedWithError( OtherError, tr("Unknown error") ); break;
+ }
}
void ReadPasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
@@ -129,10 +302,48 @@ void ReadPasswordJobPrivate::kwalletReadFinished( QDBusPendingCallWatcher* watch
}
void WritePasswordJobPrivate::scheduledStart() {
- iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this );
- const QDBusPendingReply<int> reply = iface->open( QLatin1String("kdewallet"), 0, q->service() );
- QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
- connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
+ switch ( getKeyringBackend() ) {
+ case Backend_GnomeKeyring:
+ if ( mode == WritePasswordJobPrivate::Delete ) {
+ if ( !GnomeKeyring::delete_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(),
+ reinterpret_cast<GnomeKeyring::OperationDoneCallback>( &WritePasswordJobPrivate::gnomeKeyring_cb ),
+ this, NULL ) )
+ q->emitFinishedWithError( OtherError, tr("Unknown error") );
+ } else {
+ QByteArray password = mode == WritePasswordJobPrivate::Text ? textData.toUtf8() : binaryData.toBase64();
+ QByteArray service = q->service().toUtf8();
+ if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, service.constData(),
+ key.toUtf8().constData(), service.constData(), password.constData(),
+ reinterpret_cast<GnomeKeyring::OperationDoneCallback>( &WritePasswordJobPrivate::gnomeKeyring_cb ),
+ this, NULL ) )
+ q->emitFinishedWithError( OtherError, tr("Unknown error") );
+ }
+ break;
+
+ case Backend_Kwallet:
+ iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this );
+ const QDBusPendingReply<int> reply = iface->open( QLatin1String("kdewallet"), 0, q->service() );
+ QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this );
+ connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) );
+ break;
+ }
+}
+
+void WritePasswordJobPrivate::gnomeKeyring_cb( int result, WritePasswordJobPrivate* self )
+{
+ switch ( (GnomeKeyring::Result)result ) {
+ case GnomeKeyring::RESULT_OK: self->q->emitFinished(); break;
+ case GnomeKeyring::RESULT_DENIED: self->q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); break;
+ case GnomeKeyring::RESULT_NO_KEYRING_DAEMON: self->q->emitFinishedWithError( NoBackendAvailable, tr("No keyring daemon") ); break;
+ case GnomeKeyring::RESULT_ALREADY_UNLOCKED: self->q->emitFinishedWithError( OtherError, tr("Already unlocked") ); break;
+ case GnomeKeyring::RESULT_NO_SUCH_KEYRING: self->q->emitFinishedWithError( OtherError, tr("No such keyring") ); break;
+ case GnomeKeyring::RESULT_BAD_ARGUMENTS: self->q->emitFinishedWithError( OtherError, tr("Bad arguments") ); break;
+ case GnomeKeyring::RESULT_IO_ERROR: self->q->emitFinishedWithError( OtherError, tr("I/O error") ); break;
+ case GnomeKeyring::RESULT_CANCELLED: self->q->emitFinishedWithError( OtherError, tr("Cancelled") ); break;
+ case GnomeKeyring::RESULT_KEYRING_ALREADY_EXISTS: self->q->emitFinishedWithError( OtherError, tr("Keyring already exists") ); break;
+ case GnomeKeyring::RESULT_NO_MATCH: self->q->emitFinishedWithError( EntryNotFound, tr("No match") ); break;
+ default: self->q->emitFinishedWithError( OtherError, tr("Unknown error") ); break;
+ }
}
void WritePasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
diff --git a/keychain_p.h b/keychain_p.h
index 9b87d08..1f0f1f3 100644
--- a/keychain_p.h
+++ b/keychain_p.h
@@ -67,6 +67,7 @@ public:
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
org::kde::KWallet* iface;
+ static void gnomeKeyring_cb( int result, const char* string, ReadPasswordJobPrivate* data );
friend class QKeychain::JobExecutor;
private Q_SLOTS:
@@ -101,9 +102,9 @@ public:
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
org::kde::KWallet* iface;
+ static void gnomeKeyring_cb( int result, WritePasswordJobPrivate* self );
friend class QKeychain::JobExecutor;
-
private Q_SLOTS:
void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
void kwalletWriteFinished( QDBusPendingCallWatcher* watcher );
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/qtkeychain.git
More information about the Pkg-owncloud-commits
mailing list