* [pmg-devel] [PATCH pmg-api v2 0/4] add support for locally configured SA channels @ 2020-12-30 17:15 Stoiko Ivanov 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files Stoiko Ivanov ` (3 more replies) 0 siblings, 4 replies; 10+ messages in thread From: Stoiko Ivanov @ 2020-12-30 17:15 UTC (permalink / raw) To: pmg-devel v1->v2: * addressed Fabian's feedback (where appropriate more details are added to the individual patches) original cover-letter: With the recent announcement by KAM about the availability of a signed update channel for the KAM.cf (and other) ruleset [0], I thought that this might be a better suited way to provide regular updates to KAM.cf compared to the initial patch I sent some time ago [1]. The upside of using sa-update is that it does lint the ruleset before trying to pull the updates, and afterwards as well. GPG signed updates by KAM can also be considered production worthy. I tried to align the implementation to the channel.d mechanism mentioned in [0] since it seems: * somewhat sensible (these days my first choice would not be shell-code snippets) * one mechanism of potentially having a distributable way of providing the necessary configuration for an external SA ruleset - and the only one I'm aware of, which is not a self-tailored script The patchset was tested with the file provided at [0] on my test installation Should this be accepted we could ship /etc/mail/spamassassin/channel.d/KAM_channel.conf in proxmox-spamassassin [0] https://mcgrail.com/template/kam.cf_channel [1] https://lists.proxmox.com/pipermail/pmg-devel/2020-November/001397.html Stoiko Ivanov (4): add helper for parsing SA channel.d files api: spamassassin: read local channels api: spamassassin: update local channels pmg-daily: run sa-update for local channels src/PMG/API2/SpamAssassin.pm | 89 +++++++++++++++++++++--------------- src/PMG/Utils.pm | 58 +++++++++++++++++++++++ src/bin/pmg-daily | 9 +++- 3 files changed, 118 insertions(+), 38 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files 2020-12-30 17:15 [pmg-devel] [PATCH pmg-api v2 0/4] add support for locally configured SA channels Stoiko Ivanov @ 2020-12-30 17:15 ` Stoiko Ivanov 2021-01-15 8:21 ` Thomas Lamprecht 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels Stoiko Ivanov ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Stoiko Ivanov @ 2020-12-30 17:15 UTC (permalink / raw) To: pmg-devel RHEL/CentOS based SpamAssassin implementations ship an update script, which reads shell snippets from /etc/mail/spamassassin/channel.d/*.conf and uses the information there to update SA rules from the configured channels [0]. Noticed the existence of this directory/mechanism while reading the announcement of the updatechannel for the KAM ruleset [1]. Parsing the file as text, instead of sourcing it in a shell, since I hope that the channel files distributed don't rely on running commands to get the ruleset url and gpg key. [0] https://src.fedoraproject.org/rpms/spamassassin/blob/master/f/sa-update.cronscript [1] https://mcgrail.com/template/kam.cf_channel Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> --- v1->v2: * added anchors to all regex-matches src/PMG/Utils.pm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm index d3fae9e..ba6e839 100644 --- a/src/PMG/Utils.pm +++ b/src/PMG/Utils.pm @@ -1442,5 +1442,32 @@ sub domain_regex { return $regex; } +sub local_spamassassin_channels { + + my $res = []; + + my $local_channel_dir = '/etc/mail/spamassassin/channel.d/'; + my $read_sa_channel = sub { + my ($filename) = @_; + + my $channel_file = $local_channel_dir.$filename; + my $content = PVE::Tools::file_get_contents($channel_file); + my $channel = { + filename => $channel_file, + }; + + ($channel->{keyid}) = ($content =~ /^KEYID=([a-fA-F0-9]+)$/m); + die "no KEYID in $filename!\n" if !defined($channel->{keyid}); + ($channel->{channelurl}) = ($content =~ /^CHANNELURL=(.+)$/m); + die "no CHANNELURL in $filename!\n" if !defined($channel->{channelurl}); + ($channel->{gpgkey}) = ($content =~ /(?:^|\n)(-----BEGIN PGP PUBLIC KEY BLOCK-----.+-----END PGP PUBLIC KEY BLOCK-----)(?:\n|$)/s); + die "no GPG public key in $filename!\n" if !defined($channel->{gpgkey}); + + push(@$res, $channel); + }; + + PVE::Tools::dir_glob_foreach($local_channel_dir, '.*\.conf', $read_sa_channel); + return $res; +} 1; -- 2.20.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files Stoiko Ivanov @ 2021-01-15 8:21 ` Thomas Lamprecht 0 siblings, 0 replies; 10+ messages in thread From: Thomas Lamprecht @ 2021-01-15 8:21 UTC (permalink / raw) To: Stoiko Ivanov, pmg-devel On 30.12.20 18:15, Stoiko Ivanov wrote: > RHEL/CentOS based SpamAssassin implementations ship an update script, > which reads shell snippets from > /etc/mail/spamassassin/channel.d/*.conf and uses the information there > to update SA rules from the configured channels [0]. > > Noticed the existence of this directory/mechanism while reading the > announcement of the updatechannel for the KAM ruleset [1]. > > Parsing the file as text, instead of sourcing it in a shell, since I > hope that the channel files distributed don't rely on running commands > to get the ruleset url and gpg key. I'd like to have a, at least minimal, test for new parsers. Ideally a OK one and problematic one per success or error condition, respectively. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels 2020-12-30 17:15 [pmg-devel] [PATCH pmg-api v2 0/4] add support for locally configured SA channels Stoiko Ivanov 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files Stoiko Ivanov @ 2020-12-30 17:15 ` Stoiko Ivanov 2021-01-15 10:02 ` Thomas Lamprecht 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 3/4] api: spamassassin: update " Stoiko Ivanov 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 4/4] pmg-daily: run sa-update for " Stoiko Ivanov 3 siblings, 1 reply; 10+ messages in thread From: Stoiko Ivanov @ 2020-12-30 17:15 UTC (permalink / raw) To: pmg-devel Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> --- v1->v2: * changed the transliteration (tr///) to an equivalent more common s/// src/PMG/API2/SpamAssassin.pm | 83 +++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/src/PMG/API2/SpamAssassin.pm b/src/PMG/API2/SpamAssassin.pm index eab02d9..6b9f8f9 100644 --- a/src/PMG/API2/SpamAssassin.pm +++ b/src/PMG/API2/SpamAssassin.pm @@ -80,50 +80,65 @@ __PACKAGE__->register_method({ my ($param) = @_; my $saversion = $Mail::SpamAssassin::VERSION; - my $channelfile = "/var/lib/spamassassin/$saversion/updates_spamassassin_org.cf"; + my $sa_update_dir = "/var/lib/spamassassin/$saversion/"; + + my $check_channel = sub { + my ($channel) = @_; + + # see sa-update source: + my $channel_file_base = $channel; + $channel_file_base =~ s/[^A-Za-z0-9-]+/_/g; + my $channelfile = "${sa_update_dir}${channel_file_base}.cf"; + + my $mtime = -1; + my $version = -1; + my $newversion = -1; + + if (-f $channelfile) { + # stat metadata cf file + $mtime = (stat($channelfile))[9]; # 9 is mtime + + # parse version from metadata cf file + my $metadata = PVE::Tools::file_read_firstline($channelfile); + if ($metadata =~ m/\s([0-9]+)$/) { + $version = $1; + } else { + warn "invalid metadata in '$channelfile'\n"; + } + } + # call sa-update to see if updates are available - my $mtime = -1; - my $version = -1; - my $newversion = -1; + my $cmd = "$SAUPDATE -v --checkonly --channel $channel"; + PVE::Tools::run_command($cmd, noerr => 1, logfunc => sub { + my ($line) = @_; - if (-f $channelfile) { - # stat metadata cf file - $mtime = (stat($channelfile))[9]; # 9 is mtime + if ($line =~ m/Update available for channel \S+: -?[0-9]+ -> ([0-9]+)/) { + $newversion = $1; + } + }); - # parse version from metadata cf file - my $metadata = PVE::Tools::file_read_firstline($channelfile); - if ($metadata =~ m/\s([0-9]+)$/) { - $version = $1; - } else { - warn "invalid metadata in '$channelfile'\n"; - } - } - # call sa-update to see if updates are available + my $result = { + channel => $channel, + }; - my $cmd = "$SAUPDATE -v --checkonly"; - PVE::Tools::run_command($cmd, noerr => 1, logfunc => sub { - my ($line) = @_; + $result->{version} = $version if $version > -1; + $result->{update_version} = $newversion if $newversion > -1; + $result->{last_updated} = $mtime if $mtime > -1; - if ($line =~ m/Update available for channel \S+: -?[0-9]+ -> ([0-9]+)/) { - $newversion = $1; + if ($newversion > $version) { + $result->{update_avail} = 1; + } else { + $result->{update_avail} = 0; } - }); - - my $result = { - channel => 'updates.spamassassin.org', + return $result; }; - $result->{version} = $version if $version > -1; - $result->{update_version} = $newversion if $newversion > -1; - $result->{last_updated} = $mtime if $mtime > -1; + my @channels = ('updates.spamassassin.org'); - if ($newversion > $version) { - $result->{update_avail} = 1; - } else { - $result->{update_avail} = 0; - } + my $localchannels = PMG::Utils::local_spamassassin_channels(); + push(@channels, map { $_->{channelurl} } @$localchannels); - return [$result]; + return [ map { $check_channel->($_) } @channels]; }}); __PACKAGE__->register_method({ -- 2.20.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels Stoiko Ivanov @ 2021-01-15 10:02 ` Thomas Lamprecht 2021-01-18 19:47 ` Stoiko Ivanov 0 siblings, 1 reply; 10+ messages in thread From: Thomas Lamprecht @ 2021-01-15 10:02 UTC (permalink / raw) To: Stoiko Ivanov, pmg-devel On 30.12.20 18:15, Stoiko Ivanov wrote: > Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> > --- > v1->v2: > * changed the transliteration (tr///) to an equivalent more common s/// > > src/PMG/API2/SpamAssassin.pm | 83 +++++++++++++++++++++--------------- > 1 file changed, 49 insertions(+), 34 deletions(-) > > diff --git a/src/PMG/API2/SpamAssassin.pm b/src/PMG/API2/SpamAssassin.pm > index eab02d9..6b9f8f9 100644 > --- a/src/PMG/API2/SpamAssassin.pm > +++ b/src/PMG/API2/SpamAssassin.pm > @@ -80,50 +80,65 @@ __PACKAGE__->register_method({ > my ($param) = @_; > > my $saversion = $Mail::SpamAssassin::VERSION; > - my $channelfile = "/var/lib/spamassassin/$saversion/updates_spamassassin_org.cf"; > + my $sa_update_dir = "/var/lib/spamassassin/$saversion/"; > + > + my $check_channel = sub { > + my ($channel) = @_; > + > + # see sa-update source: > + my $channel_file_base = $channel; > + $channel_file_base =~ s/[^A-Za-z0-9-]+/_/g; > + my $channelfile = "${sa_update_dir}${channel_file_base}.cf"; > + > + my $mtime = -1; > + my $version = -1; > + my $newversion = -1; > + > + if (-f $channelfile) { > + # stat metadata cf file > + $mtime = (stat($channelfile))[9]; # 9 is mtime > + > + # parse version from metadata cf file > + my $metadata = PVE::Tools::file_read_firstline($channelfile); > + if ($metadata =~ m/\s([0-9]+)$/) { > + $version = $1; > + } else { > + warn "invalid metadata in '$channelfile'\n"; I know it was already there, but this mayresults in a undef comparison when checking `if ($newversion > $version) {` below. I'd do a separate followup with that being fixed, e.g., by either prepending the if check with a `!defined($version) || ...` check or setting it to -1000 or so. > + } > + } > + # call sa-update to see if updates are available > > - my $mtime = -1; > - my $version = -1; > - my $newversion = -1; > + my $cmd = "$SAUPDATE -v --checkonly --channel $channel"; > + PVE::Tools::run_command($cmd, noerr => 1, logfunc => sub { > + my ($line) = @_; > > - if (-f $channelfile) { > - # stat metadata cf file > - $mtime = (stat($channelfile))[9]; # 9 is mtime > + if ($line =~ m/Update available for channel \S+: -?[0-9]+ -> ([0-9]+)/) { > + $newversion = $1; > + } > + }); > > - # parse version from metadata cf file > - my $metadata = PVE::Tools::file_read_firstline($channelfile); > - if ($metadata =~ m/\s([0-9]+)$/) { > - $version = $1; > - } else { > - warn "invalid metadata in '$channelfile'\n"; > - } > - } > - # call sa-update to see if updates are available > + my $result = { > + channel => $channel, > + }; > > - my $cmd = "$SAUPDATE -v --checkonly"; > - PVE::Tools::run_command($cmd, noerr => 1, logfunc => sub { > - my ($line) = @_; > + $result->{version} = $version if $version > -1; > + $result->{update_version} = $newversion if $newversion > -1; > + $result->{last_updated} = $mtime if $mtime > -1; > > - if ($line =~ m/Update available for channel \S+: -?[0-9]+ -> ([0-9]+)/) { > - $newversion = $1; > + if ($newversion > $version) { > + $result->{update_avail} = 1; > + } else { > + $result->{update_avail} = 0; > } > - }); > - > - my $result = { > - channel => 'updates.spamassassin.org', > + return $result; > }; > > - $result->{version} = $version if $version > -1; > - $result->{update_version} = $newversion if $newversion > -1; > - $result->{last_updated} = $mtime if $mtime > -1; > + my @channels = ('updates.spamassassin.org'); > > - if ($newversion > $version) { > - $result->{update_avail} = 1; > - } else { > - $result->{update_avail} = 0; > - } > + my $localchannels = PMG::Utils::local_spamassassin_channels(); > + push(@channels, map { $_->{channelurl} } @$localchannels); > > - return [$result]; > + return [ map { $check_channel->($_) } @channels]; this reads a bit weird, but can be OK as $check_channel does seem to catch all actual possible errors. > }}); > > __PACKAGE__->register_method({ > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels 2021-01-15 10:02 ` Thomas Lamprecht @ 2021-01-18 19:47 ` Stoiko Ivanov 2021-01-19 9:10 ` Thomas Lamprecht 0 siblings, 1 reply; 10+ messages in thread From: Stoiko Ivanov @ 2021-01-18 19:47 UTC (permalink / raw) To: Thomas Lamprecht; +Cc: pmg-devel On Fri, 15 Jan 2021 11:02:42 +0100 Thomas Lamprecht <t.lamprecht@proxmox.com> wrote: > On 30.12.20 18:15, Stoiko Ivanov wrote: > > Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> > > --- > > v1->v2: > > * changed the transliteration (tr///) to an equivalent more common s/// > > > > src/PMG/API2/SpamAssassin.pm | 83 +++++++++++++++++++++--------------- > > 1 file changed, 49 insertions(+), 34 deletions(-) > > > > diff --git a/src/PMG/API2/SpamAssassin.pm b/src/PMG/API2/SpamAssassin.pm > > index eab02d9..6b9f8f9 100644 > > --- a/src/PMG/API2/SpamAssassin.pm > > +++ b/src/PMG/API2/SpamAssassin.pm > > @@ -80,50 +80,65 @@ __PACKAGE__->register_method({ > > my ($param) = @_; > > > > my $saversion = $Mail::SpamAssassin::VERSION; > > - my $channelfile = "/var/lib/spamassassin/$saversion/updates_spamassassin_org.cf"; > > + my $sa_update_dir = "/var/lib/spamassassin/$saversion/"; > > + > > + my $check_channel = sub { > > + my ($channel) = @_; > > + > > + # see sa-update source: > > + my $channel_file_base = $channel; > > + $channel_file_base =~ s/[^A-Za-z0-9-]+/_/g; > > + my $channelfile = "${sa_update_dir}${channel_file_base}.cf"; > > + > > + my $mtime = -1; > > + my $version = -1; $version gets initialized to -1 here... > > + my $newversion = -1; > > + > > + if (-f $channelfile) { > > + # stat metadata cf file > > + $mtime = (stat($channelfile))[9]; # 9 is mtime > > + > > + # parse version from metadata cf file > > + my $metadata = PVE::Tools::file_read_firstline($channelfile); > > + if ($metadata =~ m/\s([0-9]+)$/) { > > + $version = $1; > > + } else { > > + warn "invalid metadata in '$channelfile'\n"; > > I know it was already there, but this mayresults in a undef comparison > when checking `if ($newversion > $version) {` below. > I'd do a separate followup with that being fixed, e.g., by either prepending the > if check with a `!defined($version) || ...` check or setting it to -1000 or so. so it should not be undefined if the metadata is not matching? (I quickly tested in on my system - and if I drop the -1 I get a undef comparison in the logs - but it works as is) or am I missing something? > > > + } > > + } > > + # call sa-update to see if updates are available > > > > - my $mtime = -1; > > - my $version = -1; > > - my $newversion = -1; > > + my $cmd = "$SAUPDATE -v --checkonly --channel $channel"; > > + PVE::Tools::run_command($cmd, noerr => 1, logfunc => sub { > > + my ($line) = @_; > > > > - if (-f $channelfile) { > > - # stat metadata cf file > > - $mtime = (stat($channelfile))[9]; # 9 is mtime > > + if ($line =~ m/Update available for channel \S+: -?[0-9]+ -> ([0-9]+)/) { > > + $newversion = $1; > > + } > > + }); > > > > - # parse version from metadata cf file > > - my $metadata = PVE::Tools::file_read_firstline($channelfile); > > - if ($metadata =~ m/\s([0-9]+)$/) { > > - $version = $1; > > - } else { > > - warn "invalid metadata in '$channelfile'\n"; > > - } > > - } > > - # call sa-update to see if updates are available > > + my $result = { > > + channel => $channel, > > + }; > > > > - my $cmd = "$SAUPDATE -v --checkonly"; > > - PVE::Tools::run_command($cmd, noerr => 1, logfunc => sub { > > - my ($line) = @_; > > + $result->{version} = $version if $version > -1; > > + $result->{update_version} = $newversion if $newversion > -1; > > + $result->{last_updated} = $mtime if $mtime > -1; > > > > - if ($line =~ m/Update available for channel \S+: -?[0-9]+ -> ([0-9]+)/) { > > - $newversion = $1; > > + if ($newversion > $version) { > > + $result->{update_avail} = 1; > > + } else { > > + $result->{update_avail} = 0; > > } > > - }); > > - > > - my $result = { > > - channel => 'updates.spamassassin.org', > > + return $result; > > }; > > > > - $result->{version} = $version if $version > -1; > > - $result->{update_version} = $newversion if $newversion > -1; > > - $result->{last_updated} = $mtime if $mtime > -1; > > + my @channels = ('updates.spamassassin.org'); > > > > - if ($newversion > $version) { > > - $result->{update_avail} = 1; > > - } else { > > - $result->{update_avail} = 0; > > - } > > + my $localchannels = PMG::Utils::local_spamassassin_channels(); > > + push(@channels, map { $_->{channelurl} } @$localchannels); > > > > - return [$result]; > > + return [ map { $check_channel->($_) } @channels]; > > this reads a bit weird, but can be OK as $check_channel does seem to catch > all actual possible errors. > > > }}); > > > > __PACKAGE__->register_method({ > > > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels 2021-01-18 19:47 ` Stoiko Ivanov @ 2021-01-19 9:10 ` Thomas Lamprecht 0 siblings, 0 replies; 10+ messages in thread From: Thomas Lamprecht @ 2021-01-19 9:10 UTC (permalink / raw) To: Stoiko Ivanov; +Cc: pmg-devel On 18.01.21 20:47, Stoiko Ivanov wrote: >>> + my $check_channel = sub { >>> + my ($channel) = @_; >>> + >>> + # see sa-update source: >>> + my $channel_file_base = $channel; >>> + $channel_file_base =~ s/[^A-Za-z0-9-]+/_/g; >>> + my $channelfile = "${sa_update_dir}${channel_file_base}.cf"; >>> + >>> + my $mtime = -1; >>> + my $version = -1; > $version gets initialized to -1 here... >>> + my $newversion = -1; >>> + >>> + if (-f $channelfile) { >>> + # stat metadata cf file >>> + $mtime = (stat($channelfile))[9]; # 9 is mtime >>> + >>> + # parse version from metadata cf file >>> + my $metadata = PVE::Tools::file_read_firstline($channelfile); >>> + if ($metadata =~ m/\s([0-9]+)$/) { >>> + $version = $1; >>> + } else { >>> + warn "invalid metadata in '$channelfile'\n"; >> I know it was already there, but this mayresults in a undef comparison >> when checking `if ($newversion > $version) {` below. >> I'd do a separate followup with that being fixed, e.g., by either prepending the >> if check with a `!defined($version) || ...` check or setting it to -1000 or so. > so it should not be undefined if the metadata is not matching? > (I quickly tested in on my system - and if I drop the -1 I get a undef > comparison in the logs - but it works as is) > or am I missing something? > Ok, my bad then - sorry! ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pmg-devel] [PATCH pmg-api v2 3/4] api: spamassassin: update local channels 2020-12-30 17:15 [pmg-devel] [PATCH pmg-api v2 0/4] add support for locally configured SA channels Stoiko Ivanov 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files Stoiko Ivanov 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels Stoiko Ivanov @ 2020-12-30 17:15 ` Stoiko Ivanov 2021-01-15 9:58 ` Thomas Lamprecht 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 4/4] pmg-daily: run sa-update for " Stoiko Ivanov 3 siblings, 1 reply; 10+ messages in thread From: Stoiko Ivanov @ 2020-12-30 17:15 UTC (permalink / raw) To: pmg-devel This patch adds a helper to loop over all present Spamassassin channels files in /etc/mail/spamassassin/channel.d and: * import the included gpg key into sa-update's keyring * run sa-update for each channel separately the verbose argument of the helper is for reusing the code in pmg-daily (where we only want to log errors and be less informative) In order to only hardcode the path of sa-update once the definition was moved to PMG::Utils. The choice of invoking sa-update for each channel separately, instead of providing multiple '--channel' and '--gpgkey' options to a single command was made to prevent downloading signatures, which were signed by a key not configured for the channel. Importing gpg-keys is also done with individual sa-update invocations, because sa-update only imports the last present --import argument (wrong use of Getopt::Long) Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> --- src/PMG/API2/SpamAssassin.pm | 6 +++--- src/PMG/Utils.pm | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/PMG/API2/SpamAssassin.pm b/src/PMG/API2/SpamAssassin.pm index 6b9f8f9..fa638c4 100644 --- a/src/PMG/API2/SpamAssassin.pm +++ b/src/PMG/API2/SpamAssassin.pm @@ -11,15 +11,13 @@ use PVE::RESTHandler; use PMG::RESTEnvironment; use PVE::JSONSchema qw(get_standard_option); -use PMG::Utils; +use PMG::Utils qw($SAUPDATE); use PMG::Config; use Mail::SpamAssassin; use base qw(PVE::RESTHandler); -my $SAUPDATE = '/usr/bin/sa-update'; - __PACKAGE__->register_method ({ name => 'index', path => '', @@ -174,6 +172,8 @@ __PACKAGE__->register_method({ my $cmd = "$SAUPDATE -v"; PVE::Tools::run_command($cmd, noerr => 1); + + PMG::Utils::update_local_spamassassin_channels(1); }; return $rpcenv->fork_worker('saupdate', undef, $authuser, $realcmd); diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm index ba6e839..9992c64 100644 --- a/src/PMG/Utils.pm +++ b/src/PMG/Utils.pm @@ -44,6 +44,7 @@ use base 'Exporter'; our @EXPORT_OK = qw( postgres_admin_cmd +$SAUPDATE ); my $valid_pmg_realms = ['pam', 'pmg', 'quarantine']; @@ -1442,6 +1443,8 @@ sub domain_regex { return $regex; } +our $SAUPDATE = '/usr/bin/sa-update'; + sub local_spamassassin_channels { my $res = []; @@ -1470,4 +1473,32 @@ sub local_spamassassin_channels { return $res; } +sub update_local_spamassassin_channels { + my ($verbose) = @_; + # import all configured channel's gpg-keys to sa-update's keyring + my $localchannels = PMG::Utils::local_spamassassin_channels(); + for my $channel (@$localchannels) { + my $importcmd = [$SAUPDATE, '--import', $channel->{filename}]; + push @$importcmd, '-v' if $verbose; + + print "Importing gpg key from $channel->{filename}\n" if $verbose; + PVE::Tools::run_command($importcmd); + } + + my $fresh_updates = 0; + + for my $channel (@$localchannels) { + my $cmd = [$SAUPDATE, '--channel', $channel->{channelurl}, '--gpgkey', $channel->{keyid}]; + push @$cmd, '-v' if $verbose; + + print "Updating $channel->{channelurl}\n" if $verbose; + my $ret = PVE::Tools::run_command($cmd, noerr => 1); + die "updating $channel->{channelurl} failed - sa-update exited with $ret\n" if $ret >= 2; + + $fresh_updates = 1 if $ret == 0; + } + + return $fresh_updates +} + 1; -- 2.20.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [pmg-devel] [PATCH pmg-api v2 3/4] api: spamassassin: update local channels 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 3/4] api: spamassassin: update " Stoiko Ivanov @ 2021-01-15 9:58 ` Thomas Lamprecht 0 siblings, 0 replies; 10+ messages in thread From: Thomas Lamprecht @ 2021-01-15 9:58 UTC (permalink / raw) To: Stoiko Ivanov, pmg-devel On 30.12.20 18:15, Stoiko Ivanov wrote: > This patch adds a helper to loop over all present Spamassassin > channels files in /etc/mail/spamassassin/channel.d and: > * import the included gpg key into sa-update's keyring > * run sa-update for each channel separately > > the verbose argument of the helper is for reusing the code in > pmg-daily (where we only want to log errors and be less informative) > > In order to only hardcode the path of sa-update once the definition > was moved to PMG::Utils. > > The choice of invoking sa-update for each channel separately, instead > of providing multiple '--channel' and '--gpgkey' options to a single > command was made to prevent downloading signatures, which were signed > by a key not configured for the channel. > > Importing gpg-keys is also done with individual sa-update invocations, > because sa-update only imports the last present --import argument > (wrong use of Getopt::Long) > > Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> > --- > src/PMG/API2/SpamAssassin.pm | 6 +++--- > src/PMG/Utils.pm | 31 +++++++++++++++++++++++++++++++ > 2 files changed, 34 insertions(+), 3 deletions(-) > > diff --git a/src/PMG/API2/SpamAssassin.pm b/src/PMG/API2/SpamAssassin.pm > index 6b9f8f9..fa638c4 100644 > --- a/src/PMG/API2/SpamAssassin.pm > +++ b/src/PMG/API2/SpamAssassin.pm > @@ -11,15 +11,13 @@ use PVE::RESTHandler; > use PMG::RESTEnvironment; > use PVE::JSONSchema qw(get_standard_option); > > -use PMG::Utils; > +use PMG::Utils qw($SAUPDATE); can we please avoid the $SAUPDATE variable completely, either just directly use "sa-updates" with no path prefixed as this is much cleaner and safer to do, we have a sensible PATH env after all and having fixed paths made problems in the past (especially with usr-merge in built systems). If you must, add a sa_update helper method doing the actual run_command and some possible other common things, maybe even having a clean, not overly general, parameter signature. > use PMG::Config; > > use Mail::SpamAssassin; > > use base qw(PVE::RESTHandler); > > -my $SAUPDATE = '/usr/bin/sa-update'; > - > __PACKAGE__->register_method ({ > name => 'index', > path => '', > @@ -174,6 +172,8 @@ __PACKAGE__->register_method({ > my $cmd = "$SAUPDATE -v"; > > PVE::Tools::run_command($cmd, noerr => 1); > + > + PMG::Utils::update_local_spamassassin_channels(1); > }; > > return $rpcenv->fork_worker('saupdate', undef, $authuser, $realcmd); > diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm > index ba6e839..9992c64 100644 > --- a/src/PMG/Utils.pm > +++ b/src/PMG/Utils.pm > @@ -44,6 +44,7 @@ use base 'Exporter'; > > our @EXPORT_OK = qw( > postgres_admin_cmd > +$SAUPDATE > ); > > my $valid_pmg_realms = ['pam', 'pmg', 'quarantine']; > @@ -1442,6 +1443,8 @@ sub domain_regex { > return $regex; > } > > +our $SAUPDATE = '/usr/bin/sa-update'; > + > sub local_spamassassin_channels { > > my $res = []; > @@ -1470,4 +1473,32 @@ sub local_spamassassin_channels { > return $res; > } > > +sub update_local_spamassassin_channels { > + my ($verbose) = @_; > + # import all configured channel's gpg-keys to sa-update's keyring > + my $localchannels = PMG::Utils::local_spamassassin_channels(); > + for my $channel (@$localchannels) { > + my $importcmd = [$SAUPDATE, '--import', $channel->{filename}]; > + push @$importcmd, '-v' if $verbose; > + > + print "Importing gpg key from $channel->{filename}\n" if $verbose; > + PVE::Tools::run_command($importcmd); > + } > + > + my $fresh_updates = 0; > + > + for my $channel (@$localchannels) { > + my $cmd = [$SAUPDATE, '--channel', $channel->{channelurl}, '--gpgkey', $channel->{keyid}]; > + push @$cmd, '-v' if $verbose; > + > + print "Updating $channel->{channelurl}\n" if $verbose; > + my $ret = PVE::Tools::run_command($cmd, noerr => 1); > + die "updating $channel->{channelurl} failed - sa-update exited with $ret\n" if $ret >= 2; > + > + $fresh_updates = 1 if $ret == 0; > + } > + > + return $fresh_updates > +} > + > 1; > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [pmg-devel] [PATCH pmg-api v2 4/4] pmg-daily: run sa-update for local channels 2020-12-30 17:15 [pmg-devel] [PATCH pmg-api v2 0/4] add support for locally configured SA channels Stoiko Ivanov ` (2 preceding siblings ...) 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 3/4] api: spamassassin: update " Stoiko Ivanov @ 2020-12-30 17:15 ` Stoiko Ivanov 3 siblings, 0 replies; 10+ messages in thread From: Stoiko Ivanov @ 2020-12-30 17:15 UTC (permalink / raw) To: pmg-devel Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com> --- src/bin/pmg-daily | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/bin/pmg-daily b/src/bin/pmg-daily index 32ccb95..8865c94 100755 --- a/src/bin/pmg-daily +++ b/src/bin/pmg-daily @@ -73,12 +73,19 @@ if (my $http_proxy = $cfg->get('admin', 'http_proxy')) { } # update spamassassin rules +my $restart_filter = 0; if (system('sa-update') == 0) { # if the exit code is 0, new updates were downloaded # then restart the pmg-smtp-filter to load the new rules - PMG::Utils::service_cmd('pmg-smtp-filter', 'restart'); + $restart_filter = 1; } +eval { + $restart_filter ||= PMG::Utils::update_local_spamassassin_channels(0); +}; +syslog('err', "$@") if $@; + +PMG::Utils::service_cmd('pmg-smtp-filter', 'restart') if $restart_filter; # run bayes database maintainance system('sa-learn --force-expire >/dev/null 2>&1'); -- 2.20.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-01-19 9:10 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-12-30 17:15 [pmg-devel] [PATCH pmg-api v2 0/4] add support for locally configured SA channels Stoiko Ivanov 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 1/4] add helper for parsing SA channel.d files Stoiko Ivanov 2021-01-15 8:21 ` Thomas Lamprecht 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 2/4] api: spamassassin: read local channels Stoiko Ivanov 2021-01-15 10:02 ` Thomas Lamprecht 2021-01-18 19:47 ` Stoiko Ivanov 2021-01-19 9:10 ` Thomas Lamprecht 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 3/4] api: spamassassin: update " Stoiko Ivanov 2021-01-15 9:58 ` Thomas Lamprecht 2020-12-30 17:15 ` [pmg-devel] [PATCH pmg-api v2 4/4] pmg-daily: run sa-update for " Stoiko Ivanov
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.Service provided by Proxmox Server Solutions GmbH | Privacy | Legal