Index: trunk/extensions/TorBlock/TorBlock.i18n.php |
— | — | @@ -11,8 +11,9 @@ |
12 | 12 | * @author Andrew Garrett |
13 | 13 | */ |
14 | 14 | $messages['en'] = array( |
15 | | - 'torblock-desc' => 'Allows Tor exit nodes to be blocked from editing a wiki', |
16 | | - 'torblock-blocked' => 'Your IP address, <tt>$1</tt>, has been automatically identified as a tor exit node. Editing through tor is blocked to prevent abuse.' |
| 15 | + 'torblock-desc' => 'Allows tor exit nodes to be blocked from editing a wiki', |
| 16 | + 'torblock-blocked' => 'Your IP address, <tt>$1</tt>, has been automatically identified as a tor exit node. |
| 17 | +Editing through tor is blocked to prevent abuse.' |
17 | 18 | ); |
18 | 19 | |
19 | 20 | /** German (Deutsch) |
— | — | @@ -21,4 +22,4 @@ |
22 | 23 | $messages['de'] = array( |
23 | 24 | 'torblock-desc' => 'Ermöglicht die Schreibsperre im Wiki für Tor-Ausgangsknoten', |
24 | 25 | 'torblock-blocked' => 'Deine IP-Adresse <tt>$1</tt> wurde automatisch als Tor-Ausgangsknoten identifiziert. Die Seitenbearbeitung in Verbindung mit dem Tor-Netzwerk ist unerwünscht, da die Missbrauchsgefahr sehr hoch ist.' |
25 | | -); |
\ No newline at end of file |
| 26 | +); |
Index: trunk/extensions/TorBlock/TorBlock.php |
— | — | @@ -13,24 +13,25 @@ |
14 | 14 | * @author Andrew Garrett <andrew@epstone.net> |
15 | 15 | * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later |
16 | 16 | */ |
17 | | - |
| 17 | + |
18 | 18 | $dir = dirname(__FILE__); |
19 | 19 | $wgExtensionCredits['other'][] = array( |
20 | 20 | 'name' => 'TorBlock', |
21 | 21 | 'author' => 'Andrew Garrett', |
22 | | - 'version' => preg_replace('/^.* (\d\d\d\d-\d\d-\d\d) .*$/', '\1', '$LastChangedDate: 2008-04-28 18:12:02 +1000 (Mon, 28 Apr 2008) $'), #just the date of the last change |
| 22 | + 'svn-date' => '$LastChangedDate$', |
| 23 | + 'svn-revision' => '$LastChangedRevision$', |
23 | 24 | 'description' => 'Prevents Tor exit nodes from editing a wiki', |
24 | 25 | 'descriptionmsg' => 'torblock-desc', |
25 | 26 | 'url' => 'http://www.mediawiki.org/wiki/Extension:TorBlock', |
26 | 27 | ); |
27 | 28 | |
28 | 29 | $wgExtensionMessagesFiles['TorBlock'] = "$dir/TorBlock.i18n.php"; |
| 30 | +$wgAutoloadClasses[ 'TorBlock' ] = "$dir/TorBlock.class.php"; |
29 | 31 | |
30 | 32 | $wgHooks['getUserPermissionsErrorsExpensive'][] = 'TorBlock::onGetUserPermissionsErrorsExpensive'; |
31 | 33 | $wgHooks['AbortAutoblock'][] = 'TorBlock::onAbortAutoblock'; |
32 | 34 | $wgHooks['GetAutoPromoteGroups'][] = 'TorBlock::onGetAutoPromoteGroups'; |
33 | 35 | |
34 | | - |
35 | 36 | /** |
36 | 37 | * Permission keys that bypass Tor blocks. |
37 | 38 | * Array of permission keys. |
— | — | @@ -68,143 +69,3 @@ |
69 | 70 | * (i.e. all IPs which can be used to access the site. |
70 | 71 | */ |
71 | 72 | $wgTorIPs = array( '208.80.152.2' ); |
72 | | - |
73 | | -class TorBlock { |
74 | | - public static $mExitNodes; |
75 | | - |
76 | | - public static function onGetUserPermissionsErrorsExpensive( &$title, &$user, &$action, &$result ) { |
77 | | - global $wgTorAllowedActions; |
78 | | - if (in_array( $action, $wgTorAllowedActions)) { |
79 | | - return true; |
80 | | - } |
81 | | - |
82 | | - wfDebug( "Checking Tor status\n" ); |
83 | | - |
84 | | - if (self::isExitNode()) { |
85 | | - wfDebug( "-User detected as editing through tor.\n" ); |
86 | | - |
87 | | - global $wgTorBypassPermissions; |
88 | | - foreach( $wgTorBypassPermissions as $perm) { |
89 | | - if ($user->isAllowed( $perm )) { |
90 | | - wfDebug( "-User has $perm permission. Exempting from Tor Blocks\n" ); |
91 | | - return true; |
92 | | - } |
93 | | - } |
94 | | - |
95 | | - $ip = wfGetIp(); |
96 | | - wfDebug( "-User detected as editing from Tor node. Adding Tor block to permissions errors\n" ); |
97 | | - wfLoadExtensionMessages( 'TorBlock' ); |
98 | | - |
99 | | - $result[] = array('torblock-blocked', $ip); |
100 | | - |
101 | | - return false; |
102 | | - } |
103 | | - |
104 | | - return true; |
105 | | - } |
106 | | - |
107 | | - public static function getExitNodes() { |
108 | | - |
109 | | - if (is_array(self::$mExitNodes)) { |
110 | | - wfDebug( "Loading Tor exit node list from memory.\n" ); |
111 | | - return self::$mExitNodes; |
112 | | - } |
113 | | - |
114 | | - global $wgMemc; |
115 | | - |
116 | | - $nodes = $wgMemc->get( 'mw-tor-exit-nodes' ); // No use of wfMemcKey because it should be multi-wiki. |
117 | | - |
118 | | - if (is_array($nodes)) { |
119 | | - wfDebug( "Loading Tor exit node list from memcached.\n" ); |
120 | | - // Lucky. |
121 | | - return self::$mExitNodes = $nodes; |
122 | | - } |
123 | | - |
124 | | - // We have to actually load them. |
125 | | - |
126 | | - if (!$wgTorLoadNodes) { |
127 | | - // Disabled. |
128 | | - wfDebug( "Unable to load Tor exit node list: cold load disabled on page-views.\n" ); |
129 | | - return array(); |
130 | | - } |
131 | | - |
132 | | - wfDebug( "Loading Tor exit node list cold.\n" ); |
133 | | - |
134 | | - return self::$mExitNodes = self::loadExitNodes(); |
135 | | - } |
136 | | - |
137 | | - public static function loadExitNodes() { |
138 | | - $nodes = array(); |
139 | | - |
140 | | - global $wgTorIPs; |
141 | | - |
142 | | - foreach( $wgTorIPs as $ip ) { |
143 | | - $nodes = array_unique( array_merge( $nodes, self::getExitList( $ip ) ) ); |
144 | | - } |
145 | | - |
146 | | - global $wgMemc; |
147 | | - |
148 | | - $wgMemc->set( 'mw-tor-exit-nodes', $nodes, 1800 ); // Store for half an hour. |
149 | | - |
150 | | - return $nodes; |
151 | | - } |
152 | | - |
153 | | - public static function getExitList( $ip ) { |
154 | | - $url = 'https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip='.$ip; |
155 | | - |
156 | | - $data = Http::get( $url ); |
157 | | - |
158 | | - $lines = split("\n", $data); |
159 | | - |
160 | | - $nodes = array(); |
161 | | - |
162 | | - foreach( $lines as $line ) { |
163 | | - if (strpos( $line, '#' )===false) { |
164 | | - $nodes[] = trim($line); |
165 | | - } |
166 | | - } |
167 | | - |
168 | | - return $nodes; |
169 | | - } |
170 | | - |
171 | | - public static function isExitNode($ip = null) { |
172 | | - #return true; ## FOR DEBUGGING |
173 | | - if ($ip == null) { |
174 | | - $ip = wfGetIp(); |
175 | | - } |
176 | | - |
177 | | - $nodes = self::getExitNodes(); |
178 | | - |
179 | | - return in_array( $ip, $nodes ); |
180 | | - } |
181 | | - |
182 | | - public static function onGetBlockedStatus( &$user ) { |
183 | | - if (self::isExitNode() && $user->mBlock && !$user->mBlock->mUser) { |
184 | | - wfDebug( "User using Tor node. Disabling IP block as it was probably targetted at the tor node." ); |
185 | | - // Node is probably blocked for being a Tor node. Remove block. |
186 | | - $user->mBlockedBy = 0; |
187 | | - } |
188 | | - |
189 | | - return true; |
190 | | - } |
191 | | - |
192 | | - public static function onAbortAutoblock( $autoblockip, &$block ) { |
193 | | - return !self::isExitNode( $autoblockip ); |
194 | | - } |
195 | | - |
196 | | - public static function onGetAutoPromoteGroups( $user, &$promote ) { |
197 | | - if (self::isExitNode()) { |
198 | | - // Check against stricter requirements. |
199 | | - $age = time() - wfTimestampOrNull( TS_UNIX, $user->getRegistration() ); |
200 | | - |
201 | | - global $wgTorAutoConfirmAge, $wgTorAutoConfirmCount; |
202 | | - |
203 | | - if ($age < $wgTorAutoConfirmAge || $user->getEditCount() < $wgTorAutoConfirmCount) { |
204 | | - // No! |
205 | | - $promote = array(); |
206 | | - } |
207 | | - } |
208 | | - |
209 | | - return true; |
210 | | - } |
211 | | -} |
\ No newline at end of file |
Property changes on: trunk/extensions/TorBlock/TorBlock.php |
___________________________________________________________________ |
Added: svn:keywords |
212 | 73 | + LastChangedDate LastChangedRevision |
Index: trunk/extensions/TorBlock/TorBlock.class.php |
— | — | @@ -0,0 +1,143 @@ |
| 2 | +<?php |
| 3 | +if ( ! defined( 'MEDIAWIKI' ) ) |
| 4 | + die(); |
| 5 | + |
| 6 | +class TorBlock { |
| 7 | + public static $mExitNodes; |
| 8 | + |
| 9 | + public static function onGetUserPermissionsErrorsExpensive( &$title, &$user, &$action, &$result ) { |
| 10 | + global $wgTorAllowedActions; |
| 11 | + if (in_array( $action, $wgTorAllowedActions)) { |
| 12 | + return true; |
| 13 | + } |
| 14 | + |
| 15 | + wfDebug( "Checking Tor status\n" ); |
| 16 | + |
| 17 | + if (self::isExitNode()) { |
| 18 | + wfDebug( "-User detected as editing through tor.\n" ); |
| 19 | + |
| 20 | + global $wgTorBypassPermissions; |
| 21 | + foreach( $wgTorBypassPermissions as $perm) { |
| 22 | + if ($user->isAllowed( $perm )) { |
| 23 | + wfDebug( "-User has $perm permission. Exempting from Tor Blocks\n" ); |
| 24 | + return true; |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | + $ip = wfGetIp(); |
| 29 | + wfDebug( "-User detected as editing from Tor node. Adding Tor block to permissions errors\n" ); |
| 30 | + wfLoadExtensionMessages( 'TorBlock' ); |
| 31 | + |
| 32 | + $result[] = array('torblock-blocked', $ip); |
| 33 | + |
| 34 | + return false; |
| 35 | + } |
| 36 | + |
| 37 | + return true; |
| 38 | + } |
| 39 | + |
| 40 | + public static function getExitNodes() { |
| 41 | + |
| 42 | + if (is_array(self::$mExitNodes)) { |
| 43 | + wfDebug( "Loading Tor exit node list from memory.\n" ); |
| 44 | + return self::$mExitNodes; |
| 45 | + } |
| 46 | + |
| 47 | + global $wgMemc; |
| 48 | + |
| 49 | + $nodes = $wgMemc->get( 'mw-tor-exit-nodes' ); // No use of wfMemcKey because it should be multi-wiki. |
| 50 | + |
| 51 | + if (is_array($nodes)) { |
| 52 | + wfDebug( "Loading Tor exit node list from memcached.\n" ); |
| 53 | + // Lucky. |
| 54 | + return self::$mExitNodes = $nodes; |
| 55 | + } |
| 56 | + |
| 57 | + // We have to actually load them. |
| 58 | + |
| 59 | + if (!$wgTorLoadNodes) { |
| 60 | + // Disabled. |
| 61 | + wfDebug( "Unable to load Tor exit node list: cold load disabled on page-views.\n" ); |
| 62 | + return array(); |
| 63 | + } |
| 64 | + |
| 65 | + wfDebug( "Loading Tor exit node list cold.\n" ); |
| 66 | + |
| 67 | + return self::$mExitNodes = self::loadExitNodes(); |
| 68 | + } |
| 69 | + |
| 70 | + public static function loadExitNodes() { |
| 71 | + $nodes = array(); |
| 72 | + |
| 73 | + global $wgTorIPs; |
| 74 | + |
| 75 | + foreach( $wgTorIPs as $ip ) { |
| 76 | + $nodes = array_unique( array_merge( $nodes, self::getExitList( $ip ) ) ); |
| 77 | + } |
| 78 | + |
| 79 | + global $wgMemc; |
| 80 | + |
| 81 | + $wgMemc->set( 'mw-tor-exit-nodes', $nodes, 1800 ); // Store for half an hour. |
| 82 | + |
| 83 | + return $nodes; |
| 84 | + } |
| 85 | + |
| 86 | + public static function getExitList( $ip ) { |
| 87 | + $url = 'https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip='.$ip; |
| 88 | + |
| 89 | + $data = Http::get( $url ); |
| 90 | + |
| 91 | + $lines = split("\n", $data); |
| 92 | + |
| 93 | + $nodes = array(); |
| 94 | + |
| 95 | + foreach( $lines as $line ) { |
| 96 | + if (strpos( $line, '#' )===false) { |
| 97 | + $nodes[] = trim($line); |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + return $nodes; |
| 102 | + } |
| 103 | + |
| 104 | + public static function isExitNode($ip = null) { |
| 105 | + #return true; ## FOR DEBUGGING |
| 106 | + if ($ip == null) { |
| 107 | + $ip = wfGetIp(); |
| 108 | + } |
| 109 | + |
| 110 | + $nodes = self::getExitNodes(); |
| 111 | + |
| 112 | + return in_array( $ip, $nodes ); |
| 113 | + } |
| 114 | + |
| 115 | + public static function onGetBlockedStatus( &$user ) { |
| 116 | + if (self::isExitNode() && $user->mBlock && !$user->mBlock->mUser) { |
| 117 | + wfDebug( "User using Tor node. Disabling IP block as it was probably targetted at the tor node." ); |
| 118 | + // Node is probably blocked for being a Tor node. Remove block. |
| 119 | + $user->mBlockedBy = 0; |
| 120 | + } |
| 121 | + |
| 122 | + return true; |
| 123 | + } |
| 124 | + |
| 125 | + public static function onAbortAutoblock( $autoblockip, &$block ) { |
| 126 | + return !self::isExitNode( $autoblockip ); |
| 127 | + } |
| 128 | + |
| 129 | + public static function onGetAutoPromoteGroups( $user, &$promote ) { |
| 130 | + if (self::isExitNode()) { |
| 131 | + // Check against stricter requirements. |
| 132 | + $age = time() - wfTimestampOrNull( TS_UNIX, $user->getRegistration() ); |
| 133 | + |
| 134 | + global $wgTorAutoConfirmAge, $wgTorAutoConfirmCount; |
| 135 | + |
| 136 | + if ($age < $wgTorAutoConfirmAge || $user->getEditCount() < $wgTorAutoConfirmCount) { |
| 137 | + // No! |
| 138 | + $promote = array(); |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + return true; |
| 143 | + } |
| 144 | +} |
Property changes on: trunk/extensions/TorBlock/TorBlock.class.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 145 | + native |