From: Stoiko Ivanov <s.ivanov@proxmox.com>
To: pmg-devel@lists.proxmox.com
Subject: [pmg-devel] [PATCH pmg-api v3 4/5] quarantine: use reinject_local_mail to deliver quarantined mail
Date: Fri, 17 Mar 2023 19:44:53 +0100 [thread overview]
Message-ID: <20230317184456.26465-5-s.ivanov@proxmox.com> (raw)
In-Reply-To: <20230317184456.26465-1-s.ivanov@proxmox.com>
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 <s.ivanov@proxmox.com>
---
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
next prev parent reply other threads:[~2023-03-17 18:45 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-17 18:44 [pmg-devel] [PATCH pmg-api v3 0/5] improve local mail injection and add smtputf8 support Stoiko Ivanov
2023-03-17 18:44 ` [pmg-devel] [PATCH pmg-api v3 1/5] smtputf8: keep smtputf8 from incoming postfix, detect for local mail Stoiko Ivanov
2023-03-17 18:44 ` [pmg-devel] [PATCH pmg-api v3 2/5] config: make smtputf8 configurable through the API Stoiko Ivanov
2023-03-17 18:44 ` [pmg-devel] [PATCH pmg-api v3 3/5] reinject mail: improve error logging Stoiko Ivanov
2023-03-17 18:44 ` Stoiko Ivanov [this message]
2023-03-17 18:44 ` [pmg-devel] [PATCH pmg-api v3 5/5] api: quarantine: decode addresses before delivery/userlisting Stoiko Ivanov
2023-03-17 18:44 ` [pmg-devel] [PATCH pmg-gui v3 1/1] mail proxy options: add smtputf8 checkbox Stoiko Ivanov
2023-03-17 18:44 ` [pmg-devel] [PATCH pmg-docs v3 1/1] doc-generator: add new option smtputf8 Stoiko Ivanov
2023-03-23 11:18 ` [pmg-devel] [PATCH pmg-api v3 0/5] improve local mail injection and add smtputf8 support Dominik Csapak
2023-03-27 10:33 ` [pmg-devel] applied-series: " Thomas Lamprecht
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230317184456.26465-5-s.ivanov@proxmox.com \
--to=s.ivanov@proxmox.com \
--cc=pmg-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.