From: Dietmar Maurer Date: Mon, 9 Jul 2018 10:47:48 +0000 (+0200) Subject: add support for SMTPUTF8 extensions X-Git-Url: https://git.proxmox.com/?p=pmg-api.git;a=commitdiff_plain;h=00eaaf69ba4cb7d05a218f7cc362ddf6c1599e9d add support for SMTPUTF8 extensions --- diff --git a/PMG/SMTP.pm b/PMG/SMTP.pm index ea4a013..ed4fd73 100644 --- a/PMG/SMTP.pm +++ b/PMG/SMTP.pm @@ -3,6 +3,7 @@ package PMG::SMTP; use strict; use warnings; use IO::Socket; +use Encode; use PVE::SafeSyslog; @@ -72,6 +73,7 @@ sub loop { $self->reply ("250-PIPELINING"); $self->reply ("250-ENHANCEDSTATUSCODES"); $self->reply ("250-8BITMIME"); + $self->reply ("250-SMTPUTF8"); $self->reply ("250-XFORWARD NAME ADDR PROTO HELO"); $self->reply ("250 OK."); $self->{lmtp} = 1 if ($cmd eq 'lhlo'); @@ -95,9 +97,11 @@ sub loop { $self->reply ("250 2.5.0 OK"); next; } elsif ($cmd eq 'mail') { - if ($args =~ m/^from:\s*<([^\s\>]*)>[^>]*$/i) { + if ($args =~ m/^from:\s*<([^\s\>]*)>([^>]*)$/i) { delete $self->{to}; - $self->{from} = $1; + my ($from, $opts) = ($1, $2); + $from = decode('UTF-8', $from) if $opts =~ m/\sSMTPUTF8/; + $self->{from} = $from; $self->reply ('250 2.5.0 OK'); next; } else { @@ -105,7 +109,9 @@ sub loop { next; } } elsif ($cmd eq 'rcpt') { - if ($args =~ m/^to:\s*<([^\s\>]+)>[^>]*$/i) { + if ($args =~ m/^to:\s*<([^\s\>]+)>([^>]*)$/i) { + my ($to, $opts) = ($1, $2); + $to = decode('UTF-8', $to) if $opts =~ m/\sSMTPUTF8/; push @{$self->{to}} , $1; $self->reply ('250 2.5.0 OK'); next; diff --git a/PMG/Utils.pm b/PMG/Utils.pm index 46fb89e..26c0921 100644 --- a/PMG/Utils.pm +++ b/PMG/Utils.pm @@ -23,6 +23,9 @@ use Socket; use RRDs; use Filesys::Df; use Encode; +use utf8; +no utf8; + use HTML::Entities; use PVE::ProcFSTools; @@ -208,16 +211,42 @@ sub reinject_mail { } } - if (!$smtp->mail($sender)) { + my $has_utf8_targets = 0; + foreach my $target (@$targets) { + if (utf8::is_utf8($target)) { + $has_utf8_targets = 1; + last; + } + } + + my $mail_opts = " BODY=8BITMIME"; + my $sender_addr; + if (utf8::is_utf8($sender)) { + $sender_addr = encode('UTF-8', $smtp->_addr($sender)); + $mail_opts .= " SMTPUTF8"; + } else { + $sender_addr = $smtp->_addr($sender); + $mail_opts .= " SMTPUTF8" if $has_utf8_targets; + } + + if (!$smtp->_MAIL("FROM:" . $sender_addr . $mail_opts)) { syslog('err', "smtp error - got: %s %s", $smtp->code, scalar ($smtp->message)); die "smtp from: ERROR"; } - my $dsnopts = $nodsn ? {Notify => ['NEVER']} : {}; + my $rcpt_opts = $nodsn ? " NOTIFY=NEVER" : ""; - if (!$smtp->to (@$targets, $dsnopts)) { - syslog ('err', "smtp error - got: %s %s", $smtp->code, scalar($smtp->message)); - die "smtp to: ERROR"; + foreach my $target (@$targets) { + my $rcpt_addr; + if (utf8::is_utf8($target)) { + $rcpt_addr = encode('UTF-8', $smtp->_addr($target)); + } else { + $rcpt_addr = $smtp->_addr($target); + } + if (!$smtp->_RCPT("TO:" . $rcpt_addr . $rcpt_opts)) { + syslog ('err', "smtp error - got: %s %s", $smtp->code, scalar($smtp->message)); + die "smtp to: ERROR"; + } } # Output the head: