From 2965a981b7ec22866fbdf2d567d87e2d068d3617 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Fri, 31 Jul 2015 16:04:08 -0400
Subject: [PATCH] Allow to search and import missing PGP pubkeys from keyservers using Publickey.js
---
plugins/enigma/lib/enigma_engine.php | 99 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 68 insertions(+), 31 deletions(-)
diff --git a/plugins/enigma/lib/enigma_engine.php b/plugins/enigma/lib/enigma_engine.php
index fd25944..0111d93 100644
--- a/plugins/enigma/lib/enigma_engine.php
+++ b/plugins/enigma/lib/enigma_engine.php
@@ -26,12 +26,12 @@
private $enigma;
private $pgp_driver;
private $smime_driver;
+ private $password_time;
- public $decryptions = array();
- public $signatures = array();
- public $signed_parts = array();
-
- const PASSWORD_TIME = 120;
+ public $decryptions = array();
+ public $signatures = array();
+ public $signed_parts = array();
+ public $encrypted_parts = array();
const SIGN_MODE_BODY = 1;
const SIGN_MODE_SEPARATE = 2;
@@ -49,8 +49,12 @@
$this->rc = rcmail::get_instance();
$this->enigma = $enigma;
+ $this->password_time = $this->rc->config->get('enigma_password_time');
+
// this will remove passwords from session after some time
- $this->get_passwords();
+ if ($this->password_time) {
+ $this->get_passwords();
+ }
}
/**
@@ -329,6 +333,8 @@
{
// encrypted attachment, see parse_plain_encrypted()
if ($p['part']->need_decryption && $p['part']->body === null) {
+ $this->load_pgp_driver();
+
$storage = $this->rc->get_storage();
$body = $storage->get_message_part($p['object']->uid, $p['part']->mime_id, $p['part'], null, null, true, 0, false);
$result = $this->pgp_decrypt($body);
@@ -354,7 +360,7 @@
$part = $p['structure'];
// exit, if we're already inside a decrypted message
- if ($part->encrypted) {
+ if (in_array($part->mime_id, $this->encrypted_parts)) {
return;
}
@@ -441,7 +447,9 @@
// Verify signature
if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
- $sig = $this->pgp_verify($body);
+ if ($this->rc->config->get('enigma_signatures', true)) {
+ $sig = $this->pgp_verify($body);
+ }
}
// @TODO: Handle big bodies using (temp) files
@@ -491,6 +499,10 @@
*/
private function parse_pgp_signed(&$p)
{
+ if (!$this->rc->config->get('enigma_signatures', true)) {
+ return;
+ }
+
// Verify signature
if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
$this->load_pgp_driver();
@@ -519,9 +531,6 @@
else {
$this->signed_parts[$msg_part->mime_id] = $struct->mime_id;
}
-
- // Remove signature file from attachments list (?)
- unset($struct->parts[1]);
}
}
@@ -534,6 +543,10 @@
private function parse_smime_signed(&$p)
{
return; // @TODO
+
+ if (!$this->rc->config->get('enigma_signatures', true)) {
+ return;
+ }
// Verify signature
if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
@@ -556,9 +569,6 @@
else {
$this->signed_parts[$msg_part->mime_id] = $struct->mime_id;
}
-
- // Remove signature file from attachments list
- unset($struct->parts[1]);
}
}
@@ -570,6 +580,10 @@
*/
private function parse_plain_encrypted(&$p, $body)
{
+ if (!$this->rc->config->get('enigma_decryption', true)) {
+ return;
+ }
+
$this->load_pgp_driver();
$part = $p['structure'];
@@ -579,11 +593,23 @@
// Store decryption status
$this->decryptions[$part->mime_id] = $result;
+ // find parent part ID
+ if (strpos($part->mime_id, '.')) {
+ $items = explode('.', $part->mime_id);
+ array_pop($items);
+ $parent = implode('.', $items);
+ }
+ else {
+ $parent = 0;
+ }
+
// Parse decrypted message
if ($result === true) {
$part->body = $body;
$part->body_modified = true;
- $part->encrypted = true;
+
+ // Remember it was decrypted
+ $this->encrypted_parts[] = $part->mime_id;
// PGP signed inside? verify signature
if (preg_match('/^-----BEGIN PGP SIGNED MESSAGE-----/', $body)) {
@@ -591,19 +617,9 @@
}
// Encrypted plain message may contain encrypted attachments
- // in such case attachments have .pgp extension and application/octet-stream.
+ // in such case attachments have .pgp extension and type application/octet-stream.
// This is what happens when you select "Encrypt each attachment separately
// and send the message using inline PGP" in Thunderbird's Enigmail.
-
- // find parent part ID
- if (strpos($part->mime_id, '.')) {
- $items = explode('.', $part->mime_id);
- array_pop($items);
- $parent = implode('.', $items);
- }
- else {
- $parent = 0;
- }
if ($p['object']->mime_parts[$parent]) {
foreach ((array)$p['object']->mime_parts[$parent]->parts as $p) {
@@ -620,6 +636,19 @@
}
}
}
+ // decryption failed, but the message may have already
+ // been cached with the modified parts (see above),
+ // let's bring the original state back
+ else if ($p['object']->mime_parts[$parent]) {
+ foreach ((array)$p['object']->mime_parts[$parent]->parts as $p) {
+ if ($p->need_decryption && !preg_match('/^(.*)\.pgp$/i', $p->filename, $m)) {
+ // modify filename
+ $p->filename .= '.pgp';
+ // flag the part, it will be decrypted when needed
+ unset($p->need_decryption);
+ }
+ }
+ }
}
/**
@@ -629,6 +658,10 @@
*/
private function parse_pgp_encrypted(&$p)
{
+ if (!$this->rc->config->get('enigma_decryption', true)) {
+ return;
+ }
+
$this->load_pgp_driver();
$struct = $p['structure'];
@@ -669,6 +702,10 @@
*/
private function parse_smime_encrypted(&$p)
{
+ if (!$this->rc->config->get('enigma_decryption', true)) {
+ return;
+ }
+
// $this->load_smime_driver();
}
@@ -969,12 +1006,12 @@
$config = @unserialize($config);
}
- $threshold = time() - self::PASSWORD_TIME;
+ $threshold = time() - $this->password_time;
$keys = array();
// delete expired passwords
foreach ((array) $config as $key => $value) {
- if ($value[1] < $threshold) {
+ if ($pass_time && $value[1] < $threshold) {
unset($config[$key]);
$modified = true;
}
@@ -1066,14 +1103,14 @@
$part->body_modified = true;
$part->encoding = 'stream';
- // Cache the fact it was decrypted
- $part->encrypted = true;
-
// modify part identifier
if ($old_id) {
$part->mime_id = !$part->mime_id ? $old_id : ($old_id . '.' . $part->mime_id);
}
+ // Cache the fact it was decrypted
+ $this->encrypted_parts[] = $part->mime_id;
+
$msg->mime_parts[$part->mime_id] = $part;
// modify sub-parts
--
Gitblit v1.9.1