mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-08 22:18:28 +03:00
Improved GnuPG error handling
This commit is contained in:
parent
c73e3637a3
commit
3d176d4e4f
9 changed files with 110 additions and 56 deletions
|
|
@ -69,10 +69,10 @@ export const GnuPGUserStore = new class {
|
|||
}
|
||||
};
|
||||
if (isPrivate) {
|
||||
key.password = async (btnTxt = 'SIGN') => {
|
||||
key.password = async (btnTxt = 'CRYPTO/SIGN') => {
|
||||
const pass = await Passphrases.ask(key,
|
||||
'GnuPG key<br>' + key.id + ' ' + key.emails[0],
|
||||
'OPENPGP/'+btnTxt
|
||||
btnTxt
|
||||
);
|
||||
pass && pass.remember && Passphrases.set(key, pass.password);
|
||||
return pass?.password;
|
||||
|
|
@ -82,7 +82,7 @@ export const GnuPGUserStore = new class {
|
|||
if (key.armor) {
|
||||
callback && callback();
|
||||
} else {
|
||||
let pass = isPrivate ? await key.password('POPUP_VIEW_TITLE') : '';
|
||||
let pass = isPrivate ? await key.password('OPENPGP/POPUP_VIEW_TITLE') : '';
|
||||
if (null != pass) try {
|
||||
const result = await Remote.post('GnupgExportKey', null, {
|
||||
keyId: key.id,
|
||||
|
|
@ -184,15 +184,20 @@ export const GnuPGUserStore = new class {
|
|||
uid: message.uid,
|
||||
partId: pgpInfo.partId,
|
||||
keyId: key.id,
|
||||
passphrase: await key.password('DECRYPT'),
|
||||
passphrase: await key.password('CRYPTO/DECRYPT'),
|
||||
data: '' // message.plain() optional
|
||||
}
|
||||
if (null !== params.passphrase) {
|
||||
const result = await Remote.post('GnupgDecrypt', null, params);
|
||||
if (result?.Result?.data) {
|
||||
return result.Result;
|
||||
if (null != params.passphrase) {
|
||||
try {
|
||||
const response = await Remote.post('GnupgDecrypt', null, params);
|
||||
if (response?.Result?.data) {
|
||||
return response.Result;
|
||||
}
|
||||
throw response;
|
||||
} catch (e) {
|
||||
Passphrases.delete(key);
|
||||
throw e;
|
||||
}
|
||||
Passphrases.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -587,10 +587,13 @@ export class MailMessageView extends AbstractViewRight {
|
|||
}
|
||||
} else {
|
||||
// TODO: translate
|
||||
alert('Decryption failed, canceled or not possible');
|
||||
throw 'Decryption failed, canceled or not possible';
|
||||
}
|
||||
})
|
||||
.catch(e => console.error(e));
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
alert(e.message);
|
||||
});
|
||||
}
|
||||
|
||||
pgpVerify(/*self, event*/) {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ trait Pgp
|
|||
$sData = $this->GetActionParam('data', '');
|
||||
$oPart = null;
|
||||
$result = [
|
||||
'data' => '',
|
||||
'data' => null,
|
||||
'signatures' => []
|
||||
];
|
||||
if ($sData) {
|
||||
|
|
@ -130,11 +130,13 @@ trait Pgp
|
|||
$this->initMailClientConnection();
|
||||
$this->MailClient()->MessageMimeStream(
|
||||
function ($rResource) use ($GPG, &$result, &$oPart) {
|
||||
if (\is_resource($rResource)) {
|
||||
if (\is_resource($rResource)) try {
|
||||
$result['data'] = $GPG->decryptStream($rResource);
|
||||
// $oPart = \MailSo\Mime\Part::FromString($result);
|
||||
// $GPG->decryptStream($rResource, $rStreamHandle);
|
||||
// $oPart = \MailSo\Mime\Part::FromStream($rStreamHandle);
|
||||
} catch (\Throwable $e) {
|
||||
$result = $e;
|
||||
}
|
||||
},
|
||||
$this->GetActionParam('folder', ''),
|
||||
|
|
@ -148,6 +150,10 @@ trait Pgp
|
|||
// $result['signatures'] = $oPart->SubParts[0];
|
||||
}
|
||||
|
||||
if ($result instanceof \Throwable) {
|
||||
throw $result;
|
||||
}
|
||||
|
||||
return $this->DefaultResponse($result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,9 +45,10 @@ trait Response
|
|||
|
||||
public function ExceptionResponse(\Throwable $oException) : array
|
||||
{
|
||||
$iErrorCode = 0;
|
||||
$sErrorMessage = '';
|
||||
$iErrorCode = Notifications::UnknownError;
|
||||
$sErrorMessage = $oException->getMessage();
|
||||
$sErrorMessageAdditional = '';
|
||||
$iExceptionCode = 0;
|
||||
|
||||
if ($oException instanceof \RainLoop\Exceptions\ClientException) {
|
||||
$iErrorCode = $oException->getCode();
|
||||
|
|
@ -56,8 +57,7 @@ trait Response
|
|||
}
|
||||
$sErrorMessageAdditional = $oException->getAdditionalMessage();
|
||||
} else {
|
||||
$iErrorCode = Notifications::UnknownError;
|
||||
$sErrorMessage = $oException->getCode().' - '.$oException->getMessage();
|
||||
$iExceptionCode = $oException->getCode();
|
||||
}
|
||||
|
||||
$this->logException($oException->getPrevious() ?: $oException);
|
||||
|
|
@ -65,7 +65,8 @@ trait Response
|
|||
return $this->DefaultResponse(false, [
|
||||
'ErrorCode' => $iErrorCode,
|
||||
'ErrorMessage' => $sErrorMessage,
|
||||
'ErrorMessageAdditional' => $sErrorMessageAdditional
|
||||
'ErrorMessageAdditional' => $sErrorMessageAdditional,
|
||||
'ExceptionCode' => $iExceptionCode
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -114,14 +114,15 @@ class ServiceActions
|
|||
|
||||
if ($_POST) {
|
||||
$this->oActions->SetActionParams($_POST, $sMethodName);
|
||||
foreach ($_POST as $key => $value) {
|
||||
$aPost = $_POST;
|
||||
foreach ($aPost as $key => $value) {
|
||||
// password & passphrase
|
||||
if (false !== \stripos($key, 'pass')) {
|
||||
// $_POST[$key] = '*******';
|
||||
$this->oActions->logMask($value);
|
||||
$aPost[$key] = '*******';
|
||||
// $this->oActions->logMask($value);
|
||||
}
|
||||
}
|
||||
$this->oActions->logWrite(Utils::jsonEncode($_POST), \LOG_INFO, 'POST');
|
||||
$this->oActions->logWrite(Utils::jsonEncode($aPost), \LOG_INFO, 'POST');
|
||||
} else if (3 < \count($this->aPaths) && $this->oHttp->IsGet()) {
|
||||
$this->oActions->SetActionParams(array(
|
||||
'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3]
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ abstract class Base
|
|||
/**
|
||||
* Signs a given file
|
||||
*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: array|false*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: string|false*/
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -666,7 +666,7 @@ class PGP extends Base
|
|||
/**
|
||||
* Signs a given file
|
||||
*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: array|false*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: string|false*/
|
||||
{
|
||||
if (!$fp || !\is_resource($fp)) {
|
||||
throw new \Exception('Invalid stream resource');
|
||||
|
|
@ -674,7 +674,7 @@ class PGP extends Base
|
|||
return $this->_sign($fp, $output);
|
||||
}
|
||||
|
||||
protected function _verify($input, string $signature)
|
||||
protected function _verify($input, string $signature) /*: array|false*/
|
||||
{
|
||||
$arguments = ['--verify'];
|
||||
if ($signature) {
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ class SMIME extends Base
|
|||
/**
|
||||
* Signs a given file
|
||||
*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: array|false*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: string|false*/
|
||||
{
|
||||
if (!$fp || !\is_resource($fp)) {
|
||||
throw new \Exception('Invalid stream resource');
|
||||
|
|
@ -548,7 +548,7 @@ class SMIME extends Base
|
|||
return $this->_sign($fp, $output);
|
||||
}
|
||||
|
||||
protected function _verify($input, string $signature)
|
||||
protected function _verify($input, string $signature) /*: array|false*/
|
||||
{
|
||||
$arguments = ['--verify'];
|
||||
if ($signature) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class GnuPG
|
|||
]);
|
||||
// Output is ASCII
|
||||
$this->GnuPG->setarmor(1);
|
||||
\SnappyMail\Log::info('GnuPG', 'Using PECL');
|
||||
} else {
|
||||
$this->getGPG();
|
||||
}
|
||||
|
|
@ -52,6 +53,12 @@ class GnuPG
|
|||
*/
|
||||
}
|
||||
|
||||
function __destruct()
|
||||
{
|
||||
$this->clearDecryptKeys();
|
||||
$this->clearSignKeys();
|
||||
}
|
||||
|
||||
public static function isSupported() : bool
|
||||
{
|
||||
return \class_exists('gnupg') || GPG::isSupported();
|
||||
|
|
@ -71,11 +78,20 @@ class GnuPG
|
|||
return $this->GnuPG ?: $this->GPG;
|
||||
}
|
||||
|
||||
public function gnupgError()
|
||||
{
|
||||
$error = $this->GnuPG ? $this->GnuPG->geterrorinfo() : null;
|
||||
if ($error) {
|
||||
throw new \Exception("{$error['gpgme_source']} {$error['generic_message']}. {$error['gpgme_message']}", $error['gpgme_code']);
|
||||
}
|
||||
}
|
||||
|
||||
public function getGPG(bool $throw = true) : ?GPG
|
||||
{
|
||||
if (!$this->GPG) {
|
||||
if (GPG::isSupported()) {
|
||||
$this->GPG = new GPG($this->homedir);
|
||||
\SnappyMail\Log::info('GnuPG', 'Using ' . GPG::class);
|
||||
} else if ($throw) {
|
||||
throw new \Exception('GnuPG not supported');
|
||||
}
|
||||
|
|
@ -88,7 +104,9 @@ class GnuPG
|
|||
*/
|
||||
public function addDecryptKey(string $fingerprint, \SnappyMail\SensitiveString $passphrase) : bool
|
||||
{
|
||||
return $this->handler()->adddecryptkey($fingerprint, $passphrase);
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->adddecryptkey($fingerprint, \strval($passphrase)) || $this->gnupgError()
|
||||
: $this->GPG->addDecryptKey($fingerprint, $passphrase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -104,7 +122,9 @@ class GnuPG
|
|||
*/
|
||||
public function addSignKey(string $fingerprint, \SnappyMail\SensitiveString $passphrase) : bool
|
||||
{
|
||||
return $this->handler()->addsignkey($fingerprint, $passphrase);
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->addsignkey($fingerprint, \strval($passphrase)) || $this->gnupgError()
|
||||
: $this->GPG->addSignKey($fingerprint, $passphrase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -136,9 +156,12 @@ class GnuPG
|
|||
*/
|
||||
public function decrypt(string $text) /*: string|false */
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->decrypt($text)
|
||||
: $this->GPG->decrypt($text);
|
||||
if ($this->GnuPG) {
|
||||
$result = $this->GnuPG->decrypt($text);
|
||||
(false === $result) && $this->gnupgError();
|
||||
return $result;
|
||||
}
|
||||
return $this->GPG->decrypt($text);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,9 +169,12 @@ class GnuPG
|
|||
*/
|
||||
public function decryptFile(string $filename) /*: string|false */
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->decrypt(\file_get_contents($filename))
|
||||
: $this->GPG->decryptFile($filename);
|
||||
if ($this->GnuPG) {
|
||||
$result = $this->GnuPG->decrypt(\file_get_contents($filename));
|
||||
(false === $result) && $this->gnupgError();
|
||||
return $result;
|
||||
}
|
||||
return $this->GPG->decryptFile($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,9 +185,12 @@ class GnuPG
|
|||
if (!$fp || !\is_resource($fp)) {
|
||||
throw new \Exception('Invalid stream resource');
|
||||
}
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->decrypt(\stream_get_contents($fp))
|
||||
: $this->GPG->decryptStream($fp, $output);
|
||||
if ($this->GnuPG) {
|
||||
$result = $this->GnuPG->decrypt(\stream_get_contents($fp));
|
||||
(false === $result) && $this->gnupgError();
|
||||
return $result;
|
||||
}
|
||||
return $this->GPG->decryptStream($fp, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -169,9 +198,12 @@ class GnuPG
|
|||
*/
|
||||
public function decryptVerify(string $text, string &$plaintext) /*: array|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->decryptverify($text, $plaintext)
|
||||
: $this->GPG->decryptverify($text, $plaintext);
|
||||
if ($this->GnuPG) {
|
||||
$result = $this->GnuPG->decryptverify($text, $plaintext);
|
||||
(false === $result) && $this->gnupgError();
|
||||
return $result;
|
||||
}
|
||||
return $this->GPG->decryptverify($text, $plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -179,9 +211,12 @@ class GnuPG
|
|||
*/
|
||||
public function decryptVerifyFile(string $filename, string &$plaintext) /*: array|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->decryptverify(\file_get_contents($filename), $plaintext)
|
||||
: $this->GPG->decryptverifyFile($filename, $plaintext);
|
||||
if ($this->GnuPG) {
|
||||
$result = $this->GnuPG->decryptverify(\file_get_contents($filename), $plaintext);
|
||||
(false === $result) && $this->gnupgError();
|
||||
return $result;
|
||||
}
|
||||
return $this->GPG->decryptverifyFile($filename, $plaintext);
|
||||
}
|
||||
|
||||
public function deleteKey(string $keyId, bool $private) : bool
|
||||
|
|
@ -195,7 +230,7 @@ class GnuPG
|
|||
public function encrypt(string $plaintext) /*: string|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->encrypt($plaintext)
|
||||
? $this->GnuPG->encrypt($plaintext) ?: $this->gnupgError()
|
||||
: $this->GPG->encrypt($plaintext);
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +240,7 @@ class GnuPG
|
|||
public function encryptFile(string $filename) /*: string|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->encrypt(\file_get_contents($filename))
|
||||
? $this->GnuPG->encrypt(\file_get_contents($filename)) ?: $this->gnupgError()
|
||||
: $this->GPG->encryptFile($filename);
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +248,7 @@ class GnuPG
|
|||
{
|
||||
\rewind($fp);
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->encrypt(\stream_get_contents($fp))
|
||||
? $this->GnuPG->encrypt(\stream_get_contents($fp)) ?: $this->gnupgError()
|
||||
: $this->GPG->encryptStream($fp);
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +263,7 @@ class GnuPG
|
|||
->exportPrivateKey($fingerprint);
|
||||
}
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->export($fingerprint)
|
||||
? $this->GnuPG->export($fingerprint) ?: $this->gnupgError()
|
||||
: $this->GPG->export($fingerprint);
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +322,7 @@ class GnuPG
|
|||
public function importFile(string $filename) /*: array|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->import(\file_get_contents($filename))
|
||||
? $this->GnuPG->import(\file_get_contents($filename)) ?: $this->gnupgError()
|
||||
: $this->GPG->importFile($filename);
|
||||
}
|
||||
|
||||
|
|
@ -350,7 +385,7 @@ class GnuPG
|
|||
public function sign(string $plaintext) /*: string|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->sign($plaintext)
|
||||
? $this->GnuPG->sign($plaintext) ?: $this->gnupgError()
|
||||
: $this->GPG->sign($plaintext);
|
||||
}
|
||||
|
||||
|
|
@ -360,18 +395,18 @@ class GnuPG
|
|||
public function signFile(string $filename) /*: string|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->sign(\file_get_contents($filename))
|
||||
? $this->GnuPG->sign(\file_get_contents($filename)) ?: $this->gnupgError()
|
||||
: $this->GPG->signFile($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a given file
|
||||
*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: array|false*/
|
||||
public function signStream($fp, /*string|resource*/ $output = null) /*: string|false*/
|
||||
{
|
||||
\rewind($fp);
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->sign(\stream_get_contents($fp))
|
||||
? $this->GnuPG->sign(\stream_get_contents($fp)) ?: $this->gnupgError()
|
||||
: $this->GPG->signStream($fp);
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +416,7 @@ class GnuPG
|
|||
public function verify(string $signed_text, string $signature, string &$plaintext = null) /*: array|false*/
|
||||
{
|
||||
$result = $this->GnuPG
|
||||
? $this->GnuPG->verify($signed_text, $signature ?: false, $plaintext)
|
||||
? $this->GnuPG->verify($signed_text, $signature ?: false, $plaintext) ?: $this->gnupgError()
|
||||
: $this->GPG->verify($signed_text, $signature, $plaintext);
|
||||
if (!$result) {
|
||||
if ($this->GnuPG) {
|
||||
|
|
@ -400,18 +435,21 @@ class GnuPG
|
|||
public function verifyFile(string $filename, string $signature, string &$plaintext = null) /*: array|false*/
|
||||
{
|
||||
return $this->GnuPG
|
||||
? $this->GnuPG->verify(\file_get_contents($filename), $signature, $plaintext)
|
||||
? $this->GnuPG->verify(\file_get_contents($filename), $signature, $plaintext) ?: $this->gnupgError()
|
||||
: $this->GPG->verifyFile($filename, $signature, $plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a given resource
|
||||
*/
|
||||
public function verifyStream(/*resource*/ $fp, string $signature, string &$plaintext = null) /*: string|false */
|
||||
public function verifyStream(/*resource*/ $fp, string $signature, string &$plaintext = null) /*: array|false */
|
||||
{
|
||||
if (!$fp || !\is_resource($fp)) {
|
||||
throw new \Exception('Invalid stream resource');
|
||||
}
|
||||
// return $this->GnuPG
|
||||
// ? $this->GnuPG->verify(\stream_get_contents($fp), $signature, $plaintext) ?: $this->gnupgError()
|
||||
// : $this->GPG->verifyStream($fp, $signature, $plaintext);
|
||||
return $this->getGPG()->verifyStream($fp, $signature, $plaintext);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue