Aleksander Machniak
2012-12-18 9945f24274d84f6fe2124bdf23bc3bd2f128a6c9
CS fixes
1 files modified
136 ■■■■■ changed files
program/lib/Roundcube/rcube_smtp.php 136 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_smtp.php
@@ -5,7 +5,7 @@
 | program/include/rcube_smtp.php                                        |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2005-2010, The Roundcube Dev Team                       |
 | Copyright (C) 2005-2012, The Roundcube Dev Team                       |
 |                                                                       |
 | Licensed under the GNU General Public License version 3 or            |
 | any later version with exceptions for skins & plugins.                |
@@ -19,9 +19,6 @@
 +-----------------------------------------------------------------------+
*/
// define headers delimiter
define('SMTP_MIME_CRLF', "\r\n");
/**
 * Class to provide SMTP functionality using PEAR Net_SMTP
 *
@@ -32,10 +29,12 @@
 */
class rcube_smtp
{
  private $conn = null;
  private $response;
  private $error;
    // define headers delimiter
    const SMTP_MIME_CRLF = "\r\n";
  /**
@@ -79,15 +78,15 @@
    $smtp_host_url = parse_url($smtp_host);
    // overwrite port
    if (isset($smtp_host_url['host']) && isset($smtp_host_url['port']))
    {
        if (isset($smtp_host_url['host']) && isset($smtp_host_url['port'])) {
      $smtp_host = $smtp_host_url['host'];
      $smtp_port = $smtp_host_url['port'];
    }
    // re-write smtp host
    if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme']))
        if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme'])) {
      $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
        }
    // remove TLS prefix and set flag for use in Net_SMTP::auth()
    if (preg_match('#^tls://#i', $smtp_host)) {
@@ -95,20 +94,24 @@
      $use_tls = true;
    }
    if (!empty($CONFIG['smtp_helo_host']))
        if (!empty($CONFIG['smtp_helo_host'])) {
      $helo_host = $CONFIG['smtp_helo_host'];
    else if (!empty($_SERVER['SERVER_NAME']))
        }
        else if (!empty($_SERVER['SERVER_NAME'])) {
      $helo_host = preg_replace('/:\d+$/', '', $_SERVER['SERVER_NAME']);
    else
        }
        else {
      $helo_host = 'localhost';
        }
    // IDNA Support
    $smtp_host = rcube_utils::idn_to_ascii($smtp_host);
    $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
    if ($rcube->config->get('smtp_debug'))
        if ($rcube->config->get('smtp_debug')) {
      $this->conn->setDebug(true, array($this, 'debug_handler'));
        }
    // register authentication methods
    if (!empty($CONFIG['smtp_auth_callbacks']) && method_exists($this->conn, 'setAuthMethod')) {
@@ -146,8 +149,7 @@
    }
    // attempt to authenticate to the SMTP server
    if ($smtp_user && $smtp_pass)
    {
        if ($smtp_user && $smtp_pass) {
      // IDNA Support
      if (strpos($smtp_user, '@')) {
        $smtp_user = rcube_utils::idn_to_ascii($smtp_user);
@@ -155,8 +157,7 @@
      $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type, $use_tls, $smtp_authz);
      if (PEAR::isError($result))
      {
            if (PEAR::isError($result)) {
        $this->error = array('label' => 'smtpautherror', 'vars' => array('code' => $this->conn->_code));
        $this->response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
        $this->reset();
@@ -167,7 +168,6 @@
    return true;
  }
  /**
   * Function for sending mail
@@ -190,12 +190,12 @@
   */
  public function send_mail($from, $recipients, &$headers, &$body, $opts=null)
  {
    if (!is_object($this->conn))
        if (!is_object($this->conn)) {
      return false;
        }
    // prepare message headers as string
    if (is_array($headers))
    {
        if (is_array($headers)) {
      if (!($headerElements = $this->_prepare_headers($headers))) {
        $this->reset();
        return false;
@@ -203,18 +203,17 @@
      list($from, $text_headers) = $headerElements;
    }
    else if (is_string($headers))
        else if (is_string($headers)) {
      $text_headers = $headers;
    else
    {
        }
        else {
      $this->reset();
      $this->response[] = "Invalid message headers";
      return false;
    }
    // exit if no from address is given
    if (!isset($from))
    {
        if (!isset($from)) {
      $this->reset();
      $this->response[] = "No From address has been provided";
      return false;
@@ -238,8 +237,7 @@
    }
    // set From: address
    if (PEAR::isError($this->conn->mailFrom($from, $from_params)))
    {
        if (PEAR::isError($this->conn->mailFrom($from, $from_params))) {
      $err = $this->conn->getResponse();
      $this->error = array('label' => 'smtpfromerror', 'vars' => array(
        'from' => $from, 'code' => $this->conn->_code, 'msg' => $err[1]));
@@ -250,16 +248,14 @@
    // prepare list of recipients
    $recipients = $this->_parse_rfc822($recipients);
    if (PEAR::isError($recipients))
    {
        if (PEAR::isError($recipients)) {
      $this->error = array('label' => 'smtprecipientserror');
      $this->reset();
      return false;
    }
    // set mail recipients
    foreach ($recipients as $recipient)
    {
        foreach ($recipients as $recipient) {
      if (PEAR::isError($this->conn->rcptTo($recipient, $recipient_params))) {
        $err = $this->conn->getResponse();
        $this->error = array('label' => 'smtptoerror', 'vars' => array(
@@ -270,12 +266,12 @@
      }
    }
    if (is_resource($body))
    {
        if (is_resource($body)) {
      // file handle
      $data = $body;
      $text_headers = preg_replace('/[\r\n]+$/', '', $text_headers);
    } else {
        }
        else {
      // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data
      // so preg_replace in SMTP_CONN->quotedata will store a reference instead of a copy. 
      // We are still forced to make another copy here for a couple ticks so we don't really 
@@ -287,13 +283,14 @@
    }
    // Send the message's headers and the body as SMTP data.
    if (PEAR::isError($result = $this->conn->data($data, $text_headers)))
    {
        if (PEAR::isError($result = $this->conn->data($data, $text_headers))) {
      $err = $this->conn->getResponse();
      if (!in_array($err[0], array(354, 250, 221)))
            if (!in_array($err[0], array(354, 250, 221))) {
        $msg = sprintf('[%d] %s', $err[0], $err[1]);
      else
            }
            else {
        $msg = $result->getMessage();
            }
      $this->error = array('label' => 'smtperror', 'vars' => array('msg' => $msg));
      $this->response[] = "Failed to send data";
@@ -305,21 +302,18 @@
    return true;
  }
  /**
   * Reset the global SMTP connection
   * @access public
   */
  public function reset()
  {
    if (is_object($this->conn))
        if (is_object($this->conn)) {
      $this->conn->rset();
  }
    }
  /**
   * Disconnect the global SMTP connection
   * @access public
   */
  public function disconnect()
  {
@@ -332,33 +326,27 @@
  /**
   * This is our own debug handler for the SMTP connection
   * @access public
   */
  public function debug_handler(&$smtp, $message)
  {
    rcube::write_log('smtp', preg_replace('/\r\n$/', '', $message));
  }
  /**
   * Get error message
   * @access public
   */
  public function get_error()
  {
    return $this->error;
  }
  /**
   * Get server response messages array
   * @access public
   */
  public function get_response()
  {
    return $this->response;
  }
  /**
   * Take an array of mail headers and return a string containing
@@ -374,38 +362,35 @@
   *               otherwise returns an array containing two
   *               elements: Any From: address found in the headers,
   *               and the plain text version of the headers.
   * @access private
   */
  private function _prepare_headers($headers)
  {
    $lines = array();
    $from = null;
    foreach ($headers as $key => $value)
    {
      if (strcasecmp($key, 'From') === 0)
      {
        foreach ($headers as $key => $value) {
            if (strcasecmp($key, 'From') === 0) {
        $addresses = $this->_parse_rfc822($value);
        if (is_array($addresses))
                if (is_array($addresses)) {
          $from = $addresses[0];
                }
        // Reject envelope From: addresses with spaces.
        if (strpos($from, ' ') !== false)
                if (strpos($from, ' ') !== false) {
          return false;
                }
        $lines[] = $key . ': ' . $value;
      }
      else if (strcasecmp($key, 'Received') === 0)
      {
            else if (strcasecmp($key, 'Received') === 0) {
        $received = array();
        if (is_array($value))
        {
          foreach ($value as $line)
                if (is_array($value)) {
                    foreach ($value as $line) {
            $received[] = $key . ': ' . $line;
        }
        else
        {
                }
                else {
          $received[] = $key . ': ' . $value;
        }
@@ -414,18 +399,18 @@
        // as spam.
        $lines = array_merge($received, $lines);
      }
      else
      {
            else {
        // If $value is an array (i.e., a list of addresses), convert
        // it to a comma-delimited string of its elements (addresses).
        if (is_array($value))
                if (is_array($value)) {
          $value = implode(', ', $value);
                }
        $lines[] = $key . ': ' . $value;
      }
    }
    return array($from, join(SMTP_MIME_CRLF, $lines) . SMTP_MIME_CRLF);
        return array($from, join(self::SMTP_MIME_CRLF, $lines) . self::SMTP_MIME_CRLF);
  }
  /**
@@ -438,33 +423,30 @@
   *              each RFC822 valid.
   *
   * @return array An array of forward paths (bare addresses).
   * @access private
   */
  private function _parse_rfc822($recipients)
  {
    // if we're passed an array, assume addresses are valid and implode them before parsing.
    if (is_array($recipients))
        if (is_array($recipients)) {
      $recipients = implode(', ', $recipients);
        }
    $addresses = array();
    $recipients = rcube_utils::explode_quoted_string(',', $recipients);
    reset($recipients);
    while (list($k, $recipient) = each($recipients))
    {
        while (list($k, $recipient) = each($recipients)) {
      $a = rcube_utils::explode_quoted_string(' ', $recipient);
      while (list($k2, $word) = each($a))
      {
        if (strpos($word, "@") > 0 && $word[strlen($word)-1] != '"')
        {
            while (list($k2, $word) = each($a)) {
                if (strpos($word, "@") > 0 && $word[strlen($word)-1] != '"') {
          $word = preg_replace('/^<|>$/', '', trim($word));
          if (in_array($word, $addresses)===false)
                    if (in_array($word, $addresses) === false) {
            array_push($addresses, $word);
                    }
        }
      }
    }
    return $addresses;
  }
}