2012-10-11 08:00:15 +00:00
< ?
class Tools {
/**
* Returns true if given IP is banned .
*
* @ param string $IP
*/
2013-04-19 08:00:55 +00:00
public static function site_ban_ip ( $IP ) {
2013-08-28 23:08:41 +00:00
global $Debug ;
2013-04-19 08:00:55 +00:00
$A = substr ( $IP , 0 , strcspn ( $IP , '.' ));
$IPNum = Tools :: ip_to_unsigned ( $IP );
2013-08-28 23:08:41 +00:00
$IPBans = G :: $Cache -> get_value ( 'ip_bans_' . $A );
2013-04-19 08:00:55 +00:00
if ( ! is_array ( $IPBans )) {
2013-05-28 08:01:02 +00:00
$SQL = sprintf ( "
SELECT ID , FromIP , ToIP
FROM ip_bans
WHERE FromIP BETWEEN % d << 24 AND ( % d << 24 ) - 1 " , $A , $A + 1);
2013-08-28 23:08:41 +00:00
$QueryID = G :: $DB -> get_query_id ();
G :: $DB -> query ( $SQL );
$IPBans = G :: $DB -> to_array ( 0 , MYSQLI_NUM );
G :: $DB -> set_query_id ( $QueryID );
G :: $Cache -> cache_value ( 'ip_bans_' . $A , $IPBans , 0 );
2013-04-19 08:00:55 +00:00
}
foreach ( $IPBans as $Index => $IPBan ) {
list ( $ID , $FromIP , $ToIP ) = $IPBan ;
if ( $IPNum >= $FromIP && $IPNum <= $ToIP ) {
return true ;
}
2013-02-06 08:00:17 +00:00
}
2013-04-20 08:01:01 +00:00
2013-04-19 08:00:55 +00:00
return false ;
2013-02-06 08:00:17 +00:00
}
2012-10-11 08:00:15 +00:00
/**
* Returns the unsigned form of an IP address .
*
* @ param string $IP The IP address x . x . x . x
* @ return string the long it represents .
*/
public static function ip_to_unsigned ( $IP ) {
2013-04-19 08:00:55 +00:00
return sprintf ( '%u' , ip2long ( $IP ));
2012-10-11 08:00:15 +00:00
}
/**
* Geolocate an IP address using the database
*
* @ param $IP the ip to fetch the country for
* @ return the country of origin
*/
public static function geoip ( $IP ) {
static $IPs = array ();
if ( isset ( $IPs [ $IP ])) {
return $IPs [ $IP ];
}
2013-02-10 08:00:29 +00:00
if ( is_number ( $IP )) {
$Long = $IP ;
} else {
$Long = Tools :: ip_to_unsigned ( $IP );
}
2013-04-18 08:00:54 +00:00
if ( ! $Long || $Long == 2130706433 ) { // No need to check cc for 127.0.0.1
2012-10-11 08:00:15 +00:00
return false ;
}
2013-08-28 23:08:41 +00:00
$QueryID = G :: $DB -> get_query_id ();
G :: $DB -> query ( "
2013-05-28 08:01:02 +00:00
SELECT EndIP , Code
FROM geoip_country
WHERE $Long >= StartIP
ORDER BY StartIP DESC
LIMIT 1 " );
2013-08-28 23:08:41 +00:00
if (( ! list ( $EndIP , $Country ) = G :: $DB -> next_record ()) || $EndIP < $Long ) {
2012-10-11 08:00:15 +00:00
$Country = '?' ;
}
2013-08-28 23:08:41 +00:00
G :: $DB -> set_query_id ( $QueryID );
2012-10-11 08:00:15 +00:00
$IPs [ $IP ] = $Country ;
return $Country ;
}
/**
* Gets the hostname for an IP address
*
* @ param $IP the IP to get the hostname for
* @ return hostname fetched
*/
2013-04-19 08:00:55 +00:00
public static function get_host_by_ip ( $IP ) {
2013-05-28 08:01:02 +00:00
$testar = explode ( '.' , $IP );
2013-04-19 08:00:55 +00:00
if ( count ( $testar ) != 4 ) {
2012-10-11 08:00:15 +00:00
return $IP ;
}
2013-04-19 08:00:55 +00:00
for ( $i = 0 ; $i < 4 ; ++ $i ) {
2012-10-11 08:00:15 +00:00
if ( ! is_numeric ( $testar [ $i ])) {
return $IP ;
}
}
$host = `host -W 1 $IP` ;
2013-05-28 08:01:02 +00:00
return ( $host ? end ( explode ( ' ' , $host )) : $IP );
2012-10-11 08:00:15 +00:00
}
/**
* Gets an hostname using AJAX
*
* @ param $IP the IP to fetch
2013-06-17 08:01:02 +00:00
* @ return a span with JavaScript code
2012-10-11 08:00:15 +00:00
*/
public static function get_host_by_ajax ( $IP ) {
2015-01-28 08:00:26 +00:00
static $IPs = array ();
$Class = strtr ( $IP , '.' , '-' );
$HTML = '<span class="host_' . $Class . '">Resolving host...' ;
if ( ! isset ( $IPs [ $IP ])) {
$HTML .= '<script type="text/javascript">' .
'$(document).ready(function() {' .
'$.get(\'tools.php?action=get_host&ip=' . $IP . '\', function(host) {' .
'$(\'.host_' . $Class . '\').html(host);' .
'});' .
'});' .
'</script>' ;
}
$HTML .= '</span>' ;
$IPs [ $IP ] = 1 ;
return $HTML ;
2012-10-11 08:00:15 +00:00
}
/**
* Looks up the full host of an IP address , by system call .
* Used as the server - side counterpart to get_host_by_ajax .
*
* @ param string $IP The IP address to look up .
* @ return string the host .
*/
public static function lookup_ip ( $IP ) {
2013-08-28 23:08:41 +00:00
//TODO: use the G::$Cache
2012-10-11 08:00:15 +00:00
$Output = explode ( ' ' , shell_exec ( 'host -W 1 ' . escapeshellarg ( $IP )));
2013-04-18 08:00:54 +00:00
if ( count ( $Output ) == 1 && empty ( $Output [ 0 ])) {
2012-10-11 08:00:15 +00:00
//No output at all implies the command failed
return '' ;
}
2013-04-18 08:00:54 +00:00
if ( count ( $Output ) != 5 ) {
2012-10-11 08:00:15 +00:00
return false ;
} else {
2013-01-19 08:00:51 +00:00
return trim ( $Output [ 4 ]);
2012-10-11 08:00:15 +00:00
}
}
/**
* Format an IP address with links to IP history .
*
* @ param string IP
* @ return string The HTML
*/
public static function display_ip ( $IP ) {
$Line = display_str ( $IP ) . ' (' . Tools :: get_country_code_by_ajax ( $IP ) . ') ' ;
2013-10-26 08:00:58 +00:00
$Line .= '<a href="user.php?action=search&ip_history=on&ip=' . display_str ( $IP ) . '&matchtype=strict" title="Search" class="brackets tooltip">S</a>' ;
2013-05-16 16:15:57 +00:00
2012-10-11 08:00:15 +00:00
return $Line ;
}
public static function get_country_code_by_ajax ( $IP ) {
2015-01-28 08:00:26 +00:00
static $IPs = array ();
$Class = strtr ( $IP , '.' , '-' );
$HTML = '<span class="cc_' . $Class . '">Resolving CC...' ;
if ( ! isset ( $IPs [ $IP ])) {
$HTML .= '<script type="text/javascript">' .
'$(document).ready(function() {' .
'$.get(\'tools.php?action=get_cc&ip=' . $IP . '\', function(cc) {' .
'$(\'.cc_' . $Class . '\').html(cc);' .
'});' .
'});' .
'</script>' ;
}
$HTML .= '</span>' ;
$IPs [ $IP ] = 1 ;
return $HTML ;
2012-10-11 08:00:15 +00:00
}
/**
* Disable an array of users .
*
* @ param array $UserIDs ( You can also send it one ID as an int , because fuck types )
* @ param BanReason 0 - Unknown , 1 - Manual , 2 - Ratio , 3 - Inactive , 4 - Unused .
*/
public static function disable_users ( $UserIDs , $AdminComment , $BanReason = 1 ) {
2013-08-28 23:08:41 +00:00
$QueryID = G :: $DB -> get_query_id ();
2013-04-18 08:00:54 +00:00
if ( ! is_array ( $UserIDs )) {
2012-10-11 08:00:15 +00:00
$UserIDs = array ( $UserIDs );
}
2013-08-28 23:08:41 +00:00
G :: $DB -> query ( "
2013-04-20 08:01:01 +00:00
UPDATE users_info AS i
2014-02-19 08:00:32 +00:00
JOIN users_main AS m ON m . ID = i . UserID
SET m . Enabled = '2' ,
m . can_leech = '0' ,
2013-04-20 08:01:01 +00:00
i . AdminComment = CONCAT ( '".sqltime()." - ".($AdminComment ? $AdminComment : ' Disabled by system ')."\n\n' , i . AdminComment ),
2014-02-19 08:00:32 +00:00
i . BanDate = '".sqltime()."' ,
i . BanReason = '$BanReason' ,
i . RatioWatchDownload = " .( $BanReason == 2 ? 'm.Downloaded' : " '0' " ). "
2013-06-18 08:00:48 +00:00
WHERE m . ID IN ( " .implode(',', $UserIDs ).') ');
2013-08-28 23:08:41 +00:00
G :: $Cache -> decrement ( 'stats_user_count' , G :: $DB -> affected_rows ());
2013-04-20 08:01:01 +00:00
foreach ( $UserIDs as $UserID ) {
2013-08-28 23:08:41 +00:00
G :: $Cache -> delete_value ( " enabled_ $UserID " );
G :: $Cache -> delete_value ( " user_info_ $UserID " );
G :: $Cache -> delete_value ( " user_info_heavy_ $UserID " );
G :: $Cache -> delete_value ( " user_stats_ $UserID " );
2012-10-11 08:00:15 +00:00
2013-08-28 23:08:41 +00:00
G :: $DB -> query ( "
2013-06-06 08:01:03 +00:00
SELECT SessionID
FROM users_sessions
2013-08-28 23:08:41 +00:00
WHERE UserID = '$UserID'
2013-06-06 08:01:03 +00:00
AND Active = 1 " );
2013-08-28 23:08:41 +00:00
while ( list ( $SessionID ) = G :: $DB -> next_record ()) {
G :: $Cache -> delete_value ( " session_ $UserID " . " _ $SessionID " );
2012-10-11 08:00:15 +00:00
}
2013-08-28 23:08:41 +00:00
G :: $Cache -> delete_value ( " users_sessions_ $UserID " );
2013-05-16 16:15:57 +00:00
2013-08-28 23:08:41 +00:00
G :: $DB -> query ( "
2013-06-06 08:01:03 +00:00
DELETE FROM users_sessions
2013-08-28 23:08:41 +00:00
WHERE UserID = '$UserID' " );
2013-05-16 16:15:57 +00:00
2012-10-11 08:00:15 +00:00
}
// Remove the users from the tracker.
2013-08-28 23:08:41 +00:00
G :: $DB -> query ( '
2013-06-06 08:01:03 +00:00
SELECT torrent_pass
FROM users_main
2013-08-28 23:08:41 +00:00
WHERE ID in ( '.implode(' , ', $UserIDs).' ) ' );
$PassKeys = G :: $DB -> collect ( 'torrent_pass' );
2013-04-18 08:00:54 +00:00
$Concat = '' ;
foreach ( $PassKeys as $PassKey ) {
if ( strlen ( $Concat ) > 3950 ) { // Ocelot's read buffer is 4 KiB and anything exceeding it is truncated
2012-10-11 08:00:15 +00:00
Tracker :: update_tracker ( 'remove_users' , array ( 'passkeys' => $Concat ));
$Concat = $PassKey ;
} else {
$Concat .= $PassKey ;
}
}
Tracker :: update_tracker ( 'remove_users' , array ( 'passkeys' => $Concat ));
2013-08-28 23:08:41 +00:00
G :: $DB -> set_query_id ( $QueryID );
2012-10-11 08:00:15 +00:00
}
/**
* Warn a user .
*
* @ param int $UserID
* @ param int $Duration length of warning in seconds
* @ param string $reason
*/
public static function warn_user ( $UserID , $Duration , $Reason ) {
2013-08-28 23:08:41 +00:00
global $Time ;
2012-10-11 08:00:15 +00:00
2013-08-28 23:08:41 +00:00
$QueryID = G :: $DB -> get_query_id ();
G :: $DB -> query ( "
2013-04-19 08:00:55 +00:00
SELECT Warned
FROM users_info
2013-08-28 23:08:41 +00:00
WHERE UserID = $UserID
2013-05-27 08:00:58 +00:00
AND Warned != '0000-00-00 00:00:00' " );
2013-08-28 23:08:41 +00:00
if ( G :: $DB -> has_results ()) {
2012-10-11 08:00:15 +00:00
//User was already warned, appending new warning to old.
2013-08-28 23:08:41 +00:00
list ( $OldDate ) = G :: $DB -> next_record ();
2012-10-11 08:00:15 +00:00
$NewExpDate = date ( 'Y-m-d H:i:s' , strtotime ( $OldDate ) + $Duration );
Misc :: send_pm ( $UserID , 0 ,
2013-04-19 08:00:55 +00:00
'You have received multiple warnings.' ,
2013-08-28 23:08:41 +00:00
" When you received your latest warning (set to expire on " . date ( 'Y-m-d' , ( time () + $Duration )) . '), you already had a different warning (set to expire on ' . date ( 'Y-m-d' , strtotime ( $OldDate )) . " ). \n \n Due to this collision, your warning status will now expire at $NewExpDate . " );
2012-10-11 08:00:15 +00:00
2013-08-28 23:08:41 +00:00
$AdminComment = date ( 'Y-m-d' ) . " - Warning (Clash) extended to expire at $NewExpDate by " . G :: $LoggedUser [ 'Username' ] . " \n Reason: $Reason\n\n " ;
2012-10-11 08:00:15 +00:00
2013-08-28 23:08:41 +00:00
G :: $DB -> query ( '
2013-05-16 16:15:57 +00:00
UPDATE users_info
SET
2013-08-28 23:08:41 +00:00
Warned = \ '' . db_string ( $NewExpDate ) . ' \ ' ,
WarnedTimes = WarnedTimes + 1 ,
AdminComment = CONCAT ( \ '' . db_string ( $AdminComment ) . ' \ ' , AdminComment )
WHERE UserID = \ '' . db_string ( $UserID ) . '\'' );
2012-10-11 08:00:15 +00:00
} else {
//Not changing, user was not already warned
$WarnTime = time_plus ( $Duration );
2013-08-28 23:08:41 +00:00
G :: $Cache -> begin_transaction ( " user_info_ $UserID " );
G :: $Cache -> update_row ( false , array ( 'Warned' => $WarnTime ));
G :: $Cache -> commit_transaction ( 0 );
2012-10-11 08:00:15 +00:00
2013-08-28 23:08:41 +00:00
$AdminComment = date ( 'Y-m-d' ) . " - Warned until $WarnTime by " . G :: $LoggedUser [ 'Username' ] . " \n Reason: $Reason\n\n " ;
2012-10-11 08:00:15 +00:00
2013-08-28 23:08:41 +00:00
G :: $DB -> query ( '
2013-05-16 16:15:57 +00:00
UPDATE users_info
SET
2013-08-28 23:08:41 +00:00
Warned = \ '' . db_string ( $WarnTime ) . ' \ ' ,
WarnedTimes = WarnedTimes + 1 ,
2014-02-19 08:00:32 +00:00
AdminComment = CONCAT ( \ '' . db_string ( $AdminComment ) . ' \ ' , AdminComment )
2013-08-28 23:08:41 +00:00
WHERE UserID = \ '' . db_string ( $UserID ) . '\'' );
2012-10-11 08:00:15 +00:00
}
2013-08-28 23:08:41 +00:00
G :: $DB -> set_query_id ( $QueryID );
2012-10-11 08:00:15 +00:00
}
2013-02-10 08:00:29 +00:00
2012-10-19 08:00:17 +00:00
/**
* Update the notes of a user
* @ param unknown $UserID ID of user
* @ param unknown $AdminComment Comment to update with
*/
public static function update_user_notes ( $UserID , $AdminComment ) {
2013-08-28 23:08:41 +00:00
$QueryID = G :: $DB -> get_query_id ();
G :: $DB -> query ( '
2013-05-16 16:15:57 +00:00
UPDATE users_info
2014-02-19 08:00:32 +00:00
SET AdminComment = CONCAT ( \ '' . db_string ( $AdminComment ) . ' \ ' , AdminComment )
2013-08-28 23:08:41 +00:00
WHERE UserID = \ '' . db_string ( $UserID ) . '\'' );
G :: $DB -> set_query_id ( $QueryID );
2012-10-19 08:00:17 +00:00
}
2014-08-11 08:00:26 +00:00
/**
2014-08-13 08:00:26 +00:00
* Check if an IP address is part of a given CIDR range .
* @ param string $CheckIP the IP address to be looked up
2014-08-11 08:00:26 +00:00
* @ param string $Subnet the CIDR subnet to be checked against
*/
public static function check_cidr_range ( $CheckIP , $Subnet ) {
$IP = ip2long ( $CheckIP );
2014-08-13 08:00:26 +00:00
$CIDR = split ( '/' , $Subnet );
2014-08-11 08:00:26 +00:00
$SubnetIP = ip2long ( $CIDR [ 0 ]);
$SubnetMaskBits = 32 - $CIDR [ 1 ];
return (( $IP >> $SubnetMaskBits ) == ( $SubnetIP >> $SubnetMaskBits ));
}
2012-10-11 08:00:15 +00:00
}
?>