diff options
author | Jeremy Benoist <jeremy.benoist@gmail.com> | 2017-06-11 23:05:19 +0200 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2017-06-20 16:03:35 +0200 |
commit | 906424c1b6fd884bf2081bfe6dd0b1f9651c2801 (patch) | |
tree | 8ca6896e1279e4d403a7b63c775bde7aa2bcf7ce /src | |
parent | 9de9f1e5ceed4ac7ecd27e1cb808e630a831f94b (diff) | |
download | wallabag-906424c1b6fd884bf2081bfe6dd0b1f9651c2801.tar.gz wallabag-906424c1b6fd884bf2081bfe6dd0b1f9651c2801.tar.zst wallabag-906424c1b6fd884bf2081bfe6dd0b1f9651c2801.zip |
Crypt site credential password
Diffstat (limited to 'src')
8 files changed, 121 insertions, 3 deletions
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index 0f119377..eb725a59 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php | |||
@@ -313,6 +313,8 @@ class InstallCommand extends ContainerAwareCommand | |||
313 | 313 | ||
314 | $this | 314 | $this |
315 | ->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]); | 315 | ->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]); |
316 | |||
317 | return $this; | ||
316 | } | 318 | } |
317 | 319 | ||
318 | /** | 320 | /** |
diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php index dc8e723d..0bacafb7 100644 --- a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php +++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php | |||
@@ -45,6 +45,8 @@ class SiteCredentialController extends Controller | |||
45 | $form->handleRequest($request); | 45 | $form->handleRequest($request); |
46 | 46 | ||
47 | if ($form->isSubmitted() && $form->isValid()) { | 47 | if ($form->isSubmitted() && $form->isValid()) { |
48 | $credential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getPassword())); | ||
49 | |||
48 | $em = $this->getDoctrine()->getManager(); | 50 | $em = $this->getDoctrine()->getManager(); |
49 | $em->persist($credential); | 51 | $em->persist($credential); |
50 | $em->flush($credential); | 52 | $em->flush($credential); |
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php index 33df92d3..a9791f6b 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php | |||
@@ -63,6 +63,8 @@ class Configuration implements ConfigurationInterface | |||
63 | ->end() | 63 | ->end() |
64 | ->end() | 64 | ->end() |
65 | ->end() | 65 | ->end() |
66 | ->scalarNode('encryption_key_path') | ||
67 | ->end() | ||
66 | ->end() | 68 | ->end() |
67 | ; | 69 | ; |
68 | 70 | ||
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php index b4d8a386..532ce238 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php | |||
@@ -29,6 +29,7 @@ class WallabagCoreExtension extends Extension | |||
29 | $container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']); | 29 | $container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']); |
30 | $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']); | 30 | $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']); |
31 | $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']); | 31 | $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']); |
32 | $container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']); | ||
32 | 33 | ||
33 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | 34 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
34 | $loader->load('services.yml'); | 35 | $loader->load('services.yml'); |
diff --git a/src/Wallabag/CoreBundle/Entity/SiteCredential.php b/src/Wallabag/CoreBundle/Entity/SiteCredential.php index 85ee07d4..732d9506 100644 --- a/src/Wallabag/CoreBundle/Entity/SiteCredential.php +++ b/src/Wallabag/CoreBundle/Entity/SiteCredential.php | |||
@@ -46,8 +46,7 @@ class SiteCredential | |||
46 | * @var string | 46 | * @var string |
47 | * | 47 | * |
48 | * @Assert\NotBlank() | 48 | * @Assert\NotBlank() |
49 | * @Assert\Length(max=255) | 49 | * @ORM\Column(name="password", type="text") |
50 | * @ORM\Column(name="password", type="string", length=255) | ||
51 | */ | 50 | */ |
52 | private $password; | 51 | private $password; |
53 | 52 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php new file mode 100644 index 00000000..d0a9b85c --- /dev/null +++ b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php | |||
@@ -0,0 +1,86 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Helper; | ||
4 | |||
5 | use Psr\Log\LoggerInterface; | ||
6 | use Defuse\Crypto\Key; | ||
7 | use Defuse\Crypto\Crypto; | ||
8 | use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException; | ||
9 | |||
10 | /** | ||
11 | * This is a proxy to crypt and decrypt password used by SiteCredential entity. | ||
12 | * BTW, It might be re-use for sth else. | ||
13 | */ | ||
14 | class CryptoProxy | ||
15 | { | ||
16 | private $logger; | ||
17 | private $encryptionKey; | ||
18 | |||
19 | public function __construct($encryptionKeyPath, LoggerInterface $logger) | ||
20 | { | ||
21 | $this->logger = $logger; | ||
22 | |||
23 | if (!file_exists($encryptionKeyPath)) { | ||
24 | $key = Key::createNewRandomKey(); | ||
25 | |||
26 | file_put_contents($encryptionKeyPath, $key->saveToAsciiSafeString()); | ||
27 | chmod($encryptionKeyPath, 0600); | ||
28 | } | ||
29 | |||
30 | $this->encryptionKey = file_get_contents($encryptionKeyPath); | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Ensure the given value will be crypted. | ||
35 | * | ||
36 | * @param string $secretValue Secret valye to crypt | ||
37 | * | ||
38 | * @return string | ||
39 | */ | ||
40 | public function crypt($secretValue) | ||
41 | { | ||
42 | $this->logger->debug('Crypto: crypting value: '.$this->mask($secretValue)); | ||
43 | |||
44 | return Crypto::encrypt($secretValue, $this->loadKey()); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * Ensure the given crypted value will be decrypted. | ||
49 | * | ||
50 | * @param string $cryptedValue The value to be decrypted | ||
51 | * | ||
52 | * @return string | ||
53 | */ | ||
54 | public function decrypt($cryptedValue) | ||
55 | { | ||
56 | $this->logger->debug('Crypto: decrypting value: '.$this->mask($cryptedValue)); | ||
57 | |||
58 | try { | ||
59 | return Crypto::decrypt($cryptedValue, $this->loadKey()); | ||
60 | } catch (WrongKeyOrModifiedCiphertextException $e) { | ||
61 | throw new \RuntimeException('Decrypt fail: '.$e->getMessage()); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | /** | ||
66 | * Load the private key. | ||
67 | * | ||
68 | * @return string | ||
69 | */ | ||
70 | private function loadKey() | ||
71 | { | ||
72 | return Key::loadFromAsciiSafeString($this->encryptionKey); | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * Keep first and last character and put some stars in between. | ||
77 | * | ||
78 | * @param string $value Value to mask | ||
79 | * | ||
80 | * @return string | ||
81 | */ | ||
82 | private function mask($value) | ||
83 | { | ||
84 | return $value[0].'*****'.$value[strlen($value) - 1]; | ||
85 | } | ||
86 | } | ||
diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php index 316ecc75..6f904f0a 100644 --- a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php +++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php | |||
@@ -2,11 +2,20 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\CoreBundle\Repository; | 3 | namespace Wallabag\CoreBundle\Repository; |
4 | 4 | ||
5 | use Wallabag\CoreBundle\Helper\CryptoProxy; | ||
6 | |||
5 | /** | 7 | /** |
6 | * SiteCredentialRepository. | 8 | * SiteCredentialRepository. |
7 | */ | 9 | */ |
8 | class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository | 10 | class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository |
9 | { | 11 | { |
12 | private $cryptoProxy; | ||
13 | |||
14 | public function setCrypto(CryptoProxy $cryptoProxy) | ||
15 | { | ||
16 | $this->cryptoProxy = $cryptoProxy; | ||
17 | } | ||
18 | |||
10 | /** | 19 | /** |
11 | * Retrieve one username/password for the given host and userId. | 20 | * Retrieve one username/password for the given host and userId. |
12 | * | 21 | * |
@@ -17,12 +26,21 @@ class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository | |||
17 | */ | 26 | */ |
18 | public function findOneByHostAndUser($host, $userId) | 27 | public function findOneByHostAndUser($host, $userId) |
19 | { | 28 | { |
20 | return $this->createQueryBuilder('s') | 29 | $res = $this->createQueryBuilder('s') |
21 | ->select('s.username', 's.password') | 30 | ->select('s.username', 's.password') |
22 | ->where('s.host = :hostname')->setParameter('hostname', $host) | 31 | ->where('s.host = :hostname')->setParameter('hostname', $host) |
23 | ->andWhere('s.user = :userId')->setParameter('userId', $userId) | 32 | ->andWhere('s.user = :userId')->setParameter('userId', $userId) |
24 | ->setMaxResults(1) | 33 | ->setMaxResults(1) |
25 | ->getQuery() | 34 | ->getQuery() |
26 | ->getOneOrNullResult(); | 35 | ->getOneOrNullResult(); |
36 | |||
37 | if (null === $res) { | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | // decrypt password before returning it | ||
42 | $res['password'] = $this->cryptoProxy->decrypt($res['password']); | ||
43 | |||
44 | return $res; | ||
27 | } | 45 | } |
28 | } | 46 | } |
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index 09bc77fe..e09b0f18 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml | |||
@@ -126,6 +126,8 @@ services: | |||
126 | factory: [ "@doctrine.orm.default_entity_manager", getRepository ] | 126 | factory: [ "@doctrine.orm.default_entity_manager", getRepository ] |
127 | arguments: | 127 | arguments: |
128 | - WallabagCoreBundle:SiteCredential | 128 | - WallabagCoreBundle:SiteCredential |
129 | calls: | ||
130 | - [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ] | ||
129 | 131 | ||
130 | wallabag_core.helper.entries_export: | 132 | wallabag_core.helper.entries_export: |
131 | class: Wallabag\CoreBundle\Helper\EntriesExport | 133 | class: Wallabag\CoreBundle\Helper\EntriesExport |
@@ -208,3 +210,9 @@ services: | |||
208 | 210 | ||
209 | wallabag_core.entry.download_images.client: | 211 | wallabag_core.entry.download_images.client: |
210 | class: GuzzleHttp\Client | 212 | class: GuzzleHttp\Client |
213 | |||
214 | wallabag_core.helper.crypto_proxy: | ||
215 | class: Wallabag\CoreBundle\Helper\CryptoProxy | ||
216 | arguments: | ||
217 | - "%wallabag_core.site_credentials.encryption_key_path%" | ||
218 | - "@logger" | ||