[git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-20-g65599bb

by Andre Heinecke cvs at cvs.gnupg.org
Wed Feb 14 07:54:45 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  65599bb918388d537c29a3d29b4263497eb261de (commit)
       via  cd5db6bf72dd3318d06a4861070ecdf2effec1a7 (commit)
       via  c7b17baec73ee5191ee7a98c9e884e70bea3621d (commit)
      from  77208c29861a06b70a8f4464e3255f0818ba96b0 (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 65599bb918388d537c29a3d29b4263497eb261de
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Feb 14 07:51:45 2018 +0100

    Fix state machine for PGP/Inline mails
    
    * src/mail.cpp, src/mail.h (Mail::WantsSendMIME)
    (Mail::WantsSendInline): More explicit states.
    (Mail::update_crypt_oom): Switch into Inline send for inline
    body.
    (Mail::update_crypt_mapi): Switch into WantsSendMime.
    * src/mailitem-events.cpp (EVENT_SINK_INVOKE): Pass inline mails
    directly.

diff --git a/src/mail.cpp b/src/mail.cpp
index 8f209a8..c5e6946 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -2574,7 +2574,7 @@ Mail::update_crypt_mapi()
     }
   else
     {
-      m_crypt_state = WantsSend;
+      m_crypt_state = WantsSendMIME;
     }
   // We don't need the crypter anymore.
   m_crypter = nullptr;
@@ -2605,7 +2605,7 @@ Mail::update_crypt_oom()
     {
       log_debug ("%s:%s: Looks like inline body. You can pass %p.",
                  SRCNAME, __func__, this);
-      m_crypt_state = NeedsSecondAfterWrite;
+      m_crypt_state = WantsSendInline;
       return;
     }
 
diff --git a/src/mail.h b/src/mail.h
index a0c6c65..08450d9 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -56,7 +56,8 @@ public:
       NeedsUpdateInOOM,
       NeedsSecondAfterWrite,
       NeedsUpdateInMAPI,
-      WantsSend
+      WantsSendInline,
+      WantsSendMIME,
     };
 
   /** @brief Construct a mail object for the item.
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 34999e9..dc667be 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -383,12 +383,19 @@ EVENT_SINK_INVOKE(MailItemEvents)
                     }
                   if (m_mail->crypt_state () == Mail::NeedsSecondAfterWrite)
                     {
-                      m_mail->set_crypt_state (Mail::WantsSend);
+                      m_mail->set_crypt_state (Mail::WantsSendMIME);
                     }
                 }
             }
 
-          if (m_mail->crypt_state () == Mail::WantsSend)
+          if (m_mail->crypt_state () == Mail::WantsSendInline)
+            {
+              log_debug ("%s:%s: Passing send event for no-mime message %p.",
+                         SRCNAME, __func__, m_object);
+              break;
+            }
+
+          if (m_mail->crypt_state () == Mail::WantsSendMIME)
             {
               /* Now we adress T3656 if Outlooks internal S/MIME is somehow
                * mixed in (even if it is enabled and then disabled) it might
@@ -419,8 +426,8 @@ EVENT_SINK_INVOKE(MailItemEvents)
               if (propval->Value.lpszA && !strstr (propval->Value.lpszA, "GpgOL"))
                 {
                   // Does not have a message class by us.
-                  log_debug ("%s:%s: Message %p - No GpgOL Message class after encryption.",
-                             SRCNAME, __func__, m_object);
+                  log_debug ("%s:%s: Message %p - No GpgOL Message class after encryption. cls is: '%s'",
+                             SRCNAME, __func__, m_object, propval->Value.lpszA);
                   log_debug ("%s:%s: Message %p - Activating T3656 Workaround",
                              SRCNAME, __func__, m_object);
                   message = get_oom_base_message (m_object);

commit cd5db6bf72dd3318d06a4861070ecdf2effec1a7
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Feb 14 07:48:11 2018 +0100

    Implement key parsing in cryptcontroller
    
    * src/cryptcontroller.cpp (release_recipient_array): Renamed.
    (rtrim): New helper.
    (CryptController::lookup_fingerprints): New. Resolve keys from
    fingerprints.
    (CryptController::parse_keys): Renamed to parse_output.
    * src/cryptcontroller.h: Update accordingly.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index 0ccaacf..9f6cdbf 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -156,7 +156,7 @@ CryptController::collect_data ()
 }
 
 static void
-release_recipient_array (char **recipients)
+release_carray (char **recipients)
 {
   int idx;
 
@@ -168,20 +168,85 @@ release_recipient_array (char **recipients)
     }
 }
 
+static inline void
+rtrim(std::string &s) {
+    s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
+        return !std::isspace(ch);
+    }).base(), s.end());
+}
+
 int
-CryptController::parse_keys (GpgME::Data &resolverOutput)
+CryptController::lookup_fingerprints (const std::string &sigFpr,
+                                      const std::vector<std::string> recpFprs,
+                                      GpgME::Protocol proto)
+{
+  auto ctx = std::shared_ptr<GpgME::Context> (GpgME::Context::createForProtocol (proto));
+
+  ctx->setKeyListMode (GpgME::Local);
+  GpgME::Error err;
+
+  if (!sigFpr.empty()) {
+      m_signer_key = ctx->key (sigFpr.c_str (), err, true);
+      if (err || m_signer_key.isNull () ) {
+          log_error ("%s:%s: failed to lookup key for '%s'",
+                     SRCNAME, __func__, sigFpr.c_str ());
+          return -1;
+      }
+      // reset context
+      ctx = std::shared_ptr<GpgME::Context> (GpgME::Context::createForProtocol (proto));
+      ctx->setKeyListMode (GpgME::Local);
+  }
+
+  if (!recpFprs.size()) {
+      return 0;
+  }
+
+  // Convert recipient fingerprints
+  char **cRecps = (char**) xmalloc (sizeof (char*) * (recpFprs.size() + 1));
+  for (size_t i = 0; i < recpFprs.size(); i++)
+    {
+      cRecps[i] = strdup (recpFprs[i].c_str());
+    }
+  cRecps[recpFprs.size()] = NULL;
+
+  err = ctx->startKeyListing (const_cast<const char **> (cRecps));
+
+  if (err) {
+      log_error ("%s:%s: failed to start recipient keylisting",
+                 SRCNAME, __func__);
+      return -1;
+  }
+
+  do {
+      m_recipients.push_back(ctx->nextKey(err));
+  } while (!err);
+
+  m_recipients.pop_back();
+
+  release_carray (cRecps);
+
+  return 0;
+}
+
+
+int
+CryptController::parse_output (GpgME::Data &resolverOutput)
 {
   // Todo: Use Data::toString
   std::istringstream ss(resolverOutput.toString());
   std::string line;
 
+  GpgME::Protocol proto = GpgME::UnknownProtocol;
+
+  std::string sigFpr;
+  std::vector<std::string> recpFprs;
   while (std::getline (ss, line))
     {
       if (line == "cancel")
         {
           log_debug ("%s:%s: resolver canceled",
                      SRCNAME, __func__);
-          return -1;
+          return -2;
         }
       if (line == "unencrypted")
         {
@@ -196,13 +261,49 @@ CryptController::parse_keys (GpgME::Data &resolverOutput)
       std::string how;
       std::string fingerprint;
 
-      lss >> what;
-      lss >> how;
-      lss >> fingerprint;
+      std::getline (lss, what, ':');
+      std::getline (lss, how, ':');
+      std::getline (lss, fingerprint, ':');
 
-      log_debug ("Data what: %s how: %s fingerprint: %s", what.c_str (), how.c_str (), fingerprint.c_str ());
+      // Remove possible trailing newline / cr
+      rtrim (fingerprint);
+
+      if (proto == GpgME::UnknownProtocol)
+        {
+          proto = (how == "smime") ? GpgME::CMS : GpgME::OpenPGP;
+        }
+
+      if (what == "sig")
+        {
+          if (!sigFpr.empty ())
+            {
+              log_error ("%s:%s: multiple signing keys not supported",
+                         SRCNAME, __func__);
+
+            }
+          sigFpr = fingerprint;
+          continue;
+        }
+      if (what == "enc")
+        {
+          recpFprs.push_back (fingerprint);
+        }
     }
-  return -1;
+
+  if (m_sign && sigFpr.empty())
+    {
+      log_error ("%s:%s: Sign requested but no signing fingerprint",
+                 SRCNAME, __func__);
+      return -1;
+    }
+  if (m_encrypt && !recpFprs.size())
+    {
+      log_error ("%s:%s: Encrypt requested but no recipient fingerprints",
+                 SRCNAME, __func__);
+      return -1;
+    }
+
+  return lookup_fingerprints (sigFpr, recpFprs, proto);
 }
 
 int
@@ -223,11 +324,27 @@ CryptController::resolve_keys ()
   args.push_back (resolver);
 
   log_debug ("%s:%s: resolving keys with '%s'",
-                 SRCNAME, __func__, resolver.c_str ());
+             SRCNAME, __func__, resolver.c_str ());
 
   // We want debug output as OutputDebugString
   args.push_back (std::string ("--debug"));
 
+  // Pass the handle of the active window for raise / overlay.
+  args.push_back (std::string ("--hwnd"));
+  // Yes passing it as int is ok.
+  args.push_back (std::to_string ((int) m_mail->get_window ()));
+
+  // Set the overlay caption
+  args.push_back (std::string ("--overlayText"));
+  if (m_encrypt)
+    {
+      args.push_back (std::string (_("Resolving recipients...")));
+    }
+  else if (m_sign)
+    {
+      args.push_back (std::string (_("Resolving signers...")));
+    }
+
   if (m_sign)
     {
       args.push_back (std::string ("--sign"));
@@ -261,7 +378,7 @@ CryptController::resolve_keys ()
       args.push_back (GpgME::UserID::addrSpecFromString (recipients[i]));
     }
 
-  release_recipient_array (recipients);
+  release_carray (recipients);
 
   // Convert our collected vector to c strings
   // It's a bit overhead but should be quick for such small
@@ -269,7 +386,7 @@ CryptController::resolve_keys ()
   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[i] = strdup (args[i].c_str());
     }
   cargs[args.size()] = NULL;
 
@@ -279,7 +396,7 @@ CryptController::resolve_keys ()
   if (!ctx)
     {
       // can't happen
-      release_recipient_array (cargs);
+      release_carray (cargs);
       TRACEPOINT;
       return -1;
     }
@@ -305,7 +422,7 @@ CryptController::resolve_keys ()
   log_debug ("Resolver stderr:\n'%s'", mystderr.toString ().c_str ());
 #endif
 
-  release_recipient_array (cargs);
+  release_carray (cargs);
 
   if (err)
     {
@@ -313,7 +430,7 @@ CryptController::resolve_keys ()
                  SRCNAME, __func__, err.code(), err.asString());
     }
 
-  if (parse_keys (mystdout))
+  if (parse_output (mystdout))
     {
       log_debug ("%s:%s: Failed to parse / resolve keys.",
                  SRCNAME, __func__);
@@ -579,11 +696,13 @@ create_encrypt_attach (sink_t sink, protocol_t protocol,
 int
 CryptController::update_mail_mapi ()
 {
-  log_debug ("%s:%s:", SRCNAME, __func__);
+  log_debug ("%s:%s", SRCNAME, __func__);
 
   if (m_inline)
     {
       // Nothing to do for inline.
+      log_debug ("%s:%s: Inline mail. No MAPI update.",
+                 SRCNAME, __func__);
       return 0;
     }
 
diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h
index 580d696..416a918 100644
--- a/src/cryptcontroller.h
+++ b/src/cryptcontroller.h
@@ -60,7 +60,10 @@ public:
 
 private:
   int resolve_keys ();
-  int parse_keys (GpgME::Data &resolverOutput);
+  int parse_output (GpgME::Data &resolverOutput);
+  int lookup_fingerprints (const std::string &sigFpr,
+                           const std::vector<std::string> recpFprs,
+                           GpgME::Protocol proto);
 
 private:
   Mail *m_mail;

commit c7b17baec73ee5191ee7a98c9e884e70bea3621d
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Feb 14 07:53:37 2018 +0100

    Add mail window id accessor
    
    * src/mail.h (Mail::get_window): New.
    
    --
    Kind of ugly as the window is only valid for a short
    time but helps in cryptcontroller.

diff --git a/src/mail.h b/src/mail.h
index 80d57f9..a0c6c65 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -410,6 +410,12 @@ public:
   */
   bool check_inline_response ();
 
+  /** Get the window for the mail. Caution! This is only
+    really valid in the time that the window is disabled.
+    Use with care and can be null or invalid.
+  */
+  HWND get_window () { return m_window; }
+
 private:
   void update_categories ();
   void update_body ();

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

Summary of changes:
 src/cryptcontroller.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++-----
 src/cryptcontroller.h   |   5 +-
 src/mail.cpp            |   4 +-
 src/mail.h              |   9 ++-
 src/mailitem-events.cpp |  15 +++--
 5 files changed, 159 insertions(+), 23 deletions(-)


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




More information about the Gnupg-commits mailing list