[git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-45-g0853344

by Andre Heinecke cvs at cvs.gnupg.org
Thu Feb 22 09:58:19 CET 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG extension for MS Outlook".

The branch, async-enc has been updated
       via  0853344d1dcf520ea657d7208661214f69b59dad (commit)
      from  9017cf6fb9c78a83d9d5d08d886c41878444369b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0853344d1dcf520ea657d7208661214f69b59dad
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Feb 22 09:45:46 2018 +0100

    Implement handling of WKS-Confirmation mails
    
    * src/common_indep.h (msgtype_t): New messagtype for WKS_Confirm
    mails.
    * src/mail.cpp (Mail::decrypt_verify): Handle new message type.
    (Mail::is_smime): Clarify an error message.
    * src/mapihelp.cpp
    (change_message_class_ipm_note_smime_multipartsigned),
    (string_to_type, mapi_change_message_class),
    (mapi_get_message_content_type): Handle
    wks confirmation mails.
    * src/message.cpp: Default / ignore new message type in old code.
    * src/wks-helper.cpp: Lots of changes.

diff --git a/src/common_indep.h b/src/common_indep.h
index 10b14d6..adfc8bf 100644
--- a/src/common_indep.h
+++ b/src/common_indep.h
@@ -98,7 +98,8 @@ typedef enum
     MSGTYPE_GPGOL_OPAQUE_SIGNED,
     MSGTYPE_GPGOL_OPAQUE_ENCRYPTED,
     MSGTYPE_GPGOL_CLEAR_SIGNED,
-    MSGTYPE_GPGOL_PGP_MESSAGE
+    MSGTYPE_GPGOL_PGP_MESSAGE,
+    MSGTYPE_GPGOL_WKS_CONFIRMATION
   }
 msgtype_t;
 
diff --git a/src/mail.cpp b/src/mail.cpp
index 00b42d3..e9a8d59 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -37,6 +37,7 @@
 #include "gpgolstr.h"
 #include "windowmessages.h"
 #include "mlang-charset.h"
+#include "wks-helper.h"
 
 #include <gpgme++/configuration.h>
 #include <gpgme++/tofuinfo.h>
@@ -841,9 +842,22 @@ Mail::decrypt_verify()
     }
   set_uuid ();
   m_processed = true;
+
+
   /* Insert placeholder */
   char *placeholder_buf;
-  if (gpgrt_asprintf (&placeholder_buf, opt.prefer_html ? decrypt_template_html :
+  if (m_type == MSGTYPE_GPGOL_WKS_CONFIRMATION)
+    {
+      gpgrt_asprintf (&placeholder_buf, opt.prefer_html ? decrypt_template_html :
+                      decrypt_template,
+                      "OpenPGP",
+                      _("Pubkey directory confirmation"),
+                      _("This is a confirmation request to publish your Pubkey in the "
+                        "directory for your domain.\n\n"
+                        "<p>If you did not request to publish your Pubkey in your providers "
+                        "directory, simply ignore this message.</p>\n"));
+    }
+  else if (gpgrt_asprintf (&placeholder_buf, opt.prefer_html ? decrypt_template_html :
                       decrypt_template,
                       is_smime() ? "S/MIME" : "OpenPGP",
                       _("Encrypted message"),
@@ -877,6 +891,12 @@ Mail::decrypt_verify()
   /* Do the actual parsing */
   auto cipherstream = get_attachment_stream (m_mailitem, m_moss_position);
 
+  if (m_type == MSGTYPE_GPGOL_WKS_CONFIRMATION)
+    {
+      WKSHelper::instance ()->handle_confirmation_read (this, cipherstream);
+      return 0;
+    }
+
   if (!cipherstream)
     {
       log_debug ("%s:%s: Failed to get cipherstream.",
@@ -1504,7 +1524,8 @@ Mail::is_smime ()
         }
       else
         {
-          log_error ("Protocol in multipart signed mail.");
+          log_error ("%s:%s: No protocol in multipart / signed mail.",
+                     SRCNAME, __func__);
         }
       xfree (proto);
       xfree (ct);
diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp
index a9c69c3..5ff9ad1 100644
--- a/src/mapihelp.cpp
+++ b/src/mapihelp.cpp
@@ -1047,7 +1047,7 @@ change_message_class_ipm_note_smime (LPMESSAGE message)
   if (ct)
     {
       log_debug ("%s:%s: content type is '%s'", SRCNAME, __func__, ct);
-      if (proto 
+      if (proto
           && !strcmp (ct, "multipart/signed")
           && !strcmp (proto, "application/pgp-signature"))
         {
@@ -1140,6 +1140,10 @@ change_message_class_ipm_note_smime_multipartsigned (LPMESSAGE message)
         {
           newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
         }
+      else if (!strcmp (ct, "wks.confirmation.mail"))
+        {
+          newvalue = xstrdup ("IPM.Note.GpgOL.WKSConfirmation");
+        }
       xfree (proto);
       xfree (ct);
     }
@@ -1283,6 +1287,8 @@ string_to_type (const char *s)
         return MSGTYPE_GPGOL_CLEAR_SIGNED;
       else if (!strcmp (s, ".PGPMessage"))
         return MSGTYPE_GPGOL_PGP_MESSAGE;
+      else if (!strcmp (s, ".WKSConfirmation"))
+        return MSGTYPE_GPGOL_WKS_CONFIRMATION;
       else
         log_debug ("%s:%s: message class `%s' not supported",
                    SRCNAME, __func__, s-14);
@@ -1357,8 +1363,23 @@ mapi_change_message_class (LPMESSAGE message, int sync_override,
              keep the SMIME; we need to change the SMIME part of the
              class name so that Outlook does not process it as an
              SMIME message. */
-          newvalue = (char*)xmalloc (strlen (s) + 1);
-          strcpy (stpcpy (newvalue, "IPM.Note.GpgOL"), s+14);
+
+          char *tmp = change_message_class_ipm_note_smime_multipartsigned
+            (message);
+          /* This case happens even for PGP/MIME mails but that is ok
+             as we later fiddle out the protocol. But we have to
+             check if this is a WKS Mail now so that we can do the
+             special handling for that. */
+          if (tmp && !strcmp (tmp, "IPM.Note.GpgOL.WKSConfirmation"))
+            {
+              newvalue = tmp;
+            }
+          else
+            {
+              xfree (tmp);
+              newvalue = (char*)xmalloc (strlen (s) + 1);
+              strcpy (stpcpy (newvalue, "IPM.Note.GpgOL"), s+14);
+            }
         }
       else if (!strcmp (s, "IPM.Note.SMIME.MultipartSigned"))
         {
@@ -3038,6 +3059,16 @@ mapi_get_message_content_type (LPMESSAGE message,
       length = (s - header_lines);
       if (length && s[-1] == '\r')
         length--;
+
+      if (!strncmp ("Wks-Phase: confirm", header_lines, length))
+        {
+          log_debug ("%s:%s: detected wks confirmation mail",
+                     SRCNAME, __func__);
+          retstr = xstrdup ("wks.confirmation.mail");
+          rfc822parse_close (msg);
+          return retstr;
+        }
+
       rfc822parse_insert (msg, (const unsigned char*)header_lines, length);
       header_lines = s+1;
     }
diff --git a/src/mapihelp.h b/src/mapihelp.h
index 0355618..1f2f35c 100644
--- a/src/mapihelp.h
+++ b/src/mapihelp.h
@@ -136,5 +136,7 @@ int mapi_body_to_attachment (LPMESSAGE message);
 char * mapi_get_uid (LPMESSAGE message);
 #ifdef __cplusplus
 }
+#include <string>
+std::string mapi_get_header (LPMESSAGE message);
 #endif
 #endif /*MAPIHELP_H*/
diff --git a/src/message.cpp b/src/message.cpp
index 8e63c0d..c33ad1b 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -135,6 +135,8 @@ message_incoming_handler (LPMESSAGE message, HWND hwnd, bool force)
       retval = 2;
       message_decrypt (message, msgtype, force, hwnd);
       break;
+    default:
+      break;
     }
 
   return retval;
@@ -537,6 +539,7 @@ message_verify (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd)
                               "that S/MIME processing has been enabled."));
       else
         show_message (hwnd, _("This message has no signature."));
+    default:
       return 0; /* Nothing to do.  */
     }
   
@@ -712,6 +715,7 @@ message_decrypt (LPMESSAGE message, msgtype_t msgtype, int force, HWND hwnd)
       is_opaque = 1;
       break;
     case MSGTYPE_GPGOL_PGP_MESSAGE:
+    default:
       break;
     }
   
diff --git a/src/wks-helper.cpp b/src/wks-helper.cpp
index 753de8d..6d9f9e2 100644
--- a/src/wks-helper.cpp
+++ b/src/wks-helper.cpp
@@ -23,8 +23,8 @@
 #include "cpphelp.h"
 #include "oomhelp.h"
 #include "windowmessages.h"
-#include "overlay.h"
 #include "mail.h"
+#include "mapihelp.h"
 
 #include <map>
 #include <sstream>
@@ -38,13 +38,16 @@
 
 #define CHECK_MIN_INTERVAL (60 * 60 * 24 * 7)
 
+#define DEBUG_WKS 1
+
 #undef _
 #define _(a) utf8_gettext (a)
 
 static std::map <std::string, WKSHelper::WKSState> s_states;
 static std::map <std::string, time_t> s_last_checked;
+static std::map <std::string, std::pair <GpgME::Data *, Mail *> > s_confirmation_cache;
 
-static WKSHelper* singleton = NULL;
+static WKSHelper* singleton = nullptr;
 
 GPGRT_LOCK_DEFINE (wks_lock);
 
@@ -99,6 +102,24 @@ WKSHelper::get_check_time (const std::string &mbox) const
   return it->second;
 }
 
+std::pair <GpgME::Data *, Mail *>
+WKSHelper::get_cached_confirmation (const std::string &mbox) const
+{
+  gpgrt_lock_lock (&wks_lock);
+  const auto it = s_confirmation_cache.find(mbox);
+  const auto dataEnd = s_confirmation_cache.end();
+
+  if (it == dataEnd)
+    {
+      gpgrt_lock_unlock (&wks_lock);
+      return std::make_pair (nullptr, nullptr);
+    }
+  auto ret = it->second;
+  s_confirmation_cache.erase (it);
+  gpgrt_lock_unlock (&wks_lock);
+  return ret;
+}
+
 static std::string
 get_wks_client_path ()
 {
@@ -218,8 +239,8 @@ WKSHelper::start_check (const std::string &mbox, bool forced) const
   log_debug ("%s:%s: WKSHelper starting check",
              SRCNAME, __func__);
   /* Start the actual work that can be done in a background thread. */
-  CloseHandle (CreateThread (NULL, 0, do_check, strdup (mbox.c_str ()), 0,
-                             NULL));
+  CloseHandle (CreateThread (nullptr, 0, do_check, strdup (mbox.c_str ()), 0,
+                             nullptr));
   return;
 }
 
@@ -239,23 +260,28 @@ static DWORD WINAPI
 do_notify (LPVOID arg)
 {
   /** Wait till a message was sent */
-  //Sleep (5000);
-  do_in_ui_thread (WKS_NOTIFY, arg);
+  std::pair<char *, int> *args = (std::pair<char *, int> *) arg;
+
+  Sleep (args->second);
+  do_in_ui_thread (WKS_NOTIFY, args->first);
+  delete args;
 
   return 0;
 }
 
 void
-WKSHelper::allow_notify () const
+WKSHelper::allow_notify (int sleepTimeMS) const
 {
   gpgrt_lock_lock (&wks_lock);
   for (auto &pair: s_states)
     {
-      if (pair.second == NeedsPublish)
+      if (pair.second == ConfirmationSeen ||
+          pair.second == NeedsPublish)
         {
-          CloseHandle (CreateThread (NULL, 0, do_notify,
-                                     strdup (pair.first.c_str ()), 0,
-                                     NULL));
+          auto *args = new std::pair<char *, int> (strdup (pair.first.c_str()), sleepTimeMS);
+          CloseHandle (CreateThread (nullptr, 0, do_notify,
+                                     args, 0,
+                                     nullptr));
           break;
         }
     }
@@ -272,11 +298,12 @@ WKSHelper::notify (const char *cBox) const
   if (state == NeedsPublish)
     {
       if (gpgol_message_box (get_active_hwnd (),
-                             _("Your mail provider supports a key directory.\n\n"
-                                          "Register your key in that directory to make\n"
-                                          "it easier for others to send you encrypted mail.\n\n\n"
-                                          "Register Key?"),
-                             _("GpgOL: Key directory available!"), MB_YESNO) == IDYES)
+                             _("A Pubkey directory is available for your domain.\n\n"
+                               "Register your Pubkey in that directory to make\n"
+                               "it easy for others to send you encrypted mail.\n\n"
+                               "It's secure and free!\n\n"
+                               "Register automatically?"),
+                             _("GpgOL: Pubkey directory available!"), MB_YESNO) == IDYES)
         {
           start_publish (mbox);
         }
@@ -286,20 +313,20 @@ WKSHelper::notify (const char *cBox) const
         }
       return;
     }
-  else
+  if (state == ConfirmationSeen)
     {
-      log_debug ("%s:%s: Unhandled notify state: %i for '%s'",
-                 SRCNAME, __func__, state, cBox);
+      handle_confirmation_notify (mbox);
       return;
     }
+
+  log_debug ("%s:%s: Unhandled notify state: %i for '%s'",
+             SRCNAME, __func__, state, cBox);
+  return;
 }
 
 void
 WKSHelper::start_publish (const std::string &mbox) const
 {
-//  Overlay (get_active_hwnd (),
-//           std::string (_("Creating registration request...")));
-
   log_debug ("%s:%s: Start publish for '%s'",
              SRCNAME, __func__, mbox.c_str ());
 
@@ -357,21 +384,27 @@ WKSHelper::start_publish (const std::string &mbox) const
   if (data.empty ())
     {
       gpgol_message_box (get_active_hwnd (),
-                         "WKS client failed to create publishing request.",
-                         _("GpgOL"),
+                         mystderr.toString().c_str (),
+                         _("GpgOL: Directory request failed"),
                          MB_OK);
       return;
     }
 
+#ifdef DEBUG_WKS
   log_debug ("%s:%s: WKS client: returned '%s'",
              SRCNAME, __func__, data.c_str ());
+#endif
 
-  send_mail (data);
-
+  if (!send_mail (data))
+    {
+      gpgol_message_box (get_active_hwnd (),
+                         _("You might receive a confirmation challenge from\n"
+                           "your provider to finish the registration."),
+                         _("GpgOL: Registration request sent!"), MB_OK);
+    }
   return;
 }
 
-
 void
 WKSHelper::update_state (const std::string &mbox, WKSState state) const
 {
@@ -389,7 +422,7 @@ WKSHelper::update_state (const std::string &mbox, WKSState state) const
   gpgrt_lock_unlock (&wks_lock);
 }
 
-void
+int
 WKSHelper::send_mail (const std::string &mimeData) const
 {
   std::istringstream ss(mimeData);
@@ -408,7 +441,7 @@ WKSHelper::send_mail (const std::string &mimeData) const
     {
       log_error ("%s:%s: Invalid mime data..",
                  SRCNAME, __func__);
-      return;
+      return -1;
     }
 
   std::getline (ss, withoutHeaders, '\0');
@@ -427,21 +460,21 @@ WKSHelper::send_mail (const std::string &mimeData) const
     {
       log_error ("%s:%s: Failed to create mail for request.",
                  SRCNAME, __func__);
-      return;
+      return -1;
     }
 
   if (put_oom_string (mail, "Subject", subject.c_str ()))
     {
       TRACEPOINT;
       gpgol_release (mail);
-      return;
+      return -1;
     }
 
   if (put_oom_string (mail, "To", to.c_str ()))
     {
       TRACEPOINT;
       gpgol_release (mail);
-      return;
+      return -1;
     }
 
   LPDISPATCH account = get_account_for_mail (from.c_str ());
@@ -462,9 +495,207 @@ WKSHelper::send_mail (const std::string &mimeData) const
   last_mail->set_override_mime_data (mimeData);
   last_mail->set_crypt_state (Mail::NeedsSecondAfterWrite);
 
-  invoke_oom_method (mail, "Save", NULL);
-  invoke_oom_method (mail, "Send", NULL);
-
+  if (invoke_oom_method (mail, "Save", nullptr))
+    {
+      // Should not happen.
+      log_error ("%s:%s: Failed to save mail.",
+                 SRCNAME, __func__);
+      return -1;
+    }
+  if (invoke_oom_method (mail, "Send", nullptr))
+    {
+      log_error ("%s:%s: Failed to send mail.",
+                 SRCNAME, __func__);
+      return -1;
+    }
   log_debug ("%s:%s: Done send mail.",
              SRCNAME, __func__);
+  return 0;
+}
+
+static void
+copy_stream_to_data (LPSTREAM stream, GpgME::Data *data)
+{
+  HRESULT hr;
+  char buf[4096];
+  ULONG bRead;
+  while ((hr = stream->Read (buf, 4096, &bRead)) == S_OK ||
+         hr == S_FALSE)
+    {
+      if (!bRead)
+        {
+          // EOF
+          return;
+        }
+      data->write (buf, (size_t) bRead);
+    }
+}
+
+void
+WKSHelper::handle_confirmation_notify (const std::string &mbox) const
+{
+  auto pair = get_cached_confirmation (mbox);
+  GpgME::Data *mimeData = pair.first;
+  Mail *mail = pair.second;
+
+  if (!mail)
+    {
+      log_debug ("%s:%s: Confirmation notify without cached mail.",
+                 SRCNAME, __func__);
+    }
+
+  if (!mimeData)
+    {
+      log_error ("%s:%s: Confirmation notify without cached data.",
+                 SRCNAME, __func__);
+      return;
+    }
+
+  /* First ask the user if he wants to confirm */
+  if (gpgol_message_box (get_active_hwnd (),
+                         _("Confirm registration?"),
+                         _("GpgOL: Pubkey directory confirmation"), MB_YESNO) != IDYES)
+    {
+      log_debug ("%s:%s: User aborted confirmation.",
+                 SRCNAME, __func__);
+      delete mimeData;
+
+      /* Next time we read the confirmation we ask again. */
+      update_state (mbox, RequestSent);
+      return;
+    }
+
+  /* Do the confirmation */
+  const auto wksPath = get_wks_client_path ();
+
+  if (wksPath.empty())
+    {
+      TRACEPOINT;
+      return;
+    }
+
+  std::vector<std::string> args;
+
+  args.push_back (wksPath);
+  args.push_back (std::string ("--receive"));
+
+  // Spawn the process
+  auto ctx = GpgME::Context::createForEngine (GpgME::SpawnEngine);
+  if (!ctx)
+    {
+      TRACEPOINT;
+      return;
+    }
+  GpgME::Data mystdout, mystderr;
+
+  char **cargs = vector_to_cArray (args);
+
+  GpgME::Error err = ctx->spawn (cargs[0], const_cast <const char **> (cargs),
+                                 *mimeData, mystdout, mystderr,
+                                 GpgME::Context::SpawnNone);
+  release_cArray (cargs);
+
+  if (err)
+    {
+      log_debug ("%s:%s: WKS client spawn code: %i asString: %s",
+                 SRCNAME, __func__, err.code(), err.asString());
+      return;
+    }
+  const auto data = mystdout.toString ();
+
+  if (data.empty ())
+    {
+      gpgol_message_box (get_active_hwnd (),
+                         mystderr.toString().c_str (),
+                         _("GpgOL: Confirmation failed"),
+                         MB_OK);
+      return;
+    }
+
+#ifdef DEBUG_WKS
+  log_debug ("%s:%s: WKS client: returned '%s'",
+             SRCNAME, __func__, data.c_str ());
+#endif
+  if (!send_mail (data))
+   {
+     gpgol_message_box (get_active_hwnd (),
+                        _("Your Pubkey can soon be retrieved from your domain."),
+                        _("GpgOL: Request confirmed!"), MB_OK);
+   }
+
+  if (mail && Mail::is_valid_ptr (mail))
+    {
+      invoke_oom_method (mail->item(), "Delete", nullptr);
+    }
+
+  update_state (mbox, ConfirmationSent);
+}
+
+void
+WKSHelper::handle_confirmation_read (Mail *mail, LPSTREAM stream) const
+{
+  /* We get the handle_confirmation in the Read event. To do sending
+     etc. we have to move out of that event. For this we prepare
+     the data for later usage. */
+
+  if (!mail || !stream)
+    {
+      TRACEPOINT;
+      return;
+    }
+
+  /* Get the recipient of the confirmation mail */
+  char **recipients = mail->get_recipients ();
+
+  /* We assert that we have one recipient as the mail should have been
+     sent by the wks-server. */
+  if (!recipients || !recipients[0] || recipients[1])
+    {
+      log_error ("%s:%s: invalid recipients",
+                 SRCNAME, __func__);
+      release_cArray (recipients);
+      gpgol_release (stream);
+      return;
+    }
+
+  std::string mbox = recipients[0];
+  release_cArray (recipients);
+
+  /* Prepare stdin for the wks-client process */
+
+  /* First we need to write the headers */
+  LPMESSAGE message = get_oom_base_message (mail->item());
+  if (!message)
+    {
+      log_error ("%s:%s: Failed to obtain message.",
+                 SRCNAME, __func__);
+      gpgol_release (stream);
+      return;
+    }
+
+  const auto headers = mapi_get_header (message);
+  gpgol_release (message);
+
+  GpgME::Data *mystdin = new GpgME::Data();
+
+  mystdin->write (headers.c_str (), headers.size ());
+
+  /* Then the MIME data */
+  copy_stream_to_data (stream, mystdin);
+  gpgol_release (stream);
+
+  /* Then lets make sure its flushy */
+  mystdin->write (nullptr, 0);
+
+  /* And reset it to start */
+  mystdin->seek (0, SEEK_SET);
+
+  gpgrt_lock_lock (&wks_lock);
+  s_confirmation_cache.insert (std::make_pair (mbox, std::make_pair (mystdin, mail)));
+  gpgrt_lock_unlock (&wks_lock);
+
+  update_state (mbox, ConfirmationSeen);
+
+  /* Send the window message for notify. */
+  allow_notify (5000);
 }
diff --git a/src/wks-helper.h b/src/wks-helper.h
index efd36f5..a6429f7 100644
--- a/src/wks-helper.h
+++ b/src/wks-helper.h
@@ -21,11 +21,22 @@
 #include "config.h"
 
 #include <string>
+#include "oomhelp.h"
+
+#include <utility>
+
+class Mail;
+namespace GpgME
+{
+  class Data;
+} // namespace GpgME
 
 /** @brief Helper for web key services.
  *
  * Everything is public to make it easy to access data
  * members from another windows thread. Don't mess with them.
+ *
+ * This is all a bit weird, don't look at it too much as it works ;-)
  */
 class WKSHelper
 {
@@ -39,9 +50,11 @@ public:
         NotSupported, /* <-- WKS is not supported for this address */
         Supported, /* <-- WKS is supported for this address */
         NeedsPublish, /* <-- There was no key published for this address */
+        ConfirmationSeen, /* A confirmation request was seen for this mail addres. */
         NeedsUpdate, /* <-- Not yet implemeted. */
         RequestSent, /* <-- A publishing request has been sent. */
         PublishDenied, /* <-- A user denied publishing. */
+        ConfirmationSent, /* <-- The confirmation response was sent. */
       };
 
     ~WKSHelper ();
@@ -76,8 +89,8 @@ public:
     /** Starts gpg-wks-client --create */
     void start_publish (const std::string &mbox) const;
 
-    /** Allow queueing a notification. */
-    void allow_notify () const;
+    /** Allow queueing a notification after a sleepTime */
+    void allow_notify (int sleepTimeMS = 0) const;
 
     /** Send a notification and start publishing accordingly */
     void notify (const char *mbox) const;
@@ -88,9 +101,20 @@ public:
     /** Update or insert a state in the static maps. */
     void update_state (const std::string &mbox, WKSState state) const;
 
-    /** Create / Build Mail */
-    void send_mail (const std::string &mimeData) const;
+    /** Create / Build / Send Mail
+      returns 0 on success.
+    */
+    int send_mail (const std::string &mimeData) const;
+
+    /** Handle a confirmation mail read event */
+    void handle_confirmation_read (Mail *mail, LPSTREAM msgstream) const;
+
+    /** Handle the notifcation following the read. */
+    void handle_confirmation_notify (const std::string &mbox) const;
 
+    /** Get the cached confirmation data. Caller takes ownership of
+      the data object and has to delete it. It is removed from the cache. */
+    std::pair <GpgME::Data *, Mail *> get_cached_confirmation (const std::string &mbox) const;
 private:
     time_t get_check_time (const std::string &mbox) const;
 

-----------------------------------------------------------------------

Summary of changes:
 src/common_indep.h |   3 +-
 src/mail.cpp       |  25 ++++-
 src/mapihelp.cpp   |  37 ++++++-
 src/mapihelp.h     |   2 +
 src/message.cpp    |   4 +
 src/wks-helper.cpp | 301 ++++++++++++++++++++++++++++++++++++++++++++++-------
 src/wks-helper.h   |  32 +++++-
 7 files changed, 359 insertions(+), 45 deletions(-)


hooks/post-receive
-- 
GnuPG extension for MS Outlook
http://git.gnupg.org




More information about the Gnupg-commits mailing list