From c3c1d5555672c8348feb8f545aad7241a2f81a0a Mon Sep 17 00:00:00 2001
From: Mike Perry <mikeperry-git@torproject.org>
Date: Tue, 4 Dec 2012 15:45:59 -0800
Subject: [PATCH 02/41] Make Permissions Manager memory-only

This patch exposes a pref 'permissions.memory_only' that properly isolates the
permissions manager to memory, which is responsible for all user specified
site permissions, as well as stored STS policy.

The pref does successfully clear the permissions manager memory if toggled. It
does not need to be set in prefs.js, and can be handled by Torbutton.

https://trac.torproject.org/projects/tor/ticket/2950
---
 extensions/cookie/nsPermissionManager.cpp | 34 ++++++++++++++++++++++++++++---
 1 file changed, 31 insertions(+), 3 deletions(-)

diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp
index 9c50080..4102408 100644
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -24,6 +24,10 @@
 #include "nsIPrincipal.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
+#include "nsCOMPtr.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefBranch2.h"
 
 static nsPermissionManager *gPermissionManager = nullptr;
 
@@ -301,6 +305,11 @@ nsPermissionManager::Init()
     mObserverService->AddObserver(this, "profile-do-change", true);
   }
 
+  nsCOMPtr<nsIPrefBranch2> pbi = do_GetService(NS_PREFSERVICE_CONTRACTID);
+  if (pbi) {
+    pbi->AddObserver("permissions.", this, PR_FALSE);
+  }
+
   if (IsChildProcess()) {
     // Get the permissions from the parent process
     InfallibleTArray<IPC::Permission> perms;
@@ -356,8 +365,18 @@ nsPermissionManager::InitDB(bool aRemoveFile)
   if (!storage)
     return NS_ERROR_UNEXPECTED;
 
+  bool memory_db = false;
+  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+  if (prefs) {
+    prefs->GetBoolPref("permissions.memory_only", &memory_db); 
+  }
+
   // cache a connection to the hosts database
-  rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
+  if (memory_db) {
+    rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
+  } else {
+    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
+  }
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool ready;
@@ -367,7 +386,11 @@ nsPermissionManager::InitDB(bool aRemoveFile)
     rv = permissionsFile->Remove(false);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
+    if (memory_db) {
+      rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(mDBConn));
+    } else {
+      rv = storage->OpenDatabase(permissionsFile, getter_AddRefs(mDBConn));
+    }
     NS_ENSURE_SUCCESS(rv, rv);
 
     mDBConn->GetConnectionReady(&ready);
@@ -1052,7 +1075,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT
 {
   ENSURE_NOT_CHILD_PROCESS;
 
-  if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
+  if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
+    if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("permissions.memory_only").get())) {
+      // XXX: Should we remove the file? Probably not..
+      InitDB(PR_FALSE);
+    }
+  } else if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     // The profile is about to change,
     // or is going away because the application is shutting down.
     mIsShuttingDown = true;
-- 
1.8.1.2

