[pan2: 240/268] compile fixes for gnome-keyring and libnotify



commit 262c989645a23e175824f8ba20001103326c2f04
Author: Heinrich MÃller <henmull src gnome org>
Date:   Mon Dec 12 09:51:30 2011 +0100

    compile fixes for gnome-keyring and libnotify

 configure.in                   |   46 ++++++----
 pan/data-impl/data-impl.cc     |    6 +-
 pan/data/data.h                |    7 +-
 pan/gui/body-pane.cc           |   21 ++---
 pan/gui/gui.cc                 |    1 -
 pan/gui/pan.cc                 |    8 +-
 pan/gui/post-ui.cc             |  179 ++++++-------------------------------
 pan/gui/post-ui.h              |   10 +--
 pan/gui/prefs-ui.cc            |    2 +
 pan/usenet-utils/mime-utils.cc |  194 ++++++++++++++++++++++++++++++++++++++--
 pan/usenet-utils/mime-utils.h  |    5 +-
 11 files changed, 274 insertions(+), 205 deletions(-)
---
diff --git a/configure.in b/configure.in
index 9175c81..6ce0f6c 100644
--- a/configure.in
+++ b/configure.in
@@ -46,7 +46,7 @@ dnl GtkSpell is optional: GTKSPELL_REQUIRED refers to the minimum version
 dnl needed if you want to build Pan with spellchecking in the Post window.
 
 GLIB_REQUIRED=2.14.0
-GMIME_REQUIRED=2.6.0
+GMIME_REQUIRED=2.4.0
 GTK_REQUIRED=2.16.0
 GTK3_REQUIRED=3.0.0
 GTKSPELL_REQUIRED=2.0.7
@@ -122,7 +122,7 @@ fi
 
 dnl Check for libnotify if user-enabled for popup notifications
 AC_ARG_ENABLE([libnotify],
-AC_HELP_STRING([--enable-libnotify],[enable libnotify support]),,[enable_libnotify=yes])
+AC_HELP_STRING([--enable-libnotify],[enable libnotify support]),,[enable_libnotify=no])
 if test "x$enable_libnotify" = "xyes" ; then
   PKG_CHECK_MODULES([LIBNOTIFY],[libnotify >= $LIBNOTIFY_REQUIRED],[HAVE_LIBNOTIFY="yes"],[HAVE_LIBNOTIFY="no"])
   AC_SUBST([LIBNOTIFY_CFLAGS])
@@ -132,26 +132,38 @@ if test "x$enable_libnotify" = "xyes" ; then
   fi
 fi
 
-dnl Check for gsasl for secure authentication
-PKG_CHECK_MODULES([LIBGSASL],[libgsasl >= $LIBGSASL_REQUIRED],[HAVE_SASL="yes"],[HAVE_SASL="no"])
-AC_SUBST([LIBGSASL_CFLAGS])
-AC_SUBST([LIBGSASL_LIBS])
-if test "x$HAVE_SASL" = "xyes"; then
-  AC_DEFINE([HAVE_SASL],[1],[libgsasl for secure NNTP authentication])
+dnl check for libgsasl for secure authentication
+AC_ARG_ENABLE([libgsasl],
+AC_HELP_STRING([--enable-libgsasl],[enable libgsasl support]),,[enable_libgsasl=no])
+if test "x$enable_libgsasl" = "xyes" ; then
+  PKG_CHECK_MODULES([LIBGSASL],[libgsasl >= $LIBGSASL_REQUIRED],[HAVE_SASL="yes"],[HAVE_SASL="no"])
+  AC_SUBST([LIBGSASL_CFLAGS])
+  AC_SUBST([LIBGSASL_LIBS])
+  if test "x$HAVE_SASL" = "xyes"; then
+    AC_DEFINE([HAVE_SASL],[1],[libgsasl for secure authentication])
+  fi
 fi
 
-dnl Check for gnome-keyring for password storage
-PKG_CHECK_MODULES([LIBGNOME_KEYRING_1],[gnome-keyring-1 >= $LIBGKR_REQUIRED],[HAVE_GKR="yes"],[HAVE_GKR="no"])
-AC_SUBST([LIBGNOME_KEYRING_1_CFLAGS])
-AC_SUBST([LIBGNOME_KEYRING_1_LIBS])
-if test "x$HAVE_GKR" = "xyes"; then
-  AC_DEFINE([HAVE_GKR],[1],[gnome-keyring-1 for password storage])
+dnl Check for gnome-keyring if user-enabled for popup notifications
+AC_ARG_ENABLE([gnome-keyring],
+AC_HELP_STRING([--enable-gnome-keyring],[enable gnome-keyring support]),,[enable_gnome-keyring=no])
+if test "x$enable-gnome-keyring" = "xyes" ; then
+  PKG_CHECK_MODULES([LIBGNOME_KEYRING_1],[gnome-keyring-1 >= $LIBGKR_REQUIRED],[HAVE_GKR="yes"],[HAVE_GKR="no"])
+  AC_SUBST([LIBGNOME_KEYRING_1_CFLAGS])
+  AC_SUBST([LIBGNOME_KEYRING_1_LIBS])
+  if test "x$HAVE_GKR" = "xyes"; then
+    AC_DEFINE([HAVE_GKR],[1],[gnome-keyring-1 for password storage])
+  fi
 fi
 
 dnl Check for gpgme for message encryption / signing
-AM_PATH_GPGME([$LIBGPGME_REQUIRED],[HAVE_GPGME="yes"],[HAVE_GPGME="no"])
-if test "x$HAVE_GPGME" = "xyes"; then
-  AC_DEFINE([HAVE_GPGME],[1],[gpgme for message encryption / signing])
+AC_ARG_ENABLE([gpgme],
+AC_HELP_STRING([--enable-gpgme],[enable gpgme support]),,[enable_gpgme=no])
+if test "x$enable-gpgme" = "xyes" ; then
+  AM_PATH_GPGME([$LIBGPGME_REQUIRED],[HAVE_GPGME="yes"],[HAVE_GPGME="no"])
+  if test "x$HAVE_GKR" = "xyes"; then
+    AC_DEFINE([HAVE_GPGME],[1],[gpgme for message encryption / signing])
+  fi
 fi
 
 dnl Check to see if strftime supports the use of %l and %k
diff --git a/pan/data-impl/data-impl.cc b/pan/data-impl/data-impl.cc
index 6d822ee..217fd77 100644
--- a/pan/data-impl/data-impl.cc
+++ b/pan/data-impl/data-impl.cc
@@ -33,8 +33,10 @@ extern "C" {
 #include <pan/general/time-elapsed.h>
 #include "data-impl.h"
 
-#include <gnome-keyring-1/gnome-keyring.h>
-#include <gnome-keyring-1/gnome-keyring-memory.h>
+#ifdef HAVE_GKR
+  #include <gnome-keyring-1/gnome-keyring.h>
+  #include <gnome-keyring-1/gnome-keyring-memory.h>
+#endif
 
 using namespace pan;
 
diff --git a/pan/data/data.h b/pan/data/data.h
index f9d94ea..02d9667 100644
--- a/pan/data/data.h
+++ b/pan/data/data.h
@@ -35,8 +35,11 @@
 #include <pan/data/cert-store.h>
 #include <pan/data/server-info.h>
 
-#include <gnome-keyring-1/gnome-keyring.h>
-#include <gnome-keyring-1/gnome-keyring-memory.h>
+
+#ifdef HAVE_GKR
+  #include <gnome-keyring-1/gnome-keyring.h>
+  #include <gnome-keyring-1/gnome-keyring-memory.h>
+#endif
 
 namespace pan
 {
diff --git a/pan/gui/body-pane.cc b/pan/gui/body-pane.cc
index 637bf22..56ef715 100644
--- a/pan/gui/body-pane.cc
+++ b/pan/gui/body-pane.cc
@@ -926,7 +926,7 @@ BodyPane ::get_gpgsig_from_gmime_part (GMimePart * part)
   {
     g_mime_data_wrapper_write_to_stream (wrapper, mem_stream);
     g_mime_stream_reset(mem_stream);
-    gpd_decrypt_and_verify(_signer_info, _gpgerr, mem_stream);
+    gpg_decrypt_and_verify(_signer_info, _gpgerr, mem_stream);
     return true;
   }
   return false;
@@ -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, "*", "signed")))
+           (g_mime_content_type_is_type (type, "*", "pgp-signature")))
   {
     const char * fallback_charset (_charset.c_str());
     const char * p_flowed (g_mime_object_get_content_type_parameter(obj,"format"));
@@ -1017,16 +1017,11 @@ BodyPane :: append_part (GMimeObject * obj, GtkAllocation * widget_size)
     is_done = true;
 #ifdef HAVE_GPGME
     /* verify signature */
-    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);
-      }
+    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);
     }
 #endif
   }
@@ -1370,7 +1365,9 @@ BodyPane :: clear ()
     g_object_unref (_message);
   _message = 0;
   refresh ();
+#ifdef HAVE_GPGME
   update_sig_valid(-1);
+#endif
 }
 
 void
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 0ad9389..aa8e1ce 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -71,7 +71,6 @@ extern "C" {
 
 #ifdef HAVE_GPGME
   #include "gpg.h"
-  #define GPG_DEF 1
 #endif
 
 namespace pan
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 0074df6..9dd8968 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -53,7 +53,6 @@ extern "C" {
 
 #ifdef HAVE_GPGME
   #include <gpgme.h>
-  #define GPG_DEF 1
   #include <pan/gui/gpg.h>
 #endif
 
@@ -73,9 +72,10 @@ extern "C" {
 #include "server-ui.h"
 #include "pad.h"
 
-#include <gnome-keyring-1/gnome-keyring.h>
-#include <gnome-keyring-1/gnome-keyring-memory.h>
-
+#ifdef HAVE_GKR
+  #include <gnome-keyring-1/gnome-keyring.h>
+  #include <gnome-keyring-1/gnome-keyring-memory.h>
+#endif
 
 //#define DEBUG_LOCALE 1
 #define DEBUG_PARALLEL 1
diff --git a/pan/gui/post-ui.cc b/pan/gui/post-ui.cc
index 8572e7b..9d7fd94 100644
--- a/pan/gui/post-ui.cc
+++ b/pan/gui/post-ui.cc
@@ -347,142 +347,6 @@ PostUI :: set_always_run_editor (bool run)
   _prefs.set_flag ("always-run-editor", run);
 }
 
-#ifdef HAVE_GPGME
-
-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)
-{
-
-  const Profile profile (get_current_profile ());
-  std::string uid = profile.gpg_sig_uid;
-  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_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_BASE64);
-//  gpgme_data_set_file_name(gpg_out_buf, "signature.asc");
-
-  fail.err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
-  while (!fail.err)
-  {
-    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 0; }
-
-  gpgme_signers_clear(gpg_ctx);
-  gpgme_signers_add(gpg_ctx, mykey);
-
-  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_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;
-  }
-
-  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)
-  {
-    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)
-  {
-    ret_str << buffer;
-  }
-
-  std::cerr<<"encrypted:\n"<<ret_str.str()<<"\n\n";
-
-  gpgme_data_release(gpg_buf);
-  gpgme_data_release(gpg_out_buf);
-
-  fail.err = GPG_ERR_NO_ERROR;
-  return ret_str.str();
-}
-#endif
-
 void
 PostUI :: set_wrap_mode (bool wrap)
 {
@@ -1163,29 +1027,42 @@ PostUI :: maybe_post_message (GMimeMessage * message)
   {
 #ifdef HAVE_GPGME
     GPGEncErr fail;
-    std::string tmp = get_body();
-    if (user_has_gpg)
+    if (user_has_gpg && gpg_enc && !gpg_sign)
     {
-      if (gpg_enc)
+      std::cerr<<"encrypt\n";
+      Profile p(get_current_profile());
+      std::string res = gpg_encrypt(p.gpg_sig_uid, get_body(), fail);
+      if (gpgme_err_code(fail.err) == GPG_ERR_NO_ERROR)
+        gtk_text_buffer_set_text (_body_buf, res.c_str(), res.size());
+      else
       {
-        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;
-        }
+        Log::add_err_va("Failed to encode the Message with your key : \"%s\"",gpgme_strerror(fail.err));
+        return false;
       }
     }
+    if (user_has_gpg && gpg_enc && gpg_sign)
+    {
+      std::cerr<<"encrypt\n";
+      Profile p(get_current_profile());
+      std::string res = gpg_encrypt_and_sign(p.gpg_sig_uid,get_body(), 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 and encode the Message with your key : \"%s\"",gpgme_strerror(fail.err));
+        return false;
+      }
+    }
+
 #endif
     GMimeMessage* msg = new_message_from_ui(POSTING);
-
     bool go_on(true);
 
-    if (user_has_gpg && gpg_sign)
-      go_on = go_on && message_add_signed_part(tmp, msg, fail);
+#ifdef HAVE_GPGME
+    Profile p(get_current_profile());
+    if (user_has_gpg && gpg_sign && !gpg_enc)
+      go_on = go_on && message_add_signed_part(p.gpg_sig_uid, get_body(), msg, fail);
+#endif
 
     if (go_on)
     {
diff --git a/pan/gui/post-ui.h b/pan/gui/post-ui.h
index f0e03d0..c51319a 100644
--- a/pan/gui/post-ui.h
+++ b/pan/gui/post-ui.h
@@ -87,15 +87,7 @@ namespace pan
       void close_window (bool flag=false);
       void set_wrap_mode (bool wrap);
       void set_always_run_editor (bool);
-#ifdef HAVE_GPGME
-      /** 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_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();
 
       //popup action entries
diff --git a/pan/gui/prefs-ui.cc b/pan/gui/prefs-ui.cc
index 5e113d3..1b38eb0 100644
--- a/pan/gui/prefs-ui.cc
+++ b/pan/gui/prefs-ui.cc
@@ -602,8 +602,10 @@ PrefsDialog :: PrefsDialog (Prefs& prefs, GtkWindow* parent):
     HIG :: workarea_add_wide_control (t, &row, w);
     w = new_check_button (_("Start Pan minimized"), "start-minimized", false, prefs);
     HIG :: workarea_add_wide_control (t, &row, w);
+#ifdef HAVE_LIBNOTIFY
     w = new_check_button (_("Show notifications"), "use-notify", false, prefs);
     HIG :: workarea_add_wide_control (t, &row, w);
+#endif
   HIG :: workarea_finish (t, &row);
   gtk_notebook_append_page (GTK_NOTEBOOK(notebook), t, gtk_label_new_with_mnemonic(_("_Behavior")));
 
diff --git a/pan/usenet-utils/mime-utils.cc b/pan/usenet-utils/mime-utils.cc
index 20058bb..aeb9853 100644
--- a/pan/usenet-utils/mime-utils.cc
+++ b/pan/usenet-utils/mime-utils.cc
@@ -479,7 +479,7 @@ namespace pan
   }
 
 #ifdef HAVE_GPGME
-  GMimeStream* gpd_decrypt_and_verify (GPGSignersInfo& signer_info, GPGDecErr& info, GMimeStream* s)
+  GMimeStream* gpg_decrypt_and_verify (GPGSignersInfo& signer_info, GPGDecErr& info, GMimeStream* s, const char* body)
   {
 
     GMimeStream* decrypted = g_mime_stream_mem_new ();
@@ -493,12 +493,14 @@ namespace pan
 
     info.err = GPG_ERR_NO_ERROR;
 
-    gpgme_data_t gpg_buf, gpg_out_buf;
+    gpgme_data_t gpg_buf, gpg_out_buf, body_data;
     gpgme_key_t key;
 
     StringView v(streambuf);
     gpgme_data_new_from_mem (&gpg_buf, v.str, v.len, 0);
 
+    if (body) gpgme_data_new_from_mem (&body_data, body, strlen(body), 0);
+
     gpgme_strerror(gpgme_data_new (&gpg_out_buf));
 
     gpgme_data_set_encoding (gpg_out_buf, GPGME_DATA_ENCODING_NONE);
@@ -511,6 +513,11 @@ namespace pan
     else
       return decrypted;
 
+    if (gpgme_err_code(info.err) == GPG_ERR_NO_DATA && body) // verify attached sigs, too
+    {
+      info.err = gpgme_op_verify (gpg_ctx, gpg_buf, body_data, 0);
+    }
+
     info.dec_res  = gpgme_op_decrypt_result (gpg_ctx);
     info.v_res    = gpgme_op_verify_result  (gpg_ctx);
 
@@ -544,14 +551,12 @@ namespace pan
 
     GPGSignersInfo si;
 
-    if (info.verify_ok && !info.no_sigs)
+    if (!info.no_sigs)
     {
       if (info.v_res->signatures->fpr)
         gpgme_get_key (gpg_ctx, info.v_res->signatures->fpr, &key, 0);
       if (key)
-      {
         fill_signer_info(si, key);
-      }
     }
 
     signer_info = si;
@@ -559,6 +564,181 @@ namespace pan
 
     return decrypted;
   }
+
+  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*
+  message_add_signed_part (const std::string& uid, const std::string& body_str, GMimeMessage* body, GPGEncErr& fail)
+  {
+    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_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_BASE64);
+  //  gpgme_data_set_file_name(gpg_out_buf, "signature.asc");
+
+    fail.err = gpgme_op_keylist_start (gpg_ctx, 0, 0);
+    while (!fail.err)
+    {
+      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 0; }
+
+    gpgme_signers_clear(gpg_ctx);
+    gpgme_signers_add(gpg_ctx, mykey);
+
+    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_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;
+    }
+
+    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
+  gpg_encrypt(const std::string& uid, const std::string& body, GPGEncErr& fail)
+  {
+    fail.err = GPG_ERR_GENERAL;
+
+    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)
+    {
+      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)
+    {
+      ret_str << buffer;
+    }
+
+    gpgme_data_release(gpg_buf);
+    gpgme_data_release(gpg_out_buf);
+
+    fail.err = GPG_ERR_NO_ERROR;
+    return ret_str.str();
+  }
+
+  std::string
+  gpg_encrypt_and_sign(const std::string& uid, const std::string& body, GPGEncErr& fail)
+  {
+    fail.err = GPG_ERR_GENERAL;
+
+    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)
+    {
+      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_signers_clear(gpg_ctx);
+    gpgme_signers_add(gpg_ctx, mykey);
+
+    gpgme_key_t enc_keys[] = { mykey, NULL};
+
+    fail.err     = gpgme_op_encrypt_sign (gpg_ctx, enc_keys, GPGME_ENCRYPT_PREPARE, gpg_buf, gpg_out_buf);
+    fail.enc_res = gpgme_op_encrypt_result (gpg_ctx);
+    fail.sign_res= gpgme_op_sign_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)
+    {
+      ret_str << buffer;
+    }
+
+    gpgme_data_release(gpg_buf);
+    gpgme_data_release(gpg_out_buf);
+
+    fail.err = GPG_ERR_NO_ERROR;
+    return ret_str.str();
+  }
 #endif
 
   void apply_source_and_maybe_filter (TempPart * part, GMimeStream * s)
@@ -816,7 +996,7 @@ namespace pan
           if (gpg_is_ending_line(line_str))
           {
             GMimeStream * stream = g_mime_stream_substream (istream, sub_begin, linestart_pos+line_len);
-            GMimeStream * dec = gpd_decrypt_and_verify(state.signer_info, state.gpgerr, stream);
+            GMimeStream * dec = gpg_decrypt_and_verify(state.signer_info, state.gpgerr, stream);
             if (state.gpgerr.verify_ok)
               state.gpg_verified = "valid";
             else if (!state.gpgerr.verify_ok && !state.gpgerr.no_sigs)
@@ -1502,3 +1682,5 @@ void pan::pan_g_mime_message_set_message_id (GMimeMessage *msg, const char *mid)
     g_mime_header_list_set (GMIME_OBJECT(msg)->headers, "Message-ID", bracketed);
     g_free (bracketed);
 }
+
+
diff --git a/pan/usenet-utils/mime-utils.h b/pan/usenet-utils/mime-utils.h
index 1ec04da..0047432 100644
--- a/pan/usenet-utils/mime-utils.h
+++ b/pan/usenet-utils/mime-utils.h
@@ -76,7 +76,10 @@
 namespace pan
 {
 #ifdef HAVE_GPGME
-  GMimeStream* gpd_decrypt_and_verify (GPGSignersInfo& signer_info, GPGDecErr& info, GMimeStream* s);
+  GMimeStream* gpg_decrypt_and_verify (GPGSignersInfo& signer_info, GPGDecErr& info, GMimeStream* s, const char* body=0);
+  GMimeMessage* message_add_signed_part (const std::string& uid, const std::string& body_str, GMimeMessage* body, GPGEncErr& fail);
+  std::string gpg_encrypt(const std::string& uid, const std::string& body, GPGEncErr& fail);
+  std::string gpg_encrypt_and_sign(const std::string& uid, const std::string& body, GPGEncErr& fail);
 #endif
 
   /**



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