plugins/spamx/IP.Examine.class.php
author Dirk Haun <dirk@haun-online.de>
Thu, 29 Oct 2009 13:00:11 +0100
branchHEAD
changeset 7397 c27e9026f22a
parent 6920 add909bdec43
child 7557 20535c7a6847
permissions -rw-r--r--
Fixed inclusion protection
     1 <?php
     2 
     3 /**
     4 * File: IP.Examine.class.php
     5 * This is the IP BlackList Examine class for the Geeklog Spam-X plugin
     6 *
     7 * Copyright (C) 2004-2007 by the following authors:
     8 * Author        Tom Willett        tomw AT pigstye DOT net
     9 *
    10 * Licensed under GNU General Public License
    11 *
    12 * @package Spam-X
    13 * @subpackage Modules
    14 */
    15 
    16 if (strpos(strtolower($_SERVER['PHP_SELF']), 'ip.examine.class.php') !== false) {
    17     die('This file can not be used on its own!');
    18 }
    19 
    20 /**
    21 * Include Abstract Examine Class
    22 */
    23 require_once $_CONF['path'] . 'plugins/spamx/' . 'BaseCommand.class.php';
    24 
    25 /**
    26 * Examines Comment according to Personal BLacklist
    27 *
    28 * @author Tom Willett tomw AT pigstye DOT net
    29 *
    30 * @package Spam-X
    31 *
    32 */
    33 class IP extends BaseCommand {
    34     /**
    35      * No Constructor Use BaseCommand constructor
    36      */
    37 
    38     /**
    39      * The execute method examines the IP address a comment is coming from,
    40      * comparing it against a blacklist of banned IP addresses.
    41      *
    42      * @param $comment string                 Comment text to examine
    43      */
    44     function execute($comment)
    45     {
    46         return $this->_process($_SERVER['REMOTE_ADDR']);
    47     }
    48 
    49     /**
    50      * The re-execute method is used to massdelete spam, essentially
    51      * it does the same as execute, but is called with recorded comments
    52      * in order to match them against new rules that were not in effect
    53      * at the time of posting. To do that, it uses the IP address logged
    54      * when the comment was saved.
    55      *
    56      * @param $comment string            Comment text to examine
    57      * @param $date       unixtimestamp  Date/time the comment was posted
    58      * @param $ip         string         IPAddress comment posted from
    59      * @param $type       string         Type of comment (article etc)
    60      */
    61     function reexecute($comment, $date, $ip, $type)
    62     {
    63         return $this->_process($ip);
    64     }
    65 
    66     /**
    67      * Private internal method to match an IP address against a CIDR
    68      *
    69      * @param   string  $iptocheck  IP address to check
    70      * @param   string  $CIDR       IP address range to check against
    71      * @return  boolean             true if IP falls into the CIDR, else false
    72      *
    73      * Original author: Ian B, taken from
    74      * http://www.php.net/manual/en/function.ip2long.php#71939
    75      *
    76      */
    77     function _matchCIDR ($iptocheck, $CIDR)
    78     {
    79         // get the base and the bits from the ban in the database
    80         list($base, $bits) = explode('/', $CIDR);
    81 
    82         // now split it up into its classes
    83         $classes = explode('.', $base);
    84         $elements = count($classes);
    85         if ($elements < 4) {
    86             for ($i = $elements; $i < 4; $i++) {
    87                 $classes[$i] = 0;
    88             }
    89         }
    90         list($a, $b, $c, $d) = $classes;
    91 
    92         // now do some bit shifting/switching to convert to ints
    93         $i = ($a << 24) + ($b << 16) + ($c << 8) + $d;
    94         $mask = $bits == 0 ? 0 : (~0 << (32 - $bits));
    95 
    96         // here's our lowest int
    97         $low = $i & $mask;
    98 
    99         // here's our highest int
   100         $high = $i | (~$mask & 0xFFFFFFFF);
   101 
   102         // now split the ip we're checking against up into classes
   103         $ex = explode('.', $iptocheck);
   104 
   105         if (count($ex) == 4) {
   106             // now convert the ip we're checking against to an int
   107             $check = ($ex[0] << 24) + ($ex[1] << 16) + ($ex[2] << 8) + $ex[3];
   108 
   109             // if the ip is within the range, including
   110             // highest/lowest values, then it's witin the CIDR range
   111             if (($check >= $low) && ($check <= $high)) {
   112                 return true;
   113             }
   114         }
   115 
   116         return false;
   117     }
   118 
   119     /**
   120      * Private internal method to match an IP address against an address range
   121      *
   122      * @param   string  $ip     IP address to check
   123      * @param   string  $range  IP address range to check against
   124      * @return  boolean         true if IP falls into the IP range, else false
   125      *
   126      * Original authors: dh06 and Stephane, taken from
   127      * http://www.php.net/manual/en/function.ip2long.php#70707
   128      *
   129      */
   130     function _matchRange ($ip, $range)
   131     {
   132         $d = strpos ($range, '-');
   133         if ($d !== false) {
   134            $from = ip2long (trim (substr ($range, 0, $d)));
   135            $to = ip2long (trim (substr ($range, $d + 1)));
   136 
   137            $ip = ip2long ($ip);
   138            return (($ip >= $from) && ($ip <= $to));
   139         }
   140 
   141         return false;
   142     }
   143 
   144     /**
   145      * Private internal method, this actually processes a given ip
   146      * address against a blacklist of IP regular expressions.
   147      *
   148      * @param $ip    string    IP address of comment poster
   149      */
   150     function _process($ip)
   151     {
   152         global $_CONF, $_TABLES, $_USER, $LANG_SX00, $result;
   153 
   154         if (isset ($_USER['uid']) && ($_USER['uid'] > 1)) {
   155             $uid = $_USER['uid'];
   156         } else {
   157             $uid = 1;
   158         }
   159 
   160         /**
   161          * Include Blacklist Data
   162          */
   163         $result = DB_query("SELECT value FROM {$_TABLES['spamx']} WHERE name='IP'", 1);
   164         $nrows = DB_numRows($result);
   165 
   166         $ans = 0;
   167         for ($i = 0; $i < $nrows; $i++) {
   168             list ($val) = DB_fetchArray ($result);
   169 
   170             $matches = false;
   171             if (strpos ($val, '/') !== false) {
   172                 $matches = $this->_matchCIDR ($ip, $val);
   173             } else if (strpos ($val, '-') !== false) {
   174                 $matches = $this->_matchRange ($ip, $val);
   175             } else {
   176                 $matches = (preg_match ("#$val#i", $ip) == 0 ? false : true);
   177             }
   178 
   179             if ($matches) {
   180                 $ans = 1; // quit on first positive match
   181                 SPAMX_log ($LANG_SX00['foundspam'] . $val .
   182                            $LANG_SX00['foundspam2'] . $uid .
   183                            $LANG_SX00['foundspam3'] . $ip);
   184                 break;
   185             }
   186         }
   187 
   188         return $ans;
   189     }
   190 }
   191 
   192 ?>