[seahorse] Fix seahorse so it doesn't crash if gpg or gpg2 don't load.



commit d83bf011b7c549664eb6bb1edb7a7c03fea42060
Author: Stef Walter <stefw collabora co uk>
Date:   Mon Nov 14 10:51:25 2011 +0100

    Fix seahorse so it doesn't crash if gpg or gpg2 don't load.
    
     * Print out informative message when creating a gpgme context fails
     * Rework all code paths to handle such failures.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=659529

 pgp/seahorse-gpg-options.c        |   80 ++++++++++----------
 pgp/seahorse-gpgme-key-op.c       |   79 ++++++++++++--------
 pgp/seahorse-gpgme-key.c          |    5 +-
 pgp/seahorse-gpgme-keyring.c      |  147 ++++++++++++++++++++-----------------
 pgp/seahorse-gpgme-keyring.h      |    3 +-
 pgp/seahorse-pgp-key-properties.c |    9 ++-
 6 files changed, 177 insertions(+), 146 deletions(-)
---
diff --git a/pgp/seahorse-gpg-options.c b/pgp/seahorse-gpg-options.c
index f73bef4..d21f420 100644
--- a/pgp/seahorse-gpg-options.c
+++ b/pgp/seahorse-gpg-options.c
@@ -71,13 +71,14 @@ create_file (const gchar *file, mode_t mode, GError **err)
 static gchar *
 find_config_file (gboolean read, GError **err)
 {
-    gchar *conf = NULL;
+	gchar *conf = NULL;
 
-    g_assert (gpg_options_inited);
-    g_assert (!err || !*err);
+	g_assert (!err || !*err);
 
-    if (!gpg_homedir)
-        return NULL;
+	if (!gpg_options_inited)
+		return NULL;
+	if (!gpg_homedir)
+		return NULL;
 
     /* Check for and open ~/.gnupg/gpg.conf */
     conf = g_strconcat (gpg_homedir, "/gpg.conf", NULL);
@@ -239,35 +240,37 @@ parse_home_directory (gpgme_engine_info_t engine, GError **err)
 static gboolean
 gpg_options_init (GError **err)
 {
-    if (!gpg_options_inited) {
-        gpgme_error_t gerr;
-        gpgme_engine_info_t engine;
-
-        gerr = gpgme_get_engine_info (&engine);
-        g_return_val_if_fail (GPG_IS_OK (gerr),
-                              (seahorse_gpgme_propagate_error (gerr, err), FALSE));
-
-        /* Look for the OpenPGP engine */
-        while (engine && engine->protocol != GPGME_PROTOCOL_OpenPGP)
-            engine = engine->next;
-
-        /* 
-         * Make sure it's the right version for us to be messing 
-         * around with the configuration file.
-         */
-        g_return_val_if_fail (engine && engine->version && engine->file_name &&
-                              (g_str_has_prefix (engine->version, GPG_VERSION_PREFIX1) ||
-                               g_str_has_prefix (engine->version, GPG_VERSION_PREFIX2)),
-                              (seahorse_gpgme_propagate_error (GPG_E (GPG_ERR_INV_ENGINE), err), FALSE));
-
-        /* Now run the binary and read in the home directory */
-        if (!parse_home_directory (engine, err))
-            return FALSE;
-
-        gpg_options_inited = TRUE;
-    }
-
-    return TRUE;
+	gpgme_error_t gerr;
+	gpgme_engine_info_t engine;
+
+	if (gpg_options_inited)
+		return TRUE;
+
+	gerr = gpgme_get_engine_info (&engine);
+	if (seahorse_gpgme_propagate_error (gerr, err))
+		return FALSE;
+
+	/* Look for the OpenPGP engine */
+	while (engine && engine->protocol != GPGME_PROTOCOL_OpenPGP)
+		engine = engine->next;
+
+	/*
+	 * Make sure it's the right version for us to be messing
+	 * around with the configuration file.
+	 */
+	if (!engine || !engine->version || !engine->file_name ||
+	    !(g_str_has_prefix (engine->version, GPG_VERSION_PREFIX1) ||
+	      g_str_has_prefix (engine->version, GPG_VERSION_PREFIX2))) {
+		seahorse_gpgme_propagate_error (GPG_E (GPG_ERR_INV_ENGINE), err);
+		return FALSE;
+	}
+
+	/* Now run the binary and read in the home directory */
+	if (!parse_home_directory (engine, err))
+		return FALSE;
+
+	gpg_options_inited = TRUE;
+	return TRUE;
 }
 
 /**
@@ -275,13 +278,12 @@ gpg_options_init (GError **err)
  * 
  * Returns: The home dir that GPG uses for it's keys and configuration
  **/
-const gchar*
+const gchar *
 seahorse_gpg_homedir (void)
 {
-    /* THis shouldn't normally fail, and as such we return an invalid 
-     * directory to avoid NULL memory access */
-    g_return_val_if_fail (gpg_options_init (NULL), "/invalid/gpg/dir");
-    return gpg_homedir;
+	if (!gpg_options_init (NULL))
+		return NULL;
+	return gpg_homedir;
 }
 
 /**
diff --git a/pgp/seahorse-gpgme-key-op.c b/pgp/seahorse-gpgme-key-op.c
index 5011903..a529daf 100644
--- a/pgp/seahorse-gpgme-key-op.c
+++ b/pgp/seahorse-gpgme-key-op.c
@@ -69,7 +69,8 @@ key_op_generate_free (gpointer data)
 {
 	key_op_generate_closure *closure = data;
 	g_clear_object (&closure->cancellable);
-	gpgme_release (closure->gctx);
+	if (closure->gctx)
+		gpgme_release (closure->gctx);
 	g_free (closure);
 }
 
@@ -134,7 +135,7 @@ seahorse_gpgme_key_op_generate_async (SeahorseGpgmeKeyring *keyring,
 	GSimpleAsyncResult *res;
 	GError *error = NULL;
 	const gchar *parms;
-	gpgme_error_t gerr;
+	gpgme_error_t gerr = 0;
 	GSource *gsource;
 
 	g_return_if_fail (SEAHORSE_IS_GPGME_KEYRING (keyring));
@@ -193,7 +194,7 @@ seahorse_gpgme_key_op_generate_async (SeahorseGpgmeKeyring *keyring,
 	                                 seahorse_gpgme_key_op_generate_async);
 
 	closure = g_new0 (key_op_generate_closure, 1);
-	closure->gctx = seahorse_gpgme_keyring_new_context ();
+	closure->gctx = seahorse_gpgme_keyring_new_context (&gerr);
 	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 	gpgme_set_progress_cb (closure->gctx, on_key_op_generate_progress, res);
 	g_simple_async_result_set_op_res_gpointer (res, closure, key_op_generate_free);
@@ -203,7 +204,9 @@ seahorse_gpgme_key_op_generate_async (SeahorseGpgmeKeyring *keyring,
 	g_source_set_callback (gsource, (GSourceFunc)on_key_op_generate_complete,
 	                       g_object_ref (res), g_object_unref);
 
-	gerr = gpgme_op_genkey_start (closure->gctx, parms, NULL, NULL);
+	if (gerr == 0)
+		gerr = gpgme_op_genkey_start (closure->gctx, parms, NULL, NULL);
+
 	if (seahorse_gpgme_propagate_error (gerr, &error)) {
 		g_simple_async_result_take_error (res, error);
 		g_simple_async_result_complete_in_idle (res);
@@ -240,23 +243,28 @@ static gpgme_error_t
 op_delete (SeahorseGpgmeKey *pkey, gboolean secret)
 {
 	SeahorseGpgmeKeyring *keyring;
-	gpgme_error_t err;
+	gpgme_error_t gerr;
 	gpgme_key_t key;
+	gpgme_ctx_t ctx;
 
 	keyring = SEAHORSE_GPGME_KEYRING (seahorse_object_get_place (SEAHORSE_OBJECT (pkey)));
 	g_return_val_if_fail (SEAHORSE_IS_GPGME_KEYRING (keyring), GPG_E (GPG_ERR_INV_KEYRING));
 
 	g_object_ref (pkey);
-	
+
 	seahorse_util_wait_until ((key = seahorse_gpgme_key_get_public (pkey)) != NULL);
 
-	err = gpgme_op_delete (keyring->gctx, key, secret);
-	if (GPG_IS_OK (err))
-		seahorse_gpgme_keyring_remove_key (keyring, pkey);
+	ctx = seahorse_gpgme_keyring_new_context (&gerr);
+	if (ctx == NULL)
+		return gerr;
+
+	gerr = gpgme_op_delete (ctx, key, secret);
+	if (GPG_IS_OK (gerr))
+		seahorse_gpgme_keyring_remove_key (keyring, SEAHORSE_GPGME_KEY (pkey));
 
+	gpgme_release (ctx);
 	g_object_unref (pkey);
-	
-	return err;
+	return gerr;
 }
 
 gpgme_error_t
@@ -344,39 +352,39 @@ seahorse_gpgme_key_op_edit (gpointer data, gpgme_status_code_t status,
 
 /* Common edit operation */
 static gpgme_error_t
-edit_gpgme_key (gpgme_ctx_t ctx, gpgme_key_t key, SeahorseEditParm *parms)
+edit_gpgme_key (gpgme_ctx_t ctx,
+                gpgme_key_t key,
+                SeahorseEditParm *parms)
 {
 	gboolean own_context = FALSE;
 	gpgme_data_t out;
 	gpgme_error_t gerr;
-    
+
 	g_assert (key);
 	g_assert (parms);
-	
+
 	gpgme_key_ref (key);
-    
-	if (!ctx) {
-		ctx = seahorse_gpgme_keyring_new_context ();
-		g_return_val_if_fail (ctx, GPG_E (GPG_ERR_GENERAL));
+
+	if (ctx == NULL) {
+		ctx = seahorse_gpgme_keyring_new_context (&gerr);
+		if (ctx == NULL)
+			return gerr;
 		own_context = TRUE;
 	}
-    
+
 	out = seahorse_gpgme_data_new ();
-    
+
 	/* do edit callback, release data */
 	gerr = gpgme_op_edit (ctx, key, seahorse_gpgme_key_op_edit, parms, out);
 
 	if (gpgme_err_code (gerr) == GPG_ERR_BAD_PASSPHRASE) {
 		seahorse_util_show_error(NULL, _("Wrong password"), _("This was the third time you entered a wrong password. Please try again."));
 	}
-	
+
 	seahorse_gpgme_data_release (out);
-    
 	if (own_context)
 		gpgme_release (ctx);
-	
 	gpgme_key_unref (key);
-	
 	return gerr;
 }
 
@@ -396,21 +404,25 @@ static gpgme_error_t
 edit_key (SeahorseGpgmeKey *pkey, SeahorseEditParm *parms)
 {
 	SeahorseGpgmeKeyring *keyring;
-	gpgme_error_t err;
+	gpgme_error_t gerr;
 	gpgme_key_t key;
+	gpgme_ctx_t ctx;
 
 	keyring = SEAHORSE_GPGME_KEYRING (seahorse_object_get_place (SEAHORSE_OBJECT (pkey)));
 	g_return_val_if_fail (SEAHORSE_IS_GPGME_KEYRING (keyring), GPG_E (GPG_ERR_INV_KEYRING));
 
 	g_object_ref (pkey);
-	
+
 	seahorse_util_wait_until ((key = seahorse_gpgme_key_get_public (pkey)) != NULL);
-  
-	err = edit_refresh_gpgme_key (keyring->gctx, key, parms);
+
+	ctx = seahorse_gpgme_keyring_new_context (&gerr);
+	if (ctx != NULL) {
+		gerr = edit_refresh_gpgme_key (ctx, key, parms);
+		gpgme_release (ctx);
+	}
 
 	g_object_unref (pkey);
-    
-	return err;
+	return gerr;
 }
 
 typedef struct
@@ -586,9 +598,10 @@ sign_process (gpgme_key_t signed_key, gpgme_key_t signing_key, guint sign_index,
 	gpgme_ctx_t ctx;
 	gpgme_error_t gerr;
 
-	ctx = seahorse_gpgme_keyring_new_context ();
-	g_return_val_if_fail (ctx, GPG_E (GPG_ERR_GENERAL));
-	
+	ctx = seahorse_gpgme_keyring_new_context (&gerr);
+	if (ctx == NULL)
+		return gerr;
+
         gerr = gpgme_signers_add (ctx, signing_key);
         if (!GPG_IS_OK (gerr))
         	return gerr;
diff --git a/pgp/seahorse-gpgme-key.c b/pgp/seahorse-gpgme-key.c
index f36793a..89f086f 100644
--- a/pgp/seahorse-gpgme-key.c
+++ b/pgp/seahorse-gpgme-key.c
@@ -77,7 +77,10 @@ load_gpgme_key (const gchar *keyid,
 	gpgme_ctx_t ctx;
 	gpgme_error_t gerr;
 
-	ctx = seahorse_gpgme_keyring_new_context ();
+	ctx = seahorse_gpgme_keyring_new_context (&gerr);
+	if (gerr != 0)
+		return FALSE;
+
 	gpgme_set_keylist_mode (ctx, mode);
 	gerr = gpgme_op_keylist_start (ctx, keyid, secret);
 	if (GPG_IS_OK (gerr)) {
diff --git a/pgp/seahorse-gpgme-keyring.c b/pgp/seahorse-gpgme-keyring.c
index 1f5de02..ee8652d 100644
--- a/pgp/seahorse-gpgme-keyring.c
+++ b/pgp/seahorse-gpgme-keyring.c
@@ -123,29 +123,6 @@ passphrase_get (gconstpointer dummy, const gchar *passphrase_hint,
 	return err;
 }
 
-/* Initialise a GPGME context for PGP keys */
-static gpgme_error_t
-init_gpgme (gpgme_ctx_t *ctx)
-{
-	gpgme_protocol_t proto = GPGME_PROTOCOL_OpenPGP;
-	gpgme_error_t err;
-
-	err = gpgme_engine_check_version (proto);
-	g_return_val_if_fail (GPG_IS_OK (err), err);
-
-	err = gpgme_new (ctx);
-	g_return_val_if_fail (GPG_IS_OK (err), err);
-
-	err = gpgme_set_protocol (*ctx, proto);
-	g_return_val_if_fail (GPG_IS_OK (err), err);
-
-	gpgme_set_passphrase_cb (*ctx, (gpgme_passphrase_cb_t)passphrase_get,
-	                         NULL);
-
-	gpgme_set_keylist_mode (*ctx, GPGME_KEYLIST_MODE_LOCAL);
-	return err;
-}
-
 struct _SeahorseGpgmeKeyringPrivate {
 	GHashTable *keys;
 	guint scheduled_refresh;                /* Source for refresh timeout */
@@ -177,7 +154,8 @@ static void
 keyring_list_free (gpointer data)
 {
 	keyring_list_closure *closure = data;
-	gpgme_release (closure->gctx);
+	if (closure->gctx)
+		gpgme_release (closure->gctx);
 	if (closure->checks)
 		g_hash_table_destroy (closure->checks);
 	g_cancellable_disconnect (closure->cancellable,
@@ -355,8 +333,9 @@ seahorse_gpgme_keyring_list_async (SeahorseGpgmeKeyring *self,
 	keyring_list_closure *closure;
 	GSimpleAsyncResult *res;
 	SeahorseObject *object;
-	gpgme_error_t gerr;
+	gpgme_error_t gerr = 0;
 	GHashTableIter iter;
+	GError *error = NULL;
 	gchar *keyid;
 
 	res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
@@ -364,22 +343,29 @@ seahorse_gpgme_keyring_list_async (SeahorseGpgmeKeyring *self,
 
 	closure = g_new0 (keyring_list_closure, 1);
 	closure->parts = parts;
-	closure->gctx = seahorse_gpgme_keyring_new_context ();
+	closure->gctx = seahorse_gpgme_keyring_new_context (&gerr);
 	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 	closure->keyring = g_object_ref (self);
 	g_simple_async_result_set_op_res_gpointer (res, closure, keyring_list_free);
 
-	if (parts & LOAD_FULL) {
-		gpgme_set_keylist_mode (closure->gctx, GPGME_KEYLIST_MODE_SIGS |
-		                        gpgme_get_keylist_mode (closure->gctx));
+	/* Start the key listing */
+	if (closure->gctx) {
+		if (parts & LOAD_FULL)
+			gpgme_set_keylist_mode (closure->gctx, GPGME_KEYLIST_MODE_SIGS |
+			                        gpgme_get_keylist_mode (closure->gctx));
+		if (patterns)
+			gerr = gpgme_op_keylist_ext_start (closure->gctx, patterns, secret, 0);
+		else
+			gerr = gpgme_op_keylist_start (closure->gctx, NULL, secret);
 	}
 
-	/* Start the key listing */
-	if (patterns)
-		gerr = gpgme_op_keylist_ext_start (closure->gctx, patterns, secret, 0);
-	else
-		gerr = gpgme_op_keylist_start (closure->gctx, NULL, secret);
-	g_return_if_fail (GPG_IS_OK (gerr));
+	if (gerr != 0) {
+		seahorse_gpgme_propagate_error (gerr, &error);
+		g_simple_async_result_take_error (res, error);
+		g_simple_async_result_complete_in_idle (res);
+		g_object_unref (res);
+		return;
+	}
 
 	/* Loading all the keys? */
 	if (patterns == NULL) {
@@ -590,7 +576,8 @@ keyring_import_free (gpointer data)
 {
 	keyring_import_closure *closure = data;
 	g_clear_object (&closure->cancellable);
-	gpgme_release (closure->gctx);
+	if (closure->gctx)
+		gpgme_release (closure->gctx);
 	gpgme_data_release (closure->data);
 	g_object_unref (closure->keyring);
 	g_strfreev (closure->patterns);
@@ -689,25 +676,26 @@ seahorse_gpgme_keyring_import_async (SeahorsePlace *place,
 	SeahorseGpgmeKeyring *self = SEAHORSE_GPGME_KEYRING (place);
 	GSimpleAsyncResult *res;
 	keyring_import_closure *closure;
-	gpgme_error_t gerr;
+	gpgme_error_t gerr = 0;
 	GError *error = NULL;
-	GSource *gsource;
+	GSource *gsource = NULL;
 
 	res = g_simple_async_result_new (G_OBJECT (place), callback, user_data,
 	                                 seahorse_gpgme_keyring_import_async);
 	closure = g_new0 (keyring_import_closure, 1);
 	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
-	closure->gctx = seahorse_gpgme_keyring_new_context ();
+	closure->gctx = seahorse_gpgme_keyring_new_context (&gerr);
 	closure->data = seahorse_gpgme_data_input (input);
 	closure->keyring = g_object_ref (self);
 	g_simple_async_result_set_op_res_gpointer (res, closure, keyring_import_free);
 
-	seahorse_progress_prep_and_begin (cancellable, res, NULL);
-	gsource = seahorse_gpgme_gsource_new (closure->gctx, cancellable);
-	g_source_set_callback (gsource, (GSourceFunc)on_keyring_import_complete,
-	                       g_object_ref (res), g_object_unref);
-
-	gerr = gpgme_op_import_start (closure->gctx, closure->data);
+	if (gerr == 0) {
+		seahorse_progress_prep_and_begin (cancellable, res, NULL);
+		gsource = seahorse_gpgme_gsource_new (closure->gctx, cancellable);
+		g_source_set_callback (gsource, (GSourceFunc)on_keyring_import_complete,
+		                       g_object_ref (res), g_object_unref);
+		gerr = gpgme_op_import_start (closure->gctx, closure->data);
+	}
 
 	if (seahorse_gpgme_propagate_error (gerr, &error)) {
 		g_simple_async_result_take_error (res, error);
@@ -758,7 +746,8 @@ keyring_export_free (gpointer data)
 	g_cancellable_disconnect (closure->cancellable, closure->cancelled_sig);
 	g_clear_object (&closure->cancellable);
 	gpgme_data_release (closure->data);
-	gpgme_release (closure->gctx);
+	if (closure->gctx)
+		gpgme_release (closure->gctx);
 	g_ptr_array_free (closure->keyids, TRUE);
 	g_object_unref (closure->output);
 	g_free (closure);
@@ -815,6 +804,8 @@ seahorse_gpgme_keyring_export_async (SeahorsePlace *place,
 {
 	GSimpleAsyncResult *res;
 	keyring_export_closure *closure;
+	GError *error = NULL;
+	gpgme_error_t gerr = 0;
 	SeahorsePgpKey *key;
 	gchar *keyid;
 	GSource *gsource;
@@ -824,13 +815,20 @@ seahorse_gpgme_keyring_export_async (SeahorsePlace *place,
 	                                 seahorse_gpgme_keyring_export_async);
 	closure = g_new0 (keyring_export_closure, 1);
 	closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
-	closure->gctx = seahorse_gpgme_keyring_new_context ();
+	closure->gctx = seahorse_gpgme_keyring_new_context (&gerr);
 	closure->data = seahorse_gpgme_data_output (output);
 	closure->keyids = g_ptr_array_new_with_free_func (g_free);
 	closure->output = g_object_ref (output);
 	closure->at = -1;
 	g_simple_async_result_set_op_res_gpointer (res, closure, keyring_export_free);
 
+	if (seahorse_gpgme_propagate_error (gerr, &error)) {
+		g_simple_async_result_take_error (res, error);
+		g_simple_async_result_complete_in_idle (res);
+		g_object_unref (res);
+		return;
+	}
+
 	gpgme_set_armor (closure->gctx, TRUE);
 	gpgme_set_textmode (closure->gctx, TRUE);
 
@@ -915,7 +913,6 @@ monitor_gpg_homedir (GFileMonitor *handle, GFile *file, GFile *other_file,
 static void
 seahorse_gpgme_keyring_init (SeahorseGpgmeKeyring *self)
 {
-	gpgme_error_t gerr;
 	GError *err = NULL;
 	const gchar *gpg_homedir;
 	GFile *file;
@@ -927,9 +924,6 @@ seahorse_gpgme_keyring_init (SeahorseGpgmeKeyring *self)
 	                                        seahorse_pgp_keyid_equal,
 	                                        g_free, g_object_unref);
 
-	gerr = init_gpgme (&self->gctx);
-	g_return_if_fail (GPG_IS_OK (gerr));
-
 	/* init private vars */
 	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_GPGME_KEYRING,
 	                                        SeahorseGpgmeKeyringPrivate);
@@ -938,18 +932,20 @@ seahorse_gpgme_keyring_init (SeahorseGpgmeKeyring *self)
 	self->pv->monitor_handle = NULL;
 
 	gpg_homedir = seahorse_gpg_homedir ();
-	file = g_file_new_for_path (gpg_homedir);
-	g_return_if_fail (file != NULL);
-
-	self->pv->monitor_handle = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, &err);
-	g_object_unref (file);
-
-	if (self->pv->monitor_handle) {
-		g_signal_connect (self->pv->monitor_handle, "changed",
-		                  G_CALLBACK (monitor_gpg_homedir), self);
-	} else {
-		g_warning ("couldn't monitor the GPG home directory: %s: %s",
-		           gpg_homedir, err && err->message ? err->message : "");
+	if (gpg_homedir) {
+		file = g_file_new_for_path (gpg_homedir);
+		g_return_if_fail (file != NULL);
+
+		self->pv->monitor_handle = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, &err);
+		g_object_unref (file);
+
+		if (self->pv->monitor_handle) {
+			g_signal_connect (self->pv->monitor_handle, "changed",
+			                  G_CALLBACK (monitor_gpg_homedir), self);
+		} else {
+			g_warning ("couldn't monitor the GPG home directory: %s: %s",
+			           gpg_homedir, err && err->message ? err->message : "");
+		}
 	}
 }
 
@@ -1003,9 +999,6 @@ seahorse_gpgme_keyring_dispose (GObject *object)
 	g_list_free (self->pv->orphan_secret);
 	self->pv->orphan_secret = NULL;
 
-	if (self->gctx)
-		gpgme_release (self->gctx);
-
 	G_OBJECT_CLASS (seahorse_gpgme_keyring_parent_class)->dispose (object);
 }
 
@@ -1109,9 +1102,27 @@ seahorse_gpgme_keyring_new (void)
 }
 
 gpgme_ctx_t
-seahorse_gpgme_keyring_new_context (void)
+seahorse_gpgme_keyring_new_context (gpgme_error_t *gerr)
 {
+	gpgme_protocol_t proto = GPGME_PROTOCOL_OpenPGP;
+	gpgme_error_t error = 0;
 	gpgme_ctx_t ctx = NULL;
-	g_return_val_if_fail (GPG_IS_OK (init_gpgme (&ctx)), NULL);
+
+	error = gpgme_engine_check_version (proto);
+	if (error == 0)
+		error = gpgme_new (&ctx);
+	if (error == 0)
+		error = gpgme_set_protocol (ctx, proto);
+
+	if (error != 0) {
+		g_message ("couldn't initialize gnupg properly: %s",
+		           gpgme_strerror (error));
+		if (gerr)
+			*gerr = error;
+		return NULL;
+	}
+
+	gpgme_set_passphrase_cb (ctx, (gpgme_passphrase_cb_t)passphrase_get, NULL);
+	gpgme_set_keylist_mode (ctx, GPGME_KEYLIST_MODE_LOCAL);
 	return ctx;
 }
diff --git a/pgp/seahorse-gpgme-keyring.h b/pgp/seahorse-gpgme-keyring.h
index 5a4b0c5..893c214 100644
--- a/pgp/seahorse-gpgme-keyring.h
+++ b/pgp/seahorse-gpgme-keyring.h
@@ -59,7 +59,6 @@ typedef struct _SeahorseGpgmeKeyringPrivate SeahorseGpgmeKeyringPrivate;
 
 struct _SeahorseGpgmeKeyring {
 	GObject parent;
-	gpgme_ctx_t gctx;
 	SeahorseGpgmeKeyringPrivate *pv;
 };
 
@@ -71,7 +70,7 @@ GType                  seahorse_gpgme_keyring_get_type       (void);
 
 SeahorseGpgmeKeyring * seahorse_gpgme_keyring_new            (void);
 
-gpgme_ctx_t            seahorse_gpgme_keyring_new_context    (void);
+gpgme_ctx_t            seahorse_gpgme_keyring_new_context    (gpgme_error_t *gerr);
 
 SeahorseGpgmeKey *     seahorse_gpgme_keyring_lookup         (SeahorseGpgmeKeyring *self,
                                                               const gchar *keyid);
diff --git a/pgp/seahorse-pgp-key-properties.c b/pgp/seahorse-pgp-key-properties.c
index d958735..0b6d097 100644
--- a/pgp/seahorse-pgp-key-properties.c
+++ b/pgp/seahorse-pgp-key-properties.c
@@ -1177,12 +1177,15 @@ on_pgp_details_export_button (GtkWidget *widget,
 	uri = seahorse_util_chooser_save_prompt (dialog);
 	if (!uri) 
 		return;
-	
+
+	ctx = seahorse_gpgme_keyring_new_context (&gerr);
+	if (ctx == NULL)
+		return;
+
 	/* Export to a data block */
 	gerr = gpgme_data_new (&data);
 	g_return_if_fail (GPG_IS_OK (gerr));
-	ctx = seahorse_gpgme_keyring_new_context ();
-	g_return_if_fail (ctx);
+
 	gerr = seahorse_gpg_op_export_secret (ctx, seckey->subkeys->keyid, data);
 	gpgme_release (ctx);
 	results = gpgme_data_release_and_get_mem (data, &n_results);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]