nextcloud/lib/private/Server.php

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1963 lines
66 KiB
PHP
Raw Permalink Normal View History

2013-08-20 18:58:15 -04:00
<?php
2015-03-26 06:44:34 -04:00
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
2015-03-26 06:44:34 -04:00
*/
2013-08-20 18:58:15 -04:00
namespace OC;
2014-12-05 13:56:29 -05:00
use bantu\IniGetWrapper\IniGetWrapper;
use OC\Accounts\AccountManager;
use OC\App\AppManager;
use OC\App\AppStore\Bundles\BundleFetcher;
use OC\App\AppStore\Fetcher\AppFetcher;
use OC\App\AppStore\Fetcher\CategoryFetcher;
use OC\AppFramework\Bootstrap\Coordinator;
2013-09-04 17:45:11 -04:00
use OC\AppFramework\Http\Request;
use OC\AppFramework\Http\RequestId;
use OC\AppFramework\Utility\TimeFactory;
use OC\Authentication\Events\LoginFailed;
use OC\Authentication\Listeners\LoginFailedListener;
use OC\Authentication\Listeners\UserLoggedInListener;
use OC\Authentication\LoginCredentials\Store;
use OC\Authentication\Token\IProvider;
use OC\Avatar\AvatarManager;
use OC\Blurhash\Listener\GenerateBlurhashMetadata;
use OC\Collaboration\Collaborators\GroupPlugin;
use OC\Collaboration\Collaborators\MailPlugin;
use OC\Collaboration\Collaborators\RemoteGroupPlugin;
use OC\Collaboration\Collaborators\RemotePlugin;
use OC\Collaboration\Collaborators\UserPlugin;
use OC\Collaboration\Reference\ReferenceManager;
use OC\Command\CronBus;
use OC\Comments\ManagerFactory as CommentsManagerFactory;
use OC\Contacts\ContactsMenu\ActionFactory;
use OC\Contacts\ContactsMenu\ContactsStore;
use OC\DB\Connection;
use OC\DB\ConnectionAdapter;
2014-10-03 14:39:09 -04:00
use OC\Diagnostics\EventLogger;
use OC\Diagnostics\QueryLogger;
use OC\Federation\CloudFederationFactory;
use OC\Federation\CloudFederationProviderManager;
use OC\Federation\CloudIdManager;
use OC\Files\Cache\FileAccess;
use OC\Files\Config\MountProviderCollection;
2015-11-26 11:47:53 -05:00
use OC\Files\Config\UserMountCache;
2015-12-03 08:10:05 -05:00
use OC\Files\Config\UserMountCacheListener;
use OC\Files\Lock\LockManager;
use OC\Files\Mount\CacheMountProvider;
use OC\Files\Mount\LocalHomeMountProvider;
use OC\Files\Mount\ObjectHomeMountProvider;
use OC\Files\Mount\ObjectStorePreviewCacheMountProvider;
use OC\Files\Mount\RootMountProvider;
use OC\Files\Node\HookConnector;
2016-03-11 08:00:36 -05:00
use OC\Files\Node\LazyRoot;
2015-06-11 05:29:27 -04:00
use OC\Files\Node\Root;
use OC\Files\SetupManager;
use OC\Files\Storage\StorageFactory;
use OC\Files\Template\TemplateManager;
use OC\Files\Type\Loader;
2015-06-11 05:29:27 -04:00
use OC\Files\View;
use OC\FilesMetadata\FilesMetadataManager;
use OC\FullTextSearch\FullTextSearchManager;
2015-06-11 05:29:27 -04:00
use OC\Http\Client\ClientService;
use OC\Http\Client\NegativeDnsCache;
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 14:26:06 -05:00
use OC\IntegrityCheck\Checker;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\IntegrityCheck\Helpers\EnvironmentHelper;
use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\KnownUser\KnownUserService;
use OC\LDAP\NullLDAPProviderFactory;
use OC\Lock\DBLockingProvider;
use OC\Lock\MemcacheLockingProvider;
2015-05-21 10:11:10 -04:00
use OC\Lock\NoopLockingProvider;
use OC\Lockdown\LockdownManager;
use OC\Log\LogFactory;
use OC\Log\PsrLoggerAdapter;
use OC\Mail\Mailer;
use OC\Memcache\ArrayCache;
use OC\Memcache\Factory;
2015-08-31 06:24:37 -04:00
use OC\Notification\Manager;
use OC\OCM\Model\OCMProvider;
use OC\OCM\OCMDiscoveryService;
use OC\OCS\DiscoveryService;
use OC\Preview\GeneratorHelper;
use OC\Preview\IMagickSupport;
use OC\Preview\MimeIconProvider;
use OC\Profile\ProfileManager;
use OC\Profiler\Profiler;
use OC\Remote\Api\ApiFactory;
use OC\Remote\InstanceFactory;
use OC\RichObjectStrings\Validator;
use OC\Route\CachingRouter;
use OC\Route\Router;
use OC\Security\Bruteforce\Throttler;
2014-08-18 10:30:23 -04:00
use OC\Security\CertificateManager;
use OC\Security\CredentialsManager;
use OC\Security\Crypto;
use OC\Security\CSP\ContentSecurityPolicyManager;
use OC\Security\CSP\ContentSecurityPolicyNonceManager;
use OC\Security\CSRF\CsrfTokenManager;
use OC\Security\CSRF\TokenStorage\SessionStorage;
use OC\Security\Hasher;
use OC\Security\Ip\RemoteAddress;
use OC\Security\RateLimiting\Limiter;
use OC\Security\SecureRandom;
2015-02-16 16:12:47 -05:00
use OC\Security\TrustedDomainHelper;
use OC\Security\VerificationToken\VerificationToken;
use OC\Session\CryptoWrapper;
use OC\Settings\DeclarativeManager;
use OC\SetupCheck\SetupCheckManager;
use OC\Share20\ProviderFactory;
use OC\Share20\ShareHelper;
use OC\SpeechToText\SpeechToTextManager;
use OC\SystemTag\ManagerFactory as SystemTagManagerFactory;
use OC\Tagging\TagMapper;
use OC\Talk\Broker;
use OC\Teams\TeamManager;
use OC\Template\JSCombiner;
use OC\Translation\TranslationManager;
use OC\User\AvailabilityCoordinator;
use OC\User\DisplayNameCache;
use OC\User\Listeners\BeforeUserDeletedListener;
use OC\User\Listeners\UserChangedListener;
use OC\User\Session;
use OCA\Files_External\Service\BackendService;
use OCA\Files_External\Service\GlobalStoragesService;
use OCA\Files_External\Service\UserGlobalStoragesService;
use OCA\Files_External\Service\UserStoragesService;
use OCA\Theming\ImageManager;
use OCA\Theming\Service\BackgroundService;
use OCA\Theming\ThemingDefaults;
use OCA\Theming\Util;
use OCP\Accounts\IAccountManager;
use OCP\App\IAppManager;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Authentication\LoginCredentials\IStore;
use OCP\Authentication\Token\IProvider as OCPIProvider;
use OCP\BackgroundJob\IJobList;
use OCP\Collaboration\AutoComplete\IManager;
use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Command\IBus;
use OCP\Comments\ICommentsManager;
use OCP\Contacts\ContactsMenu\IActionFactory;
use OCP\Contacts\ContactsMenu\IContactsStore;
use OCP\Defaults;
use OCP\Diagnostics\IEventLogger;
use OCP\Diagnostics\IQueryLogger;
use OCP\Encryption\IFile;
use OCP\Encryption\Keys\IStorage;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudFederationFactory;
use OCP\Federation\ICloudFederationProviderManager;
use OCP\Federation\ICloudIdManager;
use OCP\Files\Cache\IFileAccess;
use OCP\Files\Config\IMountProviderCollection;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\IRootFolder;
use OCP\Files\Lock\ILockManager;
use OCP\Files\Mount\IMountManager;
use OCP\Files\Storage\IStorageFactory;
use OCP\Files\Template\ITemplateManager;
use OCP\FilesMetadata\IFilesMetadataManager;
use OCP\FullTextSearch\IFullTextSearchManager;
use OCP\GlobalScale\IConfig;
use OCP\Group\ISubAdmin;
use OCP\Http\Client\IClientService;
use OCP\IAppConfig;
use OCP\IAvatarManager;
use OCP\IBinaryFinder;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\ICertificateManager;
use OCP\IDateTimeFormatter;
use OCP\IDateTimeZone;
use OCP\IDBConnection;
use OCP\IEventSourceFactory;
use OCP\IGroupManager;
use OCP\IInitialStateService;
use OCP\ILogger;
use OCP\INavigationManager;
use OCP\IPhoneNumberUtil;
use OCP\IPreview;
use OCP\IRequest;
use OCP\IRequestId;
2015-06-11 05:29:27 -04:00
use OCP\IServerContainer;
use OCP\ISession;
use OCP\ITagManager;
use OCP\ITempManager;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\LDAP\ILDAPProvider;
use OCP\LDAP\ILDAPProviderFactory;
use OCP\Lock\ILockingProvider;
use OCP\Lockdown\ILockdownManager;
use OCP\Log\ILogFactory;
use OCP\Mail\IMailer;
use OCP\OCM\IOCMDiscoveryService;
use OCP\OCM\IOCMProvider;
use OCP\Preview\IMimeIconProvider;
use OCP\Profile\IProfileManager;
use OCP\Profiler\IProfiler;
use OCP\Remote\Api\IApiFactory;
use OCP\Remote\IInstanceFactory;
use OCP\RichObjectStrings\IValidator;
use OCP\Route\IRouter;
use OCP\Security\Bruteforce\IThrottler;
use OCP\Security\ICredentialsManager;
use OCP\Security\ICrypto;
use OCP\Security\IHasher;
use OCP\Security\Ip\IRemoteAddress;
use OCP\Security\ISecureRandom;
use OCP\Security\ITrustedDomainHelper;
use OCP\Security\RateLimiting\ILimiter;
use OCP\Security\VerificationToken\IVerificationToken;
use OCP\Settings\IDeclarativeManager;
use OCP\SetupCheck\ISetupCheckManager;
use OCP\Share\IProviderFactory;
use OCP\Share\IShareHelper;
use OCP\SpeechToText\ISpeechToTextManager;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\Talk\IBroker;
use OCP\Teams\ITeamManager;
use OCP\Translation\ITranslationManager;
use OCP\User\Events\BeforeUserDeletedEvent;
use OCP\User\Events\BeforeUserLoggedInEvent;
use OCP\User\Events\BeforeUserLoggedInWithCookieEvent;
use OCP\User\Events\BeforeUserLoggedOutEvent;
use OCP\User\Events\PostLoginEvent;
use OCP\User\Events\UserChangedEvent;
use OCP\User\Events\UserLoggedInEvent;
use OCP\User\Events\UserLoggedInWithCookieEvent;
use OCP\User\Events\UserLoggedOutEvent;
use OCP\User\IAvailabilityCoordinator;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
2013-08-20 18:58:15 -04:00
/**
* Class Server
2014-07-16 08:25:31 -04:00
*
2013-08-20 18:58:15 -04:00
* @package OC
*
* TODO: hookup all manager classes
*/
class Server extends ServerContainer implements IServerContainer {
2014-11-27 08:50:14 -05:00
/** @var string */
private $webRoot;
/**
* @param string $webRoot
2015-12-18 05:24:15 -05:00
* @param \OC\Config $config
2014-11-27 08:50:14 -05:00
*/
2015-12-18 05:24:15 -05:00
public function __construct($webRoot, \OC\Config $config) {
parent::__construct();
2014-11-27 08:50:14 -05:00
$this->webRoot = $webRoot;
// To find out if we are running from CLI or not
$this->registerParameter('isCLI', \OC::$CLI);
$this->registerParameter('serverRoot', \OC::$SERVERROOT);
$this->registerService(ContainerInterface::class, function (ContainerInterface $c) {
return $c;
});
$this->registerService(\OCP\IServerContainer::class, function (ContainerInterface $c) {
return $c;
});
$this->registerAlias(\OCP\Calendar\IManager::class, \OC\Calendar\Manager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CalendarManager', \OC\Calendar\Manager::class);
$this->registerAlias(\OCP\Calendar\Resource\IManager::class, \OC\Calendar\Resource\Manager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CalendarResourceBackendManager', \OC\Calendar\Resource\Manager::class);
$this->registerAlias(\OCP\Calendar\Room\IManager::class, \OC\Calendar\Room\Manager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CalendarRoomBackendManager', \OC\Calendar\Room\Manager::class);
$this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('ContactsManager', \OCP\Contacts\IManager::class);
$this->registerAlias(\OCP\DirectEditing\IManager::class, \OC\DirectEditing\Manager::class);
$this->registerAlias(ITemplateManager::class, TemplateManager::class);
$this->registerAlias(IActionFactory::class, ActionFactory::class);
$this->registerService(View::class, function (Server $c) {
return new View();
}, false);
$this->registerService(IPreview::class, function (ContainerInterface $c) {
return new PreviewManager(
$c->get(\OCP\IConfig::class),
$c->get(IRootFolder::class),
new \OC\Preview\Storage\Root(
$c->get(IRootFolder::class),
$c->get(SystemConfig::class)
),
$c->get(IEventDispatcher::class),
$c->get(GeneratorHelper::class),
$c->get(ISession::class)->get('user_id'),
$c->get(Coordinator::class),
$c->get(IServerContainer::class),
$c->get(IBinaryFinder::class),
$c->get(IMagickSupport::class)
);
2013-09-04 17:45:11 -04:00
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('PreviewManager', IPreview::class);
$this->registerAlias(IMimeIconProvider::class, MimeIconProvider::class);
$this->registerService(\OC\Preview\Watcher::class, function (ContainerInterface $c) {
return new \OC\Preview\Watcher(
new \OC\Preview\Storage\Root(
$c->get(IRootFolder::class),
$c->get(SystemConfig::class)
)
);
});
$this->registerService(IProfiler::class, function (Server $c) {
return new Profiler($c->get(SystemConfig::class));
});
$this->registerService(\OCP\Encryption\IManager::class, function (Server $c): Encryption\Manager {
$view = new View();
$util = new Encryption\Util(
$view,
$c->get(IUserManager::class),
$c->get(IGroupManager::class),
$c->get(\OCP\IConfig::class)
);
return new Encryption\Manager(
$c->get(\OCP\IConfig::class),
$c->get(LoggerInterface::class),
$c->getL10N('core'),
new View(),
$util,
new ArrayCache()
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('EncryptionManager', \OCP\Encryption\IManager::class);
/** @deprecated 21.0.0 */
$this->registerDeprecatedAlias('EncryptionFileHelper', IFile::class);
$this->registerService(IFile::class, function (ContainerInterface $c) {
$util = new Encryption\Util(
new View(),
$c->get(IUserManager::class),
$c->get(IGroupManager::class),
$c->get(\OCP\IConfig::class)
);
return new Encryption\File(
$util,
$c->get(IRootFolder::class),
$c->get(\OCP\Share\IManager::class)
);
});
/** @deprecated 21.0.0 */
$this->registerDeprecatedAlias('EncryptionKeyStorage', IStorage::class);
$this->registerService(IStorage::class, function (ContainerInterface $c) {
$view = new View();
$util = new Encryption\Util(
$view,
$c->get(IUserManager::class),
$c->get(IGroupManager::class),
$c->get(\OCP\IConfig::class)
);
return new Encryption\Keys\Storage(
$view,
$util,
$c->get(ICrypto::class),
$c->get(\OCP\IConfig::class)
);
});
/** @deprecated 20.0.0 */
$this->registerDeprecatedAlias('TagMapper', TagMapper::class);
$this->registerAlias(\OCP\ITagManager::class, TagManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('TagManager', \OCP\ITagManager::class);
$this->registerService('SystemTagManagerFactory', function (ContainerInterface $c) {
/** @var \OCP\IConfig $config */
$config = $c->get(\OCP\IConfig::class);
$factoryClass = $config->getSystemValue('systemtags.managerFactory', SystemTagManagerFactory::class);
return new $factoryClass($this);
});
$this->registerService(ISystemTagManager::class, function (ContainerInterface $c) {
return $c->get('SystemTagManagerFactory')->getManager();
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('SystemTagManager', ISystemTagManager::class);
$this->registerService(ISystemTagObjectMapper::class, function (ContainerInterface $c) {
return $c->get('SystemTagManagerFactory')->getObjectMapper();
});
$this->registerAlias(IFileAccess::class, FileAccess::class);
$this->registerService('RootFolder', function (ContainerInterface $c) {
$manager = \OC\Files\Filesystem::getMountManager();
$view = new View();
/** @var IUserSession $userSession */
$userSession = $c->get(IUserSession::class);
$root = new Root(
$manager,
$view,
$userSession->getUser(),
$c->get(IUserMountCache::class),
$this->get(LoggerInterface::class),
$this->get(IUserManager::class),
$this->get(IEventDispatcher::class),
$this->get(ICacheFactory::class),
);
$previewConnector = new \OC\Preview\WatcherConnector(
$root,
$c->get(SystemConfig::class)
);
$previewConnector->connectWatcher();
return $root;
});
$this->registerService(HookConnector::class, function (ContainerInterface $c) {
return new HookConnector(
$c->get(IRootFolder::class),
new View(),
$c->get(IEventDispatcher::class),
$c->get(LoggerInterface::class)
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('SystemTagObjectMapper', ISystemTagObjectMapper::class);
$this->registerService(IRootFolder::class, function (ContainerInterface $c) {
2017-08-24 10:21:50 -04:00
return new LazyRoot(function () use ($c) {
return $c->get('RootFolder');
2016-03-11 08:00:36 -05:00
});
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('LazyRootFolder', IRootFolder::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('UserManager', \OC\User\Manager::class);
$this->registerAlias(\OCP\IUserManager::class, \OC\User\Manager::class);
$this->registerService(DisplayNameCache::class, function (ContainerInterface $c) {
return $c->get(\OC\User\Manager::class)->getDisplayNameCache();
});
$this->registerService(\OCP\IGroupManager::class, function (ContainerInterface $c) {
$groupManager = new \OC\Group\Manager(
$this->get(IUserManager::class),
$this->get(IEventDispatcher::class),
$this->get(LoggerInterface::class),
$this->get(ICacheFactory::class),
$this->get(IRemoteAddress::class),
);
return $groupManager;
2014-07-16 08:25:31 -04:00
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('GroupManager', \OCP\IGroupManager::class);
$this->registerService(Store::class, function (ContainerInterface $c) {
$session = $c->get(ISession::class);
if (\OC::$server->get(SystemConfig::class)->getValue('installed', false)) {
$tokenProvider = $c->get(IProvider::class);
} else {
$tokenProvider = null;
}
$logger = $c->get(LoggerInterface::class);
return new Store($session, $logger, $tokenProvider);
});
$this->registerAlias(IStore::class, Store::class);
$this->registerAlias(IProvider::class, Authentication\Token\Manager::class);
$this->registerAlias(OCPIProvider::class, Authentication\Token\Manager::class);
$this->registerService(\OC\User\Session::class, function (Server $c) {
$manager = $c->get(IUserManager::class);
$session = new \OC\Session\Memory();
2016-05-02 13:58:19 -04:00
$timeFactory = new TimeFactory();
2016-04-27 06:01:13 -04:00
// Token providers might require a working database. This code
// might however be called when Nextcloud is not yet setup.
if (\OC::$server->get(SystemConfig::class)->getValue('installed', false)) {
$provider = $c->get(IProvider::class);
2016-04-27 06:01:13 -04:00
} else {
$provider = null;
2016-04-27 06:01:13 -04:00
}
2016-06-24 11:53:37 -04:00
$userSession = new \OC\User\Session(
$manager,
$session,
$timeFactory,
$provider,
$c->get(\OCP\IConfig::class),
$c->get(ISecureRandom::class),
$c->get('LockdownManager'),
$c->get(LoggerInterface::class),
$c->get(IEventDispatcher::class),
);
/** @deprecated 21.0.0 use BeforeUserCreatedEvent event with the IEventDispatcher instead */
2013-09-20 06:45:56 -04:00
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
\OC_Hook::emit('OC_User', 'pre_createUser', ['run' => true, 'uid' => $uid, 'password' => $password]);
2013-09-20 06:45:56 -04:00
});
/** @deprecated 21.0.0 use UserCreatedEvent event with the IEventDispatcher instead */
2013-09-20 06:45:56 -04:00
$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'post_createUser', ['uid' => $user->getUID(), 'password' => $password]);
2013-09-20 06:45:56 -04:00
});
/** @deprecated 21.0.0 use BeforeUserDeletedEvent event with the IEventDispatcher instead */
$userSession->listen('\OC\User', 'preDelete', function ($user) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'pre_deleteUser', ['run' => true, 'uid' => $user->getUID()]);
2013-09-20 06:45:56 -04:00
});
/** @deprecated 21.0.0 use UserDeletedEvent event with the IEventDispatcher instead */
2013-09-20 06:45:56 -04:00
$userSession->listen('\OC\User', 'postDelete', function ($user) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'post_deleteUser', ['uid' => $user->getUID()]);
2013-09-20 06:45:56 -04:00
});
$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'pre_setPassword', ['run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword]);
2013-09-20 06:45:56 -04:00
});
$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'post_setPassword', ['run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword]);
2013-09-20 06:45:56 -04:00
});
$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
\OC_Hook::emit('OC_User', 'pre_login', ['run' => true, 'uid' => $uid, 'password' => $password]);
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
$dispatcher->dispatchTyped(new BeforeUserLoggedInEvent($uid, $password));
2013-09-20 06:45:56 -04:00
});
$userSession->listen('\OC\User', 'postLogin', function ($user, $loginName, $password, $isTokenLogin) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'post_login', ['run' => true, 'uid' => $user->getUID(), 'loginName' => $loginName, 'password' => $password, 'isTokenLogin' => $isTokenLogin]);
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
$dispatcher->dispatchTyped(new UserLoggedInEvent($user, $loginName, $password, $isTokenLogin));
});
$userSession->listen('\OC\User', 'preRememberedLogin', function ($uid) {
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
$dispatcher->dispatchTyped(new BeforeUserLoggedInWithCookieEvent($uid));
2013-09-20 06:45:56 -04:00
});
$userSession->listen('\OC\User', 'postRememberedLogin', function ($user, $password) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'post_login', ['run' => true, 'uid' => $user->getUID(), 'password' => $password]);
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
$dispatcher->dispatchTyped(new UserLoggedInWithCookieEvent($user, $password));
});
$userSession->listen('\OC\User', 'logout', function ($user) {
\OC_Hook::emit('OC_User', 'logout', []);
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
$dispatcher->dispatchTyped(new BeforeUserLoggedOutEvent($user));
});
$userSession->listen('\OC\User', 'postLogout', function ($user) {
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
$dispatcher->dispatchTyped(new UserLoggedOutEvent($user));
2013-09-20 06:45:56 -04:00
});
$userSession->listen('\OC\User', 'changeUser', function ($user, $feature, $value, $oldValue) {
/** @var \OC\User\User $user */
\OC_Hook::emit('OC_User', 'changeUser', ['run' => true, 'user' => $user, 'feature' => $feature, 'value' => $value, 'old_value' => $oldValue]);
});
2013-09-20 06:45:56 -04:00
return $userSession;
});
$this->registerAlias(\OCP\IUserSession::class, \OC\User\Session::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('UserSession', \OC\User\Session::class);
2016-05-11 05:23:25 -04:00
$this->registerAlias(\OCP\Authentication\TwoFactorAuth\IRegistry::class, \OC\Authentication\TwoFactorAuth\Registry::class);
2016-05-11 05:23:25 -04:00
$this->registerAlias(INavigationManager::class, \OC\NavigationManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('NavigationManager', INavigationManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('AllConfig', \OC\AllConfig::class);
$this->registerAlias(\OCP\IConfig::class, \OC\AllConfig::class);
$this->registerService(\OC\SystemConfig::class, function ($c) use ($config) {
2015-12-18 05:24:15 -05:00
return new \OC\SystemConfig($config);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('SystemConfig', \OC\SystemConfig::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('AppConfig', \OC\AppConfig::class);
$this->registerAlias(IAppConfig::class, \OC\AppConfig::class);
$this->registerService(IFactory::class, function (Server $c) {
return new \OC\L10N\Factory(
$c->get(\OCP\IConfig::class),
$c->getRequest(),
$c->get(IUserSession::class),
$c->get(ICacheFactory::class),
\OC::$SERVERROOT,
$c->get(IAppManager::class),
);
2013-09-25 12:34:01 -04:00
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('L10NFactory', IFactory::class);
$this->registerAlias(IURLGenerator::class, URLGenerator::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('URLGenerator', IURLGenerator::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('AppFetcher', AppFetcher::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CategoryFetcher', CategoryFetcher::class);
$this->registerService(ICache::class, function ($c) {
return new Cache\File();
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('UserCache', ICache::class);
$this->registerService(Factory::class, function (Server $c) {
$profiler = $c->get(IProfiler::class);
$arrayCacheFactory = new \OC\Memcache\Factory(fn () => '', $c->get(LoggerInterface::class),
$profiler,
ArrayCache::class,
ArrayCache::class,
ArrayCache::class
);
/** @var SystemConfig $config */
$config = $c->get(SystemConfig::class);
if ($config->getValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
$logQuery = $config->getValue('log_query');
$prefixClosure = function () use ($logQuery) {
if (!$logQuery) {
try {
$v = \OC_App::getAppVersions();
} catch (\Doctrine\DBAL\Exception $e) {
// Database service probably unavailable
// Probably related to https://github.com/nextcloud/server/issues/37424
return null;
}
} else {
// If the log_query is enabled, we can not get the app versions
// as that does a query, which will be logged and the logging
// depends on redis and here we are back again in the same function.
$v = [
'log_query' => 'enabled',
];
}
$v['core'] = implode(',', \OC_Util::getVersion());
$version = implode(',', $v);
$instanceId = \OC_Util::getInstanceId();
$path = \OC::$SERVERROOT;
return md5($instanceId . '-' . $version . '-' . $path);
};
return new \OC\Memcache\Factory($prefixClosure,
$c->get(LoggerInterface::class),
$profiler,
/** @psalm-taint-escape callable */
$config->getValue('memcache.local', null),
/** @psalm-taint-escape callable */
$config->getValue('memcache.distributed', null),
/** @psalm-taint-escape callable */
$config->getValue('memcache.locking', null),
/** @psalm-taint-escape callable */
$config->getValue('redis_log_file')
);
}
return $arrayCacheFactory;
2014-01-06 06:55:56 -05:00
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('MemCacheFactory', Factory::class);
$this->registerAlias(ICacheFactory::class, Factory::class);
$this->registerService('RedisFactory', function (Server $c) {
$systemConfig = $c->get(SystemConfig::class);
return new RedisFactory($systemConfig, $c->get(IEventLogger::class));
});
$this->registerService(\OCP\Activity\IManager::class, function (Server $c) {
$l10n = $this->get(IFactory::class)->get('lib');
2016-05-02 05:57:24 -04:00
return new \OC\Activity\Manager(
$c->getRequest(),
$c->get(IUserSession::class),
$c->get(\OCP\IConfig::class),
$c->get(IValidator::class),
$l10n
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('ActivityManager', \OCP\Activity\IManager::class);
$this->registerService(\OCP\Activity\IEventMerger::class, function (Server $c) {
return new \OC\Activity\EventMerger(
$c->getL10N('lib')
);
});
$this->registerAlias(IValidator::class, Validator::class);
$this->registerService(AvatarManager::class, function (Server $c) {
return new AvatarManager(
$c->get(IUserSession::class),
$c->get(\OC\User\Manager::class),
$c->getAppDataDir('avatar'),
$c->getL10N('lib'),
$c->get(LoggerInterface::class),
$c->get(\OCP\IConfig::class),
$c->get(IAccountManager::class),
$c->get(KnownUserService::class)
);
2013-09-20 05:46:11 -04:00
});
$this->registerAlias(IAvatarManager::class, AvatarManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('AvatarManager', AvatarManager::class);
$this->registerAlias(\OCP\Support\CrashReport\IRegistry::class, \OC\Support\CrashReport\Registry::class);
$this->registerAlias(\OCP\Support\Subscription\IRegistry::class, \OC\Support\Subscription\Registry::class);
$this->registerAlias(\OCP\Support\Subscription\IAssertion::class, \OC\Support\Subscription\Assertion::class);
$this->registerService(\OC\Log::class, function (Server $c) {
$logType = $c->get(AllConfig::class)->getSystemValue('log_type', 'file');
$factory = new LogFactory($c, $this->get(SystemConfig::class));
$logger = $factory->get($logType);
$registry = $c->get(\OCP\Support\CrashReport\IRegistry::class);
return new Log($logger, $this->get(SystemConfig::class), crashReporters: $registry);
});
$this->registerAlias(ILogger::class, \OC\Log::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Logger', \OC\Log::class);
// PSR-3 logger
$this->registerAlias(LoggerInterface::class, PsrLoggerAdapter::class);
$this->registerService(ILogFactory::class, function (Server $c) {
return new LogFactory($c, $this->get(SystemConfig::class));
});
$this->registerAlias(IJobList::class, \OC\BackgroundJob\JobList::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('JobList', IJobList::class);
$this->registerService(Router::class, function (Server $c) {
$cacheFactory = $c->get(ICacheFactory::class);
if ($cacheFactory->isLocalCacheAvailable()) {
$router = $c->resolve(CachingRouter::class);
} else {
$router = $c->resolve(Router::class);
}
return $router;
});
$this->registerAlias(IRouter::class, Router::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Router', IRouter::class);
2017-08-24 10:21:50 -04:00
$this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) {
$config = $c->get(\OCP\IConfig::class);
if (ltrim($config->getSystemValueString('memcache.distributed', ''), '\\') === \OC\Memcache\Redis::class) {
$backend = new \OC\Security\RateLimiting\Backend\MemoryCacheBackend(
$c->get(AllConfig::class),
$this->get(ICacheFactory::class),
new \OC\AppFramework\Utility\TimeFactory()
);
} else {
$backend = new \OC\Security\RateLimiting\Backend\DatabaseBackend(
$c->get(AllConfig::class),
$c->get(IDBConnection::class),
new \OC\AppFramework\Utility\TimeFactory()
);
}
return $backend;
});
$this->registerAlias(\OCP\Security\ISecureRandom::class, SecureRandom::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('SecureRandom', \OCP\Security\ISecureRandom::class);
$this->registerAlias(\OCP\Security\IRemoteHostValidator::class, \OC\Security\RemoteHostValidator::class);
$this->registerAlias(IVerificationToken::class, VerificationToken::class);
$this->registerAlias(ICrypto::class, Crypto::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Crypto', ICrypto::class);
$this->registerAlias(IHasher::class, Hasher::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Hasher', IHasher::class);
$this->registerAlias(ICredentialsManager::class, CredentialsManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CredentialsManager', ICredentialsManager::class);
$this->registerAlias(IDBConnection::class, ConnectionAdapter::class);
$this->registerService(Connection::class, function (Server $c) {
$systemConfig = $c->get(SystemConfig::class);
$factory = new \OC\DB\ConnectionFactory($systemConfig, $c->get(ICacheFactory::class));
$type = $systemConfig->getValue('dbtype', 'sqlite');
if (!$factory->isValidType($type)) {
throw new \OC\DatabaseException('Invalid database type');
}
$connection = $factory->getConnection($type, []);
return $connection;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('DatabaseConnection', IDBConnection::class);
$this->registerAlias(ICertificateManager::class, CertificateManager::class);
$this->registerAlias(IClientService::class, ClientService::class);
$this->registerService(NegativeDnsCache::class, function (ContainerInterface $c) {
return new NegativeDnsCache(
$c->get(ICacheFactory::class),
);
});
$this->registerDeprecatedAlias('HttpClientService', IClientService::class);
$this->registerService(IEventLogger::class, function (ContainerInterface $c) {
return new EventLogger($c->get(SystemConfig::class), $c->get(LoggerInterface::class), $c->get(Log::class));
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('EventLogger', IEventLogger::class);
$this->registerService(IQueryLogger::class, function (ContainerInterface $c) {
$queryLogger = new QueryLogger();
if ($c->get(SystemConfig::class)->getValue('debug', false)) {
// In debug mode, module is being activated by default
$queryLogger->activate();
}
return $queryLogger;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('QueryLogger', IQueryLogger::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('TempManager', TempManager::class);
$this->registerAlias(ITempManager::class, TempManager::class);
$this->registerService(AppManager::class, function (ContainerInterface $c) {
// TODO: use auto-wiring
return new \OC\App\AppManager(
$c->get(IUserSession::class),
$c->get(\OCP\IConfig::class),
$c->get(IGroupManager::class),
$c->get(ICacheFactory::class),
$c->get(IEventDispatcher::class),
$c->get(LoggerInterface::class),
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('AppManager', AppManager::class);
$this->registerAlias(IAppManager::class, AppManager::class);
$this->registerAlias(IDateTimeZone::class, DateTimeZone::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('DateTimeZone', IDateTimeZone::class);
$this->registerService(IDateTimeFormatter::class, function (Server $c) {
$language = $c->get(\OCP\IConfig::class)->getUserValue($c->get(ISession::class)->get('user_id'), 'core', 'lang', null);
2014-12-16 09:34:55 -05:00
return new DateTimeFormatter(
$c->get(IDateTimeZone::class)->getTimeZone(),
2014-12-16 09:34:55 -05:00
$c->getL10N('lib', $language)
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('DateTimeFormatter', IDateTimeFormatter::class);
$this->registerService(IUserMountCache::class, function (ContainerInterface $c) {
$mountCache = $c->get(UserMountCache::class);
2015-12-03 08:10:05 -05:00
$listener = new UserMountCacheListener($mountCache);
$listener->listen($c->get(IUserManager::class));
2015-12-03 08:10:05 -05:00
return $mountCache;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('UserMountCache', IUserMountCache::class);
$this->registerService(IMountProviderCollection::class, function (ContainerInterface $c) {
$loader = $c->get(IStorageFactory::class);
$mountCache = $c->get(IUserMountCache::class);
$eventLogger = $c->get(IEventLogger::class);
$manager = new MountProviderCollection($loader, $mountCache, $eventLogger);
// builtin providers
$config = $c->get(\OCP\IConfig::class);
$logger = $c->get(LoggerInterface::class);
$manager->registerProvider(new CacheMountProvider($config));
$manager->registerHomeProvider(new LocalHomeMountProvider());
$manager->registerHomeProvider(new ObjectHomeMountProvider($config));
$manager->registerRootProvider(new RootMountProvider($config, $c->get(LoggerInterface::class)));
$manager->registerRootProvider(new ObjectStorePreviewCacheMountProvider($logger, $config));
return $manager;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('MountConfigManager', IMountProviderCollection::class);
/** @deprecated 20.0.0 */
$this->registerDeprecatedAlias('IniWrapper', IniGetWrapper::class);
$this->registerService(IBus::class, function (ContainerInterface $c) {
$busClass = $c->get(\OCP\IConfig::class)->getSystemValueString('commandbus');
2017-08-24 10:21:50 -04:00
if ($busClass) {
[$app, $class] = explode('::', $busClass, 2);
if ($c->get(IAppManager::class)->isInstalled($app)) {
2017-08-24 10:21:50 -04:00
\OC_App::loadApp($app);
return $c->get($class);
2017-08-24 10:21:50 -04:00
} else {
throw new ServiceUnavailableException("The app providing the command bus ($app) is not enabled");
}
} else {
$jobList = $c->get(IJobList::class);
2017-08-24 10:21:50 -04:00
return new CronBus($jobList);
}
});
$this->registerDeprecatedAlias('AsyncCommandBus', IBus::class);
/** @deprecated 20.0.0 */
$this->registerDeprecatedAlias('TrustedDomainHelper', TrustedDomainHelper::class);
$this->registerAlias(ITrustedDomainHelper::class, TrustedDomainHelper::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Throttler', Throttler::class);
$this->registerAlias(IThrottler::class, Throttler::class);
$this->registerService(\OC\Security\Bruteforce\Backend\IBackend::class, function ($c) {
$config = $c->get(\OCP\IConfig::class);
if (ltrim($config->getSystemValueString('memcache.distributed', ''), '\\') === \OC\Memcache\Redis::class) {
$backend = $c->get(\OC\Security\Bruteforce\Backend\MemoryCacheBackend::class);
} else {
$backend = $c->get(\OC\Security\Bruteforce\Backend\DatabaseBackend::class);
}
return $backend;
});
$this->registerDeprecatedAlias('IntegrityCodeChecker', Checker::class);
$this->registerService(Checker::class, function (ContainerInterface $c) {
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 14:26:06 -05:00
// IConfig and IAppManager requires a working database. This code
// might however be called when ownCloud is not yet setup.
if (\OC::$server->get(SystemConfig::class)->getValue('installed', false)) {
$config = $c->get(\OCP\IConfig::class);
$appConfig = $c->get(\OCP\IAppConfig::class);
$appManager = $c->get(IAppManager::class);
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 14:26:06 -05:00
} else {
$config = $appConfig = $appManager = null;
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 14:26:06 -05:00
}
return new Checker(
2017-08-24 10:21:50 -04:00
new EnvironmentHelper(),
new FileAccessHelper(),
new AppLocator(),
$config,
$appConfig,
$c->get(ICacheFactory::class),
2017-08-24 10:21:50 -04:00
$appManager,
$c->get(IMimeTypeDetector::class)
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 14:26:06 -05:00
);
});
$this->registerService(\OCP\IRequest::class, function (ContainerInterface $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']
: '',
'urlParams' => $urlParams,
],
$this->get(IRequestId::class),
$this->get(\OCP\IConfig::class),
$this->get(CsrfTokenManager::class),
$stream
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Request', \OCP\IRequest::class);
$this->registerService(IRequestId::class, function (ContainerInterface $c): IRequestId {
return new RequestId(
$_SERVER['UNIQUE_ID'] ?? '',
$this->get(ISecureRandom::class)
);
});
$this->registerService(IMailer::class, function (Server $c) {
2015-03-16 08:01:17 -04:00
return new Mailer(
$c->get(\OCP\IConfig::class),
$c->get(LoggerInterface::class),
$c->get(Defaults::class),
$c->get(IURLGenerator::class),
$c->getL10N('lib'),
$c->get(IEventDispatcher::class),
$c->get(IFactory::class)
2015-03-16 08:01:17 -04:00
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Mailer', IMailer::class);
/** @since 30.0.0 */
$this->registerAlias(\OCP\Mail\Provider\IManager::class, \OC\Mail\Provider\Manager::class);
/** @deprecated 21.0.0 */
$this->registerDeprecatedAlias('LDAPProvider', ILDAPProvider::class);
$this->registerService(ILDAPProviderFactory::class, function (ContainerInterface $c) {
$config = $c->get(\OCP\IConfig::class);
2016-07-22 04:46:29 -04:00
$factoryClass = $config->getSystemValue('ldapProviderFactory', null);
if (is_null($factoryClass) || !class_exists($factoryClass)) {
return new NullLDAPProviderFactory($this);
2016-07-22 04:46:29 -04:00
}
/** @var \OCP\LDAP\ILDAPProviderFactory $factory */
return new $factoryClass($this);
});
$this->registerService(ILDAPProvider::class, function (ContainerInterface $c) {
$factory = $c->get(ILDAPProviderFactory::class);
2016-07-22 04:46:29 -04:00
return $factory->getLDAPProvider();
});
$this->registerService(ILockingProvider::class, function (ContainerInterface $c) {
$ini = $c->get(IniGetWrapper::class);
$config = $c->get(\OCP\IConfig::class);
$ttl = $config->getSystemValueInt('filelocking.ttl', max(3600, $ini->getNumeric('max_execution_time')));
if ($config->getSystemValueBool('filelocking.enabled', true) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
2015-05-21 10:11:10 -04:00
/** @var \OC\Memcache\Factory $memcacheFactory */
$memcacheFactory = $c->get(ICacheFactory::class);
$memcache = $memcacheFactory->createLocking('lock');
2015-09-02 10:55:37 -04:00
if (!($memcache instanceof \OC\Memcache\NullCache)) {
$timeFactory = $c->get(ITimeFactory::class);
return new MemcacheLockingProvider($memcache, $timeFactory, $ttl);
2015-09-02 10:55:37 -04:00
}
return new DBLockingProvider(
$c->get(IDBConnection::class),
new TimeFactory(),
$ttl,
!\OC::$CLI
);
2015-05-21 10:11:10 -04:00
}
return new NoopLockingProvider();
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('LockingProvider', ILockingProvider::class);
$this->registerService(ILockManager::class, function (Server $c): LockManager {
return new LockManager();
});
$this->registerAlias(ILockdownManager::class, 'LockdownManager');
$this->registerService(SetupManager::class, function ($c) {
// create the setupmanager through the mount manager to resolve the cyclic dependency
return $c->get(\OC\Files\Mount\Manager::class)->getSetupManager();
});
$this->registerAlias(IMountManager::class, \OC\Files\Mount\Manager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('MountManager', IMountManager::class);
$this->registerService(IMimeTypeDetector::class, function (ContainerInterface $c) {
return new \OC\Files\Type\Detection(
$c->get(IURLGenerator::class),
$c->get(LoggerInterface::class),
\OC::$configDir,
\OC::$SERVERROOT . '/resources/config/'
2015-12-03 08:10:05 -05:00
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('MimeTypeDetector', IMimeTypeDetector::class);
$this->registerAlias(IMimeTypeLoader::class, Loader::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('MimeTypeLoader', IMimeTypeLoader::class);
$this->registerService(BundleFetcher::class, function () {
return new BundleFetcher($this->getL10N('lib'));
});
$this->registerAlias(\OCP\Notification\IManager::class, Manager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('NotificationManager', \OCP\Notification\IManager::class);
$this->registerService(CapabilitiesManager::class, function (ContainerInterface $c) {
$manager = new CapabilitiesManager($c->get(LoggerInterface::class));
2015-12-03 08:10:05 -05:00
$manager->registerCapability(function () use ($c) {
return new \OC\OCS\CoreCapabilities($c->get(\OCP\IConfig::class));
2015-07-21 15:44:59 -04:00
});
$manager->registerCapability(function () use ($c) {
return $c->get(\OC\Security\Bruteforce\Capabilities::class);
});
2015-07-21 15:44:59 -04:00
return $manager;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CapabilitiesManager', CapabilitiesManager::class);
$this->registerService(ICommentsManager::class, function (Server $c) {
$config = $c->get(\OCP\IConfig::class);
$factoryClass = $config->getSystemValue('comments.managerFactory', CommentsManagerFactory::class);
/** @var \OCP\Comments\ICommentsManagerFactory $factory */
$factory = new $factoryClass($this);
$manager = $factory->getManager();
$manager->registerDisplayNameResolver('user', function ($id) use ($c) {
$manager = $c->get(IUserManager::class);
$userDisplayName = $manager->getDisplayName($id);
if ($userDisplayName === null) {
$l = $c->get(IFactory::class)->get('core');
return $l->t('Unknown account');
}
return $userDisplayName;
});
return $manager;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CommentsManager', ICommentsManager::class);
$this->registerAlias(\OC_Defaults::class, 'ThemingDefaults');
2017-08-24 10:21:50 -04:00
$this->registerService('ThemingDefaults', function (Server $c) {
try {
$classExists = class_exists('OCA\Theming\ThemingDefaults');
} catch (\OCP\AutoloadNotAllowedException $e) {
// App disabled or in maintenance mode
2016-07-22 10:49:33 -04:00
$classExists = false;
}
if ($classExists && $c->get(\OCP\IConfig::class)->getSystemValueBool('installed', false) && $c->get(IAppManager::class)->isInstalled('theming') && $c->get(TrustedDomainHelper::class)->isTrustedDomain($c->getRequest()->getInsecureServerHost())) {
$backgroundService = new BackgroundService(
$c->get(IRootFolder::class),
$c->getAppDataDir('theming'),
$c->get(\OCP\IConfig::class),
$c->get(ISession::class)->get('user_id'),
);
$imageManager = new ImageManager(
$c->get(\OCP\IConfig::class),
$c->getAppDataDir('theming'),
$c->get(IURLGenerator::class),
$c->get(ICacheFactory::class),
$c->get(LoggerInterface::class),
$c->get(ITempManager::class),
$backgroundService,
);
return new ThemingDefaults(
$c->get(\OCP\IConfig::class),
$c->getL10N('theming'),
$c->get(IUserSession::class),
$c->get(IURLGenerator::class),
$c->get(ICacheFactory::class),
new Util($c->get(\OCP\IConfig::class), $this->get(IAppManager::class), $c->getAppDataDir('theming'), $imageManager),
$imageManager,
$c->get(IAppManager::class),
$c->get(INavigationManager::class),
$backgroundService,
);
}
return new \OC_Defaults();
});
$this->registerService(JSCombiner::class, function (Server $c) {
return new JSCombiner(
$c->getAppDataDir('js'),
$c->get(IURLGenerator::class),
$this->get(ICacheFactory::class),
$c->get(SystemConfig::class),
$c->get(LoggerInterface::class)
);
});
$this->registerAlias(\OCP\EventDispatcher\IEventDispatcher::class, \OC\EventDispatcher\EventDispatcher::class);
$this->registerService('CryptoWrapper', function (ContainerInterface $c) {
// FIXME: Instantiated 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,
],
$c->get(IRequestId::class),
$c->get(\OCP\IConfig::class)
);
return new CryptoWrapper(
$c->get(\OCP\IConfig::class),
$c->get(ICrypto::class),
$c->get(ISecureRandom::class),
$request
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CsrfTokenManager', CsrfTokenManager::class);
$this->registerService(SessionStorage::class, function (ContainerInterface $c) {
return new SessionStorage($c->get(ISession::class));
});
$this->registerAlias(\OCP\Security\IContentSecurityPolicyManager::class, ContentSecurityPolicyManager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('ContentSecurityPolicyManager', ContentSecurityPolicyManager::class);
$this->registerService(IProviderFactory::class, function (ContainerInterface $c) {
$config = $c->get(\OCP\IConfig::class);
$factoryClass = $config->getSystemValue('sharing.managerFactory', ProviderFactory::class);
2016-05-02 05:59:54 -04:00
/** @var \OCP\Share\IProviderFactory $factory */
return new $factoryClass($this);
});
$this->registerAlias(\OCP\Share\IManager::class, \OC\Share20\Manager::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('ShareManager', \OCP\Share\IManager::class);
$this->registerService(\OCP\Collaboration\Collaborators\ISearch::class, function (Server $c) {
$instance = new Collaboration\Collaborators\Search($c);
// register default plugins
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => UserPlugin::class]);
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => GroupPlugin::class]);
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => MailPlugin::class]);
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => RemotePlugin::class]);
$instance->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE_GROUP', 'class' => RemoteGroupPlugin::class]);
return $instance;
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('CollaboratorSearch', \OCP\Collaboration\Collaborators\ISearch::class);
$this->registerAlias(\OCP\Collaboration\Collaborators\ISearchResult::class, \OC\Collaboration\Collaborators\SearchResult::class);
$this->registerAlias(\OCP\Collaboration\AutoComplete\IManager::class, \OC\Collaboration\AutoComplete\Manager::class);
$this->registerAlias(\OCP\Collaboration\Resources\IProviderManager::class, \OC\Collaboration\Resources\ProviderManager::class);
$this->registerAlias(\OCP\Collaboration\Resources\IManager::class, \OC\Collaboration\Resources\Manager::class);
$this->registerAlias(IReferenceManager::class, ReferenceManager::class);
$this->registerAlias(ITeamManager::class, TeamManager::class);
$this->registerDeprecatedAlias('SettingsManager', \OC\Settings\Manager::class);
$this->registerAlias(\OCP\Settings\IManager::class, \OC\Settings\Manager::class);
$this->registerService(\OC\Files\AppData\Factory::class, function (ContainerInterface $c) {
return new \OC\Files\AppData\Factory(
$c->get(IRootFolder::class),
$c->get(SystemConfig::class)
);
});
$this->registerService('LockdownManager', function (ContainerInterface $c) {
2017-08-24 10:21:50 -04:00
return new LockdownManager(function () use ($c) {
return $c->get(ISession::class);
});
});
$this->registerService(\OCP\OCS\IDiscoveryService::class, function (ContainerInterface $c) {
return new DiscoveryService(
$c->get(ICacheFactory::class),
$c->get(IClientService::class)
);
});
$this->registerAlias(IOCMDiscoveryService::class, OCMDiscoveryService::class);
$this->registerService(ICloudIdManager::class, function (ContainerInterface $c) {
return new CloudIdManager(
$c->get(\OCP\Contacts\IManager::class),
$c->get(IURLGenerator::class),
$c->get(IUserManager::class),
$c->get(ICacheFactory::class),
$c->get(IEventDispatcher::class),
);
});
$this->registerAlias(\OCP\GlobalScale\IConfig::class, \OC\GlobalScale\Config::class);
$this->registerService(ICloudFederationProviderManager::class, function (ContainerInterface $c) {
return new CloudFederationProviderManager(
$c->get(\OCP\IConfig::class),
$c->get(IAppManager::class),
$c->get(IClientService::class),
$c->get(ICloudIdManager::class),
$c->get(IOCMDiscoveryService::class),
$c->get(LoggerInterface::class)
);
});
$this->registerService(ICloudFederationFactory::class, function (Server $c) {
return new CloudFederationFactory();
});
$this->registerAlias(\OCP\AppFramework\Utility\IControllerMethodReflector::class, \OC\AppFramework\Utility\ControllerMethodReflector::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('ControllerMethodReflector', \OCP\AppFramework\Utility\IControllerMethodReflector::class);
$this->registerAlias(\OCP\AppFramework\Utility\ITimeFactory::class, \OC\AppFramework\Utility\TimeFactory::class);
$this->registerAlias(\Psr\Clock\ClockInterface::class, \OCP\AppFramework\Utility\ITimeFactory::class);
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('TimeFactory', \OCP\AppFramework\Utility\ITimeFactory::class);
$this->registerService(Defaults::class, function (Server $c) {
return new Defaults(
$c->get('ThemingDefaults')
);
});
/** @deprecated 19.0.0 */
$this->registerDeprecatedAlias('Defaults', \OCP\Defaults::class);
$this->registerService(\OCP\ISession::class, function (ContainerInterface $c) {
return $c->get(\OCP\IUserSession::class)->getSession();
}, false);
$this->registerService(IShareHelper::class, function (ContainerInterface $c) {
return new ShareHelper(
$c->get(\OCP\Share\IManager::class)
);
});
$this->registerService(Installer::class, function (ContainerInterface $c) {
return new Installer(
$c->get(AppFetcher::class),
$c->get(IClientService::class),
$c->get(ITempManager::class),
$c->get(LoggerInterface::class),
$c->get(\OCP\IConfig::class),
\OC::$CLI
);
});
$this->registerService(IApiFactory::class, function (ContainerInterface $c) {
return new ApiFactory($c->get(IClientService::class));
});
$this->registerService(IInstanceFactory::class, function (ContainerInterface $c) {
$memcacheFactory = $c->get(ICacheFactory::class);
return new InstanceFactory($memcacheFactory->createLocal('remoteinstance.'), $c->get(IClientService::class));
});
$this->registerAlias(IContactsStore::class, ContactsStore::class);
$this->registerAlias(IAccountManager::class, AccountManager::class);
$this->registerAlias(IStorageFactory::class, StorageFactory::class);
$this->registerAlias(\OCP\Dashboard\IManager::class, \OC\Dashboard\Manager::class);
$this->registerAlias(IFullTextSearchManager::class, FullTextSearchManager::class);
$this->registerAlias(IFilesMetadataManager::class, FilesMetadataManager::class);
$this->registerAlias(ISubAdmin::class, SubAdmin::class);
$this->registerAlias(IInitialStateService::class, InitialStateService::class);
$this->registerAlias(\OCP\IEmojiHelper::class, \OC\EmojiHelper::class);
$this->registerAlias(\OCP\UserStatus\IManager::class, \OC\UserStatus\Manager::class);
$this->registerAlias(IBroker::class, Broker::class);
$this->registerAlias(\OCP\Files\AppData\IAppDataFactory::class, \OC\Files\AppData\Factory::class);
$this->registerAlias(\OCP\Files\IFilenameValidator::class, \OC\Files\FilenameValidator::class);
$this->registerAlias(IBinaryFinder::class, BinaryFinder::class);
$this->registerAlias(\OCP\Share\IPublicShareTemplateFactory::class, \OC\Share20\PublicShareTemplateFactory::class);
$this->registerAlias(ITranslationManager::class, TranslationManager::class);
$this->registerAlias(ISpeechToTextManager::class, SpeechToTextManager::class);
$this->registerAlias(IEventSourceFactory::class, EventSourceFactory::class);
$this->registerAlias(\OCP\TextProcessing\IManager::class, \OC\TextProcessing\Manager::class);
$this->registerAlias(\OCP\TextToImage\IManager::class, \OC\TextToImage\Manager::class);
$this->registerAlias(ILimiter::class, Limiter::class);
$this->registerAlias(IPhoneNumberUtil::class, PhoneNumberUtil::class);
$this->registerAlias(IOCMProvider::class, OCMProvider::class);
$this->registerAlias(ISetupCheckManager::class, SetupCheckManager::class);
$this->registerAlias(IProfileManager::class, ProfileManager::class);
$this->registerAlias(IAvailabilityCoordinator::class, AvailabilityCoordinator::class);
$this->registerAlias(IDeclarativeManager::class, DeclarativeManager::class);
$this->registerAlias(\OCP\TaskProcessing\IManager::class, \OC\TaskProcessing\Manager::class);
$this->registerAlias(IRemoteAddress::class, RemoteAddress::class);
$this->registerAlias(\OCP\Security\Ip\IFactory::class, \OC\Security\Ip\Factory::class);
$this->connectDispatcher();
}
public function boot() {
/** @var HookConnector $hookConnector */
$hookConnector = $this->get(HookConnector::class);
$hookConnector->viewToNode();
}
public function getCalendarManager() {
return $this->get(\OC\Calendar\Manager::class);
}
public function getCalendarResourceBackendManager() {
return $this->get(\OC\Calendar\Resource\Manager::class);
}
public function getCalendarRoomBackendManager() {
return $this->get(\OC\Calendar\Room\Manager::class);
}
private function connectDispatcher(): void {
/** @var IEventDispatcher $eventDispatcher */
$eventDispatcher = $this->get(IEventDispatcher::class);
$eventDispatcher->addServiceListener(LoginFailed::class, LoginFailedListener::class);
$eventDispatcher->addServiceListener(PostLoginEvent::class, UserLoggedInListener::class);
$eventDispatcher->addServiceListener(UserChangedEvent::class, UserChangedListener::class);
$eventDispatcher->addServiceListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class);
FilesMetadataManager::loadListeners($eventDispatcher);
GenerateBlurhashMetadata::loadListeners($eventDispatcher);
}
public function getContactsManager() {
return $this->get(\OCP\Contacts\IManager::class);
}
public function getEncryptionManager() {
return $this->get(\OCP\Encryption\IManager::class);
}
public function getEncryptionFilesHelper() {
return $this->get(IFile::class);
}
public function getEncryptionKeyStorage() {
return $this->get(IStorage::class);
}
public function getRequest() {
return $this->get(IRequest::class);
}
2013-09-04 17:45:11 -04:00
public function getPreviewManager() {
return $this->get(IPreview::class);
2013-09-04 17:45:11 -04:00
}
public function getTagManager() {
return $this->get(ITagManager::class);
}
public function getSystemTagManager() {
return $this->get(ISystemTagManager::class);
}
public function getSystemTagObjectMapper() {
return $this->get(ISystemTagObjectMapper::class);
}
public function getAvatarManager() {
return $this->get(IAvatarManager::class);
2013-09-20 05:46:11 -04:00
}
public function getRootFolder() {
return $this->get(IRootFolder::class);
}
2016-03-11 08:00:36 -05: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 IRootFolder
* @deprecated 20.0.0
2016-03-11 08:00:36 -05:00
*/
public function getLazyRootFolder() {
return $this->get(IRootFolder::class);
2016-03-11 08:00:36 -05:00
}
public function getUserFolder($userId = null) {
if ($userId === null) {
$user = $this->get(IUserSession::class)->getUser();
if (!$user) {
return null;
}
$userId = $user->getUID();
}
$root = $this->get(IRootFolder::class);
return $root->getUserFolder($userId);
2013-09-18 08:25:12 -04:00
}
public function getUserManager() {
return $this->get(IUserManager::class);
2013-09-20 06:45:56 -04:00
}
public function getGroupManager() {
return $this->get(IGroupManager::class);
2014-07-16 08:25:31 -04:00
}
public function getUserSession() {
return $this->get(IUserSession::class);
2013-09-20 06:45:56 -04:00
}
public function getSession() {
return $this->get(Session::class)->getSession();
}
/**
* @param \OCP\ISession $session
* @return void
*/
public function setSession(\OCP\ISession $session) {
$this->get(SessionStorage::class)->setSession($session);
$this->get(Session::class)->setSession($session);
$this->get(Store::class)->setSession($session);
}
2016-05-11 05:23:25 -04:00
/**
* @return \OC\Authentication\TwoFactorAuth\Manager
* @deprecated 20.0.0
2016-05-11 05:23:25 -04:00
*/
public function getTwoFactorAuthManager() {
return $this->get(\OC\Authentication\TwoFactorAuth\Manager::class);
2016-05-11 05:23:25 -04:00
}
public function getNavigationManager() {
return $this->get(INavigationManager::class);
}
public function getConfig() {
return $this->get(AllConfig::class);
}
/**
* @return \OC\SystemConfig
* @deprecated 20.0.0
*/
public function getSystemConfig() {
return $this->get(SystemConfig::class);
}
public function getAppConfig() {
return $this->get(IAppConfig::class);
}
public function getL10NFactory() {
return $this->get(IFactory::class);
}
public function getL10N($app, $lang = null) {
return $this->get(IFactory::class)->get($app, $lang);
2013-09-25 12:34:01 -04:00
}
public function getURLGenerator() {
return $this->get(IURLGenerator::class);
}
/**
* @return AppFetcher
* @deprecated 20.0.0
*/
public function getAppFetcher() {
return $this->get(AppFetcher::class);
}
public function getCache() {
return $this->get(ICache::class);
}
public function getMemCacheFactory() {
return $this->get(ICacheFactory::class);
2014-01-06 06:55:56 -05:00
}
/**
* Returns an \OC\RedisFactory instance
*
* @return \OC\RedisFactory
* @deprecated 20.0.0
*/
public function getGetRedisFactory() {
return $this->get('RedisFactory');
}
public function getDatabaseConnection() {
return $this->get(IDBConnection::class);
2013-09-20 08:33:45 -04:00
}
public function getActivityManager() {
return $this->get(\OCP\Activity\IManager::class);
2013-09-20 08:33:45 -04:00
}
public function getJobList() {
return $this->get(IJobList::class);
}
public function getLogger() {
return $this->get(ILogger::class);
}
public function getLogFactory() {
return $this->get(ILogFactory::class);
}
public function getRouter() {
return $this->get(IRouter::class);
}
2014-04-19 13:30:12 -04:00
public function getSecureRandom() {
return $this->get(ISecureRandom::class);
}
public function getCrypto() {
return $this->get(ICrypto::class);
}
public function getHasher() {
return $this->get(IHasher::class);
}
public function getCredentialsManager() {
return $this->get(ICredentialsManager::class);
}
public function getCertificateManager() {
return $this->get(ICertificateManager::class);
}
2014-08-29 11:19:38 -04:00
public function getHTTPClientService() {
return $this->get(IClientService::class);
2015-03-16 06:28:23 -04:00
}
public function getEventLogger() {
return $this->get(IEventLogger::class);
}
public function getQueryLogger() {
return $this->get(IQueryLogger::class);
}
public function getTempManager() {
return $this->get(ITempManager::class);
}
public function getAppManager() {
return $this->get(IAppManager::class);
}
2014-11-27 08:36:11 -05:00
public function getMailer() {
return $this->get(IMailer::class);
}
public function getWebRoot() {
2014-11-27 08:50:14 -05:00
return $this->webRoot;
2014-11-27 08:36:11 -05:00
}
/**
* @return \OC\OCSClient
* @deprecated 20.0.0
*/
public function getOcsClient() {
return $this->get('OcsClient');
}
2014-12-16 09:34:55 -05:00
public function getDateTimeZone() {
return $this->get(IDateTimeZone::class);
2014-12-16 09:34:55 -05:00
}
public function getDateTimeFormatter() {
return $this->get(IDateTimeFormatter::class);
}
2015-12-03 08:10:05 -05:00
public function getMountProviderCollection() {
return $this->get(IMountProviderCollection::class);
}
2014-12-05 13:56:29 -05:00
public function getIniWrapper() {
return $this->get(IniGetWrapper::class);
2014-12-05 13:56:29 -05:00
}
2015-02-16 16:12:47 -05:00
2015-12-03 08:10:05 -05:00
public function getCommandBus() {
return $this->get(IBus::class);
}
2015-02-16 16:12:47 -05:00
/**
* Get the trusted domain helper
*
* @return TrustedDomainHelper
* @deprecated 20.0.0
2015-02-16 16:12:47 -05:00
*/
public function getTrustedDomainHelper() {
return $this->get(TrustedDomainHelper::class);
2015-02-16 16:12:47 -05:00
}
public function getLockingProvider() {
return $this->get(ILockingProvider::class);
}
public function getMountManager() {
return $this->get(IMountManager::class);
}
/**
* @return IUserMountCache
* @deprecated 20.0.0
*/
public function getUserMountCache() {
return $this->get(IUserMountCache::class);
}
public function getMimeTypeDetector() {
return $this->get(IMimeTypeDetector::class);
}
2015-09-03 14:48:42 -04:00
public function getMimeTypeLoader() {
return $this->get(IMimeTypeLoader::class);
2015-09-03 14:48:42 -04:00
}
/**
* Get the manager of all the capabilities
*
* @return CapabilitiesManager
* @deprecated 20.0.0
*/
public function getCapabilitiesManager() {
return $this->get(CapabilitiesManager::class);
}
2015-08-31 06:24:37 -04:00
public function getNotificationManager() {
return $this->get(\OCP\Notification\IManager::class);
2015-08-31 06:24:37 -04:00
}
public function getCommentsManager() {
return $this->get(ICommentsManager::class);
}
/**
* @return \OCA\Theming\ThemingDefaults
* @deprecated 20.0.0
*/
public function getThemingDefaults() {
return $this->get('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 14:26:06 -05:00
/**
* @return \OC\IntegrityCheck\Checker
* @deprecated 20.0.0
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 14:26:06 -05:00
*/
public function getIntegrityCodeChecker() {
return $this->get('IntegrityCodeChecker');
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 14:26:06 -05:00
}
/**
* @return \OC\Session\CryptoWrapper
* @deprecated 20.0.0
*/
public function getSessionCryptoWrapper() {
return $this->get('CryptoWrapper');
}
/**
* @return CsrfTokenManager
* @deprecated 20.0.0
*/
public function getCsrfTokenManager() {
return $this->get(CsrfTokenManager::class);
}
/**
* @return IThrottler
* @deprecated 20.0.0
*/
public function getBruteForceThrottler() {
return $this->get(Throttler::class);
}
Add public API to give developers the possibility to adjust the global CSP defaults Allows to inject something into the default content policy. This is for example useful when you're injecting Javascript code into a view belonging to another controller and cannot modify its Content-Security-Policy itself. Note that the adjustment is only applied to applications that use AppFramework controllers. To use this from your `app.php` use `\OC::$server->getContentSecurityPolicyManager()->addDefaultPolicy($policy)`, $policy has to be of type `\OCP\AppFramework\Http\ContentSecurityPolicy`. To test this add something like the following into an `app.php` of any enabled app: ``` $manager = \OC::$server->getContentSecurityPolicyManager(); $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy(false); $policy->addAllowedFrameDomain('asdf'); $policy->addAllowedScriptDomain('yolo.com'); $policy->allowInlineScript(false); $manager->addDefaultPolicy($policy); $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy(false); $policy->addAllowedFontDomain('yolo.com'); $manager->addDefaultPolicy($policy); $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy(false); $policy->addAllowedFrameDomain('banana.com'); $manager->addDefaultPolicy($policy); ``` If you now open the files app the policy should be: ``` Content-Security-Policy:default-src 'none';script-src yolo.com 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src yolo.com 'self';connect-src 'self';media-src 'self';frame-src asdf banana.com 'self' ```
2016-01-28 08:33:02 -05:00
public function getContentSecurityPolicyManager() {
return $this->get(ContentSecurityPolicyManager::class);
Add public API to give developers the possibility to adjust the global CSP defaults Allows to inject something into the default content policy. This is for example useful when you're injecting Javascript code into a view belonging to another controller and cannot modify its Content-Security-Policy itself. Note that the adjustment is only applied to applications that use AppFramework controllers. To use this from your `app.php` use `\OC::$server->getContentSecurityPolicyManager()->addDefaultPolicy($policy)`, $policy has to be of type `\OCP\AppFramework\Http\ContentSecurityPolicy`. To test this add something like the following into an `app.php` of any enabled app: ``` $manager = \OC::$server->getContentSecurityPolicyManager(); $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy(false); $policy->addAllowedFrameDomain('asdf'); $policy->addAllowedScriptDomain('yolo.com'); $policy->allowInlineScript(false); $manager->addDefaultPolicy($policy); $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy(false); $policy->addAllowedFontDomain('yolo.com'); $manager->addDefaultPolicy($policy); $policy = new \OCP\AppFramework\Http\ContentSecurityPolicy(false); $policy->addAllowedFrameDomain('banana.com'); $manager->addDefaultPolicy($policy); ``` If you now open the files app the policy should be: ``` Content-Security-Policy:default-src 'none';script-src yolo.com 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src yolo.com 'self';connect-src 'self';media-src 'self';frame-src asdf banana.com 'self' ```
2016-01-28 08:33:02 -05:00
}
/**
* @return ContentSecurityPolicyNonceManager
* @deprecated 20.0.0
*/
public function getContentSecurityPolicyNonceManager() {
return $this->get(ContentSecurityPolicyNonceManager::class);
}
/**
* Not a public API as of 8.2, wait for 9.0
2015-12-03 08:10:05 -05:00
*
* @return \OCA\Files_External\Service\BackendService
* @deprecated 20.0.0
*/
public function getStoragesBackendService() {
return $this->get(BackendService::class);
}
/**
* Not a public API as of 8.2, wait for 9.0
2015-12-03 08:10:05 -05:00
*
* @return \OCA\Files_External\Service\GlobalStoragesService
* @deprecated 20.0.0
*/
public function getGlobalStoragesService() {
return $this->get(GlobalStoragesService::class);
}
/**
* Not a public API as of 8.2, wait for 9.0
2015-12-03 08:10:05 -05:00
*
* @return \OCA\Files_External\Service\UserGlobalStoragesService
* @deprecated 20.0.0
*/
public function getUserGlobalStoragesService() {
return $this->get(UserGlobalStoragesService::class);
}
/**
* Not a public API as of 8.2, wait for 9.0
2015-12-03 08:10:05 -05:00
*
* @return \OCA\Files_External\Service\UserStoragesService
* @deprecated 20.0.0
*/
public function getUserStoragesService() {
return $this->get(UserStoragesService::class);
}
public function getShareManager() {
return $this->get(\OCP\Share\IManager::class);
}
2015-12-03 08:10:05 -05:00
/**
* @return \OCP\Collaboration\Collaborators\ISearch
* @deprecated 20.0.0
*/
public function getCollaboratorSearch() {
return $this->get(\OCP\Collaboration\Collaborators\ISearch::class);
}
/**
* @return \OCP\Collaboration\AutoComplete\IManager
* @deprecated 20.0.0
*/
public function getAutoCompleteManager() {
return $this->get(IManager::class);
}
2016-07-22 04:46:29 -04:00
/**
* Returns the LDAP Provider
*
* @return \OCP\LDAP\ILDAPProvider
* @deprecated 20.0.0
2016-07-22 04:46:29 -04:00
*/
public function getLDAPProvider() {
return $this->get('LDAPProvider');
2016-07-22 04:46:29 -04:00
}
/**
* @return \OCP\Settings\IManager
* @deprecated 20.0.0
*/
public function getSettingsManager() {
return $this->get(\OC\Settings\Manager::class);
}
/**
* @return \OCP\Files\IAppData
* @deprecated 20.0.0 Use get(\OCP\Files\AppData\IAppDataFactory::class)->get($app) instead
*/
public function getAppDataDir($app) {
/** @var \OC\Files\AppData\Factory $factory */
$factory = $this->get(\OC\Files\AppData\Factory::class);
return $factory->get($app);
}
/**
* @return \OCP\Lockdown\ILockdownManager
* @deprecated 20.0.0
*/
public function getLockdownManager() {
return $this->get('LockdownManager');
}
public function getCloudIdManager() {
return $this->get(ICloudIdManager::class);
}
public function getGlobalScaleConfig() {
return $this->get(IConfig::class);
}
public function getCloudFederationProviderManager() {
return $this->get(ICloudFederationProviderManager::class);
}
public function getRemoteApiFactory() {
return $this->get(IApiFactory::class);
}
public function getCloudFederationFactory() {
return $this->get(ICloudFederationFactory::class);
}
public function getRemoteInstanceFactory() {
return $this->get(IInstanceFactory::class);
}
public function getStorageFactory() {
return $this->get(IStorageFactory::class);
}
/**
* Get the Preview GeneratorHelper
*
* @return GeneratorHelper
* @since 17.0.0
* @deprecated 20.0.0
*/
public function getGeneratorHelper() {
return $this->get(\OC\Preview\GeneratorHelper::class);
}
private function registerDeprecatedAlias(string $alias, string $target) {
$this->registerService($alias, function (ContainerInterface $container) use ($target, $alias) {
try {
/** @var LoggerInterface $logger */
$logger = $container->get(LoggerInterface::class);
$logger->debug('The requested alias "' . $alias . '" is deprecated. Please request "' . $target . '" directly. This alias will be removed in a future Nextcloud version.', ['app' => 'serverDI']);
} catch (ContainerExceptionInterface $e) {
// Could not get logger. Continue
}
return $container->get($target);
}, false);
}
2013-08-20 18:58:15 -04:00
}