Page MenuHomePhorge

D5475.1775221144.diff
No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None

D5475.1775221144.diff

diff --git a/docker/postfix/rootfs/usr/libexec/postfix/kolab_contentfilter_cli b/docker/postfix/rootfs/usr/libexec/postfix/kolab_contentfilter_cli
--- a/docker/postfix/rootfs/usr/libexec/postfix/kolab_contentfilter_cli
+++ b/docker/postfix/rootfs/usr/libexec/postfix/kolab_contentfilter_cli
@@ -44,6 +44,12 @@
return EX_TEMPFAIL
+def logContent(content):
+ content = content.replace("\r", "CR")
+ content = content.replace("\n", "LF\n")
+ logging.info(content)
+
+
if __name__ == "__main__":
(cli_from, cli_to) = get_args()
@@ -53,7 +59,15 @@
filename='/var/log/kolab/postfix-content-filter.log',
filemode='a')
- content = ''.join(sys.stdin.readlines())
+ content = sys.stdin.read()
+
+ # To debug what we actually get in terms of line endings
+ # I've tested sys.stdin.buffer, but it seems we get LF line endings from postfix
+ # logContent(content)
+
+ # Normalize to CRLF line endings.
+ content = content.replace('\r\n', '\n')
+ content = content.replace('\n', '\r\n')
try:
to = ','.join(cli_to)
@@ -91,4 +105,5 @@
print(f"Request failed: {request_url}, {str(e)}")
sys.exit(EX_TEMPFAIL)
+ content = content.replace('\r\n', '\n')
sys.exit(reinject(content, cli_from, cli_to))
diff --git a/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py b/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py
--- a/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py
+++ b/docker/utils/rootfs/opt/app-root/src/mailtransporttest.py
@@ -189,6 +189,7 @@
self.bulk_send = options.bulk_send
self.attachmentSize = options.attachmentSize
self.invitation = options.invitation
+ self.testmessage = options.testmessage
self.uuid = None
self.subject = None
@@ -247,6 +248,25 @@
return True
+ def validate_testmessage(self, message):
+ import email.parser
+ import email.policy
+ msg = email.parser.BytesParser(policy=email.policy.default).parsebytes(message)
+ if self.verbose:
+ print(msg)
+
+ if "MODIFIED" not in msg['Subject']:
+ print_error("Failed to modify the Subject")
+ print("Existing header: " + str(msg['Subject']))
+ return False
+
+ if "KOLABv4TestMessage" not in msg.get_body():
+ print_error("Missing test body")
+ print("Existing body: " + str(msg.get_body()))
+ return False
+
+ return True
+
def check_for_mail(self):
print(f"Checking for uuid {self.uuid}")
imap = imaplib.IMAP4_SSL(host=self.recipient_host, port=self.recipient_port)
@@ -254,11 +274,7 @@
imap.debug = 4
imap.login(self.recipient_username, self.recipient_password)
imap.select("INBOX")
- # FIXME This seems to find emails that are not there
- if self.body:
- typ, data = imap.search(None, 'BODY', self.uuid)
- else:
- typ, data = imap.search(None, 'SUBJECT', self.uuid)
+ typ, data = imap.search(None, 'SUBJECT', self.uuid)
for num in data[0].split():
@@ -271,6 +287,13 @@
print_error("Failed to validate the message.")
print(message.decode())
sys.exit(1)
+ if self.testmessage:
+ typ, data = imap.fetch(num, "(RFC822)")
+ message = data[0][1]
+ if not self.validate_testmessage(message):
+ print_error("Failed to validate the message.")
+ print(message.decode())
+ sys.exit(1)
imap.store(num, '+FLAGS', '\\Deleted')
@@ -280,7 +303,11 @@
def get_message(self, from_address, to):
self.uuid = str(uuid.uuid4())
- self.subject = f"Delivery Check {self.uuid}"
+ if self.testmessage:
+ self.subject = f"KOLABv4TestMessage: DUMP MODIFYSUBJECT {self.uuid}"
+ self.body = "KOLABv4TestMessage"
+ else:
+ self.subject = f"Delivery Check {self.uuid}"
dtstamp = datetime.utcnow()
if self.invitation:
start = dtstamp
@@ -384,6 +411,7 @@
parser.add_argument("--validate", action='store_true', help="Validate the received message")
parser.add_argument('--bulk-send', help='Bulk send email, then exit', type=int, default=0)
parser.add_argument('--invitation', action='store_true', help='Send an invitation')
+parser.add_argument('--testmessage', action='store_true', help='Send a kolab4 testmessage')
parser.add_argument('--attachmentSize', help='in MB', type=int, default=0)
args = parser.parse_args()
diff --git a/src/app/Policy/Mailfilter.php b/src/app/Policy/Mailfilter.php
--- a/src/app/Policy/Mailfilter.php
+++ b/src/app/Policy/Mailfilter.php
@@ -206,6 +206,9 @@
}
}
+ // Always enable the test module
+ $modules[Modules\TestModule::class] = [];
+
return $modules;
}
}
diff --git a/src/app/Policy/Mailfilter/MailParser.php b/src/app/Policy/Mailfilter/MailParser.php
--- a/src/app/Policy/Mailfilter/MailParser.php
+++ b/src/app/Policy/Mailfilter/MailParser.php
@@ -44,6 +44,18 @@
$this->parseHeaders();
}
+ /**
+ * Dump stream to a string
+ */
+ public function dumpStream(): string
+ {
+ $pos = ftell($this->stream);
+ rewind($this->stream);
+ $str = stream_get_contents($this->stream);
+ fseek($this->stream, $pos);
+ return $str;
+ }
+
/**
* Log a debug message
*/
@@ -400,6 +412,13 @@
break;
}
+ // All emails MUST have CRLF line endings, per RFC and the parser does not work otherwise.
+ if (!str_ends_with($line, "\r\n")) {
+ $line = str_replace("\r", 'CR', $line);
+ $line = str_replace("\n", 'LF', $line);
+ throw new \Exception("Email with non CRLF line-ending detected: $line");
+ }
+
if ($line == "\n" || $line == "\r\n") {
break;
}
diff --git a/src/app/Policy/Mailfilter/Modules/TestModule.php b/src/app/Policy/Mailfilter/Modules/TestModule.php
new file mode 100644
--- /dev/null
+++ b/src/app/Policy/Mailfilter/Modules/TestModule.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Policy\Mailfilter\Modules;
+
+use App\Policy\Mailfilter\MailParser;
+use App\Policy\Mailfilter\Module;
+use App\Policy\Mailfilter\Result;
+
+class TestModule extends Module
+{
+ /**
+ * Handle the email message
+ */
+ public function handle(MailParser $parser): ?Result
+ {
+ $subject = $parser->getHeader('subject');
+ if (str_starts_with($subject, "KOLABv4TestMessage")) {
+ $parser->debug("Received a test message: $subject");
+ if (str_contains($subject, "DUMP")) {
+ $str = $parser->dumpStream();
+ $str = str_replace("\r", "CR", $str);
+ $str = str_replace("\n", "LF\n", $str);
+ $parser->debug($str);
+ }
+
+ if (str_contains($subject, "MODIFYSUBJECT")) {
+ $parser->setHeader('Subject', $subject . " MODIFIED");
+ }
+ }
+
+ return null;
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 12:59 PM (17 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18824150
Default Alt Text
D5475.1775221144.diff (7 KB)

Event Timeline