From c53efc6eb6e55672b3ad325d4080d2cbc7cca8d2 Mon Sep 17 00:00:00 2001 From: Stoiko Ivanov Date: Thu, 24 Nov 2022 13:21:05 +0100 Subject: [PATCH] partially fix #2465: handle smtputf8 addresses in the rule-system the envelope addresses are used in the rule-system for lookups and statistics. When the mail is received with smtputf8 the addresses are decoded (multi-byte perl-strings) and thus need encoding before using them as parameter in a database query. This patch encodes the addresses as utf-8 for the relevant queries unconditionally, because envelope-senders should either be: * (a subset of) ascii (no smtputf8) - which is invariant for utf-8 encoding * valid utf-8 (smtputf8) The patch does not address the issues with multi-byte addresses in our LDAP-implementation (hence the partial fix), but should still be an improvment for many deployments Signed-off-by: Stoiko Ivanov Signed-off-by: Dominik Csapak --- src/PMG/MailQueue.pm | 10 ++++++---- src/PMG/RuleDB/Spam.pm | 5 +++-- src/bin/pmg-smtp-filter | 5 +++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/PMG/MailQueue.pm b/src/PMG/MailQueue.pm index 2841b07..8355c30 100644 --- a/src/PMG/MailQueue.pm +++ b/src/PMG/MailQueue.pm @@ -6,6 +6,7 @@ use warnings; use PVE::SafeSyslog; use MIME::Parser; use IO::File; +use Encode; use File::Sync; use File::Basename; use File::Path; @@ -141,6 +142,7 @@ sub quarantinedb_insert { my ($self, $ruledb, $lcid, $ldap, $qtype, $header, $sender, $file, $targets, $vars) = @_; eval { + $sender = encode('UTF-8', $sender); my $dbh = $ruledb->{dbh}; my $insert_cmds = "SELECT nextval ('cmailstore_id_seq'); INSERT INTO CMailStore " . @@ -188,11 +190,11 @@ sub quarantinedb_insert { if ($pmail eq lc ($r)) { $receiver = "NULL"; } else { - $receiver = $dbh->quote ($r); + $receiver = $dbh->quote (encode('UTF-8', $r)); } - $pmail = $dbh->quote ($pmail); + $pmail = $dbh->quote (encode('UTF-8', $pmail)); $insert_cmds .= "INSERT INTO CMSReceivers " . "(CMailStore_CID, CMailStore_RID, PMail, Receiver, TicketID, Status, MTime) " . "VALUES ($lcid, currval ('cmailstore_id_seq'), $pmail, $receiver, $tid, 'N', $now); "; @@ -294,8 +296,8 @@ sub quarantine_mail { $entity->head->delete ('Return-Path'); # prepend Delivered-To and Return-Path (like QMAIL MAILDIR FORMAT) - $entity->head->add ('Return-Path', join (',', $sender), 0); - $entity->head->add ('Delivered-To', join (',', @$tg), 0); + $entity->head->add ('Return-Path', encode('UTF-8', join (',', $sender)), 0); + $entity->head->add ('Delivered-To', encode('UTF-8', join (',', @$tg)), 0); $entity->print ($fh); diff --git a/src/PMG/RuleDB/Spam.pm b/src/PMG/RuleDB/Spam.pm index cc9a347..99056a3 100644 --- a/src/PMG/RuleDB/Spam.pm +++ b/src/PMG/RuleDB/Spam.pm @@ -4,6 +4,7 @@ use strict; use warnings; use DBI; use Digest::SHA; +use Encode qw(encode); use Time::HiRes qw (gettimeofday); use PVE::SafeSyslog; @@ -135,8 +136,8 @@ sub get_blackwhite { my $cond = ''; foreach my $r (@$targets) { my $pmail = $msginfo->{pmail}->{$r} || lc ($r); - my $qr = $dbh->quote ($pmail); - $cond .= " OR " if $cond; + my $qr = $dbh->quote (encode('UTF-8', $pmail)); + $cond .= " OR " if $cond; $cond .= "pmail = $qr"; } diff --git a/src/bin/pmg-smtp-filter b/src/bin/pmg-smtp-filter index 45e68a7..911e9cd 100755 --- a/src/bin/pmg-smtp-filter +++ b/src/bin/pmg-smtp-filter @@ -4,6 +4,7 @@ use strict; use warnings; use Carp; +use Encode qw(encode); use Getopt::Long; use Time::HiRes qw (usleep gettimeofday tv_interval); use POSIX qw(:sys_wait_h errno_h signal_h); @@ -791,10 +792,10 @@ sub handle_smtp { $insert_cmds .= ($queue->{sa_score} || 0) . ','; $insert_cmds .= $dbh->quote($queue->{vinfo}) . ','; $insert_cmds .= $time_total . ','; - $insert_cmds .= $dbh->quote($msginfo->{sender}) . ');'; + $insert_cmds .= $dbh->quote(encode('UTF-8', $msginfo->{sender})) . ');'; foreach my $r (@{$msginfo->{targets}}) { - my $tmp = $dbh->quote($r); + my $tmp = $dbh->quote(encode('UTF-8',$r)); my $blocked = $queue->{status}->{$r} eq 'blocked' ? 1 : 0; $insert_cmds .= "INSERT INTO CReceivers (CStatistic_CID, CStatistic_RID, Receiver, Blocked) " . "VALUES ($lcid, currval ('cstatistic_id_seq'), $tmp, '$blocked'); "; -- 2.39.5