Project

General

Profile

1
<?php
2
/**
3
 * PHPMailer - PHP email creation and transport class.
4
 * PHP Version 5.4
5
 * @package PHPMailer
6
 * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
8
 * @author Jim Jagielski (jimjag) <jimjag@gmail.com>
9
 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
10
 * @author Brent R. Matzelle (original founder)
11
 * @copyright 2012 - 2014 Marcus Bointon
12
 * @copyright 2010 - 2012 Jim Jagielski
13
 * @copyright 2004 - 2009 Andy Prevost
14
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
15
 * @note This program is distributed in the hope that it will be useful - WITHOUT
16
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
 * FITNESS FOR A PARTICULAR PURPOSE.
18
 */
19

    
20
/**
21
 * PHPMailerOAuth - PHPMailer subclass adding OAuth support.
22
 * @package PHPMailer
23
 * @author @sherryl4george
24
 * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>
25
 */
26
class PHPMailerOAuth extends PHPMailer
27
{
28
    /**
29
     * The OAuth user's email address
30
     * @var string
31
     */
32
    public $oauthUserEmail = '';
33

    
34
    /**
35
     * The OAuth refresh token
36
     * @var string
37
     */
38
    public $oauthRefreshToken = '';
39

    
40
    /**
41
     * The OAuth client ID
42
     * @var string
43
     */
44
    public $oauthClientId = '';
45

    
46
    /**
47
     * The OAuth client secret
48
     * @var string
49
     */
50
    public $oauthClientSecret = '';
51

    
52
    /**
53
     * An instance of the PHPMailerOAuthGoogle class.
54
     * @var PHPMailerOAuthGoogle
55
     * @access protected
56
     */
57
    protected $oauth = null;
58

    
59
    /**
60
     * Get a PHPMailerOAuthGoogle instance to use.
61
     * @return PHPMailerOAuthGoogle
62
     */
63
    public function getOAUTHInstance()
64
    {
65
        if (!is_object($this->oauth)) {
66
            $this->oauth = new PHPMailerOAuthGoogle(
67
                $this->oauthUserEmail,
68
                $this->oauthClientSecret,
69
                $this->oauthClientId,
70
                $this->oauthRefreshToken
71
            );
72
        }
73
        return $this->oauth;
74
    }
75

    
76
    /**
77
     * Initiate a connection to an SMTP server.
78
     * Overrides the original smtpConnect method to add support for OAuth.
79
     * @param array $options An array of options compatible with stream_context_create()
80
     * @uses SMTP
81
     * @access public
82
     * @return bool
83
     * @throws phpmailerException
84
     */
85
    public function smtpConnect($options = array())
86
    {
87
        if (is_null($this->smtp)) {
88
            $this->smtp = $this->getSMTPInstance();
89
        }
90

    
91
        if (is_null($this->oauth)) {
92
            $this->oauth = $this->getOAUTHInstance();
93
        }
94

    
95
        // Already connected?
96
        if ($this->smtp->connected()) {
97
            return true;
98
        }
99

    
100
        $this->smtp->setTimeout($this->Timeout);
101
        $this->smtp->setDebugLevel($this->SMTPDebug);
102
        $this->smtp->setDebugOutput($this->Debugoutput);
103
        $this->smtp->setVerp($this->do_verp);
104
        $hosts = explode(';', $this->Host);
105
        $lastexception = null;
106

    
107
        foreach ($hosts as $hostentry) {
108
            $hostinfo = array();
109
            if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
110
                // Not a valid host entry
111
                continue;
112
            }
113
            // $hostinfo[2]: optional ssl or tls prefix
114
            // $hostinfo[3]: the hostname
115
            // $hostinfo[4]: optional port number
116
            // The host string prefix can temporarily override the current setting for SMTPSecure
117
            // If it's not specified, the default value is used
118
            $prefix = '';
119
            $secure = $this->SMTPSecure;
120
            $tls = ($this->SMTPSecure == 'tls');
121
            if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
122
                $prefix = 'ssl://';
123
                $tls = false; // Can't have SSL and TLS at the same time
124
                $secure = 'ssl';
125
            } elseif ($hostinfo[2] == 'tls') {
126
                $tls = true;
127
                // tls doesn't use a prefix
128
                $secure = 'tls';
129
            }
130
            //Do we need the OpenSSL extension?
131
            $sslext = defined('OPENSSL_ALGO_SHA1');
132
            if ('tls' === $secure or 'ssl' === $secure) {
133
                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
134
                if (!$sslext) {
135
                    throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
136
                }
137
            }
138
            $host = $hostinfo[3];
139
            $port = $this->Port;
140
            $tport = (integer)$hostinfo[4];
141
            if ($tport > 0 and $tport < 65536) {
142
                $port = $tport;
143
            }
144
            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
145
                try {
146
                    if ($this->Helo) {
147
                        $hello = $this->Helo;
148
                    } else {
149
                        $hello = $this->serverHostname();
150
                    }
151
                    $this->smtp->hello($hello);
152
                    //Automatically enable TLS encryption if:
153
                    // * it's not disabled
154
                    // * we have openssl extension
155
                    // * we are not already using SSL
156
                    // * the server offers STARTTLS
157
                    if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
158
                        $tls = true;
159
                    }
160
                    if ($tls) {
161
                        if (!$this->smtp->startTLS()) {
162
                            throw new phpmailerException($this->lang('connect_host'));
163
                        }
164
                        // We must resend HELO after tls negotiation
165
                        $this->smtp->hello($hello);
166
                    }
167
                    if ($this->SMTPAuth) {
168
                        if (!$this->smtp->authenticate(
169
                            $this->Username,
170
                            $this->Password,
171
                            $this->AuthType,
172
                            $this->Realm,
173
                            $this->Workstation,
174
                            $this->oauth
175
                        )
176
                        ) {
177
                            throw new phpmailerException($this->lang('authenticate'));
178
                        }
179
                    }
180
                    return true;
181
                } catch (phpmailerException $exc) {
182
                    $lastexception = $exc;
183
                    $this->edebug($exc->getMessage());
184
                    // We must have connected, but then failed TLS or Auth, so close connection nicely
185
                    $this->smtp->quit();
186
                }
187
            }
188
        }
189
        // If we get here, all connection attempts have failed, so close connection hard
190
        $this->smtp->close();
191
        // As we've caught all exceptions, just report whatever the last one was
192
        if ($this->exceptions and !is_null($lastexception)) {
193
            throw $lastexception;
194
        }
195
        return false;
196
    }
197
}
(5-5/9)