--- BlackListPlugin.pm.orig 2005-04-05 11:44:20.358678496 +0200 +++ BlackListPlugin.pm 2005-04-05 11:54:02.215222856 +0200 @@ -47,6 +47,15 @@ $urlHost = "initialized_later"; } +sub writeDebug { + &TWiki::Func::writeDebug("$pluginName - " . $_[0]) if $debug; +} + +sub writeDebugTimes { + &TWiki::Func::writeDebugTimes("$pluginName - " . $_[0]) if $debug; +} + + # ========================= sub initPlugin { @@ -61,6 +70,7 @@ # get debug flag $debug = TWiki::Func::getPreferencesFlag( "\U$pluginName\E_DEBUG" ); + # initialize for rel="nofollow" links $urlHost = TWiki::Func::getUrlHost(); $noFollowAge = TWiki::Func::getPreferencesValue( "\U$pluginName\E_NOFOLLOWAGE" ) || 0; @@ -86,6 +96,7 @@ my $scriptName = $ENV{'SCRIPT_NAME'} || ""; my $queryString = $ENV{'QUERY_STRING'} || ""; my $banList = _handleBanList( "read", $remoteAddr ); + $banList = join( "|", map { quotemeta } split( /\n/, $banList ) ); # black list + ban list regular expression @@ -93,11 +104,12 @@ $blackRE .= "|" if( $blackList && $banList ); $blackRE .= "$banList)"; + # black sheep if in black list unless in white list $isBlackSheep = 0; $userScore = "N/A"; if( ( $remoteAddr ) && ( $remoteAddr !~ /^$whiteList/ ) ) { - if( $remoteAddr =~ /^$blackRE/ ) { + if( $blackRE ne "()" && $remoteAddr =~ /^$blackRE/ ) { # already a black sheep $isBlackSheep = 1; } else { @@ -112,7 +124,7 @@ $cfg{ "period" } = $c6 || 300; $userScore = _handleEventLog( $remoteAddr, $scriptName, $queryString ); - TWiki::Func::writeDebug( "- TWiki::Plugins::${pluginName}::initPlugin() score: $userScore" ) if $debug; + writeDebug( "initPlugin() score: $userScore" ); if( $userScore > $cfg{ "ptLimit" } ) { $isBlackSheep = 1; _handleBanList( "add", $remoteAddr ); @@ -130,13 +142,12 @@ # view script: show message later in commonTagsHandler } else { # other scripts: force a "500 Internal Server Error" error - exit 1; + #exit 1; } } # Plugin correctly initialized - TWiki::Func::writeDebug( "- TWiki::Plugins::${pluginName}::initPlugin( $web.$topic ) is OK, " - . "whiteList $whiteList, blackRE $blackRE" ) if $debug; + writeDebug("initPlugin( $web.$topic ) is OK, whiteList $whiteList, blackRE $blackRE"); return 1; } @@ -145,7 +156,7 @@ { ### my ( $text, $topic, $web ) = @_; # do not uncomment, use $_[0], $_[1]... instead - TWiki::Func::writeDebug( "- ${pluginName}::commonTagsHandler( $_[2].$_[1] )" ) if $debug; + writeDebug( "commonTagsHandler( $_[2].$_[1] )" ); if( $isBlackSheep ) { my $message = TWiki::Func::getPreferencesValue( "\U$pluginName\E_BLACKLISTMESSAGE" ) || @@ -153,7 +164,7 @@ . "In addition, your IP address will be submitted to major blacklist databases."; $_[0] = $message; } - $_[0] =~ s/%BLACKLIST{(.*?)}%/_handleBlackList( $1, $_[2], $_[1] )/geo; + $_[0] =~ s/%BLACKLIST{([^}]*)}%/_handleBlackList( $1, $_[2], $_[1] )/geo; } # ========================= @@ -161,7 +172,7 @@ { ### my ( $text ) = @_; # do not uncomment, use $_[0] instead - TWiki::Func::writeDebug( "- ${pluginName}::endRenderingHandler( $web.$topic )" ) if $debug; + writeDebug( "endRenderingHandler( $web.$topic )" ); # This handler is called by getRenderedVersion just after the line loop, that is, # after almost all XHTML rendering of a topic. tags are removed after this. @@ -175,34 +186,35 @@ { my( $theAttributes, $theWeb, $theTopic ) = @_; my $action = &TWiki::Func::extractNameValuePair( $theAttributes, "action" ); - my $value = &TWiki::Func::extractNameValuePair( $theAttributes, "value" ); my $text = ""; + if( $action eq "ban_show" ) { - $text = _handleBanList( "read", "" ); - $text =~ s/[\n\r]+$//os; - $text =~ s/[\n\r]+/, /gos; + $text = _handleBanList( "read", "" ); + $text =~ s/[\n\r]+$//os; + $text =~ s/[\n\r]+/, /gos; } elsif( $action eq "user_score" ) { - $text = $userScore; + $text = $userScore; } elsif( $action =~ /^(ban_add|ban_remove)$/ ) { - if( "$theWeb.$theTopic" eq "$installWeb.$pluginName" ) { - my $wikiName = &TWiki::Func::userToWikiName( $user ); - if( &TWiki::Func::checkAccessPermission( "CHANGE", $wikiName, "", $pluginName, $installWeb ) ) { - if( $action eq "ban_add" ) { - $text = _handleBanList( "add", $value ); - _writeLog( "BANLIST add: $value, by user" ); - } else { - $text = _handleBanList( "remove", $value ); - _writeLog( "BANLIST delete: $value by user" ); - } - } else { - $text = "Error: You do not have permission to add IP addresses"; - } - } else { - $text = "Error: For use on $installWeb.$pluginName topic only"; - } - $text .= " [ [[$theWeb.$theTopic][OK]] ]"; + if( "$theWeb.$theTopic" eq "$installWeb.$pluginName" ) { + my $wikiName = &TWiki::Func::userToWikiName( $user ); + if( &TWiki::Func::checkAccessPermission( "CHANGE", $wikiName, "", $pluginName, $installWeb ) ) { + my $value = &TWiki::Func::extractNameValuePair( $theAttributes, "value" ); + if( $action eq "ban_add" ) { + $text .= _handleBanList( "add", $value ); + _writeLog( "BANLIST add: $value, by user" ); + } else { + $text .= _handleBanList( "remove", $value ); + _writeLog( "BANLIST delete: $value by user" ); + } + } else { + $text = "Error: You do not have permission to add IP addresses"; + } + } else { + $text = "Error: For use on $installWeb.$pluginName topic only"; + } + $text .= " [ [[$theWeb.$theTopic][OK]] ]"; } return $text; } @@ -210,36 +222,73 @@ # ========================= sub _handleBanList { - my ( $theAction, $theIP ) = @_; + my ( $theAction, $theIPs ) = @_; my $fileName = _makeFileName( "ban_list", 0 ); - TWiki::Func::writeDebug( "- ${pluginName}::_handleBanList( Action: $theAction, IP: $theIP, file: $fileName )" ) if $debug; + + writeDebug( "_handleBanList( Action: $theAction, IPs: $theIPs, file: $fileName )" ); + my $text = TWiki::Func::readFile( $fileName ) || "# The ban-list is a generated file, do not edit\n"; + if( $theAction eq "read" ) { $text =~ s/^\#[^\n]*\n//s; return $text; - } elsif( $theAction eq "add" ) { - unless( ( $theIP ) && ( $theIP =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ ) ) { - return "Error: Invalid IP address $theIP"; - } - if( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) { - return "Error: IP address $theIP is already on the list"; - } - $text .= "$theIP\n"; - TWiki::Func::saveFile( $fileName, $text ); - unless( -e "$fileName" ) { - # assuming save failed because of missing dir - _makeFileDir(); - TWiki::Func::saveFile( $fileName, $text ); - } - return "Note: Added IP address $theIP"; + } - } elsif( $theAction eq "remove" ) { - unless( ( $theIP ) && ( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) ) { - return "Error: IP address $theIP not found"; - } - TWiki::Func::saveFile( $fileName, $text ); - return "Note: Removed IP address $theIP"; + my @errorMessages; + my @infoMessages; + foreach my $theIP (split(/,/, $theIPs)) { + $theIP =~ s/^\s+//; + $theIP =~ s/\s+$//; + + if( $theAction eq "add" ) { + + unless( ( $theIP ) && ( $theIP =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ ) ) { + push @errorMessages, "Error: Invalid IP address '$theIP'"; + next; + } + + if( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) { + push @infoMessages, "Warning: IP address '$theIP' is already on the list"; + next; + } + + $text .= "$theIP\n"; + + push @infoMessages, "Note: Added IP address '$theIP'"; + + } elsif( $theAction eq "remove" ) { + + unless( ( $theIP ) && ( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) ) { + push @errorMessages, "Error: IP address '$theIP' not found"; + next; + } + + push @infoMessages, "Note: Removed IP address '$theIP'"; + } else { + # never reach + return "Error: invalid action '$theAction'"; + } + } + + if (@errorMessages) { + writeDebug("banlist=$text"); + return '
' . join("
\n", @errorMessages) . '
'; + + } else { + if (@infoMessages) { + # SMELL: overwrites a concurrent save + writeDebug("banlist=$text"); + TWiki::Func::saveFile( $fileName, $text ); + unless( -e "$fileName" ) { + # assuming save failed because of missing dir + _makeFileDir(); + TWiki::Func::saveFile( $fileName, $text ); + } + return join("
\n", @infoMessages) + } else { + return 'Error: done nothing'; + } } } @@ -250,7 +299,7 @@ # read/update/save event logs my $fileName = _makeFileName( "event_log" ); - TWiki::Func::writeDebug( "- ${pluginName}::_handleEventLog( IP: $theIP, type: $theType, query: $theQueryString )" ) if $debug; + writeDebug( "_handleEventLog( IP: $theIP, type: $theType, query: $theQueryString )" ); my $text = TWiki::Func::readFile( $fileName ) || "# The event-list is a generated file, do not edit\n"; my $time = time(); $text .= "$time, $theIP, $theType"; @@ -326,7 +375,7 @@ if( TWiki::Func::getPreferencesFlag( "\U$pluginName\E_LOGACCESS" ) ) { # FIXME: Call to unofficial function TWiki::Store::writeLog( "blacklist", "$web.$topic", $theText ); - ##TWiki::Func::writeDebug( "BLACKLIST access by $remoteAddr, $web/$topic, $theText" ); + writeDebug("BLACKLIST access by $remoteAddr, $web/$topic, $theText"); } }