diff --git a/README.md b/README.md index d0a04f0..189b621 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The plugin name to add to your config file is: `tls_icon`. ## Requirements -- Roundcube `1.3.0` or newer. +- Roundcube `1.3.0` or newer (tested up to 1.7). - PHP `5.4` or newer. ## Currently supported languages diff --git a/test/TlsIconTest.php b/test/TlsIconTest.php index b50e545..d8165f0 100644 --- a/test/TlsIconTest.php +++ b/test/TlsIconTest.php @@ -12,514 +12,567 @@ final class TlsIconTest extends TestCase { - /** @var string */ - private $strUnEnCrypted = ''; - - /** @var string */ - private $strCryptedTlsv12 = ''; - - /** @var string */ - private $strCryptedTlsv12WithCipher = ''; - - /** @var string */ - private $strInternal = ''; - - /** @var string */ - private $strSendmailCryptedTlsv13WithCipherNoVerify = ''; - - /** @var string */ - private $strSendmailCryptedTlsv12WithCipherVerify = ''; - - /** @var string */ - private $strStalwartCryptedTlsv13WithCipher = ''; - - /** @var string */ - private $strNewPostfixTLSv13 = ''; - - public function testInstance() - { - $o = new tls_icon(); - $this->assertInstanceOf('tls_icon', $o); - } - - public function testStorage_Init() - { - $o = new tls_icon(); - $this->assertSame([ - 'fetch_headers' => 'RECEIVED' - ], $o->storage_init([])); - $this->assertSame([ - 'fetch_headers' => 'RECEIVED' - ], $o->storage_init(['fetch_headers' => null])); - $this->assertSame([ - 'fetch_headers' => 'foo bar RECEIVED' - ], $o->storage_init(['fetch_headers' => 'foo bar'])); - $this->assertSame([ - 'fetch_headers' => 'spaces RECEIVED' - ], $o->storage_init(['fetch_headers' => 'spaces '])); - } - - public function testMessageHeadersNothing() - { - $o = new tls_icon(); - $this->assertSame([], $o->message_headers([])); - } - - public function testMessageHeadersNoMatching() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'my header', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strUnEnCrypted, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'my header', - ] - ] - ], $headersProcessed); - } - - public function testMessageHeadersTlsWithCipher() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) - by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 - for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strCryptedTlsv12WithCipher, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) - by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 - for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', - ] - ] - ], $headersProcessed); - } - - public function testMessageHeadersTls() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) - (using TLSv1.2) (No client certificate requested) - by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 - for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strCryptedTlsv12, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) - (using TLSv1.2) (No client certificate requested) - by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 - for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', - ] - ] - ], $headersProcessed); - } - - public function testMessageHeadersInternal() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'by aaa.bbb.ccc (Postfix, from userid 0) - id A70248414D5; Sun, 26 Apr 2020 16:49:01 +0200 (CEST)', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strInternal, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'by aaa.bbb.ccc (Postfix, from userid 0) - id A70248414D5; Sun, 26 Apr 2020 16:49:01 +0200 (CEST)', - ] - ] - ], $headersProcessed); - } - - - public function testMessageHeadersInternalLocalhostIPv4() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from mail.whitequark.org (localhost [127.0.0.1]) - by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strInternal, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from mail.whitequark.org (localhost [127.0.0.1]) - by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', - ] - ] - ], $headersProcessed); - } - - public function testMessageHeadersInternalLocalhostIPv6() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from mail.whitequark.org (localhost [IPv6:::1]) - by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strInternal, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from mail.whitequark.org (localhost [IPv6:::1]) - by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', - ] - ] - ], $headersProcessed); - } - - public function testPostfixTLS13NewSyntax() - { - $header = 'from GVXPR05CU001.outbound.protection.outlook.com (mail-swedencentralazon11023139.outbound.protection.outlook.com [52.101.83.139]) + /** @var string */ + private $strUnEnCrypted; + + /** @var string */ + private $strCryptedTlsv12; + + /** @var string */ + private $strCryptedTlsv12WithCipher; + + /** @var string */ + private $strInternal; + + /** @var string */ + private $strSendmailCryptedTlsv13WithCipherNoVerify; + + /** @var string */ + private $strSendmailCryptedTlsv12WithCipherVerify; + + /** @var string */ + private $strStalwartCryptedTlsv13WithCipher; + + /** @var string */ + private $strNewPostfixTLSv13; + + public function __construct($name = null, array $data = [], $dataName = '') + { + parent::__construct($name, $data, $dataName); + $plugin = new tls_icon(); + $this->strUnEnCrypted = ''; + $this->strCryptedTlsv12 = ''; + $this->strCryptedTlsv12WithCipher = ''; + $this->strInternal = ''; + $this->strSendmailCryptedTlsv13WithCipherNoVerify = ''; + $this->strSendmailCryptedTlsv12WithCipherVerify = ''; + $this->strStalwartCryptedTlsv13WithCipher = ''; + $this->strNewPostfixTLSv13 = ''; + } + + public function testInstance() + { + $o = new tls_icon(); + $this->assertInstanceOf('tls_icon', $o); + } + + public function testStorage_Init() + { + $o = new tls_icon(); + $this->assertSame([ + 'fetch_headers' => 'RECEIVED' + ], $o->storage_init([])); + $this->assertSame([ + 'fetch_headers' => 'RECEIVED' + ], $o->storage_init(['fetch_headers' => null])); + $this->assertSame([ + 'fetch_headers' => 'foo bar RECEIVED' + ], $o->storage_init(['fetch_headers' => 'foo bar'])); + $this->assertSame([ + 'fetch_headers' => 'spaces RECEIVED' + ], $o->storage_init(['fetch_headers' => 'spaces '])); + } + + public function testMessageHeadersNothing() + { + $o = new tls_icon(); + $this->assertSame([], $o->message_headers([])); + } + + public function testMessageHeadersNoMatching() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'my header', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strUnEnCrypted, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'my header', + ] + ] + ], $headersProcessed); + } + + public function testMessageHeadersTlsWithCipher() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) + by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 + for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strCryptedTlsv12WithCipher, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) + by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 + for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', + ] + ] + ], $headersProcessed); + } + + public function testMessageHeadersTls() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) + (using TLSv1.2) (No client certificate requested) + by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 + for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strCryptedTlsv12, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from smtp.github.com (out-21.smtp.github.com [192.30.252.204]) + (using TLSv1.2) (No client certificate requested) + by mail.example.org (Postfix) with ESMTPS id 46B4C497C2 + for ; Sat, 9 Jul 2022 14:03:01 +0000 (UTC)', + ] + ] + ], $headersProcessed); + } + + public function testMessageHeadersInternal() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'by aaa.bbb.ccc (Postfix, from userid 0) + id A70248414D5; Sun, 26 Apr 2020 16:49:01 +0200 (CEST)', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strInternal, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'by aaa.bbb.ccc (Postfix, from userid 0) + id A70248414D5; Sun, 26 Apr 2020 16:49:01 +0200 (CEST)', + ] + ] + ], $headersProcessed); + } + + + public function testMessageHeadersInternalLocalhostIPv4() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from mail.whitequark.org (localhost [127.0.0.1]) + by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strInternal, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from mail.whitequark.org (localhost [127.0.0.1]) + by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', + ] + ] + ], $headersProcessed); + } + + public function testMessageHeadersInternalLocalhostIPv6() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from mail.whitequark.org (localhost [IPv6:::1]) + by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strInternal, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from mail.whitequark.org (localhost [IPv6:::1]) + by mail.whitequark.org (Postfix) with ESMTP id CDCA2E08B7', + ] + ] + ], $headersProcessed); + } + + public function testPostfixTLS13NewSyntax() + { + $header = 'from GVXPR05CU001.outbound.protection.outlook.com (mail-swedencentralazon11023139.outbound.protection.outlook.com [52.101.83.139]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (secp384r1) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by example.com with ESMTPS id EXAMPLE for ; Tue, 16 Sep 2025 12:26:17 +0200 (CEST)'; - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => $header, - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strNewPostfixTLSv13, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => $header, - ] - ] - ], $headersProcessed); - } - - - public function testMessageHeadersMultiFromWithConfig() - { - $inputHeaders = [ - 'from mail.example.org by mail.example.org with LMTP id pLzoBVClyGIiVgAA3BZZyA (envelope-from ) for ; Fri, 08 Jul 2022 21:44:48 +0000', - 'from localhost (localhost [127.0.0.1]) by mail.example.org (Postfix) with ESMTP id 0D33249414 for ; Fri, 8 Jul 2022 21:44:48 +0000 (UTC)', - 'from xxxx-ord.mtasv.net (xxxx-ord.mtasv.net [255.255.255.255]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.example.org (Postfix) with ESMTPS id 73C3B461AF for ; Fri, 8 Jul 2022 21:44:39 +0000 (UTC)', - 'by xxxx-ord.mtasv.net id hp2il427tk41 for ; Fri, 8 Jul 2022 17:44:41 -0400 (envelope-from )', - ]; - - $o = new tls_icon(); - $o->init(); - rcmail::get_instance()->config->set('tls_icon_ignore_hops', 2); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => $inputHeaders, - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strCryptedTlsv12WithCipher, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => $inputHeaders, - ] - ] - ], $headersProcessed); - } - - public function testMessageHeadersMultiFromWithBadConfig() - { - $inputHeaders = [ - 'from mail.example.org by mail.example.org with LMTP id pLzoBVClyGIiVgAA3BZZyA (envelope-from ) for ; Fri, 08 Jul 2022 21:44:48 +0000', - 'from internalhost (internalhost [192.168.0.1]) by mail.example.org (Postfix) with ESMTP id 0D33249414 for ; Fri, 8 Jul 2022 21:44:48 +0000 (UTC)', - 'from xxxx-ord.mtasv.net (xxxx-ord.mtasv.net [255.255.255.255]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.example.org (Postfix) with ESMTPS id 73C3B461AF for ; Fri, 8 Jul 2022 21:44:39 +0000 (UTC)', - 'by xxxx-ord.mtasv.net id hp2il427tk41 for ; Fri, 8 Jul 2022 17:44:41 -0400 (envelope-from )', - ]; - - $o = new tls_icon(); - $o->init(); - rcmail::get_instance()->config->set('tls_icon_ignore_hops', 1); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => $inputHeaders, - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strUnEnCrypted, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => $inputHeaders, - ] - ] - ], $headersProcessed); - } - - public function testSendmailTLS13NoVerify() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from 69-171-232-143.mail-mail.facebook.com (69-171-232-143.mail-mail.facebook.com [69.171.232.143]) - by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BI73F8b1489360 - (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO) - for ; Sun, 18 Dec 2022 07:03:16 GMT', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strSendmailCryptedTlsv13WithCipherNoVerify, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from 69-171-232-143.mail-mail.facebook.com (69-171-232-143.mail-mail.facebook.com [69.171.232.143]) - by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BI73F8b1489360 - (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO) - for ; Sun, 18 Dec 2022 07:03:16 GMT', - ] - ] - ], $headersProcessed); - } - - public function testSendmailTLS12WithVerify() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from smtp.github.com (out-18.smtp.github.com [192.30.252.201]) - by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BGMf4uY685293 - (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) - for ; Fri, 16 Dec 2022 22:41:05 GMT', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strSendmailCryptedTlsv12WithCipherVerify, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from smtp.github.com (out-18.smtp.github.com [192.30.252.201]) - by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BGMf4uY685293 - (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) - for ; Fri, 16 Dec 2022 22:41:05 GMT', - ] - ] - ], $headersProcessed); - } - - public function testSendmailTLS13MultipleRecipients() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from mout.kundenserver.de (mout.kundenserver.de [212.227.126.134]) - by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BLGrgYw3602565 - (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); - Wed, 21 Dec 2022 16:53:42 GMT', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strSendmailCryptedTlsv13WithCipherNoVerify, - 'html' => 1, - ], - ], - 'headers' => (object)[ - 'others' => [ - 'received' => 'from mout.kundenserver.de (mout.kundenserver.de [212.227.126.134]) - by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BLGrgYw3602565 - (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); - Wed, 21 Dec 2022 16:53:42 GMT', - ] - ] - ], $headersProcessed); - } - - public function testStalwartTls() - { - $o = new tls_icon(); - $headersProcessed = $o->message_headers([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you', - ], - ], - 'headers' => (object) [ - 'others' => [ - 'received' => 'from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174] (AS15169 Google LLC, US)) - (using TLSv1.3 with cipher TLS13_AES_256_GCM_SHA384) - by mail.example.org (Stalwart SMTP) with ESMTPS id 36DAF29F3A02098; - Mon, 16 Jun 2025 13:33:03 +0000', - ] - ] - ]); - $this->assertEquals([ - 'output' => [ - 'subject' => [ - 'value' => 'Sent to you' . $this->strStalwartCryptedTlsv13WithCipher, - 'html' => 1, - ], - ], - 'headers' => (object) [ - 'others' => [ - 'received' => 'from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174] (AS15169 Google LLC, US)) - (using TLSv1.3 with cipher TLS13_AES_256_GCM_SHA384) - by mail.example.org (Stalwart SMTP) with ESMTPS id 36DAF29F3A02098; - Mon, 16 Jun 2025 13:33:03 +0000', - ] - ] - ], $headersProcessed); - } + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => $header, + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strNewPostfixTLSv13, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => $header, + ] + ] + ], $headersProcessed); + } + + + public function testMessageHeadersMultiFromWithConfig() + { + $inputHeaders = [ + 'from mail.example.org by mail.example.org with LMTP id pLzoBVClyGIiVgAA3BZZyA (envelope-from ) for ; Fri, 08 Jul 2022 21:44:48 +0000', + 'from localhost (localhost [127.0.0.1]) by mail.example.org (Postfix) with ESMTP id 0D33249414 for ; Fri, 8 Jul 2022 21:44:48 +0000 (UTC)', + 'from xxxx-ord.mtasv.net (xxxx-ord.mtasv.net [255.255.255.255]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.example.org (Postfix) with ESMTPS id 73C3B461AF for ; Fri, 8 Jul 2022 21:44:39 +0000 (UTC)', + 'by xxxx-ord.mtasv.net id hp2il427tk41 for ; Fri, 8 Jul 2022 17:44:41 -0400 (envelope-from )', + ]; + + $o = new tls_icon(); + $o->init(); + rcmail::get_instance()->config->set('tls_icon_ignore_hops', 2); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => $inputHeaders, + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strCryptedTlsv12WithCipher, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => $inputHeaders, + ] + ] + ], $headersProcessed); + } + + public function testMessageHeadersMultiFromWithBadConfig() + { + $inputHeaders = [ + 'from mail.example.org by mail.example.org with LMTP id pLzoBVClyGIiVgAA3BZZyA (envelope-from ) for ; Fri, 08 Jul 2022 21:44:48 +0000', + 'from internalhost (internalhost [192.168.0.1]) by mail.example.org (Postfix) with ESMTP id 0D33249414 for ; Fri, 8 Jul 2022 21:44:48 +0000 (UTC)', + 'from xxxx-ord.mtasv.net (xxxx-ord.mtasv.net [255.255.255.255]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.example.org (Postfix) with ESMTPS id 73C3B461AF for ; Fri, 8 Jul 2022 21:44:39 +0000 (UTC)', + 'by xxxx-ord.mtasv.net id hp2il427tk41 for ; Fri, 8 Jul 2022 17:44:41 -0400 (envelope-from )', + ]; + + $o = new tls_icon(); + $o->init(); + rcmail::get_instance()->config->set('tls_icon_ignore_hops', 1); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => $inputHeaders, + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strUnEnCrypted, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => $inputHeaders, + ] + ] + ], $headersProcessed); + } + + public function testSendmailTLS13NoVerify() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from 69-171-232-143.mail-mail.facebook.com (69-171-232-143.mail-mail.facebook.com [69.171.232.143]) + by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BI73F8b1489360 + (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO) + for ; Sun, 18 Dec 2022 07:03:16 GMT', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strSendmailCryptedTlsv13WithCipherNoVerify, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from 69-171-232-143.mail-mail.facebook.com (69-171-232-143.mail-mail.facebook.com [69.171.232.143]) + by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BI73F8b1489360 + (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO) + for ; Sun, 18 Dec 2022 07:03:16 GMT', + ] + ] + ], $headersProcessed); + } + + public function testSendmailTLS12WithVerify() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from smtp.github.com (out-18.smtp.github.com [192.30.252.201]) + by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BGMf4uY685293 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) + for ; Fri, 16 Dec 2022 22:41:05 GMT', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strSendmailCryptedTlsv12WithCipherVerify, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from smtp.github.com (out-18.smtp.github.com [192.30.252.201]) + by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BGMf4uY685293 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) + for ; Fri, 16 Dec 2022 22:41:05 GMT', + ] + ] + ], $headersProcessed); + } + + public function testSendmailTLS13MultipleRecipients() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from mout.kundenserver.de (mout.kundenserver.de [212.227.126.134]) + by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BLGrgYw3602565 + (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); + Wed, 21 Dec 2022 16:53:42 GMT', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strSendmailCryptedTlsv13WithCipherNoVerify, + 'html' => 1, + ], + ], + 'headers' => (object)[ + 'others' => [ + 'received' => 'from mout.kundenserver.de (mout.kundenserver.de [212.227.126.134]) + by mail.aegee.org (8.17.1/8.17.1) with ESMTPS id 2BLGrgYw3602565 + (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); + Wed, 21 Dec 2022 16:53:42 GMT', + ] + ] + ], $headersProcessed); + } + + public function testStalwartTls() + { + $o = new tls_icon(); + $headersProcessed = $o->message_headers([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you', + ], + ], + 'headers' => (object) [ + 'others' => [ + 'received' => 'from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174] (AS15169 Google LLC, US)) + (using TLSv1.3 with cipher TLS13_AES_256_GCM_SHA384) + by mail.example.org (Stalwart SMTP) with ESMTPS id 36DAF29F3A02098; + Mon, 16 Jun 2025 13:33:03 +0000', + ] + ] + ]); + $this->assertEquals([ + 'output' => [ + 'subject' => [ + 'value' => 'Sent to you' . $this->strStalwartCryptedTlsv13WithCipher, + 'html' => 1, + ], + ], + 'headers' => (object) [ + 'others' => [ + 'received' => 'from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174] (AS15169 Google LLC, US)) + (using TLSv1.3 with cipher TLS13_AES_256_GCM_SHA384) + by mail.example.org (Stalwart SMTP) with ESMTPS id 36DAF29F3A02098; + Mon, 16 Jun 2025 13:33:03 +0000', + ] + ] + ], $headersProcessed); + } + + /** + * @runInSeparateProcess + */ + public function testGetSvgPathPre17() + { + if (!defined('RCMAIL_VERSION')) { + define('RCMAIL_VERSION', '1.6.9'); + } + + $plugin = new tls_icon(); + $this->assertSame('plugins/tls_icon/lock.svg', $plugin->get_svg_path('lock.svg')); + } + + /** + * @runInSeparateProcess + */ + public function testGetSvgPath17() + { + if (!defined('RCMAIL_VERSION')) { + define('RCMAIL_VERSION', '1.7.0'); + } + + $plugin = new tls_icon(); + $this->assertSame('static.php/plugins/tls_icon/lock.svg', $plugin->get_svg_path('lock.svg')); + } + + /** + * @runInSeparateProcess + */ + public function testGetSvgPath17Git() + { + if (!defined('RCMAIL_VERSION')) { + define('RCMAIL_VERSION', '1.7-git'); + } + + $plugin = new tls_icon(); + $this->assertSame('static.php/plugins/tls_icon/lock.svg', $plugin->get_svg_path('lock.svg')); + } } diff --git a/tls_icon.php b/tls_icon.php index 4a17f33..e4a28b3 100644 --- a/tls_icon.php +++ b/tls_icon.php @@ -39,12 +39,25 @@ function get_received_header_content($Received_Header) return $Received; } - public function storage_init($p) - { - $headers = isset($p['fetch_headers']) ? $p['fetch_headers'] : ''; - $p['fetch_headers'] = trim(trim($headers) . ' ' . strtoupper('Received')); - return $p; - } + public function storage_init($p) + { + $headers = isset($p['fetch_headers']) ? $p['fetch_headers'] : ''; + $p['fetch_headers'] = trim(trim($headers) . ' ' . strtoupper('Received')); + return $p; + } + + public function get_svg_path($filename) + { + // Roundcube 1.7+ requires using static.php for direct file access + if (defined('RCMAIL_VERSION')) { + // Parse version: remove non-numeric parts after the version numbers + $version = preg_replace('/[^0-9.].*/', '', RCMAIL_VERSION); + if (version_compare($version, '1.7', '>=')) { + return 'static.php/plugins/tls_icon/' . $filename; + } + } + return 'plugins/tls_icon/' . $filename; + } public function message_headers($p) { @@ -59,18 +72,18 @@ public function message_headers($p) return $p; } - if ( - preg_match_all(tls_icon::POSTFIX_TLS_REGEX, $Received, $items, PREG_PATTERN_ORDER) || - preg_match_all(tls_icon::SENDMAIL_TLS_REGEX, $Received, $items, PREG_PATTERN_ORDER) - ) { - $data = $items[1][0]; - $this->icon_img .= ''; - } elseif (preg_match_all(tls_icon::POSTFIX_LOCAL_REGEX, $Received, $items, PREG_PATTERN_ORDER)) { - $this->icon_img .= ''; - } else { - $this->icon_img .= ''; - } - } + if ( + preg_match_all(tls_icon::POSTFIX_TLS_REGEX, $Received, $items, PREG_PATTERN_ORDER) || + preg_match_all(tls_icon::SENDMAIL_TLS_REGEX, $Received, $items, PREG_PATTERN_ORDER) + ) { + $data = $items[1][0]; + $this->icon_img .= ''; + } elseif (preg_match_all(tls_icon::POSTFIX_LOCAL_REGEX, $Received, $items, PREG_PATTERN_ORDER)) { + $this->icon_img .= ''; + } else { + $this->icon_img .= ''; + } + } if (isset($p['output']['subject'])) { $p['output']['subject']['value'] = htmlentities($p['output']['subject']['value']) . $this->icon_img;