pidgin/pidgin

Merged in default (pull request #565)

2019-10-04, Gary Kramlich
691b13b22239
Merged in default (pull request #565)

kwallet updates

Approved-by: Elliott Sales de Andrade
Approved-by: John Bailey
--- a/libpurple/plugins/keyrings/kwallet.cpp Wed Oct 02 20:27:30 2019 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-/**
- * @file kwallet.cpp KWallet password storage
- * @ingroup plugins
- */
-
-/* purple
- *
- * Purple is the legal property of its developers, whose names are too numerous
- * to list here. Please refer to the COPYRIGHT file distributed with this
- * source distribution.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program ; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "internal.h"
-#include "account.h"
-#include "core.h"
-#include "debug.h"
-#include "keyring.h"
-#include "plugins.h"
-#include "version.h"
-
-#include <QQueue>
-#include <QCoreApplication>
-#include <kwallet.h>
-
-#define KWALLET_NAME N_("KWallet")
-#define KWALLET_DESCRIPTION N_("This plugin will store passwords in KWallet.")
-#define KWALLET_AUTHORS { "QuLogic (qulogic[at]pidgin.im)", NULL }
-#define KWALLET_ID "keyring-kwallet"
-#define KWALLET_DOMAIN (g_quark_from_static_string(KWALLET_ID))
-
-#define KWALLET_WALLET_NAME KWallet::Wallet::NetworkWallet()
-#define KWALLET_APP_NAME "Libpurple"
-#define KWALLET_FOLDER_NAME "libpurple"
-
-PurpleKeyring *keyring_handler = NULL;
-QCoreApplication *qCoreApp = NULL;
-
-namespace KWalletPlugin {
-
-class request
-{
- public:
- virtual ~request();
- virtual void detailedAbort(enum PurpleKeyringError error) = 0;
- void abort();
- virtual void execute(KWallet::Wallet *wallet) = 0;
-
- protected:
- gpointer data;
- PurpleAccount *account;
- QString password;
- bool noPassword;
-};
-
-class engine : private QObject, private QQueue<request*>
-{
- Q_OBJECT
-
- public:
- engine();
- ~engine();
- void queue(request *req);
- void abortAll();
- static engine *instance(bool create);
- static void closeInstance(void);
-
- private slots:
- void walletOpened(bool opened);
- void walletClosed();
-
- private:
- static engine *pinstance;
-
- bool connected;
- bool failed;
- bool closing;
- bool externallyClosed;
- bool busy;
- bool closeAfterBusy;
-
- KWallet::Wallet *wallet;
-
- void reopenWallet();
- void executeRequests();
-};
-
-class save_request : public request
-{
- public:
- save_request(PurpleAccount *account, const char *password,
- PurpleKeyringSaveCallback cb, void *data);
- void detailedAbort(enum PurpleKeyringError error);
- void execute(KWallet::Wallet *wallet);
-
- private:
- PurpleKeyringSaveCallback callback;
-};
-
-class read_request : public request
-{
- public:
- read_request(PurpleAccount *account,
- PurpleKeyringReadCallback cb, void *data);
- void detailedAbort(enum PurpleKeyringError error);
- void execute(KWallet::Wallet *wallet);
-
- private:
- PurpleKeyringReadCallback callback;
-};
-
-}
-
-static gboolean
-kwallet_is_enabled(void)
-{
- return KWallet::Wallet::isEnabled() ? TRUE : FALSE;
-}
-
-KWalletPlugin::engine *KWalletPlugin::engine::pinstance = NULL;
-
-KWalletPlugin::request::~request()
-{
-}
-
-void
-KWalletPlugin::request::abort()
-{
- detailedAbort(PURPLE_KEYRING_ERROR_CANCELLED);
-}
-
-KWalletPlugin::engine::engine()
-{
- connected = false;
- failed = false;
- closing = false;
- externallyClosed = false;
- wallet = NULL;
- busy = false;
- closeAfterBusy = false;
-
- reopenWallet();
-}
-
-void
-KWalletPlugin::engine::reopenWallet()
-{
- if (closing) {
- purple_debug_error("keyring-kwallet",
- "wallet is closing right now\n");
- failed = true;
- return;
- }
-
- connected = false;
- failed = false;
- externallyClosed = false;
-
- wallet = KWallet::Wallet::openWallet(KWALLET_WALLET_NAME, 0,
- KWallet::Wallet::Asynchronous);
- if (wallet == NULL) {
- failed = true;
- purple_debug_error("keyring-kwallet",
- "failed opening a wallet\n");
- return;
- }
-
- failed |= !connect(wallet, SIGNAL(walletClosed()),
- SLOT(walletClosed()));
- failed |= !connect(wallet, SIGNAL(walletOpened(bool)),
- SLOT(walletOpened(bool)));
- if (failed) {
- purple_debug_error("keyring-kwallet",
- "failed connecting to wallet signal\n");
- }
-}
-
-KWalletPlugin::engine::~engine()
-{
- closing = true;
-
- abortAll();
-
- delete wallet;
-
- if (pinstance == this)
- pinstance = NULL;
-}
-
-void
-KWalletPlugin::engine::abortAll()
-{
- int abortedCount = 0;
-
- while (!isEmpty()) {
- request *req = dequeue();
- req->abort();
- delete req;
- abortedCount++;
- }
-
- if (abortedCount > 0) {
- purple_debug_info("keyring-kwallet", "aborted requests: %d\n",
- abortedCount);
- }
-}
-
-KWalletPlugin::engine *
-KWalletPlugin::engine::instance(bool create)
-{
- if (pinstance == NULL && create)
- pinstance = new engine;
- return pinstance;
-}
-
-void
-KWalletPlugin::engine::closeInstance(void)
-{
- if (pinstance == NULL)
- return;
- if (pinstance->closing)
- return;
- if (pinstance->busy) {
- purple_debug_misc("keyring-kwallet",
- "current instance is busy, will be freed later\n");
- pinstance->closeAfterBusy = true;
- } else
- delete pinstance;
- pinstance = NULL;
-}
-
-void
-KWalletPlugin::engine::walletOpened(bool opened)
-{
- connected = opened;
-
- if (!opened) {
- purple_debug_warning("keyring-kwallet",
- "failed to open a wallet\n");
- delete this;
- return;
- }
-
- if (!wallet->hasFolder(KWALLET_FOLDER_NAME)) {
- if (!wallet->createFolder(KWALLET_FOLDER_NAME)) {
- purple_debug_error("keyring-kwallet",
- "couldn't create \"" KWALLET_FOLDER_NAME
- "\" folder in wallet\n");
- failed = true;
- }
- }
- if (!failed)
- wallet->setFolder(KWALLET_FOLDER_NAME);
-
- executeRequests();
-}
-
-void
-KWalletPlugin::engine::walletClosed()
-{
- if (!closing) {
- purple_debug_info("keyring-kwallet",
- "wallet was externally closed\n");
- externallyClosed = true;
- delete wallet;
- wallet = NULL;
- }
-}
-
-void
-KWalletPlugin::engine::queue(request *req)
-{
- enqueue(req);
- executeRequests();
-}
-
-void
-KWalletPlugin::engine::executeRequests()
-{
- if (closing || busy)
- return;
- busy = true;
- if (externallyClosed) {
- reopenWallet();
- } else if (connected || failed) {
- while (!isEmpty()) {
- request *req = dequeue();
- if (connected)
- req->execute(wallet);
- else
- req->abort();
- delete req;
- }
- } else if (purple_debug_is_verbose()) {
- purple_debug_misc("keyring-kwallet", "not yet connected\n");
- }
- busy = false;
- if (closeAfterBusy) {
- purple_debug_misc("keyring-kwallet",
- "instance freed after being busy\n");
- delete this;
- }
-}
-
-KWalletPlugin::save_request::save_request(PurpleAccount *acc, const char *pw,
- PurpleKeyringSaveCallback cb, void *userdata)
-{
- account = acc;
- data = userdata;
- callback = cb;
- password = QString(pw);
- noPassword = (pw == NULL);
-}
-
-KWalletPlugin::read_request::read_request(PurpleAccount *acc,
- PurpleKeyringReadCallback cb, void *userdata)
-{
- account = acc;
- data = userdata;
- callback = cb;
- password = QString();
-}
-
-void
-KWalletPlugin::save_request::detailedAbort(enum PurpleKeyringError error)
-{
- GError *gerror;
- if (callback == NULL)
- return;
-
- gerror = g_error_new(PURPLE_KEYRING_ERROR, error,
- _("Failed to save password."));
- callback(account, gerror, data);
- g_error_free(gerror);
-}
-
-void
-KWalletPlugin::read_request::detailedAbort(enum PurpleKeyringError error)
-{
- GError *gerror;
- if (callback == NULL)
- return;
-
- gerror = g_error_new(PURPLE_KEYRING_ERROR, error,
- _("Failed to read password."));
- callback(account, NULL, gerror, data);
- g_error_free(gerror);
-}
-
-static QString
-kwallet_account_key(PurpleAccount *account)
-{
- return QString(purple_account_get_protocol_id(account)) + ":" +
- purple_account_get_username(account);
-}
-
-void
-KWalletPlugin::read_request::execute(KWallet::Wallet *wallet)
-{
- int result;
-
- g_return_if_fail(wallet != NULL);
-
- result = wallet->readPassword(kwallet_account_key(account), password);
-
- if (result != 0) {
- purple_debug_warning("keyring-kwallet",
- "failed to read password, result was %d\n", result);
- abort();
- return;
- }
-
- purple_debug_misc("keyring-kwallet",
- "Got password for account %s (%s).\n",
- purple_account_get_username(account),
- purple_account_get_protocol_id(account));
-
- if (callback != NULL)
- callback(account, password.toUtf8().constData(), NULL, data);
-}
-
-void
-KWalletPlugin::save_request::execute(KWallet::Wallet *wallet)
-{
- int result;
-
- g_return_if_fail(wallet != NULL);
-
- if (noPassword)
- result = wallet->removeEntry(kwallet_account_key(account));
- else {
- result = wallet->writePassword(kwallet_account_key(account),
- password);
- }
-
- if (result != 0) {
- purple_debug_warning("keyring-kwallet",
- "failed to write password, result was %d\n", result);
- abort();
- return;
- }
-
- purple_debug_misc("keyring-kwallet",
- "Password %s for account %s (%s).\n",
- (noPassword ? "removed" : "saved"),
- purple_account_get_username(account),
- purple_account_get_protocol_id(account));
-
- if (callback != NULL)
- callback(account, NULL, data);
-}
-
-extern "C"
-{
-
-static void
-kwallet_read(PurpleAccount *account, PurpleKeyringReadCallback cb,
- gpointer data)
-{
- KWalletPlugin::read_request *req =
- new KWalletPlugin::read_request(account, cb, data);
-
- if (KWallet::Wallet::keyDoesNotExist(KWALLET_WALLET_NAME,
- KWALLET_FOLDER_NAME, kwallet_account_key(account)))
- {
- req->detailedAbort(PURPLE_KEYRING_ERROR_NOPASSWORD);
- delete req;
- }
- else
- KWalletPlugin::engine::instance(true)->queue(req);
-}
-
-static void
-kwallet_save(PurpleAccount *account, const char *password,
- PurpleKeyringSaveCallback cb, gpointer data)
-{
- if (password == NULL && KWallet::Wallet::keyDoesNotExist(
- KWALLET_WALLET_NAME, KWALLET_FOLDER_NAME,
- kwallet_account_key(account)))
- {
- if (cb != NULL)
- cb(account, NULL, data);
- }
- else
- KWalletPlugin::engine::instance(true)->queue(
- new KWalletPlugin::save_request(account, password, cb,
- data));
-}
-
-static void
-kwallet_cancel(void)
-{
- KWalletPlugin::engine *instance =
- KWalletPlugin::engine::instance(false);
- if (instance)
- instance->abortAll();
-}
-
-static void *
-kwallet_get_handle(void)
-{
- static int handle;
-
- return &handle;
-}
-
-static const char *kwallet_get_ui_name(void)
-{
- GHashTable *ui_info;
- const char *ui_name = NULL;
-
- ui_info = purple_core_get_ui_info();
- if (ui_info != NULL)
- ui_name = (const char*)g_hash_table_lookup(ui_info, "name");
- if (ui_name == NULL)
- ui_name = KWALLET_APP_NAME;
-
- return ui_name;
-}
-
-static PurplePluginInfo *
-plugin_query(GError **error)
-{
- const gchar * const authors[] = KWALLET_AUTHORS;
-
- return purple_plugin_info_new(
- "id", KWALLET_ID,
- "name", KWALLET_NAME,
- "version", DISPLAY_VERSION,
- "category", N_("Keyring"),
- "summary", "KWallet Keyring Plugin",
- "description", KWALLET_DESCRIPTION,
- "authors", authors,
- "website", PURPLE_WEBSITE,
- "abi-version", PURPLE_ABI_VERSION,
- "flags", PURPLE_PLUGIN_INFO_FLAGS_INTERNAL,
- NULL
- );
-}
-
-static gboolean
-plugin_load(PurplePlugin *plugin, GError **error)
-{
- if (!qCoreApp) {
- int argc = 0;
- qCoreApp = new QCoreApplication(argc, NULL);
- qCoreApp->setApplicationName(kwallet_get_ui_name());
- }
-
- if (!kwallet_is_enabled()) {
- g_set_error(error, KWALLET_DOMAIN, 0, "KWallet service is disabled.");
- purple_debug_info("keyring-kwallet",
- "KWallet service is disabled\n");
- return FALSE;
- }
-
- keyring_handler = purple_keyring_new();
-
- purple_keyring_set_name(keyring_handler, _(KWALLET_NAME));
- purple_keyring_set_id(keyring_handler, KWALLET_ID);
- purple_keyring_set_read_password(keyring_handler, kwallet_read);
- purple_keyring_set_save_password(keyring_handler, kwallet_save);
- purple_keyring_set_cancel_requests(keyring_handler, kwallet_cancel);
- purple_keyring_set_close_keyring(keyring_handler,
- KWalletPlugin::engine::closeInstance);
-
- purple_keyring_register(keyring_handler);
-
- return TRUE;
-}
-
-static gboolean
-plugin_unload(PurplePlugin *plugin, GError **error)
-{
- if (purple_keyring_get_inuse() == keyring_handler) {
- g_set_error(error, KWALLET_DOMAIN, 0, "The keyring is currently "
- "in use.");
- purple_debug_warning("keyring-kwallet",
- "keyring in use, cannot unload\n");
- return FALSE;
- }
-
- purple_signals_disconnect_by_handle(kwallet_get_handle());
-
- KWalletPlugin::engine::closeInstance();
-
- purple_keyring_unregister(keyring_handler);
- purple_keyring_free(keyring_handler);
- keyring_handler = NULL;
-
- if (qCoreApp) {
- delete qCoreApp;
- qCoreApp = NULL;
- }
-
- return TRUE;
-}
-
-PURPLE_PLUGIN_INIT(kwallet_keyring, plugin_query, plugin_load, plugin_unload);
-
-} /* extern "C" */
-
-#include "kwallet.moc"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/plugins/keyrings/kwallet/meson.build Fri Oct 04 03:36:29 2019 +0000
@@ -0,0 +1,13 @@
+if PLUGINS
+ if enable_kwallet
+ kwallet_moc = qt5.preprocess(
+ moc_headers: 'purplekwallet.h',
+ dependencies: qt5_dep,
+ )
+
+ kwallet_plugin = library('purplekwallet', 'purplekwallet.cpp', 'purplekwallet.h', kwallet_moc,
+ dependencies : [kwallet, qt5_dep, libpurple_dep],
+ name_prefix : '',
+ install : true, install_dir : PURPLE_PLUGINDIR)
+ endif
+endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/plugins/keyrings/kwallet/purplekwallet.cpp Fri Oct 04 03:36:29 2019 +0000
@@ -0,0 +1,500 @@
+/**
+ * @file kwallet.cpp KWallet password storage
+ * @ingroup plugins
+ */
+
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program ; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "internal.h"
+#include "account.h"
+#include "core.h"
+#include "debug.h"
+#include "plugins.h"
+#include "version.h"
+
+#include <QQueue>
+#include <QCoreApplication>
+
+#include "purplekwallet.h"
+
+#define KWALLET_NAME N_("KWallet")
+#define KWALLET_DESCRIPTION N_("This plugin will store passwords in KWallet.")
+#define KWALLET_AUTHORS { "QuLogic (qulogic[at]pidgin.im)", NULL }
+#define KWALLET_ID "keyring-kwallet"
+#define KWALLET_DOMAIN (g_quark_from_static_string(KWALLET_ID))
+
+#define KWALLET_WALLET_NAME KWallet::Wallet::NetworkWallet()
+#define KWALLET_APP_NAME "Libpurple"
+#define KWALLET_FOLDER_NAME "libpurple"
+
+PurpleKeyring *keyring_handler = NULL;
+QCoreApplication *qCoreApp = NULL;
+
+static gboolean
+kwallet_is_enabled(void)
+{
+ return KWallet::Wallet::isEnabled() ? TRUE : FALSE;
+}
+
+KWalletPlugin::engine *KWalletPlugin::engine::pinstance = NULL;
+
+KWalletPlugin::request::~request()
+{
+}
+
+void
+KWalletPlugin::request::abort()
+{
+ detailedAbort(PURPLE_KEYRING_ERROR_CANCELLED);
+}
+
+KWalletPlugin::engine::engine()
+{
+ connected = false;
+ failed = false;
+ closing = false;
+ externallyClosed = false;
+ wallet = NULL;
+ busy = false;
+ closeAfterBusy = false;
+
+ reopenWallet();
+}
+
+void
+KWalletPlugin::engine::reopenWallet()
+{
+ if (closing) {
+ purple_debug_error("keyring-kwallet",
+ "wallet is closing right now\n");
+ failed = true;
+ return;
+ }
+
+ connected = false;
+ failed = false;
+ externallyClosed = false;
+
+ wallet = KWallet::Wallet::openWallet(KWALLET_WALLET_NAME, 0,
+ KWallet::Wallet::Asynchronous);
+ if (wallet == NULL) {
+ failed = true;
+ purple_debug_error("keyring-kwallet",
+ "failed opening a wallet\n");
+ return;
+ }
+
+ failed |= !connect(wallet, SIGNAL(walletClosed()),
+ SLOT(walletClosed()));
+ failed |= !connect(wallet, SIGNAL(walletOpened(bool)),
+ SLOT(walletOpened(bool)));
+ if (failed) {
+ purple_debug_error("keyring-kwallet",
+ "failed connecting to wallet signal\n");
+ }
+}
+
+KWalletPlugin::engine::~engine()
+{
+ closing = true;
+
+ abortAll();
+
+ delete wallet;
+
+ if (pinstance == this)
+ pinstance = NULL;
+}
+
+void
+KWalletPlugin::engine::abortAll()
+{
+ int abortedCount = 0;
+
+ while (!isEmpty()) {
+ request *req = dequeue();
+ req->abort();
+ delete req;
+ abortedCount++;
+ }
+
+ if (abortedCount > 0) {
+ purple_debug_info("keyring-kwallet", "aborted requests: %d\n",
+ abortedCount);
+ }
+}
+
+KWalletPlugin::engine *
+KWalletPlugin::engine::instance(bool create)
+{
+ if (pinstance == NULL && create)
+ pinstance = new engine;
+ return pinstance;
+}
+
+void
+KWalletPlugin::engine::closeInstance(void)
+{
+ if (pinstance == NULL)
+ return;
+ if (pinstance->closing)
+ return;
+ if (pinstance->busy) {
+ purple_debug_misc("keyring-kwallet",
+ "current instance is busy, will be freed later\n");
+ pinstance->closeAfterBusy = true;
+ } else
+ delete pinstance;
+ pinstance = NULL;
+}
+
+void
+KWalletPlugin::engine::walletOpened(bool opened)
+{
+ connected = opened;
+
+ if (!opened) {
+ purple_debug_warning("keyring-kwallet",
+ "failed to open a wallet\n");
+ delete this;
+ return;
+ }
+
+ if (!wallet->hasFolder(KWALLET_FOLDER_NAME)) {
+ if (!wallet->createFolder(KWALLET_FOLDER_NAME)) {
+ purple_debug_error("keyring-kwallet",
+ "couldn't create \"" KWALLET_FOLDER_NAME
+ "\" folder in wallet\n");
+ failed = true;
+ }
+ }
+ if (!failed)
+ wallet->setFolder(KWALLET_FOLDER_NAME);
+
+ executeRequests();
+}
+
+void
+KWalletPlugin::engine::walletClosed()
+{
+ if (!closing) {
+ purple_debug_info("keyring-kwallet",
+ "wallet was externally closed\n");
+ externallyClosed = true;
+ delete wallet;
+ wallet = NULL;
+ }
+}
+
+void
+KWalletPlugin::engine::queue(request *req)
+{
+ enqueue(req);
+ executeRequests();
+}
+
+void
+KWalletPlugin::engine::executeRequests()
+{
+ if (closing || busy)
+ return;
+ busy = true;
+ if (externallyClosed) {
+ reopenWallet();
+ } else if (connected || failed) {
+ while (!isEmpty()) {
+ request *req = dequeue();
+ if (connected)
+ req->execute(wallet);
+ else
+ req->abort();
+ delete req;
+ }
+ } else if (purple_debug_is_verbose()) {
+ purple_debug_misc("keyring-kwallet", "not yet connected\n");
+ }
+ busy = false;
+ if (closeAfterBusy) {
+ purple_debug_misc("keyring-kwallet",
+ "instance freed after being busy\n");
+ delete this;
+ }
+}
+
+KWalletPlugin::save_request::save_request(PurpleAccount *acc, const char *pw,
+ PurpleKeyringSaveCallback cb, void *userdata)
+{
+ account = acc;
+ data = userdata;
+ callback = cb;
+ password = QString(pw);
+ noPassword = (pw == NULL);
+}
+
+KWalletPlugin::read_request::read_request(PurpleAccount *acc,
+ PurpleKeyringReadCallback cb, void *userdata)
+{
+ account = acc;
+ data = userdata;
+ callback = cb;
+ password = QString();
+}
+
+void
+KWalletPlugin::save_request::detailedAbort(enum PurpleKeyringError error)
+{
+ GError *gerror;
+ if (callback == NULL)
+ return;
+
+ gerror = g_error_new(PURPLE_KEYRING_ERROR, error,
+ _("Failed to save password."));
+ callback(account, gerror, data);
+ g_error_free(gerror);
+}
+
+void
+KWalletPlugin::read_request::detailedAbort(enum PurpleKeyringError error)
+{
+ GError *gerror;
+ if (callback == NULL)
+ return;
+
+ gerror = g_error_new(PURPLE_KEYRING_ERROR, error,
+ _("Failed to read password."));
+ callback(account, NULL, gerror, data);
+ g_error_free(gerror);
+}
+
+static QString
+kwallet_account_key(PurpleAccount *account)
+{
+ return QString(purple_account_get_protocol_id(account)) + ":" +
+ purple_account_get_username(account);
+}
+
+void
+KWalletPlugin::read_request::execute(KWallet::Wallet *wallet)
+{
+ int result;
+
+ g_return_if_fail(wallet != NULL);
+
+ result = wallet->readPassword(kwallet_account_key(account), password);
+
+ if (result != 0) {
+ purple_debug_warning("keyring-kwallet",
+ "failed to read password, result was %d\n", result);
+ abort();
+ return;
+ }
+
+ purple_debug_misc("keyring-kwallet",
+ "Got password for account %s (%s).\n",
+ purple_account_get_username(account),
+ purple_account_get_protocol_id(account));
+
+ if (callback != NULL)
+ callback(account, password.toUtf8().constData(), NULL, data);
+}
+
+void
+KWalletPlugin::save_request::execute(KWallet::Wallet *wallet)
+{
+ int result;
+
+ g_return_if_fail(wallet != NULL);
+
+ if (noPassword)
+ result = wallet->removeEntry(kwallet_account_key(account));
+ else {
+ result = wallet->writePassword(kwallet_account_key(account),
+ password);
+ }
+
+ if (result != 0) {
+ purple_debug_warning("keyring-kwallet",
+ "failed to write password, result was %d\n", result);
+ abort();
+ return;
+ }
+
+ purple_debug_misc("keyring-kwallet",
+ "Password %s for account %s (%s).\n",
+ (noPassword ? "removed" : "saved"),
+ purple_account_get_username(account),
+ purple_account_get_protocol_id(account));
+
+ if (callback != NULL)
+ callback(account, NULL, data);
+}
+
+extern "C"
+{
+
+static void
+kwallet_read(PurpleAccount *account, PurpleKeyringReadCallback cb,
+ gpointer data)
+{
+ KWalletPlugin::read_request *req =
+ new KWalletPlugin::read_request(account, cb, data);
+
+ if (KWallet::Wallet::keyDoesNotExist(KWALLET_WALLET_NAME,
+ KWALLET_FOLDER_NAME, kwallet_account_key(account)))
+ {
+ req->detailedAbort(PURPLE_KEYRING_ERROR_NOPASSWORD);
+ delete req;
+ }
+ else
+ KWalletPlugin::engine::instance(true)->queue(req);
+}
+
+static void
+kwallet_save(PurpleAccount *account, const char *password,
+ PurpleKeyringSaveCallback cb, gpointer data)
+{
+ if (password == NULL && KWallet::Wallet::keyDoesNotExist(
+ KWALLET_WALLET_NAME, KWALLET_FOLDER_NAME,
+ kwallet_account_key(account)))
+ {
+ if (cb != NULL)
+ cb(account, NULL, data);
+ }
+ else
+ KWalletPlugin::engine::instance(true)->queue(
+ new KWalletPlugin::save_request(account, password, cb,
+ data));
+}
+
+static void
+kwallet_cancel(void)
+{
+ KWalletPlugin::engine *instance =
+ KWalletPlugin::engine::instance(false);
+ if (instance)
+ instance->abortAll();
+}
+
+static void *
+kwallet_get_handle(void)
+{
+ static int handle;
+
+ return &handle;
+}
+
+static const char *kwallet_get_ui_name(void)
+{
+ GHashTable *ui_info;
+ const char *ui_name = NULL;
+
+ ui_info = purple_core_get_ui_info();
+ if (ui_info != NULL)
+ ui_name = (const char*)g_hash_table_lookup(ui_info, "name");
+ if (ui_name == NULL)
+ ui_name = KWALLET_APP_NAME;
+
+ return ui_name;
+}
+
+static PurplePluginInfo *
+plugin_query(GError **error)
+{
+ const gchar * const authors[] = KWALLET_AUTHORS;
+
+ return purple_plugin_info_new(
+ "id", KWALLET_ID,
+ "name", KWALLET_NAME,
+ "version", DISPLAY_VERSION,
+ "category", N_("Keyring"),
+ "summary", "KWallet Keyring Plugin",
+ "description", KWALLET_DESCRIPTION,
+ "authors", authors,
+ "website", PURPLE_WEBSITE,
+ "abi-version", PURPLE_ABI_VERSION,
+ "flags", PURPLE_PLUGIN_INFO_FLAGS_INTERNAL,
+
+ NULL
+ );
+}
+
+static gboolean
+plugin_load(PurplePlugin *plugin, GError **error)
+{
+ if (!qCoreApp) {
+ int argc = 0;
+ qCoreApp = new QCoreApplication(argc, NULL);
+ qCoreApp->setApplicationName(kwallet_get_ui_name());
+ }
+
+ if (!kwallet_is_enabled()) {
+ g_set_error(error, KWALLET_DOMAIN, 0, "KWallet service is disabled.");
+ purple_debug_info("keyring-kwallet",
+ "KWallet service is disabled\n");
+ return FALSE;
+ }
+
+ keyring_handler = purple_keyring_new();
+
+ purple_keyring_set_name(keyring_handler, _(KWALLET_NAME));
+ purple_keyring_set_id(keyring_handler, KWALLET_ID);
+ purple_keyring_set_read_password(keyring_handler, kwallet_read);
+ purple_keyring_set_save_password(keyring_handler, kwallet_save);
+ purple_keyring_set_cancel_requests(keyring_handler, kwallet_cancel);
+ purple_keyring_set_close_keyring(keyring_handler,
+ KWalletPlugin::engine::closeInstance);
+
+ purple_keyring_register(keyring_handler);
+
+ return TRUE;
+}
+
+static gboolean
+plugin_unload(PurplePlugin *plugin, GError **error)
+{
+ if (purple_keyring_get_inuse() == keyring_handler) {
+ g_set_error(error, KWALLET_DOMAIN, 0, "The keyring is currently "
+ "in use.");
+ purple_debug_warning("keyring-kwallet",
+ "keyring in use, cannot unload\n");
+ return FALSE;
+ }
+
+ purple_signals_disconnect_by_handle(kwallet_get_handle());
+
+ KWalletPlugin::engine::closeInstance();
+
+ purple_keyring_unregister(keyring_handler);
+ purple_keyring_free(keyring_handler);
+ keyring_handler = NULL;
+
+ if (qCoreApp) {
+ delete qCoreApp;
+ qCoreApp = NULL;
+ }
+
+ return TRUE;
+}
+
+PURPLE_PLUGIN_INIT(kwallet_keyring, plugin_query, plugin_load, plugin_unload);
+
+} /* extern "C" */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/plugins/keyrings/kwallet/purplekwallet.h Fri Oct 04 03:36:29 2019 +0000
@@ -0,0 +1,100 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program ; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+#include "internal.h"
+#include "keyring.h"
+
+#include <kwallet.h>
+#include <QQueue>
+
+namespace KWalletPlugin {
+
+class request
+{
+ public:
+ virtual ~request();
+ virtual void detailedAbort(enum PurpleKeyringError error) = 0;
+ void abort();
+ virtual void execute(KWallet::Wallet *wallet) = 0;
+
+ protected:
+ gpointer data;
+ PurpleAccount *account;
+ QString password;
+ bool noPassword;
+};
+
+class engine : private QObject, private QQueue<request*>
+{
+ Q_OBJECT
+
+ public:
+ engine();
+ ~engine();
+ void queue(request *req);
+ void abortAll();
+ static engine *instance(bool create);
+ static void closeInstance(void);
+
+ private slots:
+ void walletOpened(bool opened);
+ void walletClosed();
+
+ private:
+ static engine *pinstance;
+
+ bool connected;
+ bool failed;
+ bool closing;
+ bool externallyClosed;
+ bool busy;
+ bool closeAfterBusy;
+
+ KWallet::Wallet *wallet;
+
+ void reopenWallet();
+ void executeRequests();
+};
+
+class save_request : public request
+{
+ public:
+ save_request(PurpleAccount *account, const char *password,
+ PurpleKeyringSaveCallback cb, void *data);
+ void detailedAbort(enum PurpleKeyringError error);
+ void execute(KWallet::Wallet *wallet);
+
+ private:
+ PurpleKeyringSaveCallback callback;
+};
+
+class read_request : public request
+{
+ public:
+ read_request(PurpleAccount *account,
+ PurpleKeyringReadCallback cb, void *data);
+ void detailedAbort(enum PurpleKeyringError error);
+ void execute(KWallet::Wallet *wallet);
+
+ private:
+ PurpleKeyringReadCallback callback;
+};
+
+}
--- a/libpurple/plugins/keyrings/meson.build Wed Oct 02 20:27:30 2019 -0400
+++ b/libpurple/plugins/keyrings/meson.build Fri Oct 04 03:36:29 2019 +0000
@@ -1,4 +1,6 @@
if PLUGINS
+ subdir('kwallet')
+
if enable_nettle
internalkeyring_plugin = library('internalkeyring', 'internalkeyring.c',
dependencies : [nettle, libpurple_dep],
@@ -19,13 +21,4 @@
name_prefix : '',
install : true, install_dir : PURPLE_PLUGINDIR)
endif
-
- if enable_kwallet
- kwallet_moc = moc.process('kwallet.cpp')
-
- kwallet_plugin = library('kwallet', 'kwallet.cpp', kwallet_moc,
- dependencies : [kwallet, qt4, libpurple_dep],
- name_prefix : '',
- install : true, install_dir : PURPLE_PLUGINDIR)
- endif
endif # PLUGINS
--- a/meson.build Wed Oct 02 20:27:30 2019 -0400
+++ b/meson.build Fri Oct 04 03:36:29 2019 +0000
@@ -690,76 +690,18 @@
#######################################################################
enable_kwallet = get_option('kwallet') and not IS_WIN32
-enable_kwallet = false
if enable_kwallet
# Ensure C++ compiler works
add_languages('cpp')
cxx_compiler = meson.get_compiler('cpp')
-
- qt4 = dependency('qt4', modules : 'Core', required : force_deps)
- enable_kwallet = qt4.found()
-endif
+ add_project_arguments('-DHAVE_CONFIG_H=1', language : 'cpp')
-if enable_kwallet
-# AC_MSG_CHECKING([for metaobject compiler])
-# MOC=`$PKG_CONFIG --variable=moc_location QtCore`
-# AC_SUBST(MOC)
-# AC_MSG_RESULT([$MOC])
-#
-# KWALLET_CXXFLAGS=''
-# KWALLET_LIBS=''
-# if test -z '$with_kwallet_includes' || test -z '$with_kwallet_libs'; then
-# AC_CHECK_PROG(KDE4_CONFIG, kde4-config, kde4-config, no)
-# if test 'x$KDE4_CONFIG' = 'xno'; then
-# enable_kwallet = false
-# if test 'x$force_deps' = 'xyes'; then
-# AC_MSG_ERROR([
-#kde4-config not found. $KDE4_CONFIG
-#Use -Dkwallet=false if you do not need KWallet support.
-#])
-# fi
-# fi
-# fi
-endif
+ qt5 = import('qt5')
-if enable_kwallet
-# if test 'x$KDE4_CONFIG' != 'xno'; then
-# KWALLET_CXXFLAGS='$QT4_CFLAGS -I`$KDE4_CONFIG --path include`'
-# fi
-# CPPFLAGS='$CPPFLAGS $KWALLET_CXXFLAGS'
-# AC_CHECK_HEADER([kwallet.h], , [
-# enable_kwallet = false
-# if test 'x$force_deps' = 'xyes'; then
-# AC_MSG_ERROR([
-#KWallet development headers not found.
-#Use -Dkwallet=false if you do not need KWallet support.
-#])
-# fi
-#])
-endif
+ qt5_dep = dependency('qt5', modules: ['Core'])
-if enable_kwallet
-# AC_MSG_CHECKING([for KWallet libraries])
-# if test 'x$KDE4_CONFIG' != 'xno'; then
-# KWALLET_LIBS='-L`$KDE4_CONFIG --install lib`/kde4/devel -lkdeui'
-# else
-# KWALLET_LIBS='-lkdeui'
-# fi
-# KWALLET_LIBS='$KWALLET_LIBS'
-# LIBS='$LIBS $KWALLET_LIBS $QT4_LIBS'
-# AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <kwallet.h>],
-# [KWallet::Wallet::LocalWallet();])], [AC_MSG_RESULT([yes])],
-# [
-# AC_MSG_RESULT(no)
-# enable_kwallet = false
-# if test 'x$force_deps' = 'xyes'; then
-# AC_MSG_ERROR([
-#KWallet development libraries not found.
-#Use -Dkwallet=false if you do not need KWallet support.
-#])
-# fi
-# ])
+ kwallet = dependency('KF5Wallet')
endif
#######################################################################