[git] GpgOL - branch, async-enc, updated. gpgol-2.0.6-58-gab5232c

by Andre Heinecke cvs at cvs.gnupg.org
Thu Mar 1 16:17:52 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  ab5232cb52e4265be48c1d4d977aae45ad91f844 (commit)
       via  93b423f9632b7740dbf0a21341898fb3efb48b4a (commit)
      from  3e851bed56cba229a1a6de656c6639ffbc288081 (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 ab5232cb52e4265be48c1d4d977aae45ad91f844
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Mar 1 16:16:09 2018 +0100

    Use keycache to autoresolve
    
    * lots of changes.
    
    --
    The keycache is now used if opt.autoresolve is set to resolve
    the signing / encryption keys without loading the resolver binary.

diff --git a/src/cryptcontroller.cpp b/src/cryptcontroller.cpp
index 8557cc4..a977e79 100644
--- a/src/cryptcontroller.cpp
+++ b/src/cryptcontroller.cpp
@@ -28,6 +28,7 @@
 #include "mimemaker.h"
 #include "wks-helper.h"
 #include "overlay.h"
+#include "keycache.h"
 
 #include <gpgme++/context.h>
 #include <gpgme++/signingresult.h>
@@ -76,12 +77,14 @@ CryptController::CryptController (Mail *mail, bool encrypt, bool sign,
 {
   log_debug ("%s:%s: CryptController ctor for %p encrypt %i sign %i inline %i.",
              SRCNAME, __func__, mail, encrypt, sign, doInline);
+  m_recipient_addrs = mail->take_cached_recipients ();
 }
 
 CryptController::~CryptController()
 {
   log_debug ("%s:%s:%p",
              SRCNAME, __func__, m_mail);
+  release_cArray (m_recipient_addrs);
 }
 
 int
@@ -298,10 +301,65 @@ CryptController::parse_output (GpgME::Data &resolverOutput)
 }
 
 int
+CryptController::resolve_keys_cached()
+{
+  const auto cache = KeyCache::instance();
+
+  bool fallbackToSMIME = false;
+
+  if (m_encrypt)
+    {
+      m_recipients = cache->getEncryptionKeys((const char **)m_recipient_addrs, GpgME::OpenPGP);
+
+      if (m_recipients.empty() && opt.enable_smime)
+        {
+          m_recipients = cache->getEncryptionKeys((const char **)m_recipient_addrs, GpgME::CMS);
+          fallbackToSMIME = true;
+        }
+      if (m_recipients.empty())
+        {
+          log_debug ("%s:%s: Failed to resolve keys through cache",
+                     SRCNAME, __func__);
+          return 1;
+        }
+    }
+
+  if (m_sign)
+    {
+      if (!fallbackToSMIME)
+        {
+          m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (),
+                                               GpgME::OpenPGP);
+        }
+      if (m_signer_key.isNull() && opt.enable_smime)
+        {
+          m_signer_key = cache->getSigningKey (m_mail->get_cached_sender ().c_str (),
+                                               GpgME::CMS);
+        }
+      if (m_signer_key.isNull())
+        {
+          log_debug ("%s:%s: Failed to resolve signer key through cache",
+                     SRCNAME, __func__);
+          m_recipients.clear();
+          return 1;
+        }
+    }
+  return 0;
+}
+
+int
 CryptController::resolve_keys ()
 {
   m_recipients.clear();
 
+  if (opt.autoresolve && !resolve_keys_cached ())
+    {
+      log_debug ("%s:%s: resolved keys through the cache",
+                 SRCNAME, __func__);
+      start_crypto_overlay();
+      return 0;
+    }
+
   std::vector<std::string> args;
 
   // Collect the arguments
@@ -366,13 +424,10 @@ CryptController::resolve_keys ()
     {
       args.push_back (std::string ("--encrypt"));
       // Get the recipients that are cached from OOM
-      char **recipients = m_mail->take_cached_recipients ();
-      for (size_t i = 0; recipients && recipients[i]; i++)
+      for (size_t i = 0; m_recipient_addrs && m_recipient_addrs[i]; i++)
         {
-          args.push_back (GpgME::UserID::addrSpecFromString (recipients[i]));
+          args.push_back (GpgME::UserID::addrSpecFromString (m_recipient_addrs[i]));
         }
-
-      release_cArray (recipients);
     }
 
   args.push_back (std::string ("--lang"));
diff --git a/src/cryptcontroller.h b/src/cryptcontroller.h
index ebcd4e0..9398c5b 100644
--- a/src/cryptcontroller.h
+++ b/src/cryptcontroller.h
@@ -66,6 +66,7 @@ public:
 
 private:
   int resolve_keys ();
+  int resolve_keys_cached ();
   int parse_output (GpgME::Data &resolverOutput);
   int lookup_fingerprints (const std::string &sigFpr,
                            const std::vector<std::string> recpFprs);
@@ -83,6 +84,7 @@ private:
   GpgME::Key m_signer_key;
   std::vector<GpgME::Key> m_recipients;
   std::unique_ptr<Overlay> m_overlay;
+  char **m_recipient_addrs;
 };
 
 #endif
diff --git a/src/keycache.cpp b/src/keycache.cpp
index 3907772..73011aa 100644
--- a/src/keycache.cpp
+++ b/src/keycache.cpp
@@ -50,9 +50,9 @@ public:
     gpgrt_lock_lock (&keycache_lock);
     auto it = m_pgp_key_map.find (sMbox);
 
-    if ( it == m_pgp_key_map.end ())
+    if (it == m_pgp_key_map.end ())
       {
-        m_pgp_key_map.insert (std::pair<std::string, GpgME::Key> (sMbox, GpgME::Key()));
+        m_pgp_key_map.insert (std::pair<std::string, GpgME::Key> (sMbox, key));
       }
     else
       {
@@ -68,9 +68,45 @@ public:
     gpgrt_lock_lock (&keycache_lock);
     auto it = m_smime_key_map.find (sMbox);
 
-    if ( it == m_smime_key_map.end ())
+    if (it == m_smime_key_map.end ())
+      {
+        m_smime_key_map.insert (std::pair<std::string, GpgME::Key> (sMbox, key));
+      }
+    else
+      {
+        it->second = key;
+      }
+    gpgrt_lock_unlock (&keycache_lock);
+  }
+
+  void setPgpKeySecret(const char *mbox, const GpgME::Key &key)
+  {
+    const std::string sMbox(mbox);
+
+    gpgrt_lock_lock (&keycache_lock);
+    auto it = m_pgp_skey_map.find (sMbox);
+
+    if (it == m_pgp_skey_map.end ())
       {
-        m_smime_key_map.insert (std::pair<std::string, GpgME::Key> (sMbox, GpgME::Key()));
+        m_pgp_skey_map.insert (std::pair<std::string, GpgME::Key> (sMbox, key));
+      }
+    else
+      {
+        it->second = key;
+      }
+    gpgrt_lock_unlock (&keycache_lock);
+  }
+
+  void setSmimeKeySecret(const char *mbox, const GpgME::Key &key)
+  {
+    const std::string sMbox(mbox);
+
+    gpgrt_lock_lock (&keycache_lock);
+    auto it = m_smime_skey_map.find (sMbox);
+
+    if (it == m_smime_skey_map.end ())
+      {
+        m_smime_skey_map.insert (std::pair<std::string, GpgME::Key> (sMbox, key));
       }
     else
       {
@@ -116,11 +152,50 @@ public:
     return ret;
   }
 
+  GpgME::Key getSKey (const char *addr, GpgME::Protocol proto)
+  {
+    if (!addr)
+      {
+        return GpgME::Key();
+      }
+    auto mbox = GpgME::UserID::addrSpecFromString (addr);
+
+    if (proto == GpgME::OpenPGP)
+      {
+        gpgrt_lock_lock (&keycache_lock);
+        const auto it = m_pgp_skey_map.find (mbox);
+
+        if (it == m_pgp_skey_map.end ())
+          {
+            gpgrt_lock_unlock (&keycache_lock);
+            return GpgME::Key();
+          }
+        const auto ret = it->second;
+        gpgrt_lock_unlock (&keycache_lock);
+
+        return ret;
+      }
+    gpgrt_lock_lock (&keycache_lock);
+    const auto it = m_smime_skey_map.find (mbox);
+
+    if (it == m_smime_skey_map.end ())
+      {
+        gpgrt_lock_unlock (&keycache_lock);
+        return GpgME::Key();
+      }
+    const auto ret = it->second;
+    gpgrt_lock_unlock (&keycache_lock);
+
+    return ret;
+  }
+
   GpgME::Key getSigningKey (const char *addr, GpgME::Protocol proto)
   {
-    const auto key = getKey (addr, proto);
+    const auto key = getSKey (addr, proto);
     if (key.isNull())
       {
+        log_mime_parser ("%s:%s: secret key for %s is null",
+                   SRCNAME, __func__, addr);
         return key;
       }
     if (!key.canReallySign())
@@ -208,6 +283,8 @@ public:
 
   std::map<std::string, GpgME::Key> m_pgp_key_map;
   std::map<std::string, GpgME::Key> m_smime_key_map;
+  std::map<std::string, GpgME::Key> m_pgp_skey_map;
+  std::map<std::string, GpgME::Key> m_smime_skey_map;
 };
 
 KeyCache::KeyCache():
@@ -256,7 +333,7 @@ do_locate (LPVOID arg)
 
   if (opt.enable_smime)
     {
-      auto ctx = GpgME::Context::createForProtocol (GpgME::OpenPGP);
+      auto ctx = GpgME::Context::createForProtocol (GpgME::CMS);
       if (!ctx)
         {
           TRACEPOINT;
@@ -315,44 +392,155 @@ do_locate (LPVOID arg)
   return 0;
 }
 
-void KeyCache::startLocate (char **recipients) const
+static void
+locate_secret (char *addr, GpgME::Protocol proto)
 {
-  log_debug ("%s:%s start locate",
-             SRCNAME, __func__);
-  if (!recipients)
+  auto ctx = GpgME::Context::createForProtocol (proto);
+  if (!ctx)
     {
       TRACEPOINT;
       return;
     }
-  gpgrt_lock_lock (&keycache_lock);
-  log_debug ("%s:%s locked",
-             SRCNAME, __func__);
+  // We need to validate here to fetch CRL's
+  ctx->setKeyListMode (GpgME::KeyListMode::Local |
+                       GpgME::KeyListMode::Validate);
+  GpgME::Error e = ctx->startKeyListing (addr, true);
+  if (e)
+    {
+      TRACEPOINT;
+      xfree (addr);
+      return;
+    }
 
-  for (int i = 0; recipients[i]; i++)
+  std::vector<GpgME::Key> keys;
+  GpgME::Error err;
+  do
     {
-      log_debug ("%s:%s looking tat %s",
-                 SRCNAME, __func__, recipients[i]);
-      std::string recp = GpgME::UserID::addrSpecFromString (recipients[i]);
-      if (recp.empty ())
+      const auto key = ctx->nextKey(err);
+      if (key.isNull())
         {
           continue;
         }
-      if (d->m_pgp_key_map.find (recp) == d->m_pgp_key_map.end ())
+      if (key.isRevoked() || key.isExpired() ||
+          key.isDisabled() || key.isInvalid())
         {
-          // It's enough to look at the PGP Key map. We marked
-          // searched keys there.
-          d->m_pgp_key_map.insert (std::pair<std::string, GpgME::Key> (recp, GpgME::Key()));
-          log_debug ("%s:%s Creating a locator thread",
-                     SRCNAME, __func__);
-          HANDLE thread = CreateThread (NULL, 0, do_locate,
-                                        (LPVOID) strdup (recp.c_str ()), 0,
-                                        NULL);
-          CloseHandle (thread);
+          log_mime_parser ("%s:%s: Skipping invalid secret key",
+                           SRCNAME, __func__);
+          continue;
         }
+      if (proto == GpgME::OpenPGP)
+        {
+          log_mime_parser ("%s:%s found pgp skey for addr: \"%s\":%s",
+                           SRCNAME, __func__, addr, key.primaryFingerprint());
+          KeyCache::instance()->setPgpKeySecret (addr, key);
+          delete ctx;
+          return;
+        }
+      if (proto == GpgME::CMS)
+        {
+          log_mime_parser ("%s:%s found cms skey for addr: \"%s\":%s",
+                           SRCNAME, __func__, addr, key.primaryFingerprint());
+          KeyCache::instance()->setSmimeKeySecret (addr, key);
+          delete ctx;
+          return;
+        }
+    } while (!err);
+  delete ctx;
+  return;
+}
+
+static DWORD WINAPI
+do_locate_secret (LPVOID arg)
+{
+  char *addr = (char*) arg;
+
+  log_mime_parser ("%s:%s searching secret key for addr: \"%s\"",
+                   SRCNAME, __func__, addr);
+
+  locate_secret (addr, GpgME::OpenPGP);
+  if (opt.enable_smime)
+    {
+      locate_secret (addr, GpgME::CMS);
+    }
+  xfree (addr);
+  log_debug ("%s:%s locator sthread thread done",
+             SRCNAME, __func__);
+  return 0;
+}
+
+void
+KeyCache::startLocate (char **recipients) const
+{
+  if (!recipients)
+    {
+      TRACEPOINT;
+      return;
+    }
+  for (int i = 0; recipients[i]; i++)
+    {
+      startLocate (recipients[i]);
+    }
+}
+
+void
+KeyCache::startLocate (const char *addr) const
+{
+  if (!addr)
+    {
+      TRACEPOINT;
+      return;
+    }
+  std::string recp = GpgME::UserID::addrSpecFromString (addr);
+  if (recp.empty ())
+    {
+      return;
+    }
+  gpgrt_lock_lock (&keycache_lock);
+  if (d->m_pgp_key_map.find (recp) == d->m_pgp_key_map.end ())
+    {
+      // It's enough to look at the PGP Key map. We marked
+      // searched keys there.
+      d->m_pgp_key_map.insert (std::pair<std::string, GpgME::Key> (recp, GpgME::Key()));
+      log_debug ("%s:%s Creating a locator thread",
+                 SRCNAME, __func__);
+      HANDLE thread = CreateThread (NULL, 0, do_locate,
+                                    (LPVOID) strdup (recp.c_str ()), 0,
+                                    NULL);
+      CloseHandle (thread);
+    }
+  gpgrt_lock_unlock (&keycache_lock);
+}
+
+void
+KeyCache::startLocateSecret (const char *addr) const
+{
+  if (!addr)
+    {
+      TRACEPOINT;
+      return;
+    }
+  std::string recp = GpgME::UserID::addrSpecFromString (addr);
+  if (recp.empty ())
+    {
+      return;
+    }
+  gpgrt_lock_lock (&keycache_lock);
+  if (d->m_pgp_skey_map.find (recp) == d->m_pgp_skey_map.end ())
+    {
+      // It's enough to look at the PGP Key map. We marked
+      // searched keys there.
+      d->m_pgp_skey_map.insert (std::pair<std::string, GpgME::Key> (recp, GpgME::Key()));
+      log_debug ("%s:%s Creating a locator thread",
+                 SRCNAME, __func__);
+      HANDLE thread = CreateThread (NULL, 0, do_locate_secret,
+                                    (LPVOID) strdup (recp.c_str ()), 0,
+                                    NULL);
+      CloseHandle (thread);
     }
   gpgrt_lock_unlock (&keycache_lock);
 }
 
+
 void
 KeyCache::setSmimeKey(const char *mbox, const GpgME::Key &key)
 {
@@ -364,3 +552,15 @@ KeyCache::setPgpKey(const char *mbox, const GpgME::Key &key)
 {
   d->setPgpKey(mbox, key);
 }
+
+void
+KeyCache::setSmimeKeySecret(const char *mbox, const GpgME::Key &key)
+{
+  d->setSmimeKeySecret(mbox, key);
+}
+
+void
+KeyCache::setPgpKeySecret(const char *mbox, const GpgME::Key &key)
+{
+  d->setPgpKeySecret(mbox, key);
+}
diff --git a/src/keycache.h b/src/keycache.h
index 7f68fe2..9a3aded 100644
--- a/src/keycache.h
+++ b/src/keycache.h
@@ -44,7 +44,7 @@ public:
     /** Get the KeyCache */
     static KeyCache* instance ();
 
-    /* Try to find a key for signing in the internal
+    /* Try to find a key for signing in the internal secret key
        cache. If no proper key is found a Null key is
        returned.*/
     GpgME::Key getSigningKey (const char *addr, GpgME::Protocol proto) const;
@@ -61,12 +61,21 @@ public:
        of address strings. */
     void startLocate (char **cArray) const;
 
+    /* Look for a secret key for the addr. */
+    void startLocateSecret (const char *addr) const;
+
+    /* Start a key location in a background thread filling
+       the key cache. */
+    void startLocate (const char *addr) const;
 
     // Internal for thread
     void setSmimeKey(const char *mbox, const GpgME::Key &key);
     void setPgpKey(const char *mbox, const GpgME::Key &key);
+    void setSmimeKeySecret(const char *mbox, const GpgME::Key &key);
+    void setPgpKeySecret(const char *mbox, const GpgME::Key &key);
 
 private:
+
     class Private;
     std::shared_ptr<Private> d;
 };
diff --git a/src/mail.cpp b/src/mail.cpp
index 7405328..04dec00 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -2401,10 +2401,13 @@ Mail::get_sig_fpr() const
 }
 
 /** Try to locate the keys for all recipients */
-void Mail::locate_keys()
+void
+Mail::locate_keys()
 {
   char ** recipients = get_recipients ();
   KeyCache::instance()->startLocate (recipients);
+  KeyCache::instance()->startLocate (get_sender ().c_str ());
+  KeyCache::instance()->startLocateSecret (get_sender ().c_str ());
   release_cArray (recipients);
 }
 

commit 93b423f9632b7740dbf0a21341898fb3efb48b4a
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Thu Mar 1 16:10:22 2018 +0100

    Bring mail to front after encryption
    
    * src/overlay.cpp (Overlay::~Overlay): Bring old window to front.
    
    --
    Pinentry brings the wrong window to front. This mitigates that a
    bit.

diff --git a/src/overlay.cpp b/src/overlay.cpp
index 8e088d6..a6ba341 100644
--- a/src/overlay.cpp
+++ b/src/overlay.cpp
@@ -85,4 +85,5 @@ Overlay::~Overlay()
   m_overlayStdin.write (nullptr, 0);
   m_overlayCtx->wait ();
   EnableWindow (m_wid, TRUE);
+  bring_to_front (m_wid);
 }

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

Summary of changes:
 src/cryptcontroller.cpp |  65 +++++++++++-
 src/cryptcontroller.h   |   2 +
 src/keycache.cpp        | 256 ++++++++++++++++++++++++++++++++++++++++++------
 src/keycache.h          |  11 ++-
 src/mail.cpp            |   5 +-
 src/overlay.cpp         |   1 +
 6 files changed, 305 insertions(+), 35 deletions(-)


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




More information about the Gnupg-commits mailing list