From 68e4030fe50e5bbfff5a26bd9bdc6ba2cd05cb8d Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Wed, 4 Jul 2018 15:41:43 +0200 Subject: [PATCH] * Mail: fix some smime signed messages get recognized wrongly as encrypted --- api/src/Mail.php | 7 ++--- api/src/Mail/Smime.php | 48 ++++++++++++++++++++++++++++++---- mail/inc/class.mail_ui.inc.php | 14 +++------- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/api/src/Mail.php b/api/src/Mail.php index 6be8c6f2b7..98cb04b41c 100644 --- a/api/src/Mail.php +++ b/api/src/Mail.php @@ -1765,6 +1765,7 @@ class Mail $retValue['header'][$sortOrder[$uid]]['uid'] = $headerObject['UID']; $retValue['header'][$sortOrder[$uid]]['bodypreview'] = $headerObject['BODYPREVIEW']; $retValue['header'][$sortOrder[$uid]]['priority'] = ($headerObject['PRIORITY']?$headerObject['PRIORITY']:3); + $retValue['header'][$sortOrder[$uid]]['smimeType'] = Mail\Smime::getSmimeType($mailStructureObject); //error_log(__METHOD__.' ('.__LINE__.') '.' '.array2string($retValue['header'][$sortOrder[$uid]])); if (isset($headerObject['DISPOSITION-NOTIFICATION-TO'])) $retValue['header'][$sortOrder[$uid]]['disposition-notification-to'] = $headerObject['DISPOSITION-NOTIFICATION-TO']; if (is_array($headerObject['FLAGS'])) { @@ -5648,7 +5649,7 @@ class Mail if (is_object($mail)) { $structure = $mail->getStructure(); - $isSmime = Mail\Smime::isSmime(($mimeType = $structure->getType())) || Mail\Smime::isSmimeSignatureOnly(($protocol=$structure->getContentTypeParameter('protocol'))); + $isSmime = Mail\Smime::isSmime(($mimeType = $structure->getType())) || Mail\Smime::isSmime(($protocol=$structure->getContentTypeParameter('protocol'))); if ($isSmime) { return $this->resolveSmimeMessage($structure, array( @@ -5966,7 +5967,7 @@ class Mail { $mailStructureObject = $_headerObject->getStructure(); if (Mail\Smime::isSmime(($mimeType = $mailStructureObject->getType())) || - Mail\Smime::isSmimeSignatureOnly(($protocol=$mailStructureObject->getContentTypeParameter('protocol')))) + Mail\Smime::isSmime(($protocol=$mailStructureObject->getContentTypeParameter('protocol')))) { $mailStructureObject = $this->resolveSmimeMessage($mailStructureObject, array( 'uid' => $_uid, @@ -7457,7 +7458,7 @@ class Mail ); $this->smime = new Mail\Smime; $message = $this->getMessageRawBody($params['uid'], null, $params['mailbox']); - if (!Mail\Smime::isSmimeSignatureOnly($params['mimeType'])) + if (!Mail\Smime::isSmimeSignatureOnly(Mail\Smime::getSmimeType($_mime_part))) { try{ $message = $this->_decryptSmimeBody($message, $params['passphrase'] !='' ? diff --git a/api/src/Mail/Smime.php b/api/src/Mail/Smime.php index 85091f13cc..1f677e3a65 100644 --- a/api/src/Mail/Smime.php +++ b/api/src/Mail/Smime.php @@ -83,6 +83,21 @@ class Smime extends Horde_Crypt_Smime */ const TYPE_SIGN_ENCRYPT = 'smime_sign_encrypt'; + /** + * Smime content type of signed message + * + * @var string + */ + const SMIME_TYPE_SIGNED_DATA = 'signed-data'; + + /** + * Smime content type of encrypted message + * + * @var string + */ + const SMIME_TYPE_ENVELOPED_DATA = 'enveleoped-data'; + + /** * Constructor. * @@ -106,15 +121,38 @@ class Smime extends Horde_Crypt_Smime } /** - * Check if a given mime type is smime type of signature only + * Check if a given smime type is smime type of signature only * - * @param string $_mime mimetype + * @param string $_smimeType smime type + * @param string $_mimeType mime type, it takes into account only if smimeType is not found * - * @return type + * @return boolean return whether given type is smime signature or not */ - public static function isSmimeSignatureOnly ($_mime) + public static function isSmimeSignatureOnly ($_smimeType) { - return in_array($_mime, self::$SMIME_SIGNATURE_ONLY_TYPES); + return $_smimeType == self::SMIME_TYPE_SIGNED_DATA ? true : false; + } + + /** + * Extract smime type form mime part + * @param Horde_Mime_Part $_mime_part + * + * @return string return smime type or null if not found + */ + public static function getSmimeType (Horde_Mime_Part $_mime_part) + { + if (($type = $_mime_part->getContentTypeParameter('smime-type'))) { + return strtolower($type); + } + // + $protocol = $_mime_part->getContentTypeParameter('protocol'); + switch ($_mime_part->getType()) + { + case "multipart/signed": + return self::isSmime($protocol) ? self::SMIME_TYPE_SIGNED_DATA : null; + } + + return null; } /** diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php index e4f7335a6e..9e6f365439 100644 --- a/mail/inc/class.mail_ui.inc.php +++ b/mail/inc/class.mail_ui.inc.php @@ -1847,16 +1847,10 @@ $filter['before']= date("d-M-Y", $cutoffdate2); $data['uid'] = $message_uid; $data['row_id']=$this->createRowID($_folderName,$message_uid); - if (is_array($header['attachments'])) + if ($header['smimeType']) { - foreach ($header['attachments'] as $attch) - { - if (Mail\Smime::isSmime($attch['mimeType'])) - { - $data['smime'] = Mail\Smime::isSmimeSignatureOnly($attch['mimeType'])? - Mail\Smime::TYPE_SIGN : Mail\Smime::TYPE_ENCRYPT; - } - } + $data['smime'] = Mail\Smime::isSmimeSignatureOnly($header['smimeType'])? + Mail\Smime::TYPE_SIGN : Mail\Smime::TYPE_ENCRYPT; } $flags = ""; @@ -5447,4 +5441,4 @@ $filter['before']= date("d-M-Y", $cutoffdate2); $response->data($res); } } -} \ No newline at end of file +}