diff options
-rw-r--r-- | indra/newview/llchatbar.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llcommandhandler.cpp | 51 | ||||
-rw-r--r-- | indra/newview/llcommandhandler.h | 11 | ||||
-rw-r--r-- | indra/newview/llfloaterhandler.h | 2 | ||||
-rw-r--r-- | indra/newview/llfloaterparcel.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llgroupactions.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llloginhandler.h | 2 | ||||
-rw-r--r-- | indra/newview/llmediactrl.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llnearbychatbar.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanelclassified.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanellogin.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanelprofile.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llstatusbar.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llurldispatcher.cpp | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 8 |
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"> |