├── LICENSE ├── README.md ├── blue_lock.svg ├── composer.json ├── config.inc.php.dist ├── localization ├── de_DE.inc ├── en_US.inc ├── fr_FR.inc ├── nl_NL.inc └── ru_RU.inc ├── lock.svg ├── tls_icon.css ├── tls_icon.php └── unlock.svg /LICENSE: -------------------------------------------------------------------------------- 1 | This project was inspired by https://github.com/SS88UK/roundcube-easy-unsubscribe and copies some code of it. 2 | 3 | License of this project: 4 | 5 | MIT License 6 | 7 | Copyright (c) 2020 GermanCoding 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | ------------------------------------------------------------------------------- 28 | License of roundcube-easy-unsubscribe: 29 | 30 | MIT License 31 | 32 | Copyright (c) 2018 Steven Sullivan 33 | 34 | Permission is hereby granted, free of charge, to any person obtaining a copy 35 | of this software and associated documentation files (the "Software"), to deal 36 | in the Software without restriction, including without limitation the rights 37 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 38 | copies of the Software, and to permit persons to whom the Software is 39 | furnished to do so, subject to the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be included in all 42 | copies or substantial portions of the Software. 43 | 44 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 49 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 50 | SOFTWARE. 51 | 52 | -------------------------------------------------------------------------------- 53 | The lock icons used are modified versions (colored) of icons included in Fork Awesome (https://github.com/ForkAwesome/Fork-Awesome) 54 | 55 | Fork-Awesome Icon License: 56 | 57 | /!\ The SIL OPEN FONT LICENSE applies to all desktop and webfont files in the 58 | following directory: fonts/ and to all glyphs and SVG files in the following 59 | directory: src/icons/svg/. 60 | 61 | 62 | Copyright (c) 2018, Fork Awesome (https://forkawesome.github.io), 63 | with Reserved Font Name Fork Awesome. 64 | 65 | 66 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 67 | This license is copied below, and is also available with a FAQ at: 68 | http://scripts.sil.org/OFL 69 | 70 | 71 | ----------------------------------------------------------- 72 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 73 | ----------------------------------------------------------- 74 | 75 | PREAMBLE 76 | The goals of the Open Font License (OFL) are to stimulate worldwide 77 | development of collaborative font projects, to support the font creation 78 | efforts of academic and linguistic communities, and to provide a free and 79 | open framework in which fonts may be shared and improved in partnership 80 | with others. 81 | 82 | The OFL allows the licensed fonts to be used, studied, modified and 83 | redistributed freely as long as they are not sold by themselves. The 84 | fonts, including any derivative works, can be bundled, embedded, 85 | redistributed and/or sold with any software provided that any reserved 86 | names are not used by derivative works. The fonts and derivatives, 87 | however, cannot be released under any other type of license. The 88 | requirement for fonts to remain under this license does not apply 89 | to any document created using the fonts or their derivatives. 90 | 91 | DEFINITIONS 92 | "Font Software" refers to the set of files released by the Copyright 93 | Holder(s) under this license and clearly marked as such. This may 94 | include source files, build scripts and documentation. 95 | 96 | "Reserved Font Name" refers to any names specified as such after the 97 | copyright statement(s). 98 | 99 | "Original Version" refers to the collection of Font Software components as 100 | distributed by the Copyright Holder(s). 101 | 102 | "Modified Version" refers to any derivative made by adding to, deleting, 103 | or substituting -- in part or in whole -- any of the components of the 104 | Original Version, by changing formats or by porting the Font Software to a 105 | new environment. 106 | 107 | "Author" refers to any designer, engineer, programmer, technical 108 | writer or other person who contributed to the Font Software. 109 | 110 | PERMISSION & CONDITIONS 111 | Permission is hereby granted, free of charge, to any person obtaining 112 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 113 | redistribute, and sell modified and unmodified copies of the Font 114 | Software, subject to the following conditions: 115 | 116 | 1) Neither the Font Software nor any of its individual components, 117 | in Original or Modified Versions, may be sold by itself. 118 | 119 | 2) Original or Modified Versions of the Font Software may be bundled, 120 | redistributed and/or sold with any software, provided that each copy 121 | contains the above copyright notice and this license. These can be 122 | included either as stand-alone text files, human-readable headers or 123 | in the appropriate machine-readable metadata fields within text or 124 | binary files as long as those fields can be easily viewed by the user. 125 | 126 | 3) No Modified Version of the Font Software may use the Reserved Font 127 | Name(s) unless explicit written permission is granted by the corresponding 128 | Copyright Holder. This restriction only applies to the primary font name as 129 | presented to the users. 130 | 131 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 132 | Software shall not be used to promote, endorse or advertise any 133 | Modified Version, except to acknowledge the contribution(s) of the 134 | Copyright Holder(s) and the Author(s) or with their explicit written 135 | permission. 136 | 137 | 5) The Font Software, modified or unmodified, in part or in whole, 138 | must be distributed entirely under this license, and must not be 139 | distributed under any other license. The requirement for fonts to 140 | remain under this license does not apply to any document created 141 | using the Font Software. 142 | 143 | TERMINATION 144 | This license becomes null and void if any of the above conditions are 145 | not met. 146 | 147 | DISCLAIMER 148 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 149 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 150 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 151 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 152 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 153 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 154 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 155 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 156 | OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Roundcube TLS Icon 2 | 3 | Displays a small icon after the subject line that displays the (presumed) encryption state of received mails. 4 | This plugin parses the "Received" header for the last hop and checks if TLS was used. This requires TLS logging in the 5 | receiving MTA. 6 | 7 | In Postfix this can be enabled by 8 | setting [`smtpd_tls_received_header = yes`](https://www.postfix.org/postconf.5.html#smtpd_tls_received_header). Sendmail 9 | should work out of the box. Other MTAs have not been explicitly tested. 10 | 11 | Note that while this talks about "encryption", this does not imply security. An encrypted mail may still be insecure, 12 | mostly because mailservers generally use "opportunistic TLS", where MITM attacks are possible. 13 | This also only validates the last hop of an email - some emails may run through multiple hops and we don't know anything 14 | about the security of these. 15 | 16 | Inspired by [roundcube-easy-unsubscribe](https://github.com/SS88UK/roundcube-easy-unsubscribe) 17 | 18 | ![Example screenshot](tls_icon_example.png) 19 | 20 | ## Installation 21 | 22 | The [composer library](https://packagist.org/packages/germancoding/tls_icon) name is: `germancoding/tls_icon`. 23 | 24 | The plugin name to add to your config file is: `tls_icon`. 25 | 26 | ## Requirements 27 | 28 | - Roundcube `1.3.0` or newer. 29 | - PHP `5.4` or newer. 30 | 31 | ## Currently supported languages 32 | 33 | - Dutch 34 | - English 35 | - French 36 | - German 37 | - Russian 38 | -------------------------------------------------------------------------------- /blue_lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "germancoding/tls_icon", 3 | "type": "roundcube-plugin", 4 | "description": "Displays a lock next to the message if it was received using TLS. Requires TLS logging enabled in the MTA.", 5 | "license": "MIT", 6 | "keywords": ["TLS", "SSL", "icon", "logging"], 7 | "homepage": "https://github.com/GermanCoding/Roundcube_TLS_Icon", 8 | "repositories": [ 9 | { 10 | "type": "composer", 11 | "url": "https://plugins.roundcube.net" 12 | } 13 | ], 14 | "require": { 15 | "php": "^5.4 || ^7.0 || ^8.0", 16 | "roundcube/plugin-installer": ">=0.1.6" 17 | }, 18 | "config": { 19 | "allow-plugins": { 20 | "roundcube/plugin-installer": true 21 | } 22 | }, 23 | "extra": { 24 | "roundcube": { 25 | "min-version": "1.3.0" 26 | } 27 | }, 28 | "require-dev": { 29 | "phpunit/phpunit": "^4 || ^5 || ^6 || ^7 || ^8 || ^9" 30 | }, 31 | "scripts": { 32 | "test": "@php phpunit" 33 | }, 34 | "autoload": { 35 | "classmap": [ 36 | "tls_icon.php" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /config.inc.php.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tls_icon.css: -------------------------------------------------------------------------------- 1 | .lock_icon { 2 | height: 13px; 3 | margin-left: 10px; 4 | vertical-align: middle; 5 | transition:all 0.3s ease; 6 | text-decoration: underline; 7 | cursor: help; 8 | white-space: pre-line; 9 | } -------------------------------------------------------------------------------- /tls_icon.php: -------------------------------------------------------------------------------- 1 | rcmail = rcmail::get_instance(); 16 | $this->load_config(); 17 | 18 | $this->add_hook('message_headers_output', array($this, 'message_headers')); 19 | $this->add_hook('storage_init', array($this, 'storage_init')); 20 | 21 | $this->include_stylesheet('tls_icon.css'); 22 | 23 | $this->add_texts('localization/'); 24 | } 25 | 26 | function get_received_header_content($Received_Header) 27 | { 28 | $Received = null; 29 | if (is_array($Received_Header)) { 30 | $ignore_n_hops = $this->rcmail->config->get('tls_icon_ignore_hops'); 31 | if ($ignore_n_hops && count($Received_Header) > $ignore_n_hops) { 32 | $Received = $Received_Header[$ignore_n_hops]; 33 | } else { 34 | $Received = $Received_Header[0]; 35 | } 36 | } else { 37 | $Received = $Received_Header; 38 | } 39 | return $Received; 40 | } 41 | 42 | public function storage_init($p) 43 | { 44 | $headers = isset($p['fetch_headers']) ? $p['fetch_headers'] : ''; 45 | $p['fetch_headers'] = trim(trim($headers) . ' ' . strtoupper('Received')); 46 | return $p; 47 | } 48 | 49 | public function message_headers($p) 50 | { 51 | if ($this->message_headers_done === false) { 52 | $this->message_headers_done = true; 53 | 54 | $Received_Header = isset($p['headers']->others['received']) ? $p['headers']->others['received'] : null; 55 | $Received = $this->get_received_header_content($Received_Header); 56 | 57 | if ($Received == null) { 58 | // There was no Received Header. Possibly an outbound mail. Do nothing. 59 | return $p; 60 | } 61 | 62 | if (preg_match_all(tls_icon::POSTFIX_TLS_REGEX, $Received, $items, PREG_PATTERN_ORDER) || 63 | preg_match_all(tls_icon::SENDMAIL_TLS_REGEX, $Received, $items, PREG_PATTERN_ORDER)) { 64 | $data = $items[1][0]; 65 | $this->icon_img .= ''; 66 | } elseif (preg_match_all(tls_icon::POSTFIX_LOCAL_REGEX, $Received, $items, PREG_PATTERN_ORDER)) { 67 | $this->icon_img .= ''; 68 | } else { 69 | // TODO: Mails received from localhost but without TLS are currently flagged insecure 70 | $this->icon_img .= ''; 71 | } 72 | } 73 | 74 | if (isset($p['output']['subject'])) { 75 | $p['output']['subject']['value'] = htmlentities($p['output']['subject']['value']) . $this->icon_img; 76 | $p['output']['subject']['html'] = 1; 77 | } 78 | 79 | return $p; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /unlock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | --------------------------------------------------------------------------------