[Pkg-owncloud-commits] [qtkeychain] 40/63: Added libsecret implementation.

Sandro Knauß hefee at debian.org
Sat Jun 10 14:39:30 UTC 2017


This is an automated email from the git hooks/post-receive script.

hefee pushed a commit to branch master
in repository qtkeychain.

commit 2426ebe04cc9b62cf3b8d5890c8faeb3f34303d4
Author: Armin Novak <armin.novak at thincast.com>
Date:   Mon Mar 14 10:16:06 2016 +0100

    Added libsecret implementation.
---
 libsecret.cpp | 334 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 libsecret_p.h |  33 ++++++
 2 files changed, 367 insertions(+)

diff --git a/libsecret.cpp b/libsecret.cpp
new file mode 100644
index 0000000..ad6383b
--- /dev/null
+++ b/libsecret.cpp
@@ -0,0 +1,334 @@
+#if defined(HAVE_LIBSECRET)
+#include <libsecret/secret.h>
+#endif
+
+#include "libsecret_p.h"
+
+#include <QLibrary>
+#include <QDebug>
+
+#if defined(HAVE_LIBSECRET)
+const SecretSchema* qtkeychainSchema(void) {
+    static const SecretSchema schema = {
+        "org.qt.keychain", SECRET_SCHEMA_NONE,
+        {
+            { "user", SECRET_SCHEMA_ATTRIBUTE_STRING },
+            { "server", SECRET_SCHEMA_ATTRIBUTE_STRING },
+            { "type", SECRET_SCHEMA_ATTRIBUTE_STRING }
+        }
+    };
+
+    return &schema;
+}
+
+typedef struct {
+    QKeychain::JobPrivate *self;
+    QString user;
+    QString server;
+} callbackArg;
+
+typedef void (*secret_password_lookup_t) (const SecretSchema *schema,
+                                          GCancellable *cancellable,
+                                          GAsyncReadyCallback callback,
+                                          gpointer user_data,
+                                          ...) G_GNUC_NULL_TERMINATED;
+typedef gchar *(*secret_password_lookup_finish_t) (GAsyncResult *result,
+                                                   GError **error);
+typedef void (*secret_password_store_t) (const SecretSchema *schema,
+                                         const gchar *collection,
+                                         const gchar *label,
+                                         const gchar *password,
+                                         GCancellable *cancellable,
+                                         GAsyncReadyCallback callback,
+                                         gpointer user_data,
+                                         ...) G_GNUC_NULL_TERMINATED;
+typedef gboolean (*secret_password_store_finish_t) (GAsyncResult *result,
+                                                    GError **error);
+typedef void (*secret_password_clear_t) (const SecretSchema *schema,
+                                         GCancellable *cancellable,
+                                         GAsyncReadyCallback callback,
+                                         gpointer user_data,
+                                         ...) G_GNUC_NULL_TERMINATED;
+typedef gboolean (*secret_password_clear_finish_t) (GAsyncResult *result,
+                                                    GError **error);
+typedef void (*secret_password_free_t) (gchar *password);
+typedef GQuark (*secret_error_get_quark_t) (void) G_GNUC_CONST;
+
+static secret_password_lookup_t secret_password_lookup_fn = NULL;
+static secret_password_lookup_finish_t secret_password_lookup_finish_fn = NULL;
+static secret_password_store_t secret_password_store_fn = NULL;
+static secret_password_store_finish_t secret_password_store_finish_fn = NULL;
+static secret_password_clear_t secret_password_clear_fn = NULL;
+static secret_password_clear_finish_t secret_password_clear_finish_fn = NULL;
+static secret_password_free_t secret_password_free_fn = NULL;
+static secret_error_get_quark_t secret_error_get_quark_fn = NULL;
+
+static QKeychain::Error gerrorToCode(const GError *error) {
+    if (error->domain != secret_error_get_quark_fn()) {
+        return QKeychain::OtherError;
+    }
+
+    switch(error->code) {
+    case SECRET_ERROR_NO_SUCH_OBJECT:
+        return QKeychain::EntryNotFound;
+    case SECRET_ERROR_IS_LOCKED:
+        return QKeychain::AccessDenied;
+    default:
+        return QKeychain::OtherError;
+    }
+}
+
+static void
+on_password_lookup (GObject *source,
+                    GAsyncResult *result,
+                    gpointer inst)
+{
+    GError *error = NULL;
+    callbackArg *arg = (callbackArg*)inst;
+    gchar *password = secret_password_lookup_finish_fn (result, &error);
+
+    Q_UNUSED(source);
+
+    if (arg) {
+        if (error) {
+            QKeychain::Error code = gerrorToCode(error);
+
+            arg->self->q->emitFinishedWithError( code, QString::fromUtf8(error->message) );
+        } else {
+            if (password != NULL) {
+                QByteArray raw = QByteArray(password);
+                switch(arg->self->mode) {
+                case QKeychain::JobPrivate::Binary:
+                    arg->self->data = QByteArray::fromBase64(raw);
+                    break;
+                case QKeychain::JobPrivate::Text:
+                default:
+                    arg->self->data = raw;
+                }
+
+                arg->self->q->emitFinished();
+            } else if (arg->self->mode == QKeychain::JobPrivate::Text) {
+                arg->self->mode = QKeychain::JobPrivate::Binary;
+                secret_password_lookup_fn (qtkeychainSchema(), NULL,
+                                           on_password_lookup, arg,
+                                           "user", arg->user.toUtf8().constData(),
+                                           "server", arg->server.toUtf8().constData(),
+                                           "type", "base64",
+                                           NULL);
+                return;
+            } else {
+                arg->self->q->emitFinishedWithError( QKeychain::EntryNotFound, QObject::tr("Entry not found") );
+            }
+        }
+    }
+    if (error) {
+        g_error_free (error);
+    }
+
+    if (password) {
+        secret_password_free_fn (password);
+    }
+
+    if (arg) {
+        delete arg;
+    }
+}
+
+static void
+on_password_stored (GObject *source,
+                    GAsyncResult *result,
+                    gpointer inst)
+{
+    GError *error = NULL;
+    QKeychain::JobPrivate *self = (QKeychain::JobPrivate*)inst;
+
+    Q_UNUSED(source);
+
+    secret_password_store_finish_fn (result, &error);
+
+    if (self) {
+        if (error != NULL) {
+            self->q->emitFinishedWithError( gerrorToCode(error),
+                                            QString::fromUtf8(error->message) );
+        } else {
+            self->q->emitFinished();
+        }
+    }
+    if (error != NULL) {
+        g_error_free (error);
+    }
+}
+
+static void
+on_password_cleared (GObject *source,
+                     GAsyncResult *result,
+                     gpointer inst)
+{
+    GError *error = NULL;
+    QKeychain::JobPrivate *self = (QKeychain::JobPrivate*)inst;
+    gboolean removed = secret_password_clear_finish_fn (result, &error);
+
+    Q_UNUSED(source);
+    if (self) {
+        if ( error ) {
+            self->q->emitFinishedWithError( gerrorToCode(error),
+                                            QString::fromUtf8(error->message) );
+        } else {
+            Q_UNUSED(removed);
+            self->q->emitFinished();
+        }
+    }
+    if (error != NULL) {
+        g_error_free (error);
+    }
+}
+
+static QString modeToString(QKeychain::JobPrivate::Mode mode) {
+    switch(mode) {
+    case QKeychain::JobPrivate::Binary:
+        return "base64";
+    default:
+        return "plaintext";
+    }
+}
+#endif
+
+bool LibSecretKeyring::isAvailable() {
+    const LibSecretKeyring& keyring = instance();
+#if defined(HAVE_LIBSECRET)
+    if (!keyring.isLoaded())
+        return false;
+    if (secret_password_lookup_fn == NULL)
+        return false;
+    if (secret_password_lookup_finish_fn == NULL)
+        return false;
+    if (secret_password_store_fn == NULL)
+        return false;
+    if (secret_password_store_finish_fn == NULL)
+        return false;
+    if (secret_password_clear_fn == NULL)
+        return false;
+    if (secret_password_clear_finish_fn == NULL)
+        return false;
+    if (secret_password_free_fn == NULL)
+        return false;
+    if (secret_error_get_quark_fn == NULL)
+        return false;
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool LibSecretKeyring::findPassword(const QString &user, const QString &server,
+                                    QKeychain::JobPrivate *self)
+{
+#if defined(HAVE_LIBSECRET)
+    if (!isAvailable()) {
+        return false;
+    }
+
+    self->mode = QKeychain::JobPrivate::Text;
+    self->data = QByteArray();
+
+    callbackArg *arg = new callbackArg;
+    arg->self = self;
+    arg->user = user;
+    arg->server = server;
+
+    qDebug() << Q_FUNC_INFO;
+    secret_password_lookup_fn (qtkeychainSchema(), NULL, on_password_lookup, arg,
+                               "user", user.toUtf8().constData(),
+                               "server", server.toUtf8().constData(),
+                               "type", "plaintext",
+                               NULL);
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool LibSecretKeyring::writePassword(const QString &display_name,
+                                     const QString &user,
+                                     const QString &server,
+                                     const QKeychain::JobPrivate::Mode mode,
+                                     const QByteArray &password,
+                                     QKeychain::JobPrivate *self)
+{
+#if defined(HAVE_LIBSECRET)
+    if (!isAvailable()) {
+        return false;
+    }
+
+    QString type = modeToString(mode);
+    QByteArray pwd;
+    switch(mode) {
+    case QKeychain::JobPrivate::Binary:
+        pwd = password.toBase64();
+        break;
+    default:
+        pwd = password;
+        break;
+    }
+
+    qDebug() << Q_FUNC_INFO;
+    secret_password_store_fn (qtkeychainSchema(), SECRET_COLLECTION_DEFAULT,
+                              display_name.toUtf8().constData(),
+                              pwd.constData(), NULL, on_password_stored, self,
+                              "user", user.toUtf8().constData(),
+                              "server", server.toUtf8().constData(),
+                              "type", type.toUtf8().constData(),
+                              NULL);
+    return true;
+#else
+    return false;
+#endif
+}
+
+bool LibSecretKeyring::deletePassword(const QString &key, const QString &service,
+                                      QKeychain::JobPrivate* self)
+{
+#if defined(HAVE_LIBSECRET)
+    if (!isAvailable()) {
+        return false;
+    }
+
+    qDebug() << Q_FUNC_INFO;
+    secret_password_clear_fn (qtkeychainSchema(), NULL, on_password_cleared, self,
+                              "user", key.toUtf8().constData(),
+                              "server", service.toUtf8().constData(),
+                              NULL);
+    return true;
+#else
+    return false;
+#endif
+}
+
+LibSecretKeyring::LibSecretKeyring()
+    : QLibrary("secret-1")
+{
+    if (load()) {
+        secret_password_lookup_fn =
+                (secret_password_lookup_t)resolve("secret_password_lookup");
+        secret_password_lookup_finish_fn =
+                (secret_password_lookup_finish_t)resolve("secret_password_lookup_finish");
+        secret_password_store_fn =
+                (secret_password_store_t)resolve("secret_password_store");
+        secret_password_store_finish_fn =
+                (secret_password_store_finish_t)resolve("secret_password_store_finish");
+        secret_password_clear_fn =
+                (secret_password_clear_t)resolve("secret_password_clear");
+        secret_password_clear_finish_fn =
+                (secret_password_clear_finish_t)resolve("secret_password_clear_finish");
+        secret_password_free_fn =
+                (secret_password_free_t)resolve("secret_password_free");
+        secret_error_get_quark_fn =
+                (secret_error_get_quark_t)resolve("secret_error_get_quark");
+    }
+}
+
+LibSecretKeyring &LibSecretKeyring::instance() {
+    static LibSecretKeyring instance;
+
+    return instance;
+}
diff --git a/libsecret_p.h b/libsecret_p.h
new file mode 100644
index 0000000..bd966fe
--- /dev/null
+++ b/libsecret_p.h
@@ -0,0 +1,33 @@
+#ifndef QTKEYCHAIN_LIBSECRET_P_H
+#define QTKEYCHAIN_LIBSECRET_P_H
+
+#include <QLibrary>
+
+#include "keychain_p.h"
+
+class LibSecretKeyring : public QLibrary {
+public:
+    static bool isAvailable();
+
+    static bool findPassword(const QString& user,
+			     const QString& server,
+			     QKeychain::JobPrivate* self);
+
+    static bool writePassword(const QString& display_name,
+			      const QString& user,
+			      const QString& server,
+			      const QKeychain::JobPrivate::Mode type,
+			      const QByteArray& password,
+			      QKeychain::JobPrivate* self);
+
+    static bool deletePassword(const QString &key, const QString &service,
+			       QKeychain::JobPrivate* self);
+
+private:
+    LibSecretKeyring();
+
+    static LibSecretKeyring &instance();
+};
+
+
+#endif

-- 
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