[Libreoffice-commits] online.git: loleaflet/js wsd/FileServer.cpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Tue Apr 28 17:34:33 UTC 2020
loleaflet/js/global.js | 2 -
wsd/FileServer.cpp | 89 +++++++++++++++++++++++++++++--------------------
2 files changed, 55 insertions(+), 36 deletions(-)
New commits:
commit d439f8098d2fbec7ace4fa6a66f7c9c00d77edfe
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Tue Apr 28 18:05:25 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Tue Apr 28 19:34:15 2020 +0200
Proxy: improving parsing & URL passing for websocket to fix connect-src.
Change-Id: Id017c46e755eb14bc25d18be450b6100ff6bed92
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/93094
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/loleaflet/js/global.js b/loleaflet/js/global.js
index c3c8343ad..c2935ab96 100644
--- a/loleaflet/js/global.js
+++ b/loleaflet/js/global.js
@@ -344,7 +344,7 @@
};
this.getEndPoint = function(type) {
var base = this.uri;
- return base.replace(/^ws/, 'http') + '/' + type + '/' + this.outSerial;
+ return base + '/' + type + '/' + this.outSerial;
};
console.debug('proxy: new socket ' + this.id + ' ' + this.uri);
diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp
index 99ac332b3..888509591 100644
--- a/wsd/FileServer.cpp
+++ b/wsd/FileServer.cpp
@@ -641,44 +641,62 @@ constexpr char BRANDING_UNSUPPORTED[] = "branding-unsupported";
#endif
namespace {
- // The user can override the ServerRoot with a new prefix.
- std::string getResponseRoot(const HTTPRequest &request)
- {
- if (!request.has("ProxyPrefix"))
- return LOOLWSD::ServiceRoot;
- std::string proxyPrefix = request.get("ProxyPrefix", "");
-
- // skip url to the root path.
- size_t pos = proxyPrefix.find("://");
- if (pos != std::string::npos) {
- pos = proxyPrefix.find("/", pos + 3);
- if (pos != std::string::npos)
- proxyPrefix = proxyPrefix.substr(pos);
- else
- LOG_DBG("Unusual proxy prefix '" << proxyPrefix << "'");
- } else
- LOG_DBG("No http[s]:// in unusual proxy prefix '" << proxyPrefix);
- return proxyPrefix;
- }
+ /// Very simple splitting of proxy URLs without fear of escaping or validation.
+ class ProxyURL {
+ std::string _schemeAuthority;
+ std::string _pathPlus;
+ public:
+ ProxyURL(const HTTPRequest &request)
+ {
+ // The user can override the ServerRoot with a new prefix.
+ if (_pathPlus.size() <= 0)
+ _pathPlus = LOOLWSD::ServiceRoot;
- std::string getWebSocketUrl(const HTTPRequest &request)
- {
- bool ssl = (LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination());
- std::string proxyPrefix = request.get("ProxyPrefix", "");
- std::string serverName = LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName;
- if (proxyPrefix.size() > 0)
+ if (_schemeAuthority.size() <= 0)
+ {
+ bool ssl = (LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination());
+ std::string serverName = LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName;
+ _schemeAuthority = (ssl ? "wss://" : "ws://") + serverName;
+ }
+
+ // A well formed ProxyPrefix will override it.
+ std::string url = request.get("ProxyPrefix", "");
+ if (url.size() <= 0)
+ return;
+
+ size_t pos = url.find("://");
+ if (pos != std::string::npos) {
+ pos = url.find("/", pos + 3);
+ if (pos != std::string::npos)
+ {
+ _schemeAuthority = url.substr(0, pos);
+ _pathPlus = url.substr(pos);
+ return;
+ }
+ else
+ LOG_ERR("Unusual proxy prefix '" << url << "'");
+ } else
+ LOG_ERR("No http[s]:// in unusual proxy prefix '" << url << "'");
+
+ }
+
+ std::string getResponseRoot() const
{
- ssl = !strcmp(proxyPrefix.c_str(), "https://");
- serverName = request.getHost();
+ return _pathPlus;
}
- return (ssl ? "wss://" : "ws://") + serverName;
- }
+
+ std::string getWebSocketUrl() const
+ {
+ return _schemeAuthority;
+ }
+ };
}
void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message,
const std::shared_ptr<StreamSocket>& socket)
{
- const auto host = getWebSocketUrl(request);
+ ProxyURL cnxDetails(request);
+
const Poco::URI::QueryParameters params = Poco::URI(request.getURI()).getQueryParameters();
// Is this a file we read at startup - if not; its not for serving.
@@ -725,12 +743,12 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
socketProxy = "true";
Poco::replaceInPlace(preprocess, std::string("%SOCKET_PROXY%"), socketProxy);
- std::string responseRoot = getResponseRoot(request);
+ std::string responseRoot = cnxDetails.getResponseRoot();
Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN%"), escapedAccessToken);
Poco::replaceInPlace(preprocess, std::string("%ACCESS_TOKEN_TTL%"), std::to_string(tokenTtl));
Poco::replaceInPlace(preprocess, std::string("%ACCESS_HEADER%"), escapedAccessHeader);
- Poco::replaceInPlace(preprocess, std::string("%HOST%"), host);
+ Poco::replaceInPlace(preprocess, std::string("%HOST%"), cnxDetails.getWebSocketUrl());
Poco::replaceInPlace(preprocess, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH));
Poco::replaceInPlace(preprocess, std::string("%SERVICE_ROOT%"), responseRoot);
@@ -807,7 +825,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
std::ostringstream cspOss;
cspOss << "Content-Security-Policy: default-src 'none'; "
"frame-src 'self' blob: " << documentSigningURL << "; "
- "connect-src 'self' " << host << "; "
+ "connect-src 'self' " << cnxDetails.getWebSocketUrl() << "; "
"script-src 'unsafe-inline' 'self'; "
"style-src 'self' 'unsafe-inline'; "
"font-src 'self' data:; "
@@ -816,7 +834,7 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::
// Frame ancestors: Allow loolwsd host, wopi host and anything configured.
std::string configFrameAncestor = config.getString("net.frame_ancestors", "");
std::string frameAncestors = configFrameAncestor;
- Poco::URI uriHost(host);
+ Poco::URI uriHost(cnxDetails.getWebSocketUrl());
if (uriHost.getHost() != configFrameAncestor)
frameAncestors += " " + uriHost.getHost() + ":*";
@@ -945,7 +963,8 @@ void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,co
if (!FileServerRequestHandler::isAdminLoggedIn(request, response))
throw Poco::Net::NotAuthenticatedException("Invalid admin login");
- std::string responseRoot = getResponseRoot(request);
+ ProxyURL cnxDetails(request);
+ std::string responseRoot = cnxDetails.getResponseRoot();
static const std::string scriptJS("<script src=\"%s/loleaflet/" LOOLWSD_VERSION_HASH "/%s.js\"></script>");
static const std::string footerPage("<div class=\"footer navbar-fixed-bottom text-info text-center\"><strong>Key:</strong> %s <strong>Expiry Date:</strong> %s</div>");
More information about the Libreoffice-commits
mailing list