summaryrefslogtreecommitdiffstats
path: root/settings/Controller/CheckSetupController.php
diff options
context:
space:
mode:
Diffstat (limited to 'settings/Controller/CheckSetupController.php')
-rw-r--r--settings/Controller/CheckSetupController.php350
1 files changed, 350 insertions, 0 deletions
diff --git a/settings/Controller/CheckSetupController.php b/settings/Controller/CheckSetupController.php
new file mode 100644
index 00000000000..cfdfa5021bc
--- /dev/null
+++ b/settings/Controller/CheckSetupController.php
@@ -0,0 +1,350 @@
+<?php
+/**
+ * @author Joas Schilling <nickvergessen@owncloud.com>
+ * @author Lukas Reschke <lukas@owncloud.com>
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roeland Jago Douma <rullzer@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Settings\Controller;
+
+use GuzzleHttp\Exception\ClientException;
+use OC\AppFramework\Http;
+use OC\IntegrityCheck\Checker;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\DataDisplayResponse;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\RedirectResponse;
+use OCP\Http\Client\IClientService;
+use OCP\IConfig;
+use OCP\IL10N;
+use OCP\IRequest;
+use OC_Util;
+use OCP\IURLGenerator;
+
+/**
+ * @package OC\Settings\Controller
+ */
+class CheckSetupController extends Controller {
+ /** @var IConfig */
+ private $config;
+ /** @var IClientService */
+ private $clientService;
+ /** @var \OC_Util */
+ private $util;
+ /** @var IURLGenerator */
+ private $urlGenerator;
+ /** @var IL10N */
+ private $l10n;
+ /** @var Checker */
+ private $checker;
+
+ /**
+ * @param string $AppName
+ * @param IRequest $request
+ * @param IConfig $config
+ * @param IClientService $clientService
+ * @param IURLGenerator $urlGenerator
+ * @param \OC_Util $util
+ * @param IL10N $l10n
+ * @param Checker $checker
+ */
+ public function __construct($AppName,
+ IRequest $request,
+ IConfig $config,
+ IClientService $clientService,
+ IURLGenerator $urlGenerator,
+ \OC_Util $util,
+ IL10N $l10n,
+ Checker $checker) {
+ parent::__construct($AppName, $request);
+ $this->config = $config;
+ $this->clientService = $clientService;
+ $this->util = $util;
+ $this->urlGenerator = $urlGenerator;
+ $this->l10n = $l10n;
+ $this->checker = $checker;
+ }
+
+ /**
+ * Checks if the ownCloud server can connect to the internet using HTTPS and HTTP
+ * @return bool
+ */
+ private function isInternetConnectionWorking() {
+ if ($this->config->getSystemValue('has_internet_connection', true) === false) {
+ return false;
+ }
+
+ try {
+ $client = $this->clientService->newClient();
+ $client->get('https://www.owncloud.org/');
+ $client->get('http://www.owncloud.org/');
+ return true;
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Checks whether a local memcache is installed or not
+ * @return bool
+ */
+ private function isMemcacheConfigured() {
+ return $this->config->getSystemValue('memcache.local', null) !== null;
+ }
+
+ /**
+ * Whether /dev/urandom is available to the PHP controller
+ *
+ * @return bool
+ */
+ private function isUrandomAvailable() {
+ if(@file_exists('/dev/urandom')) {
+ $file = fopen('/dev/urandom', 'rb');
+ if($file) {
+ fclose($file);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Public for the sake of unit-testing
+ *
+ * @return array
+ */
+ protected function getCurlVersion() {
+ return curl_version();
+ }
+
+ /**
+ * Check if the used SSL lib is outdated. Older OpenSSL and NSS versions do
+ * have multiple bugs which likely lead to problems in combination with
+ * functionality required by ownCloud such as SNI.
+ *
+ * @link https://github.com/owncloud/core/issues/17446#issuecomment-122877546
+ * @link https://bugzilla.redhat.com/show_bug.cgi?id=1241172
+ * @return string
+ */
+ private function isUsedTlsLibOutdated() {
+ // Appstore is disabled by default in EE
+ $appStoreDefault = false;
+ if (\OC_Util::getEditionString() === '') {
+ $appStoreDefault = true;
+ }
+
+ // Don't run check when:
+ // 1. Server has `has_internet_connection` set to false
+ // 2. AppStore AND S2S is disabled
+ if(!$this->config->getSystemValue('has_internet_connection', true)) {
+ return '';
+ }
+ if(!$this->config->getSystemValue('appstoreenabled', $appStoreDefault)
+ && $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'no'
+ && $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'no') {
+ return '';
+ }
+
+ $versionString = $this->getCurlVersion();
+ if(isset($versionString['ssl_version'])) {
+ $versionString = $versionString['ssl_version'];
+ } else {
+ return '';
+ }
+
+ $features = (string)$this->l10n->t('installing and updating apps via the app store or Federated Cloud Sharing');
+ if(!$this->config->getSystemValue('appstoreenabled', $appStoreDefault)) {
+ $features = (string)$this->l10n->t('Federated Cloud Sharing');
+ }
+
+ // Check if at least OpenSSL after 1.01d or 1.0.2b
+ if(strpos($versionString, 'OpenSSL/') === 0) {
+ $majorVersion = substr($versionString, 8, 5);
+ $patchRelease = substr($versionString, 13, 6);
+
+ if(($majorVersion === '1.0.1' && ord($patchRelease) < ord('d')) ||
+ ($majorVersion === '1.0.2' && ord($patchRelease) < ord('b'))) {
+ return (string) $this->l10n->t('cURL is using an outdated %s version (%s). Please update your operating system or features such as %s will not work reliably.', ['OpenSSL', $versionString, $features]);
+ }
+ }
+
+ // Check if NSS and perform heuristic check
+ if(strpos($versionString, 'NSS/') === 0) {
+ try {
+ $firstClient = $this->clientService->newClient();
+ $firstClient->get('https://www.owncloud.org/');
+
+ $secondClient = $this->clientService->newClient();
+ $secondClient->get('https://owncloud.org/');
+ } catch (ClientException $e) {
+ if($e->getResponse()->getStatusCode() === 400) {
+ return (string) $this->l10n->t('cURL is using an outdated %s version (%s). Please update your operating system or features such as %s will not work reliably.', ['NSS', $versionString, $features]);
+ }
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * Whether the php version is still supported (at time of release)
+ * according to: https://secure.php.net/supported-versions.php
+ *
+ * @return array
+ */
+ private function isPhpSupported() {
+ $eol = false;
+
+ //PHP 5.4 is EOL on 14 Sep 2015
+ if (version_compare(PHP_VERSION, '5.5.0') === -1) {
+ $eol = true;
+ }
+
+ return ['eol' => $eol, 'version' => PHP_VERSION];
+ }
+
+ /**
+ * Check if the reverse proxy configuration is working as expected
+ *
+ * @return bool
+ */
+ private function forwardedForHeadersWorking() {
+ $trustedProxies = $this->config->getSystemValue('trusted_proxies', []);
+ $remoteAddress = $this->request->getRemoteAddress();
+
+ if (is_array($trustedProxies) && in_array($remoteAddress, $trustedProxies)) {
+ return false;
+ }
+
+ // either not enabled or working correctly
+ return true;
+ }
+
+ /**
+ * Checks if the correct memcache module for PHP is installed. Only
+ * fails if memcached is configured and the working module is not installed.
+ *
+ * @return bool
+ */
+ private function isCorrectMemcachedPHPModuleInstalled() {
+ if ($this->config->getSystemValue('memcache.distributed', null) !== '\OC\Memcache\Memcached') {
+ return true;
+ }
+
+ // there are two different memcached modules for PHP
+ // we only support memcached and not memcache
+ // https://code.google.com/p/memcached/wiki/PHPClientComparison
+ return !(!extension_loaded('memcached') && extension_loaded('memcache'));
+ }
+
+ /**
+ * @return RedirectResponse
+ */
+ public function rescanFailedIntegrityCheck() {
+ $this->checker->runInstanceVerification();
+ return new RedirectResponse(
+ $this->urlGenerator->linkToRoute('settings_admin')
+ );
+ }
+
+ /**
+ * @NoCSRFRequired
+ * @return DataResponse
+ */
+ public function getFailedIntegrityCheckFiles() {
+ if(!$this->checker->isCodeCheckEnforced()) {
+ return new DataDisplayResponse('Integrity checker has been disabled. Integrity cannot be verified.');
+ }
+
+ $completeResults = $this->checker->getResults();
+
+ if(!empty($completeResults)) {
+ $formattedTextResponse = 'Technical information
+=====================
+The following list covers which files have failed the integrity check. Please read
+the previous linked documentation to learn more about the errors and how to fix
+them.
+
+Results
+=======
+';
+ foreach($completeResults as $context => $contextResult) {
+ $formattedTextResponse .= "- $context\n";
+
+ foreach($contextResult as $category => $result) {
+ $formattedTextResponse .= "\t- $category\n";
+ if($category !== 'EXCEPTION') {
+ foreach ($result as $key => $results) {
+ $formattedTextResponse .= "\t\t- $key\n";
+ }
+ } else {
+ foreach ($result as $key => $results) {
+ $formattedTextResponse .= "\t\t- $results\n";
+ }
+ }
+
+ }
+ }
+
+ $formattedTextResponse .= '
+Raw output
+==========
+';
+ $formattedTextResponse .= print_r($completeResults, true);
+ } else {
+ $formattedTextResponse = 'No errors have been found.';
+ }
+
+
+ $response = new DataDisplayResponse(
+ $formattedTextResponse,
+ Http::STATUS_OK,
+ [
+ 'Content-Type' => 'text/plain',
+ ]
+ );
+
+ return $response;
+ }
+
+ /**
+ * @return DataResponse
+ */
+ public function check() {
+ return new DataResponse(
+ [
+ 'serverHasInternetConnection' => $this->isInternetConnectionWorking(),
+ 'isMemcacheConfigured' => $this->isMemcacheConfigured(),
+ 'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
+ 'isUrandomAvailable' => $this->isUrandomAvailable(),
+ 'securityDocs' => $this->urlGenerator->linkToDocs('admin-security'),
+ 'isUsedTlsLibOutdated' => $this->isUsedTlsLibOutdated(),
+ 'phpSupported' => $this->isPhpSupported(),
+ 'forwardedForHeadersWorking' => $this->forwardedForHeadersWorking(),
+ 'reverseProxyDocs' => $this->urlGenerator->linkToDocs('admin-reverse-proxy'),
+ 'isCorrectMemcachedPHPModuleInstalled' => $this->isCorrectMemcachedPHPModuleInstalled(),
+ 'hasPassedCodeIntegrityCheck' => $this->checker->hasPassedCheck(),
+ 'codeIntegrityCheckerDocumentation' => $this->urlGenerator->linkToDocs('admin-code-integrity'),
+ ]
+ );
+ }
+}