1: <?php
2: /**
3: * @package Kolab_Filter
4: */
5:
6: /**
7: * Extended LMTP class with support for TLS.
8: *
9: * Copyright 2008-2012 Horde LLC (http://www.horde.org/)
10: *
11: * See the enclosed file COPYING for license information (LGPL). If you
12: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
13: *
14: * @author Gunnar Wrobel <wrobel@pardus.de>
15: * @package Kolab_Filter
16: */
17: class Net_LMTP_TLS extends Net_LMTP {
18:
19: /**
20: * Attempt to do LMTP authentication.
21: *
22: * @param string The userid to authenticate as.
23: * @param string The password to authenticate with.
24: * @param string The requested authentication method. If none is
25: * specified, the best supported method will be used.
26: *
27: * @return mixed Returns a PEAR_Error with an error message on any
28: * kind of failure, or true on success.
29: * @access public
30: */
31: function auth($uid, $pwd , $method = '')
32: {
33: if (!isset($this->_esmtp['STARTTLS'])) {
34: return PEAR::raiseError('LMTP server does not support authentication');
35: }
36: if (PEAR::isError($result = $this->_put('STARTTLS'))) {
37: return $result;
38: }
39: if (PEAR::isError($result = $this->_parseResponse(220))) {
40: return $result;
41: }
42: if (PEAR::isError($result = $this->_socket->enableCrypto(true, STREAM_CRYPTO_METHOD_TLS_CLIENT))) {
43: return $result;
44: } elseif ($result !== true) {
45: return PEAR::raiseError('STARTTLS failed');
46: }
47:
48: /* Send LHLO again to recieve the AUTH string from the LMTP server. */
49: $this->_negotiate();
50: if (empty($this->_esmtp['AUTH'])) {
51: return PEAR::raiseError('LMTP server does not support authentication');
52: }
53:
54: /*
55: * If no method has been specified, get the name of the best supported
56: * method advertised by the LMTP server.
57: */
58: if (empty($method) || $method === true ) {
59: if (PEAR::isError($method = $this->_getBestAuthMethod())) {
60: /* Return the PEAR_Error object from _getBestAuthMethod(). */
61: return $method;
62: }
63: } else {
64: $method = strtoupper($method);
65: }
66:
67: switch ($method) {
68: case 'DIGEST-MD5':
69: $result = $this->_authDigest_MD5($uid, $pwd);
70: break;
71: case 'CRAM-MD5':
72: $result = $this->_authCRAM_MD5($uid, $pwd);
73: break;
74: case 'LOGIN':
75: $result = $this->_authLogin($uid, $pwd);
76: break;
77: case 'PLAIN':
78: $result = $this->_authPlain($uid, $pwd);
79: break;
80: default :
81: $result = new PEAR_Error("$method is not a supported authentication method");
82: break;
83: }
84:
85: /* If an error was encountered, return the PEAR_Error object. */
86: if (PEAR::isError($result)) {
87: return $result;
88: }
89:
90: /* RFC-2554 requires us to re-negotiate ESMTP after an AUTH. */
91: if (PEAR::isError($error = $this->_negotiate())) {
92: return $error;
93: }
94:
95: return true;
96: }
97: }
98: