Changeset 19942 for branches/version-2_5-dev/data
- Timestamp:
- 2011/01/17 14:46:37 (13 years ago)
- Location:
- branches/version-2_5-dev/data/module
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/version-2_5-dev/data/module/Mail.php
r16523 r19942 1 1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 2.02 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available at through the world-wide-web at | 11 // | http://www.php.net/license/2_02.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Author: Chuck Hagenbuch <chuck@horde.org> | 17 // +----------------------------------------------------------------------+ 18 // 19 // $Id: Mail.php,v 1.17 2006/09/15 03:41:18 jon Exp $ 20 21 require_once dirname(__FILE__) . "/PEAR.php"; 2 /** 3 * PEAR's Mail:: interface. 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: 8 * 9 * Copyright (c) 2002-2007, Richard Heyes 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * o Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * o Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * o The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @category Mail 38 * @package Mail 39 * @author Chuck Hagenbuch <chuck@horde.org> 40 * @copyright 1997-2010 Chuck Hagenbuch 41 * @license http://opensource.org/licenses/bsd-license.php New BSD License 42 * @version CVS: $Id: Mail.php 294747 2010-02-08 08:18:33Z clockwerx $ 43 * @link http://pear.php.net/package/Mail/ 44 */ 45 46 require_once 'PEAR.php'; 22 47 23 48 /** … … 27 52 * 28 53 * @access public 29 * @version $Revision: 1.17 $54 * @version $Revision: 294747 $ 30 55 * @package Mail 31 56 */ … … 50 75 { 51 76 $driver = strtolower($driver); 52 $include_dir = realpath(dirname( __FILE__)); 53 include_once $include_dir ."/Mail/" . $driver . ".php"; 77 @include_once 'Mail/' . $driver . '.php'; 54 78 $class = 'Mail_' . $driver; 55 79 if (class_exists($class)) { … … 84 108 * containing a descriptive error message on 85 109 * failure. 110 * 86 111 * @access public 87 112 * @deprecated use Mail_mail::send instead … … 89 114 function send($recipients, $headers, $body) 90 115 { 91 $this->_sanitizeHeaders($headers); 116 if (!is_array($headers)) { 117 return PEAR::raiseError('$headers must be an array'); 118 } 119 120 $result = $this->_sanitizeHeaders($headers); 121 if (is_a($result, 'PEAR_Error')) { 122 return $result; 123 } 92 124 93 125 // if we're passed an array of recipients, implode it. … … 105 137 106 138 // flatten the headers out. 107 list(, $text_headers) = Mail::prepareHeaders($headers);139 list(, $text_headers) = Mail::prepareHeaders($headers); 108 140 109 141 return mail($recipients, $subject, $body, $text_headers); 110 111 142 } 112 143 … … 152 183 foreach ($headers as $key => $value) { 153 184 if (strcasecmp($key, 'From') === 0) { 154 $include_dir = realpath(dirname( __FILE__)); 155 include_once $include_dir ."/Mail/RFC822.php"; 156 $parser = &new Mail_RFC822(); 185 include_once 'Mail/RFC822.php'; 186 $parser = new Mail_RFC822(); 157 187 $addresses = $parser->parseAddressList($value, 'localhost', false); 158 if ( PEAR::isError($addresses)) {188 if (is_a($addresses, 'PEAR_Error')) { 159 189 return $addresses; 160 190 } … … 210 240 function parseRecipients($recipients) 211 241 { 212 include_once dirname(__FILE__) . "/Mail/RFC822.php";242 include_once 'Mail/RFC822.php'; 213 243 214 244 // if we're passed an array, assume addresses are valid and … … 224 254 225 255 // If parseAddressList() returned a PEAR_Error object, just return it. 226 if ( PEAR::isError($addresses)) {256 if (is_a($addresses, 'PEAR_Error')) { 227 257 return $addresses; 228 258 } -
branches/version-2_5-dev/data/module/Mail/RFC822.php
r16302 r19942 1 1 <?php 2 // +-----------------------------------------------------------------------+ 3 // | Copyright (c) 2001-2002, Richard Heyes | 4 // | All rights reserved. | 5 // | | 6 // | Redistribution and use in source and binary forms, with or without | 7 // | modification, are permitted provided that the following conditions | 8 // | are met: | 9 // | | 10 // | o Redistributions of source code must retain the above copyright | 11 // | notice, this list of conditions and the following disclaimer. | 12 // | o Redistributions in binary form must reproduce the above copyright | 13 // | notice, this list of conditions and the following disclaimer in the | 14 // | documentation and/or other materials provided with the distribution.| 15 // | o The names of the authors may not be used to endorse or promote | 16 // | products derived from this software without specific prior written | 17 // | permission. | 18 // | | 19 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 20 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 21 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 22 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 23 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 24 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 25 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 26 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 27 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 28 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 29 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 30 // | | 31 // +-----------------------------------------------------------------------+ 32 // | Authors: Richard Heyes <richard@phpguru.org> | 33 // | Chuck Hagenbuch <chuck@horde.org> | 34 // +-----------------------------------------------------------------------+ 2 /** 3 * RFC 822 Email address list validation Utility 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: 8 * 9 * Copyright (c) 2001-2010, Richard Heyes 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * o Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * o Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * o The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @category Mail 38 * @package Mail 39 * @author Richard Heyes <richard@phpguru.org> 40 * @author Chuck Hagenbuch <chuck@horde.org 41 * @copyright 2001-2010 Richard Heyes 42 * @license http://opensource.org/licenses/bsd-license.php New BSD License 43 * @version CVS: $Id: RFC822.php 294749 2010-02-08 08:22:25Z clockwerx $ 44 * @link http://pear.php.net/package/Mail/ 45 */ 35 46 36 47 /** … … 53 64 * @author Richard Heyes <richard@phpguru.org> 54 65 * @author Chuck Hagenbuch <chuck@horde.org> 55 * @version $Revision: 1.23$66 * @version $Revision: 294749 $ 56 67 * @license BSD 57 68 * @package Mail … … 185 196 186 197 if ($this->address === false || isset($this->error)) { 187 require_once dirname(__FILE__) . '/../PEAR.php';198 require_once 'PEAR.php'; 188 199 return PEAR::raiseError($this->error); 189 200 } … … 195 206 196 207 if ($valid === false || isset($this->error)) { 197 require_once dirname(__FILE__) . '/../PEAR.php';208 require_once 'PEAR.php'; 198 209 return PEAR::raiseError($this->error); 199 210 } … … 343 354 344 355 /** 345 * Checks if a string has an unclosed quotes or not. 346 * 347 * @access private 348 * @param string $string The string to check. 349 * @return boolean True if there are unclosed quotes inside the string, false otherwise. 356 * Checks if a string has unclosed quotes or not. 357 * 358 * @access private 359 * @param string $string The string to check. 360 * @return boolean True if there are unclosed quotes inside the string, 361 * false otherwise. 350 362 */ 351 363 function _hasUnclosedQuotes($string) 352 364 { 353 $string = explode('"', $string); 354 $string_cnt = count($string); 355 356 for ($i = 0; $i < (count($string) - 1); $i++) 357 if (substr($string[$i], -1) == '\\') 358 $string_cnt--; 359 360 return ($string_cnt % 2 === 0); 365 $string = trim($string); 366 $iMax = strlen($string); 367 $in_quote = false; 368 $i = $slashes = 0; 369 370 for (; $i < $iMax; ++$i) { 371 switch ($string[$i]) { 372 case '\\': 373 ++$slashes; 374 break; 375 376 case '"': 377 if ($slashes % 2 == 0) { 378 $in_quote = !$in_quote; 379 } 380 // Fall through to default action below. 381 382 default: 383 $slashes = 0; 384 break; 385 } 386 } 387 388 return $in_quote; 361 389 } 362 390 … … 619 647 $comments[] = $comment; 620 648 621 // + 1 is for the trailing )622 $_mailbox = substr($_mailbox, strpos($_mailbox, $comment)+strlen($comment)+1);649 // +2 is for the brackets 650 $_mailbox = substr($_mailbox, strpos($_mailbox, '('.$comment)+strlen($comment)+2); 623 651 } else { 624 652 break; -
branches/version-2_5-dev/data/module/Mail/mail.php
r16503 r19942 1 1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 2.02 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available at through the world-wide-web at | 11 // | http://www.php.net/license/2_02.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Author: Chuck Hagenbuch <chuck@horde.org> | 17 // +----------------------------------------------------------------------+ 18 // 19 // $Id$ 2 /** 3 * internal PHP-mail() implementation of the PEAR Mail:: interface. 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: 8 * 9 * Copyright (c) 2010 Chuck Hagenbuch 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * o Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * o Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * o The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @category Mail 38 * @package Mail 39 * @author Chuck Hagenbuch <chuck@horde.org> 40 * @copyright 2010 Chuck Hagenbuch 41 * @license http://opensource.org/licenses/bsd-license.php New BSD License 42 * @version CVS: $Id$ 43 * @link http://pear.php.net/package/Mail/ 44 */ 20 45 21 46 /** … … 42 67 function Mail_mail($params = null) 43 68 { 44 / *The other mail implementations accept parameters as arrays.45 *In the interest of being consistent, explode an array into46 * a string of parameter arguments. */69 // The other mail implementations accept parameters as arrays. 70 // In the interest of being consistent, explode an array into 71 // a string of parameter arguments. 47 72 if (is_array($params)) { 48 73 $this->_params = join(' ', $params); … … 62 87 } 63 88 64 89 /** 65 90 * Implements Mail_mail::send() function using php's built-in mail() 66 91 * command. … … 90 115 function send($recipients, $headers, $body) 91 116 { 92 $this->_sanitizeHeaders($headers); 117 if (!is_array($headers)) { 118 return PEAR::raiseError('$headers must be an array'); 119 } 120 121 $result = $this->_sanitizeHeaders($headers); 122 if (is_a($result, 'PEAR_Error')) { 123 return $result; 124 } 93 125 94 126 // If we're passed an array of recipients, implode it. … … 105 137 } 106 138 107 /* 108 * Also remove the To: header. The mail() function will add its own 109 * To: header based on the contents of $recipients. 110 */ 139 // Also remove the To: header. The mail() function will add its own 140 // To: header based on the contents of $recipients. 111 141 unset($headers['To']); 112 142 113 143 // Flatten the headers out. 114 144 $headerElements = $this->prepareHeaders($headers); 115 if ( PEAR::isError($headerElements)) {145 if (is_a($headerElements, 'PEAR_Error')) { 116 146 return $headerElements; 117 147 } 118 148 list(, $text_headers) = $headerElements; 119 149 120 /* 121 * We only use mail()'s optional fifth parameter if the additional 122 * parameters have been provided and we're not running in safe mode. 123 */ 150 // We only use mail()'s optional fifth parameter if the additional 151 // parameters have been provided and we're not running in safe mode. 124 152 if (empty($this->_params) || ini_get('safe_mode')) { 125 153 $result = mail($recipients, $subject, $body, $text_headers); … … 129 157 } 130 158 131 /* 132 * If the mail() function returned failure, we need to create a 133 * PEAR_Error object and return it instead of the boolean result. 134 */ 159 // If the mail() function returned failure, we need to create a 160 // PEAR_Error object and return it instead of the boolean result. 135 161 if ($result === false) { 136 162 $result = PEAR::raiseError('mail() returned failure'); -
branches/version-2_5-dev/data/module/Mail/null.php
r16503 r19942 1 1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 2.02 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available at through the world-wide-web at | 11 // | http://www.php.net/license/2_02.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Author: Phil Kernick <philk@rotfl.com.au> | 17 // +----------------------------------------------------------------------+ 18 // 19 // $Id$ 20 // 2 /** 3 * Null implementation of the PEAR Mail interface 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: 8 * 9 * Copyright (c) 2010 Phil Kernick 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * o Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * o Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * o The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @category Mail 38 * @package Mail 39 * @author Phil Kernick <philk@rotfl.com.au> 40 * @copyright 2010 Phil Kernick 41 * @license http://opensource.org/licenses/bsd-license.php New BSD License 42 * @version CVS: $Id$ 43 * @link http://pear.php.net/package/Mail/ 44 */ 21 45 22 46 /** -
branches/version-2_5-dev/data/module/Mail/sendmail.php
r16503 r19942 25 25 class Mail_sendmail extends Mail { 26 26 27 27 /** 28 28 * The location of the sendmail or sendmail wrapper binary on the 29 29 * filesystem. … … 32 32 var $sendmail_path = '/usr/sbin/sendmail'; 33 33 34 34 /** 35 35 * Any extra command-line parameters to pass to the sendmail or 36 36 * sendmail wrapper binary. … … 39 39 var $sendmail_args = '-i'; 40 40 41 41 /** 42 42 * Constructor. 43 43 * … … 78 78 } 79 79 80 80 /** 81 81 * Implements Mail::send() function using the sendmail 82 82 * command-line binary. … … 105 105 function send($recipients, $headers, $body) 106 106 { 107 if (!is_array($headers)) { 108 return PEAR::raiseError('$headers must be an array'); 109 } 110 111 $result = $this->_sanitizeHeaders($headers); 112 if (is_a($result, 'PEAR_Error')) { 113 return $result; 114 } 115 107 116 $recipients = $this->parseRecipients($recipients); 108 if ( PEAR::isError($recipients)) {117 if (is_a($recipients, 'PEAR_Error')) { 109 118 return $recipients; 110 119 } 111 $recipients = escapeShellCmd(implode('', $recipients));120 $recipients = implode(' ', array_map('escapeshellarg', $recipients)); 112 121 113 $this->_sanitizeHeaders($headers);114 122 $headerElements = $this->prepareHeaders($headers); 115 if ( PEAR::isError($headerElements)) {123 if (is_a($headerElements, 'PEAR_Error')) { 116 124 return $headerElements; 117 125 } 118 126 list($from, $text_headers) = $headerElements; 127 128 /* Since few MTAs are going to allow this header to be forged 129 * unless it's in the MAIL FROM: exchange, we'll use 130 * Return-Path instead of From: if it's set. */ 131 if (!empty($headers['Return-Path'])) { 132 $from = $headers['Return-Path']; 133 } 119 134 120 135 if (!isset($from)) { … … 127 142 } 128 143 129 $from = escapeShellCmd($from); 144 $from = escapeshellarg($from); // Security bug #16200 145 130 146 $mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w'); 131 147 if (!$mail) { -
branches/version-2_5-dev/data/module/Mail/smtp.php
r18253 r19942 1 1 <?php 2 // 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 The PHP Group | 7 // +----------------------------------------------------------------------+ 8 // | This source file is subject to version 2.02 of the PHP license, | 9 // | that is bundled with this package in the file LICENSE, and is | 10 // | available at through the world-wide-web at | 11 // | http://www.php.net/license/2_02.txt. | 12 // | If you did not receive a copy of the PHP license and are unable to | 13 // | obtain it through the world-wide-web, please send a note to | 14 // | license@php.net so we can mail you a copy immediately. | 15 // +----------------------------------------------------------------------+ 16 // | Authors: Chuck Hagenbuch <chuck@horde.org> | 17 // | Jon Parise <jon@php.net> | 18 // +----------------------------------------------------------------------+ 2 /** 3 * SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class. 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: 8 * 9 * Copyright (c) 2010, Chuck Hagenbuch 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 16 * o Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * o Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * o The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @category HTTP 38 * @package HTTP_Request 39 * @author Jon Parise <jon@php.net> 40 * @author Chuck Hagenbuch <chuck@horde.org> 41 * @copyright 2010 Chuck Hagenbuch 42 * @license http://opensource.org/licenses/bsd-license.php New BSD License 43 * @version CVS: $Id: smtp.php 294747 2010-02-08 08:18:33Z clockwerx $ 44 * @link http://pear.php.net/package/Mail/ 45 */ 19 46 20 47 /** Error: Failed to create a Net_SMTP object */ … … 43 70 * @access public 44 71 * @package Mail 45 * @version $Revision: 1.28$72 * @version $Revision: 294747 $ 46 73 */ 47 74 class Mail_smtp extends Mail { … … 56 83 57 84 /** 85 * The list of service extension parameters to pass to the Net_SMTP 86 * mailFrom() command. 87 * @var array 88 */ 89 var $_extparams = array(); 90 91 /** 58 92 * The SMTP host to connect to. 59 93 * @var string … … 108 142 109 143 /** 110 * Whether to use VERP or not. If not a boolean, the string value111 * will be used as the VERP separators.112 *113 * @var mixed boolean or string114 */115 var $verp = false;116 117 /**118 144 * Turn on Net_SMTP debugging? 119 145 * … … 129 155 */ 130 156 var $persist = false; 157 158 /** 159 * Use SMTP command pipelining (specified in RFC 2920) if the SMTP server 160 * supports it. This speeds up delivery over high-latency connections. By 161 * default, use the default value supplied by Net_SMTP. 162 * @var bool 163 */ 164 var $pipelining; 131 165 132 166 /** … … 143 177 * timeout The SMTP connection timeout. Defaults to none. 144 178 * verp Whether to use VERP or not. Defaults to false. 179 * DEPRECATED as of 1.2.0 (use setMailParams()). 145 180 * debug Activate SMTP debug mode? Defaults to false. 146 181 * persist Should the SMTP connection persist? 182 * pipelining Use SMTP command pipelining 147 183 * 148 184 * If a parameter is present in the $params array, it replaces the … … 162 198 if (isset($params['localhost'])) $this->localhost = $params['localhost']; 163 199 if (isset($params['timeout'])) $this->timeout = $params['timeout']; 164 if (isset($params['verp'])) $this->verp = $params['verp']; 165 if (isset($params['debug'])) $this->debug = (boolean)$params['debug']; 166 if (isset($params['persist'])) $this->persist = (boolean)$params['persist']; 200 if (isset($params['debug'])) $this->debug = (bool)$params['debug']; 201 if (isset($params['persist'])) $this->persist = (bool)$params['persist']; 202 if (isset($params['pipelining'])) $this->pipelining = (bool)$params['pipelining']; 203 204 // Deprecated options 205 if (isset($params['verp'])) { 206 $this->addServiceExtensionParameter('XVERP', is_bool($params['verp']) ? null : $params['verp']); 207 } 167 208 168 209 register_shutdown_function(array(&$this, '_Mail_smtp')); … … 195 236 * 196 237 * @param string $body The full text of the message body, including any 197 * M imeparts, etc.238 * MIME parts, etc. 198 239 * 199 240 * @return mixed Returns true on success, or a PEAR_Error … … 204 245 function send($recipients, $headers, $body) 205 246 { 206 $include_dir = realpath(dirname( __FILE__));207 include_once $include_dir . "/../Net/SMTP.php";208 209 247 /* If we don't already have an SMTP object, create one. */ 210 if (is_object($this->_smtp) === false) { 211 $this->_smtp =& new Net_SMTP($this->host, $this->port, 212 $this->localhost); 213 214 /* If we still don't have an SMTP object at this point, fail. */ 215 if (is_object($this->_smtp) === false) { 216 return PEAR::raiseError('Failed to create a Net_SMTP object', 217 PEAR_MAIL_SMTP_ERROR_CREATE); 218 } 219 220 /* Configure the SMTP connection. */ 221 if ($this->debug) { 222 $this->_smtp->setDebug(true); 223 } 224 225 /* Attempt to connect to the configured SMTP server. */ 226 if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) { 227 $error = $this->_error('Failed to connect to ' . 228 $this->host . ':' . $this->port, 229 $res); 230 return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_CONNECT); 231 } 232 233 /* Attempt to authenticate if authentication has been enabled. */ 234 if ($this->auth) { 235 $method = is_string($this->auth) ? $this->auth : ''; 236 237 if (PEAR::isError($res = $this->_smtp->auth($this->username, 238 $this->password, 239 $method))) { 240 $error = $this->_error("$method authentication failure", 241 $res); 242 $this->_smtp->rset(); 243 return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_AUTH); 244 } 245 } 248 $result = &$this->getSMTPObject(); 249 if (PEAR::isError($result)) { 250 return $result; 251 } 252 253 if (!is_array($headers)) { 254 return PEAR::raiseError('$headers must be an array'); 246 255 } 247 256 248 257 $this->_sanitizeHeaders($headers); 258 249 259 $headerElements = $this->prepareHeaders($headers); 250 if ( PEAR::isError($headerElements)) {260 if (is_a($headerElements, 'PEAR_Error')) { 251 261 $this->_smtp->rset(); 252 262 return $headerElements; … … 267 277 } 268 278 269 $args['verp'] = $this->verp; 270 if (PEAR::isError($res = $this->_smtp->mailFrom($from, $args))) { 279 $params = null; 280 if (!empty($this->_extparams)) { 281 foreach ($this->_extparams as $key => $val) { 282 $params .= ' ' . $key . (is_null($val) ? '' : '=' . $val); 283 } 284 } 285 if (PEAR::isError($res = $this->_smtp->mailFrom($from, ltrim($params)))) { 271 286 $error = $this->_error("Failed to set sender: $from", $res); 272 287 $this->_smtp->rset(); … … 275 290 276 291 $recipients = $this->parseRecipients($recipients); 277 if ( PEAR::isError($recipients)) {292 if (is_a($recipients, 'PEAR_Error')) { 278 293 $this->_smtp->rset(); 279 294 return $recipients; … … 281 296 282 297 foreach ($recipients as $recipient) { 283 if (PEAR::isError($res = $this->_smtp->rcptTo($recipient))) {284 $error = $this->_error("Failed to add recipient: $recipient",285 298 $res = $this->_smtp->rcptTo($recipient); 299 if (is_a($res, 'PEAR_Error')) { 300 $error = $this->_error("Failed to add recipient: $recipient", $res); 286 301 $this->_smtp->rset(); 287 302 return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_RECIPIENT); … … 290 305 291 306 /* Send the message's headers and the body as SMTP data. */ 292 if (PEAR::isError($res = $this->_smtp->data($textHeaders . "\r\n\r\n" . $body))) { 307 $res = $this->_smtp->data($textHeaders . "\r\n\r\n" . $body); 308 list(,$args) = $this->_smtp->getResponse(); 309 310 if (preg_match("/Ok: queued as (.*)/", $args, $queued)) { 311 $this->queued_as = $queued[1]; 312 } 313 314 /* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to. 315 * ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */ 316 $this->greeting = $this->_smtp->getGreeting(); 317 318 if (is_a($res, 'PEAR_Error')) { 293 319 $error = $this->_error('Failed to send data', $res); 294 320 $this->_smtp->rset(); … … 305 331 306 332 /** 333 * Connect to the SMTP server by instantiating a Net_SMTP object. 334 * 335 * @return mixed Returns a reference to the Net_SMTP object on success, or 336 * a PEAR_Error containing a descriptive error message on 337 * failure. 338 * 339 * @since 1.2.0 340 * @access public 341 */ 342 function &getSMTPObject() 343 { 344 if (is_object($this->_smtp) !== false) { 345 return $this->_smtp; 346 } 347 348 include_once 'Net/SMTP.php'; 349 $this->_smtp = &new Net_SMTP($this->host, 350 $this->port, 351 $this->localhost); 352 353 /* If we still don't have an SMTP object at this point, fail. */ 354 if (is_object($this->_smtp) === false) { 355 return PEAR::raiseError('Failed to create a Net_SMTP object', 356 PEAR_MAIL_SMTP_ERROR_CREATE); 357 } 358 359 /* Configure the SMTP connection. */ 360 if ($this->debug) { 361 $this->_smtp->setDebug(true); 362 } 363 364 /* Attempt to connect to the configured SMTP server. */ 365 if (PEAR::isError($res = $this->_smtp->connect($this->timeout))) { 366 $error = $this->_error('Failed to connect to ' . 367 $this->host . ':' . $this->port, 368 $res); 369 return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_CONNECT); 370 } 371 372 /* Attempt to authenticate if authentication has been enabled. */ 373 if ($this->auth) { 374 $method = is_string($this->auth) ? $this->auth : ''; 375 376 if (PEAR::isError($res = $this->_smtp->auth($this->username, 377 $this->password, 378 $method))) { 379 $error = $this->_error("$method authentication failure", 380 $res); 381 $this->_smtp->rset(); 382 return PEAR::raiseError($error, PEAR_MAIL_SMTP_ERROR_AUTH); 383 } 384 } 385 386 return $this->_smtp; 387 } 388 389 /** 390 * Add parameter associated with a SMTP service extension. 391 * 392 * @param string Extension keyword. 393 * @param string Any value the keyword needs. 394 * 395 * @since 1.2.0 396 * @access public 397 */ 398 function addServiceExtensionParameter($keyword, $value = null) 399 { 400 $this->_extparams[$keyword] = $value; 401 } 402 403 /** 307 404 * Disconnect and destroy the current SMTP connection. 308 405 * … … 340 437 341 438 /* Build our standardized error string. */ 342 $msg = $text; 343 $msg .= ' [SMTP: ' . $error->getMessage(); 344 $msg .= " (code: $code, response: $response)]"; 345 346 return $msg; 439 return $text 440 . ' [SMTP: ' . $error->getMessage() 441 . " (code: $code, response: $response)]"; 347 442 } 348 443 -
branches/version-2_5-dev/data/module/Net/SMTP.php
r16300 r19942 19 19 // +----------------------------------------------------------------------+ 20 20 // 21 // $Id: SMTP.php,v 1.58 2007/03/28 04:53:34 chagenbu Exp $ 22 23 $include_dir = realpath(dirname( __FILE__)); 24 require_once $include_dir . "/../PEAR.php"; 25 require_once $include_dir . "/../Net/Socket.php"; 21 // $Id: SMTP.php 304535 2010-10-20 06:48:06Z jon $ 22 23 require_once 'PEAR.php'; 24 require_once 'Net/Socket.php'; 26 25 27 26 /** … … 67 66 68 67 /** 68 * Use SMTP command pipelining (specified in RFC 2920) if the SMTP 69 * server supports it. 70 * 71 * When pipeling is enabled, rcptTo(), mailFrom(), sendFrom(), 72 * somlFrom() and samlFrom() do not wait for a response from the 73 * SMTP server but return immediately. 74 * 75 * @var bool 76 * @access public 77 */ 78 var $pipelining = false; 79 80 /** 81 * Number of pipelined commands. 82 * @var int 83 * @access private 84 */ 85 var $_pipelined_commands = 0; 86 87 /** 69 88 * Should debugging output be enabled? 70 89 * @var boolean … … 74 93 75 94 /** 95 * Debug output handler. 96 * @var callback 97 * @access private 98 */ 99 var $_debug_handler = null; 100 101 /** 76 102 * The socket resource being used to connect to the SMTP server. 77 103 * @var resource … … 93 119 */ 94 120 var $_arguments = array(); 121 122 /** 123 * Stores the SMTP server's greeting string. 124 * @var string 125 * @access private 126 */ 127 var $_greeting = null; 95 128 96 129 /** … … 115 148 * @param integer $port The port to connect to. 116 149 * @param string $localhost The value to give when sending EHLO or HELO. 150 * @param boolean $pipeling Use SMTP command pipelining 117 151 * 118 152 * @access public 119 153 * @since 1.0 120 154 */ 121 function Net_SMTP($host = null, $port = null, $localhost = null) 122 { 123 if (isset($host)) $this->host = $host; 124 if (isset($port)) $this->port = $port; 125 if (isset($localhost)) $this->localhost = $localhost; 155 function Net_SMTP($host = null, $port = null, $localhost = null, $pipelining = false) 156 { 157 if (isset($host)) { 158 $this->host = $host; 159 } 160 if (isset($port)) { 161 $this->port = $port; 162 } 163 if (isset($localhost)) { 164 $this->localhost = $localhost; 165 } 166 $this->pipelining = $pipelining; 126 167 127 168 $this->_socket = new Net_Socket(); 128 169 129 /* 130 * Include the Auth_SASL package. If the package is not available, 131 * we disable the authentication methods that depend upon it. 132 */ 133 if ((@include_once '../Auth/SASL.php') === false) { 170 /* Include the Auth_SASL package. If the package is not 171 * available, we disable the authentication methods that 172 * depend upon it. */ 173 if ((@include_once 'Auth/SASL.php') === false) { 134 174 $pos = array_search('DIGEST-MD5', $this->auth_methods); 135 175 unset($this->auth_methods[$pos]); … … 147 187 * @since 1.1.0 148 188 */ 149 function setDebug($debug )189 function setDebug($debug, $handler = null) 150 190 { 151 191 $this->_debug = $debug; 192 $this->_debug_handler = $handler; 193 } 194 195 /** 196 * Write the given debug text to the current debug output handler. 197 * 198 * @param string $message Debug mesage text. 199 * 200 * @access private 201 * @since 1.3.3 202 */ 203 function _debug($message) 204 { 205 if ($this->_debug) { 206 if ($this->_debug_handler) { 207 call_user_func_array($this->_debug_handler, 208 array(&$this, $message)); 209 } else { 210 echo "DEBUG: $message\n"; 211 } 212 } 152 213 } 153 214 … … 164 225 function _send($data) 165 226 { 166 if ($this->_debug) { 167 echo "DEBUG: Send: $data\n"; 168 } 169 170 if (PEAR::isError($error = $this->_socket->write($data))) { 171 return PEAR::raiseError('Failed to write to socket: ' . 172 $error->getMessage()); 227 $this->_debug("Send: $data"); 228 229 $error = $this->_socket->write($data); 230 if ($error === false || PEAR::isError($error)) { 231 $msg = ($error) ? $error->getMessage() : "unknown error"; 232 return PEAR::raiseError("Failed to write to socket: $msg"); 173 233 } 174 234 … … 213 273 * may be specified as an array of integer 214 274 * values or as a single integer value. 275 * @param bool $later Do not parse the response now, but wait 276 * until the last command in the pipelined 277 * command group 215 278 * 216 279 * @return mixed True if the server returned a valid response code or … … 222 285 * @see getResponse 223 286 */ 224 function _parseResponse($valid )287 function _parseResponse($valid, $later = false) 225 288 { 226 289 $this->_code = -1; 227 290 $this->_arguments = array(); 228 291 229 while ($line = $this->_socket->readLine()) { 230 if ($this->_debug) { 231 echo "DEBUG: Recv: $line\n"; 232 } 233 234 /* If we receive an empty line, the connection has been closed. */ 235 if (empty($line)) { 236 $this->disconnect(); 237 return PEAR::raiseError('Connection was unexpectedly closed'); 238 } 239 240 /* Read the code and store the rest in the arguments array. */ 241 $code = substr($line, 0, 3); 242 $this->_arguments[] = trim(substr($line, 4)); 243 244 /* Check the syntax of the response code. */ 245 if (is_numeric($code)) { 246 $this->_code = (int)$code; 247 } else { 248 $this->_code = -1; 249 break; 250 } 251 252 /* If this is not a multiline response, we're done. */ 253 if (substr($line, 3, 1) != '-') { 254 break; 255 } 256 } 257 258 /* Compare the server's response code with the valid code. */ 292 if ($later) { 293 $this->_pipelined_commands++; 294 return true; 295 } 296 297 for ($i = 0; $i <= $this->_pipelined_commands; $i++) { 298 while ($line = $this->_socket->readLine()) { 299 $this->_debug("Recv: $line"); 300 301 /* If we receive an empty line, the connection has been closed. */ 302 if (empty($line)) { 303 $this->disconnect(); 304 return PEAR::raiseError('Connection was unexpectedly closed'); 305 } 306 307 /* Read the code and store the rest in the arguments array. */ 308 $code = substr($line, 0, 3); 309 $this->_arguments[] = trim(substr($line, 4)); 310 311 /* Check the syntax of the response code. */ 312 if (is_numeric($code)) { 313 $this->_code = (int)$code; 314 } else { 315 $this->_code = -1; 316 break; 317 } 318 319 /* If this is not a multiline response, we're done. */ 320 if (substr($line, 3, 1) != '-') { 321 break; 322 } 323 } 324 } 325 326 $this->_pipelined_commands = 0; 327 328 /* Compare the server's response code with the valid code/codes. */ 259 329 if (is_int($valid) && ($this->_code === $valid)) { 260 330 return true; 261 } 262 263 /* If we were given an array of valid response codes, check each one. */ 264 if (is_array($valid)) { 265 foreach ($valid as $valid_code) { 266 if ($this->_code === $valid_code) { 267 return true; 268 } 269 } 331 } elseif (is_array($valid) && in_array($this->_code, $valid, true)) { 332 return true; 270 333 } 271 334 … … 287 350 { 288 351 return array($this->_code, join("\n", $this->_arguments)); 352 } 353 354 /** 355 * Return the SMTP server's greeting string. 356 * 357 * @return string A string containing the greeting string, or null if a 358 * greeting has not been received. 359 * 360 * @access public 361 * @since 1.3.3 362 */ 363 function getGreeting() 364 { 365 return $this->_greeting; 289 366 } 290 367 … … 304 381 function connect($timeout = null, $persistent = false) 305 382 { 383 $this->_greeting = null; 306 384 $result = $this->_socket->connect($this->host, $this->port, 307 385 $persistent, $timeout); … … 314 392 return $error; 315 393 } 394 395 /* Extract and store a copy of the server's greeting string. */ 396 list(, $this->_greeting) = $this->getResponse(); 397 316 398 if (PEAR::isError($error = $this->_negotiate())) { 317 399 return $error; … … 385 467 } 386 468 469 if (!isset($this->_esmtp['PIPELINING'])) { 470 $this->pipelining = false; 471 } 472 387 473 return true; 388 474 } … … 418 504 * @param string The requested authentication method. If none is 419 505 * specified, the best supported method will be used. 506 * @param bool Flag indicating whether or not TLS should be attempted. 507 * @param string An optional authorization identifier. If specified, this 508 * identifier will be used as the authorization proxy. 420 509 * 421 510 * @return mixed Returns a PEAR_Error with an error message on any … … 424 513 * @since 1.0 425 514 */ 426 function auth($uid, $pwd , $method = '') 427 { 515 function auth($uid, $pwd , $method = '', $tls = true, $authz = '') 516 { 517 /* We can only attempt a TLS connection if one has been requested, 518 * we're running PHP 5.1.0 or later, have access to the OpenSSL 519 * extension, are connected to an SMTP server which supports the 520 * STARTTLS extension, and aren't already connected over a secure 521 * (SSL) socket connection. */ 522 if ($tls && version_compare(PHP_VERSION, '5.1.0', '>=') && 523 extension_loaded('openssl') && isset($this->_esmtp['STARTTLS']) && 524 strncasecmp($this->host, 'ssl://', 6) !== 0) { 525 /* Start the TLS connection attempt. */ 526 if (PEAR::isError($result = $this->_put('STARTTLS'))) { 527 return $result; 528 } 529 if (PEAR::isError($result = $this->_parseResponse(220))) { 530 return $result; 531 } 532 if (PEAR::isError($result = $this->_socket->enableCrypto(true, STREAM_CRYPTO_METHOD_TLS_CLIENT))) { 533 return $result; 534 } elseif ($result !== true) { 535 return PEAR::raiseError('STARTTLS failed'); 536 } 537 538 /* Send EHLO again to recieve the AUTH string from the 539 * SMTP server. */ 540 $this->_negotiate(); 541 } 542 428 543 if (empty($this->_esmtp['AUTH'])) { 429 if (version_compare(PHP_VERSION, '5.1.0', '>=')) { 430 if (!isset($this->_esmtp['STARTTLS'])) { 431 return PEAR::raiseError('SMTP server does not support authentication'); 432 } 433 if (PEAR::isError($result = $this->_put('STARTTLS'))) { 434 return $result; 435 } 436 if (PEAR::isError($result = $this->_parseResponse(220))) { 437 return $result; 438 } 439 if (PEAR::isError($result = $this->_socket->enableCrypto(true, STREAM_CRYPTO_METHOD_TLS_CLIENT))) { 440 return $result; 441 } elseif ($result !== true) { 442 return PEAR::raiseError('STARTTLS failed'); 443 } 444 445 /* Send EHLO again to recieve the AUTH string from the 446 * SMTP server. */ 447 $this->_negotiate(); 448 if (empty($this->_esmtp['AUTH'])) { 449 return PEAR::raiseError('SMTP server does not support authentication'); 450 } 451 } else { 452 return PEAR::raiseError('SMTP server does not support authentication'); 453 } 544 return PEAR::raiseError('SMTP server does not support authentication'); 454 545 } 455 546 … … 470 561 switch ($method) { 471 562 case 'DIGEST-MD5': 472 $result = $this->_authDigest_MD5($uid, $pwd );563 $result = $this->_authDigest_MD5($uid, $pwd, $authz); 473 564 break; 474 565 … … 482 573 483 574 case 'PLAIN': 484 $result = $this->_authPlain($uid, $pwd );575 $result = $this->_authPlain($uid, $pwd, $authz); 485 576 break; 486 577 … … 503 594 * @param string The userid to authenticate as. 504 595 * @param string The password to authenticate with. 596 * @param string The optional authorization proxy identifier. 505 597 * 506 598 * @return mixed Returns a PEAR_Error with an error message on any … … 509 601 * @since 1.1.0 510 602 */ 511 function _authDigest_MD5($uid, $pwd )603 function _authDigest_MD5($uid, $pwd, $authz = '') 512 604 { 513 605 if (PEAR::isError($error = $this->_put('AUTH', 'DIGEST-MD5'))) { … … 539 631 * allow subsequent authentication, so we just silently ignore 540 632 * it. */ 541 if (PEAR::isError($error = $this->_put(' 633 if (PEAR::isError($error = $this->_put(''))) { 542 634 return $error; 543 635 } … … 637 729 * @param string The userid to authenticate as. 638 730 * @param string The password to authenticate with. 731 * @param string The optional authorization proxy identifier. 639 732 * 640 733 * @return mixed Returns a PEAR_Error with an error message on any … … 643 736 * @since 1.1.0 644 737 */ 645 function _authPlain($uid, $pwd )738 function _authPlain($uid, $pwd, $authz = '') 646 739 { 647 740 if (PEAR::isError($error = $this->_put('AUTH', 'PLAIN'))) { … … 657 750 } 658 751 659 $auth_str = base64_encode( chr(0) . $uid . chr(0) . $pwd);752 $auth_str = base64_encode($authz . chr(0) . $uid . chr(0) . $pwd); 660 753 661 754 if (PEAR::isError($error = $this->_put($auth_str))) { … … 691 784 692 785 return true; 786 } 787 788 /** 789 * Return the list of SMTP service extensions advertised by the server. 790 * 791 * @return array The list of SMTP service extensions. 792 * @access public 793 * @since 1.3 794 */ 795 function getServiceExtensions() 796 { 797 return $this->_esmtp; 693 798 } 694 799 … … 733 838 return $error; 734 839 } 735 if (PEAR::isError($error = $this->_parseResponse(250 ))) {840 if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { 736 841 return $error; 737 842 } … … 763 868 return $error; 764 869 } 765 if (PEAR::isError($error = $this->_parseResponse(array(250, 251) ))) {870 if (PEAR::isError($error = $this->_parseResponse(array(250, 251), $this->pipelining))) { 766 871 return $error; 767 872 } … … 798 903 * Send the DATA command. 799 904 * 800 * @param string $data The message body to send. 905 * @param mixed $data The message data, either as a string or an open 906 * file resource. 907 * @param string $headers The message headers. If $headers is provided, 908 * $data is assumed to contain only body data. 801 909 * 802 910 * @return mixed Returns a PEAR_Error with an error message on any … … 805 913 * @since 1.0 806 914 */ 807 function data($data) 808 { 809 /* RFC 1870, section 3, subsection 3 states "a value of zero 810 * indicates that no fixed maximum message size is in force". 811 * Furthermore, it says that if "the parameter is omitted no 812 * information is conveyed about the server's fixed maximum 813 * message size". */ 814 if (isset($this->_esmtp['SIZE']) && ($this->_esmtp['SIZE'] > 0)) { 815 if (strlen($data) >= $this->_esmtp['SIZE']) { 816 $this->disconnect(); 817 return PEAR::raiseError('Message size excedes the server limit'); 818 } 819 } 820 821 /* Quote the data based on the SMTP standards. */ 822 $this->quotedata($data); 823 915 function data($data, $headers = null) 916 { 917 /* Verify that $data is a supported type. */ 918 if (!is_string($data) && !is_resource($data)) { 919 return PEAR::raiseError('Expected a string or file resource'); 920 } 921 922 /* Start by considering the size of the optional headers string. We 923 * also account for the addition 4 character "\r\n\r\n" separator 924 * sequence. */ 925 $size = (is_null($headers)) ? 0 : strlen($headers) + 4; 926 927 if (is_resource($data)) { 928 $stat = fstat($data); 929 if ($stat === false) { 930 return PEAR::raiseError('Failed to get file size'); 931 } 932 $size += $stat['size']; 933 } else { 934 $size += strlen($data); 935 } 936 937 /* RFC 1870, section 3, subsection 3 states "a value of zero indicates 938 * that no fixed maximum message size is in force". Furthermore, it 939 * says that if "the parameter is omitted no information is conveyed 940 * about the server's fixed maximum message size". */ 941 $limit = (isset($this->_esmtp['SIZE'])) ? $this->_esmtp['SIZE'] : 0; 942 if ($limit > 0 && $size >= $limit) { 943 $this->disconnect(); 944 return PEAR::raiseError('Message size exceeds server limit'); 945 } 946 947 /* Initiate the DATA command. */ 824 948 if (PEAR::isError($error = $this->_put('DATA'))) { 825 949 return $error; … … 829 953 } 830 954 831 if (PEAR::isError($result = $this->_send($data . "\r\n.\r\n"))) { 955 /* If we have a separate headers string, send it first. */ 956 if (!is_null($headers)) { 957 $this->quotedata($headers); 958 if (PEAR::isError($result = $this->_send($headers . "\r\n\r\n"))) { 959 return $result; 960 } 961 } 962 963 /* Now we can send the message body data. */ 964 if (is_resource($data)) { 965 /* Stream the contents of the file resource out over our socket 966 * connection, line by line. Each line must be run through the 967 * quoting routine. */ 968 while ($line = fgets($data, 1024)) { 969 $this->quotedata($line); 970 if (PEAR::isError($result = $this->_send($line))) { 971 return $result; 972 } 973 } 974 } else { 975 /* 976 * Break up the data by sending one chunk (up to 512k) at a time. 977 * This approach reduces our peak memory usage. 978 */ 979 for ($offset = 0; $offset < $size;) { 980 $end = $offset + 512000; 981 982 /* 983 * Ensure we don't read beyond our data size or span multiple 984 * lines. quotedata() can't properly handle character data 985 * that's split across two line break boundaries. 986 */ 987 if ($end >= $size) { 988 $end = $size; 989 } else { 990 for (; $end < $size; $end++) { 991 if ($data[$end] != "\n") { 992 break; 993 } 994 } 995 } 996 997 /* Extract our chunk and run it through the quoting routine. */ 998 $chunk = substr($data, $offset, $end - $offset); 999 $this->quotedata($chunk); 1000 1001 /* If we run into a problem along the way, abort. */ 1002 if (PEAR::isError($result = $this->_send($chunk))) { 1003 return $result; 1004 } 1005 1006 /* Advance the offset to the end of this chunk. */ 1007 $offset = $end; 1008 } 1009 } 1010 1011 /* Finally, send the DATA terminator sequence. */ 1012 if (PEAR::isError($result = $this->_send("\r\n.\r\n"))) { 832 1013 return $result; 833 1014 } 834 if (PEAR::isError($error = $this->_parseResponse(250))) { 1015 1016 /* Verify that the data was successfully received by the server. */ 1017 if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { 835 1018 return $error; 836 1019 } … … 854 1037 return $error; 855 1038 } 856 if (PEAR::isError($error = $this->_parseResponse(250 ))) {1039 if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { 857 1040 return $error; 858 1041 } … … 893 1076 return $error; 894 1077 } 895 if (PEAR::isError($error = $this->_parseResponse(250 ))) {1078 if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { 896 1079 return $error; 897 1080 } … … 932 1115 return $error; 933 1116 } 934 if (PEAR::isError($error = $this->_parseResponse(250 ))) {1117 if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { 935 1118 return $error; 936 1119 } … … 969 1152 return $error; 970 1153 } 971 if (PEAR::isError($error = $this->_parseResponse(250 ))) {1154 if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) { 972 1155 return $error; 973 1156 }
Note: See TracChangeset
for help on using the changeset viewer.