gunnar: server/kolab-filter/filter config.php, 1.3, 1.4 kolabfilter.php, 1.2, 1.3 kolabmailboxfilter.php, 1.2, 1.3

cvs at kolab.org cvs at kolab.org
Mon Nov 26 17:35:23 CET 2007


Author: gunnar

Update of /kolabrepository/server/kolab-filter/filter
In directory doto:/tmp/cvs-serv723/kolab-filter/filter

Modified Files:
	config.php kolabfilter.php kolabmailboxfilter.php 
Log Message:
Restructured Kolab_Filter package with the focus on error
handling and unit testing.

Index: config.php
===================================================================
RCS file: /kolabrepository/server/kolab-filter/filter/config.php,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- config.php	16 Aug 2007 10:53:19 -0000	1.3
+++ config.php	26 Nov 2007 16:35:21 -0000	1.4
@@ -34,95 +34,127 @@
  *
  */
 
-// What is the address of the Cyrus server where the calendar data is stored?
-$params['server'] = 'localhost';
+$conf = array();
+
+/* Horde::Log configuration */
+$conf['log']['enabled']          = true;
+$conf['log']['priority']         = PEAR_LOG_DEBUG; // Leave this on DEBUG for now. We just restructured the package...
+$conf['log']['type']             = 'file';
+$conf['log']['name']             = '/kolab/var/kolab-filter/log/filter.log';
+$conf['log']['ident']            = 'Kolab Filter';
+$conf['log']['params']['append'] = true;
+
+/* PHP error logging */
+$conf['filter']['error_log']     = '/kolab/var/kolab-filter/log/php-error.log';
+
+/* Temporary data storage for the scripts */
+$conf['filter']['tempdir'] = '';
+
+/* What is the address of this host? */
+$conf['filter']['server'] = 'localhost';
+
+/* What is our default mail domain? This is used if any users do not
+ * have '@domain' specified after their username as part of their
+ * email address.
+ */
+$conf['filter']['email_domain'] = 'example.com';
+
+/* LMTP settings (Cyrus IMAPd usually offers LMTP on port 2003) */
+$conf['filter']['lmpt_host'] = 'localhost';
+$conf['filter']['lmpt_port'] = 2003;
+
+/* SMTP settings (Kolab Postfix usually offers reinjection port on
+ * 10025)
+ */
+$conf['filter']['smpt_host'] = 'localhost';
+$conf['filter']['smpt_port'] = 10025;
+
+/* Should we make sure that the sender and From header match for mail
+ * that origins on this server?
+ */
+$conf['filter']['verify_from_header'] = true;
+
+/* Should the Sender: header be used over From: if present? */
+$conf['filter']['allow_sender_header'] = true;
+
+/* Should we allow forwarded ical messages from Outlook
+ * by encapsulating them in a MIME multipart
+ */
+$conf['filter']['allow_outlook_ical_forward']  = true;
+
 
-// What is our default mail domain? This is used if any users do not have
-// '@domain' specified after their username as part of their email address.
-$params['email_domain'] = 'example.com';
 
 // List of kolab hosts that are privileged
-$params['kolabhosts'] = 'one.example.com,two.example.com,three.example.com';
+$conf['kolabhosts'] = 'one.example.com,two.example.com,three.example.com';
 
 // Are we using virtual domains with Cyrus?
-$params['virtual_domains'] = true;
+$conf['virtual_domains'] = true;
 
 // Should we append domains to mailbox URIs? This only applies when
 // virtual_domains is true, and when using manager accounts.
-$params['append_domains'] = false;
-
-// Should we make sure that the sender and From header match for mail
-// that origins on this server?
-$params['verify_from_header'] = true;
+$conf['append_domains'] = false;
 
 // Should we perform this check on mail from our
 // subdomains too?
-$params['verify_subdomains'] = true;
-
-// Should the Sender: header be used over From: if present?
-$params['allow_sender_header'] = true;
+$conf['verify_subdomains'] = true;
 
 // Should reject messages with From headers that dont match
 // the envelope? Default is to rewrite the header
-$params['reject_forged_from_header'] = false;
+$conf['reject_forged_from_header'] = false;
 
 // Text to be inserted in From: when rewriting untrusted mails
-$params['untrusted_subject_insert'] = "(UNTRUSTED, sender is <%s>)";
-$params['unauthenticated_subject_insert'] = "(UNTRUSTED, sender <%s> is not authenticated)";
-
-// Should we allow forwarded ical messages from Outlook
-// by encapsulating them in a MIME multipart
-$params['allow_outlook_ical_forward']  = true;
+$conf['untrusted_subject_insert'] = "(UNTRUSTED, sender is <%s>)";
+$conf['unauthenticated_subject_insert'] = "(UNTRUSTED, sender <%s> is not authenticated)";
 
 // LDAP data
 // What is the address of the LDAP server address where user objects reside
-$params['ldap_uri'] = 'ldaps://ldap.example.com';
+$conf['ldap_uri'] = 'ldaps://ldap.example.com';
 
 // What is the Base DN of our LDAP database?
-$params['base_dn'] = 'dc=example,dc=com';
+$conf['base_dn'] = 'dc=example,dc=com';
 
 // What DN should we use to bind to the LDAP server?
-$params['bind_dn'] = 'cn=nobody,cn=internal,dc=example,dc=com';
+$conf['bind_dn'] = 'cn=nobody,cn=internal,dc=example,dc=com';
 
 // What password should we use with the above DN when binding?
-$params['bind_pw'] = 'xyz';
+$conf['bind_pw'] = 'xyz';
 
 
 // What account should we use to read/write calendar data? This account should
 // have access to the calendar mailbox of all resource/group mailboxes.
-$params['calendar_user'] = 'calendar@'.$params['email_domain'];
-$params['calendar_pass'] = 'zyx';
+$conf['calendar_user'] = 'calendar@'.$conf['email_domain'];
+$conf['calendar_pass'] = 'zyx';
 
 // Filename of private key used to decrypt password from LDAP
-$params['priv_key_file'] = '@sysconfdir@/kolab/res_priv.pem';
+$conf['priv_key_file'] = '@sysconfdir@/kolab/res_priv.pem';
 
 // What is the name of the users' calendar mailbox?
 // This is only used when the user does not already have
 // a primary calendar folder (search via Kolab annotation)
-$params['calendar_store'] = 'Calendar';
+$conf['calendar_store'] = 'Calendar';
 
 // Where can we get free/busy information from?
-$params['freebusy_url'] = 'http://kolab.example.com/freebusy/${USER}.xfb';
+$conf['freebusy_url'] = 'http://kolab.example.com/freebusy/${USER}.xfb';
  
 // PFB url to trigger creation of pfb
-$params['pfb_trigger_url'] = 'http://@@@fqdnhostname@@@/freebusy/trigger/${USER}/${FOLDER}.xpfb';
+$conf['pfb_trigger_url'] = 'http://@@@fqdnhostname@@@/freebusy/trigger/${USER}/${FOLDER}.xpfb';
 
 // Where are we logging to?
-$params['log'] = 'file:@resmgr_logfile@';                // File...
-// $params['log'] = 'syslog:cons, pid';            // Or syslog...
+$conf['log'] = 'file:@resmgr_logfile@';                // File...
+// $conf['log'] = 'syslog:cons, pid';            // Or syslog...
 
 // What level of output should we log? Higher levels give more verbose output.
 // One of: RM_LOG_SILENT; RM_LOG_ERROR; RM_LOG_WARN; RM_LOG_INFO or RM_LOG_DEBUG.
-$params['log_level'] = RM_LOG_DEBUG;
-
-// Temporary data storage for the script
-$params['resmgr_filterdir'] = '';
+$conf['log_level'] = RM_LOG_DEBUG;
 
 // Activate if you wish to use the new horde framework
 // (horde-framework-kolab) package instead of the old code in
 // kolab-horde-framework. This is still untested and considered
 // UNSAFE!
-$params['use_new_horde'] = false;
+$conf['use_new_horde'] = false;
+
+// FIXME: HACK
+$params = $conf;
 
 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 //

Index: kolabfilter.php
===================================================================
RCS file: /kolabrepository/server/kolab-filter/filter/kolabfilter.php,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- kolabfilter.php	8 Oct 2007 15:50:11 -0000	1.2
+++ kolabfilter.php	26 Nov 2007 16:35:21 -0000	1.3
@@ -29,469 +29,26 @@
  *  ABOUT
  *  -----
  *
- *  FIXME
+ *  A filter for outgoing mail on a Kolab Server.
  *
  */
 
-/* Fix include_path to pick up our modified Horde classes */
-require_once 'PEAR.php';
-require_once 'Kolab/Filter/misc.php';
-require_once 'Kolab/Filter/kolabmailtransport.php';
-
-// Profiling code
-/*
-function mymtime(){
-  $tmp=explode(' ',microtime());
-  $rt=$tmp[0]+$tmp[1];
-  return $rt;
-}
-
-class MyTimer {
-  function MyTimer( $name ) {
-    $this->name = $name;
-  }
-  function start() {
-    $this->time = mymtime();
-  }
-  function stop() {
-    $time = 100*(mymtime()-$this->time);
-    myLog("Section ".$this->name." took $time msecs", RM_LOG_DEBUG);
-  }
-
-  var $name;
-  var $time;
-};
-
-$totaltime =& new MyTimer("Total");
-$totaltime->start();
-*/
+/* Load the filter libraries */
+require_once 'Kolab/Filter/Outgoing.php';
+require_once 'Kolab/Filter/Response.php';
 
-// Load our configuration file
-$params = array();
+/* Read our configuration */
 require_once 'config.php';
-init();
-
-define( 'TMPDIR', $params['resmgr_filterdir'] );
-define( 'EX_TEMPFAIL', 75 );
-define( 'EX_UNAVAILABLE', 69 );
-
-//$inputtime =& new MyTimer("Input");
-//$inputtime->start();
-
-// Temp file for storing the message
-$tmpfname = tempnam( TMPDIR, 'IN.' );
-$tmpf = @fopen($tmpfname, "w");
-if( !$tmpf ) {
-  myLog("Error: Could not open $tempfname for writing: ".php_error(), RM_LOG_ERROR);
-  exit(EX_TEMPFAIL);
-}
-
-// Cleanup function
-function cleanup() {
-  global $tmpfname;
-  file_exists($tmpfname) && unlink($tmpfname);
-}
-register_shutdown_function( 'cleanup' );
-
-function is_my_domain( $addr ) {
-  global $params;
-  if( is_array($params['email_domain']) ) {
-	$domains = $params['email_domain'];
-  } else {
-	$domains = array($params['email_domain']);
-  }
-  
-  $adrs = imap_rfc822_parse_adrlist($addr, $params['email_domain']);
-  foreach ($adrs as $adr) {
-    $adrdom = $adr->host;
-    if( empty($adrdom) ) continue;
-    foreach( $domains as $dom ) {
-      if( $dom == $adrdom ) return true;
-      if( $params['verify_subdomains'] && substr($adrdom, -strlen($dom)-1) == ".$dom" ) return true;
-    }
-  }
-  return false;
-}
-
-/**
- Returns a list of allowed email addresses for user $sasluser
- or a PEAR_Error object if something croaked.
-*/
-function addrs_for_uid( $sasluser )
-{
-  global $params;
-  /* Connect to the LDAP server and retrieve the users'
-   allowed email addresses */
-  $ldap = ldap_connect($params['ldap_uri']);
-  if (!ldap_bind($ldap, $params['bind_dn'], $params['bind_pw'])) {
-    myLog('Unable to contact LDAP server: ' . ldap_error($ldap));
-    return new PEAR_Error('Unable to contact LDAP server: ' . ldap_error($ldap));
-  }
-  
-  $filter = "(&(objectClass=kolabInetOrgPerson)(|(mail=$sasluser)(uid=$sasluser)))";
-  $result = ldap_search($ldap, $params['base_dn'],
-			$filter,
-			array("dn", "mail", "alias" ));
-  if (!$result) {
-    myLog('Unable to perform LDAP search: ' . ldap_error($ldap));
-    return new PEAR_Error('Unable to perform LDAP search: ' . ldap_error($ldap));
-  }
-  
-  $entries = ldap_get_entries($ldap, $result);
-  if ($entries['count'] != 1) {
-    myLog($entries['count']." objects returned for uid $sasluser");
-    return new PEAR_Error("Temporary LDAP error, unable to look up user $sasluser");
-  }
-  unset($entries[0]['mail']['count']);
-  unset($entries[0]['alias']['count']);
-  $addrs = array_merge((array) $entries[0]['mail'],(array) $entries[0]['alias']);
-  $mail = $entries[0]['mail'][0];
-
-  ldap_free_result($result);
-
-  $filter = "(&(objectClass=kolabInetOrgPerson)(kolabDelegate=$mail))";
-  $result = ldap_search($ldap, $params['base_dn'],
-			$filter,
-			array("dn", "mail" ));
-  if (!$result) {
-    myLog('Unable to perform LDAP search: ' . ldap_error($ldap));
-    return new PEAR_Error('Unable to perform LDAP search: ' . ldap_error($ldap));
-  }
-  
-  $entries = ldap_get_entries($ldap, $result);
-  unset( $entries['count'] );
-  foreach( $entries as $adr ) {
-    if( $adr['mail']['count'] > 0 ) {
-      unset($adr['mail']['count']);
-      $addrs = array_merge((array) $addrs,(array) $adr['mail']);
-    }
-  }
-  ldap_free_result($result);
-  ldap_close($ldap);
-
-  #myLog("Found addresses ".print_r($addrs,true)." for user $sasluser", RM_LOG_DEBUG);
-  return $addrs;
-}
-
-/** Returns the format string used to rewrite
-    the From header for untrusted messages */
-function get_untrusted_subject_insert($sasluser,$sender)
-{
-  global $params;
-  if( $sasluser ) {
-    if( array_key_exists('untrusted_subject_insert', $params) ) {
-      $fmt = $params['untrusted_subject_insert'];
-    } else {
-      $fmt = "(UNTRUSTED, sender is <%s>)";
-    }
-  } else {
-    if( array_key_exists('unauthenticated_subject_insert', $params) ) {
-      $fmt = $params['unauthenticated_subject_insert'];
-    } else {
-      $fmt = "(UNTRUSTED, sender <%s> is not authenticated)";
-    }
-  }
-  return sprintf($fmt,$sender);
-}
-
-/** Check that the From header is not trying
-    to impersonate a valid user that is not
-    $sasluser. Returns one of:
-
-    * True if From can be accepted
-    * False if From must be rejected
-    * A string with a corrected From header that makes
-      From acceptable
-    * A PEAR_Error object if something croaked
-*/
-function verify_sender( $sasluser, $sender, $fromhdr, $client_addr ) {
-  global $params;
-
-  /* Allow anything from localhost and
-     fellow Kolab-hosts */
-  if( $client_addr == $params['local_addr'] ) return true;
-  $kolabhosts = split(',', $params['kolabhosts'] );
-  $kolabhosts = array_map( "gethostbyname", $kolabhosts );
-  if( array_search( $client_addr, $kolabhosts ) !== false ) return true;
-
-  if( is_array($params['email_domain']) ) {
-    $domains = $params['email_domain'];
-  } else {
-    $domains = array($params['email_domain']);
-  }
-
-  if( $sasluser ) {
-    if( PEAR::isError($allowed_addrs = addrs_for_uid($sasluser)) ) {
-      myLog("Error reading allowed addresses for $sasluser: ".$allowed_addrs->getMessage(), RM_LOG_ERROR);
-      return $allowed_addrs;
-    }
-  } else {
-    $allowed_addrs = false;
-  }
-  $untrusted = get_untrusted_subject_insert($sasluser,$sender);
-  $adrs = imap_rfc822_parse_adrlist($fromhdr, $params['email_domain'][0]);
-  foreach ($adrs as $adr) {
-    $from = $adr->mailbox.'@'.$adr->host;
-    $fromdom = $adr->host;
-    if( $sasluser ) {
-      if( !in_array( strtolower($from), $allowed_addrs ) ) {
-	myLog("$from is not an allowed From address for $sasluser", RM_LOG_DEBUG);
-	return false;
-      }
-    } else {
-      foreach( $domains as $domain ) {
-	if( strtolower($fromdom) == $domain 
-	    || ( $params['verify_subdomains'] 
-		 && substr($fromdom, -strlen($domain)-1) == ".$domain" ) ) {
-	  if( $params['reject_forged_from_header'] ) {
-	    myLog("$from is not an allowed From address for unauthenticated users", RM_LOG_DEBUG);	    
-	    return false;
-	  } else {
-	    /* Rewrite */
-	    myLog("$from is not an allowed From address for unauthenticated users, rewriting", RM_LOG_DEBUG);
-	    
-	    if( strpos( $fromhdr, $untrusted )===false ) {
-	      return '"'.str_replace(array("\\",'"'),array("\\\\",'\"'),$adr->personal).' '.$untrusted.'" '.'<'.$from.'>';
-	    } else {
-	      return true;
-	    }
-	  }
-	}
-      }
-    }
-  }
-
-  /* All seems OK */
-  return true;
 
-
-  /* TODO: What do we do about subdomains? */
-  /*
-    $senderdom = substr(strrchr($sender, '@'), 1);
-    foreach( $domains as $domain ) {
-      if( $params['verify_subdomains'] ) {	
-	if( ($senderdom == $domain ||
-	     $fromdom   == $domain ||
-	     substr($senderdom, -strlen($domain)-1) == ".$domain" ||
-	     substr($fromdom, -strlen($domain)-1) == ".$domain" ) &&
-	    $sender != $from ) {
-	  return false;
-	}
-      } else {
-	if( ($senderdom == $domain ||
-	     $fromdom   == $domain ) &&
-	    $sender != $from ) {
-		  return false;
-	}
-      }
-    }
-  }
-  return true;
-  */
-}
-
-$options = parse_args( array( 's', 'r', 'c', 'h', 'u' ), $_SERVER['argv']); //getopt("s:r:c:h:u:");
-
-if (!array_key_exists('r', $options) || !array_key_exists('s', $options)) {
-    fwrite(STDOUT, "Usage is $argv[0] -s sender at domain -r recip at domain\n");
-    exit(EX_TEMPFAIL);
-}
-
-$sender = strtolower($options['s']);
-$recipients = $options['r'];
-$client_address = $options['c'];
-$fqhostname = strtolower($options['h']);
-$sasl_username = strtolower($options['u']);
-
-// make sure recipients is an array
-if( !is_array($recipients) ) {
-  $recipients = array( $recipients );
-}
-
-// make recipients lowercase
-for( $i = 0; $i < count($recipients); $i++ ) {
-  $recipients[$i] = strtolower($recipients[$i]);
-}
-
-myLog("Kolabfilter starting up, user=$sasl_username, sender=$sender, recipients=".join(',', $recipients)
-      .", client_address=$client_address", RM_LOG_DEBUG);
-
-define( RM_STATE_READING_HEADER, 1 );
-define( RM_STATE_READING_FROM,   2 );
-define( RM_STATE_READING_SUBJECT,3 );
-define( RM_STATE_READING_SENDER, 4 );
-define( RM_STATE_READING_BODY,   5 );
-
-$ical = false;
-$from = false;
-$subject = false;
-$senderok = true;
-$rewrittenfrom = false;
-$state = RM_STATE_READING_HEADER;
-while (!feof(STDIN) && $state != RM_STATE_READING_BODY) {
-  $buffer = fgets(STDIN, 8192);
-  $line = rtrim( $buffer, "\r\n");
-  if( $line == '' ) {
-    // Done with headers
-    $state = RM_STATE_READING_BODY;
-    if( $from && $params['verify_from_header'] ) {
-      $rc = verify_sender( $sasl_username, $sender, $from, $client_address);
-      if( PEAR::isError($rc) ) {
-	$msg = $error->getMessage().", code ".$error->getCode();
-	mylog($msg, RM_LOG_ERROR);
-	fwrite(STDOUT, $msg."\n"); 
-	exit(EX_TEMPFAIL);
-      } else if( $rc === true ) {
-	/* All OK, do nothing */
-      } else if( $rc === false ) {
-	/* Reject! */
-	$senderok = false;
-      } else if( is_string($rc) ) {
-	/* Rewrite from */
-	if( strpos( $from, $rc )===false ) {
-	  myLog("Rewriting '$from' to '$rc'", RM_LOG_DEBUG);
-	  $rewrittenfrom = "From: $rc\r\n";
-	}
-      }
-    }
-  } else {
-    if( $line[0] != ' ' && $line[0] != "\t" ) $state = RM_STATE_READING_HEADER;
-    switch( $state ) {
-    case RM_STATE_READING_HEADER:
-      if( $params['allow_sender_header'] && eregi( '^Sender: (.*)', $line, $regs ) ) {
-	$from = $regs[1];
-	$state = RM_STATE_READING_SENDER;
-      } else if( !$from && eregi( '^From: (.*)', $line, $regs ) ) {
-	$from = $regs[1];
-	$state = RM_STATE_READING_FROM;
-      } else if( eregi( '^Subject: (.*)', $line, $regs ) ) {
-	$subject = $regs[1];
-	$state = RM_STATE_READING_SUBJECT;
-      } else if( eregi( '^Content-Type: text/calendar', $line ) ) {
-	myLog("Found iCal data in message", RM_LOG_DEBUG);
-	$ical = true;
-      }
-      break;
-    case RM_STATE_READING_FROM:
-      $from .= $line;
-      break;
-    case RM_STATE_READING_SENDER:
-      $from .= $line;
-      break;
-    case RM_STATE_READING_SUBJECT:
-      $subject .= $line;
-      break;
-    }
-  }
-  if( fwrite($tmpf, $buffer) === false ) {
-    exit(EX_TEMPFAIL);
-  }
-}
-while (!feof(STDIN)) {
-  $buffer = fread( STDIN, 8192 );
-  if( fwrite($tmpf, $buffer) === false ) {
-    exit(EX_TEMPFAIL);
-  }
-}
-fclose($tmpf);
-
-//$inputtime->stop();
-
-if( !$senderok ) {
-  if( $ical && $params['allow_outlook_ical_forward'] ) {
-    require_once('Kolab/Filter/olhacks.php');
-    $rc = olhacks_embedical( $fqhostname, $sender, $recipients, $from, $subject, $tmpfname );
-    if( PEAR::isError( $rc ) ) {
-      fwrite(STDOUT,"Filter failed: ".$rc->getMessage()."\n");
-      exit(EX_TEMPFAIL);
-    } else if( $rc === true ) {
-      exit(0);
-    }
-  } else {
-    $msg = "Invalid From: header. $from looks like a forged sender";
-    myLog($msg, RM_LOG_DEBUG);
-    fwrite(STDOUT,"$msg\n");
-    exit(EX_UNAVAILABLE);
-  }
-}
-
-//$outputtime =& new MyTimer("Output");
-//$outputtime->start();
-
-$tmpf = @fopen($tmpfname,"r");
-if( !$tmpf ) {
-  myLog("Error: Could not open $tempfname for reading: ".php_error(), RM_LOG_ERROR);
-  exit(EX_TEMPFAIL);
-}
-
-/* TODO: Dont hardcode localhost:10025 */
-$smtp = new KolabSMTP( $params['local_addr'], 10025 );
-if( PEAR::isError( $smtp ) ) {
-  fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-  if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-  else exit(EX_UNAVAILABLE);
-}
-if( PEAR::isError( $error = $smtp->start($sender,$recipients) ) ) {
-  fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-  if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-  else exit(EX_UNAVAILABLE);
+/* Setup the classes */
+if (empty($conf['filter']['error_log'])) {
+    $conf['filter']['error_log'] = sys_get_temp_dir() . PATH_SEPARATOR . 'kolab-filter.log';
 }
 
-$state = RM_STATE_READING_HEADER;
-while (!feof($tmpf) && $state != RM_STATE_READING_BODY) {
-  $buffer = fgets($tmpf, 8192);
-  if( $rewrittenfrom ) {
-    if( eregi( '^From: (.*)', $buffer ) ) {
-      if( PEAR::isError($error = $smtp->data( $rewrittenfrom )) ) {
-	$str = $error->getMessage().", code ".$error->getCode();
-	myLog($str,RM_LOG_ERROR);
-	fwrite(STDOUT, $str."\n");
-	if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-	else exit(EX_UNAVAILABLE);
-      }
-      $state = RM_STATE_READING_FROM;
-      continue;
-    } else if( $state == RM_STATE_READING_FROM &&
-	       ($buffer[0] == ' ' || $buffer[0] == "\t" ) ) {
-      // Folded From header, ignore
-      continue;
-    }
-  }
-  if( rtrim( $buffer, "\r\n" ) == '' ) {
-    $state = RM_STATE_READING_BODY;
-  } else if( $buffer[0] != ' ' && $buffer[0] != "\t" ) {
-    $state = RM_STATE_READING_HEADER;
-  }
-  if( PEAR::isError($error = $smtp->data( $buffer )) ) {
-    $str = $error->getMessage().", code ".$error->getCode();
-    myLog($str,RM_LOG_ERROR);
-    fwrite(STDOUT, $str."\n");
-    if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-    else exit(EX_UNAVAILABLE);
-  }
-}
-while (!feof($tmpf) ) {
-    $buffer = fread($tmpf, 8192);
-    $len = strlen($buffer);
+$response = &new Response($conf['filter']['error_log']);
+$parser   = &new Filter_Outgoing();
 
-    /* We can't tolerate that the buffer breaks the data
-       between \r and \n, so we try to avoid that. The limit 
-       of 100 reads is to battle abuse */
-    while( $buffer{$len-1} == "\r" && $len < 8192 + 100 ) {
-      $buffer .= fread($tmpf,1);
-      $len++;
-    }
-    if( PEAR::isError($error = $smtp->data( $buffer )) ) {
-        fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-	if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-	else exit(EX_UNAVAILABLE);
-    }
-};
+/* Parse the mail and spit out the response */
+$response->handle($parser->parse());
 
-//myLog("Calling smtp->end()", RM_LOG_DEBUG);
-$smtp->end();
-//$outputtime->stop();
-myLog("Kolabfilter successfully completed", RM_LOG_DEBUG);
-//$totaltime->stop();
-exit(0);
 ?>

Index: kolabmailboxfilter.php
===================================================================
RCS file: /kolabrepository/server/kolab-filter/filter/kolabmailboxfilter.php,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- kolabmailboxfilter.php	8 Oct 2007 15:50:11 -0000	1.2
+++ kolabmailboxfilter.php	26 Nov 2007 16:35:21 -0000	1.3
@@ -29,166 +29,26 @@
  *  ABOUT
  *  -----
  *
- *  FIXME
+ *  A filter for incoming mail on a Kolab Server. It checks the
+ *  messages for iCal data and handles automatic invitations.
  *
  */
 
-require_once 'PEAR.php';
-require_once 'Kolab/Filter/misc.php';
-require_once 'Kolab/Filter/kolabmailtransport.php';
+/* Load the filter libraries */
+require_once 'Kolab/Filter/Incoming.php';
+require_once 'Kolab/Filter/Response.php';
 
-// Load our configuration file
-$params = array();
+/* Read our configuration */
 require_once 'config.php';
-init();
-
-define( 'TMPDIR', $params['resmgr_filterdir'] );
-define( 'EX_TEMPFAIL', 75 );
-define( 'EX_UNAVAILABLE', 69 );
-
-// Temp file for storing the message
-$tmpfname = tempnam( TMPDIR, 'IN.' );
-$tmpf = @fopen($tmpfname, "w");
-if( !$tmpf ) {
-  myLog("Error: Could not open $tempfname for writing: ".php_error(), RM_LOG_ERROR);
-  exit(EX_TEMPFAIL);
-}
-
-// Cleanup function
-function cleanup() {
-  global $tmpfname;
-  file_exists($tmpfname) && unlink($tmpfname);
-}
-register_shutdown_function( 'cleanup' );
-
-$options = parse_args( array( 's', 'r', 'c', 'h' ), $_SERVER['argv']); //getopt("s:r:c:h:");
-
-if (!array_key_exists('r', $options) || !array_key_exists('s', $options)) {
-    fwrite(STDOUT, "Usage is $argv[0] -s sender at domain -r recip at domain\n");
-    exit(EX_TEMPFAIL);
-}
-
-$sender = strtolower($options['s']);
-$recipients = $options['r'];
-$client_address = $options['c'];
-$fqhostname = strtolower($options['h']);
-
-// make sure recipients is an array
-if( !is_array($recipients) ) {
-  $recipients = array( $recipients );
-}
-
-// make recipients lowercase
-for( $i = 0; $i < count($recipients); $i++ ) {
-  $recipients[$i] = strtolower($recipients[$i]);
-}
-
-myLog("Kolabmailboxfilter starting up, sender=$sender, recipients=".join(',', $recipients)
-      .", client_address=$client_address", RM_LOG_DEBUG);
-
-$ical = false;
-$add_headers = array();
-$headers_done = false;
-while (!feof(STDIN) && !$headers_done) {
-  $buffer = fgets(STDIN, 8192);
-  $line = rtrim( $buffer, "\r\n");
-  if( $line == '' ) {
-    // Done with headers
-    $headers_done = true;
-  } else if( eregi( '^Content-Type: text/calendar', $line ) ) {
-    myLog("Found iCal data in message", RM_LOG_DEBUG);    
-    $ical = true;
-  }
-  if( fwrite($tmpf, $buffer) === false ) {
-    exit(EX_TEMPFAIL);
-  }
-}
-while (!feof(STDIN)) {
-  $buffer = fread( STDIN, 8192 );
-  if( fwrite($tmpf, $buffer) === false ) {
-    exit(EX_TEMPFAIL);
-  }
-}
-fclose($tmpf);
-if( $ical ) {
-  require_once 'Kolab/Filter/resmgr.php';
-  $newrecips = array();
-  foreach( $recipients as $recip ) {
-    myLog("Calling resmgr_filter( $sender, $recip, $tmpfname )", RM_LOG_DEBUG);
-    $rc = resmgr_filter( $fqhostname, $sender, $recip, $tmpfname );
-    if( PEAR::isError( $rc ) ) {
-      fwrite(STDOUT,"Filter failed: ".$rc->getMessage()."\n");
-      exit(EX_TEMPFAIL);
-    } else if( $rc === true ) {
-      $newrecips[] = $recip;
-    }
-  }
-  $recipients = $newrecips;
-  $add_headers[] = "X-Kolab-Scheduling-Message: TRUE";
-} else {
-  $add_headers[] = "X-Kolab-Scheduling-Message: FALSE";
-}
-
-// Check if we still have recipients
-if( empty($recipients) ) exit(0);
-
-$tmpf = @fopen($tmpfname,"r");
-if( !$tmpf ) {
-  myLog("Error: Could not open $tempfname for writing: ".php_error(), RM_LOG_ERROR);
-  exit(EX_TEMPFAIL);
-}
 
-$lmtp = new KolabLMTP( $params['local_addr'] );
-if( PEAR::isError( $lmtp ) ) {
-  fwrite(STDOUT, $lmtp->getMessage()."\n");
-  if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-  else exit(EX_UNAVAILABLE);
-}
-if( PEAR::isError( $error = $lmtp->start($sender,$recipients) ) ) {
-  fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-  if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-  else exit(EX_UNAVAILABLE);
+/* Setup the classes */
+if (empty($conf['filter']['error_log'])) {
+    $conf['filter']['error_log'] = sys_get_temp_dir() . PATH_SEPARATOR . 'kolab-filter.log';
 }
 
-$headers_done = false;
-while (!feof($tmpf) && !$headers_done) {
-  $buffer = fgets($tmpf, 8192);
-  if( !$headers_done && rtrim( $buffer, "\r\n" ) == '' ) {
-    $headers_done = true;
-    foreach( $add_headers as $h ) {
-      if( PEAR::isError($error = $lmtp->data( "$h\r\n" )) ) {
-	fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-	if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-	else exit(EX_UNAVAILABLE);
-      }
-    }
-  }
-  //myLog("Calling smtp->data( ".rtrim($buffer)." )", RM_LOG_DEBUG);
-  if( PEAR::isError($error = $lmtp->data( $buffer )) ) {
-    fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-    if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-    else exit(EX_UNAVAILABLE);
-  }
-}
-while (!feof($tmpf) ) {
-    $buffer = fread($tmpf, 8192);
-    $len = strlen($buffer);
+$response = &new Response($conf['filter']['error_log']);
+$parser   = &new Filter_Incoming();
 
-    /* We can't tolerate that the buffer breaks the data
-       between \r and \n, so we try to avoid that. The limit 
-       of 100 reads is to battle abuse */
-    while( $buffer{$len-1} == "\r" && $len < 8192 + 100 ) {
-      $buffer .= fread($tmpf,1);
-      $len++;
-    }
-    if( PEAR::isError($error = $lmtp->data( $buffer )) ) {
-	fwrite(STDOUT, $error->getMessage().", code ".$error->getCode()."\n"); 
-	if( $error->getCode() < 500 ) exit(EX_TEMPFAIL);
-	else exit(EX_UNAVAILABLE);
-    }
-};
-//myLog("Calling smtp->end()", RM_LOG_DEBUG);
-$lmtp->end();
-myLog("Kolabmailboxfilter successfully completed", RM_LOG_DEBUG);
-exit(0);
+/* Parse the mail and spit out the response */
+$response->handle($parser->parse());
 ?>





More information about the commits mailing list