diff options
-rw-r--r-- | apps/settings/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | apps/settings/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | apps/settings/lib/AppInfo/Application.php | 2 | ||||
-rw-r--r-- | apps/settings/lib/Controller/CheckSetupController.php | 21 | ||||
-rw-r--r-- | apps/settings/lib/SetupChecks/RandomnessSecure.php | 63 | ||||
-rw-r--r-- | apps/settings/tests/Controller/CheckSetupControllerTest.php | 10 | ||||
-rw-r--r-- | core/js/setupchecks.js | 8 | ||||
-rw-r--r-- | core/js/tests/specs/setupchecksSpec.js | 92 |
8 files changed, 67 insertions, 131 deletions
diff --git a/apps/settings/composer/composer/autoload_classmap.php b/apps/settings/composer/composer/autoload_classmap.php index c045d8975ca..c69b49ec309 100644 --- a/apps/settings/composer/composer/autoload_classmap.php +++ b/apps/settings/composer/composer/autoload_classmap.php @@ -85,6 +85,7 @@ return array( 'OCA\\Settings\\SetupChecks\\PhpModules' => $baseDir . '/../lib/SetupChecks/PhpModules.php', 'OCA\\Settings\\SetupChecks\\PhpOutdated' => $baseDir . '/../lib/SetupChecks/PhpOutdated.php', 'OCA\\Settings\\SetupChecks\\PhpOutputBuffering' => $baseDir . '/../lib/SetupChecks/PhpOutputBuffering.php', + 'OCA\\Settings\\SetupChecks\\RandomnessSecure' => $baseDir . '/../lib/SetupChecks/RandomnessSecure.php', 'OCA\\Settings\\SetupChecks\\ReadOnlyConfig' => $baseDir . '/../lib/SetupChecks/ReadOnlyConfig.php', 'OCA\\Settings\\SetupChecks\\SupportedDatabase' => $baseDir . '/../lib/SetupChecks/SupportedDatabase.php', 'OCA\\Settings\\SetupChecks\\TransactionIsolation' => $baseDir . '/../lib/SetupChecks/TransactionIsolation.php', diff --git a/apps/settings/composer/composer/autoload_static.php b/apps/settings/composer/composer/autoload_static.php index 5506a36e58a..eba8fadc98a 100644 --- a/apps/settings/composer/composer/autoload_static.php +++ b/apps/settings/composer/composer/autoload_static.php @@ -100,6 +100,7 @@ class ComposerStaticInitSettings 'OCA\\Settings\\SetupChecks\\PhpModules' => __DIR__ . '/..' . '/../lib/SetupChecks/PhpModules.php', 'OCA\\Settings\\SetupChecks\\PhpOutdated' => __DIR__ . '/..' . '/../lib/SetupChecks/PhpOutdated.php', 'OCA\\Settings\\SetupChecks\\PhpOutputBuffering' => __DIR__ . '/..' . '/../lib/SetupChecks/PhpOutputBuffering.php', + 'OCA\\Settings\\SetupChecks\\RandomnessSecure' => __DIR__ . '/..' . '/../lib/SetupChecks/RandomnessSecure.php', 'OCA\\Settings\\SetupChecks\\ReadOnlyConfig' => __DIR__ . '/..' . '/../lib/SetupChecks/ReadOnlyConfig.php', 'OCA\\Settings\\SetupChecks\\SupportedDatabase' => __DIR__ . '/..' . '/../lib/SetupChecks/SupportedDatabase.php', 'OCA\\Settings\\SetupChecks\\TransactionIsolation' => __DIR__ . '/..' . '/../lib/SetupChecks/TransactionIsolation.php', diff --git a/apps/settings/lib/AppInfo/Application.php b/apps/settings/lib/AppInfo/Application.php index b0c6bfbc636..0770418c3bb 100644 --- a/apps/settings/lib/AppInfo/Application.php +++ b/apps/settings/lib/AppInfo/Application.php @@ -60,6 +60,7 @@ use OCA\Settings\SetupChecks\PhpModules; use OCA\Settings\SetupChecks\PhpGetEnv; use OCA\Settings\SetupChecks\PhpOutdated; use OCA\Settings\SetupChecks\PhpOutputBuffering; +use OCA\Settings\SetupChecks\RandomnessSecure; use OCA\Settings\SetupChecks\ReadOnlyConfig; use OCA\Settings\SetupChecks\SupportedDatabase; use OCA\Settings\SetupChecks\TransactionIsolation; @@ -164,6 +165,7 @@ class Application extends App implements IBootstrap { $context->registerSetupCheck(PhpGetEnv::class); $context->registerSetupCheck(PhpOutdated::class); $context->registerSetupCheck(PhpOutputBuffering::class); + $context->registerSetupCheck(RandomnessSecure::class); $context->registerSetupCheck(ReadOnlyConfig::class); $context->registerSetupCheck(SupportedDatabase::class); $context->registerSetupCheck(TransactionIsolation::class); diff --git a/apps/settings/lib/Controller/CheckSetupController.php b/apps/settings/lib/Controller/CheckSetupController.php index ccdadcb3cea..f5849cce5a8 100644 --- a/apps/settings/lib/Controller/CheckSetupController.php +++ b/apps/settings/lib/Controller/CheckSetupController.php @@ -80,7 +80,6 @@ use OCP\IURLGenerator; use OCP\Lock\ILockingProvider; use OCP\Notification\IManager; use OCP\Security\Bruteforce\IThrottler; -use OCP\Security\ISecureRandom; use OCP\SetupCheck\ISetupCheckManager; use Psr\Log\LoggerInterface; @@ -108,8 +107,6 @@ class CheckSetupController extends Controller { private $dateTimeFormatter; /** @var MemoryInfo */ private $memoryInfo; - /** @var ISecureRandom */ - private $secureRandom; /** @var IniGetWrapper */ private $iniGetWrapper; /** @var IDBConnection */ @@ -139,7 +136,6 @@ class CheckSetupController extends Controller { ILockingProvider $lockingProvider, IDateTimeFormatter $dateTimeFormatter, MemoryInfo $memoryInfo, - ISecureRandom $secureRandom, IniGetWrapper $iniGetWrapper, IDBConnection $connection, IThrottler $throttler, @@ -162,7 +158,6 @@ class CheckSetupController extends Controller { $this->lockingProvider = $lockingProvider; $this->dateTimeFormatter = $dateTimeFormatter; $this->memoryInfo = $memoryInfo; - $this->secureRandom = $secureRandom; $this->iniGetWrapper = $iniGetWrapper; $this->connection = $connection; $this->tempManager = $tempManager; @@ -195,20 +190,6 @@ class CheckSetupController extends Controller { } /** - * Whether PHP can generate "secure" pseudorandom integers - * - * @return bool - */ - private function isRandomnessSecure() { - try { - $this->secureRandom->generate(1); - } catch (\Exception $ex) { - return false; - } - return true; - } - - /** * Public for the sake of unit-testing * * @return array @@ -767,8 +748,6 @@ Raw output 'isFairUseOfFreePushService' => $this->isFairUseOfFreePushService(), 'isBruteforceThrottled' => $this->throttler->getAttempts($this->request->getRemoteAddress()) !== 0, 'bruteforceRemoteAddress' => $this->request->getRemoteAddress(), - 'isRandomnessSecure' => $this->isRandomnessSecure(), - 'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'), 'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(), 'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(), 'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'), diff --git a/apps/settings/lib/SetupChecks/RandomnessSecure.php b/apps/settings/lib/SetupChecks/RandomnessSecure.php new file mode 100644 index 00000000000..c30d4f2f79a --- /dev/null +++ b/apps/settings/lib/SetupChecks/RandomnessSecure.php @@ -0,0 +1,63 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Côme Chilliet <come.chilliet@nextcloud.com> + * + * @author Côme Chilliet <come.chilliet@nextcloud.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCA\Settings\SetupChecks; + +use OCP\IConfig; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\Security\ISecureRandom; +use OCP\SetupCheck\ISetupCheck; +use OCP\SetupCheck\SetupResult; + +class RandomnessSecure implements ISetupCheck { + public function __construct( + private IL10N $l10n, + private IConfig $config, + private IURLGenerator $urlGenerator, + private ISecureRandom $secureRandom, + ) { + } + + public function getName(): string { + return $this->l10n->t('Random generator'); + } + + public function getCategory(): string { + return 'security'; + } + + public function run(): SetupResult { + try { + $this->secureRandom->generate(1); + } catch (\Exception $ex) { + return SetupResult::error( + $this->l10n->t('No suitable source for randomness found by PHP which is highly discouraged for security reasons.'), + $this->urlGenerator->linkToDocs('admin-security') + ); + } + return SetupResult::success($this->l10n->t('Secure')); + } +} diff --git a/apps/settings/tests/Controller/CheckSetupControllerTest.php b/apps/settings/tests/Controller/CheckSetupControllerTest.php index f992ecf8591..693d80744ce 100644 --- a/apps/settings/tests/Controller/CheckSetupControllerTest.php +++ b/apps/settings/tests/Controller/CheckSetupControllerTest.php @@ -40,7 +40,6 @@ use OC; use OC\DB\Connection; use OC\IntegrityCheck\Checker; use OC\MemoryInfo; -use OC\Security\SecureRandom; use OCA\Settings\Controller\CheckSetupController; use OCP\App\IAppManager; use OCP\AppFramework\Http; @@ -100,8 +99,6 @@ class CheckSetupControllerTest extends TestCase { private $dateTimeFormatter; /** @var MemoryInfo|MockObject */ private $memoryInfo; - /** @var SecureRandom|\PHPUnit\Framework\MockObject\MockObject */ - private $secureRandom; /** @var IniGetWrapper|\PHPUnit\Framework\MockObject\MockObject */ private $iniGetWrapper; /** @var IDBConnection|\PHPUnit\Framework\MockObject\MockObject */ @@ -154,7 +151,6 @@ class CheckSetupControllerTest extends TestCase { $this->memoryInfo = $this->getMockBuilder(MemoryInfo::class) ->setMethods(['isMemoryLimitSufficient',]) ->getMock(); - $this->secureRandom = $this->getMockBuilder(SecureRandom::class)->getMock(); $this->iniGetWrapper = $this->getMockBuilder(IniGetWrapper::class)->getMock(); $this->connection = $this->getMockBuilder(IDBConnection::class) ->disableOriginalConstructor()->getMock(); @@ -178,7 +174,6 @@ class CheckSetupControllerTest extends TestCase { $this->lockingProvider, $this->dateTimeFormatter, $this->memoryInfo, - $this->secureRandom, $this->iniGetWrapper, $this->connection, $this->throttler, @@ -443,8 +438,6 @@ class CheckSetupControllerTest extends TestCase { 'backgroundJobsUrl' => 'https://example.org', ], 'cronErrors' => [], - 'isRandomnessSecure' => self::invokePrivate($this->checkSetupController, 'isRandomnessSecure'), - 'securityDocs' => 'https://docs.example.org/server/8.1/admin_manual/configuration_server/hardening.html', 'isUsedTlsLibOutdated' => '', 'forwardedForHeadersWorking' => false, 'reverseProxyDocs' => 'reverse-proxy-doc-link', @@ -495,7 +488,6 @@ class CheckSetupControllerTest extends TestCase { $this->lockingProvider, $this->dateTimeFormatter, $this->memoryInfo, - $this->secureRandom, $this->iniGetWrapper, $this->connection, $this->throttler, @@ -1224,7 +1216,6 @@ Array $this->lockingProvider, $this->dateTimeFormatter, $this->memoryInfo, - $this->secureRandom, $this->iniGetWrapper, $this->connection, $this->throttler, @@ -1280,7 +1271,6 @@ Array $this->lockingProvider, $this->dateTimeFormatter, $this->memoryInfo, - $this->secureRandom, $this->iniGetWrapper, $this->connection, $this->throttler, diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index a334c0bd789..029096b43b2 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -224,14 +224,6 @@ type: OC.SetupChecks.MESSAGE_TYPE_ERROR }); } - if(!data.isRandomnessSecure) { - messages.push({ - msg: t('core', 'No suitable source for randomness found by PHP which is highly discouraged for security reasons. Further information can be found in the {linkstart}documentation ↗{linkend}.') - .replace('{linkstart}', '<a target="_blank" rel="noreferrer noopener" class="external" href="' + data.securityDocs + '">') - .replace('{linkend}', '</a>'), - type: OC.SetupChecks.MESSAGE_TYPE_ERROR - }); - } if(data.isUsedTlsLibOutdated) { messages.push({ msg: data.isUsedTlsLibOutdated, diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js index c1160d08f17..eaea1d2f5b8 100644 --- a/core/js/tests/specs/setupchecksSpec.js +++ b/core/js/tests/specs/setupchecksSpec.js @@ -224,7 +224,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -282,7 +281,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -340,7 +338,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -388,63 +385,6 @@ describe('OC.SetupChecks tests', function() { }); }); - it('should return an error if /dev/urandom is not accessible', function(done) { - var async = OC.SetupChecks.checkSetup(); - - suite.server.requests[0].respond( - 200, - { - 'Content-Type': 'application/json', - }, - JSON.stringify({ - suggestedOverwriteCliURL: '', - isRandomnessSecure: false, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', - isFairUseOfFreePushService: true, - forwardedForHeadersWorking: true, - isCorrectMemcachedPHPModuleInstalled: true, - hasPassedCodeIntegrityCheck: true, - OpcacheSetupRecommendations: [], - isSettimelimitAvailable: true, - hasFreeTypeSupport: true, - missingIndexes: [], - missingPrimaryKeys: [], - missingColumns: [], - cronErrors: [], - cronInfo: { - diffInSeconds: 0 - }, - isMemoryLimitSufficient: true, - appDirsWithDifferentOwner: [], - isImagickEnabled: true, - areWebauthnExtensionsEnabled: true, - is64bit: true, - pendingBigIntConversionColumns: [], - isMysqlUsedWithoutUTF8MB4: false, - isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true, - reverseProxyGeneratedURL: 'https://server', - temporaryDirectoryWritable: true, - generic: { - network: { - "Internet connectivity": { - severity: "success", - description: null, - linkToDoc: null - } - }, - }, - }) - ); - - async.done(function( data, s, x ){ - expect(data).toEqual([{ - msg: 'No suitable source for randomness found by PHP which is highly discouraged for security reasons. Further information can be found in the <a target="_blank" rel="noreferrer noopener" class="external" href="https://docs.nextcloud.com/myDocs.html">documentation ↗</a>.', - type: OC.SetupChecks.MESSAGE_TYPE_ERROR - }]); - done(); - }); - }); - it('should return an error if the wrong memcache PHP module is installed', function(done) { var async = OC.SetupChecks.checkSetup(); @@ -455,8 +395,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: false, @@ -512,8 +450,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -571,7 +507,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, forwardedForHeadersWorking: false, reverseProxyDocs: 'https://docs.nextcloud.com/foo/bar.html', @@ -628,7 +563,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, isBruteforceThrottled: true, bruteforceRemoteAddress: '::1', @@ -687,7 +621,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, reverseProxyDocs: 'https://docs.nextcloud.com/foo/bar.html', @@ -744,7 +677,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, reverseProxyDocs: 'https://docs.nextcloud.com/foo/bar.html', @@ -821,8 +753,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -885,8 +815,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -942,8 +870,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -999,8 +925,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1060,8 +984,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1118,8 +1040,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1173,8 +1093,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1231,8 +1149,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1289,8 +1205,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1346,8 +1260,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1403,8 +1315,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, @@ -1467,8 +1377,6 @@ describe('OC.SetupChecks tests', function() { }, JSON.stringify({ suggestedOverwriteCliURL: '', - isRandomnessSecure: true, - securityDocs: 'https://docs.nextcloud.com/myDocs.html', isFairUseOfFreePushService: true, forwardedForHeadersWorking: true, isCorrectMemcachedPHPModuleInstalled: true, |