Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support google XOAUTH2 authentication Issues #350 - Added Code #421

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions class.oauth.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

require_once 'vendor/autoload.php';

class OAuth {

private $oauthUserEmail = '';
private $oauthRefreshToken = '';
private $oauthClientId = '';
private $oauthClientSecret = '';

public function __construct($UserEmail,
$ClientSecret,
$ClientId,
$RefreshToken
) {
$this->oauthClientId = $ClientId;
$this->oauthClientSecret = $ClientSecret;
$this->oauthRefreshToken = $RefreshToken;
$this->oauthUserEmail = $UserEmail;
}

private function getProvider() {
return new League\OAuth2\Client\Provider\Google([
'clientId' => $this->oauthClientId,
'clientSecret' => $this->oauthClientSecret
]);
}

private function getGrant(){
return new \League\OAuth2\Client\Grant\RefreshToken();
}

private function getToken(){
$provider = $this->getProvider();
$grant = $this->getGrant();
return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);
}

public function getOauth64(){
$token = $this->getToken();
echo $this->oauthUserEmail;
return base64_encode("user=" . $this->oauthUserEmail . "\001auth=Bearer " . $token . "\001\001");
}


}
?>

23 changes: 17 additions & 6 deletions class.phpmailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,18 @@ class PHPMailer
* @type string
*/
public $XMailer = '';


/**
* Only For XOAUTH - Google
* Options: An empty string for PHPMailer default, Enter the email used to get access token
* @type string
*/
// public $UserEmail = '';
// public $RefreshToken = '';
// public $ClientId = '';
// public $ClientSecret = '';


/**
* An instance of the SMTP sender class.
* @type SMTP
Expand Down Expand Up @@ -1317,7 +1328,7 @@ public function smtpConnect($options = array())
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}

// Already connected?
if ($this->smtp->connected()) {
return true;
Expand Down Expand Up @@ -1392,10 +1403,10 @@ public function smtpConnect($options = array())
}
if ($this->SMTPAuth) {
if (!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation
)
) {
Expand Down
163 changes: 163 additions & 0 deletions class.phpmailer54.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

class PHPMailer54 extends PHPMailer {

public $oauthUserEmail = '';
public $oauthRefreshToken = '';
public $oauthClientId = '';
public $oauthClientSecret = '';

/**
* An instance of the SMTP sender class.
* @type SMTP
* @access protected
*/
protected $oauth = null;

public function __construct()
{
parent::__construct($exceptions = false);
}

/**
* Destructor.
*/
public function __destruct()
{
//Close any open SMTP connection nicely
parent::__destruct();
}

/**
* Get an instance to use for SMTP operations.
* Override this function to load your own SMTP implementation
* @return SMTP
*/
public function getOAUTHInstance()
{
if (!is_object($this->oauth)) {
$this->oauth = new OAuth($this->oauthUserEmail,
$this->oauthClientSecret,
$this->oauthClientId,
$this->oauthRefreshToken
);
}
return $this->oauth;
}

public function smtpConnect($options = array())
{
if (is_null($this->smtp)) {
$this->smtp = $this->getSMTPInstance();
}

if (is_null($this->oauth)) {
$this->oauth = $this->getOAUTHInstance();
}

// Already connected?
if ($this->smtp->connected()) {
return true;
}

$this->smtp->setTimeout($this->Timeout);
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
$hosts = explode(';', $this->Host);
$lastexception = null;

foreach ($hosts as $hostentry) {
$hostinfo = array();
if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
// Not a valid host entry
continue;
}
// $hostinfo[2]: optional ssl or tls prefix
// $hostinfo[3]: the hostname
// $hostinfo[4]: optional port number
// The host string prefix can temporarily override the current setting for SMTPSecure
// If it's not specified, the default value is used
$prefix = '';
$secure = $this->SMTPSecure;
$tls = ($this->SMTPSecure == 'tls');
if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
$prefix = 'ssl:https://';
$tls = false; // Can't have SSL and TLS at the same time
$secure = 'ssl';
} elseif ($hostinfo[2] == 'tls') {
$tls = true;
// tls doesn't use a prefix
$secure = 'tls';
}
//Do we need the OpenSSL extension?
$sslext = defined('OPENSSL_ALGO_SHA1');
if ('tls' === $secure or 'ssl' === $secure) {
//Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
if (!$sslext) {
throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);
}
}
$host = $hostinfo[3];
$port = $this->Port;
$tport = (integer)$hostinfo[4];
if ($tport > 0 and $tport < 65536) {
$port = $tport;
}
if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
try {
if ($this->Helo) {
$hello = $this->Helo;
} else {
$hello = $this->serverHostname();
}
$this->smtp->hello($hello);
//Automatically enable TLS encryption if:
// * it's not disabled
// * we have openssl extension
// * we are not already using SSL
// * the server offers STARTTLS
if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
$tls = true;
}
if ($tls) {
if (!$this->smtp->startTLS()) {
throw new phpmailerException($this->lang('connect_host'));
}
// We must resend HELO after tls negotiation
$this->smtp->hello($hello);
}
if ($this->SMTPAuth) {
if (!$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->Realm,
$this->Workstation,
$this->oauth
)
) {
throw new phpmailerException($this->lang('authenticate'));
}
}
return true;
} catch (phpmailerException $exc) {
$lastexception = $exc;
$this->edebug($exc->getMessage());
// We must have connected, but then failed TLS or Auth, so close connection nicely
$this->smtp->quit();
}
}
}
// If we get here, all connection attempts have failed, so close connection hard
$this->smtp->close();
// As we've caught all exceptions, just report whatever the last one was
if ($this->exceptions and !is_null($lastexception)) {
throw $lastexception;
}
return false;
}

}

?>
16 changes: 15 additions & 1 deletion class.smtp.php
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,8 @@ public function authenticate(
$password,
$authtype = null,
$realm = '',
$workstation = ''
$workstation = '',
$OAuth = null
) {
if (!$this->server_caps) {
$this->setError('Authentication is not allowed before HELO/EHLO');
Expand Down Expand Up @@ -436,6 +437,19 @@ public function authenticate(
return false;
}
break;
case 'XOAUTH':
//If the OAuth Instance is not set. Can be a case when PHPMailer is used
//instead of PHPMailer54
if(is_null($OAuth))
return false;

$oauth = $OAuth->getOauth64();

// Start authentication
if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
return false;
}
break;
case 'NTLM':
/*
* ntlm_sasl_client.php
Expand Down
58 changes: 31 additions & 27 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
{
"name": "phpmailer/phpmailer",
"type": "library",
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"authors": [
"name": "phpmailer/phpmailer",
"type": "library",
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"authors": [
{
"name": "Marcus Bointon",
"email": "[email protected]"
"name": "Marcus Bointon",
"email": "[email protected]"
},
{
"name": "Jim Jagielski",
"email": "[email protected]"
"name": "Jim Jagielski",
"email": "[email protected]"
},
{
"name": "Andy Prevost",
"email": "[email protected]"
"name": "Andy Prevost",
"email": "[email protected]"
},
{
"name": "Brent R. Matzelle"
"name": "Brent R. Matzelle"
}
],
"require": {
"php": ">=5.0.0"
},
"require-dev": {
],
"require": {
"php": ">=5.0.0",
"league/oauth2-client": "0.10.*",
"guzzle/guzzle": "~3.7"
},
"require-dev": {
"phpdocumentor/phpdocumentor": "*",
"phpunit/phpunit": "4.3.*"
},
"autoload": {
"phpunit/phpunit": "4.3.*"
},
"autoload": {
"classmap": [
"class.phpmailer.php",
"class.smtp.php",
"class.pop3.php",
"extras/EasyPeasyICS.php",
"extras/ntlm_sasl_client.php"
"class.phpmailer.php",
"class.phpmailer54.php",
"class.oauth.php",
"class.smtp.php",
"class.pop3.php",
"extras/EasyPeasyICS.php",
"extras/ntlm_sasl_client.php"
]
},
"license": "LGPL-2.1"
}
},
"license": "LGPL-2.1"
}
Loading