<?php

	include_once( PLOG_CLASS_PATH."class/security/pipelinefilter.class.php" );
    include_once( PLOG_CLASS_PATH."class/net/client.class.php" );	

    // custom error code that will be returned to the pipeline whenever an
    // error is found... Be careful so as to not to have two different modules
    // use the same code!!
    define( "DNS_ANTISPAM_MATCH_FOUND", 600 );

	class DNSAntiSpamFilter extends PipelineFilter 
	{

    	function DNSAntiSpamFilter( $pipelineRequest )
        {
        	$this->PipelineFilter( $pipelineRequest );
        }

        function filter()
        {
        	// get some info
            $blogInfo = $this->_pipelineRequest->getBlogInfo();
            $request  = $this->_pipelineRequest->getHttpRequest();

        	// check if this section has been enabled or disabled
            $blogSettings = $blogInfo->getSettings();
		    $pluginEnabled = $blogSettings->getValue( "plugin_dnsantispam_enabled" );
            if( !$pluginEnabled) {
            	// if not, nothing to do here...
                //_debug("ip address filter not enabled! quitting...<br/>");
            	return new PipelineResult();
            }

            // we only have to filter the contents if the user is posting a comment
            // so there's no point in doing anything else if that's not the case
            if( $request->getValue( "op" ) != "AddComment" ) {
            	$result = new PipelineResult();
                return $result;
            }

            // text and topic of the comment
            $commentText = $request->getValue( "commentText" );
            $commentTopic = $request->getValue( "commentTopic" );
            $userName = $request->getValue( "userName" );
            $userEmail = $request->getValue( "userEmail" );
            $userUrl = $request->getValue( "userUrl" );
            $clientIp = Client::getIp();
            $locale = $blogInfo->getLocale();            
                        
          	if( !$this->checkClientIP( $clientIp ) ) {
               	// if there is a match, we can quit and reject this request
                $result = new PipelineResult( false, DNS_ANTISPAM_MATCH_FOUND, $locale->tr("error_dnsantispam_client_ip_banned") );
                return $result;
            }

          	if( !$this->checkCommentText( $commentTopic ) ) {
               	// if there is a match, we can quit and reject this request
                $result = new PipelineResult( false, DNS_ANTISPAM_MATCH_FOUND, $locale->tr("error_dnsantispam_comment_topic_banned") );
                return $result;
            }

          	if( !$this->checkCommentText( $commentText ) ) {
               	// if there is a match, we can quit and reject this request
                $result = new PipelineResult( false, DNS_ANTISPAM_MATCH_FOUND, $locale->tr("error_dnsantispam_comment_text_banned") );
                return $result;
            }

          	if( !$this->checkCommentText( $userName ) ) {
               	// if there is a match, we can quit and reject this request
                $result = new PipelineResult( false, DNS_ANTISPAM_MATCH_FOUND, $locale->tr("error_dnsantispam_user_name_banned") );
                return $result;
            }                        
            
          	if( !$this->checkCommentURL( $userUrl ) ) {
               	// if there is a match, we can quit and reject this request
                $result = new PipelineResult( false, DNS_ANTISPAM_MATCH_FOUND, $locale->tr("error_dnsantispam_comment_url_banned") );
                return $result;
            }

            // if everything went fine, we can say so by returning
            // a positive PipelineResult object
            $result = new PipelineResult( true );
            
            return $result;
        }

        // The following function comese from John Sinteur
        /*
        Plugin Name: Block-lists anti-spam measures
        Version: 1.5.1
        Plugin URI: http://weblog.sinteur.com/index.php?p=8106
        Description: check if a comment poster is on an open proxy list, and check if the content contains known spammer domains
        Author: John Sinteur, with a big thank you to io_error!
        Author URI: http://weblog.sinteur.com/
        */

        function checkClientIP( $spammer_ip )
        {
            $rev = array_reverse(explode('.', $spammer_ip));
        
            $lookup = implode('.', $rev) . '.' . 'l1.spews.dnsbl.sorbs.net.';
        
            if ($lookup != gethostbyname($lookup)) {
                return false;
            }
            $lookup = implode('.', $rev) . '.' . 'sbl-xbl.spamhaus.org.';
            if ($lookup != gethostbyname($lookup)) {
                return false;
            }
            $lookup = implode('.', $rev) . '.' . 'list.dsbl.org.';
            if ($lookup != gethostbyname($lookup)) {
                return false;
            }
        
            return true ;
        }
        
        // for a full explanation, see http://www.surbl.org 
        // summary: blocks comment if it contains an url that's on a known spammers list.
        function checkCommentText ( $comment_text )
        {
            //get site names found in body of comment.
            $regex_url   = "/(www.)([^\/\"<\s]*)/im";
            $mk_regex_array = array();
            preg_match_all($regex_url, $comment_text, $mk_regex_array);
                
            for( $cnt=0; $cnt < count($mk_regex_array[2]); $cnt++ ) {
                $domain_to_test = rtrim($mk_regex_array[2][$cnt],"\\");
                if (strlen($domain_to_test) > 3)
                {
                    $domain_to_test = $domain_to_test . ".multi.surbl.org.";
                    if( gethostbyname($domain_to_test) != $domain_to_test ) {
                        return false;
                    }
                }
            }
            return true;
        }

        // for a full explanation, see http://www.surbl.org 
        // summary: blocks comment if it contains an url that's on a known spammers list.
        function checkCommentURL ( $comment_url )
        {
            $pieces = explode('/',$comment_url);
            for( $cnt=0; $cnt < count($pieces); $cnt++ ) {
                $short_url = $pieces[$cnt];
        
                if ($short_url != 'http')
                {
                    $short_url = str_replace("www.", "", "$short_url");
                    if (strlen($short_url) > 3)
                    {
                        $domain_to_test = $short_url . ".multi.surbl.org.";
                        if( gethostbyname($domain_to_test) != $domain_to_test ) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }        
    }
?>
