--- /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