summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llchatbar.cpp2
-rw-r--r--indra/newview/llcommandhandler.cpp51
-rw-r--r--indra/newview/llcommandhandler.h11
-rw-r--r--indra/newview/llfloaterhandler.h2
-rw-r--r--indra/newview/llfloaterparcel.cpp2
-rw-r--r--indra/newview/llgroupactions.cpp2
-rw-r--r--indra/newview/llloginhandler.h2
-rw-r--r--indra/newview/llmediactrl.cpp9
-rw-r--r--indra/newview/llnearbychatbar.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp2
-rw-r--r--indra/newview/llpanellogin.cpp2
-rw-r--r--indra/newview/llpanelprofile.cpp2
-rw-r--r--indra/newview/llstatusbar.cpp2
-rw-r--r--indra/newview/llurldispatcher.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml8
15 files changed, 60 insertions, 41 deletions
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 3ee2c93961..96c707b08f 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -674,7 +674,7 @@ class LLChatHandler : public LLCommandHandler
{
public:
// not allowed from outside the app
- LLChatHandler() : LLCommandHandler("chat", true) { }
+ LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index a04182a910..af6488388a 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -38,12 +38,14 @@
// system includes
#include <boost/tokenizer.hpp>
+#define THROTTLE_PERIOD 15 // required secs between throttled commands
+
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
//---------------------------------------------------------------------------
struct LLCommandHandlerInfo
{
- bool mRequireTrustedBrowser;
+ LLCommandHandler::EUntrustedAccess mUntrustedBrowserAccess;
LLCommandHandler* mHandler; // safe, all of these are static objects
};
@@ -51,7 +53,9 @@ class LLCommandHandlerRegistry
{
public:
static LLCommandHandlerRegistry& instance();
- void add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler);
+ void add(const char* cmd,
+ LLCommandHandler::EUntrustedAccess untrusted_access,
+ LLCommandHandler* handler);
bool dispatch(const std::string& cmd,
const LLSD& params,
const LLSD& query_map,
@@ -72,10 +76,12 @@ LLCommandHandlerRegistry& LLCommandHandlerRegistry::instance()
return instance;
}
-void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler)
+void LLCommandHandlerRegistry::add(const char* cmd,
+ LLCommandHandler::EUntrustedAccess untrusted_access,
+ LLCommandHandler* handler)
{
LLCommandHandlerInfo info;
- info.mRequireTrustedBrowser = require_trusted_browser;
+ info.mUntrustedBrowserAccess = untrusted_access;
info.mHandler = handler;
mMap[cmd] = info;
@@ -87,15 +93,37 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
LLMediaCtrl* web,
bool trusted_browser)
{
+ static F64 last_throttle_time = 0.0;
+ F64 cur_time = 0.0;
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
if (it == mMap.end()) return false;
const LLCommandHandlerInfo& info = it->second;
- if (!trusted_browser && info.mRequireTrustedBrowser)
+ if (!trusted_browser)
{
- // block request from external browser, but report as
- // "handled" because it was well formatted.
- LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
- return true;
+ switch (info.mUntrustedBrowserAccess)
+ {
+ case LLCommandHandler::UNTRUSTED_ALLOW:
+ // fall through and let the command be handled
+ break;
+
+ case LLCommandHandler::UNTRUSTED_BLOCK:
+ // block request from external browser, but report as
+ // "handled" because it was well formatted.
+ LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
+ return true;
+
+ case LLCommandHandler::UNTRUSTED_THROTTLE:
+ cur_time = LLTimer::getElapsedSeconds();
+ if (cur_time < last_throttle_time + THROTTLE_PERIOD)
+ {
+ // block request from external browser if it happened
+ // within THROTTLE_PERIOD secs of the last command
+ LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
+ return true;
+ }
+ last_throttle_time = cur_time;
+ break;
+ }
}
if (!info.mHandler) return false;
return info.mHandler->handle(params, query_map, web);
@@ -106,10 +134,9 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
//---------------------------------------------------------------------------
LLCommandHandler::LLCommandHandler(const char* cmd,
- bool require_trusted_browser)
+ EUntrustedAccess untrusted_access)
{
- LLCommandHandlerRegistry::instance().add(
- cmd, require_trusted_browser, this);
+ LLCommandHandlerRegistry::instance().add(cmd, untrusted_access, this);
}
LLCommandHandler::~LLCommandHandler()
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 5cb3ee73d4..1bae6d9414 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -43,7 +43,7 @@ public:
// Inform the system you handle commands starting
// with "foo" and they are only allowed from
// "trusted" (pointed at Linden content) browsers
- LLFooHandler() : LLCommandHandler("foo", true) { }
+ LLFooHandler() : LLCommandHandler("foo", UNTRUSTED_BLOCK) { }
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
@@ -65,7 +65,14 @@ class LLMediaCtrl;
class LLCommandHandler
{
public:
- LLCommandHandler(const char* command, bool allow_from_untrusted_browser);
+ enum EUntrustedAccess
+ {
+ UNTRUSTED_ALLOW, // allow commands from untrusted browsers
+ UNTRUSTED_BLOCK, // ignore commands from untrusted browsers
+ UNTRUSTED_THROTTLE // allow untrusted, but only a few per min.
+ };
+
+ LLCommandHandler(const char* command, EUntrustedAccess untrusted_access);
// Automatically registers object to get called when
// command is executed. All commands can be processed
// in links from LLMediaCtrl, but some (like teleport)
diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h
index 31ea80c12c..cd9d8b5377 100644
--- a/indra/newview/llfloaterhandler.h
+++ b/indra/newview/llfloaterhandler.h
@@ -38,7 +38,7 @@ class LLFloaterHandler
: public LLCommandHandler
{
public:
- LLFloaterHandler() : LLCommandHandler("floater", true) { }
+ LLFloaterHandler() : LLCommandHandler("floater", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web);
};
diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp
index 44270683a0..88a39a495f 100644
--- a/indra/newview/llfloaterparcel.cpp
+++ b/indra/newview/llfloaterparcel.cpp
@@ -53,7 +53,7 @@ class LLParcelHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLParcelHandler() : LLCommandHandler("parcel", true) { }
+ LLParcelHandler() : LLCommandHandler("parcel", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 10a17476d9..d1cbe96906 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -51,7 +51,7 @@ class LLGroupHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLGroupHandler() : LLCommandHandler("group", true) { }
+ LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h
index 0844b80c7c..d36ceaf3cc 100644
--- a/indra/newview/llloginhandler.h
+++ b/indra/newview/llloginhandler.h
@@ -39,7 +39,7 @@ class LLLoginHandler : public LLCommandHandler
{
public:
// allow from external browsers
- LLLoginHandler() : LLCommandHandler("login", false) { }
+ LLLoginHandler() : LLCommandHandler("login", UNTRUSTED_ALLOW) { }
/*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web);
// Fill in our internal fields from a SLURL like
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 62b38f2b4a..09a7edaa43 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -916,15 +916,8 @@ void LLMediaCtrl::onClickLinkHref( LLPluginClassMedia* self )
//
void LLMediaCtrl::onClickLinkNoFollow( LLPluginClassMedia* self )
{
+ // let the dispatcher handle blocking/throttling of SLURLs
std::string url = self->getClickURL();
- if (LLSLURL::isSLURLCommand(url)
- && !mTrusted)
- {
- // block handling of this secondlife:///app/ URL
- LLNotifications::instance().add("UnableToOpenCommandURL");
- return;
- }
-
LLURLDispatcher::dispatch(url, this, mTrusted);
}
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 764e093bcc..e348189ea9 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -616,7 +616,7 @@ class LLChatHandler : public LLCommandHandler
{
public:
// not allowed from outside the app
- LLChatHandler() : LLCommandHandler("chat", true) { }
+ LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
// Your code here
bool handle(const LLSD& tokens, const LLSD& query_map,
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index c77d089af7..ee5d265220 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -119,7 +119,7 @@ class LLClassifiedTeleportHandler : public LLCommandHandler
{
public:
// don't allow from external browsers because it moves you immediately
- LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", true) { }
+ LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& tokens, const LLSD& queryMap)
{
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index ef830d5f03..9caa751854 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -87,7 +87,7 @@ class LLLoginRefreshHandler : public LLCommandHandler
{
public:
// don't allow from external browsers
- LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { }
+ LLLoginRefreshHandler() : LLCommandHandler("login_refresh", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 6d3d307526..ce01568e99 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -46,7 +46,7 @@ class LLAgentHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLAgentHandler() : LLCommandHandler("agent", true) { }
+ LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index c724fb5315..40b8445dcf 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -623,7 +623,7 @@ class LLBalanceHandler : public LLCommandHandler
{
public:
// Requires "trusted" browser/URL source
- LLBalanceHandler() : LLCommandHandler("balance", true) { }
+ LLBalanceHandler() : LLCommandHandler("balance", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (tokens.size() == 1
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 4cdeca7707..901d0594f1 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -331,7 +331,7 @@ public:
// Teleport requests *must* come from a trusted browser
// inside the app, otherwise a malicious web page could
// cause a constant teleport loop. JC
- LLTeleportHandler() : LLCommandHandler("teleport", true) { }
+ LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_BLOCK) { }
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 1f0578f819..ea1c0dd99b 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6495,14 +6495,6 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block
<notification
icon="notifytip.tga"
- name="UnableToOpenCommandURL"
- priority="high"
- type="notifytip">
- The link you clicked cannot be opened from this web browser.
- </notification>
-
- <notification
- icon="notifytip.tga"
name="UnsupportedCommandSLURL"
priority="high"
type="notifytip">