Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Cancel-Lock in filter_nnrpd.pl/cleanfeed.local überprüfen

35 views
Skip to first unread message

Alexander Bartolich

unread,
Jul 1, 2007, 6:33:02 AM7/1/07
to
Das folgende ist eine Proof-Of-Concept-Implementierung um unter
INN mit Cleanfeed alle eingehenden Cancel-Postings zu prüfen.

filter_innd.pl wird im Kontext des inn-Daemons ausgeführt. Im Gegen-
satz zu filter_nnrpd.pl bekommt also nicht jeder Client eine eigene,
frische Instanz. Um Änderungen an filter_innd.pl wirksam zu machen,
bedarf es

ctlinnd reload filter.perl "hier noch eine begründung"

Kommt es zu Syntax-Fehlern beim Laden bzw. fatalen Fehler bei der
Ausführung ("die") wird das Perl-Filtering dauerhaft abgestellt.
In diesem Fall bedarf es dann eines Neustarts von inn.
Es empfiehlt sich daher, Änderungen vor dem "reload" mit

perl -wc filter_nnrpd.pl

zumindest oberflächlich prüfen zu lassen.

Üblicherweise ist filter_innd.pl ein Symbolic Link auf die Datei
"cleanfeed" welche ihrerseits "cleanfeed.local" lädt. Wenn die
Funktion "local_filter_cancel" existiert, wird sie von "cleanfeed"
für Cancel-Postings (nach erfolgreichen bestehen aller anderen
Cancel-Prüfungen) ausgeführt.

sub local_filter_cancel
{
unless($hdr{Control} =~ m/^cancel\s+(<[^>]+>)/i)
{ return "Cancel with broken target ID"; }
my $target = $1;

my $headers = INN::head($target) ||
return "Cancel of non-existing ID $target";

my %headers;
for my $line(split(/\s*\n/, $headers))
{
if ($line =~ m/^([[:alnum:]-]+):\s+(.*)/)
{ $headers{$1} = $2; }
}

my $lock = $headers{'Cancel-Lock'};
if (defined($lock))
{
my $key = $hdr{'Cancel-Key'} ||
return "Cancel of $target without Cancel-Key";
my $rc = verify_cancel_key($key, $lock);
return $rc . ' target=' . $target if (defined($rc));
}
# else { return "Cancel of $target without Cancel-Lock"; }

return undef;
}

Die von INN bereitgestelle Funktion "INN::head" lädt ein
Posting aus dem Newsspool und gibt dessen Header in Form
einer Zeichenkette zurück.

Diese Implementierung kümmert sich nur um Ziel-Postings,
die ein Feld "Cancel-Lock:" aufweisen. Entfernt man das
"#" vor dem "else" werden alle Ziel-Postings ohne Cancel-
Lock nicht mehr cancelbar.

sub verify_cancel_key($$)
{
my $cancel_key = shift;
my $cancel_lock = shift;

my %lock;
for my $l(split(/\s+/, $cancel_lock))
{
next unless($l =~ m/^(sha1|md5):(\S+)/);
$lock{$2} = 1;
}

for my $k(split(/\s+/, $cancel_key))
{
next unless($k =~ m/^(sha1|md5):(\S+)/);
my $key;
if ($1 eq 'sha1')
{ $key = Digest::SHA1::sha1($2); }
elsif ($1 eq 'md5')
{ $key = Digest::MD5::md5($2); }
else
{
INN::syslog('notice', "Invalid cancel-key schema $1.");
next;
}
$key = MIME::Base64::encode_base64($key);

if (exists($lock{$key}))
{
INN::syslog('notice', "Valid cancel key $key found.");
return undef;
}
}

INN::syslog('notice', "No Cancel-Key[$cancel_key] matches Cancel-Lock[$cancel_lock]");
return "No Cancel-Key matches Cancel-Lock.";
}

Diese Funktion kann mit mehreren Locks und Keys umgehen. Die von INN
bereitgestellte Funktion "INN::syslog" wird für die Ausgabe weiter-
gehender Diagnose benutzt.

Auf einen Vergleich der Schema-Felder in Key und Lock habe ich
verzichtet.

--
news.albasani.net

Alexander Bartolich

unread,
Jul 1, 2007, 6:51:10 AM7/1/07
to
Das folgende ist eine Proof-Of-Concept-Implementierung um unter
INN mit Cleanfeed alle eingehenden Cancel-Postings zu prüfen.

filter_innd.pl wird im Kontext des inn-Daemons ausgeführt. Im Gegen-
satz zu filter_nnrpd.pl bekommt also nicht jeder Client eine eigene,
frische Instanz. Um Änderungen an filter_innd.pl wirksam zu machen,
bedarf es

ctlinnd reload filter.perl "hier noch eine begründung"

Kommt es zu Syntax-Fehlern beim Laden bzw. fatalen Fehler bei der
Ausführung ("die") wird das Perl-Filtering dauerhaft abgestellt.
In diesem Fall bedarf es dann eines Neustarts von inn.
Es empfiehlt sich daher, Änderungen vor dem "reload" mit

perl -wc filter_nnrpd.pl

zumindest oberflächlich prüfen zu lassen.

Üblicherweise ist filter_innd.pl ein Symbolic Link auf die Datei
"cleanfeed" welche ihrerseits "cleanfeed.local" lädt. Wenn die
Funktion "local_filter_cancel" existiert, wird sie von "cleanfeed"
für Cancel-Postings (nach erfolgreichen bestehen aller anderen
Cancel-Prüfungen) ausgeführt.

use Digest::SHA1();
use Digest::MD5();
use MIME::Base64();

Roman Racine

unread,
Jul 1, 2007, 7:15:34 AM7/1/07
to
Alexander Bartolich wrote:

> Das folgende ist eine Proof-Of-Concept-Implementierung um unter
> INN mit Cleanfeed alle eingehenden Cancel-Postings zu prüfen.

Ich habe letzten Freitag das Perl-Modul News::Article um
Cancellock-Fähigkeiten erweitert, hier gibt's ein Diff zur Version 1.27:
http://www.trash.net/~roman/weiteres/Article.pm.diff

Gruss

Roman°
--
IRC-Freenode: #usenet-friends
http://www.usenet-friends.ch.vu/

Alexander Bartolich

unread,
Jul 1, 2007, 7:35:01 AM7/1/07
to
Alexander Bartolich schrieb:

> Das folgende ist eine Proof-Of-Concept-Implementierung um unter
> INN mit Cleanfeed alle eingehenden Cancel-Postings zu prüfen.

Der Code im Vorposting ist buggy, äh, sub-optimal.
Folgende Version ist jetzt auf news.albasani.net im Einsatz:

use Digest::SHA1();
use Digest::MD5();
use MIME::Base64();

sub verify_cancel_key($$)


{
my $cancel_key = shift;
my $cancel_lock = shift;

my %lock;
for my $l(split(/\s+/, $cancel_lock))
{
next unless($l =~ m/^(sha1|md5):(\S+)/);

$lock{$2} = $1;


}

for my $k(split(/\s+/, $cancel_key))
{

unless($k =~ m/^(sha1|md5):(\S+)/)

{
INN::syslog('notice', "Invalid cancel-key syntax $k");
next;

}

my $key;
if ($1 eq 'sha1')
{ $key = Digest::SHA1::sha1($2); }

else ($1 eq 'md5')


{ $key = Digest::MD5::md5($2); }

$key = MIME::Base64::encode_base64($key, '');



if (exists($lock{$key}))
{
INN::syslog('notice', "Valid cancel key $key found.");
return undef;
}
}

INN::syslog('notice',
"No Cancel-Key[$cancel_key] matches Cancel-Lock[$cancel_lock]"
);
return "No Cancel-Key matches Cancel-Lock.";
}

sub local_filter_cancel


{
unless($hdr{Control} =~ m/^cancel\s+(<[^>]+>)/i)
{ return "Cancel with broken target ID"; }
my $target = $1;

my $headers = INN::head($target) ||
return "Cancel of non-existing ID $target";

my %headers;
for my $line(split(/\s*\n/, $headers))
{
if ($line =~ m/^([[:alnum:]-]+):\s+(.*)/)
{ $headers{$1} = $2; }
}

my $lock = $headers{'Cancel-Lock'};
if (defined($lock))
{
my $key = $hdr{'Cancel-Key'} ||
return "Cancel of $target without Cancel-Key";
my $rc = verify_cancel_key($key, $lock);
return $rc . ' target=' . $target if (defined($rc));
}

return undef;
}

--

Alexander Bartolich

unread,
Jul 1, 2007, 7:44:38 AM7/1/07
to
Alexander Bartolich schrieb:

> Das folgende ist eine Proof-Of-Concept-Implementierung um unter
> INN mit Cleanfeed alle eingehenden Cancel-Postings zu prüfen.

Der Code im Vorposting ist buggy, äh, sub-optimal.


Folgende Version ist jetzt auf news.albasani.net im Einsatz:

use Digest::SHA1();


use Digest::MD5();
use MIME::Base64();

sub verify_cancel_key($$)


{
my $cancel_key = shift;
my $cancel_lock = shift;

my %lock;
for my $l(split(/\s+/, $cancel_lock))
{
next unless($l =~ m/^(sha1|md5):(\S+)/);

$lock{$2} = $1;


}

for my $k(split(/\s+/, $cancel_key))
{

unless($k =~ m/^(sha1|md5):(\S+)/)

{
INN::syslog('notice', "Invalid cancel-key syntax $k");
next;

}

my $key;
if ($1 eq 'sha1')
{ $key = Digest::SHA1::sha1($2); }
elsif ($1 eq 'md5')
{ $key = Digest::MD5::md5($2); }

$key = MIME::Base64::encode_base64($key, '');

if (exists($lock{$key}))
{
INN::syslog('notice', "Valid cancel key $key found.");
return undef;
}
}

INN::syslog('notice',
"No Cancel-Key[$cancel_key] matches Cancel-Lock[$cancel_lock]"
);
return "No Cancel-Key matches Cancel-Lock.";
}

sub local_filter_cancel


{
unless($hdr{Control} =~ m/^cancel\s+(<[^>]+>)/i)
{ return "Cancel with broken target ID"; }
my $target = $1;

my $headers = INN::head($target) ||
return "Cancel of non-existing ID $target";

my %headers;
for my $line(split(/\s*\n/, $headers))
{
if ($line =~ m/^([[:alnum:]-]+):\s+(.*)/)
{ $headers{$1} = $2; }
}

my $lock = $headers{'Cancel-Lock'};
if (defined($lock))
{
my $key = $hdr{'Cancel-Key'} ||
return "Cancel of $target without Cancel-Key";
my $rc = verify_cancel_key($key, $lock);
return $rc . ' target=' . $target if (defined($rc));
}

return undef;
}

--

Ray Banana

unread,
Jul 1, 2007, 9:04:43 AM7/1/07
to
Also sprach Alexander Bartolich <alexander...@gmx.at>


> Alexander Bartolich schrieb:
>> Das folgende ist eine Proof-Of-Concept-Implementierung um unter
>> INN mit Cleanfeed alle eingehenden Cancel-Postings zu prüfen.

> Der Code im Vorposting ist buggy, äh, sub-optimal.
> Folgende Version ist jetzt auf news.albasani.net im Einsatz:

Und so klappt's auch mit den Supersedes:

sub local_filter_after_emp {

if ( $hdr{Supersedes} ) {

unless($hdr{Supersedes} =~ m/^(<[^>]+>)/)
{ return "Supersedes with broken target ID"; }
my $target = $1;

my $headers = INN::head($target) ||

return "Supersedes of non-existing ID $target";

my %headers;
for my $line(split(/\s*\n/, $headers))
{
if ($line =~ m/^([[:alnum:]-]+):\s+(.*)/)
{ $headers{$1} = $2; }
}

my $lock = $headers{'Cancel-Lock'};
if (defined($lock))
{
my $key = $hdr{'Cancel-Key'} ||

return "Supersedes of $target without Cancel-Key";


my $rc = verify_cancel_key($key, $lock);
return $rc . ' target=' . $target if (defined($rc));
}

}

return undef;


}

--
Too many ingredients in the soup, no room for a spoon.
http://news.motzarella.org

0 new messages