]> git.proxmox.com Git - pmg-api.git/commitdiff
partially fix #2465: handle smtputf8 addresses in the rule-system
authorStoiko Ivanov <s.ivanov@proxmox.com>
Thu, 24 Nov 2022 12:21:05 +0000 (13:21 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 24 Nov 2022 13:38:44 +0000 (14:38 +0100)
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 <s.ivanov@proxmox.com>
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
src/PMG/MailQueue.pm
src/PMG/RuleDB/Spam.pm
src/bin/pmg-smtp-filter

index 2841b076570c25f5cb19707605650a5a7fa3c29b..8355c303a42570036fd4a3936257e6a488c35873 100644 (file)
@@ -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);
 
index cc9a34726d75e5296040f3aef3b25c7e27e4089f..99056a37f8a7161f2d63e289204d72a53bbe3825 100644 (file)
@@ -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";
     }   
 
index 45e68a700858521534fce25223f080dadd561363..911e9cd6df4d31446c8fbb0a9f7fad6804b3ff7e 100755 (executable)
@@ -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'); ";