[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/horde/framework/Horde/Mail/ -> Transport.php (source)

   1  <?php
   2  /**
   3   * Copyright 1997-2014 Horde LLC (http://www.horde.org/)
   4   * Copyright (c) 2002-2007, Richard Heyes
   5   * All rights reserved.
   6   *
   7   * Redistribution and use in source and binary forms, with or without
   8   * modification, are permitted provided that the following conditions
   9   * are met:
  10   *
  11   * o Redistributions of source code must retain the above copyright
  12   *   notice, this list of conditions and the following disclaimer.
  13   * o Redistributions in binary form must reproduce the above copyright
  14   *   notice, this list of conditions and the following disclaimer in the
  15   *   documentation and/or other materials provided with the distribution.
  16   * o The names of the authors may not be used to endorse or promote
  17   *   products derived from this software without specific prior written
  18   *   permission.
  19   *
  20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31   *
  32   * @category  Horde
  33   * @copyright 1997-2014 Horde LLC (http://www.horde.org/)
  34   * @copyright 2002-2007 Richard Heyes
  35   * @license   http://www.horde.org/licenses/bsd New BSD License
  36   * @package   Mail
  37   */
  38  
  39  /**
  40   * Mail transport base class.
  41   *
  42   * @author    Chuck Hagenbuch <chuck@horde.org>
  43   * @author    Richard Heyes <richard@phpguru.org>
  44   * @author    Michael Slusarz <slusarz@horde.org>
  45   * @category  Horde
  46   * @copyright 1997-2014 Horde LLC (http://www.horde.org/)
  47   * @copyright 2002-2007 Richard Heyes
  48   * @license   http://www.horde.org/licenses/bsd New BSD License
  49   * @package   Mail
  50   */
  51  abstract class Horde_Mail_Transport
  52  {
  53      /**
  54       * Line terminator used for separating header lines.
  55       *
  56       * @var string
  57       */
  58      public $sep = PHP_EOL;
  59  
  60      /**
  61       * Configuration parameters.
  62       *
  63       * @var array
  64       */
  65      protected $_params = array();
  66  
  67      /**
  68       * Send a message.
  69       *
  70       * @param mixed $recipients  Either a comma-seperated list of recipients
  71       *                           (RFC822 compliant), or an array of
  72       *                           recipients, each RFC822 valid. This may
  73       *                           contain recipients not specified in the
  74       *                           headers, for Bcc:, resending messages, etc.
  75       * @param array $headers     The headers to send with the mail, in an
  76       *                           associative array, where the array key is the
  77       *                           header name (ie, 'Subject'), and the array
  78       *                           value is the header value (ie, 'test'). The
  79       *                           header produced from those values would be
  80       *                           'Subject: test'.
  81       *                           If the '_raw' key exists, the value of this
  82       *                           key will be used as the exact text for
  83       *                           sending the message.
  84       * @param mixed $body        The full text of the message body, including
  85       *                           any Mime parts, etc. Either a string or a
  86       *                           stream resource.
  87       *
  88       * @throws Horde_Mail_Exception
  89       */
  90      abstract public function send($recipients, array $headers, $body);
  91  
  92      /**
  93       * Take an array of mail headers and return a string containing text
  94       * usable in sending a message.
  95       *
  96       * @param array $headers  The array of headers to prepare, in an
  97       *                        associative array, where the array key is the
  98       *                        header name (ie, 'Subject'), and the array value
  99       *                        is the header value (ie, 'test'). The header
 100       *                        produced from those values would be 'Subject:
 101       *                        test'.
 102       *                        If the '_raw' key exists, the value of this key
 103       *                        will be used as the exact text for sending the
 104       *                        message.
 105       *
 106       * @return mixed  Returns false if it encounters a bad address; otherwise
 107       *                returns an array containing two elements: Any From:
 108       *                address found in the headers, and the plain text version
 109       *                of the headers.
 110       * @throws Horde_Mail_Exception
 111       */
 112      public function prepareHeaders(array $headers)
 113      {
 114          $from = null;
 115          $lines = array();
 116          $raw = isset($headers['_raw'])
 117              ? $headers['_raw']
 118              : null;
 119  
 120          foreach ($headers as $key => $value) {
 121              if (strcasecmp($key, 'From') === 0) {
 122                  $parser = new Horde_Mail_Rfc822();
 123                  $addresses = $parser->parseAddressList($value, array(
 124                      'validate' => true
 125                  ));
 126                  $from = $addresses[0]->bare_address;
 127  
 128                  // Reject envelope From: addresses with spaces.
 129                  if (strstr($from, ' ')) {
 130                      return false;
 131                  }
 132  
 133                  $lines[] = $key . ': ' . $this->_normalizeEOL($value);
 134              } elseif (!$raw && (strcasecmp($key, 'Received') === 0)) {
 135                  $received = array();
 136                  if (!is_array($value)) {
 137                      $value = array($value);
 138                  }
 139  
 140                  foreach ($value as $line) {
 141                      $received[] = $key . ': ' . $this->_normalizeEOL($line);
 142                  }
 143  
 144                  // Put Received: headers at the top.  Spam detectors often
 145                  // flag messages with Received: headers after the Subject:
 146                  // as spam.
 147                  $lines = array_merge($received, $lines);
 148              } elseif (!$raw) {
 149                  // If $value is an array (i.e., a list of addresses), convert
 150                  // it to a comma-delimited string of its elements (addresses).
 151                  if (is_array($value)) {
 152                      $value = implode(', ', $value);
 153                  }
 154                  $lines[] = $key . ': ' . $this->_normalizeEOL($value);
 155              }
 156          }
 157  
 158          return array($from, $raw ? $raw : implode($this->sep, $lines));
 159      }
 160  
 161      /**
 162       * Take a set of recipients and parse them, returning an array of bare
 163       * addresses (forward paths) that can be passed to sendmail or an SMTP
 164       * server with the 'RCPT TO:' command.
 165       *
 166       * @param mixed $recipients  Either a comma-separated list of recipients
 167       *                           (RFC822 compliant), or an array of
 168       *                           recipients, each RFC822 valid.
 169       *
 170       * @return array  Forward paths (bare addresses, IDN encoded).
 171       * @throws Horde_Mail_Exception
 172       */
 173      public function parseRecipients($recipients)
 174      {
 175          // Parse recipients, leaving out all personal info. This is
 176          // for smtp recipients, etc. All relevant personal information
 177          // should already be in the headers.
 178          $rfc822 = new Horde_Mail_Rfc822();
 179          return $rfc822->parseAddressList($recipients, array(
 180              'validate' => true
 181          ))->bare_addresses_idn;
 182      }
 183  
 184      /**
 185       * Sanitize an array of mail headers by removing any additional header
 186       * strings present in a legitimate header's value.  The goal of this
 187       * filter is to prevent mail injection attacks.
 188       *
 189       * Raw headers are sent as-is.
 190       *
 191       * @param array $headers  The associative array of headers to sanitize.
 192       *
 193       * @return array  The sanitized headers.
 194       */
 195      protected function _sanitizeHeaders($headers)
 196      {
 197          foreach (array_diff(array_keys($headers), array('_raw')) as $key) {
 198              $headers[$key] = preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i', null, $headers[$key]);
 199          }
 200  
 201          return $headers;
 202      }
 203  
 204      /**
 205       * Normalizes EOLs in string data.
 206       *
 207       * @param string $data  Data.
 208       *
 209       * @return string  Normalized data.
 210       */
 211      protected function _normalizeEOL($data)
 212      {
 213          return strtr($data, array(
 214              "\r\n" => $this->sep,
 215              "\r" => $this->sep,
 216              "\n" => $this->sep
 217          ));
 218      }
 219  
 220      /**
 221       * Get the from address.
 222       *
 223       * @param string $from    From address.
 224       * @param array $headers  Headers array.
 225       *
 226       * @return string  Address object.
 227       * @throws Horde_Mail_Exception
 228       */
 229      protected function _getFrom($from, $headers)
 230      {
 231          /* Since few MTAs are going to allow this header to be forged unless
 232           * it's in the MAIL FROM: exchange, we'll use Return-Path instead of
 233           * From: if it's set. */
 234          foreach (array_keys($headers) as $hdr) {
 235              if (strcasecmp($hdr, 'Return-Path') === 0) {
 236                  $from = $headers[$hdr];
 237                  break;
 238              }
 239          }
 240  
 241          if (!strlen($from)) {
 242              throw new Horde_Mail_Exception('No from address provided.');
 243          }
 244  
 245          $from = new Horde_Mail_Rfc822_Address($from);
 246  
 247          return $from->bare_address_idn;
 248      }
 249  
 250  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1