[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