libreoffice-online/loolwsd/Storage.hpp
Ashod Nakashian 9485b4fe63 loolwsd: disable loading of local docs by default
Loading documents from the local filesystem
opens the door to security issues.

By default filesystem storage is disabled,
even if enabled in the config file. The
only way to enable it is to set the
allowlocalstorage command-line argument.

Change-Id: Ib8f57377260817436d101a16757aab38276cbdcd
Reviewed-on: https://gerrit.libreoffice.org/23881
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2016-04-07 04:45:31 +00:00

167 lines
4.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Storage abstraction.
#ifndef INCLUDED_STORAGE_HPP
#define INCLUDED_STORAGE_HPP
#include <string>
#include <Poco/Util/Application.h>
#include <Poco/URI.h>
#include "Auth.hpp"
#include "Util.hpp"
/// Base class of all Storage abstractions.
class StorageBase
{
public:
class FileInfo
{
public:
bool isValid() const
{
return !Filename.empty() && Size > 0;
}
std::string Filename;
Poco::Timestamp ModifiedTime;
size_t Size;
};
/// localStorePath the absolute root path of the chroot.
/// jailPath the path within the jail that the child uses.
StorageBase(const std::string& localStorePath,
const std::string& jailPath,
const std::string& uri) :
_localStorePath(localStorePath),
_jailPath(jailPath),
_uri(uri)
{
Log::debug("Storage ctor: " + uri);
}
std::string getLocalRootPath() const;
const std::string& getUri() const { return _uri; }
/// Returns information about the file.
virtual FileInfo getFileInfo(const Poco::URI& uri) = 0;
/// Returns a local file path for the given URI.
/// If necessary copies the file locally first.
virtual std::string loadStorageFileToLocal() = 0;
/// Writes the contents of the file back to the source.
/// TODO: Should we save to the specific client's URI?
/// The advantage is that subseqent views (to the first)
/// will not depend on the token of the first.
virtual bool saveLocalFileToStorage() = 0;
static
size_t getFileSize(const std::string& filename);
protected:
const std::string _localStorePath;
const std::string _jailPath;
const std::string _uri;
std::string _jailedFilePath;
FileInfo _fileInfo;
};
/// Trivial implementation of local storage that does not need do anything.
class LocalStorage : public StorageBase
{
public:
LocalStorage(const std::string& localStorePath,
const std::string& jailPath,
const std::string& uri) :
StorageBase(localStorePath, jailPath, uri),
_isCopy(false)
{
}
FileInfo getFileInfo(const Poco::URI& uri) override;
std::string loadStorageFileToLocal() override;
bool saveLocalFileToStorage() override;
private:
/// True if the jailed file is not linked but copied.
bool _isCopy;
};
class WopiStorage : public StorageBase
{
public:
WopiStorage(const std::string& localStorePath,
const std::string& jailPath,
const std::string& uri) :
StorageBase(localStorePath, jailPath, uri)
{
}
FileInfo getFileInfo(const Poco::URI& uri) override;
/// uri format: http://server/<...>/wopi*/files/<id>/content
std::string loadStorageFileToLocal() override;
bool saveLocalFileToStorage() override;
};
class WebDAVStorage : public StorageBase
{
public:
WebDAVStorage(const std::string& localStorePath,
const std::string& jailPath,
const std::string& uri,
std::unique_ptr<AuthBase> authAgent) :
StorageBase(localStorePath, jailPath, uri),
_authAgent(std::move(authAgent))
{
}
FileInfo getFileInfo(const Poco::URI& uri) override;
std::string loadStorageFileToLocal() override;
bool saveLocalFileToStorage() override;
private:
std::unique_ptr<AuthBase> _authAgent;
};
inline
std::unique_ptr<StorageBase> createStorage(const std::string& jailRoot, const std::string& jailPath, const Poco::URI& uri)
{
if (uri.isRelative() || uri.getScheme() == "file")
{
if (!Poco::Util::Application::instance().config().getBool("storage.filesystem[@allow]", false))
{
Log::error("Local Storage is disabled by default. Specify allowlocalstorage on the command-line to enable.");
return nullptr;
}
Log::info("Public URI [" + uri.toString() + "] is a file.");
return std::unique_ptr<StorageBase>(new LocalStorage(jailRoot, jailPath, uri.getPath()));
}
else
{
Log::info("Public URI [" + uri.toString() +
"] assuming cloud storage.");
//TODO: Configure the storage to use. For now, assume it's WOPI.
return std::unique_ptr<StorageBase>(new WopiStorage(jailRoot, jailPath, uri.toString()));
}
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */