extensions/pref/autoconfig/src/nsReadConfig.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifdef MOZ_LOGGING
michael@0 7 // sorry, this has to be before the pre-compiled header
michael@0 8 #define FORCE_PR_LOG /* Allow logging in the release build */
michael@0 9 #endif
michael@0 10 #include "nsReadConfig.h"
michael@0 11 #include "nsAppDirectoryServiceDefs.h"
michael@0 12 #include "nsIAppStartup.h"
michael@0 13 #include "nsDirectoryServiceDefs.h"
michael@0 14 #include "nsIAutoConfig.h"
michael@0 15 #include "nsIComponentManager.h"
michael@0 16 #include "nsIFile.h"
michael@0 17 #include "nsIObserverService.h"
michael@0 18 #include "nsIPrefBranch.h"
michael@0 19 #include "nsIPrefService.h"
michael@0 20 #include "nsIPromptService.h"
michael@0 21 #include "nsIServiceManager.h"
michael@0 22 #include "nsIStringBundle.h"
michael@0 23 #include "nsToolkitCompsCID.h"
michael@0 24 #include "nsXPIDLString.h"
michael@0 25 #include "nsNetUtil.h"
michael@0 26 #include "prmem.h"
michael@0 27 #include "nsString.h"
michael@0 28 #include "nsCRT.h"
michael@0 29 #include "nspr.h"
michael@0 30 #include "nsXULAppAPI.h"
michael@0 31
michael@0 32 extern PRLogModuleInfo *MCD;
michael@0 33
michael@0 34 extern nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
michael@0 35 const char *filename,
michael@0 36 bool bGlobalContext,
michael@0 37 bool bCallbacks,
michael@0 38 bool skipFirstLine);
michael@0 39 extern nsresult CentralizedAdminPrefManagerInit();
michael@0 40 extern nsresult CentralizedAdminPrefManagerFinish();
michael@0 41
michael@0 42
michael@0 43 static void DisplayError(void)
michael@0 44 {
michael@0 45 nsresult rv;
michael@0 46
michael@0 47 nsCOMPtr<nsIPromptService> promptService = do_GetService("@mozilla.org/embedcomp/prompt-service;1");
michael@0 48 if (!promptService)
michael@0 49 return;
michael@0 50
michael@0 51 nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
michael@0 52 if (!bundleService)
michael@0 53 return;
michael@0 54
michael@0 55 nsCOMPtr<nsIStringBundle> bundle;
michael@0 56 bundleService->CreateBundle("chrome://autoconfig/locale/autoconfig.properties",
michael@0 57 getter_AddRefs(bundle));
michael@0 58 if (!bundle)
michael@0 59 return;
michael@0 60
michael@0 61 nsXPIDLString title;
michael@0 62 rv = bundle->GetStringFromName(MOZ_UTF16("readConfigTitle"), getter_Copies(title));
michael@0 63 if (NS_FAILED(rv))
michael@0 64 return;
michael@0 65
michael@0 66 nsXPIDLString err;
michael@0 67 rv = bundle->GetStringFromName(MOZ_UTF16("readConfigMsg"), getter_Copies(err));
michael@0 68 if (NS_FAILED(rv))
michael@0 69 return;
michael@0 70
michael@0 71 promptService->Alert(nullptr, title.get(), err.get());
michael@0 72 }
michael@0 73
michael@0 74 // nsISupports Implementation
michael@0 75
michael@0 76 NS_IMPL_ISUPPORTS(nsReadConfig, nsIReadConfig, nsIObserver)
michael@0 77
michael@0 78 nsReadConfig::nsReadConfig() :
michael@0 79 mRead(false)
michael@0 80 {
michael@0 81 if (!MCD)
michael@0 82 MCD = PR_NewLogModule("MCD");
michael@0 83 }
michael@0 84
michael@0 85 nsresult nsReadConfig::Init()
michael@0 86 {
michael@0 87 nsresult rv;
michael@0 88
michael@0 89 nsCOMPtr<nsIObserverService> observerService =
michael@0 90 do_GetService("@mozilla.org/observer-service;1", &rv);
michael@0 91
michael@0 92 if (observerService) {
michael@0 93 rv = observerService->AddObserver(this, NS_PREFSERVICE_READ_TOPIC_ID, false);
michael@0 94 }
michael@0 95 return(rv);
michael@0 96 }
michael@0 97
michael@0 98 nsReadConfig::~nsReadConfig()
michael@0 99 {
michael@0 100 CentralizedAdminPrefManagerFinish();
michael@0 101 }
michael@0 102
michael@0 103 NS_IMETHODIMP nsReadConfig::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
michael@0 104 {
michael@0 105 nsresult rv = NS_OK;
michael@0 106
michael@0 107 if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
michael@0 108 rv = readConfigFile();
michael@0 109 if (NS_FAILED(rv)) {
michael@0 110 DisplayError();
michael@0 111
michael@0 112 nsCOMPtr<nsIAppStartup> appStartup =
michael@0 113 do_GetService(NS_APPSTARTUP_CONTRACTID);
michael@0 114 if (appStartup)
michael@0 115 appStartup->Quit(nsIAppStartup::eAttemptQuit);
michael@0 116 }
michael@0 117 }
michael@0 118 return rv;
michael@0 119 }
michael@0 120
michael@0 121
michael@0 122 nsresult nsReadConfig::readConfigFile()
michael@0 123 {
michael@0 124 nsresult rv = NS_OK;
michael@0 125 nsXPIDLCString lockFileName;
michael@0 126 nsXPIDLCString lockVendor;
michael@0 127 uint32_t fileNameLen = 0;
michael@0 128
michael@0 129 nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
michael@0 130 nsCOMPtr<nsIPrefService> prefService =
michael@0 131 do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
michael@0 132 if (NS_FAILED(rv))
michael@0 133 return rv;
michael@0 134
michael@0 135 rv = prefService->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch));
michael@0 136 if (NS_FAILED(rv))
michael@0 137 return rv;
michael@0 138
michael@0 139 // This preference is set in the all.js or all-ns.js (depending whether
michael@0 140 // running mozilla or netscp6)
michael@0 141
michael@0 142 rv = defaultPrefBranch->GetCharPref("general.config.filename",
michael@0 143 getter_Copies(lockFileName));
michael@0 144
michael@0 145
michael@0 146 PR_LOG(MCD, PR_LOG_DEBUG, ("general.config.filename = %s\n", lockFileName.get()));
michael@0 147 if (NS_FAILED(rv))
michael@0 148 return rv;
michael@0 149
michael@0 150 // This needs to be read only once.
michael@0 151 //
michael@0 152 if (!mRead) {
michael@0 153 // Initiate the new JS Context for Preference management
michael@0 154
michael@0 155 rv = CentralizedAdminPrefManagerInit();
michael@0 156 if (NS_FAILED(rv))
michael@0 157 return rv;
michael@0 158
michael@0 159 // Open and evaluate function calls to set/lock/unlock prefs
michael@0 160 rv = openAndEvaluateJSFile("prefcalls.js", 0, false, false);
michael@0 161 if (NS_FAILED(rv))
michael@0 162 return rv;
michael@0 163
michael@0 164 // Evaluate platform specific directives
michael@0 165 rv = openAndEvaluateJSFile("platform.js", 0, false, false);
michael@0 166 if (NS_FAILED(rv))
michael@0 167 return rv;
michael@0 168
michael@0 169 mRead = true;
michael@0 170 }
michael@0 171 // If the lockFileName is nullptr return ok, because no lockFile will be used
michael@0 172
michael@0 173
michael@0 174 // Once the config file is read, we should check that the vendor name
michael@0 175 // is consistent By checking for the vendor name after reading the config
michael@0 176 // file we allow for the preference to be set (and locked) by the creator
michael@0 177 // of the cfg file meaning the file can not be renamed (successfully).
michael@0 178
michael@0 179 nsCOMPtr<nsIPrefBranch> prefBranch;
michael@0 180 rv = prefService->GetBranch(nullptr, getter_AddRefs(prefBranch));
michael@0 181 NS_ENSURE_SUCCESS(rv, rv);
michael@0 182
michael@0 183 int32_t obscureValue = 0;
michael@0 184 (void) defaultPrefBranch->GetIntPref("general.config.obscure_value", &obscureValue);
michael@0 185 PR_LOG(MCD, PR_LOG_DEBUG, ("evaluating .cfg file %s with obscureValue %d\n", lockFileName.get(), obscureValue));
michael@0 186 rv = openAndEvaluateJSFile(lockFileName.get(), obscureValue, true, true);
michael@0 187 if (NS_FAILED(rv))
michael@0 188 {
michael@0 189 PR_LOG(MCD, PR_LOG_DEBUG, ("error evaluating .cfg file %s %x\n", lockFileName.get(), rv));
michael@0 190 return rv;
michael@0 191 }
michael@0 192
michael@0 193 rv = prefBranch->GetCharPref("general.config.filename",
michael@0 194 getter_Copies(lockFileName));
michael@0 195 if (NS_FAILED(rv))
michael@0 196 // There is NO REASON we should ever get here. This is POST reading
michael@0 197 // of the config file.
michael@0 198 return NS_ERROR_FAILURE;
michael@0 199
michael@0 200
michael@0 201 rv = prefBranch->GetCharPref("general.config.vendor",
michael@0 202 getter_Copies(lockVendor));
michael@0 203 // If vendor is not nullptr, do this check
michael@0 204 if (NS_SUCCEEDED(rv)) {
michael@0 205
michael@0 206 fileNameLen = strlen(lockFileName);
michael@0 207
michael@0 208 // lockVendor and lockFileName should be the same with the addtion of
michael@0 209 // .cfg to the filename by checking this post reading of the cfg file
michael@0 210 // this value can be set within the cfg file adding a level of security.
michael@0 211
michael@0 212 if (PL_strncmp(lockFileName, lockVendor, fileNameLen - 4) != 0)
michael@0 213 return NS_ERROR_FAILURE;
michael@0 214 }
michael@0 215
michael@0 216 // get the value of the autoconfig url
michael@0 217 nsXPIDLCString urlName;
michael@0 218 rv = prefBranch->GetCharPref("autoadmin.global_config_url",
michael@0 219 getter_Copies(urlName));
michael@0 220 if (NS_SUCCEEDED(rv) && !urlName.IsEmpty()) {
michael@0 221
michael@0 222 // Instantiating nsAutoConfig object if the pref is present
michael@0 223 mAutoConfig = do_CreateInstance(NS_AUTOCONFIG_CONTRACTID, &rv);
michael@0 224 if (NS_FAILED(rv))
michael@0 225 return NS_ERROR_OUT_OF_MEMORY;
michael@0 226
michael@0 227 rv = mAutoConfig->SetConfigURL(urlName);
michael@0 228 if (NS_FAILED(rv))
michael@0 229 return NS_ERROR_FAILURE;
michael@0 230
michael@0 231 }
michael@0 232
michael@0 233 return NS_OK;
michael@0 234 } // ReadConfigFile
michael@0 235
michael@0 236
michael@0 237 nsresult nsReadConfig::openAndEvaluateJSFile(const char *aFileName, int32_t obscureValue,
michael@0 238 bool isEncoded,
michael@0 239 bool isBinDir)
michael@0 240 {
michael@0 241 nsresult rv;
michael@0 242
michael@0 243 nsCOMPtr<nsIInputStream> inStr;
michael@0 244 if (isBinDir) {
michael@0 245 nsCOMPtr<nsIFile> jsFile;
michael@0 246 rv = NS_GetSpecialDirectory(XRE_EXECUTABLE_FILE,
michael@0 247 getter_AddRefs(jsFile));
michael@0 248 if (NS_FAILED(rv))
michael@0 249 return rv;
michael@0 250
michael@0 251 rv = jsFile->SetNativeLeafName(nsDependentCString(aFileName));
michael@0 252 if (NS_FAILED(rv))
michael@0 253 return rv;
michael@0 254
michael@0 255 rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile);
michael@0 256 if (NS_FAILED(rv))
michael@0 257 return rv;
michael@0 258
michael@0 259 } else {
michael@0 260 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
michael@0 261 if (NS_FAILED(rv))
michael@0 262 return rv;
michael@0 263
michael@0 264 nsAutoCString location("resource://gre/defaults/autoconfig/");
michael@0 265 location += aFileName;
michael@0 266
michael@0 267 nsCOMPtr<nsIURI> uri;
michael@0 268 rv = ioService->NewURI(location, nullptr, nullptr, getter_AddRefs(uri));
michael@0 269 if (NS_FAILED(rv))
michael@0 270 return rv;
michael@0 271
michael@0 272 nsCOMPtr<nsIChannel> channel;
michael@0 273 rv = ioService->NewChannelFromURI(uri, getter_AddRefs(channel));
michael@0 274 if (NS_FAILED(rv))
michael@0 275 return rv;
michael@0 276
michael@0 277 rv = channel->Open(getter_AddRefs(inStr));
michael@0 278 if (NS_FAILED(rv))
michael@0 279 return rv;
michael@0 280 }
michael@0 281
michael@0 282 uint64_t fs64;
michael@0 283 uint32_t amt = 0;
michael@0 284 rv = inStr->Available(&fs64);
michael@0 285 if (NS_FAILED(rv))
michael@0 286 return rv;
michael@0 287 // PR_Malloc dones't support over 4GB
michael@0 288 if (fs64 > UINT32_MAX)
michael@0 289 return NS_ERROR_FILE_TOO_BIG;
michael@0 290 uint32_t fs = (uint32_t)fs64;
michael@0 291
michael@0 292 char *buf = (char *)PR_Malloc(fs * sizeof(char));
michael@0 293 if (!buf)
michael@0 294 return NS_ERROR_OUT_OF_MEMORY;
michael@0 295
michael@0 296 rv = inStr->Read(buf, (uint32_t)fs, &amt);
michael@0 297 NS_ASSERTION((amt == fs), "failed to read the entire configuration file!!");
michael@0 298 if (NS_SUCCEEDED(rv)) {
michael@0 299 if (obscureValue > 0) {
michael@0 300
michael@0 301 // Unobscure file by subtracting some value from every char.
michael@0 302 for (uint32_t i = 0; i < amt; i++)
michael@0 303 buf[i] -= obscureValue;
michael@0 304 }
michael@0 305 rv = EvaluateAdminConfigScript(buf, amt, aFileName,
michael@0 306 false, true,
michael@0 307 isEncoded ? true:false);
michael@0 308 }
michael@0 309 inStr->Close();
michael@0 310 PR_Free(buf);
michael@0 311
michael@0 312 return rv;
michael@0 313 }

mercurial