From 40c418c59ee895fd61e4c50293816d7c99d3a43b Mon Sep 17 00:00:00 2001
From: Joseph Naegele <jnaegele@grierforensics.com>
Date: Mon, 13 Mar 2017 16:53:26 -0400
Subject: [PATCH] Add optional, automatic S/MIME encryption

---
 imp/config/prefs.php |  7 +++++++
 imp/lib/Compose.php  | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/imp/config/prefs.php b/imp/config/prefs.php
index 8debcd0..32ba8dc 100644
--- a/imp/config/prefs.php
+++ b/imp/config/prefs.php
@@ -438,6 +438,13 @@ $_prefs['smime_verify'] = array(
     'requires' => array('use_smime')
 );
 
+$_prefs['smime_automatic'] = array(
+    'value' => 0,
+    'type' => 'checkbox',
+    'desc' => _("Should S/MIME encryption be performed opportunistically?"),
+    'requires' => array('use_smime')
+);
+
 // S/MIME public keys management widget
 $_prefs['smimepublickey'] = array(
     'type' => 'special',
diff --git a/imp/lib/Compose.php b/imp/lib/Compose.php
index 7c4540d..d7d609d 100644
--- a/imp/lib/Compose.php
+++ b/imp/lib/Compose.php
@@ -1013,6 +1013,52 @@ class IMP_Compose implements ArrayAccess, Countable, IteratorAggregate
             break;
         }
 
+        /* Attempt to enable S/MIME encrypted if configured to automatically do so */
+        if (IMP_Smime::enabled() && $prefs->getValue('smime_automatic') &&
+            !in_array($encrypt, array(IMP_Smime::ENCRYPT, IMP_Smime::SIGNENC))) {
+
+            $imp_smime = $injector->getInstance('IMP_Smime');
+            $missing = array();
+            foreach ($recip['list'] as $addr) {
+                try {
+                    $key = $imp_smime->getPublicKey($addr->bare_address);
+                    if (is_null($key)) {
+                        $missing[] = $addr->bare_address;
+                    }
+                } catch (Horde_Exception $e) {
+                    $missing[] = $addr->bare_address;
+                }
+            }
+
+            if (empty($missing)) {
+                /* Mark message to be encrypted for all recipients */
+                if ($encrypt == IMP_Smime::SIGN) {
+                    $encrypt = IMP_Smime::SIGNENC;
+                } else {
+                    $encrypt = IMP_Smime::ENCRYPT;
+                }
+            } else {
+                /* Warn user of missing public keys (if not already warned) */
+                $prev_missing = $this->getMetadata('automatic_encryption_check');
+                if (!is_array($prev_missing)) {
+                    $prev_missing = array();
+                }
+                $this->_setMetadata('automatic_encryption_check', $missing);
+
+                $new_missing = array_diff($missing, $prev_missing);
+                if (!empty($new_missing)) {
+                    /* Notify user of all recipients for which keys are missing */
+                    throw IMP_Compose_Exception::createAndLog(
+                        'DEBUG',
+                        sprintf(
+                            _("Unable to encrypt message! Public keys missing for the following recipients: %s. (This check will not be performed again for these recipients.)"),
+                            implode(', ', $missing)
+                        )
+                    );
+                }
+            }
+        }
+
         switch ($encrypt) {
         case IMP_Pgp::ENCRYPT:
         case IMP_Pgp::SIGN:
-- 
2.10.1 (Apple Git-78)