Patch by Christian Hesse, fixes bug #2868.
endif
pgpcore_la_SOURCES = \
+ autocompletion.c \
passphrase.c \
plugin.c \
prefs_gpg.c \
pluginincludedir = $(pkgincludedir)/plugins/pgpcore
plugininclude_HEADERS = \
+ autocompletion.h \
passphrase.h \
prefs_gpg.h \
select-keys.h \
--- /dev/null
+/*
+ * PGP/Core keyring autocompletion
+ *
+ * Copyright (C) 2014 Christian Hesse <mail@eworm.de>
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <gpgme.h>
+
+#include "autocompletion.h"
+
+static guint autocompletion_hook_id = 0;
+
+static gboolean pgp_autocompletion_hook(gpointer source, gpointer data)
+{
+ gpgme_ctx_t ctx;
+ gpgme_key_t key;
+ gpgme_error_t err;
+ gpgme_user_id_t uid;
+ address_entry *ae;
+
+ /* just return if autocompletion is disabled */
+ if (!prefs_gpg_get_config()->autocompletion)
+ return EXIT_SUCCESS;
+
+ /* initialize */
+ gpgme_check_version(NULL);
+
+ if ((err = gpgme_new(&ctx)) == 0) {
+ err = gpgme_op_keylist_start(ctx, NULL, 0);
+
+ /* walk the available keys */
+ while (err == 0) {
+ if ((err = gpgme_op_keylist_next(ctx, &key)) != 0)
+ break;
+
+ /* skip keys that are revoked, expired, ... */
+ if ((key->revoked || key->expired || key->disabled || key->invalid) == FALSE) {
+ uid = key->uids;
+
+ /* walk all user ids within a key */
+ while (uid != NULL) {
+ if (uid->email != NULL && *uid->email != 0) {
+ ae = g_new0(address_entry, 1);
+
+ ae->address = g_strdup(uid->email);
+ addr_compl_add_address1(ae->address, ae);
+
+ if (uid->name != NULL && *uid->name != 0) {
+ ae->name = g_strdup(uid->name);
+ addr_compl_add_address1(ae->name, ae);
+ } else
+ ae->name = NULL;
+
+ ae->grp_emails = NULL;
+
+ source = g_list_prepend(source, ae);
+
+ debug_print("%s <%s>\n", uid->name, uid->email);
+ }
+ uid = uid->next;
+ }
+ }
+ gpgme_key_release(key);
+ }
+ gpgme_release(ctx);
+ }
+
+ if (gpg_err_code(err) != GPG_ERR_EOF) {
+ debug_print("can not list keys: %s\n", gpgme_strerror(err));
+ exit(EXIT_FAILURE);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+gboolean autocompletion_done(void)
+{
+ if (autocompletion_hook_id > 0)
+ {
+ hooks_unregister_hook(ADDDRESS_COMPLETION_BUILD_ADDRESS_LIST_HOOKLIST, autocompletion_hook_id);
+
+ debug_print("PGP address autocompletion hook unregistered\n");
+ }
+
+ return TRUE;
+}
+
+gint autocompletion_init(gchar ** error)
+{
+ if ((autocompletion_hook_id = hooks_register_hook(ADDDRESS_COMPLETION_BUILD_ADDRESS_LIST_HOOKLIST, pgp_autocompletion_hook, NULL)) == -1)
+ {
+ *error = g_strdup(_("Failed to register PGP address autocompletion hook"));
+ return -1;
+ }
+ debug_print("PGP address autocompletion hook registered\n");
+
+ return EXIT_SUCCESS;
+}
+
--- /dev/null
+/*
+ * PGP/Core keyring autocompletion
+ *
+ * Copyright (C) 2014 Christian Hesse <mail@eworm.de>
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GPGMEGTK_AUTOCOMPLETION_H
+#define GPGMEGTK_AUTOCOMPLETION_H
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <gpgme.h>
+#include <plugins/pgpcore/prefs_gpg.h>
+
+#include "addr_compl.h"
+#include "claws.h"
+#include "hooks.h"
+#include "procmsg.h"
+#include "utils.h"
+
+static gboolean pgp_autocompletion_hook(gpointer source, gpointer data);
+
+gboolean autocompletion_done(void);
+
+gint autocompletion_init(gchar ** error);
+
+#endif /* GPGMEGTK_AUTOCOMPLETION_H */
#include "sgpgme.h"
#include "prefs_gpg.h"
#include "pgp_viewer.h"
+#include "autocompletion.h"
#include "plugin.h"
#define PLUGIN_NAME (_("PGP/Core"))
prefs_gpg_init();
sgpgme_check_create_key();
pgp_viewer_init();
- return 0;
+ autocompletion_init(error);
+
+ return 0;
}
gboolean plugin_done(void)
pgp_viewer_done();
prefs_gpg_done();
sgpgme_done();
+ autocompletion_done();
+
return TRUE;
}
const gchar *plugin_desc(void)
{
- return _("This plugin handles PGP core operations, it is used by other "
+ return _("This plugin handles PGP core operations and provides address "
+ "autocompletion from the GPG keyring. It is used by other "
"plugins, like PGP/Mime.\n"
"\n"
"Options can be found in /Configuration/Preferences/Plugins/GPG "
{"auto_check_signatures", "FALSE",
&prefs_gpg.auto_check_signatures, P_BOOL,
NULL, NULL, NULL},
+ {"autocompletion", "FALSE",
+ &prefs_gpg.autocompletion, P_BOOL,
+ NULL, NULL, NULL},
{"use_gpg_agent", "TRUE", &prefs_gpg.use_gpg_agent, P_BOOL,
NULL, NULL, NULL},
{"store_passphrase", "FALSE", &prefs_gpg.store_passphrase, P_BOOL,
PrefsPage page;
GtkWidget *checkbtn_auto_check_signatures;
+ GtkWidget *checkbtn_autocompletion;
GtkWidget *checkbtn_use_gpg_agent;
GtkWidget *checkbtn_store_passphrase;
GtkWidget *spinbtn_store_passphrase;
GtkWidget *checkbtn_passphrase_grab;
GtkWidget *checkbtn_store_passphrase;
GtkWidget *checkbtn_auto_check_signatures;
+ GtkWidget *checkbtn_autocompletion;
GtkWidget *checkbtn_gpg_warning;
GtkWidget *hbox1;
GtkWidget *vbox1, *vbox2;
PACK_CHECK_BUTTON (vbox2, checkbtn_auto_check_signatures,
_("Automatically check signatures"));
+ PACK_CHECK_BUTTON (vbox2, checkbtn_autocompletion,
+ _("Use keyring for address autocompletion"));
+
vbox2 = gtkut_get_options_frame(vbox1, &frame_passphrase, _("Passphrase"));
PACK_CHECK_BUTTON (vbox2, checkbtn_use_gpg_agent,
config = prefs_gpg_get_config();
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_auto_check_signatures), config->auto_check_signatures);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_autocompletion), config->autocompletion);
if (!getenv("GPG_AGENT_INFO"))
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent), FALSE);
else
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_gpg_warning), config->gpg_warning);
page->checkbtn_auto_check_signatures = checkbtn_auto_check_signatures;
+ page->checkbtn_autocompletion = checkbtn_autocompletion;
page->checkbtn_store_passphrase = checkbtn_store_passphrase;
page->spinbtn_store_passphrase = spinbtn_store_passphrase;
page->checkbtn_passphrase_grab = checkbtn_passphrase_grab;
config->auto_check_signatures =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_auto_check_signatures));
+ config->autocompletion =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_autocompletion));
config->use_gpg_agent =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_use_gpg_agent));
config->store_passphrase =
*
*/
+#ifndef GPGMEGTK_PREFS_GPG_H
+#define GPGMEGTK_PREFS_GPG_H
+
typedef struct GPGConfig GPGConfig;
typedef struct GPGAccountConfig GPGAccountConfig;
struct GPGConfig
{
gboolean auto_check_signatures;
+ gboolean autocompletion;
gboolean use_gpg_agent;
gboolean store_passphrase;
gint store_passphrase_timeout;
void prefs_gpg_remove_skip_encryption_warning(const gchar *systemid);
gboolean prefs_gpg_should_skip_encryption_warning(const gchar *systemid);
gboolean prefs_gpg_auto_check_signatures(void);
+
+#endif /* GPGMEGTK_PREFS_GPG_H */