gecko-lockdown.patch
changeset 24 ca988be0905b
child 65 6a711ebb385d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gecko-lockdown.patch	Sat Dec 19 21:51:16 2009 +0100
@@ -0,0 +1,422 @@
+From: various contributors
+Subject: lockdown hooks for Gecko
+
+diff --git a/extensions/cookie/nsCookiePermission.cpp b/extensions/cookie/nsCookiePermission.cpp
+--- a/extensions/cookie/nsCookiePermission.cpp
++++ b/extensions/cookie/nsCookiePermission.cpp
+@@ -1,10 +1,10 @@
+ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+-/* vim:ts=2:sw=2:et: */
++/* vim: set ts=2 sw=2 et: */
+ /* ***** BEGIN LICENSE BLOCK *****
+  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+  *
+  * The contents of this file are subject to the Mozilla Public License Version
+  * 1.1 (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.mozilla.org/MPL/
+  *
+@@ -81,16 +81,17 @@ static const PRBool kDefaultPolicy = PR_
+ static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
+ static const char kCookiesLifetimeDays[] = "network.cookie.lifetime.days";
+ static const char kCookiesAlwaysAcceptSession[] = "network.cookie.alwaysAcceptSessionCookies";
+ 
+ static const char kCookiesPrefsMigrated[] = "network.cookie.prefsMigrated";
+ // obsolete pref names for migration
+ static const char kCookiesLifetimeEnabled[] = "network.cookie.lifetime.enabled";
+ static const char kCookiesLifetimeBehavior[] = "network.cookie.lifetime.behavior";
++static const char kCookiesHonorExceptions[] = "network.cookie.honorExceptions";
+ static const char kCookiesAskPermission[] = "network.cookie.warnAboutCookies";
+ 
+ static const char kPermissionType[] = "cookie";
+ 
+ #ifdef MOZ_MAIL_NEWS
+ // returns PR_TRUE if URI appears to be the URI of a mailnews protocol
+ // XXXbz this should be a protocol flag, not a scheme list, dammit!
+ static PRBool
+@@ -120,16 +121,17 @@ nsCookiePermission::Init()
+ 
+   // failure to access the pref service is non-fatal...
+   nsCOMPtr<nsIPrefBranch2> prefBranch =
+       do_GetService(NS_PREFSERVICE_CONTRACTID);
+   if (prefBranch) {
+     prefBranch->AddObserver(kCookiesLifetimePolicy, this, PR_FALSE);
+     prefBranch->AddObserver(kCookiesLifetimeDays, this, PR_FALSE);
+     prefBranch->AddObserver(kCookiesAlwaysAcceptSession, this, PR_FALSE);
++    prefBranch->AddObserver(kCookiesHonorExceptions, this, PR_FALSE);
+     PrefChanged(prefBranch, nsnull);
+ 
+     // migration code for original cookie prefs
+     PRBool migrated;
+     rv = prefBranch->GetBoolPref(kCookiesPrefsMigrated, &migrated);
+     if (NS_FAILED(rv) || !migrated) {
+       PRBool warnAboutCookies = PR_FALSE;
+       prefBranch->GetBoolPref(kCookiesAskPermission, &warnAboutCookies);
+@@ -173,16 +175,20 @@ nsCookiePermission::PrefChanged(nsIPrefB
+   if (PREF_CHANGED(kCookiesLifetimeDays) &&
+       NS_SUCCEEDED(aPrefBranch->GetIntPref(kCookiesLifetimeDays, &val)))
+     // save cookie lifetime in seconds instead of days
+     mCookiesLifetimeSec = val * 24 * 60 * 60;
+ 
+   if (PREF_CHANGED(kCookiesAlwaysAcceptSession) &&
+       NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesAlwaysAcceptSession, &val)))
+     mCookiesAlwaysAcceptSession = val;
++
++  if (PREF_CHANGED(kCookiesHonorExceptions) &&
++      NS_SUCCEEDED(aPrefBranch->GetBoolPref(kCookiesHonorExceptions, &val)))
++    mCookiesHonorExceptions = val;
+ }
+ 
+ NS_IMETHODIMP
+ nsCookiePermission::SetAccess(nsIURI         *aURI,
+                               nsCookieAccess  aAccess)
+ {
+   //
+   // NOTE: nsCookieAccess values conveniently match up with
+@@ -202,16 +208,21 @@ nsCookiePermission::CanAccess(nsIURI    
+   // it.
+   if (IsFromMailNews(aURI)) {
+     *aResult = ACCESS_DENY;
+     return NS_OK;
+   }
+ #endif // MOZ_MAIL_NEWS
+   
+   // finally, check with permission manager...
++  if (!mCookiesHonorExceptions) {
++    *aResult = ACCESS_DEFAULT;
++    return NS_OK;
++  }
++
+   nsresult rv = mPermMgr->TestPermission(aURI, kPermissionType, (PRUint32 *) aResult);
+   if (NS_SUCCEEDED(rv)) {
+     switch (*aResult) {
+     // if we have one of the publicly-available values, just return it
+     case nsIPermissionManager::UNKNOWN_ACTION: // ACCESS_DEFAULT
+     case nsIPermissionManager::ALLOW_ACTION:   // ACCESS_ALLOW
+     case nsIPermissionManager::DENY_ACTION:    // ACCESS_DENY
+       break;
+diff --git a/extensions/cookie/nsCookiePermission.h b/extensions/cookie/nsCookiePermission.h
+--- a/extensions/cookie/nsCookiePermission.h
++++ b/extensions/cookie/nsCookiePermission.h
+@@ -54,30 +54,32 @@ public:
+   NS_DECL_ISUPPORTS
+   NS_DECL_NSICOOKIEPERMISSION
+   NS_DECL_NSIOBSERVER
+ 
+   nsCookiePermission() 
+     : mCookiesLifetimeSec(LL_MAXINT)
+     , mCookiesLifetimePolicy(0) // ACCEPT_NORMALLY
+     , mCookiesAlwaysAcceptSession(PR_FALSE)
++    , mCookiesHonorExceptions(PR_TRUE)
+     {}
+   virtual ~nsCookiePermission() {}
+ 
+   nsresult Init();
+   void     PrefChanged(nsIPrefBranch *, const char *);
+ 
+ private:
+   PRBool InPrivateBrowsing();
+ 
+   nsCOMPtr<nsIPermissionManager> mPermMgr;
+   nsCOMPtr<nsIPrivateBrowsingService> mPBService;
+ 
+   PRInt64      mCookiesLifetimeSec;            // lifetime limit specified in seconds
+   PRUint8      mCookiesLifetimePolicy;         // pref for how long cookies are stored
+   PRPackedBool mCookiesAlwaysAcceptSession;    // don't prompt for session cookies
++  PRPackedBool mCookiesHonorExceptions;
+ };
+ 
+ // {EF565D0A-AB9A-4A13-9160-0644CDFD859A}
+ #define NS_COOKIEPERMISSION_CID \
+  {0xEF565D0A, 0xAB9A, 0x4A13, {0x91, 0x60, 0x06, 0x44, 0xcd, 0xfd, 0x85, 0x9a }}
+ 
+ #endif
+diff --git a/extensions/permissions/nsContentBlocker.cpp b/extensions/permissions/nsContentBlocker.cpp
+--- a/extensions/permissions/nsContentBlocker.cpp
++++ b/extensions/permissions/nsContentBlocker.cpp
+@@ -71,32 +71,38 @@ static const char *kTypeString[NUMBER_OF
+ NS_IMPL_ISUPPORTS3(nsContentBlocker, 
+                    nsIContentPolicy,
+                    nsIObserver,
+                    nsSupportsWeakReference)
+ 
+ nsContentBlocker::nsContentBlocker()
+ {
+   memset(mBehaviorPref, BEHAVIOR_ACCEPT, NUMBER_OF_TYPES);
++  memset(mHonorExceptions, PR_TRUE, NUMBER_OF_TYPES);
+ }
+ 
+ nsresult
+ nsContentBlocker::Init()
+ {
+   nsresult rv;
+   mPermissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   nsCOMPtr<nsIPrefService> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   nsCOMPtr<nsIPrefBranch> prefBranch;
+   rv = prefService->GetBranch("permissions.default.", getter_AddRefs(prefBranch));
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
++  nsCOMPtr<nsIPrefBranch> honorExceptionsPrefBranch;
++  rv = prefService->GetBranch("permissions.honorExceptions.",
++                              getter_AddRefs(honorExceptionsPrefBranch));
++  NS_ENSURE_SUCCESS(rv, rv);
++
+   // Migrate old image blocker pref
+   nsCOMPtr<nsIPrefBranch> oldPrefBranch;
+   oldPrefBranch = do_QueryInterface(prefService);
+   PRInt32 oldPref;
+   rv = oldPrefBranch->GetIntPref("network.image.imageBehavior", &oldPref);
+   if (NS_SUCCEEDED(rv) && oldPref) {
+     PRInt32 newPref;
+     switch (oldPref) {
+@@ -116,39 +122,49 @@ nsContentBlocker::Init()
+ 
+ 
+   // The branch is not a copy of the prefservice, but a new object, because
+   // it is a non-default branch. Adding obeservers to it will only work if
+   // we make sure that the object doesn't die. So, keep a reference to it.
+   mPrefBranchInternal = do_QueryInterface(prefBranch, &rv);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
++  mHonorExceptionsPrefBranchInternal =
++    do_QueryInterface(honorExceptionsPrefBranch, &rv);
++  NS_ENSURE_SUCCESS(rv, rv);
++
+   rv = mPrefBranchInternal->AddObserver("", this, PR_TRUE);
+-  PrefChanged(prefBranch, nsnull);
++  NS_ENSURE_SUCCESS(rv, rv);
++
++  rv = mHonorExceptionsPrefBranchInternal->AddObserver("", this, PR_TRUE);
++  PrefChanged(nsnull);
+ 
+   return rv;
+ }
+ 
+ #undef  LIMIT
+ #define LIMIT(x, low, high, default) ((x) >= (low) && (x) <= (high) ? (x) : (default))
+ 
+ void
+-nsContentBlocker::PrefChanged(nsIPrefBranch *aPrefBranch,
+-                              const char    *aPref)
++nsContentBlocker::PrefChanged(const char *aPref)
+ {
+-  PRInt32 val;
+-
+-#define PREF_CHANGED(_P) (!aPref || !strcmp(aPref, _P))
+-
+-  for(PRUint32 i = 0; i < NUMBER_OF_TYPES; ++i) {
+-    if (PREF_CHANGED(kTypeString[i]) &&
+-        NS_SUCCEEDED(aPrefBranch->GetIntPref(kTypeString[i], &val)))
+-      mBehaviorPref[i] = LIMIT(val, 1, 3, 1);
++  for (PRUint32 i = 0; i < NUMBER_OF_TYPES; ++i) {
++    if (!aPref || !strcmp(kTypeString[i], aPref)) {
++      PRInt32 val;
++      PRBool b;
++      if (mPrefBranchInternal &&
++          NS_SUCCEEDED(mPrefBranchInternal->GetIntPref(kTypeString[i], &val))) {
++        mBehaviorPref[i] = LIMIT(val, 1, 3, 1);
++      }
++      if (mHonorExceptionsPrefBranchInternal &&
++          NS_SUCCEEDED(mHonorExceptionsPrefBranchInternal->GetBoolPref(kTypeString[i], &b))) {
++        mHonorExceptions[i] = b;
++      }
++    }
+   }
+-
+ }
+ 
+ // nsIContentPolicy Implementation
+ NS_IMETHODIMP 
+ nsContentBlocker::ShouldLoad(PRUint32          aContentType,
+                              nsIURI           *aContentLocation,
+                              nsIURI           *aRequestingLocation,
+                              nsISupports      *aRequestingContext,
+@@ -264,21 +280,23 @@ nsContentBlocker::TestPermission(nsIURI 
+   // This default will also get used if there is an unknown value in the
+   // permission list, or if the permission manager returns unknown values.
+   *aPermission = PR_TRUE;
+ 
+   // check the permission list first; if we find an entry, it overrides
+   // default prefs.
+   // Don't forget the aContentType ranges from 1..8, while the
+   // array is indexed 0..7
+-  PRUint32 permission;
+-  nsresult rv = mPermissionManager->TestPermission(aCurrentURI, 
+-                                                   kTypeString[aContentType - 1],
+-                                                   &permission);
+-  NS_ENSURE_SUCCESS(rv, rv);
++  PRUint32 permission = 0;
++  if (mHonorExceptions[aContentType - 1]) {
++    nsresult rv = mPermissionManager->TestPermission(aCurrentURI,
++                                                     kTypeString[aContentType - 1],
++                                                     &permission);
++    NS_ENSURE_SUCCESS(rv, rv);
++  }
+ 
+   // If there is nothing on the list, use the default.
+   if (!permission) {
+     permission = mBehaviorPref[aContentType - 1];
+     *aFromPrefs = PR_TRUE;
+   }
+ 
+   // Use the fact that the nsIPermissionManager values map to 
+@@ -294,17 +312,17 @@ nsContentBlocker::TestPermission(nsIURI 
+   case BEHAVIOR_NOFOREIGN:
+     // Third party checking
+ 
+     // Need a requesting uri for third party checks to work.
+     if (!aFirstURI)
+       return NS_OK;
+ 
+     PRBool trustedSource = PR_FALSE;
+-    rv = aFirstURI->SchemeIs("chrome", &trustedSource);
++    nsresult rv = aFirstURI->SchemeIs("chrome", &trustedSource);
+     NS_ENSURE_SUCCESS(rv,rv);
+     if (!trustedSource) {
+       rv = aFirstURI->SchemeIs("resource", &trustedSource);
+       NS_ENSURE_SUCCESS(rv,rv);
+     }
+     if (trustedSource)
+       return NS_OK;
+ 
+@@ -360,12 +378,11 @@ nsContentBlocker::TestPermission(nsIURI 
+ NS_IMETHODIMP
+ nsContentBlocker::Observe(nsISupports     *aSubject,
+                           const char      *aTopic,
+                           const PRUnichar *aData)
+ {
+   NS_ASSERTION(!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic),
+                "unexpected topic - we only deal with pref changes!");
+ 
+-  if (mPrefBranchInternal)
+-    PrefChanged(mPrefBranchInternal, NS_LossyConvertUTF16toASCII(aData).get());
++  PrefChanged(NS_LossyConvertUTF16toASCII(aData).get());
+   return NS_OK;
+ }
+diff --git a/extensions/permissions/nsContentBlocker.h b/extensions/permissions/nsContentBlocker.h
+--- a/extensions/permissions/nsContentBlocker.h
++++ b/extensions/permissions/nsContentBlocker.h
+@@ -61,26 +61,28 @@ public:
+   NS_DECL_NSIOBSERVER
+ 
+   nsContentBlocker();
+   nsresult Init();
+ 
+ private:
+   ~nsContentBlocker() {}
+ 
+-  void PrefChanged(nsIPrefBranch *, const char *);
++  void PrefChanged(const char *);
+   nsresult TestPermission(nsIURI *aCurrentURI,
+                           nsIURI *aFirstURI,
+                           PRInt32 aContentType,
+                           PRBool *aPermission,
+                           PRBool *aFromPrefs);
+ 
+   nsCOMPtr<nsIPermissionManager> mPermissionManager;
+   nsCOMPtr<nsIPrefBranch2> mPrefBranchInternal;
++  nsCOMPtr<nsIPrefBranch2> mHonorExceptionsPrefBranchInternal;
+   PRUint8 mBehaviorPref[NUMBER_OF_TYPES];
++  PRPackedBool mHonorExceptions[NUMBER_OF_TYPES];
+ };
+ 
+ #define NS_CONTENTBLOCKER_CID \
+ { 0x4ca6b67b, 0x5cc7, 0x4e71, \
+   { 0xa9, 0x8a, 0x97, 0xaf, 0x1c, 0x13, 0x48, 0x62 } }
+ 
+ #define NS_CONTENTBLOCKER_CONTRACTID "@mozilla.org/permissions/contentblocker;1"
+ 
+diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js
+--- a/modules/libpref/src/init/all.js
++++ b/modules/libpref/src/init/all.js
+@@ -842,16 +842,17 @@ pref("network.automatic-ntlm-auth.truste
+ // response to a NTLM challenge.  By default, this is disabled since servers
+ // should almost never need the LM hash, and the LM hash is what makes NTLM
+ // authentication less secure.  See bug 250691 for further details.
+ // NOTE: automatic-ntlm-auth which leverages the OS-provided NTLM
+ //       implementation will not be affected by this preference.
+ pref("network.ntlm.send-lm-response", false);
+ 
+ pref("permissions.default.image",           1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
++pref("permissions.honorExceptions.image",   true);
+ 
+ #ifndef XP_MACOSX
+ #ifdef XP_UNIX
+ pref("network.proxy.type",                  5);
+ #else
+ pref("network.proxy.type",                  0);
+ #endif
+ #else
+@@ -869,16 +870,17 @@ pref("network.proxy.ssl_port",          
+ pref("network.proxy.socks",                 "");
+ pref("network.proxy.socks_port",            0);
+ pref("network.proxy.socks_version",         5);
+ pref("network.proxy.socks_remote_dns",      false);
+ pref("network.proxy.no_proxies_on",         "localhost, 127.0.0.1");
+ pref("network.proxy.failover_timeout",      1800); // 30 minutes
+ pref("network.online",                      true); //online/offline
+ pref("network.cookie.cookieBehavior",       0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
++pref("network.cookie.honorExceptions",      true);
+ pref("network.cookie.lifetimePolicy",       0); // accept normally, 1-askBeforeAccepting, 2-acceptForSession,3-acceptForNDays
+ pref("network.cookie.alwaysAcceptSessionCookies", false);
+ pref("network.cookie.prefsMigrated",        false);
+ pref("network.cookie.lifetime.days",        90);
+ 
+ // The PAC file to load.  Ignored unless network.proxy.type is 2.
+ pref("network.proxy.autoconfig_url", "");
+ 
+diff --git a/xpinstall/src/nsXPInstallManager.cpp b/xpinstall/src/nsXPInstallManager.cpp
+--- a/xpinstall/src/nsXPInstallManager.cpp
++++ b/xpinstall/src/nsXPInstallManager.cpp
+@@ -300,36 +300,46 @@ nsXPInstallManager::InitManagerInternal(
+             packageList[j++] = item->GetSafeURLString();
+             packageList[j++] = item->mIconURL.get();
+             packageList[j++] = item->mCertName.get();
+         }
+ 
+         //-----------------------------------------------------
+         // Get permission to install
+         //-----------------------------------------------------
++        nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ 
+ #ifdef ENABLE_SKIN_SIMPLE_INSTALLATION_UI
+         if ( mChromeType == CHROME_SKIN )
+         {
+             // We may want to enable the simple installation UI once
+             // bug 343037 is fixed
+ 
+             // skins get a simpler/friendlier dialog
+             // XXX currently not embeddable
+-            OKtoInstall = ConfirmChromeInstall( mParentWindow, packageList );
++            PRBool themesDisabled = PR_FALSE;
++            if (pref)
++              pref->GetBoolPref("config.lockdown.disable_themes", &themesDisabled);
++            OKtoInstall = !themesDisabled &&
++              ConfirmChromeInstall( mParentWindow, packageList );
+         }
+         else
+         {
+ #endif
++          PRBool extensionsDisabled = PR_FALSE;
++          if (pref)
++            pref->GetBoolPref("config.lockdown.disable_extensions", &extensionsDisabled);
++          if (!extensionsDisabled) {
+             rv = dlgSvc->ConfirmInstall( mParentWindow,
+                                          packageList,
+                                          numStrings,
+                                          &OKtoInstall );
+             if (NS_FAILED(rv))
+                 OKtoInstall = PR_FALSE;
++          }
+ #ifdef ENABLE_SKIN_SIMPLE_INSTALLATION_UI
+         }
+ #endif
+ 
+         if (OKtoInstall)
+         {
+             //-----------------------------------------------------
+             // Open the progress dialog