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