[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-3' - 13 commits - kit/ChildSession.cpp loleaflet/dist loleaflet/src loolwsd.xml.in net/ServerSocket.hpp net/Socket.hpp wsd/DocumentBroker.cpp wsd/LOOLWSD.cpp wsd/protocol.txt wsd/Storage.cpp wsd/Storage.hpp
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Tue Sep 11 18:36:42 UTC 2018
kit/ChildSession.cpp | 13 ++++++--
loleaflet/dist/toolbar/toolbar.js | 14 ++++++++
loleaflet/src/control/Control.Menubar.js | 12 +++++++
loleaflet/src/control/Toolbar.js | 4 ++
loleaflet/src/map/handler/Map.FileInserter.js | 29 +++++++++++++++++
loleaflet/src/map/handler/Map.WOPI.js | 9 +++++
loolwsd.xml.in | 7 ++++
net/ServerSocket.hpp | 31 +++++++++++++++++--
net/Socket.hpp | 6 +++
wsd/DocumentBroker.cpp | 2 +
wsd/LOOLWSD.cpp | 42 ++++++++++++++++++++++++++
wsd/Storage.cpp | 6 +++
wsd/Storage.hpp | 8 ++++
wsd/protocol.txt | 8 ++++
14 files changed, 181 insertions(+), 10 deletions(-)
New commits:
commit 6d50bdf9f7d910e60800e33d8402bbba7857ace2
Author: Henry Castro <hcastro at collabora.com>
AuthorDate: Sat Aug 18 20:37:51 2018 -0400
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
loleaflet: wopi: add EnableShare
Change-Id: I1a2a86e671f97891855cc2bd8d8047829e819508
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index e10501ae9..5fe17ada1 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -17,6 +17,7 @@ L.Control.Menubar = L.Control.extend({
{name: _UNO('.uno:PickList', 'text'), id: 'file', type: 'menu', menu: [
{name: _UNO('.uno:Save', 'text'), id: 'save', type: 'action'},
{name: _UNO('.uno:SaveAs', 'text'), id: 'saveas', type: 'action'},
+ {name: _('Share...'), id:'shareas', type: 'action'},
{name: _UNO('.uno:Print', 'text'), id: 'print', type: 'action'},
{name: _('See revision history'), id: 'rev-history', type: 'action'},
{name: _('Download as'), id: 'downloadas', type: 'menu', menu: [
@@ -666,6 +667,8 @@ L.Control.Menubar = L.Control.extend({
map.save(true, true);
} else if (id === 'saveas') {
map.fire('postMessage', {msgId: 'UI_SaveAs'});
+ } else if (id === 'shareas') {
+ map.fire('postMessage', {msgId: 'UI_Share'});
} else if (id === 'print') {
map.print();
} else if (id.startsWith('downloadas-')) {
@@ -805,6 +808,9 @@ L.Control.Menubar = L.Control.extend({
if (menu[i].id === 'saveas' && this._map['wopi'].UserCanNotWriteRelative)
continue;
+ if (menu[i].id === 'shareas' && !this._map['wopi'].EnableShare)
+ continue;
+
if (menu[i].id === 'insertgraphicremote' && !this._map['wopi'].EnableInsertRemoteImage)
continue;
diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js
index cd31fce22..d291ae71f 100644
--- a/loleaflet/src/map/handler/Map.WOPI.js
+++ b/loleaflet/src/map/handler/Map.WOPI.js
@@ -20,6 +20,7 @@ L.Map.WOPI = L.Handler.extend({
DisableInactiveMessages: false,
UserCanNotWriteRelative: true,
EnableInsertRemoteImage: false,
+ EnableShare: false,
CallPythonScriptSource: null,
_appLoadedConditions: {
@@ -76,6 +77,7 @@ L.Map.WOPI = L.Handler.extend({
this.DisableInactiveMessages = !!wopiInfo['DisableInactiveMessages'];
this.UserCanNotWriteRelative = !!wopiInfo['UserCanNotWriteRelative'];
this.EnableInsertRemoteImage = !!wopiInfo['EnableInsertRemoteImage'];
+ this.EnableShare = !!wopiInfo['EnableShare'];
this._map.fire('postMessage', {
msgId: 'App_LoadingStatus',
commit 113071182ea85f9df001b9c59d57f9d79036d366
Author: Henry Castro <hcastro at collabora.com>
AuthorDate: Sat Aug 18 20:17:25 2018 -0400
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
wsd: wopi: introduce a "EnableShare" entry in the CheckFileInfo
Change-Id: Ia47d7e8f5c8cd8ae1eb314467c664b27b50e7fd3
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 67c73c112..e01af9069 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -510,6 +510,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
wopiInfo->set("DisableInactiveMessages", wopifileinfo->_disableInactiveMessages);
wopiInfo->set("UserCanNotWriteRelative", wopifileinfo->_userCanNotWriteRelative);
wopiInfo->set("EnableInsertRemoteImage", wopifileinfo->_enableInsertRemoteImage);
+ wopiInfo->set("EnableShare", wopifileinfo->_enableShare);
if (wopifileinfo->_hideChangeTrackingControls != WopiStorage::WOPIFileInfo::TriState::Unset)
wopiInfo->set("HideChangeTrackingControls", wopifileinfo->_hideChangeTrackingControls == WopiStorage::WOPIFileInfo::TriState::True);
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index acfc18408..3e2e23ad6 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -464,6 +464,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
std::string lastModifiedTime;
bool userCanNotWriteRelative = true;
bool enableInsertRemoteImage = false;
+ bool enableShare = false;
WOPIFileInfo::TriState disableChangeTrackingRecord = WOPIFileInfo::TriState::Unset;
WOPIFileInfo::TriState disableChangeTrackingShow = WOPIFileInfo::TriState::Unset;
WOPIFileInfo::TriState hideChangeTrackingControls = WOPIFileInfo::TriState::Unset;
@@ -543,6 +544,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
JsonUtil::findJSONValue(object, "LastModifiedTime", lastModifiedTime);
JsonUtil::findJSONValue(object, "UserCanNotWriteRelative", userCanNotWriteRelative);
JsonUtil::findJSONValue(object, "EnableInsertRemoteImage", enableInsertRemoteImage);
+ JsonUtil::findJSONValue(object, "EnableShare", enableShare);
bool booleanFlag = false;
if (JsonUtil::findJSONValue(object, "DisableChangeTrackingRecord", booleanFlag))
disableChangeTrackingRecord = (booleanFlag ? WOPIFileInfo::TriState::True : WOPIFileInfo::TriState::False);
@@ -570,7 +572,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
{userId, obfuscatedUserId, userName, userExtraInfo, watermarkText, canWrite,
postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption,
enableOwnerTermination, disablePrint, disableExport, disableCopy,
- disableInactiveMessages, userCanNotWriteRelative, enableInsertRemoteImage,
+ disableInactiveMessages, userCanNotWriteRelative, enableInsertRemoteImage, enableShare,
disableChangeTrackingShow, disableChangeTrackingRecord,
hideChangeTrackingControls, callDuration}));
}
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index f1361996e..f061f818b 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -285,6 +285,7 @@ public:
const bool disableInactiveMessages,
const bool userCanNotWriteRelative,
const bool enableInsertRemoteImage,
+ const bool enableShare,
const TriState disableChangeTrackingShow,
const TriState disableChangeTrackingRecord,
const TriState hideChangeTrackingControls,
@@ -305,6 +306,7 @@ public:
_disableInactiveMessages(disableInactiveMessages),
_userCanNotWriteRelative(userCanNotWriteRelative),
_enableInsertRemoteImage(enableInsertRemoteImage),
+ _enableShare(enableShare),
_disableChangeTrackingShow(disableChangeTrackingShow),
_disableChangeTrackingRecord(disableChangeTrackingRecord),
_hideChangeTrackingControls(hideChangeTrackingControls),
@@ -347,6 +349,8 @@ public:
bool _userCanNotWriteRelative;
/// if set to true, users can access the insert remote image functionality
bool _enableInsertRemoteImage;
+ /// if set to true, users can access the file share functionality
+ bool _enableShare;
/// If we should disable change-tracking visibility by default (meaningful at loading).
TriState _disableChangeTrackingShow;
/// If we should disable change-tracking ability by default (meaningful at loading).
commit 2fb4b0fb5a7add2d200ce72ae64504c6c3b49a67
Author: Tor Lillqvist <tml at collabora.com>
AuthorDate: Wed Jul 18 17:54:45 2018 +0300
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
Allow also the IPv6 loopback address ::1
Change-Id: I4e079095d0a599f36b1d48d7a1311db75e3d79bf
diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index de50d0b02..587452ba4 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -74,6 +74,7 @@
<host desc="Ditto, but as IPv4-mapped IPv6 addresses">::ffff:192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
<host desc="The IPv4 loopback (localhost) address.">127\.0\.0\.1</host>
<host desc="Ditto, but as IPv4-mapped IPv6 address">::ffff:127\.0\.0\.1</host>
+ <host desc="The IPv6 loopback (localhost) address.">::1</host>
</post_allow>
</net>
commit 5a47102d75f7c2247fc8aca9b2c4c6f4d4967bd1
Author: Tor Lillqvist <tml at collabora.com>
AuthorDate: Thu Jul 12 18:31:36 2018 +0300
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
Accept also localhost and IPv4-mapped IPv6 addresses
Change-Id: Ifc295d164276c0dd17592ff27066a522482fe04a
Reviewed-on: https://gerrit.libreoffice.org/57351
Reviewed-by: Tor Lillqvist <tml at collabora.com>
Tested-by: Tor Lillqvist <tml at collabora.com>
diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index b11966d7d..de50d0b02 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -70,7 +70,10 @@
<proto type="string" default="all" desc="Protocol to use IPv4, IPv6 or all for both">all</proto>
<service_root type="path" default="" desc="Prefix all the pages, websockets, etc. with this path."></service_root>
<post_allow desc="Allow/deny client IP address for POST(REST)." allow="true">
- <host desc="Regex pattern of ip address to allow.">192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
+ <host desc="The IPv4 private 192.168 block as plain IPv4 dotted decimal addresses.">192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
+ <host desc="Ditto, but as IPv4-mapped IPv6 addresses">::ffff:192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
+ <host desc="The IPv4 loopback (localhost) address.">127\.0\.0\.1</host>
+ <host desc="Ditto, but as IPv4-mapped IPv6 address">::ffff:127\.0\.0\.1</host>
</post_allow>
</net>
commit 3e3295c00cd587f42f521b104b4c25cb814e8285
Author: Tor Lillqvist <tml at collabora.com>
AuthorDate: Tue Jul 10 22:50:11 2018 +0300
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
Fis our use of inet_ntop() etc
We had:
auto ipv4 = (struct sockaddr_in *)&clientInfo.sin_addr
even if the clientInfo variable itself was a struct sockaddr_in.
And then we also had:
auto ipv6 = (struct sockaddr_in6 *)&clientInfo.sin_addr
which makes even less sense.
Instead, make clientInfo into a struct sockaddr_in6, which is big
enough to also to be interpreted as a sockaddr_in. Pass the address of
the correct field, either sin_addr or sin6_addr, to inet_ntop(). (Note
that sin_addr in sockaddr_in has a different offset than sin6_addr in
sockaddr_in6.)
At least on my Fedora 28, when I connect using IPv4, accept4() still
returns the client address as an IPv4 mapped IPv6 address, that is
::ffff:192.168.1.113 for 192.168.1.113. So the sample
net.post_allow.host value in loolwsd.xml.in should probably be changed
to have that ::ffff: prefix, too.
Change-Id: I0ad774616b210d94b904982e2f7dc928adc879ed
diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index afd4b97f4..f0ad38ad3 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -61,8 +61,8 @@ public:
{
// Accept a connection (if any) and set it to non-blocking.
// There still need the client's address to filter request from POST(call from REST) here.
- struct sockaddr_in clientInfo;
- socklen_t addrlen = sizeof(struct sockaddr_in);
+ struct sockaddr_in6 clientInfo;
+ socklen_t addrlen = sizeof(clientInfo);
const int rc = ::accept4(getFD(), (struct sockaddr *)&clientInfo, &addrlen, SOCK_NONBLOCK);
LOG_DBG("Accepted socket #" << rc << ", creating socket object.");
try
@@ -73,21 +73,21 @@ public:
char addrstr[INET6_ADDRSTRLEN];
const void *inAddr;
- if (clientInfo.sin_family == AF_INET)
+ if (clientInfo.sin6_family == AF_INET)
{
- auto ipv4 = (struct sockaddr_in *)&clientInfo.sin_addr;
+ auto ipv4 = (struct sockaddr_in *)&clientInfo;
inAddr = &(ipv4->sin_addr);
}
else
{
- auto ipv6 = (struct sockaddr_in6 *)&clientInfo.sin_addr;
+ auto ipv6 = (struct sockaddr_in6 *)&clientInfo;
inAddr = &(ipv6->sin6_addr);
}
- inet_ntop(clientInfo.sin_family, inAddr, addrstr, sizeof(addrstr));
+ inet_ntop(clientInfo.sin6_family, inAddr, addrstr, sizeof(addrstr));
std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
_socket->_clientAddress = addrstr;
- LOG_DBG("Accepted socket has family " << clientInfo.sin_family <<
+ LOG_DBG("Accepted socket has family " << clientInfo.sin6_family <<
" address " << _socket->_clientAddress);
return _socket;
}
commit 57d7bdfcf8cbb4699638e7d7852c3e6858b7586f
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sun May 13 12:32:05 2018 +0100
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
Use inet_ntop for ipv6 address names.
Change-Id: Ic52b69eb2dc86b6532a78d770531b2fac928fb28
diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index abc018678..afd4b97f4 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -70,9 +70,25 @@ public:
// Create a socket object using the factory.
if (rc != -1)
{
- std::string ip = inet_ntoa(clientInfo.sin_addr);
+ char addrstr[INET6_ADDRSTRLEN];
+
+ const void *inAddr;
+ if (clientInfo.sin_family == AF_INET)
+ {
+ auto ipv4 = (struct sockaddr_in *)&clientInfo.sin_addr;
+ inAddr = &(ipv4->sin_addr);
+ }
+ else
+ {
+ auto ipv6 = (struct sockaddr_in6 *)&clientInfo.sin_addr;
+ inAddr = &(ipv6->sin6_addr);
+ }
+
+ inet_ntop(clientInfo.sin_family, inAddr, addrstr, sizeof(addrstr));
std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
- _socket->_clientAddress = ip;
+ _socket->_clientAddress = addrstr;
+ LOG_DBG("Accepted socket has family " << clientInfo.sin_family <<
+ " address " << _socket->_clientAddress);
return _socket;
}
return std::shared_ptr<Socket>(nullptr);
commit cd11971f92ae12fd3972344233c3d480c85076f8
Author: Safir Depo <selimzcn at gmail.com>
AuthorDate: Mon May 14 16:36:03 2018 +0300
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
bugfix for commit:910ae80-'wsd: to filter clientAddress before POST action.'
Change-Id: I48e6d89fc62c6a656d9e8a74f9f5f8be1d687940
Reviewed-on: https://gerrit.libreoffice.org/54325
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
Tested-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 3850875c7..eca0644f6 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1797,7 +1797,7 @@ public:
// Parse the host allow settings.
for (size_t i = 0; ; ++i)
{
- const std::string path = "post_allow.host[" + std::to_string(i) + "]";
+ const std::string path = "net.post_allow.host[" + std::to_string(i) + "]";
const auto host = app.config().getString(path, "");
if (!host.empty())
{
commit 45d4b08ac0a7afbb158a4ce003dd69fb416b9d28
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sun May 13 13:35:32 2018 +0100
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
Restrict convert-to to known hosts - not all insert / downloads.
Change-Id: Ief26c80bf7e9e96f3c5dce0d8739a825f6fac629
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index fe4ca7004..3850875c7 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1786,6 +1786,33 @@ public:
StaticFileContentCache["discovery.xml"] = getDiscoveryXML();
}
+ /// Does this address feature in the allowed hosts list.
+ bool allowPostFrom(const std::string &address)
+ {
+ static bool init = false;
+ static Util::RegexListMatcher hosts;
+ if (!init)
+ {
+ const auto& app = Poco::Util::Application::instance();
+ // Parse the host allow settings.
+ for (size_t i = 0; ; ++i)
+ {
+ const std::string path = "post_allow.host[" + std::to_string(i) + "]";
+ const auto host = app.config().getString(path, "");
+ if (!host.empty())
+ {
+ LOG_INF("Adding trusted POST_ALLOW host: [" << host << "].");
+ hosts.allow(host);
+ }
+ else if (!app.config().has(path))
+ {
+ break;
+ }
+ }
+ }
+ return hosts.match(address);
+ }
+
private:
/// Set the socket associated with this ResponseClient.
@@ -1870,42 +1897,8 @@ private:
if (!(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) &&
reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
{
- // allow/deny for POST
- const auto& app = Poco::Util::Application::instance();
- Util::RegexListMatcher hosts;
- // Parse the host allow settings.
- for (size_t i = 0; ; ++i)
- {
- const std::string path = "post_allow.host[" + std::to_string(i) + "]";
- const auto host = app.config().getString(path, "");
- if (!host.empty())
- {
- LOG_INF("Adding trusted POST_ALLOW host: [" << host << "].");
- hosts.allow(host);
- }
- else if (!app.config().has(path))
- {
- break;
- }
- }
- if (!hosts.match(socket->clientAddress()))
- {
- LOG_ERR("client address DENY: " << socket->clientAddress().c_str());
-
- std::ostringstream oss;
- oss << "HTTP/1.1 403\r\n"
- << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
- << "User-Agent: " << HTTP_AGENT_STRING << "\r\n"
- << "Content-Length: 0\r\n"
- << "\r\n";
- socket->send(oss.str());
- socket->shutdown();
- }
- else
- {
- // All post requests have url prefix 'lool'.
- handlePostRequest(request, message, disposition);
- }
+ // All post requests have url prefix 'lool'.
+ handlePostRequest(request, message, disposition);
}
else if (reqPathTokens.count() > 2 && reqPathTokens[0] == "lool" && reqPathTokens[2] == "ws" &&
request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
@@ -2103,6 +2096,21 @@ private:
std::string format = (form.has("format") ? form.get("format") : "");
+ if (!allowPostFrom(socket->clientAddress()))
+ {
+ LOG_ERR("client address DENY: " << socket->clientAddress().c_str());
+
+ std::ostringstream oss;
+ oss << "HTTP/1.1 403\r\n"
+ << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+ << "User-Agent: " << HTTP_AGENT_STRING << "\r\n"
+ << "Content-Length: 0\r\n"
+ << "\r\n";
+ socket->send(oss.str());
+ socket->shutdown();
+ return;
+ }
+
// prefer what is in the URI
if (tokens.count() > 3)
format = tokens[3];
commit 94a870f57d13d49cb586365a565110245a868046
Author: YiiChang Yen <sadwind.yan at gmail.com>
AuthorDate: Wed Dec 13 13:31:29 2017 +0800
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
wsd: to filter clientAddress before POST action.
Change-Id: I293580f041bc46b36c57f63fe4a2c0131763b3c1
Reviewed-on: https://gerrit.libreoffice.org/50977
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/loolwsd.xml.in b/loolwsd.xml.in
index 74414de97..b11966d7d 100644
--- a/loolwsd.xml.in
+++ b/loolwsd.xml.in
@@ -69,6 +69,9 @@
<net desc="Network settings">
<proto type="string" default="all" desc="Protocol to use IPv4, IPv6 or all for both">all</proto>
<service_root type="path" default="" desc="Prefix all the pages, websockets, etc. with this path."></service_root>
+ <post_allow desc="Allow/deny client IP address for POST(REST)." allow="true">
+ <host desc="Regex pattern of ip address to allow.">192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host>
+ </post_allow>
</net>
<ssl desc="SSL settings">
diff --git a/net/ServerSocket.hpp b/net/ServerSocket.hpp
index 7ae7e7141..abc018678 100644
--- a/net/ServerSocket.hpp
+++ b/net/ServerSocket.hpp
@@ -60,13 +60,22 @@ public:
std::shared_ptr<Socket> accept()
{
// Accept a connection (if any) and set it to non-blocking.
- // We don't care about the client's address, so ignored.
- const int rc = ::accept4(getFD(), nullptr, nullptr, SOCK_NONBLOCK);
+ // There still need the client's address to filter request from POST(call from REST) here.
+ struct sockaddr_in clientInfo;
+ socklen_t addrlen = sizeof(struct sockaddr_in);
+ const int rc = ::accept4(getFD(), (struct sockaddr *)&clientInfo, &addrlen, SOCK_NONBLOCK);
LOG_DBG("Accepted socket #" << rc << ", creating socket object.");
try
{
// Create a socket object using the factory.
- return rc != -1 ? _sockFactory->create(rc) : std::shared_ptr<Socket>(nullptr);
+ if (rc != -1)
+ {
+ std::string ip = inet_ntoa(clientInfo.sin_addr);
+ std::shared_ptr<Socket> _socket = _sockFactory->create(rc);
+ _socket->_clientAddress = ip;
+ return _socket;
+ }
+ return std::shared_ptr<Socket>(nullptr);
}
catch (const std::exception& ex)
{
diff --git a/net/Socket.hpp b/net/Socket.hpp
index 421222302..ce30a28c9 100644
--- a/net/Socket.hpp
+++ b/net/Socket.hpp
@@ -98,6 +98,7 @@ public:
static const int DefaultSendBufferSize = 16 * 1024;
static const int MaximumSendBufferSize = 128 * 1024;
static std::atomic<bool> InhibitThreadChecks;
+ std::string _clientAddress;
enum Type { IPv4, IPv6, All };
@@ -879,6 +880,11 @@ public:
recv = _bytesRecvd;
}
+ const std::string clientAddress()
+ {
+ return _clientAddress;
+ }
+
protected:
/// Called when a polling event is received.
diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index ecc3d4fd1..fe4ca7004 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -1870,8 +1870,42 @@ private:
if (!(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) &&
reqPathTokens.count() > 0 && reqPathTokens[0] == "lool")
{
- // All post requests have url prefix 'lool'.
- handlePostRequest(request, message, disposition);
+ // allow/deny for POST
+ const auto& app = Poco::Util::Application::instance();
+ Util::RegexListMatcher hosts;
+ // Parse the host allow settings.
+ for (size_t i = 0; ; ++i)
+ {
+ const std::string path = "post_allow.host[" + std::to_string(i) + "]";
+ const auto host = app.config().getString(path, "");
+ if (!host.empty())
+ {
+ LOG_INF("Adding trusted POST_ALLOW host: [" << host << "].");
+ hosts.allow(host);
+ }
+ else if (!app.config().has(path))
+ {
+ break;
+ }
+ }
+ if (!hosts.match(socket->clientAddress()))
+ {
+ LOG_ERR("client address DENY: " << socket->clientAddress().c_str());
+
+ std::ostringstream oss;
+ oss << "HTTP/1.1 403\r\n"
+ << "Date: " << Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n"
+ << "User-Agent: " << HTTP_AGENT_STRING << "\r\n"
+ << "Content-Length: 0\r\n"
+ << "\r\n";
+ socket->send(oss.str());
+ socket->shutdown();
+ }
+ else
+ {
+ // All post requests have url prefix 'lool'.
+ handlePostRequest(request, message, disposition);
+ }
}
else if (reqPathTokens.count() > 2 && reqPathTokens[0] == "lool" && reqPathTokens[2] == "ws" &&
request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
commit 828ed669e3b6c90f5226b9e5003d6c22e3db886b
Author: Henry Castro <hcastro at collabora.com>
AuthorDate: Sat Aug 18 11:44:07 2018 -0400
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
loleaflet: wopi: add EnableInsertRemoteImage
Change-Id: I806c3a79813e77cba85e837aa188453a5b63cacc
diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index d9a5e8712..e7b4ed8b4 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -161,9 +161,12 @@ function onClick(e, id, item, subItem) {
else if (id === 'insertpage') {
$('#spreadsheet-tab-scroll').scrollLeft($('#spreadsheet-tab-scroll').prop('scrollWidth'));
}
- else if (id === 'insertgraphic') {
+ else if (id === 'insertgraphic' || item.id === 'localgraphic') {
L.DomUtil.get('insertgraphic').click();
}
+ else if (item.id === 'remotegraphic') {
+ map.fire('postMessage', {msgId: 'UI_InsertGraphic'});
+ }
else if (id === 'fontcolor' && typeof e.color !== 'undefined') {
onColorPick(id, e.color);
}
@@ -467,6 +470,11 @@ $(function () {
{type: 'button', id: 'insertobjectchart', img: 'insertobjectchart', hint: _UNO('.uno:InsertObjectChart', '', true), uno: 'InsertObjectChart'},
{type: 'button', id: 'insertannotation', img: 'annotation', hint: _UNO('.uno:InsertAnnotation', '', true)},
{type: 'button', id: 'insertgraphic', img: 'insertgraphic', hint: _UNO('.uno:InsertGraphic', '', true)},
+ {type: 'menu', id: 'menugraphic', img: 'insertgraphic', hint: _UNO('.uno:InsertGraphic', '', true), hidden: true,
+ items: [
+ {id: 'localgraphic', text: _UNO('.uno:InsertGraphic', '', true), icon: 'insertgraphic'},
+ {id: 'remotegraphic', text: _('Remote Image...'), icon: 'insertgraphic'}
+ ]},
{type: 'button', id: 'specialcharacter', img: 'specialcharacter', hint: _UNO('.uno:InsertSymbol', '', true), uno: '.uno:InsertSymbol'}
],
onClick: function (e) {
@@ -959,6 +967,10 @@ map.on('wopiprops', function(e) {
$('#document-name-input').removeClass('editable');
$('#document-name-input').off('keypress', onDocumentNameKeyPress);
}
+ if (e.EnableInsertRemoteImage === true) {
+ w2ui['toolbar-up'].hide('insertgraphic');
+ w2ui['toolbar-up'].show('menugraphic');
+ }
});
map.on('doclayerinit', function () {
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 75f782dc0..e10501ae9 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -805,6 +805,9 @@ L.Control.Menubar = L.Control.extend({
if (menu[i].id === 'saveas' && this._map['wopi'].UserCanNotWriteRelative)
continue;
+ if (menu[i].id === 'insertgraphicremote' && !this._map['wopi'].EnableInsertRemoteImage)
+ continue;
+
if (menu[i].id && menu[i].id.startsWith('fullscreen-presentation') && this._map['wopi'].HideExportOption)
continue;
diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js
index f9135762e..cd31fce22 100644
--- a/loleaflet/src/map/handler/Map.WOPI.js
+++ b/loleaflet/src/map/handler/Map.WOPI.js
@@ -19,6 +19,7 @@ L.Map.WOPI = L.Handler.extend({
DisableCopy: false,
DisableInactiveMessages: false,
UserCanNotWriteRelative: true,
+ EnableInsertRemoteImage: false,
CallPythonScriptSource: null,
_appLoadedConditions: {
@@ -74,6 +75,7 @@ L.Map.WOPI = L.Handler.extend({
this.DisableCopy = !!wopiInfo['DisableCopy'];
this.DisableInactiveMessages = !!wopiInfo['DisableInactiveMessages'];
this.UserCanNotWriteRelative = !!wopiInfo['UserCanNotWriteRelative'];
+ this.EnableInsertRemoteImage = !!wopiInfo['EnableInsertRemoteImage'];
this._map.fire('postMessage', {
msgId: 'App_LoadingStatus',
commit c2e37224d6467ae4eeafe40040b2dfb45dc0b6af
Author: Henry Castro <hcastro at collabora.com>
AuthorDate: Fri Aug 17 17:33:15 2018 -0400
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
wsd: wopi: introduce a "EnableInsertRemoteImage" entry in the CheckFileInfo
Change-Id: I66e5f12fbd49509ce8e82ea07ae7a2cc75ddc665
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 38b4d682d..67c73c112 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -509,6 +509,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
wopiInfo->set("DisableCopy", wopifileinfo->_disableCopy);
wopiInfo->set("DisableInactiveMessages", wopifileinfo->_disableInactiveMessages);
wopiInfo->set("UserCanNotWriteRelative", wopifileinfo->_userCanNotWriteRelative);
+ wopiInfo->set("EnableInsertRemoteImage", wopifileinfo->_enableInsertRemoteImage);
if (wopifileinfo->_hideChangeTrackingControls != WopiStorage::WOPIFileInfo::TriState::Unset)
wopiInfo->set("HideChangeTrackingControls", wopifileinfo->_hideChangeTrackingControls == WopiStorage::WOPIFileInfo::TriState::True);
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index e4ab5462c..acfc18408 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -463,6 +463,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
bool disableInactiveMessages = false;
std::string lastModifiedTime;
bool userCanNotWriteRelative = true;
+ bool enableInsertRemoteImage = false;
WOPIFileInfo::TriState disableChangeTrackingRecord = WOPIFileInfo::TriState::Unset;
WOPIFileInfo::TriState disableChangeTrackingShow = WOPIFileInfo::TriState::Unset;
WOPIFileInfo::TriState hideChangeTrackingControls = WOPIFileInfo::TriState::Unset;
@@ -541,6 +542,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
JsonUtil::findJSONValue(object, "DisableInactiveMessages", disableInactiveMessages);
JsonUtil::findJSONValue(object, "LastModifiedTime", lastModifiedTime);
JsonUtil::findJSONValue(object, "UserCanNotWriteRelative", userCanNotWriteRelative);
+ JsonUtil::findJSONValue(object, "EnableInsertRemoteImage", enableInsertRemoteImage);
bool booleanFlag = false;
if (JsonUtil::findJSONValue(object, "DisableChangeTrackingRecord", booleanFlag))
disableChangeTrackingRecord = (booleanFlag ? WOPIFileInfo::TriState::True : WOPIFileInfo::TriState::False);
@@ -568,7 +570,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au
{userId, obfuscatedUserId, userName, userExtraInfo, watermarkText, canWrite,
postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption,
enableOwnerTermination, disablePrint, disableExport, disableCopy,
- disableInactiveMessages, userCanNotWriteRelative,
+ disableInactiveMessages, userCanNotWriteRelative, enableInsertRemoteImage,
disableChangeTrackingShow, disableChangeTrackingRecord,
hideChangeTrackingControls, callDuration}));
}
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 1e9544c2e..f1361996e 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -284,6 +284,7 @@ public:
const bool disableCopy,
const bool disableInactiveMessages,
const bool userCanNotWriteRelative,
+ const bool enableInsertRemoteImage,
const TriState disableChangeTrackingShow,
const TriState disableChangeTrackingRecord,
const TriState hideChangeTrackingControls,
@@ -303,6 +304,7 @@ public:
_disableCopy(disableCopy),
_disableInactiveMessages(disableInactiveMessages),
_userCanNotWriteRelative(userCanNotWriteRelative),
+ _enableInsertRemoteImage(enableInsertRemoteImage),
_disableChangeTrackingShow(disableChangeTrackingShow),
_disableChangeTrackingRecord(disableChangeTrackingRecord),
_hideChangeTrackingControls(hideChangeTrackingControls),
@@ -343,6 +345,8 @@ public:
bool _disableInactiveMessages;
/// If set to false, users can access the save-as functionality
bool _userCanNotWriteRelative;
+ /// if set to true, users can access the insert remote image functionality
+ bool _enableInsertRemoteImage;
/// If we should disable change-tracking visibility by default (meaningful at loading).
TriState _disableChangeTrackingShow;
/// If we should disable change-tracking ability by default (meaningful at loading).
commit 1ded82e9027a744ac4f981cd963be474f07a788f
Author: Jan Holesovsky <kendy at collabora.com>
AuthorDate: Fri Aug 3 05:15:19 2018 +0200
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
Insert graphic: Pass the remote url to the core for download & insertion.
Change-Id: I871de173c255dcb7b184582e486328d7f66a2fae
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index f63e2643e..678ea0f5a 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -755,20 +755,27 @@ bool ChildSession::insertFile(const char* /*buffer*/, int /*length*/, const std:
return false;
}
- if (type == "graphic")
+ if (type == "graphic" || type == "graphicurl")
{
- std::string fileName = "file://" + std::string(JAILED_DOCUMENT_ROOT) + "insertfile/" + name;
+ std::string url;
+ if (type == "graphic")
+ url = "file://" + std::string(JAILED_DOCUMENT_ROOT) + "insertfile/" + name;
+ else if (type == "graphicurl")
+ URI::decode(name, url);
+
std::string command = ".uno:InsertGraphic";
std::string arguments = "{"
"\"FileName\":{"
"\"type\":\"string\","
- "\"value\":\"" + fileName + "\""
+ "\"value\":\"" + url + "\""
"}}";
std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex());
getLOKitDocument()->setView(_viewId);
+ LOG_TRC("Inserting graphic: '" << arguments.c_str() << "', '");
+
getLOKitDocument()->postUnoCommand(command.c_str(), arguments.c_str(), false);
}
diff --git a/loleaflet/src/control/Toolbar.js b/loleaflet/src/control/Toolbar.js
index c6c4fc4ba..b9d7dacb1 100644
--- a/loleaflet/src/control/Toolbar.js
+++ b/loleaflet/src/control/Toolbar.js
@@ -156,6 +156,10 @@ L.Map.include({
this.fire('insertfile', {file: file});
},
+ insertURL: function (url) {
+ this.fire('inserturl', {url: url});
+ },
+
cellEnterString: function (string) {
var command = {
'StringName': {
diff --git a/loleaflet/src/map/handler/Map.FileInserter.js b/loleaflet/src/map/handler/Map.FileInserter.js
index 756ee4744..aa7a53745 100644
--- a/loleaflet/src/map/handler/Map.FileInserter.js
+++ b/loleaflet/src/map/handler/Map.FileInserter.js
@@ -12,6 +12,7 @@ L.Map.FileInserter = L.Handler.extend({
this._map = map;
this._childId = null;
this._toInsert = {};
+ this._toInsertURL = {};
var parser = document.createElement('a');
parser.href = map.options.server;
var wopiSrc = '';
@@ -24,11 +25,13 @@ L.Map.FileInserter = L.Handler.extend({
addHooks: function () {
this._map.on('insertfile', this._onInsertFile, this);
+ this._map.on('inserturl', this._onInsertURL, this);
this._map.on('childid', this._onChildIdMsg, this);
},
removeHooks: function () {
this._map.off('insertfile', this._onInsertFile, this);
+ this._map.off('inserturl', this._onInsertURL, this);
this._map.off('childid', this._onChildIdMsg, this);
},
@@ -42,12 +45,27 @@ L.Map.FileInserter = L.Handler.extend({
}
},
+ _onInsertURL: function (e) {
+ if (!this._childId) {
+ this._map._socket.sendMessage('getchildid');
+ this._toInsertURL[Date.now()] = e.url;
+ }
+ else {
+ this._sendURL(Date.now(), e.url);
+ }
+ },
+
_onChildIdMsg: function (e) {
this._childId = e.id;
for (var name in this._toInsert) {
this._sendFile(name, this._toInsert[name]);
}
this._toInsert = {};
+
+ for (name in this._toInsertURL) {
+ this._sendURL(name, this._toInsertURL[name]);
+ }
+ this._toInsertURL = {};
},
_sendFile: function (name, file) {
@@ -73,6 +91,10 @@ L.Map.FileInserter = L.Handler.extend({
formData.append('file', file);
}
xmlHttp.send(formData);
+ },
+
+ _sendURL: function (name, url) {
+ this._map._socket.sendMessage('insertfile name=' + encodeURIComponent(url) + ' type=graphicurl');
}
});
diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js
index 78e79f1ec..f9135762e 100644
--- a/loleaflet/src/map/handler/Map.WOPI.js
+++ b/loleaflet/src/map/handler/Map.WOPI.js
@@ -217,7 +217,7 @@ L.Map.WOPI = L.Handler.extend({
}
else if (msg.MessageId == 'Action_InsertGraphic') {
if (msg.Values) {
- this._map.insertFile(msg.Values);
+ this._map.insertURL(msg.Values.url);
}
}
else if (msg.MessageId === 'Action_ShowBusy') {
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index 159bf1516..ead37a067 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -60,7 +60,13 @@ paste mimetype=<mimeType>
insertfile name=<name> type=<type>
- Inserts the file with the name <name> into the document, we currently support type = 'graphic'
+ Inserts the file with the name <name> into the document, we currently
+ support:
+
+ type = 'graphic': The file has been previously uploaded using insertfile POST
+
+ type = 'graphicurl': The file is supposed to be downloaded by the core
+ itself; it does so from the URL provided in 'name'
key type=<type> char=<charcode> key=<keycode>
commit ef8974463294433e22307819b46598553c3d24ee
Author: Henry Castro <hcastro at collabora.com>
AuthorDate: Sat Jul 14 12:43:45 2018 -0400
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Tue Sep 11 20:24:13 2018 +0200
loleaflet: add action to insert graphic
Change-Id: If3ab2de89625f44c4178da1146ca3834702a62ec
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 808fe0e18..75f782dc0 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -62,6 +62,7 @@ L.Control.Menubar = L.Control.extend({
},
{name: _UNO('.uno:InsertMenu', 'text'), type: 'menu', menu: [
{name: _UNO('.uno:InsertGraphic', 'text'), id: 'insertgraphic', type: 'action'},
+ {name: _('Remote Image...'), id: 'insertgraphicremote', type: 'action'},
{name: _UNO('.uno:InsertAnnotation', 'text'), id: 'insertcomment', type: 'action'},
{uno: '.uno:InsertObjectChart'},
{type: 'separator'},
@@ -677,6 +678,8 @@ L.Control.Menubar = L.Control.extend({
map.insertComment();
} else if (id === 'insertgraphic') {
L.DomUtil.get('insertgraphic').click();
+ } else if (id === 'insertgraphicremote') {
+ map.fire('postMessage', {msgId: 'UI_InsertGraphic'});
} else if (id === 'zoomin' && map.getZoom() < map.getMaxZoom()) {
map.zoomIn(1);
} else if (id === 'zoomout' && map.getZoom() > map.getMinZoom()) {
diff --git a/loleaflet/src/map/handler/Map.FileInserter.js b/loleaflet/src/map/handler/Map.FileInserter.js
index 153e821a3..756ee4744 100644
--- a/loleaflet/src/map/handler/Map.FileInserter.js
+++ b/loleaflet/src/map/handler/Map.FileInserter.js
@@ -66,7 +66,12 @@ L.Map.FileInserter = L.Handler.extend({
var formData = new FormData();
formData.append('name', name);
formData.append('childid', this._childId);
- formData.append('file', file);
+ if (file.filename && file.url) {
+ formData.append('url', file.url);
+ formData.append('filename', file.filename);
+ } else {
+ formData.append('file', file);
+ }
xmlHttp.send(formData);
}
});
diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js
index 9a55fd577..78e79f1ec 100644
--- a/loleaflet/src/map/handler/Map.WOPI.js
+++ b/loleaflet/src/map/handler/Map.WOPI.js
@@ -215,6 +215,11 @@ L.Map.WOPI = L.Handler.extend({
this._map.downloadAs(filename + '.' + format, format);
}
}
+ else if (msg.MessageId == 'Action_InsertGraphic') {
+ if (msg.Values) {
+ this._map.insertFile(msg.Values);
+ }
+ }
else if (msg.MessageId === 'Action_ShowBusy') {
if (msg.Values && msg.Values.Label) {
this._map.fire('showbusy', {label: msg.Values.Label});
More information about the Libreoffice-commits
mailing list