1
0
Fork 0
mirror of https://github.com/wallabag/wallabag.git synced 2025-09-15 18:57:05 +00:00

Crypt site credential password

This commit is contained in:
Jeremy Benoist 2017-06-11 23:05:19 +02:00
parent 9de9f1e5ce
commit 906424c1b6
No known key found for this signature in database
GPG key ID: BCA73962457ACC3C
15 changed files with 169 additions and 9 deletions

View file

@ -313,6 +313,8 @@ class InstallCommand extends ContainerAwareCommand
$this
->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]);
return $this;
}
/**

View file

@ -45,6 +45,8 @@ class SiteCredentialController extends Controller
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$credential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getPassword()));
$em = $this->getDoctrine()->getManager();
$em->persist($credential);
$em->flush($credential);

View file

@ -63,6 +63,8 @@ class Configuration implements ConfigurationInterface
->end()
->end()
->end()
->scalarNode('encryption_key_path')
->end()
->end()
;

View file

@ -29,6 +29,7 @@ class WallabagCoreExtension extends Extension
$container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']);
$container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']);
$container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']);
$container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');

View file

@ -46,8 +46,7 @@ class SiteCredential
* @var string
*
* @Assert\NotBlank()
* @Assert\Length(max=255)
* @ORM\Column(name="password", type="string", length=255)
* @ORM\Column(name="password", type="text")
*/
private $password;

View file

@ -0,0 +1,86 @@
<?php
namespace Wallabag\CoreBundle\Helper;
use Psr\Log\LoggerInterface;
use Defuse\Crypto\Key;
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
/**
* This is a proxy to crypt and decrypt password used by SiteCredential entity.
* BTW, It might be re-use for sth else.
*/
class CryptoProxy
{
private $logger;
private $encryptionKey;
public function __construct($encryptionKeyPath, LoggerInterface $logger)
{
$this->logger = $logger;
if (!file_exists($encryptionKeyPath)) {
$key = Key::createNewRandomKey();
file_put_contents($encryptionKeyPath, $key->saveToAsciiSafeString());
chmod($encryptionKeyPath, 0600);
}
$this->encryptionKey = file_get_contents($encryptionKeyPath);
}
/**
* Ensure the given value will be crypted.
*
* @param string $secretValue Secret valye to crypt
*
* @return string
*/
public function crypt($secretValue)
{
$this->logger->debug('Crypto: crypting value: '.$this->mask($secretValue));
return Crypto::encrypt($secretValue, $this->loadKey());
}
/**
* Ensure the given crypted value will be decrypted.
*
* @param string $cryptedValue The value to be decrypted
*
* @return string
*/
public function decrypt($cryptedValue)
{
$this->logger->debug('Crypto: decrypting value: '.$this->mask($cryptedValue));
try {
return Crypto::decrypt($cryptedValue, $this->loadKey());
} catch (WrongKeyOrModifiedCiphertextException $e) {
throw new \RuntimeException('Decrypt fail: '.$e->getMessage());
}
}
/**
* Load the private key.
*
* @return string
*/
private function loadKey()
{
return Key::loadFromAsciiSafeString($this->encryptionKey);
}
/**
* Keep first and last character and put some stars in between.
*
* @param string $value Value to mask
*
* @return string
*/
private function mask($value)
{
return $value[0].'*****'.$value[strlen($value) - 1];
}
}

View file

@ -2,11 +2,20 @@
namespace Wallabag\CoreBundle\Repository;
use Wallabag\CoreBundle\Helper\CryptoProxy;
/**
* SiteCredentialRepository.
*/
class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
{
private $cryptoProxy;
public function setCrypto(CryptoProxy $cryptoProxy)
{
$this->cryptoProxy = $cryptoProxy;
}
/**
* Retrieve one username/password for the given host and userId.
*
@ -17,12 +26,21 @@ class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
*/
public function findOneByHostAndUser($host, $userId)
{
return $this->createQueryBuilder('s')
$res = $this->createQueryBuilder('s')
->select('s.username', 's.password')
->where('s.host = :hostname')->setParameter('hostname', $host)
->andWhere('s.user = :userId')->setParameter('userId', $userId)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
if (null === $res) {
return;
}
// decrypt password before returning it
$res['password'] = $this->cryptoProxy->decrypt($res['password']);
return $res;
}
}

View file

@ -126,6 +126,8 @@ services:
factory: [ "@doctrine.orm.default_entity_manager", getRepository ]
arguments:
- WallabagCoreBundle:SiteCredential
calls:
- [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ]
wallabag_core.helper.entries_export:
class: Wallabag\CoreBundle\Helper\EntriesExport
@ -208,3 +210,9 @@ services:
wallabag_core.entry.download_images.client:
class: GuzzleHttp\Client
wallabag_core.helper.crypto_proxy:
class: Wallabag\CoreBundle\Helper\CryptoProxy
arguments:
- "%wallabag_core.site_credentials.encryption_key_path%"
- "@logger"