Cancel-Lock in filter nnrpd.pl/cleanfeed.local überprüfen
Von: Alexander Bartolich (alexander.bartolich@gmx.at) [Profil]
Datum: 01.07.2007 12:51
Message-ID: <f680uu$vqn$1@news.albasani.net>
Newsgroup: de.comm.software.newsserver
Datum: 01.07.2007 12:51
Message-ID: <f680uu$vqn$1@news.albasani.net>
Newsgroup: de.comm.software.newsserver
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();
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
[ Auf dieses Posting antworten ]Antworten
- Beleidigte Leberwurst (01.07.2007 13:15)
- Alexander alba Bartolich (01.07.2007 13:44)
- André Banana (01.07.2007 15:04)
