Bug 897516 - Implement a separate cookie jar for safebrowsing - cookie separation part. r=mmc
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Mon, 19 Aug 2013 12:31:24 -0700
changeset 149546 61817a92297cb5ee0c73f956fa2f7761bc34b4e6
parent 149545 5dd345031f7e5f408fd7d0590b77cfe7f4e79438
child 149547 51616efd18394ac41f2f046ec003a028f938eada
push id34588
push userryanvm@gmail.com
push dateTue, 01 Oct 2013 21:45:31 +0000
treeherdermozilla-inbound@f8787963a438 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmmc
bugs897516
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 897516 - Implement a separate cookie jar for safebrowsing - cookie separation part. r=mmc
caps/idl/nsIScriptSecurityManager.idl
docshell/base/LoadContext.cpp
docshell/base/LoadContext.h
netwerk/base/public/nsNetUtil.h
toolkit/components/url-classifier/Makefile.in
toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -222,16 +222,17 @@ interface nsIScriptSecurityManager : nsI
      * passed null, and it must be the context on the top of the
      * context stack. Does *not* reference count the returned
      * principal.
      */
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
 
     const unsigned long NO_APP_ID = 0;
     const unsigned long UNKNOWN_APP_ID = 4294967295; // UINT32_MAX
+    const unsigned long SAFEBROWSING_APP_ID = 4294967294; // UINT32_MAX - 1
 
     /**
      * Returns the jar prefix for the app.
      * appId can be NO_APP_ID or a valid app id. appId should not be
      * UNKNOWN_APP_ID.
      * inMozBrowser has to be true if the app is inside a mozbrowser iframe.
      */
     AUTF8String getJarPrefix(in unsigned long appId, in boolean inMozBrowser);
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/LoadContext.h"
 
 namespace mozilla {
 
-NS_IMPL_ISUPPORTS1(LoadContext, nsILoadContext)
+NS_IMPL_ISUPPORTS2(LoadContext, nsILoadContext, nsIInterfaceRequestor)
 
 //-----------------------------------------------------------------------------
 // LoadContext::nsILoadContext
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 LoadContext::GetAssociatedWindow(nsIDOMWindow**)
 {
@@ -106,9 +106,27 @@ LoadContext::GetAppId(uint32_t* aAppId)
   MOZ_ASSERT(mIsNotNull);
 
   NS_ENSURE_ARG_POINTER(aAppId);
 
   *aAppId = mAppId;
   return NS_OK;
 }
 
+//-----------------------------------------------------------------------------
+// LoadContext::nsIInterfaceRequestor
+//-----------------------------------------------------------------------------
+NS_IMETHODIMP
+LoadContext::GetInterface(const nsIID &aIID, void **aResult)
+{
+  NS_ENSURE_ARG_POINTER(aResult);
+  *aResult = nullptr;
+
+  if (aIID.Equals(NS_GET_IID(nsILoadContext))) {
+    *aResult = static_cast<nsILoadContext*>(this);
+    NS_ADDREF_THIS();
+    return NS_OK;
+  }
+
+  return NS_NOINTERFACE;
+}
+
 } // namespace mozilla
--- a/docshell/base/LoadContext.h
+++ b/docshell/base/LoadContext.h
@@ -6,52 +6,70 @@
 
 #ifndef LoadContext_h
 #define LoadContext_h
 
 #include "SerializedLoadContext.h"
 #include "mozilla/Attributes.h"
 #include "nsIWeakReferenceUtils.h"
 #include "mozilla/dom/Element.h"
+#include "nsIInterfaceRequestor.h"
 
 class mozIApplication;
 
 namespace mozilla {
 
 /**
  * Class that provides nsILoadContext info in Parent process.  Typically copied
  * from Child via SerializedLoadContext.
  *
  * Note: this is not the "normal" or "original" nsILoadContext.  That is
  * typically provided by nsDocShell.  This is only used when the original
  * docshell is in a different process and we need to copy certain values from
  * it.
+ *
+ * Note: we also generate a new nsILoadContext using LoadContext(uint32_t aAppId)
+ * to separate the safebrowsing cookie.
  */
 
-class LoadContext MOZ_FINAL : public nsILoadContext
+class LoadContext MOZ_FINAL : public nsILoadContext,
+                              public nsIInterfaceRequestor
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSILOADCONTEXT
+  NS_DECL_NSIINTERFACEREQUESTOR
 
   // AppId/inBrowser arguments override those in SerializedLoadContext provided
   // by child process.
   LoadContext(const IPC::SerializedLoadContext& aToCopy,
               dom::Element* aTopFrameElement,
               uint32_t aAppId, bool aInBrowser)
     : mTopFrameElement(do_GetWeakReference(aTopFrameElement))
     , mAppId(aAppId)
     , mIsContent(aToCopy.mIsContent)
     , mUsePrivateBrowsing(aToCopy.mUsePrivateBrowsing)
     , mIsInBrowserElement(aInBrowser)
 #ifdef DEBUG
     , mIsNotNull(aToCopy.mIsNotNull)
 #endif
   {}
 
+  // Constructor taking reserved appId for the safebrowsing cookie.
+  LoadContext(uint32_t aAppId)
+    : mTopFrameElement(nullptr)
+    , mAppId(aAppId)
+    , mIsContent(false)
+    , mUsePrivateBrowsing(false)
+    , mIsInBrowserElement(false)
+#ifdef DEBUG
+    , mIsNotNull(true)
+#endif
+  {}
+
 private:
   nsWeakPtr     mTopFrameElement;
   uint32_t      mAppId;
   bool          mIsContent;
   bool          mUsePrivateBrowsing;
   bool          mIsInBrowserElement;
 #ifdef DEBUG
   bool          mIsNotNull;
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -1349,16 +1349,18 @@ NS_UsePrivateBrowsing(nsIChannel *channe
     NS_QueryNotificationCallbacks(channel, loadContext);
     return loadContext && loadContext->UsePrivateBrowsing();
 }
 
 // Constants duplicated from nsIScriptSecurityManager so we avoid having necko
 // know about script security manager.
 #define NECKO_NO_APP_ID 0
 #define NECKO_UNKNOWN_APP_ID UINT32_MAX
+// special app id reserved for separating the safebrowsing cookie
+#define NECKO_SAFEBROWSING_APP_ID UINT32_MAX - 1
 
 /**
  * Gets AppId and isInBrowserElement from channel's nsILoadContext.
  * Returns false if error or channel's callbacks don't implement nsILoadContext.
  */
 inline bool
 NS_GetAppInfo(nsIChannel *aChannel, uint32_t *aAppID, bool *aIsInBrowserElement)
 {
--- a/toolkit/components/url-classifier/Makefile.in
+++ b/toolkit/components/url-classifier/Makefile.in
@@ -1,9 +1,10 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../build \
+  -I$(topsrcdir)/ipc/chromium/src \
   $(SQLITE_CFLAGS) \
   $(NULL)
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
@@ -10,19 +10,23 @@
 #include "nsIUploadChannel.h"
 #include "nsIURI.h"
 #include "nsIUrlClassifierDBService.h"
 #include "nsStreamUtils.h"
 #include "nsStringStream.h"
 #include "nsToolkitCompsCID.h"
 #include "nsUrlClassifierStreamUpdater.h"
 #include "prlog.h"
+#include "nsIInterfaceRequestor.h"
+#include "mozilla/LoadContext.h"
 
 static const char* gQuitApplicationMessage = "quit-application";
 
+#undef LOG
+
 // NSPR_LOG_MODULES=UrlClassifierStreamUpdater:5
 #if defined(PR_LOGGING)
 static const PRLogModuleInfo *gUrlClassifierStreamUpdaterLog = nullptr;
 #define LOG(args) PR_LOG(gUrlClassifierStreamUpdaterLog, PR_LOG_DEBUG, args)
 #else
 #define LOG(args)
 #endif
 
@@ -119,16 +123,24 @@ nsUrlClassifierStreamUpdater::FetchUpdat
   // purposes.
   // This is only used for testing and should be deleted.
   bool match;
   if ((NS_SUCCEEDED(aUpdateUrl->SchemeIs("file", &match)) && match) ||
       (NS_SUCCEEDED(aUpdateUrl->SchemeIs("data", &match)) && match)) {
     mChannel->SetContentType(NS_LITERAL_CSTRING("application/vnd.google.safebrowsing-update"));
   }
 
+   // Create a custom LoadContext for SafeBrowsing, so we can use callbacks on
+   // the channel to query the appId which allows separation of safebrowsing
+   // cookies in a separate jar.
+  nsCOMPtr<nsIInterfaceRequestor> sbContext =
+    new mozilla::LoadContext(NECKO_SAFEBROWSING_APP_ID);
+  rv = mChannel->SetNotificationCallbacks(sbContext);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // Make the request
   rv = mChannel->AsyncOpen(this, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mStreamTable = aStreamTable;
   mServerMAC = aServerMAC;
 
   return NS_OK;