steffen: server/kolab-resource-handlers/kolab-resource-handlers/resmgr kolabmailboxfilter.php, NONE, 1.1 lmtp.php, NONE, 1.1 olhacks.php, NONE, 1.1 kolabfilter.php, 1.18, 1.19 smtp.php, 1.4, 1.5

cvs at intevation.de cvs at intevation.de
Mon Apr 4 01:14:12 CEST 2005


Author: steffen

Update of /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/resmgr
In directory doto:/tmp/cvs-serv29528

Modified Files:
	kolabfilter.php smtp.php 
Added Files:
	kolabmailboxfilter.php lmtp.php olhacks.php 
Log Message:
split filter into two and added Outlook invitation forwarding hack

--- NEW FILE: kolabmailboxfilter.php ---
#!@l_prefix@/bin/php
<?php
/*
 *  Copyright (c) 2004,2005 Klaraelvdalens Datakonsult AB
 *
 *    Writen by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
 *
 *  This  program is free  software; you can redistribute  it and/or
 *  modify it  under the terms of the GNU  General Public License as
 *  published by the  Free Software Foundation; either version 2, or
 *  (at your option) any later version.
 *
 *  This program is  distributed in the hope that it will be useful,
 *  but WITHOUT  ANY WARRANTY; without even the  implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  General Public License for more details.
 *
 *  You can view the  GNU General Public License, online, at the GNU
 *  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
 */

/* Fix include_path to pick up our modified Horde classes */
$include_path = ini_get('include_path');
ini_set( 'include_path', 
	 '.:@l_prefix@/var/kolab/php:@l_prefix@/var/kolab/php/pear:'.$include_path);

require_once 'PEAR.php';
require_once 'kolabfilter/misc.php';
require_once 'kolabfilter/lmtp.php';

// Load our configuration file
$params = array();
require_once '@l_prefix@/etc/resmgr/resmgr.conf';
init();

define( 'TMPDIR', '@l_prefix@/var/resmgr/filter' );
define( 'EX_TEMPFAIL', 75 );
define( 'EX_UNAVAILABLE', 69 );

// Temp file for storing the message
$tmpfname = tempnam( TMPDIR, 'IN.' );
$tmpf = fopen($tmpfname, "w");

// 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("Kolabfilter starting up, sender=$sender, recipients=".join(',', $recipients)
      .", client_address=$client_address", RM_LOG_DEBUG);

$ical = false;
$add_headers = array();
$headers_done = false;
$from = false;
while (!feof(STDIN)) {
  $buffer = fgets(STDIN, 8192);
  $line = rtrim( $buffer, "\r\n");
  if( $line == '' ) {
    // Done with headers
    $headers_done = true;
  } else if( !$headers_done && $params['allow_sender_header'] && eregi( '^Sender:(.*)', $line, $regs ) ) {
    $from = strtolower($regs[1]);
  } else if( !$headers_done && !$from && eregi( '^From:(.*)', $line, $regs ) ) {
    $from = strtolower($regs[1]);
  } 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);
  }
}
fclose($tmpf);
if( $ical ) {
  require_once 'kolabfilter/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");
$lmtp = new KolabLMTP();
if( PEAR::isError( $lmtp ) ) {
  fwrite(STDOUT, $lmtp->getMessage()."\n"); exit(EX_TEMPFAIL);
}
if( PEAR::isError( $error = $lmtp->start($sender,$recipients) ) ) {
  fwrite(STDOUT, $error->getMessage()."\n"); exit(EX_TEMPFAIL);  
}

$headers_done = false;
while (!feof($tmpf)) {
  $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()."\n"); exit(EX_TEMPFAIL);
      }
    }
  }
  //myLog("Calling smtp->data( ".rtrim($buffer)." )", RM_LOG_DEBUG);
  if( PEAR::isError($error = $lmtp->data( $buffer )) ) {
    fwrite(STDOUT, $error->getMessage()."\n"); exit(EX_TEMPFAIL);
  }
}
//myLog("Calling smtp->end()", RM_LOG_DEBUG);
$lmtp->end();
myLog("Kolabfilter successfully completed", RM_LOG_DEBUG);
exit(0);
?>
--- NEW FILE: lmtp.php ---
<?php
/*
 *  Copyright (c) 2005 Klaraelvdalens Datakonsult AB
 *
 *    Writen by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
 *
 *  This  program is free  software; you can redistribute  it and/or
 *  modify it  under the terms of the GNU  General Public License as
 *  published by the  Free Software Foundation; either version 2, or
 *  (at your option) any later version.
 *
 *  This program is  distributed in the hope that it will be useful,
 *  but WITHOUT  ANY WARRANTY; without even the  implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  General Public License for more details.
 *
 *  You can view the  GNU General Public License, online, at the GNU
 *  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
 */

  /* TODO(steffen): Refactor -- this is almost exactly like KolabSMTP */

class KolabLMTP {
  function KolabLMTP( $host = '127.0.0.1', $port = 2003 ) {
    $this->host = $host;
    $this->port = $port;
    $this->lmtp = false;
  }

  function start($sender,$recips) {
    require_once 'Net/LMTP.php';
	
    $this->lmtp = &new Net_LMTP($this->host, $this->port);
    if (!$this->lmtp) {
      return new PEAR_Error('Failed to connect to LMTP: ' . $error->getMessage());
    }
    if (PEAR::isError($error = $this->lmtp->connect())) {
      return new PEAR_Error('Failed to connect to LMTP: ' . $error->getMessage());
    }

    if (PEAR::isError($error = $this->lmtp->mailFrom($sender))) {
      return new PEAR_Error('Failed to set sender: ' . $error->getMessage());
    }
    
    if( !is_array( $recips ) ) $recips = array($recips);

    foreach( $recips as $recip ) {
      if (PEAR::isError($error = $this->lmtp->rcptTo($recip))) {
	$msg = 'Failed to set recipient: ' . $error->getMessage();
	myLog($msg, RM_LOG_ERROR);
	return false;
      }
    }

    if (PEAR::isError($error = $this->lmtp->_put('DATA'))) {      
      return $error;
    }
    if (PEAR::isError($error = $this->lmtp->_parseResponse(354))) {
      return $error;
    }
    return true;
  }

  /* Modified implementation from Net_SMTP that supports
   * dotstuffing even when getting the mail line-by line */
  function quotedataline(&$data) {
    /*
     * Change Unix (\n) and Mac (\r) linefeeds into Internet-standard CRLF
     * (\r\n) linefeeds.
     */
    $data = preg_replace("/([^\r]{1})\n/", "\\1\r\n", $data);
    $data = preg_replace("/\n\n/", "\n\r\n", $data);
    
    /*
     * Because a single leading period (.) signifies an end to the data,
     * legitimate leading periods need to be "doubled" (e.g. '..').
     */
    if( $data[0] == '.' ) $data = '.'.$data;
    $data = str_replace("\n.", "\n..", $data);
  }

  function data( $data) {
    $this->quotedataline($data);
    if (PEAR::isError($this->lmtp->_send($data))) {
      return new PEAR_Error('write to socket failed');
    }
    return true;
  }

  function end() {
    if (PEAR::isError($this->lmtp->_send("\r\n.\r\n"))) {
      return new PEAR_Error('write to socket failed');
    }
    if (PEAR::isError($error = $this->lmtp->_parseResponse(250))) {
      return $error;
    }
    $this->lmtp->disconnect();
    $this->lmtp = false;
    return true;
  }

  var $host;
  var $port;
  var $lmtp;
};
?>
--- NEW FILE: olhacks.php ---
<?php
/*
 *  Copyright (c) 2004 Klaraelvdalens Datakonsult AB
 *
 *    Writen by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
 *
 *  This  program is free  software; you can redistribute  it and/or
 *  modify it  under the terms of the GNU  General Public License as
 *  published by the  Free Software Foundation; either version 2, or
 *  (at your option) any later version.
 *
 *  This program is  distributed in the hope that it will be useful,
 *  but WITHOUT  ANY WARRANTY; without even the  implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  General Public License for more details.
 *
 *  You can view the  GNU General Public License, online, at the GNU
 *  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
 */

require_once 'kolabfilter/misc.php';
require_once HORDE_BASE . '/lib/core.php';
require_once 'Horde/MIME.php';
require_once 'Horde/MIME/Message.php';
require_once 'Horde/MIME/Headers.php';
require_once 'Horde/MIME/Part.php';
require_once 'Horde/MIME/Structure.php';

$forwardtext = "This is an invitation forwarded by outlook and\n".
  "was rectified by the Kolab server.\n\n".
  "Diese Einladung wurde von Outlook weitergeleitet\n".
  "und vom Kolab-Server in gute Form gebracht.\n";

function olhacks_embedical( $fqhostname, $sender, $recipients, $tmpfname ) {
  global $forwardtext;
  // Read in message text
  $requestText = '';
  $handle = @fopen( $tmpfname, "r" );
  if( $handle === false ) {
    myLog("Error opening $tmpfname", RM_LOG_ERROR);
    return false;
  }
  while (!feof($handle)) {
    $requestText .= fread($handle, 8192);
  }
  fclose($handle);

  // Construct new MIME message with original message attached
  $toppart = &new MIME_Message();
  $textpart = &new MIME_Part('text/plain', $forwardtext, 'UTF-8' );
  $msgpart = &new MIME_Part('message/rfc822', $requestText );
  $toppart->addPart($textpart);
  $toppart->addPart($msgpart);
  
  // Build the reply headers.
  $msg_headers = &new MIME_Headers();
  $msg_headers->addReceivedHeader();
  $msg_headers->addMessageIdHeader();
  $msg_headers->addHeader('Date', date('r'));
  $msg_headers->addHeader('From', "$sender");
  foreach( $recipients as $recip ) {
    $msg_headers->addHeader('To', $recip);
  }
  $msg_headers->addHeader('Subject', 'Kolab forwarded message' );
  $msg_headers->addMIMEHeaders($toppart);

  if (is_object($msg_headers)) {
    $headerArray = $toppart->encode($msg_headers->toArray(), $toppart->getCharset());
  } else {
    $headerArray = $toppart->encode($msg_headers, $toppart->getCharset());
  }

  // Inject message back into postfix
  require_once 'Mail.php';
  $mailer = &Mail::factory('SMTP', array('auth' => false, 'port' => 10026 ));

  $msg = $toppart->toString();
  /* Make sure the message has a trailing newline. */
  if (substr($msg, -1) != "\n") {
    $msg .= "\n";
  }

  $error = $mailer->send($recipients, $headerArray, $msg);
  if( PEAR::isError($error) ) {
    fwrite(STDOUT, $error->getMessage()."\n"); exit(EX_TEMPFAIL);
  }

  return true;
}

?>
Index: kolabfilter.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/resmgr/kolabfilter.php,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- kolabfilter.php	2 Apr 2005 02:47:34 -0000	1.18
+++ kolabfilter.php	3 Apr 2005 23:14:10 -0000	1.19
@@ -118,6 +118,7 @@
 $add_headers = array();
 $headers_done = false;
 $from = false;
+$senderok = true;
 while (!feof(STDIN)) {
   $buffer = fgets(STDIN, 8192);
   $line = rtrim( $buffer, "\r\n");
@@ -126,9 +127,7 @@
     $headers_done = true;
     if( $from && $params['verify_from_header'] ) {
       if( !verify_sender( $sender, $from, $client_address) ) {
-	myLog("Invalid From: header. $from does not match envelope $sender\n", RM_LOG_DEBUG);
-	fwrite(STDOUT,"Invalid From: header. $from does not match envelope $sender\n");
-	exit(EX_UNAVAILABLE);
+	$senderok = false;
       }
     }
   } else if( !$headers_done && $params['allow_sender_header'] && eregi( '^Sender:(.*)', $line, $regs ) ) {
@@ -144,23 +143,22 @@
   }
 }
 fclose($tmpf);
-if( $ical ) {
-  require_once 'kolabfilter/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( !$senderok ) {
+  if( $ical ) {
+    require_once('kolabfilter/olhacks.php');
+    $rc = olhacks_embedical( $fqhostname, $sender, $recipients, $tmpfname );
     if( PEAR::isError( $rc ) ) {
       fwrite(STDOUT,"Filter failed: ".$rc->getMessage()."\n");
       exit(EX_TEMPFAIL);
     } else if( $rc === true ) {
-      $newrecips[] = $recip;
+      exit(0);
     }
+  } else {
+    myLog("Invalid From: header. $from does not match envelope $sender\n", RM_LOG_DEBUG);
+    fwrite(STDOUT,"Invalid From: header. $from does not match envelope $sender\n");
+    exit(EX_UNAVAILABLE);
   }
-  $recipients = $newrecips;
-  $add_headers[] = "X-Kolab-Scheduling-Message: TRUE";
-} else {
-  $add_headers[] = "X-Kolab-Scheduling-Message: FALSE";
 }
 
 $tmpf = fopen($tmpfname,"r");
@@ -168,7 +166,6 @@
 if( PEAR::isError( $smtp ) ) {
   fwrite(STDOUT, $smtp->getMessage()."\n"); exit(EX_TEMPFAIL);
 }
-//myLog("Calling smtp->start( $sender, $recipient, $tmpfname )", RM_LOG_DEBUG);
 if( PEAR::isError( $error = $smtp->start($sender,$recipients) ) ) {
   fwrite(STDOUT, $error->getMessage()."\n"); exit(EX_TEMPFAIL);  
 }

Index: smtp.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/resmgr/smtp.php,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- smtp.php	2 Apr 2005 02:47:34 -0000	1.4
+++ smtp.php	3 Apr 2005 23:14:10 -0000	1.5
@@ -18,6 +18,8 @@
  *  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
  */
 
+  /* TODO(steffen): Refactor -- this is almost exactly like KolabLMTP */
+
 class KolabSMTP {
   function KolabSMTP( $host, $port ) {
     $this->host = $host;





More information about the commits mailing list