[git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-11-g88118b5

by Andre Heinecke cvs at cvs.gnupg.org
Mon Feb 12 13:02:39 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  88118b5baaff9c7289d27ca55b084e5c1860f8aa (commit)
       via  193d521b1bd7161fa28b86524acaf2e7046dc343 (commit)
      from  26b931937fe139a9acd3240242e154d3789652f5 (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 88118b5baaff9c7289d27ca55b084e5c1860f8aa
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Feb 12 13:01:14 2018 +0100

    Shorter and more careful window disabling
    
    * src/mail.cpp (do_crypt): Ensure window is renabled on error.
    (Mail::encrypt_sign_start): Disable window here.
    * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Don't disable
    window in event.
    
    --
    Leaving Outlooks window disabled for whatever reason is a
    big bug as Outlook then has to be killed.

diff --git a/src/mail.cpp b/src/mail.cpp
index 1734ba8..9013076 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -748,6 +748,7 @@ do_crypt (LPVOID arg)
     {
       log_debug ("%s:%s: invalid state %i",
                  SRCNAME, __func__, mail->crypt_state ());
+      mail->set_window_enabled (true);
       gpgrt_lock_unlock (&dtor_lock);
       return -1;
     }
@@ -762,6 +763,7 @@ do_crypt (LPVOID arg)
       log_error ("%s:%s: no crypter found for mail: %p",
                  SRCNAME, __func__, arg);
       gpgrt_lock_unlock (&parser_lock);
+      mail->set_window_enabled (true);
       return -1;
     }
 
@@ -782,6 +784,7 @@ do_crypt (LPVOID arg)
     {
       log_debug ("%s:%s: crypto failed for: %p with: %i",
                  SRCNAME, __func__, arg, rc);
+      mail->set_crypt_state (Mail::NoCryptMail);
       gpgrt_lock_unlock (&dtor_lock);
       return rc;
     }
@@ -1148,22 +1151,19 @@ Mail::encrypt_sign_start ()
 
   m_do_inline = m_is_gsuite ? true : opt.inline_pgp;
 
-  if (m_crypter)
-    {
-      log_error ("%s:%s: Crypter already exists for mail %p",
-                 SRCNAME, __func__, this);
-      return -1;
-    }
-
   GpgME::Protocol proto = opt.enable_smime ? GpgME::UnknownProtocol: GpgME::OpenPGP;
   m_crypter = std::shared_ptr <CryptController> (new CryptController (this, flags & 1,
                                                                       flags & 2,
                                                                       m_do_inline, proto));
 
+  // Careful from here on we have to check every
+  // error condition with window enabling again.
+  set_window_enabled (false);
   if (m_crypter->collect_data ())
     {
       log_error ("%s:%s: Crypter for mail %p failed to collect data.",
                  SRCNAME, __func__, this);
+      set_window_enabled (true);
       return -1;
     }
 
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index ec38046..34999e9 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -355,7 +355,6 @@ EVENT_SINK_INVOKE(MailItemEvents)
               // First contact with a mail to encrypt update
               // state and oom data.
               m_mail->update_oom_data ();
-              m_mail->set_window_enabled (false);
               m_mail->set_crypt_state (Mail::NeedsFirstAfterWrite);
 
               // Check inline response state before the write.

commit 193d521b1bd7161fa28b86524acaf2e7046dc343
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Feb 12 12:59:45 2018 +0100

    Start impl. new key resolution with resolver
    
    * src/cryptcontroller.cpp (release_recipient_array),
    (CryptController::parse_keys): New helpers.
    (CryptController::resolve_keys): Prepare args and launch resolver.
    * src/mail.cpp, src/mail.h (Mail::get_cached_sender): New helper
    to ensure getting sender without oom or mapi.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index 2d14038..0ccaacf 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -38,6 +38,11 @@
 #else
 # define _(a) a
 #endif
+
+#include <sstream>
+
+#define DEBUG_RESOLVER 1
+
 static int
 sink_data_write (sink_t sink, const void *data, size_t datalen)
 {
@@ -150,25 +155,173 @@ CryptController::collect_data ()
   return 0;
 }
 
+static void
+release_recipient_array (char **recipients)
+{
+  int idx;
+
+  if (recipients)
+    {
+      for (idx=0; recipients[idx]; idx++)
+        xfree (recipients[idx]);
+      xfree (recipients);
+    }
+}
+
+int
+CryptController::parse_keys (GpgME::Data &resolverOutput)
+{
+  // Todo: Use Data::toString
+  std::istringstream ss(resolverOutput.toString());
+  std::string line;
+
+  while (std::getline (ss, line))
+    {
+      if (line == "cancel")
+        {
+          log_debug ("%s:%s: resolver canceled",
+                     SRCNAME, __func__);
+          return -1;
+        }
+      if (line == "unencrypted")
+        {
+          log_debug ("%s:%s: FIXME resolver wants unencrypted",
+                     SRCNAME, __func__);
+          return -1;
+        }
+      std::istringstream lss (line);
+
+      // First is sig or enc
+      std::string what;
+      std::string how;
+      std::string fingerprint;
+
+      lss >> what;
+      lss >> how;
+      lss >> fingerprint;
+
+      log_debug ("Data what: %s how: %s fingerprint: %s", what.c_str (), how.c_str (), fingerprint.c_str ());
+    }
+  return -1;
+}
+
 int
 CryptController::resolve_keys ()
 {
   m_recipients.clear();
 
-  /*XXX Temporary hack part do key resolution here. */
-  GpgME::Error err;
-  auto ctx = std::shared_ptr<GpgME::Context> (GpgME::Context::createForProtocol(GpgME::OpenPGP));
-  const auto key = ctx->key ("EB4C5A5B7AD6C8527F050BAF1ED4F0BC6CFBC912", err, true);
+  std::vector<std::string> args;
+
+  // Collect the arguments
+  char *gpg4win_dir = get_gpg4win_dir ();
+  if (!gpg4win_dir)
+    {
+      TRACEPOINT;
+      return -1;
+    }
+  const auto resolver = std::string (gpg4win_dir) + "\\bin\\resolver.exe";
+  args.push_back (resolver);
+
+  log_debug ("%s:%s: resolving keys with '%s'",
+                 SRCNAME, __func__, resolver.c_str ());
+
+  // We want debug output as OutputDebugString
+  args.push_back (std::string ("--debug"));
+
+  if (m_sign)
+    {
+      args.push_back (std::string ("--sign"));
+    }
+  const auto cached_sender = m_mail->get_cached_sender ();
+  if (cached_sender.empty())
+    {
+      log_error ("%s:%s: resolve keys without sender.",
+                 SRCNAME, __func__);
+    }
+  else
+    {
+      args.push_back (std::string ("--sender"));
+      args.push_back (cached_sender);
+    }
+
+  if (m_encrypt)
+    {
+      args.push_back (std::string ("--encrypt"));
+    }
+
+  if (!opt.autoresolve)
+    {
+      args.push_back (std::string ("--alwaysShow"));
+    }
+
+  // Get the recipients that are cached from OOM
+  char **recipients = m_mail->take_cached_recipients ();
+  for (size_t i = 0; recipients && recipients[i]; i++)
+    {
+      args.push_back (GpgME::UserID::addrSpecFromString (recipients[i]));
+    }
+
+  release_recipient_array (recipients);
+
+  // Convert our collected vector to c strings
+  // It's a bit overhead but should be quick for such small
+  // data.
+  char **cargs = (char**) xmalloc (sizeof (char*) * (args.size() + 1));
+  for (size_t i = 0; i < args.size(); i++)
+    {
+      gpgrt_asprintf (cargs + i, "%s", args[i].c_str());
+    }
+  cargs[args.size()] = NULL;
+
+  // Args are prepared. Spawn the resolver.
+  auto ctx = GpgME::Context::createForEngine (GpgME::SpawnEngine);
+
+  if (!ctx)
+    {
+      // can't happen
+      release_recipient_array (cargs);
+      TRACEPOINT;
+      return -1;
+    }
+
+  GpgME::Data mystdin (GpgME::Data::null), mystdout, mystderr;
+
+#ifdef DEBUG_RESOLVER
+  log_debug ("Spawning args:");
+  for (size_t i = 0; cargs && cargs[i]; i++)
+    {
+      log_debug ("%i: '%s'", i, cargs[i]);
+    }
+#endif
+
+  GpgME::Error err = ctx->spawn (cargs[0], const_cast <const char**> (cargs),
+                                 mystdin, mystdout, mystderr,
+                                 (GpgME::Context::SpawnFlags) (
+                                  GpgME::Context::SpawnAllowSetFg |
+                                  GpgME::Context::SpawnShowWindow));
+
+#ifdef DEBUG_RESOLVER
+  log_debug ("Resolver stdout:\n'%s'", mystdout.toString ().c_str ());
+  log_debug ("Resolver stderr:\n'%s'", mystderr.toString ().c_str ());
+#endif
+
+  release_recipient_array (cargs);
+
+  if (err)
+    {
+      log_debug ("%s:%s: Resolver spawn finished Err code: %i asString: %s",
+                 SRCNAME, __func__, err.code(), err.asString());
+    }
 
-  if (key.isNull())
+  if (parse_keys (mystdout))
     {
-      log_error ("%s:%s: Failure to resolve keys.",
+      log_debug ("%s:%s: Failed to parse / resolve keys.",
                  SRCNAME, __func__);
+      log_debug ("Resolver stdout:\n'%s'", mystdout.toString ().c_str ());
+      log_debug ("Resolver stderr:\n'%s'", mystderr.toString ().c_str ());
       return -1;
     }
 
-  m_recipients.push_back(key);
-  m_signer_key = key;
   return 0;
 }
 
diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h
index 193c8cc..580d696 100644
--- a/src/cryptcontroller.h
+++ b/src/cryptcontroller.h
@@ -60,6 +60,7 @@ public:
 
 private:
   int resolve_keys ();
+  int parse_keys (GpgME::Data &resolverOutput);
 
 private:
   Mail *m_mail;
diff --git a/src/mail.cpp b/src/mail.cpp
index e9000f2..1734ba8 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -1340,6 +1340,12 @@ Mail::get_sender ()
   return m_sender;
 }
 
+std::string
+Mail::get_cached_sender ()
+{
+  return m_sender;
+}
+
 int
 Mail::close_all_mails ()
 {
diff --git a/src/mail.h b/src/mail.h
index ef0f353..80d57f9 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -195,9 +195,16 @@ public:
    * If the sender address has not been set through update_sender this
    * calls update_sender before returning the sender.
    *
-   * @returns A reference to the utf8 sender address. Or NULL. */
+   * @returns A reference to the utf8 sender address. Or an empty string. */
   std::string get_sender ();
 
+  /** @brief get sender SMTP address (UTF-8 encoded).
+   *
+   * Like get_sender but ensures not to touch oom or mapi
+   *
+   * @returns A reference to the utf8 sender address. Or an empty string. */
+  std::string get_cached_sender ();
+
   /** @brief get the subject string (UTF-8 encoded).
     *
     * @returns the subject or an empty string. */

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

Summary of changes:
 src/cryptcontroller.cpp | 169 +++++++++++++++++++++++++++++++++++++++++++++---
 src/cryptcontroller.h   |   1 +
 src/mail.cpp            |  20 ++++--
 src/mail.h              |   9 ++-
 src/mailitem-events.cpp |   1 -
 5 files changed, 183 insertions(+), 17 deletions(-)


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




More information about the Gnupg-commits mailing list