2013-08-21 02:58:15 +04:00
|
|
|
<?php
|
2015-03-26 13:44:34 +03:00
|
|
|
/**
|
2016-07-21 18:07:57 +03:00
|
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
|
|
|
*
|
2016-05-26 20:56:05 +03:00
|
|
|
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Bart Visscher <bartv@thisnet.nl>
|
|
|
|
* @author Bernhard Posselt <dev@bernhard-posselt.com>
|
|
|
|
* @author Bernhard Reiter <ockham@raz.or.at>
|
2016-07-21 18:07:57 +03:00
|
|
|
* @author Bjoern Schiessle <bjoern@schiessle.org>
|
2016-05-26 20:56:05 +03:00
|
|
|
* @author Björn Schießle <bjoern@schiessle.org>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Christopher Schäpers <kondou@ts.unde.re>
|
2016-07-21 18:07:57 +03:00
|
|
|
* @author Christoph Wurst <christoph@owncloud.com>
|
|
|
|
* @author Joas Schilling <coding@schilljs.com>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
2016-05-26 20:56:05 +03:00
|
|
|
* @author Lukas Reschke <lukas@statuscode.ch>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Morris Jobke <hey@morrisjobke.de>
|
2016-07-21 19:13:36 +03:00
|
|
|
* @author Robin Appelman <robin@icewind.nl>
|
2016-01-12 17:02:16 +03:00
|
|
|
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
2016-07-21 18:07:57 +03:00
|
|
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
2015-03-26 13:44:34 +03:00
|
|
|
* @author Sander <brantje@gmail.com>
|
|
|
|
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
|
|
|
* @author Thomas Tanghus <thomas@tanghus.net>
|
|
|
|
* @author Vincent Petry <pvince81@owncloud.com>
|
|
|
|
*
|
|
|
|
* @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/>
|
|
|
|
*
|
|
|
|
*/
|
2013-08-21 02:58:15 +04:00
|
|
|
namespace OC;
|
|
|
|
|
2014-12-05 21:56:29 +03:00
|
|
|
use bantu\IniGetWrapper\IniGetWrapper;
|
2013-09-05 01:45:11 +04:00
|
|
|
use OC\AppFramework\Http\Request;
|
2014-04-19 21:30:12 +04:00
|
|
|
use OC\AppFramework\Db\Db;
|
2015-08-21 19:27:52 +03:00
|
|
|
use OC\AppFramework\Utility\TimeFactory;
|
2015-02-17 18:49:14 +03:00
|
|
|
use OC\Command\AsyncBus;
|
2014-10-03 22:39:09 +04:00
|
|
|
use OC\Diagnostics\EventLogger;
|
2015-06-11 12:29:27 +03:00
|
|
|
use OC\Diagnostics\NullEventLogger;
|
|
|
|
use OC\Diagnostics\NullQueryLogger;
|
2014-10-03 22:39:09 +04:00
|
|
|
use OC\Diagnostics\QueryLogger;
|
2015-11-26 19:47:53 +03:00
|
|
|
use OC\Files\Config\UserMountCache;
|
2015-12-03 16:10:05 +03:00
|
|
|
use OC\Files\Config\UserMountCacheListener;
|
2016-04-21 15:48:08 +03:00
|
|
|
use OC\Files\Mount\CacheMountProvider;
|
2016-05-17 22:40:55 +03:00
|
|
|
use OC\Files\Mount\LocalHomeMountProvider;
|
|
|
|
use OC\Files\Mount\ObjectHomeMountProvider;
|
2015-09-28 18:17:44 +03:00
|
|
|
use OC\Files\Node\HookConnector;
|
2016-03-11 16:00:36 +03:00
|
|
|
use OC\Files\Node\LazyRoot;
|
2015-06-11 12:29:27 +03:00
|
|
|
use OC\Files\Node\Root;
|
|
|
|
use OC\Files\View;
|
|
|
|
use OC\Http\Client\ClientService;
|
Add code integrity check
This PR implements the base foundation of the code signing and integrity check. In this PR implemented is the signing and verification logic, as well as commands to sign single apps or the core repository.
Furthermore, there is a basic implementation to display problems with the code integrity on the update screen.
Code signing basically happens the following way:
- There is a ownCloud Root Certificate authority stored `resources/codesigning/root.crt` (in this PR I also ship the private key which we obviously need to change before a release :wink:). This certificate is not intended to be used for signing directly and only is used to sign new certificates.
- Using the `integrity:sign-core` and `integrity:sign-app` commands developers can sign either the core release or a single app. The core release needs to be signed with a certificate that has a CN of `core`, apps need to be signed with a certificate that either has a CN of `core` (shipped apps!) or the AppID.
- The command generates a signature.json file of the following format:
```json
{
"hashes": {
"/filename.php": "2401fed2eea6f2c1027c482a633e8e25cd46701f811e2d2c10dc213fd95fa60e350bccbbebdccc73a042b1a2799f673fbabadc783284cc288e4f1a1eacb74e3d",
"/lib/base.php": "55548cc16b457cd74241990cc9d3b72b6335f2e5f45eee95171da024087d114fcbc2effc3d5818a6d5d55f2ae960ab39fd0414d0c542b72a3b9e08eb21206dd9"
},
"certificate": "-----BEGIN CERTIFICATE-----MIIBvTCCASagAwIBAgIUPvawyqJwCwYazcv7iz16TWxfeUMwDQYJKoZIhvcNAQEF\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTAx\nNDEzMTcxMFoXDTE2MTAxNDEzMTcxMFowEzERMA8GA1UEAwwIY29udGFjdHMwgZ8w\nDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANoQesGdCW0L2L+a2xITYipixkScrIpB\nkX5Snu3fs45MscDb61xByjBSlFgR4QI6McoCipPw4SUr28EaExVvgPSvqUjYLGps\nfiv0Cvgquzbx/X3mUcdk9LcFo1uWGtrTfkuXSKX41PnJGTr6RQWGIBd1V52q1qbC\nJKkfzyeMeuQfAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvF/KIhRMQ3tYTmgHWsiM\nwDMgIDb7iaHF0fS+/Nvo4PzoTO/trev6tMyjLbJ7hgdCpz/1sNzE11Cibf6V6dsz\njCE9invP368Xv0bTRObRqeSNsGogGl5ceAvR0c9BG+NRIKHcly3At3gLkS2791bC\niG+UxI/MNcWV0uJg9S63LF8=\n-----END CERTIFICATE-----",
"signature": "U29tZVNpZ25lZERhdGFFeGFtcGxl"
}
```
`hashes` is an array of all files in the folder with their corresponding SHA512 hashes (this is actually quite cheap to calculate), the `certificate` is the certificate used for signing. It has to be issued by the ownCloud Root Authority and it's CN needs to be permitted to perform the required action. The `signature` is then a signature of the `hashes` which can be verified using the `certificate`.
Steps to do in other PRs, this is already a quite huge one:
- Add nag screen in case the code check fails to ensure that administrators are aware of this.
- Add code verification also to OCC upgrade and unify display code more.
- Add enforced code verification to apps shipped from the appstore with a level of "official"
- Add enfocrced code verification to apps shipped from the appstore that were already signed in a previous release
- Add some developer documentation on how devs can request their own certificate
- Check when installing ownCloud
- Add support for CRLs to allow revoking certificates
**Note:** The upgrade checks are only run when the instance has a defined release channel of `stable` (defined in `version.php`). If you want to test this, you need to change the channel thus and then generate the core signature:
```
➜ master git:(add-integrity-checker) ✗ ./occ integrity:sign-core --privateKey=resources/codesigning/core.key --certificate=resources/codesigning/core.crt
Successfully signed "core"
```
Then increase the version and you should see something like the following:
![2015-11-04_12-02-57](https://cloud.githubusercontent.com/assets/878997/10936336/6adb1d14-82ec-11e5-8f06-9a74801c9abf.png)
As you can see a failed code check will not prevent the further update. It will instead just be a notice to the admin. In a next step we will add some nag screen.
For packaging stable releases this requires the following additional steps as a last action before zipping:
1. Run `./occ integrity:sign-core` once
2. Run `./occ integrity:sign-app` _for each_ app. However, this can be simply automated using a simple foreach on the apps folder.
2015-11-03 22:26:06 +03:00
|
|
|
use OC\IntegrityCheck\Checker;
|
|
|
|
use OC\IntegrityCheck\Helpers\AppLocator;
|
|
|
|
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
|
|
|
|
use OC\IntegrityCheck\Helpers\FileAccessHelper;
|
2015-07-15 17:14:48 +03:00
|
|
|
use OC\Lock\DBLockingProvider;
|
2015-05-04 15:02:27 +03:00
|
|
|
use OC\Lock\MemcacheLockingProvider;
|
2015-05-21 17:11:10 +03:00
|
|
|
use OC\Lock\NoopLockingProvider;
|
2015-02-12 15:53:27 +03:00
|
|
|
use OC\Mail\Mailer;
|
2016-03-31 00:20:37 +03:00
|
|
|
use OC\Memcache\ArrayCache;
|
2015-08-31 13:24:37 +03:00
|
|
|
use OC\Notification\Manager;
|
2016-07-20 19:36:15 +03:00
|
|
|
use OC\Security\Bruteforce\Throttler;
|
2014-08-18 18:30:23 +04:00
|
|
|
use OC\Security\CertificateManager;
|
2016-01-28 16:33:02 +03:00
|
|
|
use OC\Security\CSP\ContentSecurityPolicyManager;
|
2014-08-26 21:02:40 +04:00
|
|
|
use OC\Security\Crypto;
|
2016-01-25 19:15:54 +03:00
|
|
|
use OC\Security\CSRF\CsrfTokenGenerator;
|
|
|
|
use OC\Security\CSRF\CsrfTokenManager;
|
|
|
|
use OC\Security\CSRF\TokenStorage\SessionStorage;
|
2014-11-04 18:05:31 +03:00
|
|
|
use OC\Security\Hasher;
|
2015-08-24 18:13:16 +03:00
|
|
|
use OC\Security\CredentialsManager;
|
2014-08-26 21:02:40 +04:00
|
|
|
use OC\Security\SecureRandom;
|
2015-02-17 00:12:47 +03:00
|
|
|
use OC\Security\TrustedDomainHelper;
|
2015-07-20 13:59:04 +03:00
|
|
|
use OC\Session\CryptoWrapper;
|
2014-09-08 21:58:43 +04:00
|
|
|
use OC\Tagging\TagMapper;
|
2016-06-21 22:21:46 +03:00
|
|
|
use OCA\Theming\Template;
|
2016-04-14 16:38:00 +03:00
|
|
|
use OCP\IL10N;
|
2015-06-11 12:29:27 +03:00
|
|
|
use OCP\IServerContainer;
|
2016-01-28 16:33:02 +03:00
|
|
|
use OCP\Security\IContentSecurityPolicyManager;
|
2015-08-14 16:40:15 +03:00
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
2013-08-21 02:58:15 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class Server
|
2014-07-16 16:25:31 +04:00
|
|
|
*
|
2013-08-21 02:58:15 +04:00
|
|
|
* @package OC
|
|
|
|
*
|
|
|
|
* TODO: hookup all manager classes
|
|
|
|
*/
|
2015-12-18 13:43:39 +03:00
|
|
|
class Server extends ServerContainer implements IServerContainer {
|
2014-11-27 16:50:14 +03:00
|
|
|
/** @var string */
|
|
|
|
private $webRoot;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $webRoot
|
2015-12-18 13:24:15 +03:00
|
|
|
* @param \OC\Config $config
|
2014-11-27 16:50:14 +03:00
|
|
|
*/
|
2015-12-18 13:24:15 +03:00
|
|
|
public function __construct($webRoot, \OC\Config $config) {
|
2015-07-24 14:43:50 +03:00
|
|
|
parent::__construct();
|
2014-11-27 16:50:14 +03:00
|
|
|
$this->webRoot = $webRoot;
|
|
|
|
|
2014-07-16 16:25:31 +04:00
|
|
|
$this->registerService('ContactsManager', function ($c) {
|
2013-08-27 01:48:18 +04:00
|
|
|
return new ContactsManager();
|
|
|
|
});
|
2015-01-14 22:39:23 +03:00
|
|
|
|
2015-03-12 14:08:31 +03:00
|
|
|
$this->registerService('PreviewManager', function (Server $c) {
|
|
|
|
return new PreviewManager($c->getConfig());
|
2013-09-05 01:45:11 +04:00
|
|
|
});
|
2015-01-14 22:39:23 +03:00
|
|
|
|
|
|
|
$this->registerService('EncryptionManager', function (Server $c) {
|
2015-07-24 13:24:18 +03:00
|
|
|
$view = new View();
|
|
|
|
$util = new Encryption\Util(
|
|
|
|
$view,
|
|
|
|
$c->getUserManager(),
|
|
|
|
$c->getGroupManager(),
|
|
|
|
$c->getConfig()
|
|
|
|
);
|
|
|
|
return new Encryption\Manager(
|
|
|
|
$c->getConfig(),
|
|
|
|
$c->getLogger(),
|
|
|
|
$c->getL10N('core'),
|
|
|
|
new View(),
|
2016-03-31 00:20:37 +03:00
|
|
|
$util,
|
|
|
|
new ArrayCache()
|
2015-07-24 13:24:18 +03:00
|
|
|
);
|
2015-01-14 22:39:23 +03:00
|
|
|
});
|
|
|
|
|
2015-03-31 17:23:31 +03:00
|
|
|
$this->registerService('EncryptionFileHelper', function (Server $c) {
|
2015-07-24 13:24:18 +03:00
|
|
|
$util = new Encryption\Util(
|
|
|
|
new View(),
|
2015-04-15 14:19:17 +03:00
|
|
|
$c->getUserManager(),
|
|
|
|
$c->getGroupManager(),
|
|
|
|
$c->getConfig()
|
|
|
|
);
|
2015-03-31 17:23:31 +03:00
|
|
|
return new Encryption\File($util);
|
|
|
|
});
|
|
|
|
|
2015-04-22 12:18:18 +03:00
|
|
|
$this->registerService('EncryptionKeyStorage', function (Server $c) {
|
2015-07-24 13:24:18 +03:00
|
|
|
$view = new View();
|
|
|
|
$util = new Encryption\Util(
|
2015-04-22 12:18:18 +03:00
|
|
|
$view,
|
|
|
|
$c->getUserManager(),
|
|
|
|
$c->getGroupManager(),
|
|
|
|
$c->getConfig()
|
|
|
|
);
|
|
|
|
|
|
|
|
return new Encryption\Keys\Storage($view, $util);
|
2015-01-14 22:39:23 +03:00
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('TagMapper', function (Server $c) {
|
2015-02-25 15:18:36 +03:00
|
|
|
return new TagMapper($c->getDatabaseConnection());
|
2014-09-08 21:58:43 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('TagManager', function (Server $c) {
|
2014-09-08 21:58:43 +04:00
|
|
|
$tagMapper = $c->query('TagMapper');
|
2014-12-10 17:59:41 +03:00
|
|
|
return new TagManager($tagMapper, $c->getUserSession());
|
2013-09-18 02:37:00 +04:00
|
|
|
});
|
2016-01-19 18:17:49 +03:00
|
|
|
$this->registerService('SystemTagManagerFactory', function (Server $c) {
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$factoryClass = $config->getSystemValue('systemtags.managerFactory', '\OC\SystemTag\ManagerFactory');
|
|
|
|
/** @var \OC\SystemTag\ManagerFactory $factory */
|
|
|
|
$factory = new $factoryClass($this);
|
|
|
|
return $factory;
|
|
|
|
});
|
2015-11-26 17:49:14 +03:00
|
|
|
$this->registerService('SystemTagManager', function (Server $c) {
|
2016-01-19 18:17:49 +03:00
|
|
|
return $c->query('SystemTagManagerFactory')->getManager();
|
2015-11-26 17:49:14 +03:00
|
|
|
});
|
|
|
|
$this->registerService('SystemTagObjectMapper', function (Server $c) {
|
2016-01-19 18:17:49 +03:00
|
|
|
return $c->query('SystemTagManagerFactory')->getObjectMapper();
|
2015-11-26 17:49:14 +03:00
|
|
|
});
|
2016-02-18 15:55:28 +03:00
|
|
|
$this->registerService('RootFolder', function () {
|
2016-02-18 11:21:32 +03:00
|
|
|
$manager = \OC\Files\Filesystem::getMountManager(null);
|
2013-09-16 00:24:57 +04:00
|
|
|
$view = new View();
|
2016-02-18 11:21:32 +03:00
|
|
|
$root = new Root($manager, $view, null);
|
2015-09-28 18:17:44 +03:00
|
|
|
$connector = new HookConnector($root, $view);
|
|
|
|
$connector->viewToNode();
|
|
|
|
return $root;
|
2013-09-16 00:24:57 +04:00
|
|
|
});
|
2016-03-11 16:00:36 +03:00
|
|
|
$this->registerService('LazyRootFolder', function(Server $c) {
|
|
|
|
return new LazyRoot(function() use ($c) {
|
|
|
|
return $c->getRootFolder();
|
|
|
|
});
|
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('UserManager', function (Server $c) {
|
|
|
|
$config = $c->getConfig();
|
2013-12-16 17:22:25 +04:00
|
|
|
return new \OC\User\Manager($config);
|
2013-09-20 14:45:56 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('GroupManager', function (Server $c) {
|
2014-12-04 16:15:55 +03:00
|
|
|
$groupManager = new \OC\Group\Manager($this->getUserManager());
|
|
|
|
$groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
|
|
|
|
\OC_Hook::emit('OC_Group', 'pre_createGroup', array('run' => true, 'gid' => $gid));
|
|
|
|
});
|
|
|
|
$groupManager->listen('\OC\Group', 'postCreate', function (\OC\Group\Group $gid) {
|
|
|
|
\OC_Hook::emit('OC_User', 'post_createGroup', array('gid' => $gid->getGID()));
|
|
|
|
});
|
|
|
|
$groupManager->listen('\OC\Group', 'preDelete', function (\OC\Group\Group $group) {
|
|
|
|
\OC_Hook::emit('OC_Group', 'pre_deleteGroup', array('run' => true, 'gid' => $group->getGID()));
|
|
|
|
});
|
|
|
|
$groupManager->listen('\OC\Group', 'postDelete', function (\OC\Group\Group $group) {
|
|
|
|
\OC_Hook::emit('OC_User', 'post_deleteGroup', array('gid' => $group->getGID()));
|
|
|
|
});
|
|
|
|
$groupManager->listen('\OC\Group', 'preAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
|
|
|
|
\OC_Hook::emit('OC_Group', 'pre_addToGroup', array('run' => true, 'uid' => $user->getUID(), 'gid' => $group->getGID()));
|
|
|
|
});
|
|
|
|
$groupManager->listen('\OC\Group', 'postAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
|
|
|
|
\OC_Hook::emit('OC_Group', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
|
2015-07-02 17:25:11 +03:00
|
|
|
//Minimal fix to keep it backward compatible TODO: clean up all the GroupManager hooks
|
|
|
|
\OC_Hook::emit('OC_User', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
|
2014-12-04 16:15:55 +03:00
|
|
|
});
|
|
|
|
return $groupManager;
|
2014-07-16 16:25:31 +04:00
|
|
|
});
|
2016-04-25 17:40:41 +03:00
|
|
|
$this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) {
|
2016-04-25 15:10:55 +03:00
|
|
|
$dbConnection = $c->getDatabaseConnection();
|
|
|
|
return new Authentication\Token\DefaultTokenMapper($dbConnection);
|
|
|
|
});
|
2016-04-25 17:40:41 +03:00
|
|
|
$this->registerService('OC\Authentication\Token\DefaultTokenProvider', function (Server $c) {
|
|
|
|
$mapper = $c->query('OC\Authentication\Token\DefaultTokenMapper');
|
2016-04-25 15:10:55 +03:00
|
|
|
$crypto = $c->getCrypto();
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$logger = $c->getLogger();
|
2016-05-02 20:58:19 +03:00
|
|
|
$timeFactory = new TimeFactory();
|
|
|
|
return new \OC\Authentication\Token\DefaultTokenProvider($mapper, $crypto, $config, $logger, $timeFactory);
|
2016-04-25 15:10:55 +03:00
|
|
|
});
|
2016-05-18 13:03:22 +03:00
|
|
|
$this->registerAlias('OC\Authentication\Token\IProvider', 'OC\Authentication\Token\DefaultTokenProvider');
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('UserSession', function (Server $c) {
|
|
|
|
$manager = $c->getUserManager();
|
2015-07-20 13:59:04 +03:00
|
|
|
$session = new \OC\Session\Memory('');
|
2016-05-02 20:58:19 +03:00
|
|
|
$timeFactory = new TimeFactory();
|
2016-04-27 13:01:13 +03:00
|
|
|
// Token providers might require a working database. This code
|
|
|
|
// might however be called when ownCloud is not yet setup.
|
|
|
|
if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
|
2016-05-18 13:03:22 +03:00
|
|
|
$defaultTokenProvider = $c->query('OC\Authentication\Token\IProvider');
|
2016-04-27 13:01:13 +03:00
|
|
|
} else {
|
|
|
|
$defaultTokenProvider = null;
|
|
|
|
}
|
2016-06-24 18:53:37 +03:00
|
|
|
|
2016-05-24 15:08:42 +03:00
|
|
|
$userSession = new \OC\User\Session($manager, $session, $timeFactory, $defaultTokenProvider, $c->getConfig());
|
2013-09-20 14:45:56 +04:00
|
|
|
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
|
|
|
|
\OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
|
|
|
|
/** @var $user \OC\User\User */
|
|
|
|
\OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'preDelete', function ($user) {
|
|
|
|
/** @var $user \OC\User\User */
|
|
|
|
\OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'postDelete', function ($user) {
|
|
|
|
/** @var $user \OC\User\User */
|
|
|
|
\OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
|
|
|
|
/** @var $user \OC\User\User */
|
|
|
|
\OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
|
|
|
|
/** @var $user \OC\User\User */
|
|
|
|
\OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
|
|
|
|
\OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
|
|
|
|
/** @var $user \OC\User\User */
|
|
|
|
\OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
|
|
|
|
});
|
|
|
|
$userSession->listen('\OC\User', 'logout', function () {
|
|
|
|
\OC_Hook::emit('OC_User', 'logout', array());
|
|
|
|
});
|
2016-02-09 20:37:41 +03:00
|
|
|
$userSession->listen('\OC\User', 'changeUser', function ($user, $feature, $value) {
|
2016-01-18 22:27:43 +03:00
|
|
|
/** @var $user \OC\User\User */
|
2016-02-09 20:37:41 +03:00
|
|
|
\OC_Hook::emit('OC_User', 'changeUser', array('run' => true, 'user' => $user, 'feature' => $feature, 'value' => $value));
|
2016-01-18 22:27:43 +03:00
|
|
|
});
|
2013-09-20 14:45:56 +04:00
|
|
|
return $userSession;
|
|
|
|
});
|
2016-05-11 12:23:25 +03:00
|
|
|
|
|
|
|
$this->registerService('\OC\Authentication\TwoFactorAuth\Manager', function (Server $c) {
|
2016-05-17 16:48:41 +03:00
|
|
|
return new \OC\Authentication\TwoFactorAuth\Manager($c->getAppManager(), $c->getSession(), $c->getConfig());
|
2016-05-11 12:23:25 +03:00
|
|
|
});
|
|
|
|
|
2014-07-16 16:25:31 +04:00
|
|
|
$this->registerService('NavigationManager', function ($c) {
|
2013-09-20 19:34:33 +04:00
|
|
|
return new \OC\NavigationManager();
|
|
|
|
});
|
2014-11-27 18:40:12 +03:00
|
|
|
$this->registerService('AllConfig', function (Server $c) {
|
|
|
|
return new \OC\AllConfig(
|
2014-12-04 11:35:01 +03:00
|
|
|
$c->getSystemConfig()
|
2014-11-27 18:40:12 +03:00
|
|
|
);
|
|
|
|
});
|
2015-12-18 13:24:15 +03:00
|
|
|
$this->registerService('SystemConfig', function ($c) use ($config) {
|
|
|
|
return new \OC\SystemConfig($config);
|
2013-09-20 22:21:24 +04:00
|
|
|
});
|
2016-01-07 12:26:00 +03:00
|
|
|
$this->registerService('AppConfig', function (Server $c) {
|
|
|
|
return new \OC\AppConfig($c->getDatabaseConnection());
|
2014-02-07 16:42:18 +04:00
|
|
|
});
|
2016-01-15 13:09:37 +03:00
|
|
|
$this->registerService('L10NFactory', function (Server $c) {
|
|
|
|
return new \OC\L10N\Factory(
|
|
|
|
$c->getConfig(),
|
2016-01-27 17:54:57 +03:00
|
|
|
$c->getRequest(),
|
2016-03-18 15:59:44 +03:00
|
|
|
$c->getUserSession(),
|
|
|
|
\OC::$SERVERROOT
|
2016-01-15 13:09:37 +03:00
|
|
|
);
|
2013-09-25 20:34:01 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('URLGenerator', function (Server $c) {
|
|
|
|
$config = $c->getConfig();
|
2015-03-17 14:35:47 +03:00
|
|
|
$cacheFactory = $c->getMemCacheFactory();
|
|
|
|
return new \OC\URLGenerator(
|
|
|
|
$config,
|
|
|
|
$cacheFactory
|
|
|
|
);
|
2013-09-26 20:41:19 +04:00
|
|
|
});
|
2014-07-16 16:25:31 +04:00
|
|
|
$this->registerService('AppHelper', function ($c) {
|
2013-09-26 20:41:19 +04:00
|
|
|
return new \OC\AppHelper();
|
|
|
|
});
|
2015-06-15 18:54:48 +03:00
|
|
|
$this->registerService('UserCache', function ($c) {
|
|
|
|
return new Cache\File();
|
2013-09-17 19:46:33 +04:00
|
|
|
});
|
2015-03-18 13:47:16 +03:00
|
|
|
$this->registerService('MemCacheFactory', function (Server $c) {
|
2015-01-14 21:25:00 +03:00
|
|
|
$config = $c->getConfig();
|
2015-03-18 13:47:16 +03:00
|
|
|
|
2015-12-03 16:10:05 +03:00
|
|
|
if ($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
|
2015-03-18 13:47:16 +03:00
|
|
|
$v = \OC_App::getAppVersions();
|
2015-09-08 22:15:08 +03:00
|
|
|
$v['core'] = md5(file_get_contents(\OC::$SERVERROOT . '/version.php'));
|
2015-03-18 13:47:16 +03:00
|
|
|
$version = implode(',', $v);
|
|
|
|
$instanceId = \OC_Util::getInstanceId();
|
|
|
|
$path = \OC::$SERVERROOT;
|
2015-12-03 16:10:05 +03:00
|
|
|
$prefix = md5($instanceId . '-' . $version . '-' . $path);
|
2015-07-15 17:21:07 +03:00
|
|
|
return new \OC\Memcache\Factory($prefix, $c->getLogger(),
|
2015-03-18 13:47:16 +03:00
|
|
|
$config->getSystemValue('memcache.local', null),
|
2015-05-26 15:41:37 +03:00
|
|
|
$config->getSystemValue('memcache.distributed', null),
|
|
|
|
$config->getSystemValue('memcache.locking', null)
|
2015-03-18 13:47:16 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2015-07-15 17:21:07 +03:00
|
|
|
return new \OC\Memcache\Factory('', $c->getLogger(),
|
2015-07-16 00:55:30 +03:00
|
|
|
'\\OC\\Memcache\\ArrayCache',
|
|
|
|
'\\OC\\Memcache\\ArrayCache',
|
|
|
|
'\\OC\\Memcache\\ArrayCache'
|
2015-01-14 21:25:00 +03:00
|
|
|
);
|
2014-01-06 15:55:56 +04:00
|
|
|
});
|
2016-04-14 16:41:04 +03:00
|
|
|
$this->registerService('RedisFactory', function (Server $c) {
|
|
|
|
$systemConfig = $c->getSystemConfig();
|
|
|
|
return new RedisFactory($systemConfig);
|
|
|
|
});
|
2015-03-25 17:18:11 +03:00
|
|
|
$this->registerService('ActivityManager', function (Server $c) {
|
2016-05-02 12:57:24 +03:00
|
|
|
return new \OC\Activity\Manager(
|
2015-03-25 17:18:11 +03:00
|
|
|
$c->getRequest(),
|
|
|
|
$c->getUserSession(),
|
|
|
|
$c->getConfig()
|
|
|
|
);
|
2013-09-29 22:31:12 +04:00
|
|
|
});
|
2015-12-02 00:08:42 +03:00
|
|
|
$this->registerService('AvatarManager', function (Server $c) {
|
|
|
|
return new AvatarManager(
|
|
|
|
$c->getUserManager(),
|
|
|
|
$c->getRootFolder(),
|
2016-03-11 15:44:35 +03:00
|
|
|
$c->getL10N('lib'),
|
|
|
|
$c->getLogger()
|
2015-12-02 00:08:42 +03:00
|
|
|
);
|
2013-09-20 13:46:11 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('Logger', function (Server $c) {
|
2014-05-07 03:55:06 +04:00
|
|
|
$logClass = $c->query('AllConfig')->getSystemValue('log_type', 'owncloud');
|
2016-05-02 15:04:58 +03:00
|
|
|
$logger = 'OC\\Log\\' . ucfirst($logClass);
|
2014-05-07 03:55:06 +04:00
|
|
|
call_user_func(array($logger, 'init'));
|
|
|
|
|
|
|
|
return new Log($logger);
|
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('JobList', function (Server $c) {
|
2014-02-11 17:00:24 +04:00
|
|
|
$config = $c->getConfig();
|
2016-05-18 15:27:48 +03:00
|
|
|
return new \OC\BackgroundJob\JobList(
|
|
|
|
$c->getDatabaseConnection(),
|
|
|
|
$config,
|
|
|
|
new TimeFactory()
|
|
|
|
);
|
2014-02-11 17:00:24 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('Router', function (Server $c) {
|
2014-03-24 17:55:03 +04:00
|
|
|
$cacheFactory = $c->getMemCacheFactory();
|
2015-11-27 15:51:20 +03:00
|
|
|
$logger = $c->getLogger();
|
2014-03-24 17:55:03 +04:00
|
|
|
if ($cacheFactory->isAvailable()) {
|
2015-11-27 15:51:20 +03:00
|
|
|
$router = new \OC\Route\CachingRouter($cacheFactory->create('route'), $logger);
|
2014-03-24 17:55:03 +04:00
|
|
|
} else {
|
2015-11-27 15:51:20 +03:00
|
|
|
$router = new \OC\Route\Router($logger);
|
2014-03-24 17:55:03 +04:00
|
|
|
}
|
2014-03-10 17:04:58 +04:00
|
|
|
return $router;
|
|
|
|
});
|
2014-07-16 16:25:31 +04:00
|
|
|
$this->registerService('Search', function ($c) {
|
2014-06-06 03:17:02 +04:00
|
|
|
return new Search();
|
|
|
|
});
|
2014-10-03 03:16:57 +04:00
|
|
|
$this->registerService('SecureRandom', function ($c) {
|
2014-08-26 21:02:40 +04:00
|
|
|
return new SecureRandom();
|
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('Crypto', function (Server $c) {
|
|
|
|
return new Crypto($c->getConfig(), $c->getSecureRandom());
|
2014-08-26 21:02:40 +04:00
|
|
|
});
|
2014-11-04 18:05:31 +03:00
|
|
|
$this->registerService('Hasher', function (Server $c) {
|
|
|
|
return new Hasher($c->getConfig());
|
|
|
|
});
|
2015-08-24 18:13:16 +03:00
|
|
|
$this->registerService('CredentialsManager', function (Server $c) {
|
|
|
|
return new CredentialsManager($c->getCrypto(), $c->getDatabaseConnection());
|
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('DatabaseConnection', function (Server $c) {
|
2014-09-10 15:24:49 +04:00
|
|
|
$factory = new \OC\DB\ConnectionFactory();
|
2014-11-27 18:40:12 +03:00
|
|
|
$systemConfig = $c->getSystemConfig();
|
|
|
|
$type = $systemConfig->getValue('dbtype', 'sqlite');
|
2014-09-10 15:24:49 +04:00
|
|
|
if (!$factory->isValidType($type)) {
|
2014-11-26 14:38:24 +03:00
|
|
|
throw new \OC\DatabaseException('Invalid database type');
|
2014-09-10 15:24:49 +04:00
|
|
|
}
|
2014-11-27 18:40:12 +03:00
|
|
|
$connectionParams = $factory->createConnectionParams($systemConfig);
|
2014-09-10 15:24:49 +04:00
|
|
|
$connection = $factory->getConnection($type, $connectionParams);
|
|
|
|
$connection->getConfiguration()->setSQLLogger($c->getQueryLogger());
|
|
|
|
return $connection;
|
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('Db', function (Server $c) {
|
2014-09-10 15:24:49 +04:00
|
|
|
return new Db($c->getDatabaseConnection());
|
2014-04-19 21:30:12 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('HTTPHelper', function (Server $c) {
|
|
|
|
$config = $c->getConfig();
|
2015-03-16 13:28:23 +03:00
|
|
|
return new HTTPHelper(
|
|
|
|
$config,
|
|
|
|
$c->getHTTPClientService()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
$this->registerService('HttpClientService', function (Server $c) {
|
|
|
|
$user = \OC_User::getUser();
|
|
|
|
$uid = $user ? $user : null;
|
|
|
|
return new ClientService(
|
|
|
|
$c->getConfig(),
|
2015-08-06 17:51:31 +03:00
|
|
|
new \OC\Security\CertificateManager($uid, new View(), $c->getConfig())
|
2015-03-16 13:28:23 +03:00
|
|
|
);
|
2014-09-11 21:21:56 +04:00
|
|
|
});
|
2014-10-24 16:13:40 +04:00
|
|
|
$this->registerService('EventLogger', function (Server $c) {
|
2015-08-24 13:00:37 +03:00
|
|
|
if ($c->getSystemConfig()->getValue('debug', false)) {
|
2014-10-03 03:16:57 +04:00
|
|
|
return new EventLogger();
|
|
|
|
} else {
|
2014-10-14 17:49:00 +04:00
|
|
|
return new NullEventLogger();
|
2014-10-03 03:16:57 +04:00
|
|
|
}
|
|
|
|
});
|
2015-08-24 13:00:37 +03:00
|
|
|
$this->registerService('QueryLogger', function (Server $c) {
|
|
|
|
if ($c->getSystemConfig()->getValue('debug', false)) {
|
2014-10-03 03:35:07 +04:00
|
|
|
return new QueryLogger();
|
|
|
|
} else {
|
2014-10-14 17:49:00 +04:00
|
|
|
return new NullQueryLogger();
|
2014-10-03 03:35:07 +04:00
|
|
|
}
|
|
|
|
});
|
2014-11-27 16:50:14 +03:00
|
|
|
$this->registerService('TempManager', function (Server $c) {
|
2015-08-29 19:36:21 +03:00
|
|
|
return new TempManager(
|
|
|
|
$c->getLogger(),
|
|
|
|
$c->getConfig()
|
|
|
|
);
|
2014-10-22 19:33:36 +04:00
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('AppManager', function (Server $c) {
|
2015-04-01 16:37:22 +03:00
|
|
|
return new \OC\App\AppManager(
|
|
|
|
$c->getUserSession(),
|
|
|
|
$c->getAppConfig(),
|
|
|
|
$c->getGroupManager(),
|
2016-02-09 04:51:12 +03:00
|
|
|
$c->getMemCacheFactory(),
|
|
|
|
$c->getEventDispatcher()
|
2015-04-01 16:37:22 +03:00
|
|
|
);
|
2014-11-07 16:26:12 +03:00
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('DateTimeZone', function (Server $c) {
|
2014-12-16 17:34:55 +03:00
|
|
|
return new DateTimeZone(
|
|
|
|
$c->getConfig(),
|
|
|
|
$c->getSession()
|
|
|
|
);
|
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('DateTimeFormatter', function (Server $c) {
|
2014-11-24 18:37:04 +03:00
|
|
|
$language = $c->getConfig()->getUserValue($c->getSession()->get('user_id'), 'core', 'lang', null);
|
|
|
|
|
2014-12-16 17:34:55 +03:00
|
|
|
return new DateTimeFormatter(
|
|
|
|
$c->getDateTimeZone()->getTimeZone(),
|
|
|
|
$c->getL10N('lib', $language)
|
|
|
|
);
|
2014-11-24 18:37:04 +03:00
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('UserMountCache', function (Server $c) {
|
|
|
|
$mountCache = new UserMountCache($c->getDatabaseConnection(), $c->getUserManager(), $c->getLogger());
|
|
|
|
$listener = new UserMountCacheListener($mountCache);
|
|
|
|
$listener->listen($c->getUserManager());
|
|
|
|
return $mountCache;
|
|
|
|
});
|
2015-11-26 19:47:53 +03:00
|
|
|
$this->registerService('MountConfigManager', function (Server $c) {
|
2014-11-24 17:54:42 +03:00
|
|
|
$loader = \OC\Files\Filesystem::getLoader();
|
2015-12-03 16:10:05 +03:00
|
|
|
$mountCache = $c->query('UserMountCache');
|
2016-04-21 15:48:08 +03:00
|
|
|
$manager = new \OC\Files\Config\MountProviderCollection($loader, $mountCache);
|
|
|
|
|
|
|
|
// builtin providers
|
|
|
|
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$manager->registerProvider(new CacheMountProvider($config));
|
2016-05-17 22:40:55 +03:00
|
|
|
$manager->registerHomeProvider(new LocalHomeMountProvider());
|
|
|
|
$manager->registerHomeProvider(new ObjectHomeMountProvider($config));
|
2016-04-21 15:48:08 +03:00
|
|
|
|
|
|
|
return $manager;
|
2014-11-24 17:54:42 +03:00
|
|
|
});
|
2014-12-05 21:56:29 +03:00
|
|
|
$this->registerService('IniWrapper', function ($c) {
|
2014-12-05 21:57:06 +03:00
|
|
|
return new IniGetWrapper();
|
2014-12-05 21:56:29 +03:00
|
|
|
});
|
2015-02-17 18:49:14 +03:00
|
|
|
$this->registerService('AsyncCommandBus', function (Server $c) {
|
|
|
|
$jobList = $c->getJobList();
|
|
|
|
return new AsyncBus($jobList);
|
|
|
|
});
|
2015-02-17 00:12:47 +03:00
|
|
|
$this->registerService('TrustedDomainHelper', function ($c) {
|
|
|
|
return new TrustedDomainHelper($this->getConfig());
|
|
|
|
});
|
2016-07-20 19:36:15 +03:00
|
|
|
$this->registerService('Throttler', function(Server $c) {
|
|
|
|
return new Throttler(
|
|
|
|
$c->getDatabaseConnection(),
|
|
|
|
new TimeFactory(),
|
|
|
|
$c->getLogger(),
|
|
|
|
$c->getConfig()
|
|
|
|
);
|
|
|
|
});
|
Add code integrity check
This PR implements the base foundation of the code signing and integrity check. In this PR implemented is the signing and verification logic, as well as commands to sign single apps or the core repository.
Furthermore, there is a basic implementation to display problems with the code integrity on the update screen.
Code signing basically happens the following way:
- There is a ownCloud Root Certificate authority stored `resources/codesigning/root.crt` (in this PR I also ship the private key which we obviously need to change before a release :wink:). This certificate is not intended to be used for signing directly and only is used to sign new certificates.
- Using the `integrity:sign-core` and `integrity:sign-app` commands developers can sign either the core release or a single app. The core release needs to be signed with a certificate that has a CN of `core`, apps need to be signed with a certificate that either has a CN of `core` (shipped apps!) or the AppID.
- The command generates a signature.json file of the following format:
```json
{
"hashes": {
"/filename.php": "2401fed2eea6f2c1027c482a633e8e25cd46701f811e2d2c10dc213fd95fa60e350bccbbebdccc73a042b1a2799f673fbabadc783284cc288e4f1a1eacb74e3d",
"/lib/base.php": "55548cc16b457cd74241990cc9d3b72b6335f2e5f45eee95171da024087d114fcbc2effc3d5818a6d5d55f2ae960ab39fd0414d0c542b72a3b9e08eb21206dd9"
},
"certificate": "-----BEGIN CERTIFICATE-----MIIBvTCCASagAwIBAgIUPvawyqJwCwYazcv7iz16TWxfeUMwDQYJKoZIhvcNAQEF\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTAx\nNDEzMTcxMFoXDTE2MTAxNDEzMTcxMFowEzERMA8GA1UEAwwIY29udGFjdHMwgZ8w\nDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANoQesGdCW0L2L+a2xITYipixkScrIpB\nkX5Snu3fs45MscDb61xByjBSlFgR4QI6McoCipPw4SUr28EaExVvgPSvqUjYLGps\nfiv0Cvgquzbx/X3mUcdk9LcFo1uWGtrTfkuXSKX41PnJGTr6RQWGIBd1V52q1qbC\nJKkfzyeMeuQfAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvF/KIhRMQ3tYTmgHWsiM\nwDMgIDb7iaHF0fS+/Nvo4PzoTO/trev6tMyjLbJ7hgdCpz/1sNzE11Cibf6V6dsz\njCE9invP368Xv0bTRObRqeSNsGogGl5ceAvR0c9BG+NRIKHcly3At3gLkS2791bC\niG+UxI/MNcWV0uJg9S63LF8=\n-----END CERTIFICATE-----",
"signature": "U29tZVNpZ25lZERhdGFFeGFtcGxl"
}
```
`hashes` is an array of all files in the folder with their corresponding SHA512 hashes (this is actually quite cheap to calculate), the `certificate` is the certificate used for signing. It has to be issued by the ownCloud Root Authority and it's CN needs to be permitted to perform the required action. The `signature` is then a signature of the `hashes` which can be verified using the `certificate`.
Steps to do in other PRs, this is already a quite huge one:
- Add nag screen in case the code check fails to ensure that administrators are aware of this.
- Add code verification also to OCC upgrade and unify display code more.
- Add enforced code verification to apps shipped from the appstore with a level of "official"
- Add enfocrced code verification to apps shipped from the appstore that were already signed in a previous release
- Add some developer documentation on how devs can request their own certificate
- Check when installing ownCloud
- Add support for CRLs to allow revoking certificates
**Note:** The upgrade checks are only run when the instance has a defined release channel of `stable` (defined in `version.php`). If you want to test this, you need to change the channel thus and then generate the core signature:
```
➜ master git:(add-integrity-checker) ✗ ./occ integrity:sign-core --privateKey=resources/codesigning/core.key --certificate=resources/codesigning/core.crt
Successfully signed "core"
```
Then increase the version and you should see something like the following:
![2015-11-04_12-02-57](https://cloud.githubusercontent.com/assets/878997/10936336/6adb1d14-82ec-11e5-8f06-9a74801c9abf.png)
As you can see a failed code check will not prevent the further update. It will instead just be a notice to the admin. In a next step we will add some nag screen.
For packaging stable releases this requires the following additional steps as a last action before zipping:
1. Run `./occ integrity:sign-core` once
2. Run `./occ integrity:sign-app` _for each_ app. However, this can be simply automated using a simple foreach on the apps folder.
2015-11-03 22:26:06 +03:00
|
|
|
$this->registerService('IntegrityCodeChecker', function (Server $c) {
|
|
|
|
// IConfig and IAppManager requires a working database. This code
|
|
|
|
// might however be called when ownCloud is not yet setup.
|
|
|
|
if(\OC::$server->getSystemConfig()->getValue('installed', false)) {
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$appManager = $c->getAppManager();
|
|
|
|
} else {
|
|
|
|
$config = null;
|
|
|
|
$appManager = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Checker(
|
|
|
|
new EnvironmentHelper(),
|
|
|
|
new FileAccessHelper(),
|
|
|
|
new AppLocator(),
|
|
|
|
$config,
|
|
|
|
$c->getMemCacheFactory(),
|
2016-03-14 22:55:48 +03:00
|
|
|
$appManager,
|
|
|
|
$c->getTempManager()
|
Add code integrity check
This PR implements the base foundation of the code signing and integrity check. In this PR implemented is the signing and verification logic, as well as commands to sign single apps or the core repository.
Furthermore, there is a basic implementation to display problems with the code integrity on the update screen.
Code signing basically happens the following way:
- There is a ownCloud Root Certificate authority stored `resources/codesigning/root.crt` (in this PR I also ship the private key which we obviously need to change before a release :wink:). This certificate is not intended to be used for signing directly and only is used to sign new certificates.
- Using the `integrity:sign-core` and `integrity:sign-app` commands developers can sign either the core release or a single app. The core release needs to be signed with a certificate that has a CN of `core`, apps need to be signed with a certificate that either has a CN of `core` (shipped apps!) or the AppID.
- The command generates a signature.json file of the following format:
```json
{
"hashes": {
"/filename.php": "2401fed2eea6f2c1027c482a633e8e25cd46701f811e2d2c10dc213fd95fa60e350bccbbebdccc73a042b1a2799f673fbabadc783284cc288e4f1a1eacb74e3d",
"/lib/base.php": "55548cc16b457cd74241990cc9d3b72b6335f2e5f45eee95171da024087d114fcbc2effc3d5818a6d5d55f2ae960ab39fd0414d0c542b72a3b9e08eb21206dd9"
},
"certificate": "-----BEGIN CERTIFICATE-----MIIBvTCCASagAwIBAgIUPvawyqJwCwYazcv7iz16TWxfeUMwDQYJKoZIhvcNAQEF\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTAx\nNDEzMTcxMFoXDTE2MTAxNDEzMTcxMFowEzERMA8GA1UEAwwIY29udGFjdHMwgZ8w\nDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANoQesGdCW0L2L+a2xITYipixkScrIpB\nkX5Snu3fs45MscDb61xByjBSlFgR4QI6McoCipPw4SUr28EaExVvgPSvqUjYLGps\nfiv0Cvgquzbx/X3mUcdk9LcFo1uWGtrTfkuXSKX41PnJGTr6RQWGIBd1V52q1qbC\nJKkfzyeMeuQfAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvF/KIhRMQ3tYTmgHWsiM\nwDMgIDb7iaHF0fS+/Nvo4PzoTO/trev6tMyjLbJ7hgdCpz/1sNzE11Cibf6V6dsz\njCE9invP368Xv0bTRObRqeSNsGogGl5ceAvR0c9BG+NRIKHcly3At3gLkS2791bC\niG+UxI/MNcWV0uJg9S63LF8=\n-----END CERTIFICATE-----",
"signature": "U29tZVNpZ25lZERhdGFFeGFtcGxl"
}
```
`hashes` is an array of all files in the folder with their corresponding SHA512 hashes (this is actually quite cheap to calculate), the `certificate` is the certificate used for signing. It has to be issued by the ownCloud Root Authority and it's CN needs to be permitted to perform the required action. The `signature` is then a signature of the `hashes` which can be verified using the `certificate`.
Steps to do in other PRs, this is already a quite huge one:
- Add nag screen in case the code check fails to ensure that administrators are aware of this.
- Add code verification also to OCC upgrade and unify display code more.
- Add enforced code verification to apps shipped from the appstore with a level of "official"
- Add enfocrced code verification to apps shipped from the appstore that were already signed in a previous release
- Add some developer documentation on how devs can request their own certificate
- Check when installing ownCloud
- Add support for CRLs to allow revoking certificates
**Note:** The upgrade checks are only run when the instance has a defined release channel of `stable` (defined in `version.php`). If you want to test this, you need to change the channel thus and then generate the core signature:
```
➜ master git:(add-integrity-checker) ✗ ./occ integrity:sign-core --privateKey=resources/codesigning/core.key --certificate=resources/codesigning/core.crt
Successfully signed "core"
```
Then increase the version and you should see something like the following:
![2015-11-04_12-02-57](https://cloud.githubusercontent.com/assets/878997/10936336/6adb1d14-82ec-11e5-8f06-9a74801c9abf.png)
As you can see a failed code check will not prevent the further update. It will instead just be a notice to the admin. In a next step we will add some nag screen.
For packaging stable releases this requires the following additional steps as a last action before zipping:
1. Run `./occ integrity:sign-core` once
2. Run `./occ integrity:sign-app` _for each_ app. However, this can be simply automated using a simple foreach on the apps folder.
2015-11-03 22:26:06 +03:00
|
|
|
);
|
|
|
|
});
|
2015-02-27 15:05:57 +03:00
|
|
|
$this->registerService('Request', function ($c) {
|
|
|
|
if (isset($this['urlParams'])) {
|
|
|
|
$urlParams = $this['urlParams'];
|
|
|
|
} else {
|
|
|
|
$urlParams = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
|
|
|
|
&& in_array('fakeinput', stream_get_wrappers())
|
|
|
|
) {
|
|
|
|
$stream = 'fakeinput://data';
|
|
|
|
} else {
|
|
|
|
$stream = 'php://input';
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Request(
|
|
|
|
[
|
|
|
|
'get' => $_GET,
|
|
|
|
'post' => $_POST,
|
|
|
|
'files' => $_FILES,
|
|
|
|
'server' => $_SERVER,
|
|
|
|
'env' => $_ENV,
|
|
|
|
'cookies' => $_COOKIE,
|
|
|
|
'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
|
|
|
|
? $_SERVER['REQUEST_METHOD']
|
|
|
|
: null,
|
|
|
|
'urlParams' => $urlParams,
|
|
|
|
],
|
|
|
|
$this->getSecureRandom(),
|
|
|
|
$this->getConfig(),
|
2016-01-25 19:15:54 +03:00
|
|
|
$this->getCsrfTokenManager(),
|
2015-02-27 15:05:57 +03:00
|
|
|
$stream
|
|
|
|
);
|
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('Mailer', function (Server $c) {
|
2015-03-16 15:01:17 +03:00
|
|
|
return new Mailer(
|
|
|
|
$c->getConfig(),
|
|
|
|
$c->getLogger(),
|
2016-07-15 09:46:31 +03:00
|
|
|
$c->getThemingDefaults()
|
2015-03-16 15:01:17 +03:00
|
|
|
);
|
2015-02-12 15:53:27 +03:00
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('OcsClient', function (Server $c) {
|
2015-03-30 16:58:20 +03:00
|
|
|
return new OCSClient(
|
|
|
|
$this->getHTTPClientService(),
|
|
|
|
$this->getConfig(),
|
|
|
|
$this->getLogger()
|
|
|
|
);
|
|
|
|
});
|
2015-05-04 15:02:27 +03:00
|
|
|
$this->registerService('LockingProvider', function (Server $c) {
|
2016-03-24 16:07:43 +03:00
|
|
|
$ini = $c->getIniWrapper();
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$ttl = $config->getSystemValue('filelocking.ttl', max(3600, $ini->getNumeric('max_execution_time')));
|
|
|
|
if ($config->getSystemValue('filelocking.enabled', true) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
|
2015-05-21 17:11:10 +03:00
|
|
|
/** @var \OC\Memcache\Factory $memcacheFactory */
|
|
|
|
$memcacheFactory = $c->getMemCacheFactory();
|
2015-05-26 15:41:37 +03:00
|
|
|
$memcache = $memcacheFactory->createLocking('lock');
|
2015-09-02 17:55:37 +03:00
|
|
|
if (!($memcache instanceof \OC\Memcache\NullCache)) {
|
2016-03-24 16:07:43 +03:00
|
|
|
return new MemcacheLockingProvider($memcache, $ttl);
|
2015-09-02 17:55:37 +03:00
|
|
|
}
|
2016-03-24 16:07:43 +03:00
|
|
|
return new DBLockingProvider($c->getDatabaseConnection(), $c->getLogger(), new TimeFactory(), $ttl);
|
2015-05-21 17:11:10 +03:00
|
|
|
}
|
|
|
|
return new NoopLockingProvider();
|
2015-05-04 15:02:27 +03:00
|
|
|
});
|
2015-07-01 16:57:04 +03:00
|
|
|
$this->registerService('MountManager', function () {
|
|
|
|
return new \OC\Files\Mount\Manager();
|
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('MimeTypeDetector', function (Server $c) {
|
2015-07-20 13:28:36 +03:00
|
|
|
return new \OC\Files\Type\Detection(
|
|
|
|
$c->getURLGenerator(),
|
2015-09-08 13:17:57 +03:00
|
|
|
\OC::$SERVERROOT . '/config/',
|
|
|
|
\OC::$SERVERROOT . '/resources/config/'
|
2015-12-03 16:10:05 +03:00
|
|
|
);
|
2015-04-09 16:19:57 +03:00
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('MimeTypeLoader', function (Server $c) {
|
2015-09-03 21:48:42 +03:00
|
|
|
return new \OC\Files\Type\Loader(
|
|
|
|
$c->getDatabaseConnection()
|
|
|
|
);
|
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('NotificationManager', function () {
|
2015-08-31 13:24:37 +03:00
|
|
|
return new Manager();
|
|
|
|
});
|
2015-07-21 22:44:59 +03:00
|
|
|
$this->registerService('CapabilitiesManager', function (Server $c) {
|
|
|
|
$manager = new \OC\CapabilitiesManager();
|
2015-12-03 16:10:05 +03:00
|
|
|
$manager->registerCapability(function () use ($c) {
|
2015-07-22 14:04:56 +03:00
|
|
|
return new \OC\OCS\CoreCapabilities($c->getConfig());
|
2015-07-21 22:44:59 +03:00
|
|
|
});
|
|
|
|
return $manager;
|
2015-03-21 22:03:56 +03:00
|
|
|
});
|
2015-11-24 01:53:55 +03:00
|
|
|
$this->registerService('CommentsManager', function(Server $c) {
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$factoryClass = $config->getSystemValue('comments.managerFactory', '\OC\Comments\ManagerFactory');
|
|
|
|
/** @var \OCP\Comments\ICommentsManagerFactory $factory */
|
2016-01-19 18:17:49 +03:00
|
|
|
$factory = new $factoryClass($this);
|
2015-11-24 01:53:55 +03:00
|
|
|
return $factory->getManager();
|
|
|
|
});
|
2016-06-21 22:21:46 +03:00
|
|
|
$this->registerService('ThemingDefaults', function(Server $c) {
|
2016-07-19 10:54:42 +03:00
|
|
|
if(class_exists('OCA\Theming\Template', false) && $this->getConfig()->getSystemValue('installed', false) && $this->getAppManager()->isInstalled('theming')) {
|
2016-06-21 22:21:46 +03:00
|
|
|
return new Template(
|
|
|
|
$this->getConfig(),
|
|
|
|
$this->getL10N('theming'),
|
|
|
|
$this->getURLGenerator(),
|
|
|
|
new \OC_Defaults()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return new \OC_Defaults();
|
|
|
|
});
|
2015-12-03 16:10:05 +03:00
|
|
|
$this->registerService('EventDispatcher', function () {
|
2015-08-14 16:40:15 +03:00
|
|
|
return new EventDispatcher();
|
|
|
|
});
|
2015-07-20 13:59:04 +03:00
|
|
|
$this->registerService('CryptoWrapper', function (Server $c) {
|
2015-08-21 19:27:52 +03:00
|
|
|
// FIXME: Instantiiated here due to cyclic dependency
|
|
|
|
$request = new Request(
|
|
|
|
[
|
|
|
|
'get' => $_GET,
|
|
|
|
'post' => $_POST,
|
|
|
|
'files' => $_FILES,
|
|
|
|
'server' => $_SERVER,
|
|
|
|
'env' => $_ENV,
|
|
|
|
'cookies' => $_COOKIE,
|
|
|
|
'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
|
|
|
|
? $_SERVER['REQUEST_METHOD']
|
|
|
|
: null,
|
|
|
|
],
|
2016-01-09 21:57:03 +03:00
|
|
|
$c->getSecureRandom(),
|
2015-08-21 19:27:52 +03:00
|
|
|
$c->getConfig()
|
|
|
|
);
|
|
|
|
|
2015-07-20 13:59:04 +03:00
|
|
|
return new CryptoWrapper(
|
|
|
|
$c->getConfig(),
|
|
|
|
$c->getCrypto(),
|
2015-08-21 19:27:52 +03:00
|
|
|
$c->getSecureRandom(),
|
|
|
|
$request
|
2015-07-20 13:59:04 +03:00
|
|
|
);
|
|
|
|
});
|
2016-01-25 19:15:54 +03:00
|
|
|
$this->registerService('CsrfTokenManager', function (Server $c) {
|
|
|
|
$tokenGenerator = new CsrfTokenGenerator($c->getSecureRandom());
|
|
|
|
$sessionStorage = new SessionStorage($c->getSession());
|
|
|
|
|
|
|
|
return new CsrfTokenManager(
|
|
|
|
$tokenGenerator,
|
|
|
|
$sessionStorage
|
|
|
|
);
|
|
|
|
});
|
2016-01-28 16:33:02 +03:00
|
|
|
$this->registerService('ContentSecurityPolicyManager', function (Server $c) {
|
|
|
|
return new ContentSecurityPolicyManager();
|
|
|
|
});
|
2016-01-11 12:30:03 +03:00
|
|
|
$this->registerService('ShareManager', function(Server $c) {
|
|
|
|
$config = $c->getConfig();
|
|
|
|
$factoryClass = $config->getSystemValue('sharing.managerFactory', '\OC\Share20\ProviderFactory');
|
2016-05-02 12:59:54 +03:00
|
|
|
/** @var \OCP\Share\IProviderFactory $factory */
|
2016-01-20 10:30:37 +03:00
|
|
|
$factory = new $factoryClass($this);
|
2016-01-11 12:30:03 +03:00
|
|
|
|
|
|
|
$manager = new \OC\Share20\Manager(
|
|
|
|
$c->getLogger(),
|
|
|
|
$c->getConfig(),
|
|
|
|
$c->getSecureRandom(),
|
|
|
|
$c->getHasher(),
|
|
|
|
$c->getMountManager(),
|
|
|
|
$c->getGroupManager(),
|
|
|
|
$c->getL10N('core'),
|
2016-02-02 23:02:09 +03:00
|
|
|
$factory,
|
2016-02-04 14:51:23 +03:00
|
|
|
$c->getUserManager(),
|
2016-06-24 18:53:37 +03:00
|
|
|
$c->getLazyRootFolder(),
|
|
|
|
$c->getEventDispatcher()
|
2016-01-11 12:30:03 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
return $manager;
|
|
|
|
});
|
2013-08-27 01:48:18 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-08-31 23:34:29 +04:00
|
|
|
* @return \OCP\Contacts\IManager
|
2013-08-27 01:48:18 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getContactsManager() {
|
2013-08-27 01:48:18 +04:00
|
|
|
return $this->query('ContactsManager');
|
|
|
|
}
|
2013-08-31 23:34:29 +04:00
|
|
|
|
2015-01-14 22:39:23 +03:00
|
|
|
/**
|
|
|
|
* @return \OC\Encryption\Manager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getEncryptionManager() {
|
2015-01-14 22:39:23 +03:00
|
|
|
return $this->query('EncryptionManager');
|
|
|
|
}
|
|
|
|
|
2015-03-31 17:23:31 +03:00
|
|
|
/**
|
|
|
|
* @return \OC\Encryption\File
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getEncryptionFilesHelper() {
|
2015-03-31 17:23:31 +03:00
|
|
|
return $this->query('EncryptionFileHelper');
|
|
|
|
}
|
|
|
|
|
2015-01-14 22:39:23 +03:00
|
|
|
/**
|
|
|
|
* @return \OCP\Encryption\Keys\IStorage
|
|
|
|
*/
|
2015-04-22 12:18:18 +03:00
|
|
|
public function getEncryptionKeyStorage() {
|
|
|
|
return $this->query('EncryptionKeyStorage');
|
2015-01-14 22:39:23 +03:00
|
|
|
}
|
|
|
|
|
2013-08-31 23:34:29 +04:00
|
|
|
/**
|
2013-09-17 19:46:33 +04:00
|
|
|
* The current request object holding all information about the request
|
|
|
|
* currently being processed is returned from this method.
|
2013-08-31 23:34:29 +04:00
|
|
|
* In case the current execution was not initiated by a web request null is returned
|
|
|
|
*
|
2015-04-01 13:13:49 +03:00
|
|
|
* @return \OCP\IRequest
|
2013-08-31 23:34:29 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getRequest() {
|
2015-02-27 15:05:57 +03:00
|
|
|
return $this->query('Request');
|
2013-08-31 23:34:29 +04:00
|
|
|
}
|
2013-09-05 01:45:11 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the preview manager which can create preview images for a given file
|
|
|
|
*
|
|
|
|
* @return \OCP\IPreview
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getPreviewManager() {
|
2013-09-05 01:45:11 +04:00
|
|
|
return $this->query('PreviewManager');
|
|
|
|
}
|
2013-09-16 00:24:57 +04:00
|
|
|
|
2013-09-18 02:37:00 +04:00
|
|
|
/**
|
|
|
|
* Returns the tag manager which can get and set tags for different object types
|
|
|
|
*
|
2013-09-24 19:10:01 +04:00
|
|
|
* @see \OCP\ITagManager::load()
|
|
|
|
* @return \OCP\ITagManager
|
2013-09-18 02:37:00 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getTagManager() {
|
2013-09-18 02:37:00 +04:00
|
|
|
return $this->query('TagManager');
|
|
|
|
}
|
2013-09-16 00:24:57 +04:00
|
|
|
|
2015-11-26 17:49:14 +03:00
|
|
|
/**
|
|
|
|
* Returns the system-tag manager
|
|
|
|
*
|
|
|
|
* @return \OCP\SystemTag\ISystemTagManager
|
|
|
|
*
|
|
|
|
* @since 9.0.0
|
|
|
|
*/
|
|
|
|
public function getSystemTagManager() {
|
|
|
|
return $this->query('SystemTagManager');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the system-tag object mapper
|
|
|
|
*
|
|
|
|
* @return \OCP\SystemTag\ISystemTagObjectMapper
|
|
|
|
*
|
|
|
|
* @since 9.0.0
|
|
|
|
*/
|
|
|
|
public function getSystemTagObjectMapper() {
|
|
|
|
return $this->query('SystemTagObjectMapper');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-20 13:46:11 +04:00
|
|
|
/**
|
|
|
|
* Returns the avatar manager, used for avatar functionality
|
|
|
|
*
|
2013-11-22 15:34:37 +04:00
|
|
|
* @return \OCP\IAvatarManager
|
2013-09-20 13:46:11 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getAvatarManager() {
|
2013-09-20 13:46:11 +04:00
|
|
|
return $this->query('AvatarManager');
|
|
|
|
}
|
|
|
|
|
2013-09-16 00:24:57 +04:00
|
|
|
/**
|
|
|
|
* Returns the root folder of ownCloud's data directory
|
|
|
|
*
|
2015-04-28 10:36:29 +03:00
|
|
|
* @return \OCP\Files\IRootFolder
|
2013-09-16 00:24:57 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getRootFolder() {
|
2013-09-16 00:24:57 +04:00
|
|
|
return $this->query('RootFolder');
|
|
|
|
}
|
2013-09-17 19:46:33 +04:00
|
|
|
|
2016-03-11 16:00:36 +03:00
|
|
|
/**
|
|
|
|
* Returns the root folder of ownCloud's data directory
|
|
|
|
* This is the lazy variant so this gets only initialized once it
|
|
|
|
* is actually used.
|
|
|
|
*
|
|
|
|
* @return \OCP\Files\IRootFolder
|
|
|
|
*/
|
|
|
|
public function getLazyRootFolder() {
|
|
|
|
return $this->query('LazyRootFolder');
|
|
|
|
}
|
|
|
|
|
2013-09-18 16:25:12 +04:00
|
|
|
/**
|
|
|
|
* Returns a view to ownCloud's files folder
|
|
|
|
*
|
2014-08-31 11:49:19 +04:00
|
|
|
* @param string $userId user ID
|
2016-02-16 20:45:25 +03:00
|
|
|
* @return \OCP\Files\Folder|null
|
2013-09-18 16:25:12 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getUserFolder($userId = null) {
|
2014-10-03 03:16:57 +04:00
|
|
|
if ($userId === null) {
|
2014-08-31 11:49:19 +04:00
|
|
|
$user = $this->getUserSession()->getUser();
|
|
|
|
if (!$user) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
$userId = $user->getUID();
|
2014-07-25 19:52:50 +04:00
|
|
|
}
|
2013-09-18 16:25:12 +04:00
|
|
|
$root = $this->getRootFolder();
|
2015-06-16 17:02:30 +03:00
|
|
|
return $root->getUserFolder($userId);
|
2013-09-18 16:25:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an app-specific view in ownClouds data directory
|
|
|
|
*
|
|
|
|
* @return \OCP\Files\Folder
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getAppFolder() {
|
2014-07-22 21:45:01 +04:00
|
|
|
$dir = '/' . \OC_App::getCurrentApp();
|
2013-09-18 16:25:12 +04:00
|
|
|
$root = $this->getRootFolder();
|
2014-07-16 16:25:31 +04:00
|
|
|
if (!$root->nodeExists($dir)) {
|
2013-09-18 16:25:12 +04:00
|
|
|
$folder = $root->newFolder($dir);
|
|
|
|
} else {
|
|
|
|
$folder = $root->get($dir);
|
|
|
|
}
|
|
|
|
return $folder;
|
|
|
|
}
|
|
|
|
|
2013-09-20 14:45:56 +04:00
|
|
|
/**
|
|
|
|
* @return \OC\User\Manager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getUserManager() {
|
2013-09-20 14:45:56 +04:00
|
|
|
return $this->query('UserManager');
|
|
|
|
}
|
|
|
|
|
2014-07-16 16:25:31 +04:00
|
|
|
/**
|
|
|
|
* @return \OC\Group\Manager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getGroupManager() {
|
2014-07-16 16:25:31 +04:00
|
|
|
return $this->query('GroupManager');
|
|
|
|
}
|
|
|
|
|
2013-09-20 14:45:56 +04:00
|
|
|
/**
|
|
|
|
* @return \OC\User\Session
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getUserSession() {
|
2013-09-20 14:45:56 +04:00
|
|
|
return $this->query('UserSession');
|
|
|
|
}
|
|
|
|
|
2014-07-16 21:40:22 +04:00
|
|
|
/**
|
|
|
|
* @return \OCP\ISession
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getSession() {
|
2014-07-16 21:40:22 +04:00
|
|
|
return $this->query('UserSession')->getSession();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param \OCP\ISession $session
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function setSession(\OCP\ISession $session) {
|
2014-07-16 21:40:22 +04:00
|
|
|
return $this->query('UserSession')->setSession($session);
|
|
|
|
}
|
|
|
|
|
2016-05-11 12:23:25 +03:00
|
|
|
/**
|
|
|
|
* @return \OC\Authentication\TwoFactorAuth\Manager
|
|
|
|
*/
|
|
|
|
public function getTwoFactorAuthManager() {
|
|
|
|
return $this->query('\OC\Authentication\TwoFactorAuth\Manager');
|
|
|
|
}
|
|
|
|
|
2013-09-20 19:34:33 +04:00
|
|
|
/**
|
|
|
|
* @return \OC\NavigationManager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getNavigationManager() {
|
2013-09-20 19:34:33 +04:00
|
|
|
return $this->query('NavigationManager');
|
|
|
|
}
|
|
|
|
|
2013-09-20 22:21:24 +04:00
|
|
|
/**
|
2013-12-31 17:36:02 +04:00
|
|
|
* @return \OCP\IConfig
|
2013-09-20 22:21:24 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getConfig() {
|
2013-09-20 22:21:24 +04:00
|
|
|
return $this->query('AllConfig');
|
|
|
|
}
|
2013-09-24 02:09:21 +04:00
|
|
|
|
2014-11-27 18:40:12 +03:00
|
|
|
/**
|
2016-05-03 11:29:47 +03:00
|
|
|
* @internal For internal use only
|
2014-11-27 18:40:12 +03:00
|
|
|
* @return \OC\SystemConfig
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getSystemConfig() {
|
2014-11-27 18:40:12 +03:00
|
|
|
return $this->query('SystemConfig');
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:42:18 +04:00
|
|
|
/**
|
|
|
|
* Returns the app config manager
|
|
|
|
*
|
|
|
|
* @return \OCP\IAppConfig
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getAppConfig() {
|
2014-02-07 16:42:18 +04:00
|
|
|
return $this->query('AppConfig');
|
|
|
|
}
|
|
|
|
|
2015-08-27 14:14:50 +03:00
|
|
|
/**
|
|
|
|
* @return \OCP\L10N\IFactory
|
|
|
|
*/
|
|
|
|
public function getL10NFactory() {
|
|
|
|
return $this->query('L10NFactory');
|
|
|
|
}
|
|
|
|
|
2013-09-25 20:34:01 +04:00
|
|
|
/**
|
|
|
|
* get an L10N instance
|
2014-07-16 16:25:31 +04:00
|
|
|
*
|
2014-03-01 00:03:43 +04:00
|
|
|
* @param string $app appid
|
2014-08-31 12:05:59 +04:00
|
|
|
* @param string $lang
|
2016-04-14 16:38:00 +03:00
|
|
|
* @return IL10N
|
2013-09-25 20:34:01 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getL10N($app, $lang = null) {
|
2015-08-27 14:14:50 +03:00
|
|
|
return $this->getL10NFactory()->get($app, $lang);
|
2013-09-25 20:34:01 +04:00
|
|
|
}
|
|
|
|
|
2013-09-26 20:41:19 +04:00
|
|
|
/**
|
2014-05-07 03:55:06 +04:00
|
|
|
* @return \OCP\IURLGenerator
|
2013-09-26 20:41:19 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getURLGenerator() {
|
2013-09-26 20:41:19 +04:00
|
|
|
return $this->query('URLGenerator');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-05-07 03:55:06 +04:00
|
|
|
* @return \OCP\IHelper
|
2013-09-26 20:41:19 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getHelper() {
|
2013-09-26 20:41:19 +04:00
|
|
|
return $this->query('AppHelper');
|
|
|
|
}
|
|
|
|
|
2013-09-17 19:46:33 +04:00
|
|
|
/**
|
2015-05-13 12:58:19 +03:00
|
|
|
* Returns an ICache instance. Since 8.1.0 it returns a fake cache. Use
|
|
|
|
* getMemCacheFactory() instead.
|
2013-09-17 19:46:33 +04:00
|
|
|
*
|
|
|
|
* @return \OCP\ICache
|
2015-05-13 12:58:19 +03:00
|
|
|
* @deprecated 8.1.0 use getMemCacheFactory to obtain a proper cache
|
2013-09-17 19:46:33 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getCache() {
|
2015-06-15 18:54:48 +03:00
|
|
|
return $this->query('UserCache');
|
2013-09-17 19:46:33 +04:00
|
|
|
}
|
|
|
|
|
2014-01-06 15:55:56 +04:00
|
|
|
/**
|
2014-01-08 18:51:40 +04:00
|
|
|
* Returns an \OCP\CacheFactory instance
|
2014-01-06 15:55:56 +04:00
|
|
|
*
|
2014-03-24 17:55:03 +04:00
|
|
|
* @return \OCP\ICacheFactory
|
2014-01-06 15:55:56 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getMemCacheFactory() {
|
2014-01-08 18:18:12 +04:00
|
|
|
return $this->query('MemCacheFactory');
|
2014-01-06 15:55:56 +04:00
|
|
|
}
|
|
|
|
|
2016-04-14 16:41:04 +03:00
|
|
|
/**
|
|
|
|
* Returns an \OC\RedisFactory instance
|
|
|
|
*
|
|
|
|
* @return \OC\RedisFactory
|
|
|
|
*/
|
|
|
|
public function getGetRedisFactory() {
|
|
|
|
return $this->query('RedisFactory');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-17 20:31:14 +04:00
|
|
|
/**
|
|
|
|
* Returns the current session
|
2013-09-20 16:33:45 +04:00
|
|
|
*
|
|
|
|
* @return \OCP\IDBConnection
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getDatabaseConnection() {
|
2014-09-10 15:24:49 +04:00
|
|
|
return $this->query('DatabaseConnection');
|
2013-09-20 16:33:45 +04:00
|
|
|
}
|
2013-09-29 22:31:12 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the activity manager
|
|
|
|
*
|
|
|
|
* @return \OCP\Activity\IManager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getActivityManager() {
|
2013-09-29 22:31:12 +04:00
|
|
|
return $this->query('ActivityManager');
|
2013-09-20 16:33:45 +04:00
|
|
|
}
|
2014-02-11 17:00:24 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an job list for controlling background jobs
|
|
|
|
*
|
|
|
|
* @return \OCP\BackgroundJob\IJobList
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getJobList() {
|
2014-02-11 17:00:24 +04:00
|
|
|
return $this->query('JobList');
|
|
|
|
}
|
2014-03-10 17:04:58 +04:00
|
|
|
|
2014-05-07 03:55:06 +04:00
|
|
|
/**
|
|
|
|
* Returns a logger instance
|
|
|
|
*
|
|
|
|
* @return \OCP\ILogger
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getLogger() {
|
2014-05-07 03:55:06 +04:00
|
|
|
return $this->query('Logger');
|
|
|
|
}
|
|
|
|
|
2014-03-10 17:04:58 +04:00
|
|
|
/**
|
|
|
|
* Returns a router for generating and matching urls
|
|
|
|
*
|
|
|
|
* @return \OCP\Route\IRouter
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getRouter() {
|
2014-03-24 17:55:03 +04:00
|
|
|
return $this->query('Router');
|
2014-03-10 17:04:58 +04:00
|
|
|
}
|
2014-04-19 21:30:12 +04:00
|
|
|
|
2014-06-06 03:17:02 +04:00
|
|
|
/**
|
|
|
|
* Returns a search instance
|
2014-07-16 16:25:31 +04:00
|
|
|
*
|
2014-06-06 03:17:02 +04:00
|
|
|
* @return \OCP\ISearch
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getSearch() {
|
2014-06-06 03:17:02 +04:00
|
|
|
return $this->query('Search');
|
|
|
|
}
|
2014-04-19 21:30:12 +04:00
|
|
|
|
2014-08-26 21:02:40 +04:00
|
|
|
/**
|
|
|
|
* Returns a SecureRandom instance
|
|
|
|
*
|
|
|
|
* @return \OCP\Security\ISecureRandom
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getSecureRandom() {
|
2014-08-26 21:02:40 +04:00
|
|
|
return $this->query('SecureRandom');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a Crypto instance
|
|
|
|
*
|
|
|
|
* @return \OCP\Security\ICrypto
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getCrypto() {
|
2014-08-26 21:02:40 +04:00
|
|
|
return $this->query('Crypto');
|
|
|
|
}
|
|
|
|
|
2014-11-04 18:05:31 +03:00
|
|
|
/**
|
|
|
|
* Returns a Hasher instance
|
|
|
|
*
|
|
|
|
* @return \OCP\Security\IHasher
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getHasher() {
|
2014-11-04 18:05:31 +03:00
|
|
|
return $this->query('Hasher');
|
|
|
|
}
|
|
|
|
|
2015-08-24 18:13:16 +03:00
|
|
|
/**
|
|
|
|
* Returns a CredentialsManager instance
|
|
|
|
*
|
|
|
|
* @return \OCP\Security\ICredentialsManager
|
|
|
|
*/
|
|
|
|
public function getCredentialsManager() {
|
|
|
|
return $this->query('CredentialsManager');
|
|
|
|
}
|
|
|
|
|
2014-04-19 21:30:12 +04:00
|
|
|
/**
|
|
|
|
* Returns an instance of the db facade
|
2015-12-03 16:10:05 +03:00
|
|
|
*
|
2015-02-24 19:15:21 +03:00
|
|
|
* @deprecated use getDatabaseConnection, will be removed in ownCloud 10
|
2014-04-19 21:30:12 +04:00
|
|
|
* @return \OCP\IDb
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getDb() {
|
2014-04-19 21:30:12 +04:00
|
|
|
return $this->query('Db');
|
|
|
|
}
|
2014-08-14 16:24:10 +04:00
|
|
|
|
2014-09-11 21:21:56 +04:00
|
|
|
/**
|
|
|
|
* Returns an instance of the HTTP helper class
|
2015-12-03 16:10:05 +03:00
|
|
|
*
|
2015-03-16 13:28:23 +03:00
|
|
|
* @deprecated Use getHTTPClientService()
|
2014-09-11 21:21:56 +04:00
|
|
|
* @return \OC\HTTPHelper
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getHTTPHelper() {
|
2014-09-11 21:21:56 +04:00
|
|
|
return $this->query('HTTPHelper');
|
|
|
|
}
|
|
|
|
|
2014-08-14 16:24:10 +04:00
|
|
|
/**
|
|
|
|
* Get the certificate manager for the user
|
|
|
|
*
|
2015-12-22 19:42:28 +03:00
|
|
|
* @param string $userId (optional) if not specified the current loggedin user is used, use null to get the system certificate manager
|
2015-06-17 16:47:45 +03:00
|
|
|
* @return \OCP\ICertificateManager | null if $uid is null and no user is logged in
|
2014-08-14 16:24:10 +04:00
|
|
|
*/
|
2015-12-22 19:42:28 +03:00
|
|
|
public function getCertificateManager($userId = '') {
|
|
|
|
if ($userId === '') {
|
2014-08-14 16:24:10 +04:00
|
|
|
$userSession = $this->getUserSession();
|
|
|
|
$user = $userSession->getUser();
|
|
|
|
if (is_null($user)) {
|
|
|
|
return null;
|
|
|
|
}
|
2015-06-19 11:23:04 +03:00
|
|
|
$userId = $user->getUID();
|
2014-08-14 16:24:10 +04:00
|
|
|
}
|
2015-08-06 17:51:31 +03:00
|
|
|
return new CertificateManager($userId, new View(), $this->getConfig());
|
2014-08-14 16:24:10 +04:00
|
|
|
}
|
2014-08-29 19:19:38 +04:00
|
|
|
|
2015-03-16 13:28:23 +03:00
|
|
|
/**
|
|
|
|
* Returns an instance of the HTTP client service
|
|
|
|
*
|
|
|
|
* @return \OCP\Http\Client\IClientService
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getHTTPClientService() {
|
2015-03-16 13:28:23 +03:00
|
|
|
return $this->query('HttpClientService');
|
|
|
|
}
|
|
|
|
|
2014-08-29 19:19:38 +04:00
|
|
|
/**
|
2014-09-04 03:10:02 +04:00
|
|
|
* Create a new event source
|
2014-08-29 19:19:38 +04:00
|
|
|
*
|
|
|
|
* @return \OCP\IEventSource
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function createEventSource() {
|
2014-08-29 19:19:38 +04:00
|
|
|
return new \OC_EventSource();
|
|
|
|
}
|
2014-10-03 03:16:57 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the active event logger
|
|
|
|
*
|
|
|
|
* The returned logger only logs data when debug mode is enabled
|
|
|
|
*
|
2014-10-03 22:39:09 +04:00
|
|
|
* @return \OCP\Diagnostics\IEventLogger
|
2014-10-03 03:16:57 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getEventLogger() {
|
2014-10-03 03:16:57 +04:00
|
|
|
return $this->query('EventLogger');
|
|
|
|
}
|
2014-10-03 03:35:07 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the active query logger
|
|
|
|
*
|
|
|
|
* The returned logger only logs data when debug mode is enabled
|
|
|
|
*
|
2014-10-03 22:39:09 +04:00
|
|
|
* @return \OCP\Diagnostics\IQueryLogger
|
2014-10-03 03:35:07 +04:00
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getQueryLogger() {
|
2014-10-03 22:39:09 +04:00
|
|
|
return $this->query('QueryLogger');
|
2014-10-03 03:35:07 +04:00
|
|
|
}
|
2014-10-22 19:33:36 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the manager for temporary files and folders
|
|
|
|
*
|
|
|
|
* @return \OCP\ITempManager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getTempManager() {
|
2014-10-22 19:33:36 +04:00
|
|
|
return $this->query('TempManager');
|
|
|
|
}
|
2014-11-07 16:26:12 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the app manager
|
|
|
|
*
|
|
|
|
* @return \OCP\App\IAppManager
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getAppManager() {
|
2014-11-07 16:26:12 +03:00
|
|
|
return $this->query('AppManager');
|
|
|
|
}
|
2014-11-27 16:36:11 +03:00
|
|
|
|
2015-02-12 15:53:27 +03:00
|
|
|
/**
|
|
|
|
* Creates a new mailer
|
|
|
|
*
|
|
|
|
* @return \OCP\Mail\IMailer
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getMailer() {
|
2015-02-12 15:53:27 +03:00
|
|
|
return $this->query('Mailer');
|
|
|
|
}
|
|
|
|
|
2014-11-27 16:36:11 +03:00
|
|
|
/**
|
|
|
|
* Get the webroot
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2015-04-18 12:46:29 +03:00
|
|
|
public function getWebRoot() {
|
2014-11-27 16:50:14 +03:00
|
|
|
return $this->webRoot;
|
2014-11-27 16:36:11 +03:00
|
|
|
}
|
2014-11-24 17:54:42 +03:00
|
|
|
|
2015-03-30 16:58:20 +03:00
|
|
|
/**
|
|
|
|
* @return \OC\OCSClient
|
|
|
|
*/
|
|
|
|
public function getOcsClient() {
|
|
|
|
return $this->query('OcsClient');
|
|
|
|
}
|
|
|
|
|
2014-11-24 18:37:04 +03:00
|
|
|
/**
|
2014-12-16 17:34:55 +03:00
|
|
|
* @return \OCP\IDateTimeZone
|
2014-11-24 18:37:04 +03:00
|
|
|
*/
|
2014-12-16 17:34:55 +03:00
|
|
|
public function getDateTimeZone() {
|
|
|
|
return $this->query('DateTimeZone');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return \OCP\IDateTimeFormatter
|
|
|
|
*/
|
|
|
|
public function getDateTimeFormatter() {
|
|
|
|
return $this->query('DateTimeFormatter');
|
2014-11-24 18:37:04 +03:00
|
|
|
}
|
|
|
|
|
2014-11-24 17:54:42 +03:00
|
|
|
/**
|
|
|
|
* @return \OCP\Files\Config\IMountProviderCollection
|
|
|
|
*/
|
2015-12-03 16:10:05 +03:00
|
|
|
public function getMountProviderCollection() {
|
2014-11-24 17:54:42 +03:00
|
|
|
return $this->query('MountConfigManager');
|
|
|
|
}
|
2014-12-05 21:56:29 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the IniWrapper
|
|
|
|
*
|
2014-12-05 21:57:06 +03:00
|
|
|
* @return IniGetWrapper
|
2014-12-05 21:56:29 +03:00
|
|
|
*/
|
|
|
|
public function getIniWrapper() {
|
2014-12-05 21:57:06 +03:00
|
|
|
return $this->query('IniWrapper');
|
2014-12-05 21:56:29 +03:00
|
|
|
}
|
2015-02-17 00:12:47 +03:00
|
|
|
|
2015-02-17 18:49:14 +03:00
|
|
|
/**
|
|
|
|
* @return \OCP\Command\IBus
|
|
|
|
*/
|
2015-12-03 16:10:05 +03:00
|
|
|
public function getCommandBus() {
|
2015-02-17 18:49:14 +03:00
|
|
|
return $this->query('AsyncCommandBus');
|
|
|
|
}
|
|
|
|
|
2015-02-17 00:12:47 +03:00
|
|
|
/**
|
|
|
|
* Get the trusted domain helper
|
|
|
|
*
|
|
|
|
* @return TrustedDomainHelper
|
|
|
|
*/
|
|
|
|
public function getTrustedDomainHelper() {
|
|
|
|
return $this->query('TrustedDomainHelper');
|
|
|
|
}
|
2015-05-04 15:02:27 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the locking provider
|
|
|
|
*
|
|
|
|
* @return \OCP\Lock\ILockingProvider
|
|
|
|
* @since 8.1.0
|
|
|
|
*/
|
|
|
|
public function getLockingProvider() {
|
|
|
|
return $this->query('LockingProvider');
|
|
|
|
}
|
2015-07-01 16:57:04 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return \OCP\Files\Mount\IMountManager
|
|
|
|
**/
|
|
|
|
function getMountManager() {
|
|
|
|
return $this->query('MountManager');
|
|
|
|
}
|
2015-04-09 16:19:57 +03:00
|
|
|
|
2016-05-03 11:30:07 +03:00
|
|
|
/**
|
2015-04-09 16:19:57 +03:00
|
|
|
* Get the MimeTypeDetector
|
|
|
|
*
|
|
|
|
* @return \OCP\Files\IMimeTypeDetector
|
|
|
|
*/
|
|
|
|
public function getMimeTypeDetector() {
|
|
|
|
return $this->query('MimeTypeDetector');
|
|
|
|
}
|
2015-03-21 22:03:56 +03:00
|
|
|
|
2015-09-03 21:48:42 +03:00
|
|
|
/**
|
|
|
|
* Get the MimeTypeLoader
|
|
|
|
*
|
|
|
|
* @return \OCP\Files\IMimeTypeLoader
|
|
|
|
*/
|
|
|
|
public function getMimeTypeLoader() {
|
|
|
|
return $this->query('MimeTypeLoader');
|
|
|
|
}
|
|
|
|
|
2015-03-21 22:03:56 +03:00
|
|
|
/**
|
|
|
|
* Get the manager of all the capabilities
|
|
|
|
*
|
2015-07-22 14:04:56 +03:00
|
|
|
* @return \OC\CapabilitiesManager
|
2015-03-21 22:03:56 +03:00
|
|
|
*/
|
|
|
|
public function getCapabilitiesManager() {
|
|
|
|
return $this->query('CapabilitiesManager');
|
|
|
|
}
|
2015-08-14 16:40:15 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the EventDispatcher
|
|
|
|
*
|
|
|
|
* @return EventDispatcherInterface
|
|
|
|
* @since 8.2.0
|
|
|
|
*/
|
|
|
|
public function getEventDispatcher() {
|
|
|
|
return $this->query('EventDispatcher');
|
|
|
|
}
|
2015-08-21 19:27:52 +03:00
|
|
|
|
2015-08-31 13:24:37 +03:00
|
|
|
/**
|
|
|
|
* Get the Notification Manager
|
|
|
|
*
|
2016-01-14 16:35:24 +03:00
|
|
|
* @return \OCP\Notification\IManager
|
2015-08-31 13:24:37 +03:00
|
|
|
* @since 8.2.0
|
|
|
|
*/
|
|
|
|
public function getNotificationManager() {
|
|
|
|
return $this->query('NotificationManager');
|
|
|
|
}
|
|
|
|
|
2015-12-03 18:35:57 +03:00
|
|
|
/**
|
|
|
|
* @return \OCP\Comments\ICommentsManager
|
|
|
|
*/
|
2015-11-24 01:53:55 +03:00
|
|
|
public function getCommentsManager() {
|
|
|
|
return $this->query('CommentsManager');
|
|
|
|
}
|
|
|
|
|
2016-06-21 22:21:46 +03:00
|
|
|
/**
|
|
|
|
* @internal Not public by intention.
|
|
|
|
* @return \OC_Defaults
|
|
|
|
*/
|
|
|
|
public function getThemingDefaults() {
|
|
|
|
return $this->query('ThemingDefaults');
|
|
|
|
}
|
|
|
|
|
Add code integrity check
This PR implements the base foundation of the code signing and integrity check. In this PR implemented is the signing and verification logic, as well as commands to sign single apps or the core repository.
Furthermore, there is a basic implementation to display problems with the code integrity on the update screen.
Code signing basically happens the following way:
- There is a ownCloud Root Certificate authority stored `resources/codesigning/root.crt` (in this PR I also ship the private key which we obviously need to change before a release :wink:). This certificate is not intended to be used for signing directly and only is used to sign new certificates.
- Using the `integrity:sign-core` and `integrity:sign-app` commands developers can sign either the core release or a single app. The core release needs to be signed with a certificate that has a CN of `core`, apps need to be signed with a certificate that either has a CN of `core` (shipped apps!) or the AppID.
- The command generates a signature.json file of the following format:
```json
{
"hashes": {
"/filename.php": "2401fed2eea6f2c1027c482a633e8e25cd46701f811e2d2c10dc213fd95fa60e350bccbbebdccc73a042b1a2799f673fbabadc783284cc288e4f1a1eacb74e3d",
"/lib/base.php": "55548cc16b457cd74241990cc9d3b72b6335f2e5f45eee95171da024087d114fcbc2effc3d5818a6d5d55f2ae960ab39fd0414d0c542b72a3b9e08eb21206dd9"
},
"certificate": "-----BEGIN CERTIFICATE-----MIIBvTCCASagAwIBAgIUPvawyqJwCwYazcv7iz16TWxfeUMwDQYJKoZIhvcNAQEF\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTAx\nNDEzMTcxMFoXDTE2MTAxNDEzMTcxMFowEzERMA8GA1UEAwwIY29udGFjdHMwgZ8w\nDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANoQesGdCW0L2L+a2xITYipixkScrIpB\nkX5Snu3fs45MscDb61xByjBSlFgR4QI6McoCipPw4SUr28EaExVvgPSvqUjYLGps\nfiv0Cvgquzbx/X3mUcdk9LcFo1uWGtrTfkuXSKX41PnJGTr6RQWGIBd1V52q1qbC\nJKkfzyeMeuQfAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvF/KIhRMQ3tYTmgHWsiM\nwDMgIDb7iaHF0fS+/Nvo4PzoTO/trev6tMyjLbJ7hgdCpz/1sNzE11Cibf6V6dsz\njCE9invP368Xv0bTRObRqeSNsGogGl5ceAvR0c9BG+NRIKHcly3At3gLkS2791bC\niG+UxI/MNcWV0uJg9S63LF8=\n-----END CERTIFICATE-----",
"signature": "U29tZVNpZ25lZERhdGFFeGFtcGxl"
}
```
`hashes` is an array of all files in the folder with their corresponding SHA512 hashes (this is actually quite cheap to calculate), the `certificate` is the certificate used for signing. It has to be issued by the ownCloud Root Authority and it's CN needs to be permitted to perform the required action. The `signature` is then a signature of the `hashes` which can be verified using the `certificate`.
Steps to do in other PRs, this is already a quite huge one:
- Add nag screen in case the code check fails to ensure that administrators are aware of this.
- Add code verification also to OCC upgrade and unify display code more.
- Add enforced code verification to apps shipped from the appstore with a level of "official"
- Add enfocrced code verification to apps shipped from the appstore that were already signed in a previous release
- Add some developer documentation on how devs can request their own certificate
- Check when installing ownCloud
- Add support for CRLs to allow revoking certificates
**Note:** The upgrade checks are only run when the instance has a defined release channel of `stable` (defined in `version.php`). If you want to test this, you need to change the channel thus and then generate the core signature:
```
➜ master git:(add-integrity-checker) ✗ ./occ integrity:sign-core --privateKey=resources/codesigning/core.key --certificate=resources/codesigning/core.crt
Successfully signed "core"
```
Then increase the version and you should see something like the following:
![2015-11-04_12-02-57](https://cloud.githubusercontent.com/assets/878997/10936336/6adb1d14-82ec-11e5-8f06-9a74801c9abf.png)
As you can see a failed code check will not prevent the further update. It will instead just be a notice to the admin. In a next step we will add some nag screen.
For packaging stable releases this requires the following additional steps as a last action before zipping:
1. Run `./occ integrity:sign-core` once
2. Run `./occ integrity:sign-app` _for each_ app. However, this can be simply automated using a simple foreach on the apps folder.
2015-11-03 22:26:06 +03:00
|
|
|
/**
|
|
|
|
* @return \OC\IntegrityCheck\Checker
|
|
|
|
*/
|
|
|
|
public function getIntegrityCodeChecker() {
|
|
|
|
return $this->query('IntegrityCodeChecker');
|
|
|
|
}
|
|
|
|
|
2015-08-21 19:27:52 +03:00
|
|
|
/**
|
|
|
|
* @return \OC\Session\CryptoWrapper
|
|
|
|
*/
|
|
|
|
public function getSessionCryptoWrapper() {
|
|
|
|
return $this->query('CryptoWrapper');
|
|
|
|
}
|
2015-08-31 17:18:26 +03:00
|
|
|
|
2016-01-25 19:15:54 +03:00
|
|
|
/**
|
|
|
|
* @return CsrfTokenManager
|
|
|
|
*/
|
|
|
|
public function getCsrfTokenManager() {
|
|
|
|
return $this->query('CsrfTokenManager');
|
|
|
|
}
|
|
|
|
|
2016-07-20 19:36:15 +03:00
|
|
|
/**
|
|
|
|
* @return Throttler
|
|
|
|
*/
|
|
|
|
public function getBruteForceThrottler() {
|
|
|
|
return $this->query('Throttler');
|
|
|
|
}
|
|
|
|
|
2016-01-28 16:33:02 +03:00
|
|
|
/**
|
|
|
|
* @return IContentSecurityPolicyManager
|
|
|
|
*/
|
|
|
|
public function getContentSecurityPolicyManager() {
|
|
|
|
return $this->query('ContentSecurityPolicyManager');
|
|
|
|
}
|
|
|
|
|
2015-08-31 17:18:26 +03:00
|
|
|
/**
|
|
|
|
* Not a public API as of 8.2, wait for 9.0
|
2015-12-03 16:10:05 +03:00
|
|
|
*
|
2015-08-31 17:18:26 +03:00
|
|
|
* @return \OCA\Files_External\Service\BackendService
|
|
|
|
*/
|
|
|
|
public function getStoragesBackendService() {
|
|
|
|
return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\BackendService');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Not a public API as of 8.2, wait for 9.0
|
2015-12-03 16:10:05 +03:00
|
|
|
*
|
2015-08-31 17:18:26 +03:00
|
|
|
* @return \OCA\Files_External\Service\GlobalStoragesService
|
|
|
|
*/
|
|
|
|
public function getGlobalStoragesService() {
|
|
|
|
return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\GlobalStoragesService');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Not a public API as of 8.2, wait for 9.0
|
2015-12-03 16:10:05 +03:00
|
|
|
*
|
2015-08-31 17:18:26 +03:00
|
|
|
* @return \OCA\Files_External\Service\UserGlobalStoragesService
|
|
|
|
*/
|
|
|
|
public function getUserGlobalStoragesService() {
|
|
|
|
return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserGlobalStoragesService');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Not a public API as of 8.2, wait for 9.0
|
2015-12-03 16:10:05 +03:00
|
|
|
*
|
2015-08-31 17:18:26 +03:00
|
|
|
* @return \OCA\Files_External\Service\UserStoragesService
|
|
|
|
*/
|
|
|
|
public function getUserStoragesService() {
|
|
|
|
return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserStoragesService');
|
|
|
|
}
|
2016-01-11 12:30:03 +03:00
|
|
|
|
|
|
|
/**
|
2016-01-27 16:48:52 +03:00
|
|
|
* @return \OCP\Share\IManager
|
2016-01-11 12:30:03 +03:00
|
|
|
*/
|
|
|
|
public function getShareManager() {
|
|
|
|
return $this->query('ShareManager');
|
|
|
|
}
|
2015-12-03 16:10:05 +03:00
|
|
|
|
2013-08-21 02:58:15 +04:00
|
|
|
}
|