Add security controls to all plugins, get plugins build for all tier-1
platforms.

Patch by: jat
Review by: amitmanjhi, jaimeyap


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6085 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/xpcom/Preferences.cpp b/plugins/xpcom/Preferences.cpp
new file mode 100644
index 0000000..0951711
--- /dev/null
+++ b/plugins/xpcom/Preferences.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include "Preferences.h"
+#include "Debug.h"
+#include "AllowedConnections.h"
+
+#include "nsCOMPtr.h"
+#include "nsStringAPI.h"
+#include "nsISupportsImpl.h"
+#include "nsIObserver.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefBranch2.h"
+#include "nsServiceManagerUtils.h"
+
+#define DMP_PREFS_PREFIX "gwt-dmp."
+#define DMP_ACCESS_LIST "accessList"
+
+NS_IMPL_ADDREF(Preferences)
+NS_IMPL_RELEASE(Preferences)
+NS_IMPL_QUERY_INTERFACE1(Preferences, nsIObserver)
+
+Preferences::Preferences() {
+  nsCOMPtr<nsIPrefService> prefService = do_GetService(
+      NS_PREFSERVICE_CONTRACTID);
+  if (!prefService) {
+    Debug::log(Debug::Error) << "Unable to get preference service" << Debug::flush;
+    return;
+  }
+  nsCOMPtr<nsIPrefBranch> branch;
+  prefService->GetBranch(DMP_PREFS_PREFIX, getter_AddRefs(branch));
+  if (!branch) {
+    Debug::log(Debug::Error) << "Unable to get gwt-dmp. preference branch"
+        << Debug::flush;
+    return;
+  }
+  prefs = do_QueryInterface(branch);
+  if (!prefs) {
+    Debug::log(Debug::Error) << "Unable to get nsIPrefBranch2" << Debug::flush;
+    return;
+  }
+  prefs->AddObserver(DMP_ACCESS_LIST, this, PR_FALSE);
+  nsCString prefValue;
+  if (branch->GetCharPref(DMP_ACCESS_LIST, getter_Copies(prefValue)) == NS_OK) {
+    loadAccessList(prefValue.get());
+  }
+}
+
+// implements nsIObserver
+NS_IMETHODIMP
+Preferences::Observe(nsISupports *aSubject, const char* aTopic,
+    const PRUnichar *aData) {
+  nsresult rv = NS_OK;
+  Debug::log(Debug::Spam) << "Preferences::Observe(subject="
+      << aSubject << ", topic=" << aTopic << ", data=" << aData << Debug::flush;
+  if (strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  // TODO(jat): check preference name in aData if we ever add another one
+  nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject, &rv));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCString prefValue;
+  if (prefs->GetCharPref(DMP_ACCESS_LIST, getter_Copies(prefValue)) == NS_OK) {
+    loadAccessList(prefValue.get());
+  }
+  return NS_OK;
+}
+
+void Preferences::addNewRule(const std::string& pattern, bool exclude) {
+  nsCString prefValue;
+  if (prefs->GetCharPref(DMP_ACCESS_LIST, getter_Copies(prefValue)) != NS_OK) {
+    Debug::log(Debug::Error) << "Unable to retrieve access list preference"
+        << Debug::flush;
+    return;
+  }
+  // TODO(jat): see if the same rule already exists
+  std::string pref(prefValue.get());
+  if (pref.length() > 0) {
+    pref += ',';
+  }
+  if (exclude) {
+    pref += '!';
+  }
+  pref += pattern;
+  if (prefs->SetCharPref(DMP_ACCESS_LIST, pref.c_str()) != NS_OK) {
+    Debug::log(Debug::Error) << "Unable to save modified access list preference"
+        << Debug::flush;
+    return;
+  }
+}
+
+void Preferences::loadAccessList(const char* prefValue) {
+  if (!prefValue) {
+    return;
+  }
+  Debug::log(Debug::Spam) << "loadFromAccessList(prefValue=" << prefValue << ")"
+      << Debug::flush;
+  AllowedConnections::initFromAccessList(prefValue);
+}
+
+Preferences::~Preferences() {
+  if (prefs) {
+    prefs->RemoveObserver(DMP_ACCESS_LIST, this);
+  }
+}