Mercurial > hg > rc1
comparison vendor/pear/net_sieve/Sieve.php @ 35:05c4c32948af
.hgignore: add vendor tree
composer.json: new packages
plugins/thunderbird_labels/thunderbird_labels.php: change hook and RFC822 use wrt whitelisting to avoid deprecated stuff
index.php: commented debugging hooks
others: new releases of vendor packages?
| author | Charlie Root |
|---|---|
| date | Thu, 30 Aug 2018 16:21:59 -0400 |
| parents | 1e000243b222 |
| children |
comparison
equal
deleted
inserted
replaced
| 34:50ac5484d514 | 35:05c4c32948af |
|---|---|
| 44 | 44 |
| 45 require_once 'PEAR.php'; | 45 require_once 'PEAR.php'; |
| 46 require_once 'Net/Socket.php'; | 46 require_once 'Net/Socket.php'; |
| 47 | 47 |
| 48 /** | 48 /** |
| 49 * TODO | 49 * Disconnected state |
| 50 * | 50 * |
| 51 * o supportsAuthMech() | |
| 52 */ | |
| 53 | |
| 54 /** | |
| 55 * Disconnected state | |
| 56 * @const NET_SIEVE_STATE_DISCONNECTED | 51 * @const NET_SIEVE_STATE_DISCONNECTED |
| 57 */ | 52 */ |
| 58 define('NET_SIEVE_STATE_DISCONNECTED', 1, true); | 53 define('NET_SIEVE_STATE_DISCONNECTED', 1, true); |
| 59 | 54 |
| 60 /** | 55 /** |
| 61 * Authorisation state | 56 * Authorisation state |
| 57 * | |
| 62 * @const NET_SIEVE_STATE_AUTHORISATION | 58 * @const NET_SIEVE_STATE_AUTHORISATION |
| 63 */ | 59 */ |
| 64 define('NET_SIEVE_STATE_AUTHORISATION', 2, true); | 60 define('NET_SIEVE_STATE_AUTHORISATION', 2, true); |
| 65 | 61 |
| 66 /** | 62 /** |
| 67 * Transaction state | 63 * Transaction state |
| 64 * | |
| 68 * @const NET_SIEVE_STATE_TRANSACTION | 65 * @const NET_SIEVE_STATE_TRANSACTION |
| 69 */ | 66 */ |
| 70 define('NET_SIEVE_STATE_TRANSACTION', 3, true); | 67 define('NET_SIEVE_STATE_TRANSACTION', 3, true); |
| 71 | 68 |
| 72 | 69 |
| 77 * @package Net_Sieve | 74 * @package Net_Sieve |
| 78 * @author Richard Heyes <richard@phpguru.org> | 75 * @author Richard Heyes <richard@phpguru.org> |
| 79 * @author Damian Fernandez Sosa <damlists@cnba.uba.ar> | 76 * @author Damian Fernandez Sosa <damlists@cnba.uba.ar> |
| 80 * @author Anish Mistry <amistry@am-productions.biz> | 77 * @author Anish Mistry <amistry@am-productions.biz> |
| 81 * @author Jan Schneider <jan@horde.org> | 78 * @author Jan Schneider <jan@horde.org> |
| 79 * @author Neil Munday <neil@mundayweb.com> | |
| 82 * @copyright 2002-2003 Richard Heyes | 80 * @copyright 2002-2003 Richard Heyes |
| 83 * @copyright 2006-2008 Anish Mistry | 81 * @copyright 2006-2008 Anish Mistry |
| 84 * @license http://www.opensource.org/licenses/bsd-license.php BSD | 82 * @license http://www.opensource.org/licenses/bsd-license.php BSD |
| 85 * @version Release: @package_version@ | 83 * @version Release: @package_version@ |
| 86 * @link http://pear.php.net/package/Net_Sieve | 84 * @link http://pear.php.net/package/Net_Sieve |
| 101 var $supportedAuthMethods = array( | 99 var $supportedAuthMethods = array( |
| 102 'DIGEST-MD5', | 100 'DIGEST-MD5', |
| 103 'CRAM-MD5', | 101 'CRAM-MD5', |
| 104 'EXTERNAL', | 102 'EXTERNAL', |
| 105 'PLAIN' , | 103 'PLAIN' , |
| 106 'LOGIN' | 104 'LOGIN', |
| 105 'GSSAPI' | |
| 107 ); | 106 ); |
| 108 | 107 |
| 109 /** | 108 /** |
| 110 * SASL authentication methods that require Auth_SASL. | 109 * SASL authentication methods that require Auth_SASL. |
| 111 * | 110 * |
| 191 * Maximum number of referral loops | 190 * Maximum number of referral loops |
| 192 * | 191 * |
| 193 * @var array | 192 * @var array |
| 194 */ | 193 */ |
| 195 var $_maxReferralCount = 15; | 194 var $_maxReferralCount = 15; |
| 195 | |
| 196 /** | |
| 197 * Kerberos service principal to use for GSSAPI authentication. | |
| 198 * | |
| 199 * @var string | |
| 200 */ | |
| 201 var $_gssapiPrincipal = null; | |
| 202 | |
| 203 /** | |
| 204 * Kerberos service cname to use for GSSAPI authentication. | |
| 205 * | |
| 206 * @var string | |
| 207 */ | |
| 208 var $_gssapiCN = null; | |
| 196 | 209 |
| 197 /** | 210 /** |
| 198 * Constructor. | 211 * Constructor. |
| 199 * | 212 * |
| 200 * Sets up the object, connects to the server and logs in. Stores any | 213 * Sets up the object, connects to the server and logs in. Stores any |
| 214 * socket is already open. | 227 * socket is already open. |
| 215 * @param boolean $useTLS Use TLS if available. | 228 * @param boolean $useTLS Use TLS if available. |
| 216 * @param array $options Additional options for | 229 * @param array $options Additional options for |
| 217 * stream_context_create(). | 230 * stream_context_create(). |
| 218 * @param mixed $handler A callback handler for the debug output. | 231 * @param mixed $handler A callback handler for the debug output. |
| 232 * @param string $principal Kerberos service principal to use | |
| 233 * with GSSAPI authentication. | |
| 234 * @param string $cname Kerberos service cname to use | |
| 235 * with GSSAPI authentication. | |
| 219 */ | 236 */ |
| 220 function __construct($user = null, $pass = null, $host = 'localhost', | 237 function __construct($user = null, $pass = null, $host = 'localhost', |
| 221 $port = 2000, $logintype = '', $euser = '', | 238 $port = 2000, $logintype = '', $euser = '', |
| 222 $debug = false, $bypassAuth = false, $useTLS = true, | 239 $debug = false, $bypassAuth = false, $useTLS = true, |
| 223 $options = null, $handler = null | 240 $options = null, $handler = null, $principal = null, $cname = null |
| 224 ) { | 241 ) { |
| 225 $this->_pear = new PEAR(); | 242 $this->_pear = new PEAR(); |
| 226 $this->_state = NET_SIEVE_STATE_DISCONNECTED; | 243 $this->_state = NET_SIEVE_STATE_DISCONNECTED; |
| 227 $this->_data['user'] = $user; | 244 $this->_data['user'] = $user; |
| 228 $this->_data['pass'] = $pass; | 245 $this->_data['pass'] = $pass; |
| 232 $this->_data['euser'] = $euser; | 249 $this->_data['euser'] = $euser; |
| 233 $this->_sock = new Net_Socket(); | 250 $this->_sock = new Net_Socket(); |
| 234 $this->_bypassAuth = $bypassAuth; | 251 $this->_bypassAuth = $bypassAuth; |
| 235 $this->_useTLS = $useTLS; | 252 $this->_useTLS = $useTLS; |
| 236 $this->_options = (array) $options; | 253 $this->_options = (array) $options; |
| 254 $this->_gssapiPrincipal = $principal; | |
| 255 $this->_gssapiCN = $cname; | |
| 256 | |
| 237 $this->setDebug($debug, $handler); | 257 $this->setDebug($debug, $handler); |
| 238 | 258 |
| 239 /* Try to include the Auth_SASL package. If the package is not | 259 /* Try to include the Auth_SASL package. If the package is not |
| 240 * available, we disable the authentication methods that depend upon | 260 * available, we disable the authentication methods that depend upon |
| 241 * it. */ | 261 * it. */ |
| 275 $this->_debug = $debug; | 295 $this->_debug = $debug; |
| 276 $this->_debug_handler = $handler; | 296 $this->_debug_handler = $handler; |
| 277 } | 297 } |
| 278 | 298 |
| 279 /** | 299 /** |
| 300 * Sets the Kerberos service principal for use with GSSAPI | |
| 301 * authentication. | |
| 302 * | |
| 303 * @param string $principal The Kerberos service principal | |
| 304 * | |
| 305 * @return void | |
| 306 */ | |
| 307 function setServicePrincipal($principal) | |
| 308 { | |
| 309 $this->_gssapiPrincipal = $principal; | |
| 310 } | |
| 311 | |
| 312 /** | |
| 313 * Sets the Kerberos service CName for use with GSSAPI | |
| 314 * authentication. | |
| 315 * | |
| 316 * @param string $cname The Kerberos service principal | |
| 317 * | |
| 318 * @return void | |
| 319 */ | |
| 320 function setServiceCN($cname) | |
| 321 { | |
| 322 $this->_gssapiCN = $cname; | |
| 323 } | |
| 324 | |
| 325 /** | |
| 280 * Connects to the server and logs in. | 326 * Connects to the server and logs in. |
| 281 * | 327 * |
| 282 * @return boolean True on success, PEAR_Error on failure. | 328 * @return boolean True on success, PEAR_Error on failure. |
| 283 */ | 329 */ |
| 284 function _handleConnectAndLogin() | 330 function _handleConnectAndLogin() |
| 326 return $res; | 372 return $res; |
| 327 } | 373 } |
| 328 | 374 |
| 329 if ($this->_bypassAuth) { | 375 if ($this->_bypassAuth) { |
| 330 $this->_state = NET_SIEVE_STATE_TRANSACTION; | 376 $this->_state = NET_SIEVE_STATE_TRANSACTION; |
| 377 | |
| 378 // Reset capabilities | |
| 379 $this->_parseCapability(''); | |
| 331 } else { | 380 } else { |
| 332 $this->_state = NET_SIEVE_STATE_AUTHORISATION; | 381 $this->_state = NET_SIEVE_STATE_AUTHORISATION; |
| 382 | |
| 333 $res = $this->_doCmd(); | 383 $res = $this->_doCmd(); |
| 334 if (is_a($res, 'PEAR_Error')) { | 384 if (is_a($res, 'PEAR_Error')) { |
| 335 return $res; | 385 return $res; |
| 336 } | 386 } |
| 337 } | 387 |
| 338 | 388 // Reset capabilities (use unattended capabilities) |
| 339 // Explicitly ask for the capabilities in case the connection is | 389 $this->_parseCapability($res); |
| 340 // picked up from an existing connection. | 390 } |
| 341 $res = $this->_cmdCapability(); | 391 |
| 342 if (is_a($res, 'PEAR_Error')) { | 392 // Explicitly ask for the capabilities if needed |
| 343 return $this->_pear->raiseError( | 393 if (empty($this->_capability['implementation'])) { |
| 344 'Failed to connect, server said: ' . $res->getMessage(), 2 | 394 $res = $this->_cmdCapability(); |
| 345 ); | 395 if (is_a($res, 'PEAR_Error')) { |
| 396 return $this->_pear->raiseError( | |
| 397 'Failed to connect, server said: ' . $res->getMessage(), 2 | |
| 398 ); | |
| 399 } | |
| 346 } | 400 } |
| 347 | 401 |
| 348 // Check if we can enable TLS via STARTTLS. | 402 // Check if we can enable TLS via STARTTLS. |
| 349 if ($useTLS && !empty($this->_capability['starttls']) | 403 if ($useTLS && !empty($this->_capability['starttls']) |
| 350 && function_exists('stream_socket_enable_crypto') | 404 && function_exists('stream_socket_enable_crypto') |
| 398 $res = $this->_cmdAuthenticate($user, $pass, $logintype, $euser); | 452 $res = $this->_cmdAuthenticate($user, $pass, $logintype, $euser); |
| 399 if (is_a($res, 'PEAR_Error')) { | 453 if (is_a($res, 'PEAR_Error')) { |
| 400 return $res; | 454 return $res; |
| 401 } | 455 } |
| 402 } | 456 } |
| 457 | |
| 403 $this->_state = NET_SIEVE_STATE_TRANSACTION; | 458 $this->_state = NET_SIEVE_STATE_TRANSACTION; |
| 404 | 459 |
| 405 return true; | 460 return true; |
| 406 } | 461 } |
| 407 | 462 |
| 408 /** | 463 /** |
| 409 * Returns an indexed array of scripts currently on the server. | 464 * Returns an indexed array of scripts currently on the server. |
| 410 * | 465 * |
| 411 * @return array Indexed array of scriptnames. | 466 * @param string $active Will be set to the name of the active script |
| 412 */ | 467 * |
| 413 function listScripts() | 468 * @return array Indexed array of scriptnames, PEAR_Error on failure |
| 469 */ | |
| 470 function listScripts(&$active = null) | |
| 414 { | 471 { |
| 415 if (is_array($scripts = $this->_cmdListScripts())) { | 472 if (is_array($scripts = $this->_cmdListScripts())) { |
| 473 if (isset($scripts[1])) { | |
| 474 $active = $scripts[1]; | |
| 475 } | |
| 476 | |
| 416 return $scripts[0]; | 477 return $scripts[0]; |
| 417 } else { | 478 } |
| 418 return $scripts; | 479 |
| 419 } | 480 return $scripts; |
| 420 } | 481 } |
| 421 | 482 |
| 422 /** | 483 /** |
| 423 * Returns the active script. | 484 * Returns the active script. |
| 424 * | 485 * |
| 468 { | 529 { |
| 469 $res = $this->_cmdPutScript($scriptname, $script); | 530 $res = $this->_cmdPutScript($scriptname, $script); |
| 470 if (is_a($res, 'PEAR_Error')) { | 531 if (is_a($res, 'PEAR_Error')) { |
| 471 return $res; | 532 return $res; |
| 472 } | 533 } |
| 534 | |
| 473 if ($makeactive) { | 535 if ($makeactive) { |
| 474 return $this->_cmdSetActive($scriptname); | 536 return $this->_cmdSetActive($scriptname); |
| 475 } | 537 } |
| 538 | |
| 476 return true; | 539 return true; |
| 477 } | 540 } |
| 478 | 541 |
| 479 /** | 542 /** |
| 480 * Removes a script from the server. | 543 * Removes a script from the server. |
| 506 | 569 |
| 507 $res = $this->_doCmd(sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size)); | 570 $res = $this->_doCmd(sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size)); |
| 508 if (is_a($res, 'PEAR_Error')) { | 571 if (is_a($res, 'PEAR_Error')) { |
| 509 return $res; | 572 return $res; |
| 510 } | 573 } |
| 574 | |
| 511 return true; | 575 return true; |
| 512 } | 576 } |
| 513 | 577 |
| 514 /** | 578 /** |
| 515 * Returns the list of extensions the server supports. | 579 * Returns the list of extensions the server supports. |
| 519 function getExtensions() | 583 function getExtensions() |
| 520 { | 584 { |
| 521 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { | 585 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { |
| 522 return $this->_pear->raiseError('Not currently connected', 7); | 586 return $this->_pear->raiseError('Not currently connected', 7); |
| 523 } | 587 } |
| 588 | |
| 524 return $this->_capability['extensions']; | 589 return $this->_capability['extensions']; |
| 525 } | 590 } |
| 526 | 591 |
| 527 /** | 592 /** |
| 528 * Returns whether the server supports an extension. | 593 * Returns whether the server supports an extension. |
| 558 function getAuthMechs() | 623 function getAuthMechs() |
| 559 { | 624 { |
| 560 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { | 625 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { |
| 561 return $this->_pear->raiseError('Not currently connected', 7); | 626 return $this->_pear->raiseError('Not currently connected', 7); |
| 562 } | 627 } |
| 628 | |
| 563 return $this->_capability['sasl']; | 629 return $this->_capability['sasl']; |
| 564 } | 630 } |
| 565 | 631 |
| 566 /** | 632 /** |
| 567 * Returns whether the server supports an authentication method. | 633 * Returns whether the server supports an authentication method. |
| 576 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { | 642 if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) { |
| 577 return $this->_pear->raiseError('Not currently connected', 7); | 643 return $this->_pear->raiseError('Not currently connected', 7); |
| 578 } | 644 } |
| 579 | 645 |
| 580 $method = trim($this->_toUpper($method)); | 646 $method = trim($this->_toUpper($method)); |
| 647 | |
| 581 if (is_array($this->_capability['sasl'])) { | 648 if (is_array($this->_capability['sasl'])) { |
| 582 foreach ($this->_capability['sasl'] as $sasl) { | 649 foreach ($this->_capability['sasl'] as $sasl) { |
| 583 if ($sasl == $method) { | 650 if ($sasl == $method) { |
| 584 return true; | 651 return true; |
| 585 } | 652 } |
| 604 { | 671 { |
| 605 $method = $this->_getBestAuthMethod($userMethod); | 672 $method = $this->_getBestAuthMethod($userMethod); |
| 606 if (is_a($method, 'PEAR_Error')) { | 673 if (is_a($method, 'PEAR_Error')) { |
| 607 return $method; | 674 return $method; |
| 608 } | 675 } |
| 676 | |
| 609 switch ($method) { | 677 switch ($method) { |
| 610 case 'DIGEST-MD5': | 678 case 'DIGEST-MD5': |
| 611 return $this->_authDigestMD5($uid, $pwd, $euser); | 679 return $this->_authDigestMD5($uid, $pwd, $euser); |
| 612 case 'CRAM-MD5': | 680 case 'CRAM-MD5': |
| 613 $result = $this->_authCRAMMD5($uid, $pwd, $euser); | 681 $result = $this->_authCRAMMD5($uid, $pwd, $euser); |
| 619 $result = $this->_authPLAIN($uid, $pwd, $euser); | 687 $result = $this->_authPLAIN($uid, $pwd, $euser); |
| 620 break; | 688 break; |
| 621 case 'EXTERNAL': | 689 case 'EXTERNAL': |
| 622 $result = $this->_authEXTERNAL($uid, $pwd, $euser); | 690 $result = $this->_authEXTERNAL($uid, $pwd, $euser); |
| 623 break; | 691 break; |
| 692 case 'GSSAPI': | |
| 693 $result = $this->_authGSSAPI($pwd); | |
| 694 break; | |
| 624 default : | 695 default : |
| 625 $result = $this->_pear->raiseError( | 696 $result = $this->_pear->raiseError( |
| 626 $method . ' is not a supported authentication method' | 697 $method . ' is not a supported authentication method' |
| 627 ); | 698 ); |
| 628 break; | 699 break; |
| 631 $res = $this->_doCmd(); | 702 $res = $this->_doCmd(); |
| 632 if (is_a($res, 'PEAR_Error')) { | 703 if (is_a($res, 'PEAR_Error')) { |
| 633 return $res; | 704 return $res; |
| 634 } | 705 } |
| 635 | 706 |
| 636 // Query the server capabilities again now that we are authenticated. | |
| 637 if ($this->_pear->isError($res = $this->_cmdCapability())) { | 707 if ($this->_pear->isError($res = $this->_cmdCapability())) { |
| 638 return $this->_pear->raiseError( | 708 return $this->_pear->raiseError( |
| 639 'Failed to connect, server said: ' . $res->getMessage(), 2 | 709 'Failed to connect, server said: ' . $res->getMessage(), 2 |
| 640 ); | 710 ); |
| 641 } | 711 } |
| 661 ) | 731 ) |
| 662 ); | 732 ); |
| 663 } | 733 } |
| 664 | 734 |
| 665 /** | 735 /** |
| 736 * Authenticates the user using the GSSAPI method. | |
| 737 * | |
| 738 * @note the PHP krb5 extension is required and the service principal and cname | |
| 739 * must have been set. | |
| 740 * @see setServicePrincipal() | |
| 741 * | |
| 742 * @return void | |
| 743 */ | |
| 744 function _authGSSAPI() | |
| 745 { | |
| 746 if (!extension_loaded('krb5')) { | |
| 747 return $this->_pear->raiseError('The krb5 extension is required for GSSAPI authentication', 2); | |
| 748 } | |
| 749 | |
| 750 if (!$this->_gssapiPrincipal) { | |
| 751 return $this->_pear->raiseError('No Kerberos service principal set', 2); | |
| 752 } | |
| 753 | |
| 754 if (!$this->_gssapiCN) { | |
| 755 return $this->_pear->raiseError('No Kerberos service CName set', 2); | |
| 756 } | |
| 757 | |
| 758 putenv('KRB5CCNAME=' . $this->_gssapiCN); | |
| 759 | |
| 760 try { | |
| 761 $ccache = new KRB5CCache(); | |
| 762 $ccache->open($this->_gssapiCN); | |
| 763 | |
| 764 $gssapicontext = new GSSAPIContext(); | |
| 765 $gssapicontext->acquireCredentials($ccache); | |
| 766 | |
| 767 $token = ''; | |
| 768 $success = $gssapicontext->initSecContext($this->_gssapiPrincipal, null, null, null, $token); | |
| 769 $token = base64_encode($token); | |
| 770 } | |
| 771 catch (Exception $e) { | |
| 772 return $this->_pear->raiseError('GSSAPI authentication failed: ' . $e->getMessage()); | |
| 773 } | |
| 774 | |
| 775 $this->_sendCmd("AUTHENTICATE \"GSSAPI\" {" . strlen($token) . "+}"); | |
| 776 | |
| 777 $response = $this->_doCmd($token, true); | |
| 778 | |
| 779 try { | |
| 780 $challenge = base64_decode(substr($response, 1, -1)); | |
| 781 $gssapicontext->unwrap($challenge, $challenge); | |
| 782 $gssapicontext->wrap($challenge, $challenge, true); | |
| 783 } | |
| 784 catch (Exception $e) { | |
| 785 return $this->_pear->raiseError('GSSAPI authentication failed: ' . $e->getMessage()); | |
| 786 } | |
| 787 | |
| 788 $response = base64_encode($challenge); | |
| 789 | |
| 790 $this->_sendCmd("{" . strlen($response) . "+}"); | |
| 791 | |
| 792 return $this->_sendCmd($response); | |
| 793 } | |
| 794 | |
| 795 /** | |
| 666 * Authenticates the user using the LOGIN method. | 796 * Authenticates the user using the LOGIN method. |
| 667 * | 797 * |
| 668 * @param string $user The userid to authenticate as. | 798 * @param string $user The userid to authenticate as. |
| 669 * @param string $pass The password to authenticate with. | 799 * @param string $pass The password to authenticate with. |
| 670 * @param string $euser The effective uid to authenticate as. Not used. | 800 * @param string $euser The effective uid to authenticate as. Not used. |
| 675 { | 805 { |
| 676 $result = $this->_sendCmd('AUTHENTICATE "LOGIN"'); | 806 $result = $this->_sendCmd('AUTHENTICATE "LOGIN"'); |
| 677 if (is_a($result, 'PEAR_Error')) { | 807 if (is_a($result, 'PEAR_Error')) { |
| 678 return $result; | 808 return $result; |
| 679 } | 809 } |
| 810 | |
| 680 $result = $this->_doCmd('"' . base64_encode($user) . '"', true); | 811 $result = $this->_doCmd('"' . base64_encode($user) . '"', true); |
| 681 if (is_a($result, 'PEAR_Error')) { | 812 if (is_a($result, 'PEAR_Error')) { |
| 682 return $result; | 813 return $result; |
| 683 } | 814 } |
| 815 | |
| 684 return $this->_doCmd('"' . base64_encode($pass) . '"', true); | 816 return $this->_doCmd('"' . base64_encode($pass) . '"', true); |
| 685 } | 817 } |
| 686 | 818 |
| 687 /** | 819 /** |
| 688 * Authenticates the user using the CRAM-MD5 method. | 820 * Authenticates the user using the CRAM-MD5 method. |
| 740 | 872 |
| 741 $result = $this->_sendStringResponse(base64_encode($response)); | 873 $result = $this->_sendStringResponse(base64_encode($response)); |
| 742 if (is_a($result, 'PEAR_Error')) { | 874 if (is_a($result, 'PEAR_Error')) { |
| 743 return $result; | 875 return $result; |
| 744 } | 876 } |
| 877 | |
| 745 $result = $this->_doCmd('', true); | 878 $result = $this->_doCmd('', true); |
| 746 if (is_a($result, 'PEAR_Error')) { | 879 if (is_a($result, 'PEAR_Error')) { |
| 747 return $result; | 880 return $result; |
| 748 } | 881 } |
| 882 | |
| 749 if ($this->_toUpper(substr($result, 0, 2)) == 'OK') { | 883 if ($this->_toUpper(substr($result, 0, 2)) == 'OK') { |
| 750 return; | 884 return; |
| 751 } | 885 } |
| 752 | 886 |
| 753 /* We don't use the protocol's third step because SIEVE doesn't allow | 887 /* We don't use the protocol's third step because SIEVE doesn't allow |
| 767 * @param string $pass The password to authenticate with. | 901 * @param string $pass The password to authenticate with. |
| 768 * @param string $euser The effective uid to authenticate as. | 902 * @param string $euser The effective uid to authenticate as. |
| 769 * | 903 * |
| 770 * @return void | 904 * @return void |
| 771 * | 905 * |
| 772 * @since 1.1.7 | 906 * @since 1.1.7 |
| 773 */ | 907 */ |
| 774 function _authEXTERNAL($user, $pass, $euser) | 908 function _authEXTERNAL($user, $pass, $euser) |
| 775 { | 909 { |
| 776 $cmd = sprintf( | 910 $cmd = sprintf( |
| 777 'AUTHENTICATE "EXTERNAL" "%s"', | 911 'AUTHENTICATE "EXTERNAL" "%s"', |
| 778 base64_encode(strlen($euser) ? $euser : $user) | 912 base64_encode(strlen($euser) ? $euser : $user) |
| 779 ); | 913 ); |
| 914 | |
| 780 return $this->_sendCmd($cmd); | 915 return $this->_sendCmd($cmd); |
| 781 } | 916 } |
| 782 | 917 |
| 783 /** | 918 /** |
| 784 * Removes a script from the server. | 919 * Removes a script from the server. |
| 795 | 930 |
| 796 $res = $this->_doCmd(sprintf('DELETESCRIPT %s', $this->_escape($scriptname))); | 931 $res = $this->_doCmd(sprintf('DELETESCRIPT %s', $this->_escape($scriptname))); |
| 797 if (is_a($res, 'PEAR_Error')) { | 932 if (is_a($res, 'PEAR_Error')) { |
| 798 return $res; | 933 return $res; |
| 799 } | 934 } |
| 935 | |
| 800 return true; | 936 return true; |
| 801 } | 937 } |
| 802 | 938 |
| 803 /** | 939 /** |
| 804 * Retrieves the contents of the named script. | 940 * Retrieves the contents of the named script. |
| 976 case 'IMPLEMENTATION': | 1112 case 'IMPLEMENTATION': |
| 977 $this->_capability['implementation'] = $matches[3]; | 1113 $this->_capability['implementation'] = $matches[3]; |
| 978 break; | 1114 break; |
| 979 | 1115 |
| 980 case 'SASL': | 1116 case 'SASL': |
| 981 $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]); | 1117 if (!empty($matches[3])) { |
| 1118 $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]); | |
| 1119 } | |
| 982 break; | 1120 break; |
| 983 | 1121 |
| 984 case 'SIEVE': | 1122 case 'SIEVE': |
| 985 $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]); | 1123 if (!empty($matches[3])) { |
| 1124 $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]); | |
| 1125 } | |
| 986 break; | 1126 break; |
| 987 | 1127 |
| 988 case 'STARTTLS': | 1128 case 'STARTTLS': |
| 989 $this->_capability['starttls'] = true; | 1129 $this->_capability['starttls'] = true; |
| 990 break; | 1130 break; |
| 1225 return $res; | 1365 return $res; |
| 1226 } | 1366 } |
| 1227 | 1367 |
| 1228 if (isset($this->_options['ssl']['crypto_method'])) { | 1368 if (isset($this->_options['ssl']['crypto_method'])) { |
| 1229 $crypto_method = $this->_options['ssl']['crypto_method']; | 1369 $crypto_method = $this->_options['ssl']['crypto_method']; |
| 1230 } | 1370 } else { |
| 1231 else { | |
| 1232 // There is no flag to enable all TLS methods. Net_SMTP | 1371 // There is no flag to enable all TLS methods. Net_SMTP |
| 1233 // handles enabling TLS similarly. | 1372 // handles enabling TLS similarly. |
| 1234 $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT | 1373 $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT |
| 1235 | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | 1374 | @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT |
| 1236 | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; | 1375 | @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; |
| 1248 // CAPABILITY response, thus we would wait here forever. Parse the | 1387 // CAPABILITY response, thus we would wait here forever. Parse the |
| 1249 // Cyrus version and work around this broken behavior. | 1388 // Cyrus version and work around this broken behavior. |
| 1250 if (!preg_match('/^CYRUS TIMSIEVED V([0-9.]+)/', $this->_capability['implementation'], $matches) | 1389 if (!preg_match('/^CYRUS TIMSIEVED V([0-9.]+)/', $this->_capability['implementation'], $matches) |
| 1251 || version_compare($matches[1], '2.3.10', '>=') | 1390 || version_compare($matches[1], '2.3.10', '>=') |
| 1252 ) { | 1391 ) { |
| 1253 $this->_doCmd(); | 1392 $res = $this->_doCmd(); |
| 1254 } | 1393 } |
| 1255 | 1394 |
| 1256 // Query the server capabilities again now that we are under | 1395 // Reset capabilities (use unattended capabilities) |
| 1257 // encryption. | 1396 $this->_parseCapability(is_string($res) ? $res : ''); |
| 1258 $res = $this->_cmdCapability(); | 1397 |
| 1259 if (is_a($res, 'PEAR_Error')) { | 1398 // Query the server capabilities again now that we are under encryption. |
| 1260 return $this->_pear->raiseError( | 1399 if (empty($this->_capability['implementation'])) { |
| 1261 'Failed to connect, server said: ' . $res->getMessage(), 2 | 1400 $res = $this->_cmdCapability(); |
| 1262 ); | 1401 if (is_a($res, 'PEAR_Error')) { |
| 1402 return $this->_pear->raiseError( | |
| 1403 'Failed to connect, server said: ' . $res->getMessage(), 2 | |
| 1404 ); | |
| 1405 } | |
| 1263 } | 1406 } |
| 1264 | 1407 |
| 1265 return true; | 1408 return true; |
| 1266 } | 1409 } |
| 1267 | 1410 |
| 1273 * @return integer The length of the string. | 1416 * @return integer The length of the string. |
| 1274 */ | 1417 */ |
| 1275 function _getLineLength($string) | 1418 function _getLineLength($string) |
| 1276 { | 1419 { |
| 1277 if (extension_loaded('mbstring')) { | 1420 if (extension_loaded('mbstring')) { |
| 1278 return mb_strlen($string, 'latin1'); | 1421 return mb_strlen($string, '8bit'); |
| 1279 } else { | 1422 } else { |
| 1280 return strlen($string); | 1423 return strlen($string); |
| 1281 } | 1424 } |
| 1282 } | 1425 } |
| 1283 | 1426 |
