00001 00032 #include "linden_common.h" 00033 00034 #include "llmessageconfig.h" 00035 #include "llfile.h" 00036 #include "lllivefile.h" 00037 #include "llsd.h" 00038 #include "llsdutil.h" 00039 #include "llsdserialize.h" 00040 #include "message.h" 00041 00042 static const char messageConfigFileName[] = "message.xml"; 00043 static const F32 messageConfigRefreshRate = 5.0; // seconds 00044 00045 static std::string sServerName = ""; 00046 static std::string sConfigDir = ""; 00047 00048 static std::string sServerDefault; 00049 static LLSD sMessages; 00050 00051 00052 class LLMessageConfigFile : public LLLiveFile 00053 { 00054 public: 00055 LLMessageConfigFile() 00056 : LLLiveFile(filename(), messageConfigRefreshRate) 00057 { } 00058 00059 static std::string filename(); 00060 00061 LLSD mMessages; 00062 std::string mServerDefault; 00063 00064 static LLMessageConfigFile& instance(); 00065 // return the singleton configuration file 00066 00067 /* virtual */ void loadFile(); 00068 void loadServerDefaults(const LLSD& data); 00069 void loadMaxQueuedEvents(const LLSD& data); 00070 void loadMessages(const LLSD& data); 00071 void loadCapBans(const LLSD& blacklist); 00072 void loadMessageBans(const LLSD& blacklist); 00073 bool isCapBanned(const std::string& cap_name) const; 00074 00075 public: 00076 LLSD mCapBans; 00077 S32 mMaxQueuedEvents; 00078 }; 00079 00080 std::string LLMessageConfigFile::filename() 00081 { 00082 std::ostringstream ostr; 00083 ostr << sConfigDir//gAppSimp->getOption("configdir").asString() 00084 << "/" << messageConfigFileName; 00085 return ostr.str(); 00086 } 00087 00088 LLMessageConfigFile& LLMessageConfigFile::instance() 00089 { 00090 static LLMessageConfigFile the_file; 00091 the_file.checkAndReload(); 00092 return the_file; 00093 } 00094 00095 // virtual 00096 void LLMessageConfigFile::loadFile() 00097 { 00098 LLSD data; 00099 { 00100 llifstream file(filename().c_str()); 00101 00102 if (file.is_open()) 00103 { 00104 LL_DEBUGS("AppInit") << "Loading message.xml file at " << filename() << LL_ENDL; 00105 LLSDSerialize::fromXML(data, file); 00106 } 00107 00108 if (data.isUndefined()) 00109 { 00110 LL_INFOS("AppInit") << "LLMessageConfigFile::loadFile: file missing," 00111 " ill-formed, or simply undefined; not changing the" 00112 " file" << LL_ENDL; 00113 return; 00114 } 00115 } 00116 loadServerDefaults(data); 00117 loadMaxQueuedEvents(data); 00118 loadMessages(data); 00119 loadCapBans(data); 00120 loadMessageBans(data); 00121 } 00122 00123 void LLMessageConfigFile::loadServerDefaults(const LLSD& data) 00124 { 00125 mServerDefault = data["serverDefaults"][sServerName].asString(); 00126 } 00127 00128 const S32 DEFAULT_MAX_QUEUED_EVENTS = 100; 00129 void LLMessageConfigFile::loadMaxQueuedEvents(const LLSD& data) 00130 { 00131 if (data.has("maxQueuedEvents")) 00132 { 00133 mMaxQueuedEvents = data["maxQueuedEvents"].asInteger(); 00134 } 00135 else 00136 { 00137 mMaxQueuedEvents = DEFAULT_MAX_QUEUED_EVENTS; 00138 } 00139 } 00140 00141 void LLMessageConfigFile::loadMessages(const LLSD& data) 00142 { 00143 mMessages = data["messages"]; 00144 00145 #ifdef DEBUG 00146 std::ostringstream out; 00147 LLSDXMLFormatter *formatter = new LLSDXMLFormatter; 00148 formatter->format(mMessages, out); 00149 llinfos << "loading ... " << out.str() 00150 << " LLMessageConfigFile::loadMessages loaded " 00151 << mMessages.size() << " messages" << llendl; 00152 #endif 00153 } 00154 00155 void LLMessageConfigFile::loadCapBans(const LLSD& data) 00156 { 00157 LLSD bans = data["capBans"]; 00158 if (!bans.isMap()) 00159 { 00160 LL_INFOS("AppInit") << "LLMessageConfigFile::loadCapBans: missing capBans section" 00161 << LL_ENDL; 00162 return; 00163 } 00164 00165 mCapBans = bans; 00166 00167 LL_DEBUGS("AppInit") << "LLMessageConfigFile::loadCapBans: " 00168 << bans.size() << " ban tests" << LL_ENDL; 00169 } 00170 00171 void LLMessageConfigFile::loadMessageBans(const LLSD& data) 00172 { 00173 LLSD bans = data["messageBans"]; 00174 if (!bans.isMap()) 00175 { 00176 LL_INFOS("AppInit") << "LLMessageConfigFile::loadMessageBans: missing messageBans section" 00177 << LL_ENDL; 00178 return; 00179 } 00180 00181 gMessageSystem->setMessageBans(bans["trusted"], bans["untrusted"]); 00182 } 00183 00184 bool LLMessageConfigFile::isCapBanned(const std::string& cap_name) const 00185 { 00186 lldebugs << "mCapBans is " << LLSDNotationStreamer(mCapBans) << llendl; 00187 return mCapBans[cap_name]; 00188 } 00189 00190 //--------------------------------------------------------------- 00191 // LLMessageConfig 00192 //--------------------------------------------------------------- 00193 00194 //static 00195 void LLMessageConfig::initClass(const std::string& server_name, 00196 const std::string& config_dir) 00197 { 00198 sServerName = server_name; 00199 sConfigDir = config_dir; 00200 (void) LLMessageConfigFile::instance(); 00201 LL_DEBUGS("AppInit") << "LLMessageConfig::initClass config file " 00202 << config_dir << "/" << messageConfigFileName << LL_ENDL; 00203 } 00204 00205 //static 00206 void LLMessageConfig::useConfig(const LLSD& config) 00207 { 00208 LLMessageConfigFile &the_file = LLMessageConfigFile::instance(); 00209 the_file.loadServerDefaults(config); 00210 the_file.loadMaxQueuedEvents(config); 00211 the_file.loadMessages(config); 00212 the_file.loadCapBans(config); 00213 the_file.loadMessageBans(config); 00214 } 00215 00216 //static 00217 LLMessageConfig::Flavor LLMessageConfig::getServerDefaultFlavor() 00218 { 00219 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00220 if (file.mServerDefault == "llsd") 00221 { 00222 return LLSD_FLAVOR; 00223 } 00224 if (file.mServerDefault == "template") 00225 { 00226 return TEMPLATE_FLAVOR; 00227 } 00228 return NO_FLAVOR; 00229 } 00230 00231 //static 00232 S32 LLMessageConfig::getMaxQueuedEvents() 00233 { 00234 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00235 return file.mMaxQueuedEvents; 00236 } 00237 00238 //static 00239 LLMessageConfig::Flavor LLMessageConfig::getMessageFlavor(const std::string& msg_name) 00240 { 00241 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00242 LLSD config = file.mMessages[msg_name]; 00243 if (config["flavor"].asString() == "llsd") 00244 { 00245 return LLSD_FLAVOR; 00246 } 00247 if (config["flavor"].asString() == "template") 00248 { 00249 return TEMPLATE_FLAVOR; 00250 } 00251 return NO_FLAVOR; 00252 } 00253 00254 //static 00255 LLMessageConfig::SenderTrust LLMessageConfig::getSenderTrustedness( 00256 const std::string& msg_name) 00257 { 00258 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00259 LLSD config = file.mMessages[msg_name]; 00260 if (config.has("trusted-sender")) 00261 { 00262 return config["trusted-sender"].asBoolean() ? TRUSTED : UNTRUSTED; 00263 } 00264 return NOT_SET; 00265 } 00266 00267 //static 00268 bool LLMessageConfig::isValidMessage(const std::string& msg_name) 00269 { 00270 if (sServerName.empty()) 00271 { 00272 llerrs << "LLMessageConfig::initClass() not called" << llendl; 00273 } 00274 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00275 return file.mMessages.has(msg_name); 00276 } 00277 00278 //static 00279 bool LLMessageConfig::onlySendLatest(const std::string& msg_name) 00280 { 00281 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00282 LLSD config = file.mMessages[msg_name]; 00283 return config["only-send-latest"].asBoolean(); 00284 } 00285 00286 bool LLMessageConfig::isCapBanned(const std::string& cap_name) 00287 { 00288 return LLMessageConfigFile::instance().isCapBanned(cap_name); 00289 } 00290 00291 // return the web-service path to use for a given 00292 // message. This entry *should* match the entry 00293 // in simulator.xml! 00294 LLSD LLMessageConfig::getConfigForMessage(const std::string& msg_name) 00295 { 00296 if (sServerName.empty()) 00297 { 00298 llerrs << "LLMessageConfig::isMessageTrusted(name) before" 00299 << " LLMessageConfig::initClass()" << llendl; 00300 } 00301 LLMessageConfigFile& file = LLMessageConfigFile::instance(); 00302 // LLSD for the CamelCase message name 00303 LLSD config = file.mMessages[msg_name]; 00304 return config; 00305 }