Changeset 5485 in subversion
- Timestamp:
- Nov 24, 2011 5:54:59 AM (18 months ago)
- Location:
- trunk/roundcubemail
- Files:
-
- 3 edited
-
CHANGELOG (modified) (1 diff)
-
program/include/rcube_smtp.php (modified) (3 diffs)
-
program/lib/Net/SMTP.php (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/roundcubemail/CHANGELOG
r5483 r5485 2 2 =========================== 3 3 4 - Add possibility to add SASL mechanisms for SMTP in smtp_connect hook (#1487937) 4 5 - Mark (with different color) folders with recent messages (#1486234) 5 6 - Fix possible infinite redirect on attachment preview (#1488199) -
trunk/roundcubemail/program/include/rcube_smtp.php
r5319 r5485 51 51 { 52 52 $RCMAIL = rcmail::get_instance(); 53 53 54 54 // disconnect/destroy $this->conn 55 55 $this->disconnect(); 56 56 57 57 // reset error/response var 58 58 $this->error = $this->response = null; 59 59 60 60 // let plugins alter smtp connection config 61 61 $CONFIG = $RCMAIL->plugins->exec_hook('smtp_connect', array( … … 69 69 'smtp_helo_host' => $RCMAIL->config->get('smtp_helo_host'), 70 70 'smtp_timeout' => $RCMAIL->config->get('smtp_timeout'), 71 'smtp_auth_callbacks' => array(), 71 72 )); 72 73 … … 108 109 if ($RCMAIL->config->get('smtp_debug')) 109 110 $this->conn->setDebug(true, array($this, 'debug_handler')); 111 112 // register authentication methods 113 if (!empty($CONFIG['smtp_auth_callbacks']) && method_exists($this->conn, 'setAuthMethod')) { 114 foreach ($CONFIG['smtp_auth_callbacks'] as $callback) { 115 $this->conn->setAuthMethod($callback['name'], $callback['function'], 116 isset($callback['prepend']) ? $callback['prepend'] : true); 117 } 118 } 110 119 111 120 // try to connect to server and exit on failure -
trunk/roundcubemail/program/lib/Net/SMTP.php
r4665 r5485 63 63 * @access public 64 64 */ 65 var $auth_methods = array( 'DIGEST-MD5', 'CRAM-MD5', 'LOGIN', 'PLAIN');65 var $auth_methods = array(); 66 66 67 67 /** … … 188 188 $this->_timeout = $timeout; 189 189 190 /* Include the Auth_SASL package. If the package is not 191 * available, we disable the authentication methods that 192 * depend upon it. */ 193 if ((@include_once 'Auth/SASL.php') === false) { 194 $pos = array_search('DIGEST-MD5', $this->auth_methods); 195 unset($this->auth_methods[$pos]); 196 $pos = array_search('CRAM-MD5', $this->auth_methods); 197 unset($this->auth_methods[$pos]); 198 } 190 /* Include the Auth_SASL package. If the package is available, we 191 * enable the authentication methods that depend upon it. */ 192 if ((@include_once 'Auth/SASL.php') === true) { 193 $this->setAuthMethod('CRAM-MD5', array($this, '_authCram_MD5')); 194 $this->setAuthMethod('DIGEST-MD5', array($this, '_authDigest_MD5')); 195 } 196 197 /* These standard authentication methods are always available. */ 198 $this->setAuthMethod('LOGIN', array($this, '_authLogin'), false); 199 $this->setAuthMethod('PLAIN', array($this, '_authPlain'), false); 199 200 } 200 201 … … 251 252 * @param string $data The string of data to send. 252 253 * 253 * @return mixed True on success or a PEAR_Error object on failure. 254 * @return mixed The number of bytes that were actually written, 255 * or a PEAR_Error object on failure. 254 256 * 255 257 * @access private … … 260 262 $this->_debug("Send: $data"); 261 263 262 $error = $this->_socket->write($data); 263 if ($error === false || PEAR::isError($error)) { 264 $msg = ($error) ? $error->getMessage() : "unknown error"; 265 return PEAR::raiseError("Failed to write to socket: $msg"); 266 } 267 268 return true; 264 $result = $this->_socket->write($data); 265 if (!$result || PEAR::isError($result)) { 266 $msg = ($result) ? $result->getMessage() : "unknown error"; 267 return PEAR::raiseError("Failed to write to socket: $msg", 268 null, PEAR_ERROR_RETURN); 269 } 270 271 return $result; 269 272 } 270 273 … … 293 296 294 297 if (strcspn($command, "\r\n") !== strlen($command)) { 295 return PEAR::raiseError('Commands cannot contain newlines'); 298 return PEAR::raiseError('Commands cannot contain newlines', 299 null, PEAR_ERROR_RETURN); 296 300 } 297 301 … … 332 336 $this->_debug("Recv: $line"); 333 337 334 /* If we receive an empty line, the connection has beenclosed. */338 /* If we receive an empty line, the connection was closed. */ 335 339 if (empty($line)) { 336 340 $this->disconnect(); 337 return PEAR::raiseError('Connection was unexpectedly closed'); 341 return PEAR::raiseError('Connection was closed', 342 null, PEAR_ERROR_RETURN); 338 343 } 339 344 … … 367 372 368 373 return PEAR::raiseError('Invalid response code received from server', 369 $this->_code); 374 $this->_code, PEAR_ERROR_RETURN); 375 } 376 377 /** 378 * Issue an SMTP command and verify its response. 379 * 380 * @param string $command The SMTP command string or data. 381 * @param mixed $valid The set of valid response codes. These 382 * may be specified as an array of integer 383 * values or as a single integer value. 384 * 385 * @return mixed True on success or a PEAR_Error object on failure. 386 * 387 * @access public 388 * @since 1.6.0 389 */ 390 function command($command, $valid) 391 { 392 if (PEAR::isError($error = $this->_put($command))) { 393 return $error; 394 } 395 if (PEAR::isError($error = $this->_parseResponse($valid))) { 396 return $error; 397 } 398 399 return true; 370 400 } 371 401 … … 500 530 } 501 531 if (PEAR::isError($this->_parseResponse(250))) { 502 return PEAR::raiseError('HELO was not accepted: ', $this->_code); 532 return PEAR::raiseError('HELO was not accepted: ', $this->_code, 533 PEAR_ERROR_RETURN); 503 534 } 504 535 … … 534 565 $available_methods = explode(' ', $this->_esmtp['AUTH']); 535 566 536 foreach ($this->auth_methods as $method ) {567 foreach ($this->auth_methods as $method => $callback) { 537 568 if (in_array($method, $available_methods)) { 538 569 return $method; … … 540 571 } 541 572 542 return PEAR::raiseError('No supported authentication methods'); 573 return PEAR::raiseError('No supported authentication methods', 574 null, PEAR_ERROR_RETURN); 543 575 } 544 576 … … 600 632 } else { 601 633 $method = strtoupper($method); 602 if (! in_array($method, $this->auth_methods)) {634 if (!array_key_exists($method, $this->auth_methods)) { 603 635 return PEAR::raiseError("$method is not a supported authentication method"); 604 636 } 605 637 } 606 638 607 switch ($method) { 608 case 'DIGEST-MD5': 609 $result = $this->_authDigest_MD5($uid, $pwd, $authz); 610 break; 611 612 case 'CRAM-MD5': 613 $result = $this->_authCRAM_MD5($uid, $pwd); 614 break; 615 616 case 'LOGIN': 617 $result = $this->_authLogin($uid, $pwd); 618 break; 619 620 case 'PLAIN': 621 $result = $this->_authPlain($uid, $pwd, $authz); 622 break; 623 624 default: 625 $result = PEAR::raiseError("$method is not a supported authentication method"); 626 break; 627 } 639 if (!isset($this->auth_methods[$method])) { 640 return PEAR::raiseError("$method is not a supported authentication method"); 641 } 642 643 if (!is_callable($this->auth_methods[$method], false)) { 644 return PEAR::raiseError("$method authentication method cannot be called"); 645 } 646 647 if (is_array($this->auth_methods[$method])) { 648 list($object, $method) = $this->auth_methods[$method]; 649 $result = $object->{$method}($uid, $pwd, $authz, $this); 650 } else { 651 $func = $this->auth_methods[$method]; 652 $result = $func($uid, $pwd, $authz, $this); 653 } 628 654 629 655 /* If an error was encountered, return the PEAR_Error object. */ 630 656 if (PEAR::isError($result)) { 631 657 return $result; 658 } 659 660 return true; 661 } 662 663 /** 664 * Add a new authentication method. 665 * 666 * @param string The authentication method name (e.g. 'PLAIN') 667 * @param mixed The authentication callback (given as the name of a 668 * function or as an (object, method name) array). 669 * @param bool Should the new method be prepended to the list of 670 * available methods? This is the default behavior, 671 * giving the new method the highest priority. 672 * 673 * @return mixed True on success or a PEAR_Error object on failure. 674 * 675 * @access public 676 * @since 1.6.0 677 */ 678 function setAuthMethod($name, $callback, $prepend = true) 679 { 680 if (!is_string($name)) { 681 return PEAR::raiseError('Method name is not a string'); 682 } 683 684 if (!is_string($callback) && !is_array($callback)) { 685 return PEAR::raiseError('Method callback must be string or array'); 686 } 687 688 if (is_array($callback)) { 689 if (!is_object($callback[0]) || !is_string($callback[1])) 690 return PEAR::raiseError('Bad mMethod callback array'); 691 } 692 693 if ($prepend) { 694 $this->auth_methods = array_merge(array($name => $callback), 695 $this->auth_methods); 696 } else { 697 $this->auth_methods[$name] = $callback; 632 698 } 633 699 … … 692 758 * @param string The userid to authenticate as. 693 759 * @param string The password to authenticate with. 760 * @param string The optional authorization proxy identifier. 694 761 * 695 762 * @return mixed Returns a PEAR_Error with an error message on any … … 698 765 * @since 1.1.0 699 766 */ 700 function _authCRAM_MD5($uid, $pwd )767 function _authCRAM_MD5($uid, $pwd, $authz = '') 701 768 { 702 769 if (PEAR::isError($error = $this->_put('AUTH', 'CRAM-MD5'))) { … … 731 798 * @param string The userid to authenticate as. 732 799 * @param string The password to authenticate with. 800 * @param string The optional authorization proxy identifier. 733 801 * 734 802 * @return mixed Returns a PEAR_Error with an error message on any … … 737 805 * @since 1.1.0 738 806 */ 739 function _authLogin($uid, $pwd )807 function _authLogin($uid, $pwd, $authz = '') 740 808 { 741 809 if (PEAR::isError($error = $this->_put('AUTH', 'LOGIN'))) { … … 1013 1081 * connection, line by line. Each line must be run through the 1014 1082 * quoting routine. */ 1015 while ($line = fgets($data, 1024)) { 1083 while (strlen($line = fread($data, 8192)) > 0) { 1084 /* If the last character is an newline, we need to grab the 1085 * next character to check to see if it is a period. */ 1086 while (!feof($data)) { 1087 $char = fread($data, 1); 1088 $line .= $char; 1089 if ($char != "\n") { 1090 break; 1091 } 1092 } 1016 1093 $this->quotedata($line); 1017 1094 if (PEAR::isError($result = $this->_send($line))) {
Note: See TracChangeset
for help on using the changeset viewer.
