1<?php
2
3/*
4 * This file is part of SwiftMailer.
5 * (c) 2004-2009 Chris Corbyn
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11/**
12 * An ESMTP handler for AUTH support.
13 *
14 * @author Chris Corbyn
15 */
16class Swift_Transport_Esmtp_AuthHandler implements Swift_Transport_EsmtpHandler
17{
18    /**
19     * Authenticators available to process the request.
20     *
21     * @var Swift_Transport_Esmtp_Authenticator[]
22     */
23    private $_authenticators = array();
24
25    /**
26     * The username for authentication.
27     *
28     * @var string
29     */
30    private $_username;
31
32    /**
33     * The password for authentication.
34     *
35     * @var string
36     */
37    private $_password;
38
39    /**
40     * The auth mode for authentication.
41     *
42     * @var string
43     */
44    private $_auth_mode;
45
46    /**
47     * The ESMTP AUTH parameters available.
48     *
49     * @var string[]
50     */
51    private $_esmtpParams = array();
52
53    /**
54     * Create a new AuthHandler with $authenticators for support.
55     *
56     * @param Swift_Transport_Esmtp_Authenticator[] $authenticators
57     */
58    public function __construct(array $authenticators)
59    {
60        $this->setAuthenticators($authenticators);
61    }
62
63    /**
64     * Set the Authenticators which can process a login request.
65     *
66     * @param Swift_Transport_Esmtp_Authenticator[] $authenticators
67     */
68    public function setAuthenticators(array $authenticators)
69    {
70        $this->_authenticators = $authenticators;
71    }
72
73    /**
74     * Get the Authenticators which can process a login request.
75     *
76     * @return Swift_Transport_Esmtp_Authenticator[]
77     */
78    public function getAuthenticators()
79    {
80        return $this->_authenticators;
81    }
82
83    /**
84     * Set the username to authenticate with.
85     *
86     * @param string $username
87     */
88    public function setUsername($username)
89    {
90        $this->_username = $username;
91    }
92
93    /**
94     * Get the username to authenticate with.
95     *
96     * @return string
97     */
98    public function getUsername()
99    {
100        return $this->_username;
101    }
102
103    /**
104     * Set the password to authenticate with.
105     *
106     * @param string $password
107     */
108    public function setPassword($password)
109    {
110        $this->_password = $password;
111    }
112
113    /**
114     * Get the password to authenticate with.
115     *
116     * @return string
117     */
118    public function getPassword()
119    {
120        return $this->_password;
121    }
122
123    /**
124     * Set the auth mode to use to authenticate.
125     *
126     * @param string $mode
127     */
128    public function setAuthMode($mode)
129    {
130        $this->_auth_mode = $mode;
131    }
132
133    /**
134     * Get the auth mode to use to authenticate.
135     *
136     * @return string
137     */
138    public function getAuthMode()
139    {
140        return $this->_auth_mode;
141    }
142
143    /**
144     * Get the name of the ESMTP extension this handles.
145     *
146     * @return bool
147     */
148    public function getHandledKeyword()
149    {
150        return 'AUTH';
151    }
152
153    /**
154     * Set the parameters which the EHLO greeting indicated.
155     *
156     * @param string[] $parameters
157     */
158    public function setKeywordParams(array $parameters)
159    {
160        $this->_esmtpParams = $parameters;
161    }
162
163    /**
164     * Runs immediately after a EHLO has been issued.
165     *
166     * @param Swift_Transport_SmtpAgent $agent to read/write
167     */
168    public function afterEhlo(Swift_Transport_SmtpAgent $agent)
169    {
170        if ($this->_username) {
171            $count = 0;
172            foreach ($this->_getAuthenticatorsForAgent() as $authenticator) {
173                if (in_array(strtolower($authenticator->getAuthKeyword()),
174                    array_map('strtolower', $this->_esmtpParams))) {
175                    ++$count;
176                    if ($authenticator->authenticate($agent, $this->_username, $this->_password)) {
177                        return;
178                    }
179                }
180            }
181            throw new Swift_TransportException(
182                'Failed to authenticate on SMTP server with username "'.
183                $this->_username.'" using '.$count.' possible authenticators'
184                );
185        }
186    }
187
188    /**
189     * Not used.
190     */
191    public function getMailParams()
192    {
193        return array();
194    }
195
196    /**
197     * Not used.
198     */
199    public function getRcptParams()
200    {
201        return array();
202    }
203
204    /**
205     * Not used.
206     */
207    public function onCommand(Swift_Transport_SmtpAgent $agent, $command, $codes = array(), &$failedRecipients = null, &$stop = false)
208    {
209    }
210
211    /**
212     * Returns +1, -1 or 0 according to the rules for usort().
213     *
214     * This method is called to ensure extensions can be execute in an appropriate order.
215     *
216     * @param string $esmtpKeyword to compare with
217     *
218     * @return int
219     */
220    public function getPriorityOver($esmtpKeyword)
221    {
222        return 0;
223    }
224
225    /**
226     * Returns an array of method names which are exposed to the Esmtp class.
227     *
228     * @return string[]
229     */
230    public function exposeMixinMethods()
231    {
232        return array('setUsername', 'getUsername', 'setPassword', 'getPassword', 'setAuthMode', 'getAuthMode');
233    }
234
235    /**
236     * Not used.
237     */
238    public function resetState()
239    {
240    }
241
242    /**
243     * Returns the authenticator list for the given agent.
244     *
245     * @param Swift_Transport_SmtpAgent $agent
246     *
247     * @return array
248     */
249    protected function _getAuthenticatorsForAgent()
250    {
251        if (!$mode = strtolower($this->_auth_mode)) {
252            return $this->_authenticators;
253        }
254
255        foreach ($this->_authenticators as $authenticator) {
256            if (strtolower($authenticator->getAuthKeyword()) == $mode) {
257                return array($authenticator);
258            }
259        }
260
261        throw new Swift_TransportException('Auth mode '.$mode.' is invalid');
262    }
263}
264