From e908e9a691a80afac5e2a51f2b6e5e62949a0246 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Pialasse Date: Sun, 28 Apr 2024 23:46:26 -0400 Subject: [PATCH] * Sun Apr 28 2024 Jean-Philippe Pialasse 1.0.0-1.sme - upgrade to last version [SME: 11802] - reapply our specific patches, rewrite them if necessary added qpsmtpd-0.96-bz12450-auth_imap-perport.patch from SME10 - apply last fixes in git since v 1.0.0 postfix: avoid logging full headers;Load plugins in qpsmtpd-forkserver; Fix received_line hook behaviour; Add missing use statement for NetAddr::IP --- qpsmtpd-0.95-allow_tls_proto_from_conf.patch | 56 ---------- qpsmtpd-0.95-spamassassin_size_limit.patch | 13 --- qpsmtpd-0.96-add_dmarc_result_notes.patch | 11 -- qpsmtpd-0.96-addr_defined_before_use.patch | 12 -- ...d-0.96-bz10387-load_plugins-on-start.patch | 12 -- qpsmtpd-0.96-bz12450-auth_imap-perport.patch | 74 +++++++++++++ ...pd-0.96-check_negative_karma_strikes.patch | 12 -- qpsmtpd-0.96-check_rua_is_defined.patch | 12 -- ...dont_log_credentials_except_in_debug.patch | 15 --- qpsmtpd-0.96-eval_dkim_policies.patch | 14 --- qpsmtpd-0.96-fix_dmarc_reject.patch | 62 ----------- qpsmtpd-0.96-fix_karma_tool_dir_path.patch | 12 -- qpsmtpd-0.96-karma_strikes.patch | 46 -------- qpsmtpd-0.96-karma_tlds_conf.patch | 86 --------------- qpsmtpd-0.96-spf_on_no_dmarc_policy.patch | 104 ------------------ qpsmtpd-0.96-store_original_plugin_name.patch | 12 -- qpsmtpd-0.96-uribl_data_post.patch | 20 ---- qpsmtpd-0.96-uribl_validate_domains.patch | 31 ------ qpsmtpd-0.96-warn_implicit_split.patch | 13 --- qpsmtpd-1.0.0-uribl_validate_domains.patch | 30 +++++ qpsmtpd-1.0.0.tar.gz | 3 + qpsmtpd-v1.0.0-20240428.patch | 53 +++++++++ qpsmtpd.spec | 67 ++++------- 23 files changed, 183 insertions(+), 587 deletions(-) delete mode 100644 qpsmtpd-0.95-allow_tls_proto_from_conf.patch delete mode 100644 qpsmtpd-0.95-spamassassin_size_limit.patch delete mode 100644 qpsmtpd-0.96-add_dmarc_result_notes.patch delete mode 100644 qpsmtpd-0.96-addr_defined_before_use.patch delete mode 100644 qpsmtpd-0.96-bz10387-load_plugins-on-start.patch create mode 100644 qpsmtpd-0.96-bz12450-auth_imap-perport.patch delete mode 100644 qpsmtpd-0.96-check_negative_karma_strikes.patch delete mode 100644 qpsmtpd-0.96-check_rua_is_defined.patch delete mode 100644 qpsmtpd-0.96-dont_log_credentials_except_in_debug.patch delete mode 100644 qpsmtpd-0.96-eval_dkim_policies.patch delete mode 100644 qpsmtpd-0.96-fix_dmarc_reject.patch delete mode 100644 qpsmtpd-0.96-fix_karma_tool_dir_path.patch delete mode 100644 qpsmtpd-0.96-karma_strikes.patch delete mode 100644 qpsmtpd-0.96-karma_tlds_conf.patch delete mode 100644 qpsmtpd-0.96-spf_on_no_dmarc_policy.patch delete mode 100644 qpsmtpd-0.96-store_original_plugin_name.patch delete mode 100644 qpsmtpd-0.96-uribl_data_post.patch delete mode 100644 qpsmtpd-0.96-uribl_validate_domains.patch delete mode 100644 qpsmtpd-0.96-warn_implicit_split.patch create mode 100644 qpsmtpd-1.0.0-uribl_validate_domains.patch create mode 100644 qpsmtpd-1.0.0.tar.gz create mode 100644 qpsmtpd-v1.0.0-20240428.patch diff --git a/qpsmtpd-0.95-allow_tls_proto_from_conf.patch b/qpsmtpd-0.95-allow_tls_proto_from_conf.patch deleted file mode 100644 index 998b27e..0000000 --- a/qpsmtpd-0.95-allow_tls_proto_from_conf.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.95/plugins/tls mezzanine_patched_qpsmtpd-0.95/plugins/tls ---- qpsmtpd-0.95/plugins/tls 2016-01-07 19:14:45.099736554 +0100 -+++ mezzanine_patched_qpsmtpd-0.95/plugins/tls 2016-01-07 19:14:30.152736181 +0100 -@@ -62,6 +62,14 @@ - and put a suitable string in config/tls_ciphers (e.g. "DEFAULT" or - "HIGH:MEDIUM") - -+=head1 SSL/TLS protocols versions -+ -+By default, SSLv2 and SSLv3 are not accepted, leaving only TLSv1, -+TLSv1.1 or TLSv1.2 enabled. You can customize this in config/tls_protocols -+For example, this will also disabled TLSv1, leaving only TLSv1.1 and TLSv1.2 -+ -+SSLv23:!SSLv2:!SSLv3:!TLSv1 -+ - =cut - - use strict; -@@ -94,6 +102,7 @@ - $self->tls_ca($ca); - $self->tls_dhparam($dhparam); - $self->tls_ciphers($self->qp->config('tls_ciphers') || 'HIGH'); -+ $self->tls_protocols($self->qp->config('tls_protocols') || 'SSLv23:!SSLv2:!SSLv3'); - - $self->log(LOGDEBUG, "ciphers: " . $self->tls_ciphers); - -@@ -102,7 +111,7 @@ - IO::Socket::SSL::SSL_Context->new( - # Disable SSLv2 and SSLv3 to avoid POODLE attacks. This is already - # the default in sufficiently recent versions of IO::Socket::SSL -- SSL_version => 'SSLv23:!SSLv3:!SSLv2', -+ SSL_version => $self->tls_protocols, - SSL_use_cert => 1, - SSL_cert_file => $self->tls_cert, - SSL_key_file => $self->tls_key, -@@ -226,6 +235,7 @@ - my $tlssocket = - IO::Socket::SSL->new_from_fd( - fileno(STDIN), '+>', -+ SSL_version => $self->tls_protocols, - SSL_use_cert => 1, - SSL_cert_file => $self->tls_cert, - SSL_key_file => $self->tls_key, -@@ -286,6 +296,12 @@ - $self->{_tls_ciphers}; - } - -+sub tls_protocols { -+ my $self = shift; -+ @_ and $self->{_tls_protocols} = shift; -+ $self->{_tls_protocols}; -+} -+ - sub ssl_context { - my $self = shift; - @_ and $self->{_ssl_ctx} = shift; diff --git a/qpsmtpd-0.95-spamassassin_size_limit.patch b/qpsmtpd-0.95-spamassassin_size_limit.patch deleted file mode 100644 index 719148e..0000000 --- a/qpsmtpd-0.95-spamassassin_size_limit.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.95/plugins/spamassassin mezzanine_patched_qpsmtpd-0.95/plugins/spamassassin ---- qpsmtpd-0.95/plugins/spamassassin 2015-02-11 23:00:25.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.95/plugins/spamassassin 2015-12-16 22:07:17.554311238 +0100 -@@ -172,7 +172,8 @@ - - return DECLINED if $self->is_immune(); - -- if ($transaction->data_size > 500_000) { -+ my $limit = $self->{_args}->{size_limit} || 500_000; -+ if ($transaction->data_size > $limit) { - $self->log(LOGINFO, - "skip, too large (" . $transaction->data_size . ")"); - return DECLINED; diff --git a/qpsmtpd-0.96-add_dmarc_result_notes.patch b/qpsmtpd-0.96-add_dmarc_result_notes.patch deleted file mode 100644 index 7263374..0000000 --- a/qpsmtpd-0.96-add_dmarc_result_notes.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/dmarc mezzanine_patched_qpsmtpd-0.96/plugins/dmarc ---- qpsmtpd-0.96/plugins/dmarc 2016-05-03 09:10:34.624577605 +0200 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/dmarc 2016-05-03 09:10:14.160581205 +0200 -@@ -154,6 +154,7 @@ - }; - }; - -+ $transaction->notes('dmarc_result', $dmarc->result); - my $disposition = $dmarc->result->disposition; - my $result = $dmarc->result->result; - my $auth_str = "dmarc=$result"; diff --git a/qpsmtpd-0.96-addr_defined_before_use.patch b/qpsmtpd-0.96-addr_defined_before_use.patch deleted file mode 100644 index f01c136..0000000 --- a/qpsmtpd-0.96-addr_defined_before_use.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur qpsmtpd-0.96/lib/Qpsmtpd.pm qpsmtpd-0.96_bz9460/lib/Qpsmtpd.pm ---- qpsmtpd-0.96/lib/Qpsmtpd.pm 2016-02-16 23:52:02.000000000 +0100 -+++ qpsmtpd-0.96_bz9460/lib/Qpsmtpd.pm 2016-05-16 11:52:07.041152848 +0200 -@@ -448,7 +448,7 @@ - sub address { - my $self = shift; - my $addr = Qpsmtpd::Address->new(@_); -- $addr->qp($self); -+ $addr->qp($self) if $addr; - return $addr; - } - diff --git a/qpsmtpd-0.96-bz10387-load_plugins-on-start.patch b/qpsmtpd-0.96-bz10387-load_plugins-on-start.patch deleted file mode 100644 index 63483cc..0000000 --- a/qpsmtpd-0.96-bz10387-load_plugins-on-start.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur --no-dereference qpsmtpd-0.96.old/qpsmtpd-forkserver qpsmtpd-0.96/qpsmtpd-forkserver ---- qpsmtpd-0.96.old/qpsmtpd-forkserver 2021-11-15 11:59:33.048000000 -0500 -+++ qpsmtpd-0.96/qpsmtpd-forkserver 2021-11-15 12:00:46.276000000 -0500 -@@ -193,7 +193,7 @@ - POSIX::setuid($quid) or die "unable to change uid: $!\n"; - $> = $quid; - --#$qpsmtpd->load_plugins; -+$qpsmtpd->load_plugins; - - foreach my $addr (@LISTENADDR) { - ::log(LOGINFO, "Listening on $addr->{addr}:$addr->{port}"); diff --git a/qpsmtpd-0.96-bz12450-auth_imap-perport.patch b/qpsmtpd-0.96-bz12450-auth_imap-perport.patch new file mode 100644 index 0000000..76598f5 --- /dev/null +++ b/qpsmtpd-0.96-bz12450-auth_imap-perport.patch @@ -0,0 +1,74 @@ +diff -Nur --no-dereference qpsmtpd-0.96.old/plugins/auth/auth_imap qpsmtpd-0.96/plugins/auth/auth_imap +--- qpsmtpd-0.96.old/plugins/auth/auth_imap 2016-02-16 17:52:02.000000000 -0500 ++++ qpsmtpd-0.96/plugins/auth/auth_imap 2023-12-18 12:14:23.581000000 -0500 +@@ -25,17 +25,30 @@ + relay or a primary mail server. The principal benefit is ease of adminstration when + an existing IMAP service is already established. + +-head1 AUTHOR Christopher Heschong ++=head1 AUTHOR Christopher Heschong + + Edits to add SSL support and updated for latest qpsmtpd version - James Turnbull + + =head1 COPYRIGHT AND LICENSE Copyright (c) 2004 Christopher Heschong + This plugin is licensed under the same terms as the qpsmtpd package itself. + Please see the LICENSE file included with qpsmtpd for details. ++ ++=head1 SYNOPSIS ++ ++In config/plugins: ++ ++ auth/auth_imap \ ++ enable_smtp no \ ++ enable_ssmtp yes + + =cut + + use Net::IMAP::Simple; ++use Qpsmtpd::Constants; ++ ++use Socket; ++use constant SMTP_PORT => getservbyname("smtp", "tcp") || 25; ++use constant SSMTP_PORT => getservbyname("ssmtp", "tcp") || 465; + + sub register { + my ($self, $qp, @args) = @_; +@@ -51,16 +64,35 @@ + if (@args > 1 and $args[1] =~ /^(\d+)$/) { + $self->{_imap_port} = $1; + } ++ if (@args > 2 and ($args[3] eq "enable_smtp" ) ) { ++ $self->{_enable_smtp}= $args[4] || 'no'; ++ } ++ if (@args > 4 and ( $args[5] eq "enable_ssmtp" )) { ++ $self->{_enable_ssmtp} = $args[6] || 'yes'; ++ } + $self->log(LOGWARN, "WARNING: Ignoring additional arguments.") +- if (@args > 2); ++ if (@args > 6); + } + else { + die("No IMAP server specified in plugins file."); + } + + # set any values that are not already +- $self->{_imap_server} ||= "127.0.0.1"; +- $self->{_imap_port} ||= 143; ++ $self->{_imap_server} ||= "127.0.0.1"; ++ $self->{_imap_port} ||= 143; ++ $self->{_enable_smtp} ||= 'no'; ++ $self->{_enable_ssmtp} ||= 'yes'; ++ ++ my $port = $ENV{PORT} || SMTP_PORT; ++ ++ if ($self->{_enable_smtp} ne 'yes' && ($port == SMTP_PORT || $port == 587)) { ++ $self->log(LOGDEBUG, "skip: enable_smtp=no"); ++ return 0; ++ } ++ if ($port == SSMTP_PORT && $self->{_enable_ssmtp} ne 'yes') { ++ $self->log(LOGDEBUG, "skip: enable_ssmtp=no"); ++ return 0; ++ }; + + $self->register_hook("auth-login", "auth_imap"); + $self->register_hook("auth-plain", "auth_imap"); diff --git a/qpsmtpd-0.96-check_negative_karma_strikes.patch b/qpsmtpd-0.96-check_negative_karma_strikes.patch deleted file mode 100644 index b853b9a..0000000 --- a/qpsmtpd-0.96-check_negative_karma_strikes.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur qpsmtpd-0.96/plugins/karma qpsmtpd-0.96_bz9462/plugins/karma ---- qpsmtpd-0.96/plugins/karma 2016-05-09 23:56:51.145450697 +0200 -+++ qpsmtpd-0.96_bz9462/plugins/karma 2016-05-09 23:57:34.484446254 +0200 -@@ -449,7 +449,7 @@ - my $history = ($nice || 0) - $naughty; - my $log_mess = ''; - -- if ($karma <= $self->{_args}{strikes}) { # Enough negative strikes ? -+ if ($karma <= -$self->{_args}{strikes}) { # Enough negative strikes ? - $history--; - my $negative_limit = 0 - $self->{_args}{negative}; - if ($history <= $negative_limit) { diff --git a/qpsmtpd-0.96-check_rua_is_defined.patch b/qpsmtpd-0.96-check_rua_is_defined.patch deleted file mode 100644 index a6610e7..0000000 --- a/qpsmtpd-0.96-check_rua_is_defined.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur qpsmtpd-0.96/plugins/dmarc qpsmtpd-0.96_bz9206/plugins/dmarc ---- qpsmtpd-0.96/plugins/dmarc 2016-05-28 10:29:34.469470149 +0200 -+++ qpsmtpd-0.96_bz9206/plugins/dmarc 2016-05-28 10:33:36.482470978 +0200 -@@ -145,7 +145,7 @@ - my $pol; - eval { $pol = $dmarc->result->published; }; - if ( $self->{_args}{reporting} && $pol ) { -- if ( $dmarc->has_valid_reporting_uri($pol->rua) ) { -+ if ( $pol->rua && $dmarc->has_valid_reporting_uri($pol->rua) ) { - eval { $dmarc->save_aggregate(); }; - $self->log(LOGERROR, $@ ) if $@; - } diff --git a/qpsmtpd-0.96-dont_log_credentials_except_in_debug.patch b/qpsmtpd-0.96-dont_log_credentials_except_in_debug.patch deleted file mode 100644 index 4bf8821..0000000 --- a/qpsmtpd-0.96-dont_log_credentials_except_in_debug.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/lib/Qpsmtpd/TcpServer.pm mezzanine_patched_qpsmtpd-0.96/lib/Qpsmtpd/TcpServer.pm ---- qpsmtpd-0.96/lib/Qpsmtpd/TcpServer.pm 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/lib/Qpsmtpd/TcpServer.pm 2016-04-15 19:13:13.873874838 +0200 -@@ -120,7 +120,10 @@ - while () { - alarm 0; - $_ =~ s/\r?\n$//s; # advanced chomp -- $self->log(LOGINFO, "dispatching $_"); -+ my $log = $_; -+ $log =~ s/AUTH PLAIN (.*)/AUTH PLAIN / -+ unless ($self->config('loglevel') || '6') >= 7; -+ $self->log(LOGINFO, "dispatching $log"); - $self->connection->notes('original_string', $_); - defined $self->dispatch(split / +/, $_, 2) - or $self->respond(502, "command unrecognized: '$_'"); diff --git a/qpsmtpd-0.96-eval_dkim_policies.patch b/qpsmtpd-0.96-eval_dkim_policies.patch deleted file mode 100644 index 96a0726..0000000 --- a/qpsmtpd-0.96-eval_dkim_policies.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -Nur qpsmtpd-0.96/plugins/dkim qpsmtpd-0.96_bz9480/plugins/dkim ---- qpsmtpd-0.96/plugins/dkim 2016-07-05 22:08:55.700102610 +0200 -+++ qpsmtpd-0.96_bz9480/plugins/dkim 2016-07-05 22:11:51.485075880 +0200 -@@ -262,7 +262,9 @@ - push @data, "selector: " . $dkim->signature->selector if $dkim->signature; - push @data, "result: " . $dkim->result_detail if $dkim->result_detail; - -- foreach my $policy ($dkim->policies) { -+ my @policies = eval { $dkim->policies }; -+ -+ foreach my $policy (@policies) { - next if !$policy; - push @data, "policy: " . $policy->as_string; - push @data, "name: " . $policy->name; diff --git a/qpsmtpd-0.96-fix_dmarc_reject.patch b/qpsmtpd-0.96-fix_dmarc_reject.patch deleted file mode 100644 index 27399d0..0000000 --- a/qpsmtpd-0.96-fix_dmarc_reject.patch +++ /dev/null @@ -1,62 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/docs/hooks.md mezzanine_patched_qpsmtpd-0.96/docs/hooks.md ---- qpsmtpd-0.96/docs/hooks.md 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/docs/hooks.md 2016-05-03 21:56:38.216306190 +0200 -@@ -343,26 +343,20 @@ - - The `data_post_headers` hook is called after the client sends the final .\r\n of - a message and before the message is processed by `data_post`. This hook is --primarily used by plugins that insert new headers (ex: Received-SPF) and/or -+used by plugins that insert new headers (ex: Received-SPF) and/or - modify headers such as appending to Authentication-Results (SPF, DKIM, DMARC). - - When it is desirable to have these header modifications evaluated by filtering - software (spamassassin, dspam, etc.) running on `data_post`, this hook should be - used instead of `data_post`. - --Allowed return codes are -- --- DENY -- -- Return a hard failure code -+Note that you cannot reject in this hook, use the data_post hook instead - --- DENYSOFT -- -- Return a soft failure code -+Allowed return codes are - --- DENY\_DISCONNECT / DENYSOFT\_DISCONNECT -+- DECLINED - -- as above but with disconnect -+ Do nothing - - ## hook\_data\_post - -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/dmarc mezzanine_patched_qpsmtpd-0.96/plugins/dmarc ---- qpsmtpd-0.96/plugins/dmarc 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/dmarc 2016-05-03 21:57:11.943312651 +0200 -@@ -102,6 +102,7 @@ - else { - $self->{_dmarc} = Mail::DMARC::PurePerl->new(); - $self->register_hook('data_post_headers', 'check_dmarc'); -+ $self->register_hook('data_post', 'reject_dmarc'); - }; - } - -@@ -189,6 +190,13 @@ - return DECLINED if $self->is_immune; - - $self->adjust_karma(-3); --# at what point do we reject? -- return $self->get_reject("failed DMARC policy"); -+ # Add a mark now so the data_post hook can do the real reject -+ $transaction->notes('reject_dmarc', '1'); -+} -+ -+sub reject_dmarc { -+ my ($self, $transaction) = @_; -+ return $self->get_reject("failed DMARC policy") -+ if ($transaction->notes('reject_dmarc')); -+ return DECLINED; - } diff --git a/qpsmtpd-0.96-fix_karma_tool_dir_path.patch b/qpsmtpd-0.96-fix_karma_tool_dir_path.patch deleted file mode 100644 index 8e05211..0000000 --- a/qpsmtpd-0.96-fix_karma_tool_dir_path.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/karma_tool mezzanine_patched_qpsmtpd-0.96/plugins/karma_tool ---- qpsmtpd-0.96/plugins/karma_tool 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/karma_tool 2016-05-04 22:22:03.913868169 +0200 -@@ -63,7 +63,7 @@ - my ( $self ) = @_; - return $self->{db} if $self->{db}; - $self->{db} = Qpsmtpd::DB->new( name => 'karma' ); -- $self->{db}->dir( -+ $self->{db}->candidate_dirs( - $self->{args}{db_dir}, - qw( /var/lib/qpsmtpd/karma ./var/db ./config . ) ); - my $path = $self->{db}->path; diff --git a/qpsmtpd-0.96-karma_strikes.patch b/qpsmtpd-0.96-karma_strikes.patch deleted file mode 100644 index dee1dc4..0000000 --- a/qpsmtpd-0.96-karma_strikes.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/karma mezzanine_patched_qpsmtpd-0.96/plugins/karma ---- qpsmtpd-0.96/plugins/karma 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/karma 2016-04-20 18:39:43.299979947 +0200 -@@ -50,6 +50,16 @@ - penalize a "mostly good" sender. Raising it to 2 reduces that possibility to - improbable. - -+=head2 strikes -+ -+How many strikes is needed to consider the mail nice or naughty. -+Various plugins can adjust the karma (see USING KARMA IN OTHER PLUGINS). -+For example, with the default value of 3, if the karma of this message is 3 -+or above, the mail is considered to be a nice one. If it's -3 or less, it's -+considered a naughty one. Between -2 and +2 it's neutral -+ -+Default: 3 -+ - =head2 penalty_days - - The number of days a naughty sender is refused connections. Use a decimal -@@ -238,6 +248,7 @@ - $self->log(LOGERROR, "Bad arguments") if @_ % 2; - $self->{_args} = {@_}; - $self->{_args}{negative} ||= 1; -+ $self->{_args}{strikes} ||= 3; - $self->{_args}{penalty_days} ||= 1; - $self->{_args}{reject_type} ||= 'disconnect'; - -@@ -428,7 +439,7 @@ - my $history = ($nice || 0) - $naughty; - my $log_mess = ''; - -- if ($karma < -2) { # they achieved at least 2 strikes -+ if ($karma <= $self->{_args}{strikes}) { # Enough negative strikes ? - $history--; - my $negative_limit = 0 - $self->{_args}{negative}; - if ($history <= $negative_limit) { -@@ -445,7 +456,7 @@ - $log_mess = "negative"; - } - } -- elsif ($karma > 2) { -+ elsif ($karma >= $self->{_args}{strikes}) { - $nice++; - $log_mess = "positive"; - } diff --git a/qpsmtpd-0.96-karma_tlds_conf.patch b/qpsmtpd-0.96-karma_tlds_conf.patch deleted file mode 100644 index 76be576..0000000 --- a/qpsmtpd-0.96-karma_tlds_conf.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/config.sample/karma_tlds mezzanine_patched_qpsmtpd-0.96/config.sample/karma_tlds ---- qpsmtpd-0.96/config.sample/karma_tlds 1970-01-01 01:00:00.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/config.sample/karma_tlds 2016-04-20 20:44:35.881444632 +0200 -@@ -0,0 +1,14 @@ -+# Karma to apply depending on the tld of the envelope sender -+# Used by the karma plugin -+# Warning: setting karma too low can blacklist the entire tld -+work:-4 -+rocks:-3 -+ninja:-3 -+info:-2 -+biz:-2 -+pw:-2 -+me:-1 -+us:-5 -+eu:-4 -+link:-3 -+science:-6 -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/karma mezzanine_patched_qpsmtpd-0.96/plugins/karma ---- qpsmtpd-0.96/plugins/karma 2016-04-20 20:44:38.326444593 +0200 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/karma 2016-04-20 19:18:31.922041433 +0200 -@@ -102,6 +102,20 @@ - - Adjust the quantity of logging for this plugin. See docs/logging.pod - -+=head1 CONFIG FILES -+ -+This plugin uses the following configuration files. All are optional. -+ -+=head2 karma_tlds -+ -+This file can contain semicolon separated tld and the corresponding -+karma adjustment to apply when the envelope sender match. It can be used to -+penalize "spammy" tlds, or to raise the karma from (mostly) good tlds. -+ -+jp:-4 -+ch:-3 -+fr:+1 -+ - =head1 BENEFITS - - Karma reduces the resources wasted by naughty mailers. When used with -@@ -352,18 +366,14 @@ - my $full_from = $self->connection->notes('envelope_from'); - $self->illegal_envelope_format( $full_from ); - -- my %spammy_tlds = ( -- map { $_ => 4 } qw/ info pw /, -- map { $_ => 3 } qw/ tw biz /, -- map { $_ => 2 } qw/ cl br fr be jp no se sg /, -- ); -- foreach my $tld ( keys %spammy_tlds ) { -+ my $karma_tlds = $self->get_karma_tlds() or return DECLINED; -+ foreach my $tld ( keys %$karma_tlds ) { - my $len = length $tld; -- my $score = $spammy_tlds{$tld} or next; -+ my $score = $karma_tlds->{$tld} or next; - $len ++; - if ( $sender->host && ".$tld" eq substr($sender->host,-$len,$len) ) { -- $self->log(LOGINFO, "penalizing .$tld envelope sender"); -- $self->adjust_karma(-$score); -+ $self->log(LOGINFO, "adjusting karma for .$tld envelope sender"); -+ $self->adjust_karma($score); - } - } - -@@ -479,6 +489,19 @@ - } - } - -+sub get_karma_tlds { -+ my $self = shift; -+ -+ my %karma_tlds = -+ map { (split /:/, $_, 2)[0, 1] } $self->qp->config('karma_tlds'); -+ if (!%karma_tlds) { -+ $self->log(LOGDEBUG, "no specific karma for tlds defined"); -+ return; -+ } -+ -+ return \%karma_tlds; -+} -+ - sub parse_db_record { - my ($self, $value) = @_; - diff --git a/qpsmtpd-0.96-spf_on_no_dmarc_policy.patch b/qpsmtpd-0.96-spf_on_no_dmarc_policy.patch deleted file mode 100644 index 8660b36..0000000 --- a/qpsmtpd-0.96-spf_on_no_dmarc_policy.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/sender_permitted_from mezzanine_patched_qpsmtpd-0.96/plugins/sender_permitted_from ---- qpsmtpd-0.96/plugins/sender_permitted_from 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/sender_permitted_from 2016-05-04 18:33:37.510387152 +0200 -@@ -37,6 +37,37 @@ - - SPF levels above 4 are for crusaders who don't mind rejecting some valid mail when the sending server administrator hasn't dotted his i's and crossed his t's. May the deities bless their obsessive little hearts. - -+=head2 no_dmarc_policy -+ -+When used with the dmarc plugin, you don't want sender_permitted_from to reject anything, because dmarc needs to check the sender's domain policy. -+So you'll most likely have reject 1. -+But then, if the sender's domain has no dmarc policy, you might want to reject solely based on SPF result. This is what this setting is for. A first hook runs at the mail stage and evaluate SPF. Then a second hook runs at the data_post stage (after dmarc), so you have a second chance to reject. -+ -+Like reject, you can set a value to indicate how agressive you want to be: -+ -+ 0 do not reject (default) -+ 1 reject if SPF record says 'fail' -+ 2 stricter reject. Also rejects 'softfail' -+ 3 reject 'neutral' -+ 4 reject if no SPF records, or a syntax error -+ -+Just like reject, the recommanded value is 1. 2 will be a bit more agressive. 3 and 4 will most likely reject some valid emails. -+ -+So, for example, you can use something like this: -+ -+sender_permetted_from reject 1 no_dmarc_policy 1 -+dkim reject 0 -+dmarc reject 1 reporting 1 -+ -+Note this setting will only have effect if: -+ -+ * dmarc plugin is used, and loaded after sender_permetted_from in your plugin's config -+ * the reject value is either 1 or 2 (meaning, no reject at the mail stage) -+ * dmarc ran with no error -+ * the sender's domain has no dmarc policy published (that means, no _dmarc DNS entry) -+ -+Note that if a domain has a dmarc "p=none" policy, then this setting has no effect. Only if there's no dmarc policy at all it'll be used. -+ - =head1 SEE ALSO - - http://spf.pobox.com/ -@@ -82,8 +113,10 @@ - if (!$self->{_args}{reject} && $self->qp->config('spfbehavior')) { - $self->{_args}{reject} = $self->qp->config('spfbehavior'); - } -+ $self->{_args}{no_dmarc_policy} ||= 0; - $self->register_hook('mail', 'evaluate_spf'); - $self->register_hook('data_post_headers', 'add_spf_header'); -+ $self->register_hook('data_post', 'no_dmarc_policy') if $self->{_args}{no_dmarc_policy} > 0; - } - - sub evaluate_spf { -@@ -202,6 +235,51 @@ - return DECLINED; - } - -+sub no_dmarc_policy { -+ my ($self, $transaction) = @_; -+ return DECLINED if $self->is_immune; -+ unless ($self->{_args}{no_dmarc_policy}){ -+ return DECLINED; -+ } -+ if ($transaction->notes('spfquery') && $transaction->notes('dmarc_result')){ -+ my $spf_result = $transaction->notes('spfquery')->code; -+ my $why = $transaction->notes('spfquery')->local_explanation; -+ my $dmarc_dispo = $transaction->notes('dmarc_result')->disposition; -+ return DECLINED unless $dmarc_dispo eq 'none'; -+ my $comment = ''; -+ if ($transaction->notes('dmarc_result')->reason && -+ $transaction->notes('dmarc_result')->reason->[0] && -+ $transaction->notes('dmarc_result')->reason->[0]->comment){ -+ $comment = $transaction->notes('dmarc_result')->reason->[0]->comment; -+ } -+ return DECLINED unless $comment eq 'no policy'; -+ # No SPF or syntaxe error: reject if no_dmarc_policy is at least 4 -+ if ((!$spf_result || $spf_result =~ m/(?:permerror|error|none)/) && $self->{_args}{no_dmarc_policy} >= 4){ -+ $self->log(LOGINFO, "fail, $spf_result, $why"); -+ return DENY, "SPF - $spf_result: $why"; -+ } -+ # All other reject levels require an SPF code -+ return DECLINED unless $spf_result; -+ # Neutral -+ if ($spf_result eq 'neutral' && $self->{_args}{no_dmarc_policy} >= 3){ -+ $self->log(LOGINFO, "fail, $spf_result, $why"); -+ return DENY, "SPF - $spf_result: $why"; -+ } -+ # Softfail -+ if ($spf_result eq 'softfail' && $self->{_args}{no_dmarc_policy} >= 2){ -+ $self->log(LOGINFO, "fail, $spf_result, $why"); -+ return DENY, "SPF - $spf_result: $why"; -+ } -+ # Fail -+ if ($spf_result eq 'fail' && $self->{_args}{no_dmarc_policy} >= 1){ -+ $self->log(LOGINFO, "fail, $spf_result, $why"); -+ return DENY, "SPF - $spf_result: $why"; -+ } -+ } -+ $self->log(LOGINFO, 'pass'); -+ return DECLINED; -+} -+ - sub handle_code_none { - my ($self, $reject, $why) = @_; - diff --git a/qpsmtpd-0.96-store_original_plugin_name.patch b/qpsmtpd-0.96-store_original_plugin_name.patch deleted file mode 100644 index 6174fbd..0000000 --- a/qpsmtpd-0.96-store_original_plugin_name.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/lib/Qpsmtpd/Plugin.pm mezzanine_patched_qpsmtpd-0.96/lib/Qpsmtpd/Plugin.pm ---- qpsmtpd-0.96/lib/Qpsmtpd/Plugin.pm 2016-04-25 18:16:52.626824508 +0200 -+++ mezzanine_patched_qpsmtpd-0.96/lib/Qpsmtpd/Plugin.pm 2016-04-25 18:16:24.785825492 +0200 -@@ -228,7 +228,7 @@ - # the naughty plugin will reject later - if ($reject eq 'naughty') { - $self->log(LOGINFO, "fail, NAUGHTY" . $log_mess); -- return $self->store_deferred_reject($smtp_mess); -+ return $self->store_deferred_reject('(' . $self->plugin_name . ') ' . $smtp_mess); - } - - # they asked for reject, we give them reject diff --git a/qpsmtpd-0.96-uribl_data_post.patch b/qpsmtpd-0.96-uribl_data_post.patch deleted file mode 100644 index ce6f0c2..0000000 --- a/qpsmtpd-0.96-uribl_data_post.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/uribl mezzanine_patched_qpsmtpd-0.96/plugins/uribl ---- qpsmtpd-0.96/plugins/uribl 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/uribl 2016-04-18 22:10:13.565072798 +0200 -@@ -271,6 +271,7 @@ - - if ($l =~ /(.*)=$/) { - push @qp_continuations, $1; -+ next; - } - elsif (@qp_continuations) { - $l = join('', @qp_continuations, $l); -@@ -498,7 +499,7 @@ - return \@matches; - } - --sub hook_data { -+sub hook_data_post { - my ($self, $transaction) = @_; - - return DECLINED if $self->is_immune(); diff --git a/qpsmtpd-0.96-uribl_validate_domains.patch b/qpsmtpd-0.96-uribl_validate_domains.patch deleted file mode 100644 index 4d8a947..0000000 --- a/qpsmtpd-0.96-uribl_validate_domains.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -Nur qpsmtpd-0.96/plugins/uribl qpsmtpd-0.96_bz9467/plugins/uribl ---- qpsmtpd-0.96/plugins/uribl 2016-07-11 22:28:55.105488861 +0200 -+++ qpsmtpd-0.96_bz9467/plugins/uribl 2016-07-11 22:32:14.607442677 +0200 -@@ -96,6 +96,9 @@ - - use Time::HiRes qw(time); - use IO::Select; -+use Data::Validate::Domain; -+ -+my $v = Data::Validate::Domain->new; - - # ccTLDs that allocate domain names within a strict two-level hierarchy, - # as in *.co.uk -@@ -348,7 +351,7 @@ - museum|name|net|org|pro|tel|travel| - [a-zA-Z]{2}) - )(?!\w) -- }gix -+ }gix && $v->is_domain($1) - ) - { - my $host = lc $1; -@@ -393,7 +396,7 @@ - museum|name|net|org|pro|tel|travel| - [a-zA-Z]{2}) - ) -- }gix -+ }gix && $v->is_domain($1) - ) - { - my $host = lc $1; diff --git a/qpsmtpd-0.96-warn_implicit_split.patch b/qpsmtpd-0.96-warn_implicit_split.patch deleted file mode 100644 index 7243882..0000000 --- a/qpsmtpd-0.96-warn_implicit_split.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -Nur -x '*.orig' -x '*.rej' qpsmtpd-0.96/plugins/helo mezzanine_patched_qpsmtpd-0.96/plugins/helo ---- qpsmtpd-0.96/plugins/helo 2016-02-16 23:52:02.000000000 +0100 -+++ mezzanine_patched_qpsmtpd-0.96/plugins/helo 2016-04-15 19:25:32.953870666 +0200 -@@ -521,7 +521,8 @@ - my ($dns_name, $helo_name) = @_; - - return if !$dns_name; -- return if split(/\./, $dns_name) < 2; # not a FQDN -+ my @dots = split(/\./, $dns_name); -+ return if scalar @dots < 2; # not a FQDN - - if ($dns_name eq $helo_name) { - $self->log(LOGDEBUG, "reverse name match"); diff --git a/qpsmtpd-1.0.0-uribl_validate_domains.patch b/qpsmtpd-1.0.0-uribl_validate_domains.patch new file mode 100644 index 0000000..c554ade --- /dev/null +++ b/qpsmtpd-1.0.0-uribl_validate_domains.patch @@ -0,0 +1,30 @@ +--- qpsmtpd/plugins/uribl.ori 2024-04-28 22:37:31.090000000 -0400 ++++ qpsmtpd/plugins/uribl 2024-04-28 22:40:04.111000000 -0400 +@@ -102,6 +102,9 @@ + + use Time::HiRes qw(time); + use IO::Select; ++use Data::Validate::Domain; ++ ++my $v = Data::Validate::Domain->new; + + # ccTLDs that allocate domain names within a strict two-level hierarchy, + # as in *.co.uk +@@ -358,7 +361,7 @@ + [a-zA-Z0-9](?:[a-zA-Z0-9\-]+\.)+ # hostname + (?:$tlds4regex|[a-zA-Z]{2}) # tld + )(?!\w) +- }gix ++ }gix && $v->is_domain($1) + ) + { + my $host = lc $1; +@@ -400,7 +403,7 @@ + [a-zA-Z0-9](?:[a-zA-Z0-9\-]+\.)+ # hostname + (?:$tlds4regex|[a-zA-Z]{2}) # tld + )(?!\w) +- }gix ++ }gix && $v->is_domain($1) + ) + { + my $host = lc $1; diff --git a/qpsmtpd-1.0.0.tar.gz b/qpsmtpd-1.0.0.tar.gz new file mode 100644 index 0000000..63a4230 --- /dev/null +++ b/qpsmtpd-1.0.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb7d7ca9cccefad09b21adbd624a34d5a2ed3b24b4e75abe270510a849a1c2c5 +size 377776 diff --git a/qpsmtpd-v1.0.0-20240428.patch b/qpsmtpd-v1.0.0-20240428.patch new file mode 100644 index 0000000..7be4323 --- /dev/null +++ b/qpsmtpd-v1.0.0-20240428.patch @@ -0,0 +1,53 @@ +diff --git a/lib/Qpsmtpd/Postfix.pm b/lib/Qpsmtpd/Postfix.pm +index 2946bba..6a98816 100644 +--- a/lib/Qpsmtpd/Postfix.pm ++++ b/lib/Qpsmtpd/Postfix.pm +@@ -206,7 +206,7 @@ sub inject_mail { + + my $hdr = $transaction->header->as_string; + for (split(/\r?\n/, $hdr)) { +- print STDERR "hdr: $_\n"; ++ # print STDERR "hdr: $_\n"; + $strm->print_msg_line($_); + } + $transaction->body_resetpos; +diff --git a/lib/Qpsmtpd/SMTP.pm b/lib/Qpsmtpd/SMTP.pm +index 70e25c5..913879d 100644 +--- a/lib/Qpsmtpd/SMTP.pm ++++ b/lib/Qpsmtpd/SMTP.pm +@@ -860,8 +860,8 @@ sub received_line { + my $header_str; + my ($rc, @received) = + $self->run_hooks("received_line", $smtp, $authheader, $sslheader); +- if ($rc == OK) { +- return join("\n", @received); ++ if ($rc == OK) { ++ $header_str = join("\n", @received); + } + else { # assume $rc == DECLINED + $header_str = +diff --git a/plugins/whitelist b/plugins/whitelist +index 3f9c10e..e79da8e 100644 +--- a/plugins/whitelist ++++ b/plugins/whitelist +@@ -99,6 +99,7 @@ use strict; + use warnings; + + use Qpsmtpd::Constants; ++use NetAddr::IP; + + my $VERSION = 0.02; + +diff --git a/qpsmtpd-forkserver b/qpsmtpd-forkserver +index f0f9e58..ef151a6 100755 +--- a/qpsmtpd-forkserver ++++ b/qpsmtpd-forkserver +@@ -193,7 +193,7 @@ POSIX::setgid($qgid) or die "unable to change gid: $!\n"; + POSIX::setuid($quid) or die "unable to change uid: $!\n"; + $> = $quid; + +-#$qpsmtpd->load_plugins; ++$qpsmtpd->load_plugins; + + foreach my $addr (@LISTENADDR) { + ::log(LOGINFO, "Listening on $addr->{addr}:$addr->{port}"); diff --git a/qpsmtpd.spec b/qpsmtpd.spec index 5bcd982..b2e3a31 100644 --- a/qpsmtpd.spec +++ b/qpsmtpd.spec @@ -1,8 +1,8 @@ # $Id: qpsmtpd.spec,v 1.30 2021/11/16 23:13:14 jpp Exp $ Name: qpsmtpd -Version: 0.96 -Release: 21%{?dist} +Version: 1.0.0 +Release: 1%{?dist} Summary: qpsmtpd + qpsmtpd-apache License: MIT Group: System Environment/Daemons @@ -26,33 +26,18 @@ Source4: in.qpsmtpd Source5: qpsmtpd.conf Source6: README.selinux -Patch1: qpsmtpd-0.95-spamassassin_size_limit.patch -Patch2: qpsmtpd-0.95-qpsmtpd_forserver_keepalive.patch -Patch3: qpsmtpd-0.95-notls_conf.patch -Patch4: qpsmtpd-0.95-allow_tls_proto_from_conf.patch -Patch5: qpsmtpd-0.96-set_hooks.patch -Patch6: qpsmtpd-0.96-warn_implicit_split.patch -Patch7: qpsmtpd-0.96-dont_log_credentials_except_in_debug.patch -Patch8: qpsmtpd-0.96-uribl_data_post.patch -Patch9: qpsmtpd-0.96-karma_strikes.patch -Patch10: qpsmtpd-0.96-more_badrcptto.patch -Patch11: qpsmtpd-0.96-karma_tlds_conf.patch -Patch12: qpsmtpd-0.96-store_original_plugin_name.patch -Patch13: qpsmtpd-0.96-fix_karma_tool_dir_path.patch -Patch14: qpsmtpd-0.96-dkim_no_sign_for_others_on_symlinks.patch -Patch15: qpsmtpd-0.96-fix_dmarc_reject.patch -Patch16: qpsmtpd-0.96-add_dmarc_result_notes.patch -Patch17: qpsmtpd-0.96-spf_on_no_dmarc_policy.patch -Patch18: qpsmtpd-0.96-check_negative_karma_strikes.patch -Patch19: qpsmtpd-0.96-addr_defined_before_use.patch -Patch20: qpsmtpd-0.96-check_rua_is_defined.patch -Patch21: qpsmtpd-0.96-remove_karma_rcpt_handler.patch -Patch22: qpsmtpd-0.96-eval_dkim_policies.patch -Patch23: qpsmtpd-0.96-uribl_validate_domains.patch -Patch24: qpsmtpd-0.96-bz10112-whitelist.patch -Patch25: qpsmtpd-0.96-SME10139-Message-Id.patch -Patch26: qpsmtpd-0.96-bz10290-spamassassin-fetchmail.patch -Patch27: qpsmtpd-0.96-bz10387-load_plugins-on-start.patch +Patch1: qpsmtpd-0.95-qpsmtpd_forserver_keepalive.patch +Patch2: qpsmtpd-0.95-notls_conf.patch +Patch3: qpsmtpd-0.96-set_hooks.patch +Patch4: qpsmtpd-0.96-more_badrcptto.patch +Patch5: qpsmtpd-0.96-dkim_no_sign_for_others_on_symlinks.patch +Patch6: qpsmtpd-0.96-remove_karma_rcpt_handler.patch +Patch7: qpsmtpd-1.0.0-uribl_validate_domains.patch +Patch8: qpsmtpd-0.96-bz10112-whitelist.patch +Patch9: qpsmtpd-0.96-SME10139-Message-Id.patch +Patch10: qpsmtpd-0.96-bz10290-spamassassin-fetchmail.patch +Patch11: qpsmtpd-0.96-bz12450-auth_imap-perport.patch +Patch12: qpsmtpd-v1.0.0-20240428.patch %description qpsmtpd is a flexible smtpd daemon written in Perl. Apart from the core @@ -75,6 +60,7 @@ that turns Apache into an SMTP server using Qpsmtpd. %prep %setup -q + %patch1 -p1 %patch2 -p1 %patch3 -p1 @@ -87,21 +73,6 @@ that turns Apache into an SMTP server using Qpsmtpd. %patch10 -p1 %patch11 -p1 %patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 %build CFLAGS="$RPM_OPT_FLAGS" perl Makefile.PL INSTALLDIRS="vendor" PREFIX="%{buildroot}%{_prefix}" @@ -174,6 +145,14 @@ fi %changelog +* Sun Apr 28 2024 Jean-Philippe Pialasse 1.0.0-1.sme +- upgrade to last version [SME: 11802] +- reapply our specific patches, rewrite them if necessary + added qpsmtpd-0.96-bz12450-auth_imap-perport.patch from SME10 +- apply last fixes in git since v 1.0.0 + postfix: avoid logging full headers;Load plugins in qpsmtpd-forkserver; + Fix received_line hook behaviour; Add missing use statement for NetAddr::IP + * Fri Jul 14 2023 BogusDateBot - Eliminated rpmbuild "bogus date" warnings due to inconsistent weekday, by assuming the date is correct and changing the weekday.