Server IP : 85.214.239.14 / Your IP : 3.128.95.37 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/2/root/usr/share/perl5/Amavis/ |
Upload File : |
# SPDX-License-Identifier: GPL-2.0-or-later package Amavis::Out; use strict; use re 'taint'; BEGIN { require Exporter; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION); $VERSION = '2.412'; @ISA = qw(Exporter); @EXPORT = qw(&mail_dispatch); } use Amavis::Conf qw(:platform :confvars c cr ca); use Amavis::Out::EditHeader; use Amavis::Util qw(ll do_log); sub mail_dispatch($$$;$) { my($msginfo, $initial_submission, $dsn_per_recip_capable, $filter) = @_; my $tmp_hdr_edits; my $saved_hdr_edits = $msginfo->header_edits; if (!c('enable_dkim_signing')) { # no signing } elsif ($initial_submission && $initial_submission eq 'Quar') { # do not attempt to sign messages on their way to a quarantine } else { # generate and add DKIM signatures my(@signatures) = Amavis::DKIM::dkim_make_signatures($msginfo,0); if (@signatures) { $msginfo->dkim_signatures_new(\@signatures); if (!defined($tmp_hdr_edits)) { $tmp_hdr_edits = Amavis::Out::EditHeader->new; $tmp_hdr_edits->inherit_header_edits($saved_hdr_edits); } for my $signature (@signatures) { my $s = $signature->as_string; local($1); $s =~ s{\015\012}{\n}gs; $s =~ s{\n+\z}{}gs; $s =~ s/^((?:DKIM|DomainKey)-Signature)://si; $tmp_hdr_edits->prepend_header($1, $s, 2); } if (c('enable_dkim_verification') && grep($_->recip_is_local, @{$msginfo->per_recip_data})) { # it is too late to split a message now, add the A-R header field # if at least one recipient is local my $allowed_hdrs = cr('allowed_added_header_fields'); if ($allowed_hdrs && $allowed_hdrs->{lc('Authentication-Results')}) { for my $h (Amavis::DKIM::generate_authentication_results( $msginfo, 0, \@signatures)) { $tmp_hdr_edits->prepend_header('Authentication-Results', $h, 1); } } } } $msginfo->header_edits($tmp_hdr_edits) if defined $tmp_hdr_edits; } my $any_deliveries = 0; my $per_recip_data = $msginfo->per_recip_data; my $num_recips_notdone = scalar(grep(!$_->recip_done && (!$filter || &$filter($_)), @$per_recip_data)); while ($num_recips_notdone > 0) { # a delivery method may be a scalar of a form protocol:socket_specs, or # a listref of such elements; if a list is provided, it is expected that # each entry will be using the same protocol name, otherwise behaviour # is unspecified - so just obtain the protocol name from the first entry # my(%protocols, $any_tempfail); for my $r (@$per_recip_data) { if (!$dsn_per_recip_capable) { my $recip_smtp_response = $r->recip_smtp_response; # any 4xx code ? if (defined($recip_smtp_response) && $recip_smtp_response =~ /^4/) { $any_tempfail = $recip_smtp_response . ' (' . $r->recip_addr . ')'; } } if (!$r->recip_done && (!$filter || &$filter($r))) { my $proto_sockname = $r->delivery_method; defined $proto_sockname or die "mail_dispatch: undefined delivery_method"; !ref $proto_sockname || ref $proto_sockname eq 'ARRAY' or die "mail_dispatch: not a scalar or array ref: $proto_sockname"; for (ref $proto_sockname ? @$proto_sockname : $proto_sockname) { local($1); if (/^([a-z][a-z0-9.+-]*):/si) { $protocols{lc($1)} = 1 } else { die "mail_dispatch: no recognized protocol name: $_" } } } } my(@unknown) = grep(!/^(?:smtp|lmtp|pipe|bsmtp|sql|local)\z/i, keys %protocols); !@unknown or die "mail_dispatch: unknown protocol: ".join(', ',@unknown); if (!$dsn_per_recip_capable && defined $any_tempfail) { do_log(0, "temporary failures, giving up further deliveries: %s", $any_tempfail); my $smtp_resp = "451 4.5.0 Giving up due to previous temporary failures, id=" . $msginfo->log_id; # flag the remaining undelivered recipients as temporary failures for my $r (@$per_recip_data) { next if $r->recip_done; $r->recip_smtp_response($smtp_resp); $r->recip_done(1); } last; } # do one protocol per iteration only, so that we can bail out # as soon as some 4xx temporary failure is detected, avoiding # further deliveries which would lead to duplicate deliveries # if ($protocols{'smtp'} || $protocols{'lmtp'}) { require Amavis::Out::SMTP; Amavis::Out::SMTP::mail_via_smtp(@_); $any_deliveries = 1; # approximation, will do for the time being } elsif ($protocols{'local'}) { require Amavis::Out::Local; Amavis::Out::Local::mail_to_local_mailbox(@_); $any_deliveries = 1; # approximation, will do for the time being } elsif ($protocols{'pipe'}) { require Amavis::Out::Pipe; Amavis::Out::Pipe::mail_via_pipe(@_); $any_deliveries = 1; # approximation, will do for the time being } elsif ($protocols{'bsmtp'}) { require Amavis::Out::BSMTP; Amavis::Out::BSMTP::mail_via_bsmtp(@_); $any_deliveries = 1; # approximation, will do for the time being } elsif ($protocols{'sql'}) { $Amavis::extra_code_sql_quar && $Amavis::sql_storage or die "SQL quarantine code not enabled (1)"; Amavis::Out::SQL::Quarantine::mail_via_sql( $Amavis::sql_dataset_conn_storage, @_); $any_deliveries = 1; # approximation, will do for the time being } # are we done yet? my $num_recips_notdone_after = scalar(grep(!$_->recip_done && (!$filter || &$filter($_)), @$per_recip_data)); if ($num_recips_notdone_after >= $num_recips_notdone) { do_log(-2, "TROUBLE: Number of recipients (%d) not reduced, ". "abandoning effort, proto: %s", $num_recips_notdone_after, join(', ', keys %protocols) ); last; } if ($num_recips_notdone_after > 0) { do_log(3, "Sent to %s recipients, %s still to go", $num_recips_notdone - $num_recips_notdone_after, $num_recips_notdone_after); } $num_recips_notdone = $num_recips_notdone_after; } # restore header edits if modified $msginfo->header_edits($saved_hdr_edits) if defined $tmp_hdr_edits; $any_deliveries; # (estimate) were any successful deliveries actually done? } 1;