From 04b2e3100999b3cd7b060d1c298b3b3489d4044b Mon Sep 17 00:00:00 2001 From: GermanCoding Date: Sat, 2 May 2026 17:10:23 +0200 Subject: [PATCH 1/2] feat: Support Roundcube 1.7 static files handling Roundcube 1.7 forces us to go trough static.php for security. However, this script does not exist in older Roundcube releases. To maintain backwards compatibility, figure out the correct path at runtime depending on the version. --- README.md | 2 +- test/TlsIconTest.php | 1024 +++++++++++++++++++++--------------------- tls_icon.php | 49 +- 3 files changed, 551 insertions(+), 524 deletions(-) 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..2628636 100644 --- a/test/TlsIconTest.php +++ b/test/TlsIconTest.php @@ -12,514 +12,528 @@ 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); + } } 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; From a69b58e12cce2d86fd51ffa6bfe6c2ddde26ebd0 Mon Sep 17 00:00:00 2001 From: GermanCoding Date: Sat, 2 May 2026 17:19:13 +0200 Subject: [PATCH 2/2] chore: Add tests for new static file handling --- test/TlsIconTest.php | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/TlsIconTest.php b/test/TlsIconTest.php index 2628636..d8165f0 100644 --- a/test/TlsIconTest.php +++ b/test/TlsIconTest.php @@ -536,4 +536,43 @@ public function testStalwartTls() ] ], $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')); + } }