Merge IMAP login SCRAM* with PLAIN

This commit is contained in:
the-djmaze 2024-02-06 11:50:47 +01:00
parent c365ffedf3
commit e5e6ad8aac
3 changed files with 26 additions and 22 deletions

View file

@ -156,49 +156,42 @@ class ImapClient extends \MailSo\Net\NetClient
try try
{ {
if (\str_starts_with($type, 'SCRAM-')) if ('CRAM-MD5' === $type)
{ {
$sAuth = $SASL->authenticate($sLogin, $sPassword); $oResponse = $this->SendRequestGetResponse('AUTHENTICATE', array($type));
if ($this->hasCapability('SASL-IR')) { $sChallenge = $this->getResponseValue($oResponse, Enumerations\ResponseType::CONTINUATION);
$this->sendRaw($this->SendRequestGetResponse('AUTHENTICATE', array($type, $sAuth)));
} else {
$this->SendRequestGetResponse('AUTHENTICATE', array($type));
$this->sendRaw($sAuth);
}
$sChallenge = $SASL->challenge($this->getResponseValue($this->getResponse(), Enumerations\ResponseType::CONTINUATION));
$this->logMask($sChallenge);
$this->sendRaw($sChallenge);
$oResponse = $this->getResponse();
$SASL->verify($this->getResponseValue($oResponse));
}
else if ('CRAM-MD5' === $type)
{
$sChallenge = $this->getResponseValue($this->SendRequestGetResponse('AUTHENTICATE', array($type)), Enumerations\ResponseType::CONTINUATION);
$this->logWrite('challenge: '.\base64_decode($sChallenge));
$sAuth = $SASL->authenticate($sLogin, $sPassword, $sChallenge); $sAuth = $SASL->authenticate($sLogin, $sPassword, $sChallenge);
$this->logMask($sAuth); $this->logMask($sAuth);
$this->sendRaw($sAuth); $this->sendRaw($sAuth);
$oResponse = $this->getResponse(); $oResponse = $this->getResponse();
} }
else if ('PLAIN' === $type || 'OAUTHBEARER' === $type /*|| 'PLAIN-CLIENTTOKEN' === $type*/) else if ('PLAIN' === $type || 'OAUTHBEARER' === $type || \str_starts_with($type, 'SCRAM-') /*|| 'PLAIN-CLIENTTOKEN' === $type*/)
{ {
$sAuth = $SASL->authenticate($sLogin, $sPassword); $sAuth = $SASL->authenticate($sLogin, $sPassword);
$this->logMask($sAuth); $this->logMask($sAuth);
if ($this->hasCapability('SASL-IR')) { if ($this->hasCapability('SASL-IR')) {
$oResponse = $this->SendRequestGetResponse('AUTHENTICATE', array($type, $sAuth)); $this->SendRequest('AUTHENTICATE', array($type, $sAuth));
} else { } else {
$this->SendRequestGetResponse('AUTHENTICATE', array($type)); $this->SendRequestGetResponse('AUTHENTICATE', array($type));
$this->sendRaw($sAuth); $this->sendRaw($sAuth);
}
$oResponse = $this->getResponse(); $oResponse = $this->getResponse();
if ($SASL->hasChallenge()) {
$sChallenge = $SASL->challenge($this->getResponseValue($oResponse, Enumerations\ResponseType::CONTINUATION));
$this->logMask($sChallenge);
$this->sendRaw($sChallenge);
$oResponse = $this->getResponse();
$SASL->verify($this->getResponseValue($oResponse));
} }
} }
else if ('XOAUTH2' === $type || 'OAUTHBEARER' === $type) else if ('XOAUTH2' === $type || 'OAUTHBEARER' === $type)
{ {
$sAuth = $SASL->authenticate($sLogin, $sPassword); $sAuth = $SASL->authenticate($sLogin, $sPassword);
$this->logMask($sAuth);
$oResponse = $this->SendRequestGetResponse('AUTHENTICATE', array($type, $sAuth)); $oResponse = $this->SendRequestGetResponse('AUTHENTICATE', array($type, $sAuth));
$oR = $oResponse->getLast(); $oR = $oResponse->getLast();
if ($oR && Enumerations\ResponseType::CONTINUATION === $oR->ResponseType) { if ($oR && Enumerations\ResponseType::CONTINUATION === $oR->ResponseType) {
if (!empty($oR->ResponseList[1]) && preg_match('/^[a-zA-Z0-9=+\/]+$/', $oR->ResponseList[1])) { if (!empty($oR->ResponseList[1]) && \preg_match('/^[a-zA-Z0-9=+\/]+$/', $oR->ResponseList[1])) {
$this->logWrite(\base64_decode($oR->ResponseList[1]), \LOG_WARNING); $this->logWrite(\base64_decode($oR->ResponseList[1]), \LOG_WARNING);
} }
$this->sendRaw(''); $this->sendRaw('');
@ -207,7 +200,8 @@ class ImapClient extends \MailSo\Net\NetClient
} }
else if ($this->hasCapability('LOGINDISABLED')) else if ($this->hasCapability('LOGINDISABLED'))
{ {
$sB64 = $this->getResponseValue($this->SendRequestGetResponse('AUTHENTICATE', array($type)), Enumerations\ResponseType::CONTINUATION); $oResponse = $this->SendRequestGetResponse('AUTHENTICATE', array($type));
$sB64 = $this->getResponseValue($oResponse, Enumerations\ResponseType::CONTINUATION);
$this->sendRaw($SASL->authenticate($sLogin, $sPassword, $sB64), true); $this->sendRaw($SASL->authenticate($sLogin, $sPassword, $sB64), true);
$this->getResponse(); $this->getResponse();
$sPass = $SASL->challenge(''/*UGFzc3dvcmQ6*/); $sPass = $SASL->challenge(''/*UGFzc3dvcmQ6*/);

View file

@ -13,6 +13,11 @@ abstract class SASL
return null; return null;
} }
public function hasChallenge() : bool
{
return false;
}
public function verify(string $data) : bool public function verify(string $data) : bool
{ {
return false; return false;

View file

@ -89,6 +89,11 @@ class Scram extends \SnappyMail\SASL
return $this->encode("{$cfmb},p={$proof}"); return $this->encode("{$cfmb},p={$proof}");
} }
public function hasChallenge() : bool
{
return true;
}
public function verify(string $data) : bool public function verify(string $data) : bool
{ {
$v = static::parseMessage($this->decode($data)); $v = static::parseMessage($this->decode($data));