From 7cacc9b503cfa2b7e7ace2e05c699f52462270b6 Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Tue, 27 Feb 2024 11:03:36 +0100 Subject: [PATCH] Make better use of SnappyMail\SensitiveString --- .../snappymail/lib/Util/SnappyMailHelper.php | 6 ++-- .../libraries/RainLoop/Actions/Accounts.php | 6 ++-- .../RainLoop/Actions/AdminDomains.php | 4 +-- .../libraries/RainLoop/Actions/Messages.php | 7 ++--- .../app/libraries/RainLoop/Actions/Pgp.php | 17 +++++----- .../app/libraries/RainLoop/Actions/SMime.php | 12 +++---- .../app/libraries/RainLoop/Actions/User.php | 4 +-- .../libraries/RainLoop/Actions/UserAuth.php | 26 ++++++---------- .../app/libraries/RainLoop/ActionsAdmin.php | 24 ++++++-------- .../libraries/RainLoop/Config/Application.php | 19 +++--------- .../app/libraries/RainLoop/Model/Account.php | 31 +++++++------------ .../app/libraries/RainLoop/ServiceActions.php | 14 ++------- .../app/libraries/snappymail/gpg/base.php | 15 ++------- .../app/libraries/snappymail/gpg/pgp.php | 8 ++--- .../app/libraries/snappymail/pgp/gnupg.php | 20 +++--------- .../libraries/snappymail/sensitivestring.php | 9 +++++- .../snappymail/smime/certificate.php | 6 +--- .../libraries/snappymail/smime/openssl.php | 3 +- 18 files changed, 84 insertions(+), 147 deletions(-) diff --git a/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php b/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php index 1752da30a..721cdf86e 100644 --- a/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php +++ b/integrations/nextcloud/snappymail/lib/Util/SnappyMailHelper.php @@ -91,7 +91,6 @@ class SnappyMailHelper */ if ($doLogin && $aCredentials[1] && $aCredentials[2]) { try { - $oActions->Logger()->AddSecret($aCredentials[2]); $oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2]); if ($oAccount) { // Must be here due to bug #1241 @@ -202,9 +201,10 @@ class SnappyMailHelper return \SnappyMail\Crypt::EncryptUrlSafe($sPassword, $sSalt); } - public static function decodePassword(string $sPassword, string $sSalt)/* : mixed */ + public static function decodePassword(string $sPassword, string $sSalt) : ?\SnappyMail\SensitiveString { static::loadApp(); - return \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt); + $result = \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt); + return $result ? new \SnappyMail\SensitiveString($result) : $result; } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Accounts.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Accounts.php index 9de1db9f4..1fd3d2003 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Accounts.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Accounts.php @@ -81,7 +81,7 @@ trait Accounts $aAccounts = $this->GetAccounts($oMainAccount); $sEmail = \trim($this->GetActionParam('email', '')); - $sPassword = $this->GetActionParam('password', ''); + $oPassword = new \SnappyMail\SensitiveString($this->GetActionParam('password', '')); $sName = \trim($this->GetActionParam('name', '')); $bNew = !empty($this->GetActionParam('new', 1)); @@ -92,8 +92,8 @@ trait Accounts throw new ClientException(Notifications::AccountDoesNotExist); } - if ($bNew || $sPassword) { - $oNewAccount = $this->LoginProcess($sEmail, $sPassword, false); + if ($bNew || \strlen($oPassword)) { + $oNewAccount = $this->LoginProcess($sEmail, $oPassword, false); $aAccounts[$sEmail] = $oNewAccount->asTokenArray($oMainAccount); } else { $aAccounts[$sEmail] = \RainLoop\Model\AdditionalAccount::convertArray($aAccounts[$sEmail]); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/AdminDomains.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/AdminDomains.php index c7b1bc35d..c917f3bbf 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/AdminDomains.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/AdminDomains.php @@ -60,9 +60,9 @@ trait AdminDomains public function DoAdminDomainMatch() : array { $sEmail = $this->GetActionParam('username'); - $sPassword = '********'; + $oPassword = new \SnappyMail\SensitiveString('********'); $sLogin = ''; - $this->resolveLoginCredentials($sEmail, $sPassword, $sLogin); + $this->resolveLoginCredentials($sEmail, $oPassword, $sLogin); $oDomain = \str_contains($sEmail, '@') ? $this->DomainProvider()->Load(\MailSo\Base\Utils::GetDomainFromEmail($sEmail), true) : null; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php index 3f6c4f163..61c847220 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php @@ -1065,8 +1065,7 @@ trait Messages } } - $sPassphrase = $this->GetActionParam('signPassphrase', ''); - $this->logMask($sPassphrase); + $oPassphrase = new \SnappyMail\SensitiveString($this->GetActionParam('signPassphrase', '')); $sFingerprint = $this->GetActionParam('signFingerprint', ''); if ($sFingerprint) { @@ -1084,7 +1083,7 @@ trait Messages $oMessage->SubParts->Clear(); $oMessage->Attachments()->Clear(); - $GPG->addSignKey($sFingerprint, $sPassphrase); + $GPG->addSignKey($sFingerprint, $oPassphrase); $GPG->setsignmode(GNUPG_SIG_MODE_DETACH); $sSignature = $GPG->signStream($fp); if (!$sSignature) { @@ -1127,7 +1126,7 @@ trait Messages $SMIME = $this->SMIME(); $SMIME->setCertificate($sCertificate); - $SMIME->setPrivateKey($sPrivateKey, $sPassphrase); + $SMIME->setPrivateKey($sPrivateKey, $oPassphrase); $sSignature = $SMIME->sign($tmp, $detached); if (!$sSignature) { diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Pgp.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Pgp.php index fd0e38158..ac427165f 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Pgp.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Pgp.php @@ -113,10 +113,9 @@ trait Pgp return $this->FalseResponse(); } - $sPassphrase = $this->GetActionParam('passphrase', ''); - $this->logMask($sPassphrase); + $oPassphrase = new \SnappyMail\SensitiveString($this->GetActionParam('passphrase', '')); - $GPG->addDecryptKey($this->GetActionParam('keyId', ''), $sPassphrase); + $GPG->addDecryptKey($this->GetActionParam('keyId', ''), $oPassphrase); $sData = $this->GetActionParam('data', ''); $oPart = null; @@ -160,12 +159,13 @@ trait Pgp public function DoGnupgExportKey() : array { - $sPassphrase = $this->GetActionParam('passphrase', ''); - $this->logMask($sPassphrase); + $oPassphrase = $this->GetActionParam('isPrivate', '') + ? new \SnappyMail\SensitiveString($this->GetActionParam('passphrase', '')) + : null; $GPG = $this->GnuPG(); return $this->DefaultResponse($GPG ? $GPG->export( $this->GetActionParam('keyId', ''), - $sPassphrase + $oPassphrase ) : false); } @@ -176,11 +176,10 @@ trait Pgp if ($GPG) { $sName = $this->GetActionParam('name', ''); $sEmail = $this->GetActionParam('email', ''); - $sPassphrase = $this->GetActionParam('passphrase', ''); - $this->logMask($sPassphrase); + $oPassphrase = new \SnappyMail\SensitiveString($this->GetActionParam('passphrase', '')); $fingerprint = $GPG->generateKey( $sName ? "{$sName} <{$sEmail}>" : $sEmail, - $sPassphrase + $oPassphrase ); } return $this->DefaultResponse($fingerprint); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php index 5068679ea..75e35e5d2 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php @@ -53,19 +53,18 @@ trait SMime } /** - * Can be use by Identity + * Can be used by Identity */ public function DoSMimeCreateCertificate() : array { $oAccount = $this->getAccountFromToken(); - $sPassphrase = $this->GetActionParam('passphrase', ''); - $this->logMask($sPassphrase); + $oPassphrase = new \SnappyMail\SensitiveString($this->GetActionParam('passphrase', '')); $cert = new Certificate(); $cert->distinguishedName['commonName'] = $this->GetActionParam('name', '') ?: $oAccount->Name(); $cert->distinguishedName['emailAddress'] = $this->GetActionParam('email', '') ?: $oAccount->Email(); - $result = $cert->createSelfSigned($sPassphrase, $this->GetActionParam('privateKey', '')); + $result = $cert->createSelfSigned($oPassphrase, $this->GetActionParam('privateKey', '')); return $this->DefaultResponse($result ?: false); } @@ -76,8 +75,7 @@ trait SMime $sPartId = $this->GetActionParam('partId', ''); $sCertificate = $this->GetActionParam('certificate', ''); $sPrivateKey = $this->GetActionParam('privateKey', ''); - $sPassphrase = $this->GetActionParam('passphrase', ''); - $this->logMask($sPassphrase); + $oPassphrase = new \SnappyMail\SensitiveString($this->GetActionParam('passphrase', '')); $this->initMailClientConnection(); $oImapClient = $this->ImapClient(); @@ -104,7 +102,7 @@ trait SMime $SMIME = $this->SMIME(); $SMIME->setCertificate($sCertificate); - $SMIME->setPrivateKey($sPrivateKey, $sPassphrase); + $SMIME->setPrivateKey($sPrivateKey, $oPassphrase); $result = $SMIME->decrypt($sBody); return $this->DefaultResponse($result ?: false); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/User.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/User.php index 8a15f8bcf..91ff9775f 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/User.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/User.php @@ -36,10 +36,10 @@ trait User public function DoLogin() : array { $sEmail = \MailSo\Base\Utils::Trim($this->GetActionParam('Email', '')); - $sPassword = $this->GetActionParam('Password', ''); + $oPassword = new \SnappyMail\SensitiveString($this->GetActionParam('Password', '')); try { - $oAccount = $this->LoginProcess($sEmail, $sPassword); + $oAccount = $this->LoginProcess($sEmail, $oPassword); } catch (\Throwable $oException) { $this->loginErrorDelay(); throw $oException; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/UserAuth.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/UserAuth.php index fc93974b9..89b72d1a8 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/UserAuth.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/UserAuth.php @@ -22,10 +22,7 @@ trait UserAuth /** * @throws \RainLoop\Exceptions\ClientException */ - public function resolveLoginCredentials(string &$sEmail, - #[\SensitiveParameter] - string &$sPassword, - string &$sLogin): void + public function resolveLoginCredentials(string &$sEmail, \SnappyMail\SensitiveString $oPassword, string &$sLogin): void { $sEmail = \MailSo\Base\Utils::Trim($sEmail); if ($this->Config()->Get('login', 'login_lowercase', true)) { @@ -101,43 +98,40 @@ trait UserAuth } } + $sPassword = (string) $oPassword; $this->Plugins()->RunHook('login.credentials.step-2', array(&$sEmail, &$sPassword)); + $this->logMask($sPassword); $sLogin = $sEmail; if ($this->Config()->Get('login', 'login_lowercase', true)) { $sLogin = \mb_strtolower($sLogin); } - $this->logMask($sPassword); $this->Plugins()->RunHook('login.credentials', array(&$sEmail, &$sLogin, &$sPassword)); $this->logMask($sPassword); + + $oPassword->setValue($sPassword); } /** * @throws \RainLoop\Exceptions\ClientException */ - public function LoginProcess(string &$sEmail, - #[\SensitiveParameter] - string &$sPassword, - bool $bMainAccount = true - ): Account + public function LoginProcess(string &$sEmail, \SnappyMail\SensitiveString $oPassword, bool $bMainAccount = true): Account { $sInputEmail = $sEmail; - $this->logMask($sPassword); - $sLogin = ''; - $this->resolveLoginCredentials($sEmail, $sPassword, $sLogin); + $this->resolveLoginCredentials($sEmail, $oPassword, $sLogin); - if (!\str_contains($sEmail, '@') || !\strlen($sPassword)) { + if (!\str_contains($sEmail, '@') || !\strlen($oPassword)) { throw new ClientException(Notifications::InvalidInputArgument); } $oAccount = null; try { $oAccount = $bMainAccount - ? MainAccount::NewInstanceFromCredentials($this, $sEmail, $sLogin, $sPassword, true) - : AdditionalAccount::NewInstanceFromCredentials($this, $sEmail, $sLogin, $sPassword, true); + ? MainAccount::NewInstanceFromCredentials($this, $sEmail, $sLogin, $oPassword, true) + : AdditionalAccount::NewInstanceFromCredentials($this, $sEmail, $sLogin, $oPassword, true); if (!$oAccount) { throw new ClientException(Notifications::AuthError); } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php index eed8be6f1..757169491 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php @@ -111,17 +111,15 @@ class ActionsAdmin extends Actions public function DoAdminLogin() : array { $sLogin = trim($this->GetActionParam('Login', '')); - $sPassword = $this->GetActionParam('Password', ''); - - $this->logMask($sPassword); + $oPassword = new \SnappyMail\SensitiveString($this->GetActionParam('Password', '')); $totp = $this->Config()->Get('security', 'admin_totp', ''); // \explode(':',`getent shadow root`)[1]; - if (!\strlen($sLogin) || !\strlen($sPassword) || + if (!\strlen($sLogin) || !\strlen($oPassword) || !$this->Config()->Get('security', 'allow_admin_panel', true) || $sLogin !== $this->Config()->Get('security', 'admin_login', '') || - !$this->Config()->ValidatePassword($sPassword) + !$this->Config()->ValidatePassword($oPassword) || ($totp && !\SnappyMail\TOTP::Verify($totp, $this->GetActionParam('TOTP', '')))) { $this->LoggerAuthHelper(null, $this->getAdditionalLogParamsByUserLogin($sLogin, true), true); @@ -183,17 +181,13 @@ class ActionsAdmin extends Actions $bResult = false; $oConfig = $this->Config(); - $sPassword = $this->GetActionParam('Password', ''); - $this->logMask($sPassword); + $oPassword = new \SnappyMail\SensitiveString($this->GetActionParam('Password', '')); - $sNewPassword = $this->GetActionParam('newPassword', ''); - if (\strlen($sNewPassword)) { - $this->logMask($sNewPassword); - } + $oNewPassword = new \SnappyMail\SensitiveString($this->GetActionParam('newPassword', '')); $passfile = APP_PRIVATE_DATA.'admin_password.txt'; - if ($oConfig->ValidatePassword($sPassword)) { + if ($oConfig->ValidatePassword($oPassword)) { $sLogin = \trim($this->GetActionParam('Login', '')); if (\strlen($sLogin)) { $oConfig->Set('security', 'admin_login', $sLogin); @@ -201,9 +195,9 @@ class ActionsAdmin extends Actions $oConfig->Set('security', 'admin_totp', $this->GetActionParam('TOTP', '')); - if (\strlen($sNewPassword)) { - $oConfig->SetPassword($sNewPassword); - if (\is_file($passfile) && \trim(\file_get_contents($passfile)) !== $sNewPassword) { + if (\strlen($oNewPassword)) { + $oConfig->SetPassword($oNewPassword); + if (\is_file($passfile) && \trim(\file_get_contents($passfile)) !== (string) $oNewPassword) { \unlink($passfile); } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php index 8ee4d7fdd..e27f7dd20 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Config/Application.php @@ -120,25 +120,14 @@ class Application extends \RainLoop\Config\AbstractConfig parent::Set($sSectionKey, $sParamKey, $mParamValue); } - public function SetPassword( - #[\SensitiveParameter] - string $sPassword - ) : void + public function SetPassword(\SnappyMail\SensitiveString $oPassword) : void { - $this->Set('security', 'admin_password', \password_hash($sPassword, PASSWORD_DEFAULT)); + $this->Set('security', 'admin_password', \password_hash($oPassword, PASSWORD_DEFAULT)); } - public function ValidatePassword( - #[\SensitiveParameter] - string $sPassword - ) : bool + public function ValidatePassword(\SnappyMail\SensitiveString $oPassword) : bool { - $sConfigPassword = (string) $this->Get('security', 'admin_password', ''); - if (32 == \strlen($sPassword) && \md5(APP_SALT.$sPassword.APP_SALT) === $sConfigPassword) { - $this->SetPassword($sPassword); - return true; - } - return \strlen($sPassword) && \password_verify($sPassword, $sConfigPassword); + return \strlen($oPassword) && \password_verify($oPassword, $this->Get('security', 'admin_password', '')); } public function Save() : bool diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Model/Account.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Model/Account.php index 05564db93..f2b9ad8b2 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Model/Account.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Model/Account.php @@ -15,7 +15,7 @@ abstract class Account implements \JsonSerializable private string $sLogin = ''; - private ?SensitiveString $sPassword = null; + private ?SensitiveString $oPassword = null; private string $sSmtpLogin = ''; @@ -46,7 +46,7 @@ abstract class Account implements \JsonSerializable public function IncPassword() : string { - return $this->sPassword ? $this->sPassword->getValue() : ''; + return $this->oPassword ? $this->oPassword->getValue() : ''; } public function OutLogin() : string @@ -66,16 +66,13 @@ abstract class Account implements \JsonSerializable $this->sEmail, $this->sLogin, // \json_encode($this->Domain()), -// $this->sPassword +// $this->oPassword ])); } - public function SetPassword( - #[\SensitiveParameter] - string $sPassword - ) : void + public function SetPassword(SensitiveString $oPassword) : void { - $this->sPassword = new SensitiveString($sPassword); + $this->oPassword = $oPassword; } public function SetSmtpPassword( @@ -125,12 +122,11 @@ abstract class Account implements \JsonSerializable public static function NewInstanceFromCredentials(\RainLoop\Actions $oActions, string $sEmail, string $sLogin, - #[\SensitiveParameter] - string $sPassword, + SensitiveString $oPassword, bool $bThrowException = false): ?self { $oAccount = null; - if ($sEmail && $sLogin && $sPassword) { + if ($sEmail && $sLogin && \strlen($oPassword)) { $oDomain = $oActions->DomainProvider()->Load(\MailSo\Base\Utils::GetDomainFromEmail($sEmail), true); if ($oDomain) { if ($oDomain->ValidateWhiteList($sEmail, $sLogin)) { @@ -138,7 +134,7 @@ abstract class Account implements \JsonSerializable $oAccount->sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true); $oAccount->sLogin = \MailSo\Base\Utils::IdnToAscii($sLogin); - $oAccount->SetPassword($sPassword); + $oAccount->SetPassword($oPassword); $oAccount->oDomain = $oDomain; $oActions->Plugins()->RunHook('filter.account', array($oAccount)); @@ -194,25 +190,22 @@ abstract class Account implements \JsonSerializable $oActions, $aAccountHash['email'], $aAccountHash['login'], - $aAccountHash['pass'], + new SensitiveString($aAccountHash['pass']), $bThrowExceptionOnFalse ); if ($oAccount) { if (isset($aAccountHash['name'])) { $oAccount->sName = $aAccountHash['name']; } - $oActions->logMask($oAccount->IncPassword()); // init smtp user/password if (isset($aAccountHash['smtp'])) { $oAccount->sSmtpLogin = $aAccountHash['smtp']['user']; $oAccount->SetSmtpPassword($aAccountHash['smtp']['pass']); - $oActions->logMask($oAccount->sSmtpPassword); } // init proxy user/password if (isset($aAccountHash['proxy'])) { $oAccount->sProxyAuthUser = $aAccountHash['proxy']['user']; $oAccount->SetProxyAuthPassword($aAccountHash['proxy']['pass']); - $oActions->logMask($oAccount->sProxyAuthPassword); } } } @@ -240,7 +233,7 @@ abstract class Account implements \JsonSerializable $oImapClient->Connect($oSettings); $oPlugins->RunHook('imap.after-connect', array($this, $oImapClient, $oSettings)); - $oSettings->Password = $this->sPassword; + $oSettings->Password = $this->oPassword; return $this->netClientLogin($oImapClient, $oPlugins); } @@ -264,7 +257,7 @@ abstract class Account implements \JsonSerializable throw new RequireCredentialsException } */ - $oSettings->Password = $this->sSmtpPassword ?: $this->sPassword; + $oSettings->Password = $this->sSmtpPassword ?: $this->oPassword; return $this->netClientLogin($oSmtpClient, $oPlugins); } @@ -279,7 +272,7 @@ abstract class Account implements \JsonSerializable $oSieveClient->Connect($oSettings); $oPlugins->RunHook('sieve.after-connect', array($this, $oSieveClient, $oSettings)); - $oSettings->Password = $this->sPassword; + $oSettings->Password = $this->oPassword; return $this->netClientLogin($oSieveClient, $oPlugins); } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php index a4986f70f..f88ccc374 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php @@ -120,16 +120,6 @@ class ServiceActions $aPost[$key] = '*******'; } } -/* - switch ($sMethodName) - { - case 'DoLogin': - case 'DoAdminLogin': - case 'DoAccountAdd': - $this->oActions->logMask($this->oActions->GetActionParam('Password', '')); - break; - } -*/ $this->oActions->logWrite(Utils::jsonEncode($aPost), \LOG_INFO, 'POST'); } else if (3 < \count($this->aPaths) && $this->oHttp->IsGet()) { $this->oActions->SetActionParams(array( @@ -561,14 +551,14 @@ class ServiceActions (0 === $aData['Time'] || \time() - 10 < $aData['Time'])) { $sEmail = \trim($aData['Email']); - $sPassword = $aData['Password']; + $oPassword = new \SnappyMail\SensitiveString($aData['Password']); $aAdditionalOptions = (isset($aData['AdditionalOptions']) && \is_array($aData['AdditionalOptions'])) ? $aData['AdditionalOptions'] : []; try { - $oAccount = $this->oActions->LoginProcess($sEmail, $sPassword); + $oAccount = $this->oActions->LoginProcess($sEmail, $oPassword); if ($aAdditionalOptions) { $bNeedToSettings = false; diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/gpg/base.php b/snappymail/v/0.0.0/app/libraries/snappymail/gpg/base.php index 858270ed1..3436e2339 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/gpg/base.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/gpg/base.php @@ -284,10 +284,7 @@ abstract class Base /** * Add a key for decryption */ - public function addDecryptKey(string $fingerprint, - #[\SensitiveParameter] - string $passphrase - ) : bool + public function addDecryptKey(string $fingerprint, \SnappyMail\SensitiveString $passphrase) : bool { $this->decryptKeys[$fingerprint] = $passphrase; // $this->decryptKeys[\substr($fingerprint, -16)] = $passphrase; @@ -306,10 +303,7 @@ abstract class Base /** * Add a key for signing */ - public function addSignKey(string $fingerprint, - #[\SensitiveParameter] - string $passphrase - ) : bool + public function addSignKey(string $fingerprint, \SnappyMail\SensitiveString $passphrase) : bool { $this->signKeys[$fingerprint] = $passphrase; // $this->signKeys[\substr($fingerprint, -16)] = $passphrase; @@ -356,10 +350,7 @@ abstract class Base ]; } - public function addPassphrase($keyId, - #[\SensitiveParameter] - $passphrase - ) + public function addPassphrase($keyId, \SnappyMail\SensitiveString $passphrase) { $this->passphrases[$keyId] = $passphrase; return $this; diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/gpg/pgp.php b/snappymail/v/0.0.0/app/libraries/snappymail/gpg/pgp.php index af80bac23..eef6ab062 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/gpg/pgp.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/gpg/pgp.php @@ -95,7 +95,7 @@ class PGP extends Base $fclose = $this->setOutput($output); if ($this->decryptKeys) { - $_ENV['PINENTRY_USER_DATA'] = \json_encode($this->decryptKeys); + $_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->decryptKeys)); } $result = $this->exec(['--decrypt','--skip-verify']); @@ -241,7 +241,7 @@ class PGP extends Base throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId); } if ($private && $this->passphrases) { - $_ENV['PINENTRY_USER_DATA'] = \json_encode($this->passphrases); + $_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->passphrases)); } $result = $this->exec([ $private ? '--export-secret-keys' : '--export', @@ -362,7 +362,7 @@ class PGP extends Base $arguments = ['--import']; if ($this->passphrases) { - $_ENV['PINENTRY_USER_DATA'] = \json_encode($this->passphrases); + $_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->passphrases)); } else { $arguments[] = '--batch'; } @@ -629,7 +629,7 @@ class PGP extends Base foreach ($this->signKeys as $fingerprint => $pass) { $arguments[] = '--local-user ' . \escapeshellarg($fingerprint); } - $_ENV['PINENTRY_USER_DATA'] = \json_encode($this->signKeys); + $_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->signKeys)); } $result = $this->exec($arguments); diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/pgp/gnupg.php b/snappymail/v/0.0.0/app/libraries/snappymail/pgp/gnupg.php index c744d0ac5..799d15142 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/pgp/gnupg.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/pgp/gnupg.php @@ -86,10 +86,7 @@ class GnuPG /** * Add a key for decryption */ - public function addDecryptKey(string $fingerprint, - #[\SensitiveParameter] - string $passphrase - ) : bool + public function addDecryptKey(string $fingerprint, \SnappyMail\SensitiveString $passphrase) : bool { return $this->handler()->adddecryptkey($fingerprint, $passphrase); } @@ -105,10 +102,7 @@ class GnuPG /** * Add a key for signing */ - public function addSignKey(string $fingerprint, - #[\SensitiveParameter] - ?string $passphrase - ) : bool + public function addSignKey(string $fingerprint, \SnappyMail\SensitiveString $passphrase) : bool { return $this->handler()->addsignkey($fingerprint, $passphrase); } @@ -226,10 +220,7 @@ class GnuPG /** * Exports a key */ - public function export(string $fingerprint, - #[\SensitiveParameter] - string $passphrase = '' - ) /*: string|false*/ + public function export(string $fingerprint, ?\SnappyMail\SensitiveString $passphrase = null) /*: string|false*/ { if ($passphrase) { return $this->getGPG() @@ -276,10 +267,7 @@ class GnuPG /** * Generates a key */ - public function generateKey(string $uid, - #[\SensitiveParameter] - string $passphrase - ) /*: string|false*/ + public function generateKey(string $uid, \SnappyMail\SensitiveString $passphrase) /*: string|false*/ { $GPG = $this->getGPG(false); return $GPG ? $GPG->generateKey($uid, $passphrase) : false; diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/sensitivestring.php b/snappymail/v/0.0.0/app/libraries/snappymail/sensitivestring.php index 420725e4e..bac6afb17 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/sensitivestring.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/sensitivestring.php @@ -2,7 +2,7 @@ namespace SnappyMail; -class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */ implements \Stringable +class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */ implements \Stringable, \JsonSerializable { private string $value, $nonce; private static ?string $key = null; @@ -28,6 +28,7 @@ class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */ string $value ) : void { + \strlen($value) && \RainLoop\Api::Actions()->logMask($value); if (\is_callable('sodium_crypto_secretbox')) { $this->nonce = \random_bytes(\SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); if (!static::$key) { @@ -60,6 +61,12 @@ class SensitiveString /* extends SensitiveParameterValue | SensitiveParameter */ return $this->getValue(); } + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + throw new \Exception("JSON serialization of 'SnappyMail\\SensitiveString' is not allowed"); + } + public function __debugInfo(): array { return []; diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/smime/certificate.php b/snappymail/v/0.0.0/app/libraries/snappymail/smime/certificate.php index b897fbd85..2a12ba905 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/smime/certificate.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/smime/certificate.php @@ -112,11 +112,7 @@ class Certificate return \openssl_get_cipher_methods($aliases); } - public function createSelfSigned( - #[\SensitiveParameter] - string $passphrase = '', - ?string $privateKey = null - ) : array + public function createSelfSigned(\SnappyMail\SensitiveString $passphrase, ?string $privateKey = null) : array { $options = array( 'config' => __DIR__ . '/openssl.cnf', diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php b/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php index 9b8fbbbc3..235ba7cfb 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php @@ -132,8 +132,7 @@ class OpenSSL } public function setPrivateKey(/*OpenSSLAsymmetricKey|string*/$privateKey, - #[\SensitiveParameter] - ?string $passphrase = null + ?\SnappyMail\SensitiveString $passphrase = null ) : void { $this->privateKey = \openssl_pkey_get_private($privateKey, $passphrase);