Skip to content

Commit 5760584

Browse files
authored
Merge pull request #454 from nextcloud/backport/451/stable30
[stable30] (fix): Encrypt sensitive values(haproxy_password) in the DB
2 parents bc277fa + 5ba6c74 commit 5760584

File tree

5 files changed

+85
-6
lines changed

5 files changed

+85
-6
lines changed

appinfo/info.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ to join us in shaping a more versatile, stable, and secure app landscape.
4343
*Your insights, suggestions, and contributions are invaluable to us.*
4444
4545
]]></description>
46-
<version>4.0.0</version>
46+
<version>4.0.3</version>
4747
<licence>agpl</licence>
4848
<author mail="andrey18106x@gmail.com" homepage="https://github.com/andrey18106">Andrey Borysenko</author>
4949
<author mail="bigcat88@icloud.com" homepage="https://github.com/bigcat88">Alexander Piskun</author>

lib/Controller/DaemonConfigController.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use OCP\IConfig;
2020
use OCP\IL10N;
2121
use OCP\IRequest;
22+
use OCP\Security\ICrypto;
2223

2324
/**
2425
* DaemonConfig actions (for UI)
@@ -33,6 +34,7 @@ public function __construct(
3334
private readonly AppAPIService $service,
3435
private readonly ExAppService $exAppService,
3536
private readonly IL10N $l10n,
37+
private readonly ICrypto $crypto,
3638
) {
3739
parent::__construct(Application::APP_ID, $request);
3840
}
@@ -66,6 +68,9 @@ public function updateDaemonConfig(string $name, array $daemonConfigParams): Res
6668
// Restore the original password if "dummySecret123" is provided
6769
if ($haproxyPassword === 'dummySecret123') {
6870
$daemonConfigParams['deploy_config']['haproxy_password'] = $daemonConfig->getDeployConfig()['haproxy_password'] ?? "";
71+
} elseif (!empty($haproxyPassword)) {
72+
// New password provided, encrypt it
73+
$daemonConfigParams['deploy_config']['haproxy_password'] = $this->crypto->encrypt($haproxyPassword);
6974
}
7075

7176
// Create and update DaemonConfig instance
@@ -129,16 +134,22 @@ public function checkDaemonConnection(array $daemonParams): Response {
129134
$haproxyPassword = $daemonParams['deploy_config']['haproxy_password'] ?? null;
130135

131136
if ($haproxyPassword === 'dummySecret123') {
132-
// If the secret is "dummySecret123" we check if such record is present in DB
137+
// For cases when the password itself is 'dummySecret123'
138+
$daemonParams['deploy_config']['haproxy_password'] = $this->crypto->encrypt($haproxyPassword);
139+
140+
// Check if such record is present in the DB
133141
$daemonConfig = $this->daemonConfigService->getDaemonConfigByName($daemonParams['name']);
134142
if ($daemonConfig !== null) {
143+
// such Daemon config already present in the DB
135144
$haproxyPasswordDB = $daemonConfig->getDeployConfig()['haproxy_password'] ?? "";
136145
if ($haproxyPasswordDB) {
137-
// if there is a record in the DB and there is a password,
138-
// then we request it from the DB instead of the “masked” one
146+
// get password from the DB instead of the “masked” one
139147
$daemonParams['deploy_config']['haproxy_password'] = $haproxyPasswordDB;
140148
}
141149
}
150+
} elseif (!empty($haproxyPassword)) {
151+
// New password provided, encrypt it, as "initGuzzleClient" expects to receive encrypted password
152+
$daemonParams['deploy_config']['haproxy_password'] = $this->crypto->encrypt($haproxyPassword);
142153
}
143154

144155
$daemonConfig = new DaemonConfig([

lib/DeployActions/DockerActions.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCP\ICertificateManager;
1919
use OCP\IConfig;
2020
use OCP\IURLGenerator;
21+
use OCP\Security\ICrypto;
2122
use Psr\Log\LoggerInterface;
2223

2324
class DockerActions implements IDeployActions {
@@ -36,6 +37,7 @@ public function __construct(
3637
private readonly IURLGenerator $urlGenerator,
3738
private readonly AppAPICommonService $service,
3839
private readonly ExAppService $exAppService,
40+
private readonly ICrypto $crypto,
3941
) {
4042
}
4143

@@ -556,7 +558,8 @@ public function resolveExAppUrl(
556558
}
557559
if ($protocol == 'https' && isset($deployConfig['haproxy_password']) && $deployConfig['haproxy_password'] !== '') {
558560
// we only set haproxy auth for remote installations, when all requests come through HaProxy.
559-
$auth = [self::APP_API_HAPROXY_USER, $deployConfig['haproxy_password']];
561+
$haproxyPass = $this->crypto->decrypt($deployConfig['haproxy_password']);
562+
$auth = [self::APP_API_HAPROXY_USER, $haproxyPass];
560563
}
561564
return sprintf('%s://%s:%s', $protocol, $exAppHost, $port);
562565
}
@@ -620,7 +623,8 @@ public function initGuzzleClient(DaemonConfig $daemonConfig): void {
620623
$guzzleParams = $this->setupCerts($guzzleParams);
621624
}
622625
if (isset($daemonConfig->getDeployConfig()['haproxy_password']) && $daemonConfig->getDeployConfig()['haproxy_password'] !== '') {
623-
$guzzleParams['auth'] = [self::APP_API_HAPROXY_USER, $daemonConfig->getDeployConfig()['haproxy_password']];
626+
$haproxyPass = $this->crypto->decrypt($daemonConfig->getDeployConfig()['haproxy_password']);
627+
$guzzleParams['auth'] = [self::APP_API_HAPROXY_USER, $haproxyPass];
624628
}
625629
$this->guzzleClient = new Client($guzzleParams);
626630
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
4+
* SPDX-License-Identifier: AGPL-3.0-or-later
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace OCA\AppAPI\Migration;
10+
11+
use Closure;
12+
use OCP\DB\ISchemaWrapper;
13+
use OCP\IDBConnection;
14+
use OCP\Migration\IOutput;
15+
use OCP\Migration\SimpleMigrationStep;
16+
use OCP\Security\ICrypto;
17+
18+
class Version5000Date20241120135411 extends SimpleMigrationStep {
19+
20+
public function __construct(
21+
private IDBConnection $connection,
22+
private ICrypto $crypto,
23+
) {
24+
}
25+
26+
/**
27+
* @param IOutput $output
28+
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
29+
* @param array $options
30+
*
31+
* @return null|ISchemaWrapper
32+
*/
33+
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
34+
// encrypt "haproxy_password" in the "ex_apps_daemons" table
35+
$qbSelect = $this->connection->getQueryBuilder();
36+
$qbSelect->select(['id', 'deploy_config'])
37+
->from('ex_apps_daemons')
38+
->where(1);
39+
$req = $qbSelect->executeQuery();
40+
41+
while ($row = $req->fetch()) {
42+
$deployConfig = $row['deploy_config'];
43+
$deployConfig = json_decode($deployConfig, true);
44+
if (!empty($deployConfig['haproxy_password'])) {
45+
$deployConfig['haproxy_password'] = $this->crypto->encrypt($deployConfig['haproxy_password']);
46+
$encodedDeployConfig = json_encode($deployConfig);
47+
$qbUpdate = $this->connection->getQueryBuilder();
48+
$qbUpdate->update('ex_apps_daemons')
49+
->set('deploy_config', $qbUpdate->createNamedParameter($encodedDeployConfig))
50+
->where(
51+
$qbUpdate->expr()->eq('id', $qbUpdate->createNamedParameter($row['id']))
52+
);
53+
$qbUpdate->executeStatement();
54+
}
55+
}
56+
$req->closeCursor();
57+
return null;
58+
}
59+
}

lib/Service/DaemonConfigService.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use OCP\AppFramework\Db\DoesNotExistException;
1111
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
1212
use OCP\DB\Exception;
13+
use OCP\Security\ICrypto;
1314
use Psr\Log\LoggerInterface;
1415

1516
/**
@@ -20,6 +21,7 @@ public function __construct(
2021
private readonly LoggerInterface $logger,
2122
private readonly DaemonConfigMapper $mapper,
2223
private readonly ExAppService $exAppService,
24+
private readonly ICrypto $crypto,
2325
) {
2426
}
2527

@@ -38,6 +40,9 @@ public function registerDaemonConfig(array $params): ?DaemonConfig {
3840
}
3941
$params['deploy_config']['nextcloud_url'] = rtrim($params['deploy_config']['nextcloud_url'], '/');
4042
try {
43+
if (isset($params['deploy_config']['haproxy_password']) && $params['deploy_config']['haproxy_password'] !== '') {
44+
$params['deploy_config']['haproxy_password'] = $this->crypto->encrypt($params['deploy_config']['haproxy_password']);
45+
}
4146
return $this->mapper->insert(new DaemonConfig([
4247
'name' => $params['name'],
4348
'display_name' => $params['display_name'],

0 commit comments

Comments
 (0)