Projects
home:sicherha:branches:Kolab:Winterfell
roundcubemail-selfcontained
0001-Enigma-WOAT-Support-8626.patch
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Enigma-WOAT-Support-8626.patch of Package roundcubemail-selfcontained
From 4f25da4f006bbf5bec15a88a08dca68df2bebdbe Mon Sep 17 00:00:00 2001 From: Christian Mollekopf <cmollekopf@gmail.com> Date: Mon, 1 Aug 2022 11:51:32 +0200 Subject: [PATCH 1/6] Enigma: WOAT Support (#8626) * Enigma: WOAT Support * Fixed public key extraction from dns record Co-authored-by: Aleksander Machniak <alec@alec.pl> Co-authored-by: Christian Mollekopf <mollekopf@apheleia-it.ch> --- plugins/enigma/config.inc.php.dist | 5 ++ plugins/enigma/lib/enigma_engine.php | 93 +++++++++++++++++++++++-- plugins/enigma/lib/enigma_subkey.php | 12 +++- program/lib/Roundcube/rcube_message.php | 10 +-- 4 files changed, 108 insertions(+), 12 deletions(-) diff --git a/plugins/enigma/config.inc.php.dist b/plugins/enigma/config.inc.php.dist index a5a5233c2..d654c764d 100644 --- a/plugins/enigma/config.inc.php.dist +++ b/plugins/enigma/config.inc.php.dist @@ -78,3 +78,8 @@ $config['enigma_passwordless'] = false; // - enigma_options_lock = ['sign'] // - dont_override = ['enigma_sign_all'] $config['enigma_options_lock'] = []; + +// Enable Kolab's Web Of Anti-Trust feature +// Fetches public keys from DNS. Default: false +// To enable set it to True or an array of domain names. +$config['enigma_woat'] = false; diff --git a/plugins/enigma/lib/enigma_engine.php b/plugins/enigma/lib/enigma_engine.php index 113030db1..1717d41da 100644 --- a/plugins/enigma/lib/enigma_engine.php +++ b/plugins/enigma/lib/enigma_engine.php @@ -28,6 +28,7 @@ class enigma_engine private $pgp_driver; private $smime_driver; private $password_time; + private $sender; private $cache = []; public $decryptions = []; @@ -272,6 +273,9 @@ class enigma_engine $recipients = array_unique($recipients); + // Fetch keys from external sources, if configured + $this->sync_keys($recipients); + // find recipient public keys foreach ((array) $recipients as $email) { if ($email == $from && $sign_key) { @@ -380,6 +384,17 @@ class enigma_engine return; } + // Get the message/part sender + if (!empty($p['object']->sender) && !empty($p['object']->sender['mailto'])) { + $this->sender = $p['object']->sender['mailto']; + } + if (!empty($p['structure']->headers) && !empty($p['structure']->headers['from'])) { + $from = rcube_mime::decode_address_list($p['structure']->headers['from'], 1, false); + if (($from = current($from)) && !empty($from['mailto'])) { + $this->sender = $from['mailto']; + } + } + // Don't be tempted to support encryption in text/html parts // Because of EFAIL vulnerability we should never support this (#6289) @@ -881,6 +896,11 @@ class enigma_engine { // @TODO: Handle big bodies using (temp) files + // Import sender's key from external sources, if configured + if ($this->sender) { + $this->sync_keys([$this->sender]); + } + // Get rid of possible non-ascii characters (#5962) $sig_body = preg_replace('/[^\x00-\x7F]/', '', $sig_body); @@ -905,6 +925,11 @@ class enigma_engine { // @TODO: Handle big bodies using (temp) files + // Import sender's key from external sources, if configured + if ($this->sender) { + $this->sync_keys([$this->sender]); + } + // Get rid of possible non-ascii characters (#5962) $msg_body = preg_replace('/[^\x00-\x7F]/', '', $msg_body); @@ -1020,19 +1045,25 @@ class enigma_engine return; } - $mode = $can_sign ? enigma_key::CAN_SIGN : enigma_key::CAN_ENCRYPT; - $ret = null; + $mode = $can_sign ? enigma_key::CAN_SIGN : enigma_key::CAN_ENCRYPT; + $found = []; // check key validity and type foreach ($result as $key) { if (($subkey = $key->find_subkey($email, $mode)) && (!$can_sign || $key->get_type() == enigma_key::TYPE_KEYPAIR) ) { - $ret = $key; - break; + $found[$subkey->get_creation_date(true)] = $key; } } + // Use the most recent one + if (count($found) > 1) { + ksort($found, SORT_NUMERIC); + } + + $ret = count($found) > 0 ? array_pop($found) : null; + // cache private key info for better performance // we can skip one list_keys() call when signing and attaching a key if ($can_sign) { @@ -1442,4 +1473,58 @@ class enigma_engine ); } } + + /** + * Import public keys from DNS according to Kolab Web-Of-Anti-Trust + * + * @param array $recipients List of email addresses + */ + protected function sync_keys($recipients) + { + $import = []; + $woat = $this->rc->config->get('enigma_woat'); + + if (empty($woat)) { + return; + } + + foreach ($recipients as $recipient) { + if (!strpos($recipient, '@')) { + continue; + } + + list($local, $domain) = explode('@', $recipient); + + // Do this for configured domains only + if (is_array($woat) && !in_array_nocase($domain, $woat)) { + continue; + } + + // remove parts behind a recipient delimiter ("jeroen+Trash" => "jeroen") + $local = preg_replace('/\+.*$/', '', $local); + + $fqdn = sha1($local) . '._woat.' . $domain; + + // Fetch the TXT record(s) + if (($records = dns_get_record($fqdn, DNS_TXT)) === false) { + continue; + } + + foreach ($records as $record) { + if (strpos($record['txt'], 'v=woat1,') === 0) { + $entry = explode('public_key=', $record['txt']); + if (count($entry) == 2) { + $import[] = $entry[1]; + // For now we support only one key + break; + } + } + } + } + + // Import the fetched keys + if (!empty($import)) { + $this->import_key(implode("\n", $import)); + } + } } diff --git a/plugins/enigma/lib/enigma_subkey.php b/plugins/enigma/lib/enigma_subkey.php index ffdb3e8ce..014ab7de3 100644 --- a/plugins/enigma/lib/enigma_subkey.php +++ b/plugins/enigma/lib/enigma_subkey.php @@ -93,12 +93,18 @@ class enigma_subkey /** * Returns subkey creation date-time string * - * @return string|null + * @param bool $asInt Return the date as an integer + * + * @return string|null|int */ - function get_creation_date() + function get_creation_date($asInt = false) { if (empty($this->created)) { - return null; + return $asInt ? 0 : null; + } + + if ($asInt) { + return (int) $this->created->format('U'); } $date_format = rcube::get_instance()->config->get('date_format', 'Y-m-d'); diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php index e81df1b2f..7a2f7d96a 100644 --- a/program/lib/Roundcube/rcube_message.php +++ b/program/lib/Roundcube/rcube_message.php @@ -126,6 +126,11 @@ class rcube_message ) ]; + $this->mime = new rcube_mime($this->headers->charset); + $this->subject = str_replace("\n", '', $this->headers->get('subject')); + $from = $this->mime->decode_address_list($this->headers->from, 1); + $this->sender = current($from); + if (!empty($this->headers->structure)) { $this->get_mime_numbers($this->headers->structure); $this->parse_structure($this->headers->structure); @@ -134,11 +139,6 @@ class rcube_message $this->body = $this->storage->get_body($uid); } - $this->mime = new rcube_mime($this->headers->charset); - $this->subject = str_replace("\n", '', $this->headers->get('subject')); - $from = $this->mime->decode_address_list($this->headers->from, 1); - $this->sender = current($from); - // notify plugins and let them analyze this structured message object $this->app->plugins->exec_hook('message_load', ['object' => $this]); } -- 2.37.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.