[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