From 7ab9d1a980d02cb3505e0fb2e0e6ca0711c03d27 Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Mon, 12 Feb 2024 17:14:38 +0100 Subject: [PATCH] Workaround disabled ACL could cause "Disconnected: Too many invalid IMAP commands" #157 --- .../libraries/MailSo/Imap/Commands/ACL.php | 37 ++++++++++++++----- .../MailSo/Imap/Commands/Folders.php | 4 +- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/ACL.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/ACL.php index 6cd6ce4bb..264bf9329 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/ACL.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/ACL.php @@ -19,13 +19,24 @@ use MailSo\Imap\Responses\ACL as ACLResponse; */ trait ACL { + private $ACLDisabled = false; + /** * https://datatracker.ietf.org/doc/html/rfc4314#section-4 */ 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) { + // at least one of the "l", "r", "i", "k", "x", "a" rights is required return true; } $rights = $this->FolderMyRights($sFolderName); @@ -130,16 +141,22 @@ trait ACL { // if ($this->ACLAllow($sFolderName, 'MYRIGHTS')) { // if ($this->hasCapability('ACL')) { - $oResponses = $this->SendRequestGetResponse('MYRIGHTS', array($this->EscapeFolderName($sFolderName))); - foreach ($oResponses as $oResponse) { - if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType - && isset($oResponse->ResponseList[3]) - && 'MYRIGHTS' === $oResponse->ResponseList[1] - && $sFolderName === $oResponse->ResponseList[2] - ) - { - return static::aclRightsToClass(\array_slice($oResponse->ResponseList, 3)); + try { + $oResponses = $this->SendRequestGetResponse('MYRIGHTS', array($this->EscapeFolderName($sFolderName))); + foreach ($oResponses as $oResponse) { + if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType + && isset($oResponse->ResponseList[3]) + && 'MYRIGHTS' === $oResponse->ResponseList[1] + && $sFolderName === $oResponse->ResponseList[2] + ) + { + 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; } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php index c53a26e80..b53209e72 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/Commands/Folders.php @@ -575,12 +575,14 @@ trait Folders } } + // ACL RIGHTS=texk if ($this->hasCapability('ACL') || $this->CapabilityValue('RIGHTS')) { foreach ($oFolderCollection as $oFolder) { if ($oFolder->Selectable()) try { $oFolder->myRights = $this->FolderMyRights($oFolder->FullName); } catch (\Throwable $oException) { - // Ignore error + // BAD Error in IMAP command MYRIGHTS: ACLs disabled + break; } } }