[Libreoffice-commits] online.git: 7 commits - loleaflet/dist wsd/FileServer.cpp wsd/FileServer.hpp
Pranav Kant
pranavk at collabora.co.uk
Fri Apr 7 08:16:41 UTC 2017
loleaflet/dist/loleaflet.html | 11 +++--
loleaflet/dist/toolbar/toolbar.js | 21 +++++----
wsd/FileServer.cpp | 81 ++++++++++++++++++++------------------
wsd/FileServer.hpp | 8 ++-
4 files changed, 69 insertions(+), 52 deletions(-)
New commits:
commit 1a1a3ebb3ce05f7c1dbdef93236f40a2a83e5b4b
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Apr 7 12:16:51 2017 +0530
wsd: Fileserver cleanup
Remove unnecessary checks
Rename preprocessFile -> preprocessAndSendLoleafletHtml and
Rename isAdminLoggedIn -> tryAdminLogin
so that their name matches the actual reality of what these
function really does.
Change-Id: I549eae31f8ab0a320bb3ff8ecd17a282b8f91e1a
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 29be66f6..70abae4a 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -44,8 +44,8 @@ using Poco::Net::HTTPBasicCredentials;
using Poco::StreamCopier;
using Poco::Util::Application;
-bool FileServerRequestHandler::isAdminLoggedIn(const HTTPRequest& request,
- HTTPResponse &response)
+bool FileServerRequestHandler::tryAdminLogin(const HTTPRequest& request,
+ HTTPResponse &response)
{
const auto& config = Application::instance().config();
const auto sslKeyPath = config.getString("ssl.key_file_path", "");
@@ -109,53 +109,40 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
{
bool noCache = false;
Poco::Net::HTTPResponse response;
- Poco::URI requestUri(request.getURI());
- LOG_TRC("Fileserver request: " << requestUri.toString());
- requestUri.normalize(); // avoid .'s and ..'s
-
- std::vector<std::string> requestSegments;
- requestUri.getPathSegments(requestSegments);
- if (requestSegments.size() < 1)
+ const auto requestPathname = Poco::Path(getRequestPathname(request));
+ const auto filePath = Poco::Path(LOOLWSD::FileServerRoot, requestPathname);
+ const auto file = Poco::File(filePath);
+ LOG_TRC("Fileserver request: " << requestPathname.toString() << ", " <<
+ "Resolved file path: " << filePath.toString());
+
+ if (!file.exists() ||
+ requestPathname[0] != "loleaflet" ||
+ requestPathname[1] != "dist")
{
- throw Poco::FileNotFoundException("Invalid URI request: [" + requestUri.toString() + "].");
+ throw Poco::FileNotFoundException("Invalid URI request: [" + filePath.toString() + "].");
}
const auto& config = Application::instance().config();
const std::string loleafletHtml = config.getString("loleaflet_html", "loleaflet.html");
- const std::string endPoint = requestSegments[requestSegments.size() - 1];
- if (endPoint == loleafletHtml)
+ if (filePath.getFileName() == loleafletHtml)
{
- preprocessFile(request, message, socket);
+ preprocessAndSendLoleafletHtml(request, message, socket);
return;
}
if (request.getMethod() == HTTPRequest::HTTP_GET)
{
- if (endPoint == "admin.html" ||
- endPoint == "adminSettings.html" ||
- endPoint == "adminAnalytics.html")
+ if (filePath.getFileName() == "admin.html" ||
+ filePath.getFileName() == "adminSettings.html" ||
+ filePath.getFileName() == "adminAnalytics.html")
{
noCache = true;
- if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
+ if (!FileServerRequestHandler::tryAdminLogin(request, response))
throw Poco::Net::NotAuthenticatedException("Invalid admin login");
}
- const auto path = Poco::Path(LOOLWSD::FileServerRoot, getRequestPathname(request));
- const auto filepath = path.absolute().toString();
- if (filepath.find(LOOLWSD::FileServerRoot) != 0)
- {
- // Accessing unauthorized path.
- throw Poco::FileAccessDeniedException("Invalid or forbidden file path: [" + filepath + "].");
- }
-
- const std::size_t extPoint = endPoint.find_last_of('.');
- if (extPoint == std::string::npos)
- {
- throw Poco::FileNotFoundException("Invalid file.");
- }
-
- const std::string fileType = endPoint.substr(extPoint + 1);
+ const std::string fileType = filePath.getExtension();
std::string mimeType;
if (fileType == "js")
mimeType = "application/javascript";
@@ -195,7 +182,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
response.setContentType(mimeType);
bool deflate = request.hasToken("Accept-Encoding", "deflate");
- HttpHelper::sendFile(socket, filepath, response, noCache, deflate);
+ HttpHelper::sendFile(socket, filePath.toString(), response, noCache, deflate);
}
}
catch (const Poco::Net::NotAuthenticatedException& exc)
@@ -248,13 +235,17 @@ std::string FileServerRequestHandler::getRequestPathname(const HTTPRequest& requ
std::string path(requestUri.getPath());
- // Convert version back to a real file name. Remove first foreslash as the root ends in one.
- Poco::replaceInPlace(path, std::string("/loleaflet/" LOOLWSD_VERSION_HASH "/"), std::string("loleaflet/dist/"));
+ // Remove first foreslash as the root ends in one.
+ if (path[0] == '/')
+ path = path.substr(1);
+
+ // Convert version back to a real file name.
+ Poco::replaceInPlace(path, std::string("loleaflet/" LOOLWSD_VERSION_HASH "/"), std::string("loleaflet/dist/"));
return path;
}
-void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket)
+void FileServerRequestHandler::preprocessAndSendLoleafletHtml(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket)
{
const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName);
const auto params = Poco::URI(request.getURI()).getQueryParameters();
diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp
index b27526f3..3ba6803f 100644
--- a/wsd/FileServer.hpp
+++ b/wsd/FileServer.hpp
@@ -20,11 +20,13 @@ class FileServerRequestHandler
{
static std::string getRequestPathname(const Poco::Net::HTTPRequest& request);
- static void preprocessFile(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
+ static void preprocessAndSendLoleafletHtml(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
public:
- /// Evaluate if the cookie exists, and if not, ask for the credentials.
- static bool isAdminLoggedIn(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
+ /// If valid cookies exists in request, log the admin in (returns true)
+ /// If no cookie exist check the credentials, set the cookie and log the admin in
+ /// In case no valid cookie exists or invalid or no credentials exist, return false
+ static bool tryAdminLogin(const Poco::Net::HTTPRequest& request, Poco::Net::HTTPResponse& response);
static void handleRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket);
};
commit 1614f8d417e48ed7731e9284e01455b8061a5f87
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Apr 7 11:58:27 2017 +0530
security: Mention X-Frame-Options too for ie/edge
ie/edge ignores frame-ancestor directive of CSP (yet). Mention X-Frame-Options
for them. Similary, X-Frame-Options allow-from attribute is not
supported by Chrome:
(see https://bugs.chromium.org/p/chromium/issues/detail?id=511521)
In that case, we already have frame-ancestor CSP directive for it.
Change-Id: Ide00c4db88c438de5e9c679360b3da6f4eb4a1be
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index cedd8259..29be66f6 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -341,7 +341,8 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
<< "Cache-Control:max-age=11059200\r\n"
<< "ETag: \"" LOOLWSD_VERSION_HASH "\"\r\n"
<< "Content-Length: " << preprocess.size() << "\r\n"
- << "Content-Type: " << mimeType << "\r\n";
+ << "Content-Type: " << mimeType << "\r\n"
+ << "X-Frame-Options: allow-from " << wopiDomain << "\r\n";
if (!wopiDomain.empty())
oss << "Content-Security-Policy: frame-ancestors " << wopiDomain << "\r\n";
commit ffc5d516b4e55b2f95f0f9b03013775fa5a5ec65
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Apr 7 11:53:43 2017 +0530
security: CSP: Add frame-ancestor directive
Block embedding LibreOffice Online is frames of different origin.
Change-Id: If3e04a0704e42853dc757b4be1f30fc22b8b33e4
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 0f987579..cedd8259 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -257,6 +257,17 @@ std::string FileServerRequestHandler::getRequestPathname(const HTTPRequest& requ
void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket)
{
const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName);
+ const auto params = Poco::URI(request.getURI()).getQueryParameters();
+ std::string wopiDomain;
+ for (const auto& param : params)
+ {
+ if (param.first == "WOPISrc")
+ {
+ std::string wopiHost;
+ Poco::URI::decode(param.second, wopiHost);
+ wopiDomain = Poco::URI(wopiHost).getScheme() + "://" + Poco::URI(wopiHost).getHost();
+ }
+ }
const auto path = Poco::Path(LOOLWSD::FileServerRoot, getRequestPathname(request));
LOG_DBG("Preprocessing file: " << path.toString());
@@ -330,8 +341,12 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
<< "Cache-Control:max-age=11059200\r\n"
<< "ETag: \"" LOOLWSD_VERSION_HASH "\"\r\n"
<< "Content-Length: " << preprocess.size() << "\r\n"
- << "Content-Type: " << mimeType << "\r\n"
- << "\r\n"
+ << "Content-Type: " << mimeType << "\r\n";
+
+ if (!wopiDomain.empty())
+ oss << "Content-Security-Policy: frame-ancestors " << wopiDomain << "\r\n";
+
+ oss << "\r\n"
<< preprocess;
socket->send(oss.str());
commit 54d0ff9c21b60dbff9cf875ab43c4f415c73459c
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Apr 7 00:49:31 2017 +0530
Stop using inline event handlers wherever possible
Unfortunately, our dependencies (various plugins etc.) still make heavy
use of inline event handlers, so not possible get rid of all of them in
our bundled js. This is the reason we still have to use 'unsafe-inline'
in our CSP.
Change-Id: I519dec0834606ab3c56e090c882a93160ddcb52c
diff --git a/loleaflet/dist/loleaflet.html b/loleaflet/dist/loleaflet.html
index cb0f73c5..05a49e07 100644
--- a/loleaflet/dist/loleaflet.html
+++ b/loleaflet/dist/loleaflet.html
@@ -57,7 +57,7 @@
<div id="formulabar"></div>
<div id="toolbar-up-more"></div>
</div>
- <input id="insertgraphic" type="file" onchange="onInsertFile()" style="position: fixed; top: -100em">
+ <input id="insertgraphic" type="file" style="position: fixed; top: -100em">
</div>
<div id="spreadsheet-row-column-frame">
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index bd8001e5..e986a78e 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -632,11 +632,15 @@ $(function () {
{type: 'button', id: 'function', img: 'equal', hint: _('Function')},
{type: 'button', hidden: true, id: 'cancelformula', img: 'cancel', hint: _('Cancel')},
{type: 'button', hidden: true, id: 'acceptformula', img: 'accepttrackedchanges', hint: _('Accept')},
- {type: 'html', id: 'formula', html: '<input id="formulaInput" onkeyup="onFormulaInput(event)"' +
- 'onblur="onFormulaBarBlur()" onfocus="onFormulaBarFocus()" type=text>'}
+ {type: 'html', id: 'formula', html: '<input id="formulaInput" type="text">'}
],
onClick: function (e) {
onClick(e.target);
+ },
+ onRefresh: function(e) {
+ $('#formulaInput').off('keyup', onFormulaInput).on('keyup', onFormulaInput);
+ $('#formulaInput').off('blur', onFormulaBarBlur).on('blur', onFormulaBarBlur);
+ $('#formulaInput').off('focus', onFormulaBarFocus).on('focus', onFormulaBarFocus);
}
});
$('#spreadsheet-toolbar').w2toolbar({
@@ -673,7 +677,7 @@ $(function () {
{type: 'html', id: 'search',
html: '<div style="padding: 3px 10px;" class="loleaflet-font">' +
' ' + _('Search:') +
- ' <input size="10" id="search-input" oninput="onSearch(event)" onkeypress="onSearchKeyPress(event)" ' +
+ ' <input size="10" id="search-input"' +
'style="padding: 3px; border-radius: 2px; border: 1px solid silver"/>' +
'</div>'
},
@@ -702,6 +706,8 @@ $(function () {
},
onRefresh: function(e) {
$('#tb_toolbar-down_item_userlist .w2ui-tb-caption').addClass('loleaflet-font');
+ $('#search-input').off('input', onSearch).on('input', onSearch);
+ $('#search-input').off('keypress', onSearchKeyPress).on('keypress', onSearchKeyPress);
}
});
});
@@ -1632,4 +1638,7 @@ $(document).ready(function() {
if (closebutton) {
toolbar.show('close');
}
+
+ // Attach insert file action
+ $('#insertgraphic').on('change', onInsertFile);
});
commit 0f2c6d8e068bb017fd63d34dacb500f7a2df62f0
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Apr 7 00:38:02 2017 +0530
Bin unused function
Change-Id: I57bc98cd382081e776e1ed58da095a404834b431
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index 29babff0..bd8001e5 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -774,12 +774,6 @@ function onSearchKeyPress(e) {
}
}
-function onSaveAs(e) {
- if (e !== false) {
- map.saveAs(e.url, e.format, e.options);
- }
-}
-
function sortFontSizes() {
var oldVal = $('.fontsizes-select').val();
var selectList = $('.fontsizes-select option');
commit 328df11a689684be0e13b1778b67d5a7648e9989
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Apr 6 23:52:32 2017 +0530
Bin this unused inline style
Change-Id: Ib4ae0cde13acea0e04526cda925f3d4528bb6605
diff --git a/loleaflet/dist/loleaflet.html b/loleaflet/dist/loleaflet.html
index 0772bee1..cb0f73c5 100644
--- a/loleaflet/dist/loleaflet.html
+++ b/loleaflet/dist/loleaflet.html
@@ -30,7 +30,6 @@
<link rel="localizations" href="/loleaflet/%VERSION%/l10n/styles-localizations.json" type="application/vnd.oftn.l10n+json" />
<link rel="localizations" href="/loleaflet/%VERSION%/l10n/uno-localizations.json" type="application/vnd.oftn.l10n+json" />
<link rel="localizations" href="/loleaflet/%VERSION%/l10n/help-localizations.json" type="application/vnd.oftn.l10n+json"/>
-<style type="text/css"></style></head>
<body>
<!--The "controls" div holds map controls such as the Zoom button and
it's separated from the map in order to have the controls on the top
commit 03341192ca728e30da9af13d8b9e700dcdc00bb8
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Apr 6 23:49:56 2017 +0530
loleaflet: Add Content Security Policy
Change-Id: I450e0c9fb24d114af35ba9c503d3940ab30a4f4e
diff --git a/loleaflet/dist/loleaflet.html b/loleaflet/dist/loleaflet.html
index d8de0bb3..0772bee1 100644
--- a/loleaflet/dist/loleaflet.html
+++ b/loleaflet/dist/loleaflet.html
@@ -3,7 +3,13 @@
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Online Editor</title>
<meta charset="utf-8">
-
+<meta http-equiv="Content-Security-Policy" content="default-src 'none';
+ frame-src blob:;
+ connect-src 'self' %HOST%;
+ script-src 'self' 'unsafe-inline';
+ style-src 'self' 'unsafe-inline';
+ font-src 'self' data:;
+ img-src 'self' data:;">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
More information about the Libreoffice-commits
mailing list