basic lockdown logic

Signed-off-by: Robin Appelman <icewind@owncloud.com>
This commit is contained in:
Robin Appelman 2016-08-01 18:27:07 +02:00 committed by Robin Appelman
parent d03446a0ae
commit b56f2c9ed0
No known key found for this signature in database
GPG Key ID: 425003AC385454C5
10 changed files with 424 additions and 16 deletions

View File

@ -159,6 +159,7 @@ class Auth extends AbstractBasic {
} catch (Exception $e) {
$class = get_class($e);
$msg = $e->getMessage();
\OC::$server->getLogger()->logException($e);
throw new ServiceUnavailable("$class: $msg");
}
}

View File

@ -112,6 +112,11 @@ class AppManager implements IAppManager {
return $value !== 'no';
});
ksort($this->installedAppsCache);
foreach ($this->installedAppsCache as $appId => $value) {
if (!\OC::$server->getLockdownManager()->canAccessApp($appId)) {
unset($this->installedAppsCache[$appId]);
}
}
}
return $this->installedAppsCache;
}

View File

@ -62,6 +62,7 @@ use OC\Cache\CappedMemoryCache;
use OC\Files\Config\MountProviderCollection;
use OC\Files\Mount\MountPoint;
use OC\Files\Storage\StorageFactory;
use OC\Lockdown\Filesystem\NullStorage;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException;
@ -216,7 +217,7 @@ class Filesystem {
* @internal
*/
public static function logWarningWhenAddingStorageWrapper($shouldLog) {
self::$logWarningWhenAddingStorageWrapper = (bool) $shouldLog;
self::$logWarningWhenAddingStorageWrapper = (bool)$shouldLog;
}
/**
@ -426,25 +427,36 @@ class Filesystem {
self::$usersSetup[$user] = true;
}
/** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */
$mountConfigManager = \OC::$server->getMountProviderCollection();
if (\OC::$server->getLockdownManager()->canAccessFilesystem()) {
/** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */
$mountConfigManager = \OC::$server->getMountProviderCollection();
// home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers
$homeMount = $mountConfigManager->getHomeMountForUser($userObject);
// home mounts are handled seperate since we need to ensure this is mounted before we call the other mount providers
$homeMount = $mountConfigManager->getHomeMountForUser($userObject);
self::getMountManager()->addMount($homeMount);
self::getMountManager()->addMount($homeMount);
\OC\Files\Filesystem::getStorage($user);
\OC\Files\Filesystem::getStorage($user);
// Chance to mount for other storages
if ($userObject) {
$mounts = $mountConfigManager->getMountsForUser($userObject);
array_walk($mounts, array(self::$mounts, 'addMount'));
$mounts[] = $homeMount;
$mountConfigManager->registerMounts($userObject, $mounts);
// Chance to mount for other storages
if ($userObject) {
$mounts = $mountConfigManager->getMountsForUser($userObject);
array_walk($mounts, array(self::$mounts, 'addMount'));
$mounts[] = $homeMount;
$mountConfigManager->registerMounts($userObject, $mounts);
}
self::listenForNewMountProviders($mountConfigManager, $userManager);
} else {
self::$mounts->addMount(new MountPoint(
new NullStorage([]),
'/' . $user
));
self::$mounts->addMount(new MountPoint(
new NullStorage([]),
'/' . $user . '/files'
));
}
self::listenForNewMountProviders($mountConfigManager, $userManager);
\OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user));
}

View File

@ -0,0 +1,122 @@
<?php
/**
* @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl>
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Lockdown\Filesystem;
use OC\Files\Cache\CacheEntry;
use OCP\Constants;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo;
class NullCache implements ICache {
public function getNumericStorageId() {
return -1;
}
public function get($file) {
return $file !== '' ? null :
new CacheEntry([
'fileid' => -1,
'parent' => -1,
'name' => '',
'path' => '',
'size' => '0',
'mtime' => time(),
'storage_mtime' => time(),
'etag' => '',
'mimetype' => FileInfo::MIMETYPE_FOLDER,
'mimepart' => 'httpd',
'permissions' => Constants::PERMISSION_READ
]);
}
public function getFolderContents($folder) {
return [];
}
public function getFolderContentsById($fileId) {
return [];
}
public function put($file, array $data) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function insert($file, array $data) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function update($id, array $data) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function getId($file) {
return -1;
}
public function getParentId($file) {
return -1;
}
public function inCache($file) {
return $file === '';
}
public function remove($file) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function move($source, $target) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function getStatus($file) {
return ICache::COMPLETE;
}
public function search($pattern) {
return [];
}
public function searchByMime($mimetype) {
return [];
}
public function searchByTag($tag, $userId) {
return [];
}
public function getIncomplete() {
return [];
}
public function getPathById($id) {
return '';
}
public function normalize($path) {
return $path;
}
}

View File

@ -0,0 +1,177 @@
<?php
/**
* @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl>
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Lockdown\Filesystem;
use Icewind\Streams\IteratorDirectory;
use OC\Files\Storage\Common;
class NullStorage extends Common {
public function __construct($parameters) {
parent::__construct($parameters);
}
public function getId() {
return 'null';
}
public function mkdir($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function rmdir($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function opendir($path) {
return new IteratorDirectory([]);
}
public function is_dir($path) {
return $path === '';
}
public function is_file($path) {
return false;
}
public function stat($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function filetype($path) {
return ($path === '') ? 'dir' : false;
}
public function filesize($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function isCreatable($path) {
return false;
}
public function isReadable($path) {
return $path === '';
}
public function isUpdatable($path) {
return false;
}
public function isDeletable($path) {
return false;
}
public function isSharable($path) {
return false;
}
public function getPermissions($path) {
return null;
}
public function file_exists($path) {
return $path === '';
}
public function filemtime($path) {
return ($path === '') ? time() : false;
}
public function file_get_contents($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function file_put_contents($path, $data) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function unlink($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function rename($path1, $path2) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function copy($path1, $path2) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function fopen($path, $mode) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function getMimeType($path) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function hash($type, $path, $raw = false) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function free_space($path) {
return 0;
}
public function touch($path, $mtime = null) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function getLocalFile($path) {
return false;
}
public function hasUpdated($path, $time) {
return false;
}
public function getETag($path) {
return '';
}
public function isLocal() {
return false;
}
public function getDirectDownload($path) {
return false;
}
public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
throw new \OC\ForbiddenException('This request is not allowed to access the filesystem');
}
public function test() {
return true;
}
public function getOwner($path) {
return null;
}
public function getCache($path = '', $storage = null) {
return new NullCache();
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl>
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Lockdown;
use OC\Authentication\Token\IToken;
use OCP\Lockdown\ILockdownManager;
class LockdownManager implements ILockdownManager {
/** @var IToken|null */
private $token;
private $enabled = false;
public function enable() {
$this->enabled = true;
}
public function setToken(IToken $token) {
$this->token = $token;
}
public function canAccessFilesystem() {
return true;
}
public function canAccessApp($app) {
return $app === 'logreader' || $app === 'files' || $app === 'dav';
}
}

View File

@ -69,6 +69,7 @@ use OC\IntegrityCheck\Helpers\FileAccessHelper;
use OC\Lock\DBLockingProvider;
use OC\Lock\MemcacheLockingProvider;
use OC\Lock\NoopLockingProvider;
use OC\Lockdown\LockdownManager;
use OC\Mail\Mailer;
use OC\Memcache\ArrayCache;
use OC\Notification\Manager;
@ -795,6 +796,9 @@ class Server extends ServerContainer implements IServerContainer {
$c->getSystemConfig()
);
});
$this->registerService('LockdownManager', function (Server $c) {
return new LockdownManager();
});
}
/**
@ -1534,4 +1538,11 @@ class Server extends ServerContainer implements IServerContainer {
$factory = $this->query(\OC\Files\AppData\Factory::class);
return $factory->get($app);
}
/**
* @return \OCP\Lockdown\ILockdownManager
*/
public function getLockdownManager() {
return $this->query('LockdownManager');
}
}

View File

@ -341,10 +341,12 @@ class Session implements IUserSession, Emitter {
if ($isTokenPassword) {
$this->session->set('app_password', $password);
\OC::$server->getLockdownManager()->setToken($this->tokenProvider->getToken($password));
} else if($this->supportsCookies($request)) {
// Password login, but cookies supported -> create (browser) session token
$this->createSessionToken($request, $this->getUser()->getUID(), $user, $password);
}
\OC::$server->getLockdownManager()->enable();
return true;
}

View File

@ -140,7 +140,7 @@ class OC_App {
public static function loadApp($app, $checkUpgrade = true) {
self::$loadedApps[] = $app;
$appPath = self::getAppPath($app);
if($appPath === false) {
if($appPath === false || !\OC::$server->getLockdownManager()->canAccessApp($app)) {
return;
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @copyright Copyright (c) 2016, Robin Appelman <robin@icewind.nl>
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCP\Lockdown;
use OC\Authentication\Token\IToken;
interface ILockdownManager {
public function enable();
public function setToken(IToken $token);
public function canAccessFilesystem();
public function canAccessApp($app);
}