Enigma: Fix handling of encrypted + signed messages (#1490632)

pull/322/head
Aleksander Machniak 8 years ago
parent c7af660bfc
commit c9e2ab488e

@ -1,6 +1,8 @@
CHANGELOG Roundcube Webmail
===========================
- Enigma: Fix handling of encrypted + signed messages (#1490632)
- Enigma: Fix invalid boundary use in signed messages structure
- Enable use of TLSv1.1 and TLSv1.2 for IMAP (#1490640)
- Save copy of original .htaccess file when using installto.sh script (1490623)
- Fix regression where some message attachments could be missing on edit/forward (#1490608)

@ -367,7 +367,7 @@ class enigma_engine
}
// Get message body from IMAP server
$body = $this->get_part_body($p['object'], $part->mime_id);
$body = $this->get_part_body($p['object'], $part);
// @TODO: big message body could be a file resource
// PGP signed message
@ -520,8 +520,8 @@ class enigma_engine
// Get bodies
// Note: The first part body need to be full part body with headers
// it also cannot be decoded
$msg_body = $this->get_part_body($p['object'], $msg_part->mime_id, true);
$sig_body = $this->get_part_body($p['object'], $sig_part->mime_id);
$msg_body = $this->get_part_body($p['object'], $msg_part, true);
$sig_body = $this->get_part_body($p['object'], $sig_part);
// Verify
$sig = $this->pgp_verify($msg_body, $sig_body);
@ -673,7 +673,7 @@ class enigma_engine
$part = $struct->parts[1];
// Get body
$body = $this->get_part_body($p['object'], $part->mime_id);
$body = $this->get_part_body($p['object'], $part);
// Decrypt
$result = $this->pgp_decrypt($body);
@ -682,6 +682,21 @@ class enigma_engine
// Parse decrypted message
$struct = $this->parse_body($body);
// If there's signed content verify the signature
if ($struct->mimetype == 'multipart/signed') {
// set signed part body
$body = $this->extract_signed_body($body, $struct->ctype_parameters['boundary']);
$struct->parts[0]->enigma_body = $body;
$struct->parts[1]->enigma_body = $struct->parts[1]->body;
$this->part_structure(array(
'object' => $p['object'],
'structure' => $struct,
'mimetype' => $struct->mimetype
));
}
// Modify original message structure
$this->modify_structure($p, $struct);
@ -1102,20 +1117,27 @@ class enigma_engine
/**
* Get message part body.
*
* @param rcube_message Message object
* @param string Message part ID
* @param bool Return raw body with headers
* @param rcube_message Message object
* @param rcube_message_part Message part
* @param bool Return raw body with headers
*/
private function get_part_body($msg, $part_id, $full = false)
private function get_part_body($msg, $part, $full = false)
{
// @TODO: Handle big bodies using file handles
if ($full) {
// $enigma_body is set if this is a part already extracted
// from encrypted message
if ($part->enigma_body) {
$body = $part->enigma_body;
unset($part->enigma_body);
}
else if ($full) {
$storage = $this->rc->get_storage();
$body = $storage->get_raw_headers($msg->uid, $part_id);
$body .= $storage->get_raw_body($msg->uid, null, $part_id);
$body = $storage->get_raw_headers($msg->uid, $part->mime_id);
$body .= $storage->get_raw_body($msg->uid, null, $part->mime_id);
}
else {
$body = $msg->get_part_body($part_id, false);
$body = $msg->get_part_body($part->mime_id, false);
}
return $body;
@ -1191,6 +1213,20 @@ class enigma_engine
}
}
/**
* Extracts body of the multipart/signed part
*/
private function extract_signed_body($body, $boundary)
{
$boundary = '--' . $boundary;
$boundary_len = strlen($boundary) + 2;
$start = strpos($body, $boundary) + $boundary_len;
$end = strpos($body, $boundary, $start);
$body = substr($body, $start, $end - $start - 2);
return $body;
}
/**
* Checks if specified message part is a PGP-key or S/MIME cert data
*

@ -756,15 +756,21 @@ class enigma_ui
return $p;
}
$engine = $this->enigma->engine;
$part_id = $p['part']->mime_id;
$engine = $this->enigma->engine;
$part_id = $p['part']->mime_id;
$parent_id = preg_replace('/\.[0-9]+$/', '', $part_id);
// Decryption status
if (isset($engine->decryptions[$part_id])) {
if (($status = $engine->decryptions[$part_id])
|| ($parent_id !== '' && ($status = $engine->decryptions[$parent_id]))
) {
$attach_scripts = true;
// get decryption status
$status = $engine->decryptions[$part_id];
// show the message only once
unset($engine->decryptions[$part_id]);
if ($parent_id !== '') {
unset($engine->decryptions[$parent_id]);
}
// display status info
$attrib['id'] = 'enigma-message';

@ -176,6 +176,8 @@ class rcube_mime_decode
case 'multipart/alternative':
case 'multipart/related':
case 'multipart/mixed':
case 'multipart/signed':
case 'multipart/encrypted':
if (!isset($content_type['other']['boundary'])) {
return false;
}

Loading…
Cancel
Save