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