Workaround disabled ACL could cause "Disconnected: Too many invalid IMAP commands" #157

This commit is contained in:
the-djmaze 2024-02-12 17:14:38 +01:00
parent 3c464cace5
commit 7ab9d1a980
2 changed files with 30 additions and 11 deletions

View file

@ -19,13 +19,24 @@ use MailSo\Imap\Responses\ACL as ACLResponse;
*/ */
trait ACL trait ACL
{ {
private $ACLDisabled = false;
/** /**
* https://datatracker.ietf.org/doc/html/rfc4314#section-4 * https://datatracker.ietf.org/doc/html/rfc4314#section-4
*/ */
public function ACLAllow(string $sFolderName, string $command) : bool public function ACLAllow(string $sFolderName, string $command) : bool
{ {
if ($this->hasCapability('ACL') || $this->CapabilityValue('RIGHTS')) { if ($this->ACLDisabled) {
return false;
}
// The "RIGHTS=" capability MUST NOT include any of the rights defined in RFC 2086:
// "l", "r", "s", "w", "i", "p", "a", "c", "d", and the digits ("0" .. "9")
// So it is: RIGHTS=texk
$mainRights = \str_split($this->CapabilityValue('RIGHTS') ?: '');
if ($this->hasCapability('ACL') || $mainRights) {
if ('MYRIGHTS' === $command) { if ('MYRIGHTS' === $command) {
// at least one of the "l", "r", "i", "k", "x", "a" rights is required
return true; return true;
} }
$rights = $this->FolderMyRights($sFolderName); $rights = $this->FolderMyRights($sFolderName);
@ -130,16 +141,22 @@ trait ACL
{ {
// if ($this->ACLAllow($sFolderName, 'MYRIGHTS')) { // if ($this->ACLAllow($sFolderName, 'MYRIGHTS')) {
// if ($this->hasCapability('ACL')) { // if ($this->hasCapability('ACL')) {
$oResponses = $this->SendRequestGetResponse('MYRIGHTS', array($this->EscapeFolderName($sFolderName))); try {
foreach ($oResponses as $oResponse) { $oResponses = $this->SendRequestGetResponse('MYRIGHTS', array($this->EscapeFolderName($sFolderName)));
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType foreach ($oResponses as $oResponse) {
&& isset($oResponse->ResponseList[3]) if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
&& 'MYRIGHTS' === $oResponse->ResponseList[1] && isset($oResponse->ResponseList[3])
&& $sFolderName === $oResponse->ResponseList[2] && 'MYRIGHTS' === $oResponse->ResponseList[1]
) && $sFolderName === $oResponse->ResponseList[2]
{ )
return static::aclRightsToClass(\array_slice($oResponse->ResponseList, 3)); {
return static::aclRightsToClass(\array_slice($oResponse->ResponseList, 3));
}
} }
} catch (\Throwable $oException) {
// \MailSo\Imap\Exceptions\NegativeResponseException: Error in IMAP command MYRIGHTS: ACLs disabled
$this->ACLDisabled = true;
throw $oException;
} }
return null; return null;
} }

View file

@ -575,12 +575,14 @@ trait Folders
} }
} }
// ACL RIGHTS=texk
if ($this->hasCapability('ACL') || $this->CapabilityValue('RIGHTS')) { if ($this->hasCapability('ACL') || $this->CapabilityValue('RIGHTS')) {
foreach ($oFolderCollection as $oFolder) { foreach ($oFolderCollection as $oFolder) {
if ($oFolder->Selectable()) try { if ($oFolder->Selectable()) try {
$oFolder->myRights = $this->FolderMyRights($oFolder->FullName); $oFolder->myRights = $this->FolderMyRights($oFolder->FullName);
} catch (\Throwable $oException) { } catch (\Throwable $oException) {
// Ignore error // BAD Error in IMAP command MYRIGHTS: ACLs disabled
break;
} }
} }
} }