common/Crypto.cpp | 10 ++++ common/Crypto.hpp | 7 ++ loleaflet/admin/admin.html | 3 - loleaflet/admin/adminAnalytics.html | 3 - loleaflet/admin/adminHistory.html | 4 - loleaflet/admin/adminSettings.html | 3 - loleaflet/loleaflet.html.m4 | 4 - wsd/FileServer.cpp | 86 ++++++++++++++++++++++++++++++++++-- wsd/FileServer.hpp | 2 9 files changed, 111 insertions(+), 11 deletions(-)
New commits: commit 6ff069db62dc38fa9f37d84789266ac4fdf02ba2 Author: Henry Castro <hcas...@collabora.com> Date: Wed Apr 25 15:53:38 2018 -0400 respond different logo brands when it has support Change-Id: Icddc8b67a20fd829c90c3c5d8eb6942da9c5e74d Reviewed-on: https://gerrit.libreoffice.org/53583 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/common/Crypto.cpp b/common/Crypto.cpp index 46ba05c0f..7c1d00052 100644 --- a/common/Crypto.cpp +++ b/common/Crypto.cpp @@ -127,6 +127,16 @@ int SupportKey::validDaysRemaining() return days; } +DateTime SupportKey::expiry() const +{ + return _impl->_expiry; +} + +std::string SupportKey::data() const +{ + return _impl->_data; +} + #endif // ENABLE_SUPPORT_KEY /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/common/Crypto.hpp b/common/Crypto.hpp index 94b194cc2..079a4f742 100644 --- a/common/Crypto.hpp +++ b/common/Crypto.hpp @@ -15,6 +15,9 @@ #include <memory> struct SupportKeyImpl; +namespace Poco { + class DateTime; +} class SupportKey { std::unique_ptr<SupportKeyImpl> _impl; @@ -28,6 +31,10 @@ public: /// How many days until key expires int validDaysRemaining(); + + Poco::DateTime expiry() const; + + std::string data() const; }; #endif diff --git a/loleaflet/admin/admin.html b/loleaflet/admin/admin.html index 0439ac16f..f23d510ca 100644 --- a/loleaflet/admin/admin.html +++ b/loleaflet/admin/admin.html @@ -19,7 +19,7 @@ </head> <body> <script src="/loleaflet/dist/admin-bundle.js"></script> - <script src="/loleaflet/dist/branding.js"></script> + <!--%BRANDING_JS%--> <script>if (typeof brandProductName !== 'undefined') {l10nstrings.strProductName = brandProductName}</script> <script>document.title = l10nstrings.strProductName + ' - ' + l10nstrings.strAdminConsole</script> <script> @@ -141,5 +141,6 @@ <li><a tabindex="-1" href="#"><script>document.write(l10nstrings.strKill)</script></a></li> </ul> </div> +<!--%FOOTER%--> </body> </html> diff --git a/loleaflet/admin/adminAnalytics.html b/loleaflet/admin/adminAnalytics.html index 722629435..1e801fcb1 100644 --- a/loleaflet/admin/adminAnalytics.html +++ b/loleaflet/admin/adminAnalytics.html @@ -19,7 +19,7 @@ </head> <body> <script src="/loleaflet/dist/admin-bundle.js"></script> - <script src="/loleaflet/dist/branding.js"></script> + <!--%BRANDING_JS%--> <script>if (typeof brandProductName !== 'undefined') {l10nstrings.strProductName = brandProductName}</script> <script>document.title = l10nstrings.strProductName + ' - ' + l10nstrings.strAdminConsole</script> <script> @@ -105,5 +105,6 @@ </div> </div> </div> +<!--%FOOTER%--> </body> </html> diff --git a/loleaflet/admin/adminHistory.html b/loleaflet/admin/adminHistory.html index 17184045a..7245a3d04 100644 --- a/loleaflet/admin/adminHistory.html +++ b/loleaflet/admin/adminHistory.html @@ -20,7 +20,7 @@ </head> <body> <script src="/loleaflet/dist/admin-bundle.js"></script> - <script src="/loleaflet/dist/branding.js"></script> + <!--%BRANDING_JS%--> <script>if (typeof brandProductName !== 'undefined') {l10nstrings.strProductName = brandProductName}</script> <script>document.title = l10nstrings.strProductName + ' - ' + l10nstrings.strAdminConsole</script> <script> @@ -71,7 +71,7 @@ </div> </div> </div> - +<!--%FOOTER%--> <!-- Bootstrap core JavaScript ================================================== --> diff --git a/loleaflet/admin/adminSettings.html b/loleaflet/admin/adminSettings.html index 9238354f5..c7b21879d 100644 --- a/loleaflet/admin/adminSettings.html +++ b/loleaflet/admin/adminSettings.html @@ -19,7 +19,7 @@ </head> <body> <script src="/loleaflet/dist/admin-bundle.js"></script> - <script src="/loleaflet/dist/branding.js"></script> + <!--%BRANDING_JS%--> <script>if (typeof brandProductName !== 'undefined') {l10nstrings.strProductName = brandProductName}</script> <script>document.title = l10nstrings.strProductName + ' - ' + l10nstrings.strAdminConsole</script> <script> @@ -97,5 +97,6 @@ </div> </div> </div> + <!--%FOOTER%--> </body> </html> diff --git a/loleaflet/loleaflet.html.m4 b/loleaflet/loleaflet.html.m4 index ed7286615..87bcf697e 100644 --- a/loleaflet/loleaflet.html.m4 +++ b/loleaflet/loleaflet.html.m4 @@ -26,7 +26,7 @@ define([_foreachq],[ifelse([$#],[3],[],[define([$1],[$4])$2[]$0([$1],[$2],shift( ifelse(DEBUG,[true],foreachq([fileCSS],[LOLEAFLET_CSS],[<link rel="stylesheet" href="/loleaflet/%VERSION%/fileCSS" /> ]),[<link rel="stylesheet" href="/loleaflet/%VERSION%/bundle.css" /> ])dnl -<link rel="stylesheet" href="/loleaflet/%VERSION%/branding.css"> <!-- add your logo here --> +<!--%BRANDING_CSS%--> <!-- add your logo here --> <link rel="localizations" href="/loleaflet/%VERSION%/l10n/localizations.json" type="application/vnd.oftn.l10n+json"/> <link rel="localizations" href="/loleaflet/%VERSION%/l10n/locore-localizations.json" type="application/vnd.oftn.l10n+json" /> <link rel="localizations" href="/loleaflet/%VERSION%/l10n/help-localizations.json" type="application/vnd.oftn.l10n+json"/> @@ -114,5 +114,5 @@ ifelse(DEBUG,[true],foreachq([fileJS],[LOLEAFLET_JS], ]), [ <script src="/loleaflet/%VERSION%/bundle.js"></script> ])dnl - <script src="/loleaflet/%VERSION%/branding.js"></script> <!-- logo onclick handler --> + <!--%BRANDING_JS%--> <!-- logo onclick handler --> </body></html> diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index ab95c6a45..17531623f 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -41,11 +41,15 @@ #include "Auth.hpp" #include <Common.hpp> +#include <Crypto.hpp> #include "FileServer.hpp" #include "LOOLWSD.hpp" #include <Log.hpp> #include <Protocol.hpp> +#define BRAND_SUPPORTED "branding" +#define BRAND_UNSUPPORTED "branding-CODE" + using Poco::Net::HTMLForm; using Poco::Net::HTTPBasicCredentials; using Poco::Net::HTTPRequest; @@ -299,11 +303,17 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M if (request.getMethod() == HTTPRequest::HTTP_GET) { if (endPoint == "admin.html" || - endPoint == "admin-bundle.js" || - endPoint == "admin-localizations.js" || endPoint == "adminSettings.html" || + endPoint == "adminHistory.html" || endPoint == "adminAnalytics.html") { + preprocessAdminFile(request, socket); + return; + } + + if (endPoint == "admin-bundle.js" || + endPoint == "admin-localizations.js") + { noCache = true; if (!LOOLWSD::AdminEnabled) @@ -557,6 +567,8 @@ std::string FileServerRequestHandler::getRequestPathname(const HTTPRequest& requ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco::MemoryInputStream& message, const std::shared_ptr<StreamSocket>& socket) { + static const std::string linkCSS = "<link rel=\"stylesheet\" href=\"/loleaflet/" LOOLWSD_VERSION_HASH "/%s.css\">"; + static const std::string scriptJS = "<script src=\"/loleaflet/" LOOLWSD_VERSION_HASH "/%s.js\"></script>"; const auto host = ((LOOLWSD::isSSLEnabled() || LOOLWSD::isSSLTermination()) ? "wss://" : "ws://") + (LOOLWSD::ServerName.empty() ? request.getHost() : LOOLWSD::ServerName); const Poco::URI::QueryParameters params = Poco::URI(request.getURI()).getQueryParameters(); @@ -605,8 +617,27 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: Poco::replaceInPlace(preprocess, std::string("%HOST%"), host); Poco::replaceInPlace(preprocess, std::string("%VERSION%"), std::string(LOOLWSD_VERSION_HASH)); + std::string brandCSS(Poco::format(linkCSS, std::string(BRAND_UNSUPPORTED))); + std::string brandJS(Poco::format(scriptJS, std::string(BRAND_UNSUPPORTED))); + const auto& config = Application::instance().config(); - const std::string loleafletLogging = config.getString("loleaflet_logging", "false"); +#if ENABLE_SUPPORT_KEY + const std::string keyString = config.getString("support_key", ""); + SupportKey key(keyString); + if (key.verify() && key.validDaysRemaining() > 0) + { + brandCSS = Poco::format(linkCSS, std::string(BRAND_SUPPORTED)); + brandJS = Poco::format(scriptJS, std::string(BRAND_SUPPORTED)); + } +#elif ENABLE_DEBUG + brandCSS = ""; + brandJS = ""; +#endif + + Poco::replaceInPlace(preprocess, std::string("<!--%BRANDING_CSS%-->"), brandCSS); + Poco::replaceInPlace(preprocess, std::string("<!--%BRANDING_JS%-->"), brandJS); + + const auto loleafletLogging = config.getString("loleaflet_logging", "false"); Poco::replaceInPlace(preprocess, std::string("%LOLEAFLET_LOGGING%"), loleafletLogging); const std::string outOfFocusTimeoutSecs= config.getString("per_view.out_of_focus_timeout_secs", "60"); Poco::replaceInPlace(preprocess, std::string("%OUT_OF_FOCUS_TIMEOUT_SECS%"), outOfFocusTimeoutSecs); @@ -749,4 +780,53 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: LOG_DBG("Sent file: " << relPath << ": " << preprocess); } +void FileServerRequestHandler::preprocessAdminFile(const HTTPRequest& request,const std::shared_ptr<StreamSocket>& socket) +{ + Poco::Net::HTTPResponse response; + static const std::string scriptJS("<script src=\"/loleaflet/dist/%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>"); + + if (!FileServerRequestHandler::isAdminLoggedIn(request, response)) + throw Poco::Net::NotAuthenticatedException("Invalid admin login"); + + const std::string relPath = getRequestPathname(request); + LOG_DBG("Preprocessing file: " << relPath); + std::string adminFile = *getUncompressedFile(relPath); + std::string brandJS(Poco::format(scriptJS, std::string(BRAND_UNSUPPORTED))); + std::string brandFooter; + +#if ENABLE_SUPPORT_KEY + const auto& config = Application::instance().config(); + const std::string keyString = config.getString("support_key", ""); + SupportKey key(keyString); + + if (key.verify() && key.validDaysRemaining() > 0) + { + brandJS = Poco::format(scriptJS, std::string(BRAND_SUPPORTED)); + brandFooter = Poco::format(footerPage, key.data(), Poco::DateTimeFormatter::format(key.expiry(), Poco::DateTimeFormat::RFC822_FORMAT)); + } +#elif ENABLE_DEBUG + brandJS = ""; +#endif + + Poco::replaceInPlace(adminFile, std::string("<!--%BRANDING_JS%-->"), brandJS); + Poco::replaceInPlace(adminFile, std::string("<!--%FOOTER%-->"), brandFooter); + + // Ask UAs to block if they detect any XSS attempt + response.add("X-XSS-Protection", "1; mode=block"); + // No referrer-policy + response.add("Referrer-Policy", "no-referrer"); + response.add("X-Content-Type-Options", "nosniff"); + response.set("User-Agent", HTTP_AGENT_STRING); + response.set("Date", Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT)); + + response.setContentType("text/html"); + response.setChunkedTransferEncoding(false); + + std::ostringstream oss; + response.write(oss); + oss << adminFile; + socket->send(oss.str()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/FileServer.hpp b/wsd/FileServer.hpp index c3ff59b7b..8bcc662c7 100644 --- a/wsd/FileServer.hpp +++ b/wsd/FileServer.hpp @@ -21,7 +21,7 @@ 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 preprocessAdminFile(const Poco::Net::HTTPRequest& request, 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); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits