From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id C2C1F9156C for ; Fri, 17 Mar 2023 19:45:48 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 87A241D111 for ; Fri, 17 Mar 2023 19:45:18 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Fri, 17 Mar 2023 19:45:17 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id E9B3245220 for ; Fri, 17 Mar 2023 19:45:16 +0100 (CET) From: Stoiko Ivanov To: pmg-devel@lists.proxmox.com Date: Fri, 17 Mar 2023 19:44:53 +0100 Message-Id: <20230317184456.26465-5-s.ivanov@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230317184456.26465-1-s.ivanov@proxmox.com> References: <20230317184456.26465-1-s.ivanov@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.143 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [quarantine.pm, metacpan.org] Subject: [pmg-devel] [PATCH pmg-api v3 4/5] quarantine: use reinject_local_mail to deliver quarantined mail X-BeenThere: pmg-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Mail Gateway development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Mar 2023 18:45:48 -0000 the current delivery looks quite similar to reinject_local_mail, apart from the database handling and sending the mail-contents from a file instead of a MIME::Entity. reinject_mail has received a few improvments over time, which never made it to this implementation - e.g. in: * ebd31d3e74d9417375b86766ee300be493044d39 * ad1c6bcea94cbaf8d4862bcb05874b59c656c632 While reparsing the mail might seem expensive, the quarantine code does so multiple times when users click in the quarantine GUI (see PMG::HTMLMail, and the attachment quarantine) The issue of MIME::Parser being lossy [0] (parsing and then printing the entity, might not return the original mail byte-by-byte), is already present in our code-base anyways (when the mail gets quarantined (or sent on) it is from a parsed MIME::Entity). [0] https://metacpan.org/pod/MIME::Tools Signed-off-by: Stoiko Ivanov --- src/PMG/Quarantine.pm | 64 ++++++++++--------------------------------- 1 file changed, 15 insertions(+), 49 deletions(-) diff --git a/src/PMG/Quarantine.pm b/src/PMG/Quarantine.pm index aa6b948..bd5e63b 100644 --- a/src/PMG/Quarantine.pm +++ b/src/PMG/Quarantine.pm @@ -2,7 +2,6 @@ package PMG::Quarantine; use strict; use warnings; -use Net::SMTP; use Encode qw(encode); use PVE::SafeSyslog; @@ -11,6 +10,7 @@ use PVE::Tools; use PMG::Utils; use PMG::RuleDB; use PMG::MailQueue; +use PMG::MIMEUtils; sub add_to_blackwhite { my ($dbh, $username, $listname, $addrs, $delete) = @_; @@ -98,55 +98,24 @@ sub deliver_quarantined_mail { my $id = 'C' . $ref->{cid} . 'R' . $ref->{rid} . 'T' . $ref->{ticketid};; - my $sender = 'postmaster'; # notify postmaster if something fails - - my $smtp; - - eval { - my $smtp = Net::SMTP->new ('127.0.0.1', Port => 10025, Hello => 'quarantine') || - die "unable to connect to localhost at port 10025\n"; - - my $resid; - - if (!$smtp->mail($sender)) { - die sprintf("smtp from error - got: %s %s\n", $smtp->code, $smtp->message); - } - - if (!$smtp->to($receiver)) { - die sprintf("smtp to error - got: %s %s\n", $smtp->code, $smtp->message); - } + my $parser = PMG::MIMEUtils::new_mime_parser({ + nested => 1, + decode_bodies => 0, + extract_uuencode => 0, + dumpdir => "/tmp/.quarantine-$id-$receiver-$$/", + }); - $smtp->data(); + my $entity = $parser->parse_open("$path"); + PMG::MIMEUtils::fixup_multipart($entity); - my $header = 1; - - open(my $fh, '<', $path) || die "unable to open file '$path' - $!\n"; - - while (defined(my $line = <$fh>)) { - chomp $line; - if ($header && ($line =~ m/^\s*$/)) { - $header = 0; - } + my $sender = 'postmaster'; # notify postmaster if something fails - # skip Delivered-To and Return-Path (avoid problem with postfix - # forwarding loop detection (man local)) - next if ($header && (($line =~ m/^Delivered-To:/i) || ($line =~ m/^Return-Path:/i))); + eval { + my ($qid, $code, $mess) = PMG::Utils::reinject_local_mail( + $entity, $sender, [$receiver], undef, 'quarantine'); - # rfc821 requires this - $line =~ s/^\./\.\./mg; - $smtp->datasend("$line\n"); - } - close($fh); - - if ($smtp->dataend()) { - my (@msgs) = $smtp->message; - my ($last_msg) = $msgs[$#msgs]; - ($resid) = $last_msg =~ m/Ok: queued as ([0-9A-Z]+)/; - if (!$resid) { - die sprintf("smtp error - got: %s %s\n", $smtp->code, $smtp->message); - } - } else { - die sprintf("sending data failed - got: %s %s\n", $smtp->code, $smtp->message); + if (!$qid) { + die "$mess\n"; } my $sth = $dbh->prepare( @@ -156,9 +125,6 @@ sub deliver_quarantined_mail { $sth->finish; }; my $err = $@; - - $smtp->quit if $smtp; - if ($err) { my $msg = "deliver quarantined mail '$id' ($path) failed: $err"; syslog('err', $msg); -- 2.30.2