[pan2: 230/268] fdgssfsdf



commit 6b40dcc012d91b648467dbce9603be8d1c16437b
Author: Heinrich MÃller <henmull src gnome org>
Date:   Fri Dec 9 12:36:13 2011 +0100

    fdgssfsdf

 pan/data-impl/article-filter.cc |    3 +-
 pan/data/article-cache.cc       |    5 +-
 pan/data/article-cache.h        |    6 +-
 pan/gui/body-pane.cc            |  159 ++++++++++++++++++++++++++++++++++++++-
 pan/gui/body-pane.h             |   11 +++
 pan/gui/gpg.cc                  |  117 ++++++++++++++++++++++++++++
 pan/gui/gpg.h                   |   76 +++++++++++++++++++
 pan/gui/gui.cc                  |    4 +-
 pan/gui/post-ui.cc              |    9 +--
 pan/gui/post-ui.h               |   15 ----
 pan/icons/Makefile.am           |    4 +-
 pan/icons/icon_sig_fail.png     |  Bin 0 -> 1777 bytes
 pan/icons/icon_sig_ok.png       |  Bin 0 -> 1759 bytes
 pan/tasks/nntp.cc               |    1 +
 pan/tasks/task-upload.cc        |    7 --
 pan/usenet-utils/mime-utils.cc  |   56 +++++++++-----
 pan/usenet-utils/mime-utils.h   |   13 +---
 17 files changed, 416 insertions(+), 70 deletions(-)
---
diff --git a/pan/data-impl/article-filter.cc b/pan/data-impl/article-filter.cc
index c8678f1..2ea298b 100644
--- a/pan/data-impl/article-filter.cc
+++ b/pan/data-impl/article-filter.cc
@@ -188,8 +188,9 @@ ArticleFilter :: test_article (const Data        & data,
         else
         {
           if (cache.contains(article.message_id)) {
+            GPGDecErr unused_for_now;
             ArticleCache::mid_sequence_t mid(1, article.message_id);
-            GMimeMessage *msg = cache.get_message(mid);
+            GMimeMessage *msg = cache.get_message(mid, unused_for_now);
             const char *hdr = g_mime_object_get_header(GMIME_OBJECT(msg), criteria._header);
             pass = criteria._text.test (hdr);
             g_object_unref(msg);
diff --git a/pan/data/article-cache.cc b/pan/data/article-cache.cc
index f7d50a4..e24e8ef 100644
--- a/pan/data/article-cache.cc
+++ b/pan/data/article-cache.cc
@@ -398,7 +398,7 @@ ArticleCache :: get_message_mem_stream (const Quark& mid) const
 }
 
 GMimeMessage*
-ArticleCache :: get_message (const mid_sequence_t& mids) const
+ArticleCache :: get_message (const mid_sequence_t& mids, GPGDecErr& err) const
 {
    debug ("trying to get a message with " << mids.size() << " parts");
    GMimeMessage * retval = NULL;
@@ -421,13 +421,12 @@ ArticleCache :: get_message (const mid_sequence_t& mids) const
 
    // build the message
    if (!streams.empty())
-     retval = mime :: construct_message (&streams.front(), streams.size());
+     retval = mime :: construct_message (&streams.front(), streams.size(), err);
 
    // cleanup
    foreach (streams_t, streams, it)
      g_object_unref (*it);
 
-   std::cerr <<"returning " << retval<<"\n";
    return retval;
 }
 
diff --git a/pan/data/article-cache.h b/pan/data/article-cache.h
index 4b59fb8..f05954b 100644
--- a/pan/data/article-cache.h
+++ b/pan/data/article-cache.h
@@ -28,6 +28,10 @@ extern "C" {
 #include <pan/general/string-view.h>
 #include <pan/general/quark.h>
 
+#ifdef HAVE_GPGME
+  #include <pan/gui/gpg.h>
+#endif
+
 extern "C"
 {
   typedef struct _GMimeMessage GMimeMessage;
@@ -70,7 +74,7 @@ namespace pan
       void resize ();
       void clear ();
 
-      GMimeMessage* get_message (const mid_sequence_t&) const;
+      GMimeMessage* get_message (const mid_sequence_t&, GPGDecErr&) const;
 
       typedef std::vector<std::string> strings_t;
       strings_t get_filenames (const mid_sequence_t&);
diff --git a/pan/gui/body-pane.cc b/pan/gui/body-pane.cc
index bdd4aff..df0fcea 100644
--- a/pan/gui/body-pane.cc
+++ b/pan/gui/body-pane.cc
@@ -21,6 +21,7 @@
 #include <cctype>
 #include <cmath>
 #include <iostream>
+#include <sstream>
 extern "C" {
   #include <glib/gi18n.h>
   #include <gtk/gtk.h>
@@ -30,10 +31,10 @@ extern "C" {
 }
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <pan/general/debug.h>
-//#include <pan/general/gdk-threads.h>
 #include <pan/general/log.h>
 #include <pan/general/macros.h>
 #include <pan/general/utf8-utils.h>
+#include <pan/general/e-util.h>
 #include <pan/usenet-utils/gnksa.h>
 #include <pan/usenet-utils/mime-utils.h>
 #include <pan/usenet-utils/url-find.h>
@@ -1047,6 +1048,7 @@ namespace
     const char * val (msg ? g_mime_object_get_header ((GMimeObject *) msg, key) : "");
     return add_header_line (s, key_i18n, key, val, fallback_charset);
   }
+
 }
 
 void
@@ -1087,6 +1089,15 @@ BodyPane :: set_text_from_message (GMimeMessage * message)
         w = std::max (w, l);
       }
     }
+
+      // obsolete in favor of the certificate icon tooltip (bodypane)
+//    const StringView gpg (g_mime_object_get_header ((GMimeObject *) message, "X-GPG-Signed"));
+//    if (!gpg.empty())
+//    {
+//      char buf[256];
+//      l = add_header_line (s, message, _("GPG-Signed message signature "), "X-GPG-Signed", fallback_charset);
+//      w = std::max (w, l);
+//    }
   }
 
   s.resize (s.size()-1); // remove trailing linefeed
@@ -1103,7 +1114,6 @@ BodyPane :: set_text_from_message (GMimeMessage * message)
     GdkPixbuf *pixbuf = NULL;
     pixbuf = pan_gdk_pixbuf_create_from_x_face (pch);
     gtk_image_set_from_pixbuf (GTK_IMAGE(_xface), pixbuf);
-    gtk_widget_show_all(_verbose);
     g_object_unref (pixbuf);
   }
   // set the face
@@ -1175,6 +1185,7 @@ BodyPane :: set_text_from_message (GMimeMessage * message)
     gtk_text_buffer_get_start_iter  (_buffer, &iter);
     gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(_text), &iter, 0.0, true, 0.0, 0.0);
   }
+
 }
 
 void
@@ -1183,6 +1194,117 @@ BodyPane :: refresh ()
   set_text_from_message (_message);
 }
 
+/***
+****
+***/
+
+namespace
+{
+
+  enum Icons
+  {
+    ICON_SIG_OK,
+    ICON_SIG_FAIL,
+    NUM_ICONS
+  };
+
+  struct Icon {
+  const guint8 * pixbuf_txt;
+  GdkPixbuf * pixbuf;
+  } icons[NUM_ICONS] = {
+    { icon_sig_ok,          0 },
+    { icon_sig_fail,        0 }
+  };
+}
+
+/***
+****
+***/
+
+namespace
+{
+
+  std::string get_email_address(std::string& s)
+  {
+    size_t in = s.find("<");
+    size_t out = s.find(">");
+    std::cerr<<s<<" "<<in<<" "<<out<<"\n";
+    if (in == std::string::npos || out == std::string::npos) return "...";
+
+    return s.substr (in+1,out-in-1);
+  }
+}
+
+gboolean
+BodyPane:: on_tooltip_query(GtkWidget  *widget,
+                            gint        x,
+                            gint        y,
+                            gboolean    keyboard_tip,
+                            GtkTooltip *tooltip,
+                            gpointer    data)
+{
+  GPGDecErr* err = static_cast<GPGDecErr*>(data);
+
+  g_return_val_if_fail(err, false);
+  g_return_val_if_fail(err->dec_ok, false);
+  g_return_val_if_fail(err->err == GPG_ERR_NO_ERROR, false);
+
+  if (err->no_sigs) return false;
+  std::cerr<<"bla 1\n";
+  if (!err->v_res) return false;
+  std::cerr<<"bla 2\n";
+  if (!err->v_res->signatures) return false;
+  std::cerr<<"bla 3\n";
+  if (!err->v_res->signatures->fpr) return false;
+  std::cerr<<"bla 4\n";
+
+  // get uid from fingerprint
+  // mask out higher bytes of key (example) 0E A9 59 12 68 0A D9 CF
+  size_t len (strlen(err->v_res->signatures->fpr));
+  size_t off (0);
+  if (len > 16) off += len - 16;
+  GPGSignersInfo info = get_uids_from_fingerprint(err->v_res->signatures->fpr+off);
+  std::cerr<<"infos "<<info.expires<<" "<<info.creation_timestamp<<" "<<info.real_name<<"\n";
+  EvolutionDateMaker ed;
+
+  char buf[2048];
+  g_snprintf(buf, sizeof(buf),
+             "<u>This is a <b>GPG-Signed</b> message.</u>\n\n"
+             "Information:\n"
+             "<b>Signer</b> : %s (\"%s\")\n"
+             "<b>Valid until</b> : %s\n"
+             "<b>Created on</b> : %s",
+             info.real_name.c_str(), get_email_address(info.uid).c_str(),
+             ed.get_date_string(info.expires),
+             ed.get_date_string(info.creation_timestamp)
+             );
+
+  gtk_tooltip_set_icon_from_stock (tooltip, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
+  gtk_tooltip_set_markup (tooltip, buf);
+
+  return true;
+}
+
+void
+BodyPane :: update_sig_valid(int i)
+{
+
+  std::cerr<<"udpate icon "<<i<<"\n";
+
+  gtk_image_clear(GTK_IMAGE(_sig_icon));
+
+  switch (i)
+  {
+    case 0:
+      gtk_image_set_from_pixbuf (GTK_IMAGE(_sig_icon), icons[ICON_SIG_FAIL].pixbuf);
+      break;
+
+    case 1:
+      gtk_image_set_from_pixbuf (GTK_IMAGE(_sig_icon), icons[ICON_SIG_OK].pixbuf);
+      break;
+  }
+}
+
 void
 BodyPane :: set_article (const Article& a)
 {
@@ -1190,7 +1312,23 @@ BodyPane :: set_article (const Article& a)
 
   if (_message)
     g_object_unref (_message);
-  _message = _cache.get_message (_article.get_part_mids());
+  _message = _cache.get_message (_article.get_part_mids(), _gpgerr);
+
+  const char* gpg_sign = g_mime_object_get_header(GMIME_OBJECT(_message), "X-GPG-Signed");
+  int val(-1);
+
+  if (gpg_sign)
+  {
+    std::cerr<<"gpg flag "<<gpg_sign<<"\n";
+
+    if (!strcmp(gpg_sign, "valid"))
+      val = 1;
+    else if (!strcmp(gpg_sign, "invalid"))
+      val = 0;
+  }
+
+  update_sig_valid(val);
+
   refresh ();
 
   _data.mark_read (_article);
@@ -1377,7 +1515,6 @@ BodyPane :: populate_popup (GtkTextView *v G_GNUC_UNUSED, GtkMenu *m)
   gtk_menu_shell_prepend (GTK_MENU_SHELL(m), mi);
 }
 
-
 /***
 ****
 ***/
@@ -1390,6 +1527,12 @@ BodyPane :: BodyPane (Data& data, ArticleCache& cache, Prefs& prefs):
   _vscroll_visible (false),
   _message (0)
 {
+
+  for (guint i=0; i<NUM_ICONS; ++i)
+    icons[i].pixbuf = gdk_pixbuf_new_from_inline (-1, icons[i].pixbuf_txt, FALSE, 0);
+
+  _sig_icon = gtk_image_new();
+
   GtkWidget * vbox = gtk_vbox_new (false, PAD);
   gtk_container_set_resize_mode (GTK_CONTAINER(vbox), GTK_RESIZE_QUEUE);
 
@@ -1422,6 +1565,12 @@ BodyPane :: BodyPane (Data& data, ArticleCache& cache, Prefs& prefs):
   gtk_label_set_ellipsize (GTK_LABEL(w), PANGO_ELLIPSIZE_MIDDLE);
   gtk_label_set_use_markup (GTK_LABEL(w), true);
   gtk_box_pack_start (GTK_BOX(hbox), w, true, true, PAD_SMALL);
+
+  gtk_widget_set_size_request (_sig_icon, 32, 32);
+  gtk_box_pack_start (GTK_BOX(hbox), _sig_icon, true, true, PAD_SMALL);
+  gtk_widget_set_has_tooltip (_sig_icon, true);
+  g_signal_connect(_sig_icon,"query-tooltip",G_CALLBACK(on_tooltip_query), &_gpgerr);
+
   w = _xface = gtk_image_new();
   gtk_widget_set_size_request (w, 48, 48);
   gtk_box_pack_start (GTK_BOX(hbox), w, false, false, PAD_SMALL);
@@ -1467,6 +1616,8 @@ BodyPane :: BodyPane (Data& data, ArticleCache& cache, Prefs& prefs):
   g_signal_connect (_root, "show", G_CALLBACK(show_cb), this);
 
   gtk_widget_show_all (_root);
+
+  update_sig_valid(-1);
 }
 
 BodyPane :: ~BodyPane ()
diff --git a/pan/gui/body-pane.h b/pan/gui/body-pane.h
index 1e73437..ce54a2d 100644
--- a/pan/gui/body-pane.h
+++ b/pan/gui/body-pane.h
@@ -41,6 +41,14 @@ namespace pan
       Prefs& _prefs;
       Data& _data;
       ArticleCache& _cache;
+      GtkWidget* _sig_icon;
+      void update_sig_valid(int i);
+      static gboolean on_tooltip_query(GtkWidget  *widget,
+                                       gint        x,
+                                       gint        y,
+                                       gboolean    keyboard_tip,
+                                       GtkTooltip *tooltip,
+                                       gpointer    data);
 
     public:
       BodyPane (Data&, ArticleCache&, Prefs&);
@@ -100,6 +108,9 @@ namespace pan
       static gboolean mouse_button_pressed_cb (GtkWidget*, GdkEventButton*, gpointer);
       gboolean mouse_button_pressed (GtkWidget*, GdkEventButton*);
 
+      /* updated with values from gmimemessage */
+      GPGDecErr _gpgerr;
+
     private:
       std::string _hover_url;
       GtkWidget * _expander;
diff --git a/pan/gui/gpg.cc b/pan/gui/gpg.cc
new file mode 100644
index 0000000..d5bf79d
--- /dev/null
+++ b/pan/gui/gpg.cc
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006  Charles Kerr <charles rebelbase com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 <config.h>
+#include <vector>
+#include <iostream>
+#include <pan/general/log.h>
+#include <pan/general/macros.h>
+#include "gpg.h"
+
+extern "C" {
+  #include <stdlib.h>
+  #include <unistd.h>
+}
+
+namespace pan
+{
+
+  gpgme_ctx_t gpg_ctx;
+  bool gpg_inited;
+  signers_m gpg_signers;
+
+  void deinit_gpg()
+  {
+    gpgme_key_t key;
+    gpgme_error_t gpg_err;
+
+    gpg_err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
+    while (!gpg_err)
+    {
+      gpg_err = gpgme_op_keylist_next (gpg_ctx, &key);
+      if (!gpg_err) gpgme_key_release (key);
+    }
+    gpgme_release(gpg_ctx);
+  }
+
+  void init_gpg()
+  {
+    gpgme_error_t gpg_err;
+
+    if (gpg_inited) return;
+    gpgme_check_version(0);
+    gpg_err = gpgme_new (&gpg_ctx);
+    if (!gpg_err) gpg_inited = true; else return;
+
+  //  gpgme_set_armor (gpg_ctx, 1);
+
+    /* get all keys */
+    gpgme_key_t key;
+
+    gpg_err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
+    gpgme_signers_clear(gpg_ctx);
+
+    GPGSignersInfo info;
+
+    while (!gpg_err)
+    {
+      gpg_err = gpgme_op_keylist_next (gpg_ctx, &key);
+      if (gpg_err) break;
+      // have i forgotten anything ? ;)
+      if (!key->can_certify && !key->can_sign && !key->can_authenticate) continue;
+      if (key->revoked || key->expired || key->disabled || key->subkeys->expired) continue;
+      if (key->uids->revoked || key->uids->invalid) continue;
+
+      gpgme_signers_add(gpg_ctx, key);
+      info.real_name = key->uids->name;
+      info.auth = key->can_authenticate == 1 ? true : false;
+      info.sign = key->can_sign == 1 ? true : false;
+      info.certify = key->can_certify == 1 ? true : false;
+      info.enc = key->can_encrypt == 1 ? true : false;
+      info.expires = key->subkeys->expires;
+      info.uid = key->uids->uid;
+      info.creation_timestamp = key->subkeys->timestamp;
+      std::cerr<<"uid of signer "<<info.real_name<<" : "<<info.uid<<", "<<key->subkeys->keyid<<"\n";
+      gpg_signers.insert(std::pair<std::string, GPGSignersInfo>(key->subkeys->keyid,info));
+    }
+
+    if (gpg_err_code (gpg_err) != GPG_ERR_EOF)
+    {
+        Log::add_err("GPG Error : can't list the keys from the keyvault, please check your settings.\n");
+
+    }
+  }
+
+  GPGSignersInfo get_uids_from_fingerprint(char* fpr)
+  {
+    GPGSignersInfo empty;
+
+    foreach(signers_m, gpg_signers, it)
+    {
+      const GPGSignersInfo& info(it->second);
+      std::cerr<<fpr<<" // uid "<<it->first<<" "<<info.uid<<" "<<info.real_name<<" "<<info.expires<<" "<<info.creation_timestamp<<"\n\n";
+    }
+
+    if (gpg_signers.count(fpr) != 0)
+      return gpg_signers[fpr];
+
+    return empty;
+  }
+
+}
diff --git a/pan/gui/gpg.h b/pan/gui/gpg.h
new file mode 100644
index 0000000..7c02fe3
--- /dev/null
+++ b/pan/gui/gpg.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006  Charles Kerr <charles rebelbase com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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 _HAVE_GPGDEFS_H
+#define _HAVE_GPGDEFS_H
+
+#include <gpgme.h>
+#include <map>
+
+namespace pan
+{
+
+  struct GPGSignersInfo
+  {
+    std::string real_name; // real world name
+    bool auth, sign, certify, enc; // used to ....
+    long int expires; // expired ?
+    std::string uid;  // userid /hex
+    long int creation_timestamp;
+
+  };
+
+  typedef std::map<std::string,GPGSignersInfo> signers_m;
+
+  extern gpgme_ctx_t gpg_ctx;
+  extern bool gpg_inited;
+  extern signers_m gpg_signers;
+
+  struct GPGDecErr
+  {
+    gpg_error_t err;
+    gpgme_decrypt_result_t dec_res;
+    gpgme_verify_result_t v_res;
+    bool dec_ok;
+    bool verify_ok;
+    bool no_sigs;
+    GPGDecErr() : dec_ok(false), verify_ok(false), no_sigs(true), err(GPG_ERR_NO_ERROR) {}
+  };
+
+  /** Error struct for gpg_sign_and_encrypt
+    * @see gpg_sign_and_encrypt
+   **/
+  struct GPGEncErr
+  {
+    /** common gpg errcode */
+    gpgme_error_t err;
+    /** encode result */
+    gpgme_encrypt_result_t enc_res;
+    /** sign result */
+    gpgme_sign_result_t sign_res;
+  };
+
+  GPGSignersInfo get_uids_from_fingerprint(char*);
+  void init_gpg();
+  void deinit_gpg();
+
+}
+
+#endif
+
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 975fe90..1ebea19 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -71,6 +71,7 @@ extern "C" {
 
 #ifdef HAVE_GPGME
   #include "gpg.h"
+  #define GPG_DEF 1
 #endif
 
 namespace pan
@@ -694,8 +695,9 @@ namespace
 
     virtual void on_progress_finished (Progress&, int status)
     {
+      GPGDecErr unused;
       if (status == OK) {
-        GMimeMessage * message = _cache.get_message (_article.get_part_mids());
+        GMimeMessage * message = _cache.get_message (_article.get_part_mids(), unused);
         g_mime_message_foreach (message, foreach_part_cb, this);
         g_object_unref (message);
       }
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 9f20fe7..a560ad9 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -367,7 +367,7 @@ PostUI :: gpg_sign_and_encrypt(const std::string& body, GPGEncErr& fail)
   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);
+  gpgme_data_set_encoding (gpg_out_buf, GPGME_DATA_ENCODING_BINARY);
 
   /* find key to uid */
   fail.err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
@@ -1586,15 +1586,10 @@ PostUI :: new_message_from_ui (Mode mode, bool copy_body)
     g_object_unref (stream);
     GMimePart * part = g_mime_part_new ();
     pch = g_strdup_printf ("text/plain; charset=%s", charset.c_str());
-//    pch = g_strdup_printf ("multipart/encrypted;"
-//                           "protocol=\"application/pgp-encrypted\";"
-//                           "boundary=\"------------24i8m5cwm904t8v\"; charset=%s", charset.c_str());
-
-    g_mime_object_set_header ((GMimeObject *) msg, "Content-Transfer-Encoding", "Base64");
 
     GMimeContentType * type = g_mime_content_type_new_from_string (pch);
     g_free (pch);
-    g_mime_object_set_content_type ((GMimeObject *) part, type); // part owns type now. type isn't refcounted.
+//    g_mime_object_set_content_type ((GMimeObject *) part, type); // part owns type now. type isn't refcounted.
     g_mime_part_set_content_object (part, content_object);
     g_mime_part_set_content_encoding (part, GMIME_CONTENT_ENCODING_8BIT);
     g_object_unref (content_object);
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index 5dfad00..aa071c3 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -88,21 +88,6 @@ namespace pan
       void set_wrap_mode (bool wrap);
       void set_always_run_editor (bool);
 
-      /** Error struct for gpg_sign_and_encrypt
-        * @see gpg_sign_and_encrypt
-       **/
-      struct GPGEncErr
-      {
-#ifdef HAVE_GPGME
-        /** common gpg errcode */
-        gpgme_error_t err;
-        /** encode result */
-        gpgme_encrypt_result_t enc_res;
-        /** sign result */
-        gpgme_sign_result_t sign_res;
-#endif
-      };
-
       /** Encrypts a message with GPG and signs it.
         * @return The encrypted/signed message
         * @param body The unencrypted/unsigned message body
diff --git a/pan/icons/Makefile.am b/pan/icons/Makefile.am
index c7c65b9..3107fb3 100644
--- a/pan/icons/Makefile.am
+++ b/pan/icons/Makefile.am
@@ -53,7 +53,9 @@ stock_images = \
   icon_status_queue_empty.png \
   icon_status_error.png \
   icon_status_idle.png \
-  icon_status_new_articles.png
+  icon_status_new_articles.png \
+  icon_sig_ok.png \
+  icon_sig_fail.png
 
 
 EXTRA_DIST = \
diff --git a/pan/icons/icon_sig_fail.png b/pan/icons/icon_sig_fail.png
new file mode 100644
index 0000000..d9d8e6a
Binary files /dev/null and b/pan/icons/icon_sig_fail.png differ
diff --git a/pan/icons/icon_sig_ok.png b/pan/icons/icon_sig_ok.png
new file mode 100644
index 0000000..49e6c06
Binary files /dev/null and b/pan/icons/icon_sig_ok.png differ
diff --git a/pan/tasks/nntp.cc b/pan/tasks/nntp.cc
index 8142b84..b8eff0f 100644
--- a/pan/tasks/nntp.cc
+++ b/pan/tasks/nntp.cc
@@ -305,6 +305,7 @@ void
 NNTP :: get_group (Listener * l, const Quark& group)
 {
    _listener = l;
+   std::cerr<<"get group "<<group<<"\n";
    _commands.push_back (build_command ("GROUP %s\r\n",group.c_str()));
    write_next_command();
 }
diff --git a/pan/tasks/task-upload.cc b/pan/tasks/task-upload.cc
index c4a0c4e..e487ca8 100644
--- a/pan/tasks/task-upload.cc
+++ b/pan/tasks/task-upload.cc
@@ -207,13 +207,6 @@ TaskUpload :: prepend_headers(GMimeMessage* msg, TaskUpload::Needed * n, std::st
     if (_first_mid != n->last_mid && !_first && !n->last_mid.empty())  mids += " <" + n->last_mid + ">";
     if (!mids.empty()) g_mime_object_set_header ((GMimeObject *) msg, "References", mids.c_str());
 
-    // modify content type
-//    g_snprintf(buf,sizeof(buf), "Message/Partial; number=%d; total=%d", n->partno, _total_parts);
-//    GMimeContentType * new_type = g_mime_content_type_new_from_string (buf);
-//    g_mime_object_set_content_type ((GMimeObject *) msg, new_type);
-//    g_object_unref (new_type);
-//    g_mime_object_set_header ((GMimeObject *) msg, "Content-Type",buf);
-
     char * all(g_mime_object_get_headers ((GMimeObject *) msg));
     if (_first && _queue_pos==-1)
       all = g_mime_object_to_string ((GMimeObject *) msg);
diff --git a/pan/usenet-utils/mime-utils.cc b/pan/usenet-utils/mime-utils.cc
index 1a0698f..d5582c7 100644
--- a/pan/usenet-utils/mime-utils.cc
+++ b/pan/usenet-utils/mime-utils.cc
@@ -35,6 +35,10 @@ extern "C"
 #include <pan/general/log.h>
 #include "mime-utils.h"
 
+#ifdef HAVE_GPGME
+  #include <pan/gui/gpg.h>
+#endif
+
 #define is_nonempty_string(a) ((a) && (*a))
 
 using namespace pan;
@@ -477,6 +481,8 @@ namespace
   GMimeStream* gpg_decrypt (GPGDecErr& info, GMimeStream* s, TempPart* part)
   {
 
+    std::cerr<<"gpg decrypt\n";
+
     GMimeStream* decrypted = g_mime_stream_mem_new ();
 
     ssize_t stream_len = g_mime_stream_length(s);
@@ -506,18 +512,19 @@ namespace
     else
       return decrypted;
 
-    std::cerr<<"dec "<<gpgme_strerror(info.err)<<" "<<info.err<<"\n";
-
     info.dec_res  = gpgme_op_decrypt_result (gpg_ctx);
     info.v_res    = gpgme_op_verify_result (gpg_ctx);
 
     if (info.v_res->signatures)
     {
+      info.no_sigs = false;
+
       if (gpgme_err_code(info.v_res->signatures->status) == GPG_ERR_NO_ERROR)
         info.verify_ok = true;
       else
         return decrypted;
-    }
+    } else
+      info.no_sigs = true;
 
     delete streambuf;
 
@@ -541,6 +548,8 @@ namespace
 
     std::cerr<<"infos "<<info.dec_ok<<" "<<info.verify_ok<<"\n";
 
+    info.err = GPG_ERR_NO_ERROR;
+
     return decrypted;
   }
 
@@ -577,9 +586,10 @@ namespace
     temp_parts_t master_list;
     temp_parts_t current_list;
     TempPart *uu_temp;
-    bool gpg_verified;
+    std::string gpg_verified;
+    GPGDecErr gpgerr;
 
-    sep_state():uu_temp(NULL), gpg_verified(false) {};
+    sep_state():uu_temp(NULL), gpg_verified("") {};
   };
 
   bool
@@ -616,6 +626,8 @@ namespace
         line_len = pch - line_str;
       }
 
+      std::cerr<<"LINE   "<<line_str;
+
       if (gpg_is_signed_begin_line(line_str))
       {
         std::cerr<<"signed begin\n";
@@ -799,7 +811,12 @@ namespace
             GMimeStream * stream = g_mime_stream_substream (istream, sub_begin, linestart_pos+line_len);
             GPGDecErr info;
             GMimeStream * dec = gpg_decrypt(info, stream, cur);
-            if (info.verify_ok) state.gpg_verified = true;
+            std::cerr<<"info verify "<<info.verify_ok<<"\n";
+            if (info.verify_ok)
+              state.gpg_verified = "valid";
+            else if (!info.verify_ok && !info.no_sigs)
+              state.gpg_verified = "invalid";
+            state.gpgerr = info;
             gpg_looking_for_line = false;
             if (info.dec_ok)
             {
@@ -1000,6 +1017,7 @@ namespace
           // reset these for each part
           const char * type = "text";
           const char * subtype = "plain";
+
           tmp_part = *it;
           filename = tmp_part->filename;
 
@@ -1014,9 +1032,6 @@ namespace
           content = g_mime_data_wrapper_new_with_stream (subpart_stream, GMIME_CONTENT_ENCODING_DEFAULT);
           g_mime_part_set_content_object (subpart, content);
           g_mime_multipart_add (GMIME_MULTIPART (multipart), GMIME_OBJECT (subpart));
-          std::cerr<<"setting gpg header "<<(state.gpg_verified ? "true" : "false")<<"\n";
-          g_mime_object_set_header (GMIME_OBJECT(subpart), "Gpg-Verified", state.gpg_verified  ? "true" : "false");
-          std::cerr<<"headers now:\n"<< g_mime_object_get_headers(GMIME_OBJECT(subpart))<<"\n";
 
           g_object_unref (content);
           g_object_unref (subpart);
@@ -1032,25 +1047,28 @@ namespace
         }
         if(GMIME_IS_MULTIPART(parent))
         {
+          std::cerr<<"parent is multipart\n";
           GMimeMultipart *mp = GMIME_MULTIPART (parent);
           int index = g_mime_multipart_index_of (mp, part);
           g_mime_multipart_remove_at (mp, index);
           g_object_unref (part);
 
-          //should be fixed meanwhile (!) workaround gmime insert bug
-          g_mime_multipart_insert (mp,index,newpart);
-//          {
-//            ptr_array_insert(mp->children, index, newpart);
+          //workaround gmime insert bug
+          //g_mime_multipart_insert (mp,index,newpart);
+          {
+            ptr_array_insert(mp->children, index, newpart);
             g_object_ref(newpart);
-//          }
+          }
         }
         else if(GMIME_IS_MESSAGE(parent))
         {
+          std::cerr<<"parent is msg\n";
           g_mime_message_set_mime_part((GMimeMessage*)parent, newpart);
         }
         g_object_unref(newpart);
       }
     }
+
     parts.clear();
     g_object_unref (istream);
   }
@@ -1099,7 +1117,8 @@ namespace{
 
 GMimeMessage*
 mime :: construct_message (GMimeStream  ** istreams,
-                           int             qty)
+                           int             qty,
+                           GPGDecErr     & gpgerr)
 {
   const char * message_id = "Foo <bar mum>";
   GMimeMessage * retval = 0;
@@ -1119,7 +1138,6 @@ mime :: construct_message (GMimeStream  ** istreams,
   for (int i=0; i<qty; ++i) {
     g_mime_parser_init_with_stream (parser, istreams[i]);
     messages[i] = g_mime_parser_construct_message (parser);
-    std::cerr<<"\nfirst gpg: "<<g_mime_object_get_header(GMIME_OBJECT(messages[i]), "Gpg-Verified")<<"\n";
   }
   g_object_unref (parser);
 
@@ -1149,6 +1167,9 @@ mime :: construct_message (GMimeStream  ** istreams,
   {
     temp_p &data(*it);
     handle_uu_and_yenc_in_text_plain_cb(data.parent, data.part, &state);
+    /* set gpg signature verify success/fail flag */
+    g_mime_object_set_header(GMIME_OBJECT(data.parent), "X-GPG-Signed", state.gpg_verified.c_str());
+    gpgerr = state.gpgerr;
   }
 
   // cleanup
@@ -1158,9 +1179,6 @@ mime :: construct_message (GMimeStream  ** istreams,
   }
   g_free (messages);
 
-  /* test for gpg */
-  std::cerr<<"\nsecond gpg: "<<g_mime_object_get_header(GMIME_OBJECT(retval), "Gpg-Verified")<<"\n";
-
   return retval;
 }
 
diff --git a/pan/usenet-utils/mime-utils.h b/pan/usenet-utils/mime-utils.h
index 868541a..55b4287 100644
--- a/pan/usenet-utils/mime-utils.h
+++ b/pan/usenet-utils/mime-utils.h
@@ -76,16 +76,6 @@
 namespace pan
 {
 
-  struct GPGDecErr
-  {
-    gpg_error_t err;
-    gpgme_decrypt_result_t dec_res;
-    gpgme_verify_result_t v_res;
-    bool dec_ok;
-    bool verify_ok;
-    GPGDecErr() : dec_ok(false), verify_ok(false) {}
-  };
-
   /**
    * Utilities to build and parse GMimeMessages.
    *
@@ -99,7 +89,8 @@ namespace pan
   {
     static GMimeMessage *
     construct_message (GMimeStream ** istreams,
-                         int            qty);
+                         int            qty,
+                         GPGDecErr  & gpgerr);
 
 
     static const char *



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