[pan2/testing] Fixes to gpg
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing] Fixes to gpg
- Date: Sat, 10 Dec 2011 04:58:29 +0000 (UTC)
commit da60b181a52dd8dd1bebf08ad321f3865195b059
Author: Heinrich MÃller <henmull src gnome org>
Date: Sat Dec 10 05:57:55 2011 +0100
Fixes to gpg
pan/data-impl/profiles.cc | 1 +
pan/gui/body-pane.cc | 17 +++--
pan/gui/gpg.cc | 7 ++
pan/gui/post-ui.cc | 173 +++++++++++++++++++++++++++++++--------------
pan/gui/post-ui.h | 9 ++-
5 files changed, 145 insertions(+), 62 deletions(-)
---
diff --git a/pan/data-impl/profiles.cc b/pan/data-impl/profiles.cc
index 646977a..b844689 100644
--- a/pan/data-impl/profiles.cc
+++ b/pan/data-impl/profiles.cc
@@ -105,6 +105,7 @@ namespace
p.use_sigfile = !strcmp (*v, "true");
p.sig_type = p.GPGSIG;
p.use_gpgsig = true;
+ std::cerr<<"got profile "<<p.use_sigfile<<" "<<p.use_gpgsig<<"\n";
}
}
}
diff --git a/pan/gui/body-pane.cc b/pan/gui/body-pane.cc
index abbb817..637bf22 100644
--- a/pan/gui/body-pane.cc
+++ b/pan/gui/body-pane.cc
@@ -999,7 +999,7 @@ BodyPane :: append_part (GMimeObject * obj, GtkAllocation * widget_size)
// or, if it's text, display it
else if (g_mime_content_type_is_type (type, "text", "*") ||
- (g_mime_content_type_is_type (type, "application", "pgp-signature")))
+ (g_mime_content_type_is_type (type, "*", "signed")))
{
const char * fallback_charset (_charset.c_str());
const char * p_flowed (g_mime_object_get_content_type_parameter(obj,"format"));
@@ -1017,11 +1017,16 @@ BodyPane :: append_part (GMimeObject * obj, GtkAllocation * widget_size)
is_done = true;
#ifdef HAVE_GPGME
/* verify signature */
- if (g_mime_content_type_is_type (type, "*", "pgp-signature"))
- {
- bool res = get_gpgsig_from_gmime_part(part);
- std::cerr<<"1023\n";
- if (res) update_sig_valid(_gpgerr.verify_ok);
+ const char* gpg (g_mime_object_get_content_type_parameter(obj,"protocol"));
+ if (gpg)
+ {
+ const bool is_gpg (!strcmp(gpg,"pgp-signature"));
+ if (g_mime_content_type_is_type (type, "*", "signed") && is_gpg)
+ {
+ bool res = get_gpgsig_from_gmime_part(part);
+ std::cerr<<"1023\n";
+ if (res) update_sig_valid(_gpgerr.verify_ok);
+ }
}
#endif
}
diff --git a/pan/gui/gpg.cc b/pan/gui/gpg.cc
index 4cb2353..30e1a2a 100644
--- a/pan/gui/gpg.cc
+++ b/pan/gui/gpg.cc
@@ -77,9 +77,16 @@ namespace pan
if (gpg_inited) return;
gpgme_check_version(0);
+ gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
+#ifndef G_OS_WIN32
+ gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
+#endif
gpg_err = gpgme_new (&gpg_ctx);
if (!gpg_err) gpg_inited = true; else return;
+ gpgme_set_textmode (gpg_ctx, 1);
+ gpgme_set_armor (gpg_ctx, 1);
+
/* get all keys */
gpgme_key_t key;
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 3264685..6cf8174 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -103,7 +103,7 @@ namespace pan
bool remember_charsets (true);
bool master_reply (true);
bool gpg_enc (false);
- bool gpg_sign (false);
+ bool gpg_sign (true);
bool user_has_gpg (false);
void on_remember_charset_toggled (GtkToggleAction * toggle, gpointer)
@@ -123,11 +123,6 @@ namespace pan
if (!self->_realized) return;
gpg_enc = gtk_toggle_action_get_active (toggle);
- if (gpg_enc)
- {
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (self->_agroup, "gpg-sign")),false);
- gpg_sign = false;
- }
}
void on_sign_toggled (GtkToggleAction * toggle, gpointer post_g)
@@ -137,11 +132,7 @@ namespace pan
if (!self->_realized) return;
gpg_sign = gtk_toggle_action_get_active (toggle);
- if (gpg_sign)
- {
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (self->_agroup, "gpg-encrypt")),false);
- gpg_enc = false;
- }
+ std::cerr<<"gpg sign toggle "<<gpg_sign<<"\n";
}
void on_spellcheck_toggled (GtkToggleAction * toggle, gpointer post_g)
@@ -351,24 +342,45 @@ PostUI :: set_always_run_editor (bool run)
}
#ifdef HAVE_GPGME
-std::string
-PostUI :: gpg_sign_and_encrypt(const std::string& body, GPGEncErr& fail)
+
+namespace
+{
+ void
+ mime_part_set_content (GMimePart *part, const char *str)
+ {
+ GMimeDataWrapper *content;
+ GMimeStream *stream;
+
+ stream = g_mime_stream_mem_new_with_buffer (str, strlen (str));
+ content = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_DEFAULT);
+ g_object_unref (stream);
+
+ g_mime_part_set_content_object (part, content);
+ g_object_unref (content);
+ }
+}
+
+GMimeMessage*
+PostUI :: message_add_signed_part (const std::string& body_str, GMimeMessage* body, GPGEncErr& fail)
{
- fail.err = GPG_ERR_GENERAL;
const Profile profile (get_current_profile ());
std::string uid = profile.gpg_sig_uid;
- if (uid.empty()) return "";
+ if (uid.empty()) return 0;
+
+ GMimeMultipart *mp = g_mime_multipart_new_with_subtype ("mixed");
+ g_mime_multipart_set_boundary(mp, NULL);
+ g_mime_multipart_add(mp,g_mime_message_get_mime_part(body));
gpgme_data_t gpg_buf, gpg_out_buf;
gpgme_key_t mykey(0), key;
- StringView v(body);
+ StringView v(body_str);
gpgme_data_new_from_mem (&gpg_buf, v.str, v.len, 0);
gpgme_data_new (&gpg_out_buf);
- gpgme_data_set_encoding (gpg_out_buf, GPGME_DATA_ENCODING_BINARY);
+// gpgme_data_set_encoding (gpg_out_buf, GPGME_DATA_ENCODING_BASE64);
+// gpgme_data_set_file_name(gpg_out_buf, "signature.asc");
- /* find key to uid */
fail.err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
while (!fail.err)
{
@@ -376,44 +388,87 @@ PostUI :: gpg_sign_and_encrypt(const std::string& body, GPGEncErr& fail)
if (fail.err) break;
if (strcmp(key->subkeys->keyid, uid.c_str()) == 0) { mykey = key; break; }
}
- if (!mykey) { fail.err = GPG_ERR_NO_PUBKEY; return std::string(""); }
-
- gpgme_key_t enc_keys[] = { mykey, NULL};
+ if (!mykey) { fail.err = GPG_ERR_NO_PUBKEY; return 0; }
gpgme_signers_clear(gpg_ctx);
gpgme_signers_add(gpg_ctx, mykey);
- if (gpg_sign)
- {
+ fail.err = gpgme_op_sign (gpg_ctx, gpg_buf, gpg_out_buf, GPGME_SIG_MODE_DETACH);
+ fail.sign_res = gpgme_op_sign_result (gpg_ctx);
+ if (fail.err) return 0;
- gpgme_sign_result_t sign_res;
- fail.err = gpgme_op_sign (gpg_ctx, gpg_buf, gpg_out_buf, GPGME_SIG_MODE_CLEAR);
- sign_res = gpgme_op_sign_result (gpg_ctx);
- fail.sign_res = sign_res;
- if (fail.err) return std::string("");
+ gpgme_data_seek (gpg_out_buf,SEEK_SET, 0);
+ ssize_t ret;
+ std::stringstream ret_str;
+ char buffer[4096]={0};
+
+ while ((ret = gpgme_data_read (gpg_out_buf, buffer, sizeof(buffer))) > 0)
+ {
+ ret_str << buffer;
}
- else if (gpg_enc)
+
+ GMimePart *sig = g_mime_part_new_with_type("multipart", "signed");
+ g_mime_object_set_content_type_parameter(GMIME_OBJECT(sig),"protocol","pgp-signature");
+ mime_part_set_content (sig, ret_str.str().c_str());
+
+ gpgme_data_release(gpg_buf);
+ gpgme_data_release(gpg_out_buf);
+
+ g_mime_multipart_add (GMIME_MULTIPART (mp), GMIME_OBJECT (sig));
+
+ g_mime_message_set_mime_part(body,GMIME_OBJECT(mp));
+ g_object_unref(mp);
+
+ fail.err = GPG_ERR_NO_ERROR;
+
+ return body;
+}
+
+std::string
+PostUI :: gpg_encrypt(const std::string& body, GPGEncErr& fail)
+{
+ fail.err = GPG_ERR_GENERAL;
+
+ const Profile profile (get_current_profile ());
+ std::string uid = profile.gpg_sig_uid;
+ if (uid.empty()) return "";
+
+ gpgme_data_t gpg_buf, gpg_out_buf;
+ gpgme_key_t mykey(0), key;
+
+ StringView v(body);
+ gpgme_data_new_from_mem (&gpg_buf, v.str, v.len, 0);
+ gpgme_data_new (&gpg_out_buf);
+ gpgme_data_set_encoding (gpg_out_buf, GPGME_DATA_ENCODING_BASE64);
+
+ /* find key to uid */
+ fail.err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
+ while (!fail.err)
{
- gpgme_encrypt_result_t enc_res;
- fail.err = gpgme_op_encrypt (gpg_ctx, enc_keys, GPGME_ENCRYPT_PREPARE, gpg_buf, gpg_out_buf);
- enc_res = gpgme_op_encrypt_result (gpg_ctx);
- fail.enc_res = enc_res;
- if (fail.err) return std::string("");
+ fail.err = gpgme_op_keylist_next (gpg_ctx, &key);
+ if (fail.err) break;
+ if (strcmp(key->subkeys->keyid, uid.c_str()) == 0) { mykey = key; break; }
}
+ if (!mykey) { fail.err = GPG_ERR_NO_PUBKEY; return std::string(""); }
+ gpgme_key_t enc_keys[] = { mykey, NULL};
+ fail.err = gpgme_op_encrypt (gpg_ctx, enc_keys, GPGME_ENCRYPT_PREPARE, gpg_buf, gpg_out_buf);
+ fail.enc_res = gpgme_op_encrypt_result (gpg_ctx);
+ if (fail.err) return std::string("");
gpgme_data_seek (gpg_out_buf,SEEK_SET, 0);
ssize_t ret;
std::stringstream ret_str;
char buffer[4096]={0};
- while ((ret = gpgme_data_read (gpg_out_buf, buffer, sizeof(buffer)) > 0))
+ while ((ret = gpgme_data_read (gpg_out_buf, buffer, sizeof(buffer))) > 0)
{
ret_str << buffer;
- ret = gpgme_data_read (gpg_out_buf, buffer, sizeof(buffer));
}
+ std::cerr<<"encrypted:\n"<<ret_str.str()<<"\n\n";
+
gpgme_data_release(gpg_buf);
gpgme_data_release(gpg_out_buf);
@@ -1101,25 +1156,37 @@ PostUI :: maybe_post_message (GMimeMessage * message)
if(_file_queue_empty)
{
#ifdef HAVE_GPGME
+ GPGEncErr fail;
+ std::string tmp = get_body();
if (user_has_gpg)
{
- GPGEncErr fail;
- std::string res = gpg_sign_and_encrypt(get_body(), fail);
- if (gpgme_err_code(fail.err) == GPG_ERR_NO_ERROR)
+ if (gpg_enc)
{
- gtk_text_buffer_set_text (_body_buf, res.c_str(), res.size());
- }
- else
- {
- Log::add_err_va("Failed to sign the Message with your public key : \"%s\"",gpgme_strerror(fail.err));
- return false;
+ std::cerr<<"encrypt\n";
+ std::string res = gpg_encrypt(tmp, fail);
+ if (gpgme_err_code(fail.err) == GPG_ERR_NO_ERROR)
+ gtk_text_buffer_set_text (_body_buf, res.c_str(), res.size());
+ else
+ {
+ Log::add_err_va("Failed to sign the Message with your public key : \"%s\"",gpgme_strerror(fail.err));
+ return false;
+ }
}
}
#endif
GMimeMessage* msg = new_message_from_ui(POSTING);
- _post_task = new TaskPost (server, msg);
- _post_task->add_listener (this);
- _queue.add_task (_post_task, Queue::TOP);
+
+ bool go_on(true);
+
+ if (user_has_gpg && gpg_sign)
+ go_on = go_on && message_add_signed_part(tmp, msg, fail);
+
+ if (go_on)
+ {
+ _post_task = new TaskPost (server, msg);
+ _post_task->add_listener (this);
+ _queue.add_task (_post_task, Queue::TOP);
+ }
} else {
// prepend header for xml file (if one was chosen)
@@ -1168,7 +1235,6 @@ PostUI :: maybe_post_message (GMimeMessage * message)
generate_unique_id(domain, 1,out);
first_mid = out;
-
TaskUpload::UploadInfo f;
f.total=1;
TaskUpload::Needed n;
@@ -2219,12 +2285,12 @@ PostUI :: body_view_realized_cb (GtkWidget*, gpointer self_gpointer)
g_signal_handler_disconnect (self->_body_view, self->body_view_realized_handler);
+ self->_realized = true;
+
/* gpg stuff */
const Profile profile (self->get_current_profile ());
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (gtk_action_group_get_action (self->_agroup, "gpg-sign")),profile.use_sigfile);
- user_has_gpg == profile.sig_type != Profile::GPGSIG;
-
- self->_realized = true;
+ user_has_gpg = profile.use_sigfile && profile.sig_type == Profile::GPGSIG;
}
/***
@@ -2763,6 +2829,9 @@ void
PostUI :: remove_files (void)
{
_upload_queue.remove_tasks (get_selected_files());
+ GtkTreeView * view (GTK_TREE_VIEW (_filequeue_store));
+ int rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(view), NULL);
+ if (rows == 0) _file_queue_empty = true;
}
void
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index 582e0b8..8e36f16 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -88,12 +88,13 @@ namespace pan
void set_wrap_mode (bool wrap);
void set_always_run_editor (bool);
#ifdef HAVE_GPGME
- /** Encrypts a message with GPG and signs it.
- * @return The encrypted/signed message
- * @param body The unencrypted/unsigned message body
+ /** Encrypts a message with GPG.
+ * @return The encrypted message
+ * @param body The unencrypted message body
* @param fail Error struct that holds the GPG errcode and two gpgme error info structs.
**/
- std::string gpg_sign_and_encrypt(const std::string& body, GPGEncErr& fail);
+ std::string gpg_encrypt(const std::string& body, GPGEncErr& fail);
+ GMimeMessage* message_add_signed_part (const std::string& body_str, GMimeMessage* body, GPGEncErr& fail);
#endif
void update_parts_tab();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]