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: }
198: