[dw-free] http://bugs.dwscoalition.org/show_bug.cgi?id=2523
[commit: http://hg.dwscoalition.org/dw-free/rev/29d5f1a356f5]
http://bugs.dwscoalition.org/show_bug.cgi?id=2523
Add ability to detect if someone is coming in via a Tor exit.
Patch by
mark.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=2523
Add ability to detect if someone is coming in via a Tor exit.
Patch by
![[staff profile]](https://www.dreamwidth.org/img/silk/identity/user_staff.png)
Files modified:
- bin/update-tor-exits
- bin/upgrading/en.dat
- bin/upgrading/update-db-general.pl
- cgi-bin/Apache/LiveJournal.pm
- cgi-bin/DW/Shop.pm
- cgi-bin/sysban.pl
- doc/config-local.pl.txt
- doc/config-private.pl.txt
-------------------------------------------------------------------------------- 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 <mark@dreamwidth.org> +# +# 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 = ( --------------------------------------------------------------------------------