mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-10 06:58:27 +03:00
Improved SASL
This commit is contained in:
parent
e96ced3bde
commit
fcc219cc07
5 changed files with 71 additions and 51 deletions
|
|
@ -180,56 +180,40 @@ class ImapClient extends \MailSo\Net\NetClient
|
|||
|
||||
try
|
||||
{
|
||||
if ('CRAM-MD5' === $type)
|
||||
if (0 === \strpos($type, 'SCRAM-SHA-'))
|
||||
{
|
||||
$oContinuationResponse = $this->SendRequestGetResponse('AUTHENTICATE', array($type))->getLast();
|
||||
if ($oContinuationResponse && Enumerations\ResponseType::CONTINUATION === $oContinuationResponse->ResponseType)
|
||||
{
|
||||
$sTicket = $oContinuationResponse->ResponseList[1] ?? null;
|
||||
if ($sTicket)
|
||||
{
|
||||
$sToken = $SASL->authenticate($sLogin, $sPassword, $sTicket);
|
||||
|
||||
$this->oLogger->Write('ticket: '.\base64_decode($sTicket));
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->AddSecret($sToken);
|
||||
}
|
||||
|
||||
$this->sendRaw($sToken, true, '*******');
|
||||
$this->getResponse();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->writeLogException(
|
||||
new Exceptions\LoginException,
|
||||
\MailSo\Log\Enumerations\Type::NOTICE, true);
|
||||
}
|
||||
$sAuthzid = $this->getResponseValue($this->SendRequestGetResponse('AUTHENTICATE', array($type)), Enumerations\ResponseType::CONTINUATION);
|
||||
$this->sendRaw($SASL->authenticate($sLogin, $sPassword/*, $sAuthzid*/));
|
||||
$sChallenge = $SASL->challenge($this->getResponseValue($this->getResponse(), Enumerations\ResponseType::CONTINUATION));
|
||||
if ($this->oLogger) {
|
||||
$this->oLogger->AddSecret($sChallenge);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->writeLogException(
|
||||
new Exceptions\LoginException,
|
||||
\MailSo\Log\Enumerations\Type::NOTICE, true);
|
||||
$this->sendRaw($sChallenge, true, '*******');
|
||||
$sSignature = $this->getResponseValue($this->getResponse());
|
||||
$SASL->verify($sSignature);
|
||||
}
|
||||
else if ('CRAM-MD5' === $type)
|
||||
{
|
||||
$sChallenge = $this->getResponseValue($this->SendRequestGetResponse('AUTHENTICATE', array($type)), Enumerations\ResponseType::CONTINUATION);
|
||||
$this->oLogger->Write('challenge: '.\base64_decode($sChallenge));
|
||||
$sAuth = $SASL->authenticate($sLogin, $sPassword, $sChallenge);
|
||||
if ($this->oLogger) {
|
||||
$this->oLogger->AddSecret($sAuth);
|
||||
}
|
||||
$this->sendRaw($sAuth, true, '*******');
|
||||
$this->getResponse();
|
||||
}
|
||||
else if ('PLAIN' === $type)
|
||||
{
|
||||
$sToken = $SASL->authenticate($sLogin, $sPassword);
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->AddSecret($sToken);
|
||||
$sAuth = $SASL->authenticate($sLogin, $sPassword);
|
||||
if ($this->oLogger) {
|
||||
$this->oLogger->AddSecret($sAuth);
|
||||
}
|
||||
|
||||
if ($this->IsSupported('SASL-IR'))
|
||||
{
|
||||
$this->SendRequestGetResponse('AUTHENTICATE', array('PLAIN', $sToken));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->IsSupported('SASL-IR')) {
|
||||
$this->SendRequestGetResponse('AUTHENTICATE', array('PLAIN', $sAuth));
|
||||
} else {
|
||||
$this->SendRequestGetResponse('AUTHENTICATE', array('PLAIN'));
|
||||
$this->sendRaw($sToken, true, '*******');
|
||||
$this->sendRaw($sAuth, true, '*******');
|
||||
$this->getResponse();
|
||||
}
|
||||
}
|
||||
|
|
@ -1025,6 +1009,23 @@ class ImapClient extends \MailSo\Net\NetClient
|
|||
return $this->getResponse();
|
||||
}
|
||||
|
||||
private function getResponseValue(ResponseCollection $oResponseCollection, int $type = 0) : string
|
||||
{
|
||||
$oResponse = $oResponseCollection->getLast();
|
||||
if ($oResponse && (!$type || $type === $oResponse->ResponseType)) {
|
||||
$sResult = $oResponse->ResponseList[1] ?? null;
|
||||
if ($sResult) {
|
||||
return $sResult;
|
||||
}
|
||||
$this->writeLogException(
|
||||
new Exceptions\LoginException,
|
||||
\MailSo\Log\Enumerations\Type::NOTICE, true);
|
||||
}
|
||||
$this->writeLogException(
|
||||
new Exceptions\LoginException,
|
||||
\MailSo\Log\Enumerations\Type::NOTICE, true);
|
||||
}
|
||||
|
||||
public function GetLastResponse() : ResponseCollection
|
||||
{
|
||||
return $this->oLastResponse;
|
||||
|
|
|
|||
|
|
@ -120,12 +120,31 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
|||
|
||||
if ($this->IsSupported('SASL'))
|
||||
{
|
||||
// $encrypted = !empty(\stream_get_meta_data($this->rConnect)['crypto']);
|
||||
$type = '';
|
||||
$types = [
|
||||
// 'SCRAM-SHA-256' => 1, // !$encrypted
|
||||
// 'SCRAM-SHA-1' => 1, // !$encrypted
|
||||
// 'CRAM-MD5' => 1, // $encrypted
|
||||
'PLAIN' => 1, // $encrypted
|
||||
'LOGIN' => 1 // $encrypted
|
||||
];
|
||||
foreach ($types as $sasl_type => $active) {
|
||||
if ($active && $this->IsAuthSupported($sasl_type) && \SnappyMail\SASL::isSupported($sasl_type)) {
|
||||
$type = $sasl_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$SASL = \SnappyMail\SASL::factory($type);
|
||||
$SASL->base64 = true;
|
||||
|
||||
$bAuth = false;
|
||||
try
|
||||
{
|
||||
if ($this->IsAuthSupported('PLAIN'))
|
||||
if ('PLAIN' === $type)
|
||||
{
|
||||
$sAuth = \base64_encode($sLoginAuthKey."\0".$sLogin."\0".$sPassword);
|
||||
$sAuth = $SASL->authenticate($sLogin, $sPassword, $sLoginAuthKey);
|
||||
|
||||
if ($this->__USE_INITIAL_AUTH_PLAIN_COMMAND)
|
||||
{
|
||||
|
|
@ -142,10 +161,10 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
|||
$this->parseStartupResponse($aResponse);
|
||||
$bAuth = true;
|
||||
}
|
||||
else if ($this->IsAuthSupported('LOGIN'))
|
||||
else if ('LOGIN' === $type)
|
||||
{
|
||||
$sLogin = \base64_encode($sLogin);
|
||||
$sPassword = \base64_encode($sPassword);
|
||||
$sLogin = $SASL->authenticate($sLogin, $sPassword);
|
||||
$sPassword = $SASL->challenge('');
|
||||
|
||||
$this->sendRequest('AUTHENTICATE "LOGIN"');
|
||||
$this->sendRequest('{'.\strlen($sLogin).'+}');
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ abstract class SASL
|
|||
public
|
||||
$base64 = false;
|
||||
|
||||
abstract public function authenticate(string $authcid, string $passphrase, ?string $authzid = null);
|
||||
abstract public function authenticate(string $authcid, string $passphrase, ?string $authzid = null) : string;
|
||||
|
||||
public function challenge(string $challenge) : string
|
||||
public function challenge(string $challenge) : ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class Login extends \SnappyMail\SASL
|
|||
return $this->encode($username);
|
||||
}
|
||||
|
||||
public function challenge(string $challenge) : string
|
||||
public function challenge(string $challenge) : ?string
|
||||
{
|
||||
if ($challenge && 'Password:' !== $this->decode($challenge)) {
|
||||
throw new \Exception("invalid response: {$challenge}");
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class Scram extends \SnappyMail\SASL
|
|||
return $this->encode($this->gs2_header . $this->auth_message);
|
||||
}
|
||||
|
||||
public function challenge(string $challenge) : string
|
||||
public function challenge(string $challenge) : ?string
|
||||
{
|
||||
$challenge = $this->decode($challenge);
|
||||
$values = static::parseMessage($challenge);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue