Exemplo n.º 1
0
 /**
  * Sends a message to an email address supposed to be added to the
  * identity.
  *
  * A message is send to this address containing a time-sensitive link to
  * confirm that the address really belongs to that user.
  *
  * @param integer $id       The identity's ID.
  * @param string $old_addr  The old From: address.
  *
  * @throws Horde_Mime_Exception
  */
 public function verifyIdentity($id, $old_addr)
 {
     global $injector, $notification, $registry;
     $hash = strval(new Horde_Support_Randomid());
     $pref = $this->_confirmEmail();
     $pref[$hash] = $this->get($id);
     $pref[$hash][self::EXPIRE] = time() + self::EXPIRE_SECS;
     $this->_confirmEmail($pref);
     $new_addr = $this->getValue($this->_prefnames['from_addr'], $id);
     $confirm = Horde::url($registry->getServiceLink('emailconfirm')->add('h', $hash)->setRaw(true), true);
     $message = sprintf(Horde_Core_Translation::t("You have requested to add the email address \"%s\" to the list of your personal email addresses.\n\nGo to the following link to confirm that this is really your address:\n%s\n\nIf you don't know what this message means, you can delete it."), $new_addr, $confirm);
     $msg_headers = new Horde_Mime_Headers();
     $msg_headers->addHeaderOb(Horde_Mime_Headers_MessageId::create());
     $msg_headers->addHeaderOb(Horde_Mime_Headers_UserAgent::create());
     $msg_headers->addHeaderOb(Horde_Mime_Headers_Date::create());
     $msg_headers->addHeader('To', $new_addr);
     $msg_headers->addHeader('From', $old_addr);
     $msg_headers->addHeader('Subject', Horde_Core_Translation::t("Confirm new email address"));
     $body = new Horde_Mime_Part();
     $body->setType('text/plain');
     $body->setContents(Horde_String::wrap($message, 76));
     $body->setCharset('UTF-8');
     $body->send($new_addr, $msg_headers, $injector->getInstance('Horde_Mail'));
     $notification->push(sprintf(Horde_Core_Translation::t("A message has been sent to \"%s\" to verify that this is really your address. The new email address is activated as soon as you confirm this message."), $new_addr), 'horde.message');
 }
Exemplo n.º 2
0
    public function testGenerate()
    {
        $h = new Horde_Mime_Headers();
        $ob = new Horde_Mime_Mdn($h);
        try {
            $ob->generate(true, true, 'deleted', 'foo', null);
            $this->fail('Expected Exception');
        } catch (RuntimeException $e) {
        }
        $date = 'Tue, 18 Nov 2014 20:14:17 -0700';
        $mdn_addr = 'Aäb <*****@*****.**>';
        $h->addHeader('Date', $date);
        $h->addHeader('Subject', 'Test');
        $h->addHeader('To', '"BAR" <*****@*****.**>');
        $ob->addMdnRequestHeaders($mdn_addr);
        $mailer = new Horde_Mail_Transport_Mock();
        $ob->generate(true, true, 'displayed', 'test.example.com', $mailer, array('from_addr' => '*****@*****.**'), array('error'), array('error' => 'Foo'));
        $sent = str_replace("\r\n", "\n", $mailer->sentMessages[0]);
        $this->assertEquals('auto-replied', $sent['headers']['Auto-Submitted']);
        $this->assertEquals('*****@*****.**', $sent['headers']['From']);
        $this->assertEquals($mdn_addr, Horde_Mime::decode($sent['headers']['To']));
        $this->assertEquals('Disposition Notification', $sent['headers']['Subject']);
        $this->assertStringMatchesFormat('This message is in MIME format.

--=%s
Content-Type: text/plain; format=flowed; DelSp=Yes

The message sent on Tue, 18 Nov 2014 20:14:17 -0700 to BAR  
<*****@*****.**> with subject "Test" has been displayed.

This is no guarantee that the message has been read or understood.

--=%s
Content-Type: message/disposition-notification

Reporting-UA: test.example.com; Horde Application Framework 5
Final-Recipient: rfc822;bar@example.com
Disposition: manual-action/MDN-sent-manually; displayed/error
Error: Foo

--=%s
Content-Type: message/rfc822

Date: Tue, 18 Nov 2014 20:14:17 -0700
Subject: Test
To: BAR <*****@*****.**>
Disposition-Notification-To: =?utf-8?b?QcOkYg==?= <*****@*****.**>

--=%s
', $sent['body']);
    }
Exemplo n.º 3
0
 /**
  */
 public function report(IMP_Contents $contents, $action)
 {
     global $injector, $registry;
     $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create();
     switch ($this->_format) {
         case 'redirect':
             /* Send the message. */
             try {
                 $imp_compose->redirectMessage($contents->getIndicesOb());
                 $imp_compose->sendRedirectMessage($this->_email, false);
                 return true;
             } catch (IMP_Compose_Exception $e) {
                 $e->log();
             }
             break;
         case 'digest':
         default:
             try {
                 $from_line = $injector->getInstance('IMP_Identity')->getFromLine();
             } catch (Horde_Exception $e) {
                 $from_line = null;
             }
             /* Build the MIME structure. */
             $mime = new Horde_Mime_Part();
             $mime->setType('multipart/digest');
             $rfc822 = new Horde_Mime_Part();
             $rfc822->setType('message/rfc822');
             $rfc822->setContents($contents->fullMessageText(array('stream' => true)));
             $mime->addPart($rfc822);
             $spam_headers = new Horde_Mime_Headers();
             $spam_headers->addMessageIdHeader();
             $spam_headers->addHeader('Date', date('r'));
             $spam_headers->addHeader('To', $this->_email);
             if (!is_null($from_line)) {
                 $spam_headers->addHeader('From', $from_line);
             }
             $spam_headers->addHeader('Subject', sprintf(_("%s report from %s"), $action == IMP_Spam::SPAM ? 'spam' : 'innocent', $registry->getAuth()));
             /* Send the message. */
             try {
                 $recip_list = $imp_compose->recipientList(array('to' => $this->_email));
                 $imp_compose->sendMessage($recip_list['list'], $spam_headers, $mime, 'UTF-8');
                 $rfc822->clearContents();
                 return true;
             } catch (IMP_Compose_Exception $e) {
                 $e->log();
                 $rfc822->clearContents();
             }
             break;
     }
     return false;
 }
Exemplo n.º 4
0
 public function userConfirmationNeededProvider()
 {
     $out = array();
     $h = new Horde_Mime_Headers();
     $out[] = array(clone $h, true);
     $h->addHeader('Return-Path', '*****@*****.**');
     $out[] = array(clone $h, false);
     $h->addHeader('Return-Path', '*****@*****.**');
     $out[] = array(clone $h, true);
     $h->replaceHeader('Return-Path', '*****@*****.**');
     $h->addHeader(Horde_Mime_Mdn::MDN_HEADER, '*****@*****.**');
     $out[] = array(clone $h, true);
     $h->replaceHeader(Horde_Mime_Mdn::MDN_HEADER, '*****@*****.**');
     $out[] = array(clone $h, false);
     return $out;
 }
Exemplo n.º 5
0
 /**
  * Adds a message header.
  *
  * @param string $header      The header name.
  * @param string $value       The header value.
  * @param boolean $overwrite  If true, an existing header of the same name
  *                            is being overwritten; if false, multiple
  *                            headers are added; if null, the correct
  *                            behaviour is automatically chosen depending
  *                            on the header name.
  *
  * @throws Horde_Mime_Exception
  */
 public function addHeader($header, $value, $overwrite = null)
 {
     $lc_header = Horde_String::lower($header);
     if (is_null($overwrite) && in_array($lc_header, $this->_headers->singleFields(true))) {
         $overwrite = true;
     }
     if ($overwrite) {
         $this->_headers->removeHeader($header);
     }
     if ($lc_header === 'bcc') {
         $this->_bcc = $value;
     } else {
         $this->_headers->addHeader($header, $value);
     }
 }
Exemplo n.º 6
0
 /**
  */
 public function __set($name, $value)
 {
     if (!strlen($value)) {
         return;
     }
     switch ($name) {
         case 'bcc':
         case 'cc':
         case 'date':
         case 'from':
         case 'in_reply_to':
         case 'message_id':
         case 'reply_to':
         case 'sender':
         case 'subject':
         case 'to':
             switch ($name) {
                 case 'from':
                     foreach (array('reply_to', 'sender') as $val) {
                         if ($this->{$val}->match($value)) {
                             $this->_data->removeHeader($val);
                         }
                     }
                     break;
                 case 'reply_to':
                 case 'sender':
                     if ($this->from->match($value)) {
                         $this->_data->removeHeader($name);
                         return;
                     }
                     /* Convert reply-to name. */
                     if ($name == 'reply_to') {
                         $name = 'reply-to';
                     }
                     break;
             }
             $this->_data->addHeader($name, $value, array('sanity_check' => true));
             break;
     }
 }
Exemplo n.º 7
0
 /**
  */
 public function __set($name, $value)
 {
     if (!strlen($value)) {
         return;
     }
     $name = $this->_normalizeProperty($name);
     switch ($name) {
         case 'bcc':
         case 'cc':
         case 'date':
         case 'from':
         case 'in-reply-to':
         case 'message-id':
         case 'reply-to':
         case 'sender':
         case 'subject':
         case 'to':
             switch ($name) {
                 case 'from':
                     if ($this->reply_to->match($value)) {
                         unset($this->_data['reply-to']);
                     }
                     if ($this->sender->match($value)) {
                         unset($this->_data['sender']);
                     }
                     break;
                 case 'reply-to':
                 case 'sender':
                     if ($this->from->match($value)) {
                         unset($this->_data[$name]);
                         return;
                     }
                     break;
             }
             $this->_data->addHeader($name, $value);
             break;
     }
 }
Exemplo n.º 8
0
 public function testUndisclosedHeaderParsing()
 {
     $hdrs = new Horde_Mime_Headers();
     $hdrs->addHeader('To', 'undisclosed-recipients');
     $this->assertEquals('', $hdrs->getValue('To'));
     $hdrs = new Horde_Mime_Headers();
     $hdrs->addHeader('To', 'undisclosed-recipients:');
     $this->assertEquals('', $hdrs->getValue('To'));
     $hdrs = new Horde_Mime_Headers();
     $hdrs->addHeader('To', 'undisclosed-recipients:;');
     $this->assertEquals('', $hdrs->getValue('To'));
 }
Exemplo n.º 9
0
 /**
  * Builds a Horde_Mime_Headers object from header text.
  *
  * @param mixed $text  A text string (or, as of 2.3.0, a Horde_Stream
  *                     object or stream resource) containing the headers.
  *
  * @return Horde_Mime_Headers  A new Horde_Mime_Headers object.
  */
 public static function parseHeaders($text)
 {
     $curr = null;
     $headers = new Horde_Mime_Headers();
     $hdr_list = array();
     if ($text instanceof Horde_Stream) {
         $stream = $text;
         $stream->rewind();
     } else {
         $stream = new Horde_Stream_Temp();
         $stream->add($text, true);
     }
     while (!$stream->eof()) {
         if (!($val = rtrim($stream->getToChar("\n", false), "\r"))) {
             break;
         }
         if ($curr && ($val[0] == ' ' || $val[0] == "\t")) {
             $curr->text .= ' ' . ltrim($val);
         } else {
             $pos = strpos($val, ':');
             $curr = new stdClass();
             $curr->header = substr($val, 0, $pos);
             $curr->text = ltrim(substr($val, $pos + 1));
             $hdr_list[] = $curr;
         }
     }
     foreach ($hdr_list as $val) {
         /* When parsing, only keep the FIRST header seen for single value
          * text-only headers, since newer headers generally are appended
          * to the top of the message. */
         if (!($ob = $headers[$val->header]) || !$ob instanceof Horde_Mime_Headers_Element_Single || $ob instanceof Horde_Mime_Headers_Addresses) {
             $headers->addHeader($val->header, rtrim($val->text));
         }
     }
     if (!$text instanceof Horde_Stream) {
         $stream->close();
     }
     return $headers;
 }
Exemplo n.º 10
0
 /**
  * Generate the headers for the MIME envelope of a Kolab groupware object.
  *
  * @param string $user The current user.
  *
  * @return Horde_Mime_Headers The headers for the MIME envelope.
  */
 protected function createEnvelopeHeaders()
 {
     $headers = new Horde_Mime_Headers();
     $headers->setEOL("\r\n");
     $headers->addHeader('From', $this->_getDriver()->getAuth());
     $headers->addHeader('To', $this->_getDriver()->getAuth());
     $headers->addHeader('Date', date('r'));
     $headers->addHeader('Subject', $this->getUid());
     $headers->addHeader('User-Agent', 'Horde_Kolab_Storage ' . Horde_Kolab_Storage::VERSION);
     $headers->addHeader('MIME-Version', '1.0');
     $headers->addHeader('X-Kolab-Type', Horde_Kolab_Storage_Object_MimeType::getMimeTypeFromObjectType($this->getType()));
     return $headers;
 }
Exemplo n.º 11
0
 /**
  * Send notification to attachment owner.
  */
 public function sendNotification()
 {
     global $conf, $injector, $registry;
     if (empty($conf['compose']['link_attachments_notify'])) {
         return;
     }
     try {
         $identity = $injector->getInstance('Horde_Core_Factory_Identity')->create($this->_user);
         $address = $identity->getDefaultFromAddress();
         /* Ignore missing addresses, which are returned as <>. */
         if (strlen($address) < 3 || $this->_getDeleteToken()) {
             return;
         }
         $address_full = $identity->getDefaultFromAddress(true);
         /* Load user prefs to correctly translate gettext strings. */
         if (!$registry->getAuth()) {
             $prefs = $injector->getInstance('Horde_Core_Factory_Prefs')->create('imp', array('user' => $this->_user));
             $registry->setLanguageEnvironment($prefs->getValue('language'));
         }
         $h = new Horde_Mime_Headers();
         $h->addReceivedHeader(array('dns' => $injector->getInstance('Net_DNS2_Resolver'), 'server' => $conf['server']['name']));
         $h->addMessageIdHeader();
         $h->addUserAgentHeader();
         $h->addHeader('Date', date('r'));
         $h->addHeader('From', $address_full);
         $h->addHeader('To', $address_full);
         $h->addHeader('Subject', _("Notification: Linked attachment downloaded"));
         $h->addHeader('Auto-Submitted', 'auto-generated');
         $msg = new Horde_Mime_Part();
         $msg->setType('text/plain');
         $msg->setCharset('UTF-8');
         $md = $this->_atc->getMetadata();
         $msg->setContents(Horde_String::wrap(_("Your linked attachment has been downloaded by at least one user.") . "\n\n" . sprintf(_("Name: %s"), $md->filename) . "\n" . sprintf(_("Type: %s"), $md->type) . "\n" . sprintf(_("Sent Date: %s"), date('r', $md->time)) . "\n\n" . _("Click on the following link to permanently delete the attachment:") . "\n" . strval($this->_atc->link_url->add('d', $this->_getDeleteToken(true)))));
         $msg->send($address, $h, $injector->getInstance('Horde_Mail'));
     } catch (Exception $e) {
         Horde::log($e, 'ERR');
     }
 }
Exemplo n.º 12
0
 /**
  * @dataProvider headerGenerationProvider
  */
 public function testHeaderGeneration($label, $data, $class)
 {
     $hdrs = new Horde_Mime_Headers();
     $this->assertNull($hdrs[$label]);
     $hdrs->addHeader($label, $data);
     $ob = $hdrs[$label];
     $this->assertNotNull($ob);
     $this->assertInstanceOf($class, $ob);
 }
Exemplo n.º 13
0
Arquivo: Mail.php Projeto: horde/horde
 /**
  * Get a Horde_Mime object representint the data contained in this object.
  *
  * [MS_ASEMAIL 3.1.53]
  *
  * @return array An array containing:
  *         - part: Horde_Mime_Part containing the body data NO ATTACHMENTS.
  *         - headers: Horde_Mime_Headers containing the envelope headers.
  */
 public function draftToMime()
 {
     // Main text body.
     $text = new Horde_Mime_Part();
     $body = $this->airsyncbasebody;
     $text->setContents($body->data);
     if ($body->type == Horde_ActiveSync::BODYPREF_TYPE_HTML) {
         $text->setType('text/html');
     } else {
         $text->setType('text/plain');
     }
     // Add headers that are sent with ADD;
     $headers = new Horde_Mime_Headers();
     if ($this->to) {
         $headers->addHeader('To', $this->to);
     }
     if ($this->cc) {
         $headers->addHeader('Cc', $this->cc);
     }
     if ($this->subject) {
         $headers->addHeader('Subject', $this->subject);
     }
     if ($this->bcc) {
         $headers->addHeader('Bcc', $this->bcc);
     }
     if ($this->reply_to) {
         $headers->addHeader('reply-to', $this->reply_to);
     }
     if ($this->importance) {
         $headers->addHeader('importance', $this->importance);
     }
     return array('part' => $text, 'headers' => $headers);
 }
Exemplo n.º 14
0
 /**
  * Send a redirect (a/k/a resent) message. See RFC 5322 [3.6.6].
  *
  * @param mixed $to  The addresses to redirect to.
  * @param boolean $log  Whether to log the resending in the history and
  *                      sentmail log.
  *
  * @return array  An object with the following properties for each
  *                redirected message:
  *   - contents: (IMP_Contents) The contents object.
  *   - headers: (Horde_Mime_Headers) The header object.
  *   - mbox: (IMP_Mailbox) Mailbox of the message.
  *   - uid: (string) UID of the message.
  *
  * @throws IMP_Compose_Exception
  */
 public function sendRedirectMessage($to, $log = true)
 {
     global $injector, $registry;
     $recip = $this->recipientList(array('to' => $to));
     $identity = $injector->getInstance('IMP_Identity');
     $from_addr = $identity->getFromAddress();
     $out = array();
     foreach ($this->getMetadata('redirect_indices') as $val) {
         foreach ($val->uids as $val2) {
             try {
                 $contents = $injector->getInstance('IMP_Factory_Contents')->create($val->mbox->getIndicesOb($val2));
             } catch (IMP_Exception $e) {
                 throw new IMP_Compose_Exception(_("Error when redirecting message."));
             }
             $headers = $contents->getHeader();
             /* We need to set the Return-Path header to the current user -
              * see RFC 2821 [4.4]. */
             $headers->removeHeader('return-path');
             $headers->addHeader('Return-Path', $from_addr);
             /* Generate the 'Resent' headers (RFC 5322 [3.6.6]). These
              * headers are prepended to the message. */
             $resent_headers = new Horde_Mime_Headers();
             $resent_headers->addHeader('Resent-Date', date('r'));
             $resent_headers->addHeader('Resent-From', $from_addr);
             $resent_headers->addHeader('Resent-To', $recip['header']['to']);
             $resent_headers->addHeader('Resent-Message-ID', Horde_Mime_Headers_MessageId::create());
             $header_text = trim($resent_headers->toString(array('encode' => 'UTF-8'))) . "\n" . trim($contents->getHeader(IMP_Contents::HEADER_TEXT));
             $this->_prepSendMessageAssert($recip['list']);
             $to = $this->_prepSendMessage($recip['list']);
             $hdr_array = $headers->toArray(array('charset' => 'UTF-8'));
             $hdr_array['_raw'] = $header_text;
             try {
                 $injector->getInstance('IMP_Mail')->send($to, $hdr_array, $contents->getBody());
             } catch (Horde_Mail_Exception $e) {
                 $e2 = new IMP_Compose_Exception($e);
                 if (($prev = $e->getPrevious()) && $prev instanceof Horde_Smtp_Exception) {
                     if ($prev instanceof Horde_Smtp_Exception_Recipients) {
                         $e2 = new IMP_Compose_Exception_Addresses($e);
                         foreach ($prev->recipients as $val) {
                             $e2->addAddress(new Horde_Mail_Rfc822_Address($val), _("Address rejected by the sending mail server."), $e2::BAD);
                         }
                     }
                     Horde::log(sprintf("SMTP Error: %s (%u; %s)", $prev->raw_msg, $prev->getCode(), $prev->getEnhancedSmtpCode() ?: 'N/A'), 'ERR');
                     $e2->logged = true;
                 }
                 throw $e2;
             }
             $recipients = strval($recip['list']);
             Horde::log(sprintf("%s Redirected message sent to %s from %s", $_SERVER['REMOTE_ADDR'], $recipients, $registry->getAuth()), 'INFO');
             if ($log && ($tmp = $headers['Message-ID'])) {
                 $msg_id = reset($tmp->getIdentificationOb()->ids);
                 /* Store history information. */
                 $injector->getInstance('IMP_Maillog')->log(new IMP_Maillog_Message($msg_id), new IMP_Maillog_Log_Redirect(array('msgid' => reset($resent_headers->getIdentificationOb()->ids), 'recipients' => $recipients)));
                 $injector->getInstance('IMP_Sentmail')->log(IMP_Sentmail::REDIRECT, $msg_id, $recipients);
             }
             $tmp = new stdClass();
             $tmp->contents = $contents;
             $tmp->headers = $headers;
             $tmp->mbox = $val->mbox;
             $tmp->uid = $val2;
             $out[] = $tmp;
         }
     }
     return $out;
 }
Exemplo n.º 15
0
 /**
  * @dataProvider getObjectAndMimeTypes
  */
 public function testMatchMimePartToHeaderType($type, $mime_type)
 {
     $headers = new Horde_Mime_Headers();
     $headers->addHeader('X-Kolab-Type', $mime_type);
     $this->assertEquals(array(2, $type), Horde_Kolab_Storage_Object_MimeType::matchMimePartToHeaderType($this->getMultipartMimeMessage($mime_type), $headers));
 }
Exemplo n.º 16
0
 /**
  * Builds a Horde_Mime_Headers object from header text.
  *
  * @param mixed $text  A text string (or, as of 2.3.0, a Horde_Stream
  *                     object or stream resource) containing the headers.
  *
  * @return Horde_Mime_Headers  A new Horde_Mime_Headers object.
  */
 public static function parseHeaders($text)
 {
     $currheader = $currtext = null;
     $mime = self::mimeParamFields();
     $to_process = array();
     if ($text instanceof Horde_Stream) {
         $stream = $text;
         $stream->rewind();
     } else {
         $stream = new Horde_Stream_Temp();
         $stream->add($text, true);
     }
     while (!$stream->eof()) {
         if (!($val = rtrim($stream->getToChar("\n", false), "\r"))) {
             break;
         }
         if ($val[0] == ' ' || $val[0] == "\t") {
             $currtext .= ' ' . ltrim($val);
         } else {
             if (!is_null($currheader)) {
                 $to_process[] = array($currheader, rtrim($currtext));
             }
             $pos = strpos($val, ':');
             $currheader = substr($val, 0, $pos);
             $currtext = ltrim(substr($val, $pos + 1));
         }
     }
     if (!is_null($currheader)) {
         $to_process[] = array($currheader, $currtext);
     }
     $headers = new Horde_Mime_Headers();
     reset($to_process);
     while (list(, $val) = each($to_process)) {
         /* Ignore empty headers. */
         if (!strlen($val[1])) {
             continue;
         }
         if (in_array(Horde_String::lower($val[0]), $mime)) {
             $res = Horde_Mime::decodeParam($val[0], $val[1]);
             $headers->addHeader($val[0], $res['val'], array('params' => $res['params'], 'sanity_check' => true));
         } else {
             $headers->addHeader($val[0], $val[1], array('sanity_check' => true));
         }
     }
     return $headers;
 }
Exemplo n.º 17
0
 /**
  */
 public function replaceHeader($header, $value, array $opts = array())
 {
     $this->_headers->removeHeader($header);
     $this->_headers->addHeader($header, $value, $opts);
 }
Exemplo n.º 18
0
 public function testBug14381()
 {
     $hdrs = new Horde_Mime_Headers();
     $hdrs->addHeader('Date', 'Sat, 22 May 2016 01:41:04 0000');
     $this->assertEquals($hdrs->getValue('Date'), 'Sat, 22 May 2016 01:41:04 +0000');
     $hdrs = new Horde_Mime_Headers();
     $hdrs->addHeader('Date', 'Sat, 22 May 2016 01:41:04 +0000');
     $this->assertEquals($hdrs->getValue('Date'), 'Sat, 22 May 2016 01:41:04 +0000');
 }
Exemplo n.º 19
0
 /**
  * Return the response as a MIME message.
  *
  * @param Horde_Itip_Response_Type    $type    The response type.
  * @param Horde_Itip_Response_Options $options The options for the response.
  *
  * @return array A list of two object: The mime headers and the mime
  *               message.
  */
 public function getMessage(Horde_Itip_Response_Type $type, Horde_Itip_Response_Options $options)
 {
     $message = new Horde_Mime_Part();
     $message->setType('text/calendar');
     $options->prepareIcsMimePart($message);
     $message->setContents($this->getIcalendar($type, $options)->exportvCalendar());
     $message->setEOL("\r\n");
     $this->_setIcsFilename($message);
     $message->setContentTypeParameter('METHOD', 'REPLY');
     // Build the reply headers.
     $from = $this->_resource->getFrom();
     $reply_to = $this->_resource->getReplyTo();
     $headers = new Horde_Mime_Headers();
     $headers->addHeaderOb(Horde_Mime_Headers_Date::create());
     $headers->addHeader('From', $from);
     $headers->addHeader('To', $this->_request->getOrganizer());
     if (!empty($reply_to) && $reply_to != $from) {
         $headers->addHeader('Reply-to', $reply_to);
     }
     $headers->addHeader('Subject', $type->getSubject());
     $options->prepareResponseMimeHeaders($headers);
     return array($headers, $message);
 }
Exemplo n.º 20
0
 /**
  * Sends this message.
  *
  * @param Mail $mailer     A Mail object.
  * @param boolean $resend  If true, the message id and date are re-used;
  *                         If false, they will be updated.
  * @param boolean $flowed  Send message in flowed text format.
  *
  * @throws Horde_Mime_Exception
  */
 public function send($mailer, $resend = false, $flowed = true)
 {
     /* Add mandatory headers if missing. */
     $has_header = $this->_headers->getValue('Message-ID');
     if (!$resend || !$has_header) {
         if ($has_header) {
             $this->_headers->removeHeader('Message-ID');
         }
         $this->_headers->addMessageIdHeader();
     }
     if (!$this->_headers->getValue('User-Agent')) {
         $this->_headers->addUserAgentHeader();
     }
     $has_header = $this->_headers->getValue('Date');
     if (!$resend || !$has_header) {
         if ($has_header) {
             $this->_headers->removeHeader('Date');
         }
         $this->_headers->addHeader('Date', date('r'));
     }
     if (isset($this->_base)) {
         $basepart = $this->_base;
     } else {
         /* Send in flowed format. */
         if ($flowed && !empty($this->_body)) {
             $flowed = new Horde_Text_Flowed($this->_body->getContents(), $this->_body->getCharset());
             $flowed->setDelSp(true);
             $this->_body->setContentTypeParameter('format', 'flowed');
             $this->_body->setContentTypeParameter('DelSp', 'Yes');
             $this->_body->setContents($flowed->toFlowed());
         }
         /* Build mime message. */
         $body = new Horde_Mime_Part();
         if (!empty($this->_body) && !empty($this->_htmlBody)) {
             $body->setType('multipart/alternative');
             $this->_body->setDescription(Horde_Mime_Translation::t("Plaintext Version of Message"));
             $body->addPart($this->_body);
             $this->_htmlBody->setDescription(Horde_Mime_Translation::t("HTML Version of Message"));
             $body->addPart($this->_htmlBody);
         } elseif (!empty($this->_htmlBody)) {
             $body = $this->_htmlBody;
         } elseif (!empty($this->_body)) {
             $body = $this->_body;
         }
         if (count($this->_parts)) {
             $basepart = new Horde_Mime_Part();
             $basepart->setType('multipart/mixed');
             $basepart->isBasePart(true);
             if ($body) {
                 $basepart->addPart($body);
             }
             foreach ($this->_parts as $mime_part) {
                 $basepart->addPart($mime_part);
             }
         } else {
             $basepart = $body;
             $basepart->isBasePart(true);
         }
     }
     $basepart->setHeaderCharset($this->_charset);
     /* Build recipients. */
     $recipients = clone $this->_recipients;
     foreach (array('to', 'cc') as $header) {
         $recipients->add($this->_headers->getOb($header));
     }
     if ($this->_bcc) {
         $recipients->add($this->_bcc);
     }
     /* Trick Horde_Mime_Part into re-generating the message headers. */
     $this->_headers->removeHeader('MIME-Version');
     /* Send message. */
     $recipients->unique();
     $basepart->send($recipients->writeAddress(), $this->_headers, $mailer);
     /* Remember the basepart */
     $this->_base = $basepart;
 }
Exemplo n.º 21
0
 /**
  * Builds and sends a digest message.
  *
  * @param array $messages  List of message contents (string|resource).
  * @param integer $action  Either Horde_Spam::SPAM or Horde_Spam::INNOCENT.
  *
  * @return integer  The number of reported messages.
  */
 protected function _reportDigest(array $messages, $action)
 {
     if (empty($messages)) {
         return 0;
     }
     /* Build the MIME structure. */
     $mime = new Horde_Mime_Part();
     $mime->setType('multipart/digest');
     foreach ($messages as $val) {
         $rfc822 = new Horde_Mime_Part();
         $rfc822->setType('message/rfc822');
         $rfc822->setContents($val);
         $mime[] = $rfc822;
     }
     $spam_headers = new Horde_Mime_Headers();
     $spam_headers->addHeaderOb(Horde_Mime_Headers_MessageId::create());
     $spam_headers->addHeaderOb(Horde_Mime_Headers_Date::create());
     $spam_headers->addHeader('To', $this->_email);
     $spam_headers->addHeader('From', $this->_from_addr);
     $spam_headers->addHeader('Subject', sprintf(Horde_Spam_Translation::t("%s report from %s"), $action === Horde_Spam::SPAM ? 'spam' : 'innocent', $this->_user));
     /* Send the message. */
     try {
         $mime->send($this->_email, $spam_headers, $this->_mail);
         return count($messages);
     } catch (Horde_Mail_Exception $e) {
         $this->_logger->warn($e);
         return 0;
     }
 }
Exemplo n.º 22
0
 /**
  * Add a MDN (read receipt) request header.
  *
  * @param mixed $to  The address(es) the receipt should be mailed to.
  */
 public function addMdnRequestHeaders($to)
 {
     /* This is the RFC 3798 way of requesting a receipt. */
     $this->_headers->addHeader(self::MDN_HEADER, $to);
 }
Exemplo n.º 23
0
 public function headersProvider()
 {
     $hdrs = new Horde_Mime_Headers();
     $hdrs->addHeader('From', '*****@*****.**');
     return array(array(null, ''), array("From: test@example.com\n\n", "From: test@example.com\n\n"), array($hdrs, "From: test@example.com\n\n"));
 }
Exemplo n.º 24
0
 /**
  * Builds a Horde_Mime_Headers object from header text.
  * This function can be called statically:
  *   $headers = Horde_Mime_Headers::parseHeaders().
  *
  * @param string $text  A text string containing the headers.
  *
  * @return Horde_Mime_Headers  A new Horde_Mime_Headers object.
  */
 public static function parseHeaders($text)
 {
     $currheader = $currtext = null;
     $mime = self::mimeParamFields();
     $to_process = array();
     foreach (explode("\n", $text) as $val) {
         $val = rtrim($val);
         if (empty($val)) {
             break;
         }
         if ($val[0] == ' ' || $val[0] == "\t") {
             $currtext .= ' ' . ltrim($val);
         } else {
             if (!is_null($currheader)) {
                 $to_process[] = array($currheader, $currtext);
             }
             $pos = strpos($val, ':');
             $currheader = substr($val, 0, $pos);
             $currtext = ltrim(substr($val, $pos + 1));
         }
     }
     if (!is_null($currheader)) {
         $to_process[] = array($currheader, $currtext);
     }
     $headers = new Horde_Mime_Headers();
     reset($to_process);
     while (list(, $val) = each($to_process)) {
         /* Ignore empty headers. */
         if (!strlen($val[1])) {
             continue;
         }
         if (in_array(Horde_String::lower($val[0]), $mime)) {
             $res = Horde_Mime::decodeParam($val[0], $val[1]);
             $headers->addHeader($val[0], $res['val'], array('params' => $res['params'], 'sanity_check' => true));
         } else {
             $headers->addHeader($val[0], $val[1], array('sanity_check' => true));
         }
     }
     return $headers;
 }
Exemplo n.º 25
0
 /**
  */
 public function report(array $msgs, $action)
 {
     global $injector;
     $ret = 0;
     switch ($this->_format) {
         case 'redirect':
             /* Send the message. */
             foreach ($msgs as $val) {
                 try {
                     $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create();
                     $imp_compose->redirectMessage($val->getIndicesOb());
                     $imp_compose->sendRedirectMessage($this->_email, false);
                     ++$ret;
                 } catch (IMP_Compose_Exception $e) {
                     $e->log();
                 }
             }
             break;
         case 'digest':
         default:
             try {
                 $from_line = $injector->getInstance('IMP_Identity')->getFromLine();
             } catch (Horde_Exception $e) {
                 $from_line = null;
             }
             $self = $this;
             $reportDigest = function ($m) use($action, $from_line, $self) {
                 global $injector, $registry;
                 if (empty($m)) {
                     return 0;
                 }
                 /* Build the MIME structure. */
                 $mime = new Horde_Mime_Part();
                 $mime->setType('multipart/digest');
                 foreach ($m as $val) {
                     $rfc822 = new Horde_Mime_Part();
                     $rfc822->setType('message/rfc822');
                     $rfc822->setContents($val->fullMessageText(array('stream' => true)));
                     $mime[] = $rfc822;
                 }
                 $spam_headers = new Horde_Mime_Headers();
                 $spam_headers->addHeaderOb(Horde_Mime_Headers_MessageId::create());
                 $spam_headers->addHeaderOb(Horde_Mime_Headers_Date::create());
                 $spam_headers->addHeader('To', $this->_email);
                 if (!is_null($from_line)) {
                     $spam_headers->addHeader('From', $from_line);
                 }
                 $spam_headers->addHeader('Subject', sprintf(_("%s report from %s"), $action === IMP_Spam::SPAM ? 'spam' : 'innocent', $registry->getAuth()));
                 /* Send the message. */
                 try {
                     $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create();
                     $recip_list = $imp_compose->recipientList(array('to' => $this->_email));
                     $imp_compose->sendMessage($recip_list['list'], $spam_headers, $mime, 'UTF-8');
                     return count($m);
                 } catch (IMP_Compose_Exception $e) {
                     $e->log();
                     return 0;
                 }
             };
             $mlimit = $orig_mlimit = empty($this->_opts['digest_limit_msgs']) ? null : $this->_opts['digest_limit_msgs'];
             $slimit = $orig_slimit = empty($this->_opts['digest_limit_size']) ? null : $this->_opts['digest_limit_size'];
             $todo = array();
             foreach ($msgs as $val) {
                 $process = false;
                 $todo[] = $val;
                 if (!is_null($mlimit) && !--$mlimit) {
                     $process = true;
                 }
                 if (!is_null($slimit) && ($slimit -= $val->getMIMEMessage()->getBytes()) < 0) {
                     $process = true;
                     /* If we have exceeded size limits with this single
                      * message, it exceeds the maximum limit and we can't
                      * send it at all. Don't confuse the user and instead
                      * report is as a "success" for UI purposes. */
                     if (count($todo) === 1) {
                         ++$ret;
                         $todo = array();
                         Horde::log('Could not send spam/innocent reporting message because original message was too large.', 'NOTICE');
                     }
                 }
                 if ($process) {
                     $ret += $reportDigest($todo);
                     $todo = array();
                     $mlimit = $orig_mlimit;
                     $slimit = $orig_slimit;
                 }
             }
             $ret += $reportDigest($todo);
             break;
     }
     return $ret;
 }
Exemplo n.º 26
0
 /**
  * Variables required in form input:
  *   - identity (TODO: ? Code uses it, but it is never set anywhere)
  *   - imple_submit: itip_action(s)
  *   - mime_id
  *   - muid
  *
  * @return boolean  True on success.
  */
 protected function _handle(Horde_Variables $vars)
 {
     global $injector, $notification, $registry;
     $actions = (array) $vars->imple_submit;
     $result = false;
     $vCal = new Horde_Icalendar();
     /* Retrieve the calendar data from the message. */
     try {
         $contents = $injector->getInstance('IMP_Factory_Contents')->create(new IMP_Indices_Mailbox($vars));
         $mime_part = $contents->getMIMEPart($vars->mime_id);
         if (empty($mime_part)) {
             throw new IMP_Exception(_("Cannot retrieve calendar data from message."));
         } elseif (!$vCal->parsevCalendar($mime_part->getContents(), 'VCALENDAR', $mime_part->getCharset())) {
             throw new IMP_Exception(_("The calendar data is invalid"));
         }
         $components = $vCal->getComponents();
     } catch (Exception $e) {
         $notification->push($e, 'horde.error');
         $actions = array();
     }
     foreach ($actions as $key => $action) {
         $pos = strpos($key, '[');
         $key = substr($key, $pos + 1, strlen($key) - $pos - 2);
         switch ($action) {
             case 'delete':
                 // vEvent cancellation.
                 if ($registry->hasMethod('calendar/delete')) {
                     $guid = $components[$key]->getAttribute('UID');
                     $recurrenceId = null;
                     try {
                         // This is a cancellation of a recurring event instance.
                         $recurrenceId = $components[$key]->getAttribute('RECURRENCE-ID');
                         $atts = $components[$key]->getAttribute('RECURRENCE-ID', true);
                         $range = null;
                         foreach ($atts as $att) {
                             if (array_key_exists('RANGE', $att)) {
                                 $range = $att['RANGE'];
                             }
                         }
                     } catch (Horde_Icalendar_Exception $e) {
                     }
                     try {
                         $registry->call('calendar/delete', array($guid, $recurrenceId, $range));
                         $notification->push(_("Event successfully deleted."), 'horde.success');
                         $result = true;
                     } catch (Horde_Exception $e) {
                         $notification->push(sprintf(_("There was an error deleting the event: %s"), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 break;
             case 'update':
                 // vEvent reply.
                 if ($registry->hasMethod('calendar/updateAttendee')) {
                     try {
                         $from = $contents->getHeader()->getOb('from');
                         $registry->call('calendar/updateAttendee', array($components[$key], $from[0]->bare_address));
                         $notification->push(_("Respondent Status Updated."), 'horde.success');
                         $result = true;
                     } catch (Horde_Exception $e) {
                         $notification->push(sprintf(_("There was an error updating the event: %s"), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 break;
             case 'import':
             case 'accept-import':
                 // vFreebusy reply.
                 // vFreebusy publish.
                 // vEvent request.
                 // vEvent publish.
                 // vTodo publish.
                 // vJournal publish.
                 switch ($components[$key]->getType()) {
                     case 'vEvent':
                         $result = $this->_handlevEvent($key, $components, $mime_part);
                         // Must check for exceptions.
                         foreach ($components as $k => $component) {
                             try {
                                 if ($component->getType() == 'vEvent' && $component->getAttribute('RECURRENCE-ID')) {
                                     $uid = $component->getAttribute('UID');
                                     if ($uid == $components[$key]->getAttribute('UID')) {
                                         $this->_handlevEvent($k, $components, $mime_part);
                                     }
                                 }
                             } catch (Horde_Icalendar_Exception $e) {
                             }
                         }
                         break;
                     case 'vFreebusy':
                         // Import into Kronolith.
                         if ($registry->hasMethod('calendar/import_vfreebusy')) {
                             try {
                                 $registry->call('calendar/import_vfreebusy', array($components[$key]));
                                 $notification->push(_("The user's free/busy information was sucessfully stored."), 'horde.success');
                                 $result = true;
                             } catch (Horde_Exception $e) {
                                 $notification->push(sprintf(_("There was an error importing user's free/busy information: %s"), $e->getMessage()), 'horde.error');
                             }
                         } else {
                             $notification->push(_("This action is not supported."), 'horde.warning');
                         }
                         break;
                     case 'vTodo':
                         // Import into Nag.
                         if ($registry->hasMethod('tasks/import')) {
                             try {
                                 $guid = $registry->call('tasks/import', array($components[$key], $mime_part->getType()));
                                 $url = Horde::url($registry->link('tasks/show', array('uid' => $guid)));
                                 $notification->push(_("The task has been added to your tasklist.") . '&nbsp;' . Horde::link($url, _("View task"), null, '_blank') . Horde_Themes_Image::tag('mime/icalendar.png', array('alt' => _("View task"))) . '</a>', 'horde.success', array('content.raw'));
                                 $result = true;
                             } catch (Horde_Exception $e) {
                                 $notification->push(sprintf(_("There was an error importing the task: %s"), $e->getMessage()), 'horde.error');
                             }
                         } else {
                             $notification->push(_("This action is not supported."), 'horde.warning');
                         }
                         break;
                     case 'vJournal':
                     default:
                         $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 if ($action == 'import') {
                     break;
                 }
                 // Fall-through for 'accept-import'
             // Fall-through for 'accept-import'
             case 'accept':
             case 'deny':
             case 'tentative':
                 // vEvent request.
                 if (isset($components[$key]) && $components[$key]->getType() == 'vEvent') {
                     $vEvent = $components[$key];
                     $resource = new Horde_Itip_Resource_Identity($injector->getInstance('IMP_Identity'), $vEvent->getAttribute('ATTENDEE'), $vars->identity);
                     switch ($action) {
                         case 'accept':
                         case 'accept-import':
                             $type = new Horde_Itip_Response_Type_Accept($resource);
                             break;
                         case 'deny':
                             $type = new Horde_Itip_Response_Type_Decline($resource);
                             break;
                         case 'tentative':
                             $type = new Horde_Itip_Response_Type_Tentative($resource);
                             break;
                     }
                     try {
                         // Send the reply.
                         Horde_Itip::factory($vEvent, $resource)->sendMultiPartResponse($type, new Horde_Core_Itip_Response_Options_Horde('UTF-8', array()), $injector->getInstance('IMP_Mail'));
                         $notification->push(_("Reply Sent."), 'horde.success');
                         $result = true;
                     } catch (Horde_Itip_Exception $e) {
                         $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 break;
             case 'send':
             case 'reply':
             case 'reply2m':
                 // vfreebusy request.
                 if (isset($components[$key]) && $components[$key]->getType() == 'vFreebusy') {
                     $vFb = $components[$key];
                     // Get the organizer details.
                     try {
                         $organizer = parse_url($vFb->getAttribute('ORGANIZER'));
                     } catch (Horde_Icalendar_Exception $e) {
                         break;
                     }
                     $organizerEmail = $organizer['path'];
                     $organizer = $vFb->getAttribute('ORGANIZER', true);
                     $organizerFullEmail = new Horde_Mail_Rfc822_Address($organizerEmail);
                     if (isset($organizer['cn'])) {
                         $organizerFullEmail->personal = $organizer['cn'];
                     }
                     if ($action == 'reply2m') {
                         $startStamp = time();
                         $endStamp = $startStamp + 60 * 24 * 3600;
                     } else {
                         try {
                             $startStamp = $vFb->getAttribute('DTSTART');
                         } catch (Horde_Icalendar_Exception $e) {
                             $startStamp = time();
                         }
                         try {
                             $endStamp = $vFb->getAttribute('DTEND');
                         } catch (Horde_Icalendar_Exception $e) {
                         }
                         if (!$endStamp) {
                             try {
                                 $duration = $vFb->getAttribute('DURATION');
                                 $endStamp = $startStamp + $duration;
                             } catch (Horde_Icalendar_Exception $e) {
                                 $endStamp = $startStamp + 60 * 24 * 3600;
                             }
                         }
                     }
                     $vfb_reply = $registry->call('calendar/getFreeBusy', array($startStamp, $endStamp));
                     // Find out who we are and update status.
                     $identity = $injector->getInstance('IMP_Identity');
                     $email = $identity->getFromAddress();
                     // Build the reply.
                     $msg_headers = new Horde_Mime_Headers();
                     $vCal = new Horde_Icalendar();
                     $vCal->setAttribute('PRODID', '-//The Horde Project//' . $msg_headers->getUserAgent() . '//EN');
                     $vCal->setAttribute('METHOD', 'REPLY');
                     $vCal->addComponent($vfb_reply);
                     $message = _("Attached is a reply to a calendar request you sent.");
                     $body = new Horde_Mime_Part();
                     $body->setType('text/plain');
                     $body->setCharset('UTF-8');
                     $body->setContents(Horde_String::wrap($message, 76));
                     $ics = new Horde_Mime_Part();
                     $ics->setType('text/calendar');
                     $ics->setCharset('UTF-8');
                     $ics->setContents($vCal->exportvCalendar());
                     $ics->setName('icalendar.ics');
                     $ics->setContentTypeParameter('METHOD', 'REPLY');
                     $mime = new Horde_Mime_Part();
                     $mime->addPart($body);
                     $mime->addPart($ics);
                     // Build the reply headers.
                     $msg_headers->addReceivedHeader(array('dns' => $injector->getInstance('Net_DNS2_Resolver'), 'server' => $conf['server']['name']));
                     $msg_headers->addMessageIdHeader();
                     $msg_headers->addHeader('Date', date('r'));
                     $msg_headers->addHeader('From', $email);
                     $msg_headers->addHeader('To', $organizerFullEmail);
                     $identity->setDefault($vars->identity);
                     $replyto = $identity->getValue('replyto_addr');
                     if (!empty($replyto) && !$email->match($replyto)) {
                         $msg_headers->addHeader('Reply-To', $replyto);
                     }
                     $msg_headers->addHeader('Subject', _("Free/Busy Request Response"));
                     // Send the reply.
                     try {
                         $mime->send($organizerEmail, $msg_headers, $injector->getInstance('IMP_Mail'));
                         $notification->push(_("Reply Sent."), 'horde.success');
                         $result = true;
                     } catch (Exception $e) {
                         $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("Invalid Action selected for this component."), 'horde.warning');
                 }
                 break;
             case 'nosup':
                 // vFreebusy request.
             // vFreebusy request.
             default:
                 $notification->push(_("This action is not supported."), 'horde.warning');
                 break;
         }
     }
     return $result;
 }
Exemplo n.º 27
0
 /**
  * Send a redirect (a/k/a resent) message. See RFC 5322 [3.6.6].
  *
  * @param mixed $to  The addresses to redirect to.
  * @param boolean $log  Whether to log the resending in the history and
  *                      sentmail log.
  *
  * @return array  An object with the following properties for each
  *                redirected message:
  *   - contents: (IMP_Contents) The contents object.
  *   - headers: (Horde_Mime_Headers) The header object.
  *   - mbox: (IMP_Mailbox) Mailbox of the message.
  *   - uid: (string) UID of the message.
  *
  * @throws IMP_Compose_Exception
  */
 public function sendRedirectMessage($to, $log = true)
 {
     global $injector, $registry;
     $recip = $this->recipientList(array('to' => $to));
     $identity = $injector->getInstance('IMP_Identity');
     $from_addr = $identity->getFromAddress();
     $out = array();
     foreach ($this->getMetadata('redirect_indices') as $val) {
         foreach ($val->uids as $val2) {
             try {
                 $contents = $injector->getInstance('IMP_Factory_Contents')->create($val->mbox->getIndicesOb($val2));
             } catch (IMP_Exception $e) {
                 throw new IMP_Compose_Exception(_("Error when redirecting message."));
             }
             $headers = $contents->getHeader();
             /* We need to set the Return-Path header to the current user -
              * see RFC 2821 [4.4]. */
             $headers->removeHeader('return-path');
             $headers->addHeader('Return-Path', $from_addr);
             /* Generate the 'Resent' headers (RFC 5322 [3.6.6]). These
              * headers are prepended to the message. */
             $resent_headers = new Horde_Mime_Headers();
             $resent_headers->addHeader('Resent-Date', date('r'));
             $resent_headers->addHeader('Resent-From', $from_addr);
             $resent_headers->addHeader('Resent-To', $recip['header']['to']);
             $resent_headers->addHeader('Resent-Message-ID', Horde_Mime::generateMessageId());
             $header_text = trim($resent_headers->toString(array('encode' => 'UTF-8'))) . "\n" . trim($contents->getHeader(IMP_Contents::HEADER_TEXT));
             $this->_prepSendMessageAssert($recip['list']);
             $to = $this->_prepSendMessage($recip['list']);
             $hdr_array = $headers->toArray(array('charset' => 'UTF-8'));
             $hdr_array['_raw'] = $header_text;
             try {
                 $injector->getInstance('IMP_Mail')->send($to, $hdr_array, $contents->getBody());
             } catch (Horde_Mail_Exception $e) {
                 throw new IMP_Compose_Exception($e);
             }
             $recipients = strval($recip['list']);
             Horde::log(sprintf("%s Redirected message sent to %s from %s", $_SERVER['REMOTE_ADDR'], $recipients, $registry->getAuth()), 'INFO');
             if ($log) {
                 /* Store history information. */
                 $msg_id = new Horde_Mail_Rfc822_Identification($headers->getValue('message-id'));
                 $injector->getInstance('IMP_Maillog')->log(new IMP_Maillog_Message(reset($msg_id->ids)), new IMP_Maillog_Log_Redirect($recipients));
                 $injector->getInstance('IMP_Sentmail')->log(IMP_Sentmail::REDIRECT, reset($msg_id->ids), $recipients);
             }
             $tmp = new stdClass();
             $tmp->contents = $contents;
             $tmp->headers = $headers;
             $tmp->mbox = $val->mbox;
             $tmp->uid = $val2;
             $out[] = $tmp;
         }
     }
     return $out;
 }