Add ability to detect if someone is coming in via a Tor exit.
Patch by mark.
diffs (204 lines):
diff -r f808bb62f298 -r 29d5f1a356f5 bin/update-tor-exits
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/update-tor-exits Mon May 03 06:49:48 2010 +0000
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+#
+# DW::Setting::AwesomeNewFeature
+#
+# This file is the accompanying settings package for AwesomeNewFeature. It
allows users to set and
+# clear their setting choices.
+#
+# Authors:
+# Mark Smith <[email protected]>
+#
+# Copyright (c) 2010 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+
+use strict;
+use lib "$ENV{LJHOME}/cgi-bin";
+require 'ljlib.pl';
+
+die "\$LJ::USE_TOR_CONFIGS is disabled.\n" unless $LJ::USE_TOR_CONFIGS;
+die "\$LJ::EXTERNAL_IP is not set.\n" unless $LJ::EXTERNAL_IP;
+
+my $ua = LJ::get_useragent( role => 'tor', timeout => 30 ) or die "No
useragent.\n";
+$ua->agent( "$LJ::SITENAME (Tor exit downloader; $LJ::ADMIN_EMAIL)" );
+
+my $res = $ua->get(
"https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=" .
$LJ::EXTERNAL_IP );
+my $content = $res && $res->is_success ? $res->content : undef;
+
+die "Failed to fetch exit list from Tor.\n" unless $content;
+
+my $dbh = LJ::get_db_writer() or die "Failed to get dbh.\n";
+$dbh->do( 'DELETE FROM tor_proxy_exits' );
+
+my $ct = 0;
+while ( $content =~ /^(\d+\.\d+\.\d+\.\d+)$/mg ) {
+ $ct++;
+
+ $dbh->do( 'REPLACE INTO tor_proxy_exits (addr) VALUES (?)', undef, $1 );
+ die "Failed on $1: " . $dbh->errstr . "\n" if $dbh->err;
+}
+
+print "Found $ct Tor exits.\n";
diff -r f808bb62f298 -r 29d5f1a356f5 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat Mon May 03 05:31:11 2010 +0000
+++ b/bin/upgrading/en.dat Mon May 03 06:49:48 2010 +0000
@@ -1144,6 +1144,8 @@ entryform.xpost.manage=Manage accounts
entryform.xpost.manage=Manage accounts
error.badpassword2=You typed the wrong password. If you make too many wrong
login attempts in a row, your account access will be temporarily blocked, so
you may want to <a [[aopts]]>reset your password</a> if you aren't sure what it
is.
+
+error.blocked=Sorry, you are currently blocked from reaching the page you are
attempting to visit. The block type is: [[blocktype]]. Please email us at
[[email]] and reference this message for further assistance.
error.code.comm_not_comm=Account is not a community
diff -r f808bb62f298 -r 29d5f1a356f5 bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl Mon May 03 05:31:11 2010 +0000
+++ b/bin/upgrading/update-db-general.pl Mon May 03 06:49:48 2010 +0000
@@ -3047,6 +3047,12 @@ CREATE TABLE cc_log (
)
EOC
+register_tablecreate('tor_proxy_exits', <<'EOC');
+CREATE TABLE tor_proxy_exits (
+ addr VARCHAR(15) NOT NULL,
+ PRIMARY KEY (addr)
+)
+EOC
# NOTE: new table declarations go ABOVE here ;)
diff -r f808bb62f298 -r 29d5f1a356f5 cgi-bin/Apache/LiveJournal.pm
--- a/cgi-bin/Apache/LiveJournal.pm Mon May 03 05:31:11 2010 +0000
+++ b/cgi-bin/Apache/LiveJournal.pm Mon May 03 06:49:48 2010 +0000
@@ -52,6 +52,7 @@ my %RQ; # per-request data
my %RQ; # per-request data
my %USERPIC; # conf related to userpics
my %REDIR;
+my ( $TOR_UPDATE_TIME, %TOR_EXITS );
# Mapping of MIME types to image types understood by the blob functions.
my %MimeTypeMapd6 = (
@@ -252,6 +253,33 @@ sub blocked_anon
return OK;
}
+# returns whether or not an IP address is from the Tor proxy exit list, but
only if we're configured
+# to actually use this data
+sub ip_is_via_tor {
+ return unless $LJ::USE_TOR_CONFIGS;
+
+ # try to load the data every few minutes so that we keep it reasonably
fresh, but so that we don't
+ # hammer the database all of the time
+ unless ( defined $TOR_UPDATE_TIME && $TOR_UPDATE_TIME > time ) {
+ # either way, wait a few minutes before trying again, that way we
don't hammer things if the
+ # database is down or something
+ $TOR_UPDATE_TIME = time + 300;
+
+ # be very conscientious not to get rid of data if we get a db error
+ my $dbh = LJ::get_db_writer() or return;
+ my $ips = $dbh->selectcol_arrayref( 'SELECT addr FROM tor_proxy_exits'
);
+ return if $dbh->err;
+
+ if ( $ips && ref $ips eq 'ARRAY' ) {
+ %TOR_EXITS = ();
+ $TOR_EXITS{$_} = 1 foreach @$ips;
+ }
+ }
+
+ # regardless of what happened above we can check and return
+ return exists $TOR_EXITS{$_[0]};
+}
+
sub trans
{
my $r = shift;
@@ -427,6 +455,9 @@ sub trans
$r->push_handlers( PerlResponseHandler => \&blocked_bot );
return OK;
}
+
+ # determine if this IP is one of the tor exits and set a note on
the request
+ $r->notes->{via_tor_exit} = 1 if ip_is_via_tor( $ip );
}
if ( LJ::Hooks::run_hook( "forbid_request", $r ) ) {
$r->handler( "perl-script" );
diff -r f808bb62f298 -r 29d5f1a356f5 cgi-bin/DW/Shop.pm
--- a/cgi-bin/DW/Shop.pm Mon May 03 05:31:11 2010 +0000
+++ b/cgi-bin/DW/Shop.pm Mon May 03 06:49:48 2010 +0000
@@ -157,14 +157,18 @@ sub remote_sysban_check {
# do sysban checks:
if ( LJ::sysban_check( 'pay_uniq', LJ::UniqCookie->current_uniq ) ) {
- return BML::ml( '/shop.bml.paymentblock', { blocktype => "computer",
email => $LJ::ACCOUNTS_EMAIL } );
+ return BML::ml( 'error.blocked', { blocktype => "computer", email =>
$LJ::ACCOUNTS_EMAIL } );
} elsif ( my $remote = LJ::get_remote() ) {
if ( LJ::sysban_check( 'pay_user', $remote->user ) ) {
- return BML::ml( '/shop.bml.paymentblock', { blocktype =>
"account", email => $LJ::ACCOUNTS_EMAIL } );
+ return BML::ml( 'error.blocked', { blocktype => "account", email
=> $LJ::ACCOUNTS_EMAIL } );
} elsif ( LJ::sysban_check( 'pay_email', $remote->email_raw ) ) {
- return BML::ml( '/shop.bml.paymentblock', { blocktype => "email
address", email => $LJ::ACCOUNTS_EMAIL } );
+ return BML::ml( 'error.blocked', { blocktype => "email address",
email => $LJ::ACCOUNTS_EMAIL } );
}
}
+
+ # now do a tor check
+ return BML::ml( 'error.blocked', { blocktype => "Tor proxy", email =>
$LJ::ACCOUNTS_EMAIL } )
+ if LJ::tor_check( 'shop' );
# looks good
return undef;
diff -r f808bb62f298 -r 29d5f1a356f5 cgi-bin/sysban.pl
--- a/cgi-bin/sysban.pl Mon May 03 05:31:11 2010 +0000
+++ b/cgi-bin/sysban.pl Mon May 03 06:49:48 2010 +0000
@@ -219,6 +219,13 @@ sub sysban_populate {
}
+# here because it relates to sysbans ...
+sub tor_check {
+ return 0 unless $LJ::USE_TOR_CONFIGS && $LJ::TOR_CONFIG{$_[0]};
+ return DW::Request->get->note( 'via_tor_exit' ) ? 1 : 0;
+}
+
+
sub _db_sysban_populate {
my ($where, $what) = @_;
my $dbh = LJ::get_db_writer();
diff -r f808bb62f298 -r 29d5f1a356f5 doc/config-local.pl.txt
--- a/doc/config-local.pl.txt Mon May 03 05:31:11 2010 +0000
+++ b/doc/config-local.pl.txt Mon May 03 06:49:48 2010 +0000
@@ -51,6 +51,14 @@
private_key => $DW::PRIVATE::RECAPTCHA{private_key},
);
+ # If enabled, disable people coming in over Tor exits from using various
parts of the site.
+ $USE_TOR_CONFIGS = 0;
+
+ # Configure what you want blocked here. Requires $USE_TOR_CONFIGS to be
on.
+ %TOR_CONFIG = (
+ shop => 1, # Disallow Tor users from accessing the Shop.
+ )
+
# PayPal configuration. If you want to use PayPal, uncomment this
# section and make sure to fill in the fields at the bottom of
config-private.pl.
#%PAYPAL_CONFIG = (
diff -r f808bb62f298 -r 29d5f1a356f5 doc/config-private.pl.txt
--- a/doc/config-private.pl.txt Mon May 03 05:31:11 2010 +0000
+++ b/doc/config-private.pl.txt Mon May 03 06:49:48 2010 +0000
@@ -94,6 +94,9 @@
'ljsite.tld',
);
+ # Set this to the IP address of your main site. This is used for Tor exit
checking.
+ #$EXTERNAL_IP = '127.0.0.1';
+
# configuration/ID for statistics tracker modules which apply to
# site pages (www, non-journal)
%SITE_PAGESTAT_CONFIG = (
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog