Handle autoimport for attached pgp keys master
authorAndre Heinecke <aheinecke@gnupg.org>
Mon, 11 Feb 2019 14:48:05 +0000 (15:48 +0100)
committerAndre Heinecke <aheinecke@gnupg.org>
Mon, 11 Feb 2019 14:48:05 +0000 (15:48 +0100)
* src/keycache.cpp (KeyCache::import_pgp_key_data): New.
* src/keycache.h: Update accordingly.
* src/parsecontroller.cpp (ParseController::parse): Check for
pgp-keys attachments and import them.

src/keycache.cpp
src/keycache.h
src/parsecontroller.cpp

index 81580ae..9d6f5d2 100644 (file)
@@ -1423,3 +1423,54 @@ KeyCache::getUltimateKeys ()
   gpgrt_lock_unlock (&fpr_map_lock);
   return ret;
 }
+
+/* static */
+bool
+KeyCache::import_pgp_key_data (const GpgME::Data &data)
+{
+  TSTART;
+  if (data.isNull())
+    {
+      STRANGEPOINT;
+      TRETURN false;
+    }
+  auto ctx = GpgME::Context::create(GpgME::OpenPGP);
+
+  if (!ctx)
+    {
+      STRANGEPOINT;
+      TRETURN false;
+    }
+
+  const auto type = data.type();
+
+  if (type != GpgME::Data::PGPKey)
+    {
+      log_debug ("%s:%s: Data does not look like PGP Keys",
+                 SRCNAME, __func__);
+      TRETURN false;
+    }
+  const auto keys = data.toKeys();
+
+  if (keys.empty())
+    {
+      log_debug ("%s:%s: Data does not contain PGP Keys",
+                 SRCNAME, __func__);
+      TRETURN false;
+    }
+
+  if (opt.enable_debug & DBG_DATA)
+    {
+      std::stringstream ss;
+      for (const auto &key: keys)
+        {
+          ss << key << '\n';
+        }
+      log_debug ("Importing keys: %s", ss.str().c_str());
+    }
+  const auto result = ctx->importKeys(keys);
+
+  log_debug ("%s:%s: Import result from attached key err: %s",
+             SRCNAME, __func__, result.error ().asString ());
+  TRETURN !result.error();
+}
index 0a90575..0563e24 100644 (file)
@@ -32,6 +32,7 @@
 namespace GpgME
 {
   class Key;
+  class Data;
 };
 
 class Mail;
@@ -130,6 +131,10 @@ public:
     /* Get a vector of ultimately trusted keys. */
     std::vector<GpgME::Key> getUltimateKeys ();
 
+    /* Import PGP Keys from a Data object. Returns
+       true on success. */
+    static bool import_pgp_key_data(const GpgME::Data &data);
+
     // Internal for thread
     void setSmimeKey(const std::string &mbox, const GpgME::Key &key);
     void setPgpKey(const std::string &mbox, const GpgME::Key &key);
index 4a72a65..309e587 100644 (file)
@@ -546,6 +546,20 @@ ParseController::parse()
       m_block_html = true;
     }
 
+  /* Import any application/pgp-keys attachments if the option is set. */
+  if (opt.autoimport)
+    {
+      for (const auto &attach: get_attachments())
+        {
+          if (attach->get_content_type () == "application/pgp-keys")
+            {
+#ifndef BUILD_TESTS
+              KeyCache::import_pgp_key_data (attach->get_data());
+#endif
+            }
+        }
+    }
+
   if (opt.enable_debug & DBG_DATA)
     {
       std::stringstream ss;