/** * Deliver the message. * * @param string $transport The name of the transport driver. * * @return mixed A PEAR_Error in case of an error, nothing otherwise. */ function _deliver($transport, $recipients) { global $conf; if (isset($conf['kolab']['filter']['lmtp_host'])) { $host = $conf['kolab']['filter']['lmtp_host']; } else { $host = 'localhost'; } if (isset($conf['kolab']['filter']['lmtp_port'])) { $port = $conf['kolab']['filter']['lmtp_port']; } else { $port = 2003; } // @todo: extract as separate (optional) class $userDb = $this->_application->getUserDb(); $hosts = array(); foreach ($recipients as $recipient) { if (strpos($recipient, '+')) { list($local, $rest) = explode('+', $recipient, 2); list($rest, $domain) = explode('@', $recipient, 2); $real_recipient = $local . '@' . $domain; } else { $real_recipient = $recipient; } try { //@todo: fix anonymous binding in Kolab_Server. The method name should be explicit. $userDb->server->connectGuid(); $guid = $userDb->search->searchGuidForUidOrMail($real_recipient); if (empty($guid)) { throw new Horde_Kolab_Filter_Exception_Temporary(sprintf('User %s does not exist!', $real_recipient)); } $imapserver = $userDb->objects->fetch($guid, 'Horde_Kolab_Server_Object_Kolab_User')->getSingle('kolabHomeServer'); } catch (Horde_Kolab_Server_Exception $e) { //@todo: If a message made it till here than we shouldn't fail // because the LDAP lookup fails. The safer alternative is to try the local // delivery. LMTP should deny anyway in case the user is unknown // (despite the initial postfix checks). throw new Horde_Kolab_Filter_Exception_Temporary(sprintf('Failed identifying IMAP host of user %s. Error was: %s', $real_recipient, $e->getMessage()), $e); } if (!empty($imapserver)) { $uhost = $imapserver; } else { $uhost = $host; } $hosts[$uhost][] = $recipient; } foreach (array_keys($hosts) as $imap_host) { $params = array('host' => $imap_host, 'port' => $port); if ($imap_host != $host) { $params['user'] = $conf['kolab']['filter']['lmtp_user']; $params['pass'] = $conf['kolab']['filter']['lmtp_pass']; } $transport =& Horde_Kolab_Filter_Transport::factory($transport, $params); $tmpf = $this->_temporary->getReadHandle(); if (!$tmpf) { $msg = $php_errormsg; return PEAR::raiseError(sprintf("Error: Could not open %s for writing: %s", $this->_tmpfile, $msg), OUT_LOG | EX_IOERR); } $result = $transport->start($this->_config->getSender(), $hosts[$imap_host]); if (is_a($result, 'PEAR_Error')) { return $result; } $headers_done = false; while (!feof($tmpf) && !$headers_done) { $buffer = fgets($tmpf, 8192); if (!$headers_done && rtrim($buffer, "\r\n") == '') { $headers_done = true; foreach ($this->_add_headers as $h) { $result = $transport->data("{$h}\r\n"); if (is_a($result, 'PEAR_Error')) { return $result; } } } $result = $transport->data($buffer); if (is_a($result, 'PEAR_Error')) { return $result; } } while (!feof($tmpf)) { $buffer = fread($tmpf, 8192); $len = strlen($buffer); /* 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++; } $result = $transport->data($buffer); if (is_a($result, 'PEAR_Error')) { return $result; } } return $transport->end(); } }
/** * Deliver the message. * * @param string $transport The name of the transport driver. * * @return mixed A PEAR_Error in case of an error, nothing otherwise. */ function _deliver($rewrittenfrom, $transport) { global $conf; if (isset($conf['kolab']['filter']['smtp_host'])) { $host = $conf['kolab']['filter']['smtp_host']; } else { $host = 'localhost'; } if (isset($conf['kolab']['filter']['smtp_port'])) { $port = $conf['kolab']['filter']['smtp_port']; } else { $port = 10025; } $transport =& Horde_Kolab_Filter_Transport::factory($transport, array('host' => $host, 'port' => $port)); $tmpf = @fopen($this->_tmpfile, 'r'); if (!$tmpf) { $msg = $php_errormsg; return PEAR::raiseError(sprintf("Error: Could not open %s for writing: %s", $this->_tmpfile, $msg), OUT_LOG | EX_IOERR); } $result = $transport->start($this->_sender, $this->_recipients); if (is_a($result, 'PEAR_Error')) { return $result; } $state = RM_STATE_READING_HEADER; while (!feof($tmpf) && $state != RM_STATE_READING_BODY) { $buffer = fgets($tmpf, 8192); if ($rewrittenfrom) { if (preg_match('#^From: (.*)#i', $buffer)) { $result = $transport->data($rewrittenfrom); if (is_a($result, 'PEAR_Error')) { return $result; } $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; } } $result = $transport->data($buffer); if (is_a($result, 'PEAR_Error')) { return $result; } } while (!feof($tmpf)) { $buffer = fread($tmpf, 8192); $len = strlen($buffer); /* 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++; } $result = $transport->data($buffer); if (is_a($result, 'PEAR_Error')) { return $result; } } return $transport->end(); }
function _inject(&$toppart, $recipients, $msg_headers, $sender, $transport) { global $conf; if (isset($conf['kolab']['filter']['smtp_host'])) { $host = $conf['kolab']['filter']['smtp_host']; } else { $host = 'localhost'; } if (isset($conf['kolab']['filter']['smtp_port'])) { $port = $conf['kolab']['filter']['smtp_port']; } else { $port = 10025; } $transport =& Horde_Kolab_Filter_Transport::factory($transport, array('host' => $host, 'port' => $port)); $result = $transport->start($sender, $recipients); if (is_a($result, 'PEAR_Error')) { return $result; } $result = $transport->data($msg_headers->toString() . $toppart->toString()); if (is_a($result, 'PEAR_Error')) { return $result; } return $transport->end(); }