mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Changes for #973
This commit is contained in:
parent
6e6ed0eab3
commit
ab77949e64
3 changed files with 96 additions and 60 deletions
|
|
@ -15,6 +15,8 @@ import { showScreenPopup } from 'Knoin/Knoin';
|
||||||
import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport';
|
import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport';
|
||||||
import { OpenPgpGeneratePopupView } from 'View/Popup/OpenPgpGenerate';
|
import { OpenPgpGeneratePopupView } from 'View/Popup/OpenPgpGenerate';
|
||||||
|
|
||||||
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
export class UserSettingsSecurity extends AbstractViewSettings {
|
export class UserSettingsSecurity extends AbstractViewSettings {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
@ -60,5 +62,11 @@ export class UserSettingsSecurity extends AbstractViewSettings {
|
||||||
* The iframe will be injected into the container identified by selector.
|
* The iframe will be injected into the container identified by selector.
|
||||||
*/
|
*/
|
||||||
window.mailvelope && mailvelope.createSettingsContainer('#mailvelope-settings'/*[, keyring], options*/);
|
window.mailvelope && mailvelope.createSettingsContainer('#mailvelope-settings'/*[, keyring], options*/);
|
||||||
|
/**
|
||||||
|
* https://github.com/the-djmaze/snappymail/issues/973
|
||||||
|
Remote.request('GetStoredPGPKeys', (iError, data) => {
|
||||||
|
console.dir([iError, data]);
|
||||||
|
});
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace RainLoop\Actions;
|
namespace RainLoop\Actions;
|
||||||
|
|
||||||
|
use SnappyMail\PGP\Backup;
|
||||||
|
|
||||||
trait Pgp
|
trait Pgp
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -191,35 +193,7 @@ trait Pgp
|
||||||
*/
|
*/
|
||||||
public function DoGetStoredPGPKeys() : array
|
public function DoGetStoredPGPKeys() : array
|
||||||
{
|
{
|
||||||
$oAccount = $this->getMainAccountFromToken();
|
return $this->DefaultResponse(\SnappyMail\PGP\Backup::getKeys());
|
||||||
if (!$oAccount) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$dir = $this->StorageProvider()->GenerateFilePath(
|
|
||||||
$oAccount,
|
|
||||||
\RainLoop\Providers\Storage\Enumerations\StorageType::PGP
|
|
||||||
);
|
|
||||||
|
|
||||||
$keys = [];
|
|
||||||
foreach (\glob("{$dir}/*") as $file) {
|
|
||||||
if (\is_file($file)) {
|
|
||||||
if ('.asc' === \substr($file, -4)) {
|
|
||||||
$keys[] = \file_get_contents($file);
|
|
||||||
} else if ('.key' === \substr($file, -4)) {
|
|
||||||
$key = \json_decode(\file_get_contents($file), true);
|
|
||||||
$mac = \array_pop($key);
|
|
||||||
$hash = $oAccount->CryptKey();
|
|
||||||
if ($mac === \hash_hmac('sha1', $key[2], $hash)) {
|
|
||||||
$key[1] = \base64_decode($key[1]);
|
|
||||||
$key[2] = \base64_decode($key[2]);
|
|
||||||
$keys[] = \SnappyMail\Crypt::Decrypt($key, $hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->DefaultResponse($keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -232,16 +206,16 @@ trait Pgp
|
||||||
$privateKey = $this->GetActionParam('privateKey', '');
|
$privateKey = $this->GetActionParam('privateKey', '');
|
||||||
|
|
||||||
$result = [
|
$result = [
|
||||||
'onServer' => [false, false, false],
|
'onServer' => [false, false],
|
||||||
'inGnuPG' => [false, false, false]
|
'inGnuPG' => [false, false]
|
||||||
];
|
];
|
||||||
|
|
||||||
$onServer = (int) $this->GetActionParam('onServer', 0);
|
$onServer = (int) $this->GetActionParam('onServer', 0);
|
||||||
if ($publicKey && $onServer & 1) {
|
if ($publicKey && $onServer & 1) {
|
||||||
$result['onServer'][0] = $this->StorePGPKey($publicKey);
|
$result['onServer'][0] = Backup::PGPKey($publicKey);
|
||||||
}
|
}
|
||||||
if ($privateKey && $onServer & 2) {
|
if ($privateKey && $onServer & 2) {
|
||||||
$result['onServer'][1] = $this->StorePGPKey($privateKey);
|
$result['onServer'][1] = Backup::PGPKey($privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
$inGnuPG = (int) $this->GetActionParam('inGnuPG', 0);
|
$inGnuPG = (int) $this->GetActionParam('inGnuPG', 0);
|
||||||
|
|
@ -267,32 +241,6 @@ trait Pgp
|
||||||
{
|
{
|
||||||
$key = $this->GetActionParam('key', '');
|
$key = $this->GetActionParam('key', '');
|
||||||
$keyId = $this->GetActionParam('keyId', '');
|
$keyId = $this->GetActionParam('keyId', '');
|
||||||
return $this->DefaultResponse(($key && $keyId && $this->StorePGPKey($key, $keyId)));
|
return $this->DefaultResponse(($key && $keyId && Backup::PGPKey($key, $keyId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function StorePGPKey(string $key, string $keyId = '') : bool
|
|
||||||
{
|
|
||||||
$oAccount = $this->getMainAccountFromToken();
|
|
||||||
if ($oAccount) {
|
|
||||||
$keyId = $keyId ? "0x{$keyId}" : \sha1($key);
|
|
||||||
$dir = $this->StorageProvider()->GenerateFilePath(
|
|
||||||
$oAccount,
|
|
||||||
\RainLoop\Providers\Storage\Enumerations\StorageType::PGP,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
if (\str_contains($key, 'PGP PRIVATE KEY')) {
|
|
||||||
$hash = $oAccount->CryptKey();
|
|
||||||
$key = \SnappyMail\Crypt::Encrypt($key, $hash);
|
|
||||||
$key[1] = \base64_encode($key[1]);
|
|
||||||
$key[2] = \base64_encode($key[2]);
|
|
||||||
$key[] = \hash_hmac('sha1', $key[2], $hash);
|
|
||||||
return !!\file_put_contents("{$dir}{$keyId}.key", \json_encode($key));
|
|
||||||
}
|
|
||||||
if (\str_contains($key, 'PGP PUBLIC KEY')) {
|
|
||||||
return !!\file_put_contents("{$dir}{$keyId}_public.asc", $key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
80
snappymail/v/0.0.0/app/libraries/snappymail/pgp/backup.php
Normal file
80
snappymail/v/0.0.0/app/libraries/snappymail/pgp/backup.php
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This class is inspired by PEAR Crypt_GPG and PECL gnupg
|
||||||
|
* It does not support gpg v1 because that is missing ECDH, ECDSA, EDDSA
|
||||||
|
* It does not support gpg < v2.2.5 as they are from before 2018
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace SnappyMail\PGP;
|
||||||
|
|
||||||
|
class Backup
|
||||||
|
{
|
||||||
|
public static function PGPKey(string $key, string $keyId = '') : bool
|
||||||
|
{
|
||||||
|
$oActions = \RainLoop\Api::Actions();
|
||||||
|
$oAccount = $oActions->getMainAccountFromToken();
|
||||||
|
if ($oAccount) {
|
||||||
|
$keyId = $keyId ? "0x{$keyId}" : \sha1($key);
|
||||||
|
$dir = $oActions->StorageProvider()->GenerateFilePath(
|
||||||
|
$oAccount,
|
||||||
|
\RainLoop\Providers\Storage\Enumerations\StorageType::PGP,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
if (\str_contains($key, 'PGP PRIVATE KEY')) {
|
||||||
|
$hash = $oAccount->CryptKey();
|
||||||
|
$key = \SnappyMail\Crypt::Encrypt($key, $hash);
|
||||||
|
$key[1] = \base64_encode($key[1]);
|
||||||
|
$key[2] = \base64_encode($key[2]);
|
||||||
|
$key[] = \hash_hmac('sha1', $key[2], $hash);
|
||||||
|
return !!\file_put_contents("{$dir}{$keyId}.key", \json_encode($key));
|
||||||
|
}
|
||||||
|
if (\str_contains($key, 'PGP PUBLIC KEY')) {
|
||||||
|
return !!\file_put_contents("{$dir}{$keyId}_public.asc", $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getKeys() : array
|
||||||
|
{
|
||||||
|
$result = [
|
||||||
|
'public' => [],
|
||||||
|
'private' => []
|
||||||
|
];
|
||||||
|
$oActions = \RainLoop\Api::Actions();
|
||||||
|
$oAccount = $oActions->getMainAccountFromToken();
|
||||||
|
if ($oAccount) {
|
||||||
|
$keyId = $keyId ? "0x{$keyId}" : \sha1($key);
|
||||||
|
$dir = $oActions->StorageProvider()->GenerateFilePath(
|
||||||
|
$oAccount,
|
||||||
|
\RainLoop\Providers\Storage\Enumerations\StorageType::PGP,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
$hash = $oAccount->CryptKey();
|
||||||
|
foreach (\glob("{$dir}*") as $file) {
|
||||||
|
if (\is_file($file)) {
|
||||||
|
if ('_public.asc' === \substr($file, -11)) {
|
||||||
|
$result['public'][] = [
|
||||||
|
'id' => \basename($file),
|
||||||
|
'value' => \file_get_contents($file),
|
||||||
|
];
|
||||||
|
} else if ('.key' === \substr($file, -4)) {
|
||||||
|
$key = \json_decode(\file_get_contents($file));
|
||||||
|
if (\is_array($key)) {
|
||||||
|
$mac = \array_pop($key);
|
||||||
|
if (!empty($key[2]) && \hash_hmac('sha1', $key[2], $hash) === $mac) {
|
||||||
|
$key[1] = \base64_decode($key[1]);
|
||||||
|
$key[2] = \base64_decode($key[2]);
|
||||||
|
$result['private'][] = [
|
||||||
|
'id' => \basename($file),
|
||||||
|
'value' => \SnappyMail\Crypt::Decrypt($key, $hash),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue