<?

/**
 * referer_check.mod.php
 * @package   Modules
 * This module needs rework !!!!!!!!
 */

/**
 * Module name
 */
define("MOD_REFERERCHECK",$name);

/**
 * Allow option
 */
define("ALLOW",1);
/**
 * Deny option
 */
define("DENY",2);
/**
 * Allowfile option
 */
define("ALLOWFILE",3);
/**
 * Denyfile option
 */
define("DENYFILE",4);

$modules[$name]= new RefererCheckModule();

/**
 * RefererCheckModule
 *
 * This module checks the referer. It is possible to only accept a set of
 * forms to use the script. It is also possible to do different things with
 * different referers. Last possibility of this module is to show the form
 * that called this script with some error. The error messages can be shown
 * within the form. This can be done by adding some template-code to the
 * form. The default is that the errors are printed at the beginning or the
 * end of the form. It is usefull to use the cookie-module too, zo the
 * script can fill in the fields already entered with the cookies that are
 * set.
 * @package   Modules
 * @author    Herman Suijs
 */

class RefererCheckModule extends Module {
  var 
$name "RefererCheckModule";
  var 
$id MOD_REFERERCHECK;
  var 
$execlevel 10;
  var 
$referer "";
  var 
$refererip "";
  var 
$allow = array();
  var 
$deny = array();

  
/**
   * Constructor
   *
   * Set options and call the superConstructor
   */
  
function RefererCheckModule() {
    
//$this->options[] = new Option("name:alias1:alias2","regular expression",required,stay_enabled_if_omitted,"default");
    
$this->options[ALLOW] = new Option("allow:referer_allow");
    
$this->options[DENY] = new Option("deny:referer_deny");
    
$this->options[ALLOWFILE] = new Option("allowfile:referer_allowfile");
    
$this->options[DENYFILE] = new Option("denyfile:referer_denyfile");
    
$this->Module();
  } 
/* function RefererCheckModule() */
  
  /**
   * Before action
   *
   * Check if the referer exists, check the options and create an allow and
   * a deny array with ip-addresses and hostnames
   */
  
function before_action() {
    global 
$HTTP_REFERER,$debug;
    
$this->check_options(); // necessary for intergration with class module

    
$this->referer=ereg_replace("http:\/\/([^\/]+).*","\\1",$HTTP_REFERER);
    
$this->refererip=gethostbyname($this->referer);
    
$debug->add(DB_INPUT,$this->name,"HTTP_REFERER ($HTTP_REFERER): %s %s",$this->referer,$this->refererip);

    if (empty(
$this->referer)) {
      
$debug->add(DB_WARN,$this->name,"No referer found; this means you use a buggy browser (IE 5?)");
      
$this->disable;
    } 
/* if (empty($this->referer)) */

    
if ($this->options[ALLOW]) {
      
$this->allow explode(REFEREROPTION_SEP,$this->options[ALLOW]->value);
      if (!
is_array($this->allow)) {
    
$this->allow[0] = $this->allow;
      } 
/* if (!is_array($this->allow)) */
      
$debug->add(DB_XFLOW,$this->name,"Allow option added");
    } 
/* if ($this->options[ALLOW]) */

    // ********* THe allow file and denyfile options should only be set in
    // configfile.inc.php.
    // **********
    
if ($this->options[ALLOWFILE]&&is_file(CONFIG_DIR."/".$this->options[ALLOWFILE]->value)) {
      
$allowfile=file(CONFIG_DIR."/".$this->options[ALLOWFILE]->value);
      while (list(,
$value) = each($allowfile)) {
    if (!
ereg(COMMENT_LINE,$value)) {
      
$value ereg_replace("([^\.])\*","\\1.*",$value);
      
$value ereg_replace("^[[:space:]]+","",$value);
      
$value ereg_replace("[[:space:]]+$","",$value);
      
$value ereg_replace("\n","",$value);
      
$allowlist[] = $value;
    } 
/* if (!ereg(COMMENT_LINE,$value)... */
      
/* while (list(,$value) = each($a... */
      
$this->allow=array_merge($allowlist,$this->allow); // in this order the form entries override the file
      
$debug->add(DB_FLOW,$this->name,"Allowfile %s read in",CONFIG_DIR."/".$this->options[ALLOWFILE]->value);
    } else 
$debug->add(DB_XFLOW,$this->name,"Allowfile %s not found",$this->options[ALLOWFILE]->value);

    if (
$this->options[DENY]) {
      
$this->deny explode(OPTION_SEP,$this->options[DENY]->value);
      if (!
is_array($this->deny)) {
    
$this->deny[0] = $this->deny;
      } 
/* if (!is_array($this->deny)) */
      
$debug->add(DB_XFLOW,$this->name,"Deny option added");
    } 
/* if ($this->options[DENY]) */

    
if ($this->options[DENYFILE]&&is_file(CONFIG_DIR."/".$this->options[DENYFILE]->value)) {
      
$denyfile=file(CONFIG_DIR."/".$this->options[DENYFILE]->value);
      while (list(,
$value) = each($denyfile)) {
    if (!
ereg(COMMENT_LINE,$value)) {
      
$value ereg_replace("([^\.])(\*)","\\1.*",$value);
      
$value ereg_replace("^[[:space:]]+","",$value);
      
$value ereg_replace("[[:space:]]+$","",$value);
      
$value ereg_replace("\n","",$value);
      
$denylist[] = $value
    } 
/* if (!ereg(COMMENT_LINE,$value)... */
      
/* while (list(,$value) = each($d... */
      
$this->deny=array_merge($denylist,$this->deny); // in this order the form entries override the file
      
$debug->add(DB_FLOW,$this->name,"Denyfile %s read in",CONFIG_DIR."/".$this->options[DENYFILE]->value);
    } else 
$debug->add(DB_XFLOW,$this->name,"Denyfile /* if
    ($this->options[DENYFILE]&&... */ %s not found"
,$this->options[DENYFILE]->value);

  } 
/* function before_action() */

  /**
   * Do action
   *
   * First check if referer is in deny list. If so, exit. If not, check if
   * there is an allow list. If not: allow. If so, only allow when present.
   */
  
function do_action() {
    global 
$debug,$error;
    if (
$this->action()) {
      
// if deny || NOT allow :
      // echo "This script is not legally configured
      //$error->add_message("",$this->name);
      
$deny=false;
      if (!empty(
$this->deny)&&is_array($this->deny)) {
    while (list(,
$value) = each($this->deny)) {
      if (!empty(
$value)) {
        if (
eregi($value,$this->referer)) {
          
$deny=true;
          
$referer=$this->referer;
          break;
       
/* if
        * (eregi($value,$this->refere...
        * */

        if (
ereg($value,$this->refererip)) {
          
$deny=true;
          
$referer=$this->refererip;
          break;
         
/* if
          * (ereg($value,$this->referer...
          * */
}
        
$debug->add(DB_XFLOW,$this->name,"DONOT DENY %s (%s) on %s",$this->referer,$this->refererip,$value);
      } else 
$debug->add(DB_INFO,$this->name,"DENY value is empty (%s)",$value);
    } 
/* while (list(,$value) = each($t... */
    
if ($deny) {
      
$error->add(ERR_INP_END,$this->name,"DENY %s (%s), because in %s of denylist",$referer,$this->referer,$value);
      echo 
"<h1>This should never be printed</h1>";
      exit;
    } 
/* if ($deny) */
      
/* if (!empty($this->deny)&&is_ar... */

      
$deny=true;
      if (!empty(
$this->allow)&&is_array($this->allow)) {
    while(list(,
$value) = each($this->allow)) {
      if (!empty(
$value)) {
        if (
eregi($value,$this->referer)) {
          
$deny=false;
          
$referer=$this->referer;
          break;
        }  
/* if
        (eregi($value,$this->refere...
        */
        
if (ereg($value,$this->refererip)) {
          
$deny=false;
          
$referer=$this->refererip;
          break;
        } 
/* if
        (ereg($value,$this->referer...
        */
        
$debug->add(DB_XFLOW,$this->name,"DONOT ALLOW %s (%s) on %s",$this->referer,$this->refererip,$value);
      } else 
$debug->add(DB_INFO,$this->name,"ALLOW value is empty (%s)",$value);
    } 
/* while(list(,$value) = each($th... */
    
if ($deny) {
      
$error->add(ERR_INP_END,$this->name,"DENY %s, because not in allowlist",$this->referer);
      echo 
"<h1>This should never be printed</h1>";
      exit;
    } else { 
/* if ($deny) */
      
$debug->add(DB_FLOW,$this->name,"ALLOW %s (%s), because in %s of allowlist",$referer,$this->referer,$value);
   
/* if ($deny) { ... } else */      }
      } 
/* if (!empty($this->allow)&&is_a... */
    
/* if ($this->action()) */
  
/* function do_action() */

  /**
   * After action
   *
   * Cleanup
   */
  
function after_action() {
    
$this->clean_up();
  } 
/* function after_action() */
// end class RefererCheckModule /* class RefererCheckModule exten... */