llcommandhandler.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file llcommandhandler.cpp
  3.  * @brief Central registry for text-driven "commands", most of
  4.  * which manipulate user interface.  For example, the command
  5.  * "agent (uuid) about" will open the UI for an avatar's profile.
  6.  *
  7.  * $LicenseInfo:firstyear=2007&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2007-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #include "llviewerprecompiledheaders.h"
  35. #include "llcommandhandler.h"
  36. #include "llnotificationsutil.h"
  37. #include "llcommanddispatcherlistener.h"
  38. #include "stringize.h"
  39. // system includes
  40. #include <boost/tokenizer.hpp>
  41. #define THROTTLE_PERIOD    15    // required secs between throttled commands
  42. static LLCommandDispatcherListener sCommandDispatcherListener;
  43. //---------------------------------------------------------------------------
  44. // Underlying registry for command handlers, not directly accessible.
  45. //---------------------------------------------------------------------------
  46. struct LLCommandHandlerInfo
  47. {
  48. LLCommandHandler::EUntrustedAccess mUntrustedBrowserAccess;
  49. LLCommandHandler* mHandler; // safe, all of these are static objects
  50. };
  51. class LLCommandHandlerRegistry
  52. {
  53. public:
  54. static LLCommandHandlerRegistry& instance();
  55. void add(const char* cmd,
  56.  LLCommandHandler::EUntrustedAccess untrusted_access,
  57.  LLCommandHandler* handler);
  58. bool dispatch(const std::string& cmd,
  59.   const LLSD& params,
  60.   const LLSD& query_map,
  61.   LLMediaCtrl* web,
  62.   bool trusted_browser);
  63. private:
  64. friend LLSD LLCommandDispatcher::enumerate();
  65. std::map<std::string, LLCommandHandlerInfo> mMap;
  66. };
  67. // static 
  68. LLCommandHandlerRegistry& LLCommandHandlerRegistry::instance()
  69. {
  70. // Force this to be initialized on first call, because we're going
  71. // to be adding items to the std::map before main() and we can't
  72. // rely on a global being initialized in the right order.
  73. static LLCommandHandlerRegistry instance;
  74. return instance;
  75. }
  76. void LLCommandHandlerRegistry::add(const char* cmd,
  77.    LLCommandHandler::EUntrustedAccess untrusted_access,
  78.    LLCommandHandler* handler)
  79. {
  80. LLCommandHandlerInfo info;
  81. info.mUntrustedBrowserAccess = untrusted_access;
  82. info.mHandler = handler;
  83. mMap[cmd] = info;
  84. }
  85. bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
  86. const LLSD& params,
  87. const LLSD& query_map,
  88. LLMediaCtrl* web,
  89. bool trusted_browser)
  90. {
  91. static bool slurl_blocked = false;
  92. static bool slurl_throttled = false;
  93. static F64 last_throttle_time = 0.0;
  94. F64 cur_time = 0.0;
  95. std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
  96. if (it == mMap.end()) return false;
  97. const LLCommandHandlerInfo& info = it->second;
  98. if (!trusted_browser)
  99. {
  100. switch (info.mUntrustedBrowserAccess)
  101. {
  102. case LLCommandHandler::UNTRUSTED_ALLOW:
  103. // fall through and let the command be handled
  104. break;
  105. case LLCommandHandler::UNTRUSTED_BLOCK:
  106. // block request from external browser, but report as
  107. // "handled" because it was well formatted.
  108. LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
  109. if (! slurl_blocked)
  110. {
  111. LLNotificationsUtil::add("BlockedSLURL");
  112. slurl_blocked = true;
  113. }
  114. return true;
  115. case LLCommandHandler::UNTRUSTED_THROTTLE:
  116. cur_time = LLTimer::getElapsedSeconds();
  117. if (cur_time < last_throttle_time + THROTTLE_PERIOD)
  118. {
  119. // block request from external browser if it happened
  120. // within THROTTLE_PERIOD secs of the last command
  121. LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
  122. if (! slurl_throttled)
  123. {
  124. LLNotificationsUtil::add("ThrottledSLURL");
  125. slurl_throttled = true;
  126. }
  127. return true;
  128. }
  129. last_throttle_time = cur_time;
  130. break;
  131. }
  132. }
  133. if (!info.mHandler) return false;
  134. return info.mHandler->handle(params, query_map, web);
  135. }
  136. //---------------------------------------------------------------------------
  137. // Automatic registration of commands, runs before main()
  138. //---------------------------------------------------------------------------
  139. LLCommandHandler::LLCommandHandler(const char* cmd,
  140.    EUntrustedAccess untrusted_access)
  141. {
  142. LLCommandHandlerRegistry::instance().add(cmd, untrusted_access, this);
  143. }
  144. LLCommandHandler::~LLCommandHandler()
  145. {
  146. // Don't care about unregistering these, all the handlers
  147. // should be static objects.
  148. }
  149. //---------------------------------------------------------------------------
  150. // Public interface
  151. //---------------------------------------------------------------------------
  152. // static
  153. bool LLCommandDispatcher::dispatch(const std::string& cmd,
  154.    const LLSD& params,
  155.    const LLSD& query_map,
  156.    LLMediaCtrl* web,
  157.    bool trusted_browser)
  158. {
  159. return LLCommandHandlerRegistry::instance().dispatch(
  160. cmd, params, query_map, web, trusted_browser);
  161. }
  162. static std::string lookup(LLCommandHandler::EUntrustedAccess value);
  163. LLSD LLCommandDispatcher::enumerate()
  164. {
  165. LLSD response;
  166. LLCommandHandlerRegistry& registry(LLCommandHandlerRegistry::instance());
  167. for (std::map<std::string, LLCommandHandlerInfo>::const_iterator chi(registry.mMap.begin()),
  168.  chend(registry.mMap.end());
  169.  chi != chend; ++chi)
  170. {
  171. LLSD info;
  172. info["untrusted"] = chi->second.mUntrustedBrowserAccess;
  173. info["untrusted_str"] = lookup(chi->second.mUntrustedBrowserAccess);
  174. response[chi->first] = info;
  175. }
  176. return response;
  177. }
  178. /*------------------------------ lookup stuff ------------------------------*/
  179. struct symbol_info
  180. {
  181. const char* name;
  182. LLCommandHandler::EUntrustedAccess value;
  183. };
  184. #define ent(SYMBOL)
  185. {
  186. #SYMBOL + 28, /* skip "LLCommandHandler::UNTRUSTED_" prefix */
  187. SYMBOL
  188. }
  189. symbol_info symbols[] =
  190. {
  191. ent(LLCommandHandler::UNTRUSTED_ALLOW),   // allow commands from untrusted browsers
  192. ent(LLCommandHandler::UNTRUSTED_BLOCK),   // ignore commands from untrusted browsers
  193. ent(LLCommandHandler::UNTRUSTED_THROTTLE)   // allow untrusted, but only a few per min.
  194. };
  195. #undef ent
  196. static std::string lookup(LLCommandHandler::EUntrustedAccess value)
  197. {
  198. for (symbol_info *sii(symbols), *siend(symbols + (sizeof(symbols)/sizeof(symbols[0])));
  199.  sii != siend; ++sii)
  200. {
  201. if (sii->value == value)
  202. {
  203. return sii->name;
  204. }
  205. }
  206. return STRINGIZE("UNTRUSTED_" << value);
  207. }