ci: working with Github Actions (#324)

- chore: update package metadata
- tests: delete dspam, disable DMARC, earlytalker, geoip, SPF
This commit is contained in:
Matt Simerson 2025-01-15 16:06:58 -08:00 committed by GitHub
parent d1043d0039
commit da5f60b962
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 86 additions and 162 deletions

30
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: CI Tests
on:
push:
pull_request:
jobs:
test:
strategy:
matrix:
os: ["ubuntu-latest"]
perl: ["5.16", "5.32"]
fail-fast: false
runs-on: ubuntu-latest
services:
redis:
image: redis
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 10
fetch-tags: true
- uses: shogo82148/actions-setup-perl@v1
with:
perl-version: ${{ matrix.perl }}
- run: cpanm --installdeps -n -f .
- run: cpanm --installdeps -n -f Mail::SPF Mail::DMARC GeoIP2 ClamAV::Client Redis
- run: prove -lv t

View File

@ -1,5 +1,5 @@
-i=4 # 4 space indentation (we used to use 2; in the future we'll use 4) -i=4 # 4 space indentation
-ci=2 # continuation indention -ci=2 # continuation indention
-bbt=0 # open code block curly braces -bbt=0 # open code block curly braces

View File

@ -1,11 +0,0 @@
language: perl
perl:
- "5.18"
- "5.16"
- "5.8"
before_install:
- cpanm -n Devel::Cover::Report::Coveralls
after_script:
- cover -test -report coveralls

View File

@ -1,8 +1,8 @@
.gitignore .gitignore
.travis.yml
bin/geolite-mirror-simple.pl bin/geolite-mirror-simple.pl
bin/install_deps.pl bin/install_deps.pl
Changes Changes
config.sample/add_geoip_headers
config.sample/badhelo config.sample/badhelo
config.sample/badmailfrom config.sample/badmailfrom
config.sample/badrcptto config.sample/badrcptto
@ -12,6 +12,7 @@ config.sample/dnsbl_zones
config.sample/flat_auth_pw config.sample/flat_auth_pw
config.sample/invalid_resolvable_fromhost config.sample/invalid_resolvable_fromhost
config.sample/IP config.sample/IP
config.sample/karma_tlds
config.sample/log2sql config.sample/log2sql
config.sample/logging config.sample/logging
config.sample/loglevel config.sample/loglevel
@ -43,6 +44,9 @@ lib/Qpsmtpd/Config.pm
lib/Qpsmtpd/ConfigServer.pm lib/Qpsmtpd/ConfigServer.pm
lib/Qpsmtpd/Connection.pm lib/Qpsmtpd/Connection.pm
lib/Qpsmtpd/Constants.pm lib/Qpsmtpd/Constants.pm
lib/Qpsmtpd/DB.pm
lib/Qpsmtpd/DB/File/DBM.pm
lib/Qpsmtpd/DB/Redis.pm
lib/Qpsmtpd/DSN.pm lib/Qpsmtpd/DSN.pm
lib/Qpsmtpd/Plugin.pm lib/Qpsmtpd/Plugin.pm
lib/Qpsmtpd/Postfix.pm lib/Qpsmtpd/Postfix.pm
@ -67,6 +71,7 @@ META.yml Module meta-data (added by MakeMaker)
plugins/auth/auth_checkpassword plugins/auth/auth_checkpassword
plugins/auth/auth_cvm_unix_local plugins/auth/auth_cvm_unix_local
plugins/auth/auth_flat_file plugins/auth/auth_flat_file
plugins/auth/auth_imap
plugins/auth/auth_ldap_bind plugins/auth/auth_ldap_bind
plugins/auth/auth_vpopmail plugins/auth/auth_vpopmail
plugins/auth/auth_vpopmail_sql plugins/auth/auth_vpopmail_sql
@ -154,8 +159,10 @@ run.tcpserver
STATUS STATUS
t/addresses.t t/addresses.t
t/auth.t t/auth.t
t/config/add_geoip_headers
t/config/badhelo t/config/badhelo
t/config/badrcptto t/config/badrcptto
t/config/content_log_enabled
t/config/dnsbl_allow t/config/dnsbl_allow
t/config/dnsbl_zones t/config/dnsbl_zones
t/config/flat_auth_pw t/config/flat_auth_pw
@ -174,6 +181,7 @@ t/misc.t
t/plugin_tests.t t/plugin_tests.t
t/plugin_tests/auth/auth_checkpassword t/plugin_tests/auth/auth_checkpassword
t/plugin_tests/auth/auth_flat_file t/plugin_tests/auth/auth_flat_file
t/plugin_tests/auth/auth_imap
t/plugin_tests/auth/auth_vpopmail t/plugin_tests/auth/auth_vpopmail
t/plugin_tests/auth/auth_vpopmail_sql t/plugin_tests/auth/auth_vpopmail_sql
t/plugin_tests/auth/auth_vpopmaild t/plugin_tests/auth/auth_vpopmaild
@ -182,11 +190,12 @@ t/plugin_tests/auth/authnull
t/plugin_tests/badmailfrom t/plugin_tests/badmailfrom
t/plugin_tests/badmailfromto t/plugin_tests/badmailfromto
t/plugin_tests/badrcptto t/plugin_tests/badrcptto
t/plugin_tests/content_log
t/plugin_tests/count_unrecognized_commands t/plugin_tests/count_unrecognized_commands
t/plugin_tests/dmarc t/plugin_tests/dmarc
t/plugin_tests/dnsbl t/plugin_tests/dnsbl
t/plugin_tests/dspam
t/plugin_tests/earlytalker t/plugin_tests/earlytalker
t/plugin_tests/fcrdns
t/plugin_tests/greylisting t/plugin_tests/greylisting
t/plugin_tests/headers t/plugin_tests/headers
t/plugin_tests/helo t/plugin_tests/helo
@ -202,6 +211,10 @@ t/plugin_tests/virus/clamdscan
t/qpsmtpd-address.t t/qpsmtpd-address.t
t/qpsmtpd-base.t t/qpsmtpd-base.t
t/qpsmtpd-config.t t/qpsmtpd-config.t
t/qpsmtpd-db-file-dbm.t
t/qpsmtpd-db-redis.t
t/qpsmtpd-db.t
t/qpsmtpd-plugin.t
t/qpsmtpd-smtp.t t/qpsmtpd-smtp.t
t/qpsmtpd.t t/qpsmtpd.t
t/rset.t t/rset.t

View File

@ -14,6 +14,7 @@ output/.*
^sqlite/ ^sqlite/
^output/ ^output/
^tmp/ ^tmp/
^t/tmp/
^blib/ ^blib/
^blibdirs$ ^blibdirs$
^Makefile$ ^Makefile$
@ -36,3 +37,4 @@ packaging
^supervise/ ^supervise/
^ssl/ ^ssl/
^t/config/greylist ^t/config/greylist
^.github

View File

@ -22,19 +22,20 @@ WriteMakefile(
'Test::More' => 0, 'Test::More' => 0,
'Test::Output' => 0, 'Test::Output' => 0,
# modules for specific features # modules for specific features
'Mail::SPF' => 1,
'Mail::DKIM' => 0.40, 'Mail::DKIM' => 0.40,
'Mail::DMARC' => 0,
'File::Tail' => 0, # log/summarize, log/watch 'File::Tail' => 0, # log/summarize, log/watch
'Time::TAI64' => 0, # log2sql 'Time::TAI64' => 0, # log2sql
'Redis' => 0,
# 'DBI' => 0, # auth_vpopmail_sql and # 'DBI' => 0, # auth_vpopmail_sql and
# 'DBD::mysql' => 0, # log2sql # 'DBD::mysql' => 0, # log2sql
# 'DBIx::Simple' => 0, # log2sql # 'DBIx::Simple' => 0, # log2sql
# modules that cause Travis build tests to fail 'Geo::IP' => 1,
# 'Mail::SpamAssassin' => 0, 'Mail::SpamAssassin' => 0,
# 'GeoIP2' => 2, 'Math::Complex' => 0, # geodesic distance in Geo::IP
# 'Geo::IP' => 1, 'PerlIO::gzip' => 0, # gunzip GeoIP databases
# 'Math::Complex' => 0, # geodesic distance in Geo::IP 'File::NFSLock' => 0,
# 'PerlIO::gzip' => 0, # gunzip GeoIP databases
# 'Mail::SPF' => 0,
}, },
ABSTRACT => 'Flexible smtpd daemon written in Perl', ABSTRACT => 'Flexible smtpd daemon written in Perl',
AUTHOR => 'Ask Bjoern Hansen <ask@develooper.com>', AUTHOR => 'Ask Bjoern Hansen <ask@develooper.com>',

View File

@ -46,11 +46,11 @@ run the following command in the /home/smtpd/ directory.
git clone git://github.com/smtpd/qpsmtpd.git git clone git://github.com/smtpd/qpsmtpd.git
Beware that the master branch might be unstable and unsuitable for anything Beware that the master branch might be unsuitable for anything
but development, so you might want to get a specific release, for but development, so you might want to get a specific release, for
example (after running git clone): example (after running git clone):
git checkout -b local_branch v0.93 git checkout -b local_branch v1.00
chmod o+t ~smtpd/qpsmtpd/ (or whatever directory you installed qpsmtpd chmod o+t ~smtpd/qpsmtpd/ (or whatever directory you installed qpsmtpd
in) to make supervise start the log process. in) to make supervise start the log process.
@ -91,9 +91,8 @@ information about what's missing) to the mailinglist or a PR to github.
# Better Performance # Better Performance
For better performance we recommend using "qpsmtpd-forkserver" or For better performance we recommend using "qpsmtpd-forkserver". If
running qpsmtpd under Apache 2.x. If you need extremely high you need extremely high concurrency use [Haraka](http://haraka.github.io/).
concurrency use [Haraka](http://haraka.github.io/).
# Plugins # Plugins

View File

@ -29,9 +29,6 @@ use English qw( -no_match_vars );
my $apps = [ my $apps = [
{ app => 'daemontools', info => { } }, { app => 'daemontools', info => { } },
{ app => 'ucspi-tcp', info => { } }, { app => 'ucspi-tcp', info => { } },
# { app => 'dspam', info => { } },
# { app => 'mysql-server-55', info => { port => 'mysql55-server', dport=>'mysql5', yum =>'mysql-server'} },
# { app => 'apache22' , info => { port => 'apache22', dport=>'', yum => 'httpd' } },
]; ];
$EUID == 0 or die "You will have better luck if you run me as root.\n"; $EUID == 0 or die "You will have better luck if you run me as root.\n";

View File

@ -4,7 +4,7 @@ use warnings;
use parent 'Qpsmtpd::DB'; use parent 'Qpsmtpd::DB';
BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File) } BEGIN { @AnyDBM_File::ISA = qw(DB_File GDBM_File NDBM_File SDBM_File ODBM_File) }
use AnyDBM_File; use AnyDBM_File;
use Fcntl qw(:DEFAULT :flock LOCK_EX LOCK_NB); use Fcntl qw(:DEFAULT :flock LOCK_EX LOCK_NB);

View File

@ -712,8 +712,6 @@ sub data_respond {
$header->extract(\@headers); $header->extract(\@headers);
#$header->add("X-SMTPD", "qpsmtpd/".$self->version.", http://smtpd.github.io/qpsmtpd/");
$buffer = ''; $buffer = '';
$self->transaction->header($header); $self->transaction->header($header);

View File

@ -7,26 +7,17 @@ use_ok('Test::Qpsmtpd');
ok(my ($smtpd, $conn) = Test::Qpsmtpd->new_conn(), "get new connection"); ok(my ($smtpd, $conn) = Test::Qpsmtpd->new_conn(), "get new connection");
is(($smtpd->command('EHLO localhost'))[0], 250, 'EHLO localhost'); is(($smtpd->command('EHLO localhost'))[0], 250, 'EHLO localhost');
is(($smtpd->command('MAIL FROM:<ask@perl.org>'))[0], is(($smtpd->command('MAIL FROM:<ask@perl.org>'))[0], 250, 'MAIL FROM:<ask@perl.org>');
250, 'MAIL FROM:<ask@perl.org>'); is($smtpd->transaction->sender->address, 'ask@perl.org', 'got the right sender');
is($smtpd->transaction->sender->address, 'ask@perl.org',
'got the right sender');
is(($smtpd->command('MAIL FROM:<ask @perl.org>'))[0], is(($smtpd->command('MAIL FROM:<ask @perl.org>'))[0], 250, 'MAIL FROM:<ask @perl.org>');
250, 'MAIL FROM:<ask @perl.org>'); is($smtpd->transaction->sender->address, 'ask @perl.org', 'got the right sender');
is($smtpd->transaction->sender->address,
'ask @perl.org',
'got the right sender');
is(($smtpd->command('MAIL FROM:ask@perl.org'))[0], is(($smtpd->command('MAIL FROM:ask@perl.org'))[0], 250, 'MAIL FROM:ask@perl.org');
250, 'MAIL FROM:ask@perl.org'); is($smtpd->transaction->sender->format, '<ask@perl.org>', 'got the right sender');
is($smtpd->transaction->sender->format,
'<ask@perl.org>', 'got the right sender');
is(($smtpd->command('MAIL FROM:ask@[1.2.3.4]'))[0], is(($smtpd->command('MAIL FROM:ask@[1.2.3.4]'))[0], 250, 'MAIL FROM:ask@[1.2.3.4]');
250, 'MAIL FROM:ask@[1.2.3.4]'); is($smtpd->transaction->sender->format, '<ask@[1.2.3.4]>', 'got the right sender');
is($smtpd->transaction->sender->format,
'<ask@[1.2.3.4]>', 'got the right sender');
my $command = 'MAIL FROM:<ask@perl.org> SIZE=1230'; my $command = 'MAIL FROM:<ask@perl.org> SIZE=1230';
is(($smtpd->command($command))[0], 250, $command); is(($smtpd->command($command))[0], 250, $command);

View File

@ -22,7 +22,7 @@ content_log
hosts_allow hosts_allow
# information plugins # information plugins
ident/geoip # ident/geoip
ident/p0f /tmp/.p0f_socket version 3 ident/p0f /tmp/.p0f_socket version 3
connection_time connection_time
fcrdns fcrdns
@ -37,7 +37,7 @@ parse_addr_withhelo
quit_fortune quit_fortune
# tls should load before count_unrecognized_commands # tls should load before count_unrecognized_commands
#tls #tls
earlytalker # earlytalker
count_unrecognized_commands 4 count_unrecognized_commands 4
relay relay
@ -66,7 +66,7 @@ rcpt_ok
headers days 5 reject_type temp require From,Date headers days 5 reject_type temp require From,Date
#domainkeys #domainkeys
dkim dkim
dmarc # dmarc
# content filters # content filters
virus/klez_filter virus/klez_filter
@ -83,11 +83,11 @@ spamassassin
# spamassassin reject_threshold 20 munge_subject_threshold 10 # spamassassin reject_threshold 20 munge_subject_threshold 10
# dspam must run after spamassassin for the learn_from_sa feature to work # dspam must run after spamassassin for the learn_from_sa feature to work
dspam learn_from_sa 7 reject 1 # dspam learn_from_sa 7 reject 1
# run the clamav virus checking plugin # run the clamav virus checking plugin
virus/clamav virus/clamav
virus/clamdscan # virus/clamdscan
# You must enable a queue plugin - see the options in plugins/queue/ - for example: # You must enable a queue plugin - see the options in plugins/queue/ - for example:

View File

@ -1,96 +0,0 @@
#!perl -w
use strict;
use warnings;
use Mail::Header;
use Qpsmtpd::Constants;
my $r;
sub register_tests {
my $self = shift;
$self->register_test('test_get_dspam_results');
$self->register_test('test_log_and_return');
$self->register_test('test_reject_type');
}
sub test_log_and_return {
my $self = shift;
my $transaction = $self->qp->transaction;
# reject not set
$self->{_args}{reject} = undef;
$transaction->notes('dspam', { class=> 'Spam', probability => .99, confidence=>1 } );
($r) = $self->log_and_return( $transaction );
cmp_ok( $r, '==', DECLINED, "($r)");
# reject exceeded
$self->{_args}{reject} = .95;
$transaction->notes('dspam', { class=> 'Spam', probability => .99, confidence=>1 } );
($r) = $self->log_and_return( $transaction );
cmp_ok( $r, '==', DENY, "($r)");
# below reject threshold
$transaction->notes('dspam', { class=> 'Spam', probability => .94, confidence=>1 } );
($r) = $self->log_and_return( $transaction );
cmp_ok( $r, '==', DECLINED, "($r)");
# requires agreement
$self->{_args}{reject} = 'agree';
$transaction->notes('spamassassin', { is_spam => 'Yes', score => 25 } );
$transaction->notes('dspam', { class=> 'Spam', probability => .90, confidence=>1 } );
($r) = $self->log_and_return( $transaction );
cmp_ok( $r, '==', DENY, "($r)");
# requires agreement
$transaction->notes('spamassassin', { is_spam => 'No', score => 15 } );
$transaction->notes('dspam', { class=> 'Spam', probability => .96, confidence=>1 } );
($r) = $self->log_and_return( $transaction );
cmp_ok( $r, '==', DECLINED, "($r)");
# requires agreement
$transaction->notes('spamassassin', { is_spam => 'Yes', score => 10 } );
$transaction->notes('dspam', { class=> 'Innocent', probability => .96, confidence=>1 } );
($r) = $self->log_and_return( $transaction );
cmp_ok( $r, '==', DECLINED, "($r)");
}
sub test_get_dspam_results {
my $self = shift;
my $transaction = $self->qp->transaction;
my $header = Mail::Header->new(Modify => 0, MailFrom => "COERCE");
$transaction->header( $header );
my @dspam_sample_headers = (
'Innocent, probability=0.0000, confidence=0.69',
'Innocent, probability=0.0000, confidence=0.85',
'Innocent, probability=0.0023, confidence=1.00',
'Spam, probability=1.0000, confidence=0.87',
'Spam, probability=1.0000, confidence=0.99',
'Whitelisted',
);
foreach my $header ( @dspam_sample_headers ) {
$transaction->header->delete('X-DSPAM-Result');
$transaction->header->add('X-DSPAM-Result', $header);
my $r = $self->get_dspam_results($transaction);
ok( ref $r, "r: ($header)" );
}
}
sub test_reject_type {
my $self = shift;
$self->{_args}{reject_type} = undef;
cmp_ok( $self->get_reject_type(), '==', DENY, "default");
$self->{_args}{reject_type} = 'temp';
cmp_ok( $self->get_reject_type(), '==', DENYSOFT, "defer");
$self->{_args}{reject_type} = 'disconnect';
cmp_ok( $self->get_reject_type(), '==', DENY_DISCONNECT, "disconnect");
}