diff options
author | Julian Ospald <hasufell@gentoo.org> | 2012-05-12 22:24:39 +0000 |
---|---|---|
committer | Julian Ospald <hasufell@gentoo.org> | 2012-05-12 22:24:39 +0000 |
commit | 4c47257f06ae77476a61eeadcc4f30f9d1e93a97 (patch) | |
tree | 2b08c61542d0eb142d15ae730f9cee383144c70f /www-client/torbrowser | |
parent | Version bump (thanks df, bug 415633) (diff) | |
download | gentoo-2-4c47257f06ae77476a61eeadcc4f30f9d1e93a97.tar.gz gentoo-2-4c47257f06ae77476a61eeadcc4f30f9d1e93a97.tar.bz2 gentoo-2-4c47257f06ae77476a61eeadcc4f30f9d1e93a97.zip |
initial import with help from Poncho wrt #406361
(Portage version: 2.2.0_alpha104/cvs/Linux x86_64)
Diffstat (limited to 'www-client/torbrowser')
21 files changed, 2296 insertions, 0 deletions
diff --git a/www-client/torbrowser/ChangeLog b/www-client/torbrowser/ChangeLog new file mode 100644 index 000000000000..b633545bd9f3 --- /dev/null +++ b/www-client/torbrowser/ChangeLog @@ -0,0 +1,27 @@ +# ChangeLog for www-client/torbrowser +# Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2 +# $Header: /var/cvsroot/gentoo-x86/www-client/torbrowser/ChangeLog,v 1.1 2012/05/12 22:24:39 hasufell Exp $ + +*torbrowser-12.0 (12 May 2012) + + 12 May 2012; Julian Ospald <hasufell@gentoo.org> + +files/12.0/0001-Block-Components.interfaces-lookupMethod-from-conten.patch, + +files/12.0/0002-Make-Permissions-Manager-memory-only.patch, + +files/12.0/0003-Make-Intermediate-Cert-Store-memory-only.patch, + +files/12.0/0004-Add-a-string-based-cacheKey.patch, + +files/12.0/0005-Block-all-plugins-except-flash.patch, + +files/12.0/0006-Make-content-pref-service-memory-only-clearable.patch, + +files/12.0/0008-Disable-SSL-Session-ID-tracking.patch, + +files/12.0/0009-Provide-an-observer-event-to-close-persistent-connec.patch, + +files/12.0/0010-Provide-client-values-only-to-CSS-Media-Queries.patch, + +files/12.0/0011-Limit-the-number-of-fonts-per-document.patch, + +files/12.0/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch, + +files/12.0/0013-Rebrand-Firefox-to-TorBrowser.patch, + +files/12.0/0014-Make-Download-manager-memory-only.patch, + +files/12.0/0015-Add-DDG-and-StartPage-to-Omnibox.patch, + +files/12.0/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch, + +files/12.0/0017-Make-nsICacheService.EvictEntries-synchronous.patch, + +torbrowser-12.0.ebuild, +files/12.0/0018-Prevent-WebSocket-DNS-leak.patch, + +metadata.xml: + initial import with help from Poncho wrt #406361 + diff --git a/www-client/torbrowser/Manifest b/www-client/torbrowser/Manifest new file mode 100644 index 000000000000..ccc3c144ebfd --- /dev/null +++ b/www-client/torbrowser/Manifest @@ -0,0 +1,24 @@ +AUX 12.0/0001-Block-Components.interfaces-lookupMethod-from-conten.patch 2341 RMD160 ea4ac7514cf0ca108c39c74c3896e8ae77077778 SHA1 6b6040ee04f1e2bd9a40db004f430a85640c8aa4 SHA256 ed24e887fdd2eff2ab75b26845539c92d637a91134af9467358c6887ce73f071 +AUX 12.0/0002-Make-Permissions-Manager-memory-only.patch 3527 RMD160 253d26b7d9119276da139ba6a3149883ad1ce640 SHA1 b826ab180edcc46e443e6e7f078f65c9d06d8aed SHA256 97e5a0fb2ed54649c175179a419cb70e7b4f8852e58bf0f6f97a8f6bb34b3d80 +AUX 12.0/0003-Make-Intermediate-Cert-Store-memory-only.patch 1759 RMD160 33cdd2cd28492d69e29fbfa3bbcc223201f9b6d7 SHA1 0a0eb5ba2f7e47e1575140c013cdc3a184576ebd SHA256 b42004e0a69bbb15aaeccf9ac89dae64557a16b5920c469680d0eb0b490a96b9 +AUX 12.0/0004-Add-a-string-based-cacheKey.patch 2944 RMD160 9da41b30d9b004cda9b5bbb097f30eedcd3144ad SHA1 7200a289f462c266ec9309981fcde6b635255057 SHA256 ccaf8992020fb0329dc2136cfe699d2258671ab80837d8548b9c2ece79713535 +AUX 12.0/0005-Block-all-plugins-except-flash.patch 2976 RMD160 922f5052784525a5d2d39c5680895d75bc285aad SHA1 8c40d8b4832ff22f72ce29f1a3c6aeb495d7497a SHA256 e1b00f96900329d6e260bf93229a786c649723aa72e6c7e15041d3ac83582db6 +AUX 12.0/0006-Make-content-pref-service-memory-only-clearable.patch 1357 RMD160 795608796f94fb845a5970f592161371d6d1339a SHA1 7fdd734e8789ae95dabb549a248e0d3319abdd80 SHA256 ccdcbdcca90fa0ef16ff17d62df567bb47747fd2b9debd727bceeaa84ac5d8ac +AUX 12.0/0008-Disable-SSL-Session-ID-tracking.patch 1165 RMD160 69788fb83c4a35578a0d592a5de51ab6f984162a SHA1 271e7dca6d0edb740d6ba4038af5d6af04175a22 SHA256 523f0e05aeac80040bcebf7202955d582de6fb65c0af6ab321f99a477f0226e4 +AUX 12.0/0009-Provide-an-observer-event-to-close-persistent-connec.patch 1448 RMD160 47e28796fb105ab76aac971bf287e023c976f601 SHA1 f4b89d78dd195ec8bc6a04894d1d65398365c0e1 SHA256 0267aa836a302852527811b43f851937e06d9f19e736fc2b9e0a30ca3d303d2b +AUX 12.0/0010-Provide-client-values-only-to-CSS-Media-Queries.patch 2042 RMD160 54b96063c6f34c97fd79c2562d57aa18c9af8ffa SHA1 de961c7437360bcc04ed1968c3efc2a32268a4a4 SHA256 245a07deaf009900b27f2abab0277a90fcfd1582abc65bd4aba0a7fc4dca704d +AUX 12.0/0011-Limit-the-number-of-fonts-per-document.patch 7318 RMD160 498e22647d198d5502e8c9bebad273de8f72698e SHA1 fef97a6c7a062f7493e7bcf5899f7d78978ac551 SHA256 60233e27f38f7afee6d78522d91aa0d8e03c80cf7d8b61c5d2232f3a37bfda6c +AUX 12.0/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch 8638 RMD160 0d667fab249165c94135af2ebd0e0c57cd9fd46f SHA1 3a01f51a8b5df9be026a48685733145878d1318d SHA256 be56ff7e4591c62604a8ac414d71273ae68db77b2c4e15c5766717d7e9aad41b +AUX 12.0/0013-Rebrand-Firefox-to-TorBrowser.patch 2151 RMD160 313ef15c00eb506bf19899774567827cbc2c2d0f SHA1 d839a369350456d852c56cc81bcfb6c91d335c1d SHA256 fb59437bc3982cb5b3edda0f3c4e545d036b11428fc58ebfbc09734e562b9e7a +AUX 12.0/0014-Make-Download-manager-memory-only.patch 2296 RMD160 7c72742923725fb3c009f01497892decbaef71a7 SHA1 950d18d528eecaac14531962735d61dd65e7dd6f SHA256 1c8291eb33f7edd41e12042d83e67f0c97dd10d9f30afb2dbdc18ce167d03db0 +AUX 12.0/0015-Add-DDG-and-StartPage-to-Omnibox.patch 5597 RMD160 88de6a2de4a912f01c543b39b38d3a8d3b3350e0 SHA1 74398f5384109024ec9256542f417e1eb9954da1 SHA256 24f9d89b071e715de28bdf7cfde06e49980264cc2173c7248dccbfd2ed6d9d20 +AUX 12.0/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch 20276 RMD160 e95c35d1fc508216cb214dc6a1735edde041a3ae SHA1 06a8a55d137a87ccd7e21259614b565b126ccdc7 SHA256 f3a66ef7ff7f1106bb4d7f124d4ba56e008fee8b1ec19713453d97c7fab17641 +AUX 12.0/0017-Make-nsICacheService.EvictEntries-synchronous.patch 1654 RMD160 508708c6f5e1727e50a840f9685bfd466e8f1136 SHA1 2171a53bc651cc9c458901bc32d07e0705db26d1 SHA256 c7f7c586bb623d943d00ea19c69f3d2b92980cafe0a5528b3e952c96202592e3 +AUX 12.0/0018-Prevent-WebSocket-DNS-leak.patch 5425 RMD160 6b0931da232e0887519975d029782d70cae6cbca SHA1 824f3ea79d4250337b6a3a50cbc4abfc7827571b SHA256 a2d6afd4dc4f3392bbbb1a0058fb1377e97b8da7354e740b0fbd43203feeeccc +DIST firefox-12.0-patches-0.1.tar.xz 12996 RMD160 cd0c534410b512ca13504106465712ae51b4e5f0 SHA1 7ce3f371f43e73deca289a354dd9155b6a9bc8ff SHA256 de8573ad0019fd9b09bd94aefb3519286a04252a9d761bbf96f4c77d3c135174 +DIST firefox-12.0.source.tar.bz2 78956707 RMD160 d83eb97543fc09f84b30a46ba8217c17f30bd572 SHA1 0177185e54b7d63dc36bd5bd5c80ba6afd52e199 SHA256 9a232a10e5803b0e4a85bd986e3e88b87ccde7bdc3363ea7022d5761944dbb1d +DIST tor-browser-gnu-linux-i686-2.2.35-11-dev-en-US.tar.gz 31601046 RMD160 dba786827a730c12e4549a4ace8e543e86709145 SHA1 5a7da7c1d9f5c05b73b93900651a5260022a311f SHA256 7403e69c1f3eb9bffa335528ec13801318ef982b37b36ff59fbd5c6b1b5bc7c0 +DIST tor-browser-gnu-linux-x86_64-2.2.35-11-dev-en-US.tar.gz 32684212 RMD160 a197d3ec4b4140e26d757b466d4f6066304c14e7 SHA1 0c6635799d20625182648499da32aa4abea2a844 SHA256 dde6fd58e4d1f246604446bc29fd243057c2eb9c1753d3c731858ef09b6a1b95 +EBUILD torbrowser-12.0.ebuild 9655 RMD160 3a0ada6e39a6fe05c6d1cd5a7ee432e14acb4c77 SHA1 443571bf74bbd1b6a45e189a5caa2f92a97261a0 SHA256 9ca5d8ae93f7147bb53b497c662adee9d3b636b3d84c5ac3c5a7036d295db769 +MISC ChangeLog 1420 RMD160 f7960a699d9198a79db2e8e3332e6af42720a6ef SHA1 be02cfdd186fa8a6425c68c887cad1832afb6214 SHA256 878ec7ebb49f411c6a71b967d7311fe25388a5c2d00148c1fd29c844ebc4d8cf +MISC metadata.xml 1404 RMD160 c4c0528aa6852060055c41a20a1c4d31b5417d92 SHA1 3047b4a2aa4f19c8f1411c931466794ed3ddd92a SHA256 7b5732d06f7998b7bf1f093fa5c05835009f8a0e632ae26551db3e48156f3ecb diff --git a/www-client/torbrowser/files/12.0/0001-Block-Components.interfaces-lookupMethod-from-conten.patch b/www-client/torbrowser/files/12.0/0001-Block-Components.interfaces-lookupMethod-from-conten.patch new file mode 100644 index 000000000000..df1c202026e0 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0001-Block-Components.interfaces-lookupMethod-from-conten.patch @@ -0,0 +1,50 @@ +From 878aa170944f7d44a76f0eb09214d46b6028c549 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 1 Feb 2012 15:40:40 -0800 +Subject: [PATCH 01/16] Block Components.interfaces,lookupMethod from content + +This patch removes the ability of content script to access +Components.interfaces.* as well as call or access Components.lookupMethod. + +These two interfaces seem to be exposed to content script only to make our +lives difficult. Components.lookupMethod can undo our JS hooks, and +Components.interfaces is useful for fingerprinting the platform, OS, and +Firebox version. + +They appear to have no other legitimate use. See also: +https://bugzilla.mozilla.org/show_bug.cgi?id=429070 +https://trac.torproject.org/projects/tor/ticket/2873 +https://trac.torproject.org/projects/tor/ticket/2874 +--- + js/xpconnect/src/XPCComponents.cpp | 8 ++++++-- + 1 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp +index 716cfdb..56e3f55 100644 +--- a/js/xpconnect/src/XPCComponents.cpp ++++ b/js/xpconnect/src/XPCComponents.cpp +@@ -4261,7 +4261,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval) + NS_IMETHODIMP + nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval) + { +- static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull }; ++ // XXX: Pref observer? Also, is this what we want? Seems like a plan ++ //static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull }; ++ static const char* allowed[] = { "isSuccessCode", nsnull }; + *_retval = xpc_CheckAccessList(methodName, allowed); + return NS_OK; + } +@@ -4270,7 +4272,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c + NS_IMETHODIMP + nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval) + { +- static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull}; ++ // XXX: Pref observer? Also, is this what we want? Seems like a plan ++ // static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull}; ++ static const char* allowed[] = { "results", nsnull}; + *_retval = xpc_CheckAccessList(propertyName, allowed); + return NS_OK; + } +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0002-Make-Permissions-Manager-memory-only.patch b/www-client/torbrowser/files/12.0/0002-Make-Permissions-Manager-memory-only.patch new file mode 100644 index 000000000000..f38dc99b6534 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0002-Make-Permissions-Manager-memory-only.patch @@ -0,0 +1,94 @@ +From 5f47c5bdf95633e28b6e338ba8794243b429aefb Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 1 Feb 2012 15:45:16 -0800 +Subject: [PATCH 02/16] 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 files changed, 31 insertions(+), 3 deletions(-) + +diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp +index cdfe21b..a7a0efb 100644 +--- a/extensions/cookie/nsPermissionManager.cpp ++++ b/extensions/cookie/nsPermissionManager.cpp +@@ -58,6 +58,10 @@ + #include "mozStorageHelper.h" + #include "mozStorageCID.h" + #include "nsXULAppAPI.h" ++#include "nsCOMPtr.h" ++#include "nsIPrefService.h" ++#include "nsIPrefBranch.h" ++#include "nsIPrefBranch2.h" + + static nsPermissionManager *gPermissionManager = nsnull; + +@@ -203,6 +207,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; +@@ -251,8 +260,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; +@@ -262,7 +281,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); +@@ -794,7 +817,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. + if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) { +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0003-Make-Intermediate-Cert-Store-memory-only.patch b/www-client/torbrowser/files/12.0/0003-Make-Intermediate-Cert-Store-memory-only.patch new file mode 100644 index 000000000000..617a78ed72e6 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0003-Make-Intermediate-Cert-Store-memory-only.patch @@ -0,0 +1,43 @@ +From 8cb78993225793692fe0560d25db4af55e0553bd Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@fscked.org> +Date: Fri, 19 Aug 2011 17:58:23 -0700 +Subject: [PATCH 03/16] Make Intermediate Cert Store memory-only. + +This patch makes the intermediate SSL cert store exist in memory only. + +The pref must be set before startup in prefs.js. +https://trac.torproject.org/projects/tor/ticket/2949 +--- + security/manager/ssl/src/nsNSSComponent.cpp | 15 ++++++++++++++- + 1 files changed, 14 insertions(+), 1 deletions(-) + +diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp +index 5abc0a5..22becca 100644 +--- a/security/manager/ssl/src/nsNSSComponent.cpp ++++ b/security/manager/ssl/src/nsNSSComponent.cpp +@@ -1738,8 +1738,21 @@ nsNSSComponent::InitializeNSS(bool showWarningBox) + // Ubuntu 8.04, which loads any nonexistent "<configdir>/libnssckbi.so" as + // "/usr/lib/nss/libnssckbi.so". + PRUint32 init_flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE; +- SECStatus init_rv = ::NSS_Initialize(profileStr.get(), "", "", ++ bool nocertdb = false; ++ mPrefBranch->GetBoolPref("security.nocertdb", &nocertdb); ++ ++ // XXX: We can also do the the following to only disable the certdb. ++ // Leaving this codepath in as a fallback in case InitNODB fails ++ if (nocertdb) ++ init_flags |= NSS_INIT_NOCERTDB; ++ ++ SECStatus init_rv; ++ if (nocertdb) { ++ init_rv = ::NSS_NoDB_Init(NULL); ++ } else { ++ init_rv = ::NSS_Initialize(profileStr.get(), "", "", + SECMOD_DB, init_flags); ++ } + + if (init_rv != SECSuccess) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("can not init NSS r/w in %s\n", profileStr.get())); +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0004-Add-a-string-based-cacheKey.patch b/www-client/torbrowser/files/12.0/0004-Add-a-string-based-cacheKey.patch new file mode 100644 index 000000000000..7ddd877a653f --- /dev/null +++ b/www-client/torbrowser/files/12.0/0004-Add-a-string-based-cacheKey.patch @@ -0,0 +1,85 @@ +From c4212c764149b74a04aad7d15cb3df810512e4ba Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@fscked.org> +Date: Fri, 2 Sep 2011 20:47:02 -0700 +Subject: [PATCH 04/16] Add a string-based cacheKey. + +Used for isolating cache according to same-origin policy. +--- + netwerk/base/public/nsICachingChannel.idl | 7 +++++++ + netwerk/protocol/http/nsHttpChannel.cpp | 22 ++++++++++++++++++++++ + netwerk/protocol/http/nsHttpChannel.h | 1 + + 3 files changed, 30 insertions(+), 0 deletions(-) + +diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl +index 2da46d6..4ee5774 100644 +--- a/netwerk/base/public/nsICachingChannel.idl ++++ b/netwerk/base/public/nsICachingChannel.idl +@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel + attribute nsISupports cacheKey; + + /** ++ * Set/get the cache domain... uniquely identifies the data in the cache ++ * for this channel. Holding a reference to this key does NOT prevent ++ * the cached data from being removed. ++ */ ++ attribute AUTF8String cacheDomain; ++ ++ /** + * Specifies whether or not the data should be cached to a file. This + * may fail if the disk cache is not present. The value of this attribute + * is usually only settable during the processing of a channel's +diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp +index fab0726..5f42b7b 100644 +--- a/netwerk/protocol/http/nsHttpChannel.cpp ++++ b/netwerk/protocol/http/nsHttpChannel.cpp +@@ -2415,6 +2415,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID, + cacheKey.Append(buf); + } + ++ if (strlen(mCacheDomain.get()) > 0) { ++ cacheKey.AppendLiteral("domain="); ++ cacheKey.Append(mCacheDomain.get()); ++ cacheKey.AppendLiteral("&"); ++ } ++ + if (!cacheKey.IsEmpty()) { + cacheKey.AppendLiteral("uri="); + } +@@ -4762,6 +4768,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value) + } + + NS_IMETHODIMP ++nsHttpChannel::GetCacheDomain(nsACString &value) ++{ ++ value = mCacheDomain; ++ ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsHttpChannel::SetCacheDomain(const nsACString &value) ++{ ++ mCacheDomain = value; ++ ++ return NS_OK; ++} ++ ++NS_IMETHODIMP + nsHttpChannel::GetOfflineCacheClientID(nsACString &value) + { + value = mOfflineCacheClientID; +diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h +index b7bba48..605dc80 100644 +--- a/netwerk/protocol/http/nsHttpChannel.h ++++ b/netwerk/protocol/http/nsHttpChannel.h +@@ -304,6 +304,7 @@ private: + nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry; + nsCacheAccessMode mOfflineCacheAccess; + nsCString mOfflineCacheClientID; ++ nsCString mCacheDomain; + + // auth specific data + nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider; +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0005-Block-all-plugins-except-flash.patch b/www-client/torbrowser/files/12.0/0005-Block-all-plugins-except-flash.patch new file mode 100644 index 000000000000..9a577c0cb80b --- /dev/null +++ b/www-client/torbrowser/files/12.0/0005-Block-all-plugins-except-flash.patch @@ -0,0 +1,85 @@ +From 89d6deddce94c720793a33a1c9fc812ad65116a9 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 1 Feb 2012 15:50:15 -0800 +Subject: [PATCH 05/16] Block all plugins except flash. + +We cannot use the @mozilla.org/extensions/blocklist;1 service, because we +actually want to stop plugins from ever entering the browser's process space +and/or executing code (for example, AV plugins that collect statistics/analyse +urls, magical toolbars that phone home or "help" the user, skype buttons that +ruin our day, and censorship filters). Hence we rolled our own. + +See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings +on a better way. Until then, it is delta-darwinism for us. +--- + dom/plugins/base/nsPluginHost.cpp | 33 +++++++++++++++++++++++++++++++++ + dom/plugins/base/nsPluginHost.h | 2 ++ + 2 files changed, 35 insertions(+), 0 deletions(-) + +diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp +index ed081fc..7384bcc 100644 +--- a/dom/plugins/base/nsPluginHost.cpp ++++ b/dom/plugins/base/nsPluginHost.cpp +@@ -1985,6 +1985,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag) + return false; + } + ++PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile) ++{ ++ nsCString leaf; ++ const char *leafStr; ++ nsresult rv; ++ ++ rv = pluginFile->GetNativeLeafName(leaf); ++ if (NS_FAILED(rv)) { ++ return PR_TRUE; // fuck 'em. blacklist. ++ } ++ ++ leafStr = leaf.get(); ++ ++ if (!leafStr) { ++ return PR_TRUE; // fuck 'em. blacklist. ++ } ++ ++ // libgnashplugin.so, libflashplayer.so, Flash Player-10.4-10.5.plugin, ++ // NPSWF32.dll, NPSWF64.dll ++ if (strstr(leafStr, "libgnashplugin") == leafStr || ++ strstr(leafStr, "libflashplayer") == leafStr || ++ strstr(leafStr, "Flash Player") == leafStr || ++ strstr(leafStr, "NPSWF") == leafStr) { ++ return PR_FALSE; ++ } ++ ++ return PR_TRUE; // fuck 'em. blacklist. ++} ++ + typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void); + + nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, +@@ -2118,6 +2147,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, + continue; + } + ++ if (GhettoBlacklist(localfile)) { ++ continue; ++ } ++ + // if it is not found in cache info list or has been changed, create a new one + if (!pluginTag) { + nsPluginFile pluginFile(localfile); +diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h +index 5630b8d..f54bd32 100644 +--- a/dom/plugins/base/nsPluginHost.h ++++ b/dom/plugins/base/nsPluginHost.h +@@ -285,6 +285,8 @@ private: + // Loads all cached plugins info into mCachedPlugins + nsresult ReadPluginInfo(); + ++ PRBool GhettoBlacklist(nsIFile *pluginFile); ++ + // Given a file path, returns the plugins info from our cache + // and removes it from the cache. + void RemoveCachedPluginsInfo(const char *filePath, +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0006-Make-content-pref-service-memory-only-clearable.patch b/www-client/torbrowser/files/12.0/0006-Make-content-pref-service-memory-only-clearable.patch new file mode 100644 index 000000000000..a26bfecda614 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0006-Make-content-pref-service-memory-only-clearable.patch @@ -0,0 +1,37 @@ +From b2cc8f517c6589def4cc126af0b5f1898d61541c Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@fscked.org> +Date: Thu, 8 Sep 2011 08:40:17 -0700 +Subject: [PATCH 06/16] Make content pref service memory-only + clearable + +This prevents random urls from being inserted into content-prefs.sqllite in +the profile directory as content prefs change (includes site-zoom and perhaps +other site prefs?). +--- + .../contentprefs/nsContentPrefService.js | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js +index 17cac93..1f12609 100644 +--- a/toolkit/components/contentprefs/nsContentPrefService.js ++++ b/toolkit/components/contentprefs/nsContentPrefService.js +@@ -1242,7 +1242,7 @@ ContentPrefService.prototype = { + + var dbConnection; + +- if (!dbFile.exists()) ++ if (true || !dbFile.exists()) + dbConnection = this._dbCreate(dbService, dbFile); + else { + try { +@@ -1290,7 +1290,7 @@ ContentPrefService.prototype = { + }, + + _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) { +- var dbConnection = aDBService.openDatabase(aDBFile); ++ var dbConnection = aDBService.openSpecialDatabase("memory"); + + try { + this._dbCreateSchema(dbConnection); +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0008-Disable-SSL-Session-ID-tracking.patch b/www-client/torbrowser/files/12.0/0008-Disable-SSL-Session-ID-tracking.patch new file mode 100644 index 000000000000..ff692fe291c6 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0008-Disable-SSL-Session-ID-tracking.patch @@ -0,0 +1,28 @@ +From 4d7f3122a76e0d5a31ba352880892fecd493252b Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@fscked.org> +Date: Wed, 7 Dec 2011 19:36:38 -0800 +Subject: [PATCH 08/16] Disable SSL Session ID tracking. + +We can't easily bind SSL Session ID tracking to url bar domain, +so we have to disable them to satisfy +https://www.torproject.org/projects/torbrowser/design/#identifier-linkability. +--- + security/nss/lib/ssl/sslsock.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c +index 22206f7..31086db 100644 +--- a/security/nss/lib/ssl/sslsock.c ++++ b/security/nss/lib/ssl/sslsock.c +@@ -173,7 +173,7 @@ static sslOptions ssl_defaults = { + PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */ + PR_TRUE, /* enableSSL3 */ + PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */ +- PR_FALSE, /* noCache */ ++ PR_TRUE, /* noCache */ + PR_FALSE, /* fdx */ + PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */ + PR_TRUE, /* detectRollBack */ +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0009-Provide-an-observer-event-to-close-persistent-connec.patch b/www-client/torbrowser/files/12.0/0009-Provide-an-observer-event-to-close-persistent-connec.patch new file mode 100644 index 000000000000..2c5f135f51da --- /dev/null +++ b/www-client/torbrowser/files/12.0/0009-Provide-an-observer-event-to-close-persistent-connec.patch @@ -0,0 +1,40 @@ +From 873acaa3fd6df60fe57f1549cdb45df7e277808d Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 1 Feb 2012 15:53:28 -0800 +Subject: [PATCH 09/16] Provide an observer event to close persistent + connections + +We need to prevent linkability across "New Identity", which includes closing +keep-alive connections. +--- + netwerk/protocol/http/nsHttpHandler.cpp | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp +index ebc7641..dbcdff7 100644 +--- a/netwerk/protocol/http/nsHttpHandler.cpp ++++ b/netwerk/protocol/http/nsHttpHandler.cpp +@@ -331,6 +331,7 @@ nsHttpHandler::Init() + mObserverService->AddObserver(this, "net:clear-active-logins", true); + mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true); + mObserverService->AddObserver(this, "net:prune-dead-connections", true); ++ mObserverService->AddObserver(this, "net:prune-all-connections", PR_TRUE); + } + + return NS_OK; +@@ -1522,6 +1523,12 @@ nsHttpHandler::Observe(nsISupports *subject, + mConnMgr->PruneDeadConnections(); + } + } ++ else if (strcmp(topic, "net:prune-all-connections") == 0) { ++ if (mConnMgr) { ++ mConnMgr->ClosePersistentConnections(); ++ mConnMgr->PruneDeadConnections(); ++ } ++ } + + return NS_OK; + } +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0010-Provide-client-values-only-to-CSS-Media-Queries.patch b/www-client/torbrowser/files/12.0/0010-Provide-client-values-only-to-CSS-Media-Queries.patch new file mode 100644 index 000000000000..661f0ca4187a --- /dev/null +++ b/www-client/torbrowser/files/12.0/0010-Provide-client-values-only-to-CSS-Media-Queries.patch @@ -0,0 +1,72 @@ +From a27dcd387d8c3c1f1e150dcdd3c8aa1872ad14b5 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@fscked.org> +Date: Tue, 20 Dec 2011 21:02:49 -0800 +Subject: [PATCH 10/16] Provide client values only to CSS Media Queries + +Also disable a bunch of Mozilla extensions that smell like they are +fingerprintable. + +This is done to address +https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability +--- + layout/style/nsMediaFeatures.cpp | 10 ++++++---- + 1 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp +index 6eca06e..c68f191 100644 +--- a/layout/style/nsMediaFeatures.cpp ++++ b/layout/style/nsMediaFeatures.cpp +@@ -383,14 +383,14 @@ nsMediaFeatures::features[] = { + nsMediaFeature::eMinMaxAllowed, + nsMediaFeature::eLength, + { nsnull }, +- GetDeviceWidth ++ GetWidth + }, + { + &nsGkAtoms::deviceHeight, + nsMediaFeature::eMinMaxAllowed, + nsMediaFeature::eLength, + { nsnull }, +- GetDeviceHeight ++ GetHeight + }, + { + &nsGkAtoms::orientation, +@@ -411,7 +411,7 @@ nsMediaFeatures::features[] = { + nsMediaFeature::eMinMaxAllowed, + nsMediaFeature::eIntRatio, + { nsnull }, +- GetDeviceAspectRatio ++ GetAspectRatio + }, + { + &nsGkAtoms::color, +@@ -457,6 +457,7 @@ nsMediaFeatures::features[] = { + }, + + // Mozilla extensions ++/* + { + &nsGkAtoms::_moz_device_pixel_ratio, + nsMediaFeature::eMinMaxAllowed, +@@ -469,7 +470,7 @@ nsMediaFeatures::features[] = { + nsMediaFeature::eMinMaxNotAllowed, + nsMediaFeature::eEnumerated, + { kOrientationKeywords }, +- GetDeviceOrientation ++ GetOrientation + }, + { + &nsGkAtoms::_moz_is_resource_document, +@@ -590,6 +591,7 @@ nsMediaFeatures::features[] = { + { nsnull }, + GetWindowsTheme + }, ++*/ + // Null-mName terminator: + { + nsnull, +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0011-Limit-the-number-of-fonts-per-document.patch b/www-client/torbrowser/files/12.0/0011-Limit-the-number-of-fonts-per-document.patch new file mode 100644 index 000000000000..9dce423f0e05 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0011-Limit-the-number-of-fonts-per-document.patch @@ -0,0 +1,228 @@ +From c4d1c23872e2be83f33f2b9bfc5c49d2b98c73a6 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 1 Feb 2012 16:01:21 -0800 +Subject: [PATCH 11/16] Limit the number of fonts per document. + +We create two prefs: +browser.display.max_font_count and browser.display.max_font_attempts. +max_font_count sets a limit on the number of fonts actually used in the +document, and max_font_attempts sets a limit on the total number of CSS +queries that a document is allowed to perform. + +Once either limit is reached, the browser behaves as if +browser.display.use_document_fonts was set to 0 for subsequent font queries. + +If a pref is not set or is negative, that limit does not apply. + +This is done to address: +https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkability +--- + layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++ + layout/base/nsPresContext.h | 9 ++++ + layout/style/nsRuleNode.cpp | 13 ++++- + 3 files changed, 119 insertions(+), 3 deletions(-) + +diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp +index 49b201e..0a8db3c 100644 +--- a/layout/base/nsPresContext.cpp ++++ b/layout/base/nsPresContext.cpp +@@ -98,6 +98,8 @@ + #include "FrameLayerBuilder.h" + #include "nsDOMMediaQueryList.h" + #include "nsSMILAnimationController.h" ++#include "nsString.h" ++#include "nsUnicharUtils.h" + + #ifdef IBMBIDI + #include "nsBidiPresUtils.h" +@@ -733,6 +735,10 @@ nsPresContext::GetUserPreferences() + // * use fonts? + mUseDocumentFonts = + Preferences::GetInt("browser.display.use_document_fonts") != 0; ++ mMaxFonts = ++ Preferences::GetInt("browser.display.max_font_count", -1); ++ mMaxFontAttempts = ++ Preferences::GetInt("browser.display.max_font_attempts", -1); + + // * replace backslashes with Yen signs? (bug 245770) + mEnableJapaneseTransform = +@@ -1334,6 +1340,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const + return font; + } + ++PRBool ++nsPresContext::FontUseCountReached(const nsFont &font) { ++ if (mMaxFonts < 0) { ++ return PR_FALSE; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) { ++ if (mFontsUsed[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsUsed[i].style == font.style*/) { ++ // seen it before: OK ++ return PR_FALSE; ++ } ++ } ++ ++ if (mFontsUsed.Length() >= mMaxFonts) { ++ return PR_TRUE; ++ } ++ ++ return PR_FALSE; ++} ++ ++PRBool ++nsPresContext::FontAttemptCountReached(const nsFont &font) { ++ if (mMaxFontAttempts < 0) { ++ return PR_FALSE; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) { ++ if (mFontsTried[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsTried[i].style == font.style*/) { ++ // seen it before: OK ++ return PR_FALSE; ++ } ++ } ++ ++ if (mFontsTried.Length() >= mMaxFontAttempts) { ++ return PR_TRUE; ++ } ++ ++ return PR_FALSE; ++} ++ ++void ++nsPresContext::AddFontUse(const nsFont &font) { ++ if (mMaxFonts < 0) { ++ return; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) { ++ if (mFontsUsed[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsUsed[i].style == font.style*/) { ++ // seen it before: OK ++ return; ++ } ++ } ++ ++ if (mFontsUsed.Length() >= mMaxFonts) { ++ return; ++ } ++ ++ mFontsUsed.AppendElement(font); ++ return; ++} ++ ++void ++nsPresContext::AddFontAttempt(const nsFont &font) { ++ if (mMaxFontAttempts < 0) { ++ return; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) { ++ if (mFontsTried[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsTried[i].style == font.style*/) { ++ // seen it before: OK ++ return; ++ } ++ } ++ ++ if (mFontsTried.Length() >= mMaxFontAttempts) { ++ return; ++ } ++ ++ mFontsTried.AppendElement(font); ++ return; ++} ++ + void + nsPresContext::SetFullZoom(float aZoom) + { +diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h +index 4b70c2f..ae8fcd5 100644 +--- a/layout/base/nsPresContext.h ++++ b/layout/base/nsPresContext.h +@@ -535,6 +535,13 @@ public: + } + } + ++ nsTArray<nsFont> mFontsUsed; // currently for font-count limiting only ++ nsTArray<nsFont> mFontsTried; // currently for font-count limiting only ++ void AddFontUse(const nsFont &font); ++ void AddFontAttempt(const nsFont &font); ++ PRBool FontUseCountReached(const nsFont &font); ++ PRBool FontAttemptCountReached(const nsFont &font); ++ + PRInt32 MinFontSize() const { + return NS_MAX(mMinFontSize, mMinimumFontSizePref); + } +@@ -1127,6 +1134,8 @@ protected: + PRUint32 mInterruptChecksToSkip; + + mozilla::TimeStamp mReflowStartTime; ++ PRInt32 mMaxFontAttempts; ++ PRInt32 mMaxFonts; + + unsigned mHasPendingInterrupt : 1; + unsigned mInterruptsEnabled : 1; +diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp +index 9eb41ac..47065d0 100644 +--- a/layout/style/nsRuleNode.cpp ++++ b/layout/style/nsRuleNode.cpp +@@ -3087,6 +3087,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + + // See if there is a minimum font-size constraint to honor + nscoord minimumFontSize = mPresContext->MinFontSize(); ++ PRBool isXUL = PR_FALSE; + + if (minimumFontSize < 0) + minimumFontSize = 0; +@@ -3098,10 +3099,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + // We only need to know this to determine if we have to use the + // document fonts (overriding the useDocumentFonts flag), or to + // determine if we have to override the minimum font-size constraint. +- if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) { ++ if (mPresContext->IsChrome()) { + // if we are not using document fonts, but this is a XUL document, + // then we use the document fonts anyway +- useDocumentFonts = true; ++ isXUL = PR_TRUE; + minimumFontSize = 0; + } + +@@ -3116,9 +3117,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + // generic? + nsFont::GetGenericID(font->mFont.name, &generic); + ++ mPresContext->AddFontAttempt(font->mFont); ++ + // If we aren't allowed to use document fonts, then we are only entitled + // to use the user's default variable-width font and fixed-width font +- if (!useDocumentFonts) { ++ if (!isXUL && (!useDocumentFonts || ++ mPresContext->FontAttemptCountReached(font->mFont) || ++ mPresContext->FontUseCountReached(font->mFont))) { + // Extract the generic from the specified font family... + nsAutoString genericName; + if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) { +@@ -3154,6 +3159,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + minimumFontSize, font); + } + ++ if (font->mGenericID == kGenericFont_NONE) ++ mPresContext->AddFontUse(font->mFont); + COMPUTE_END_INHERITED(Font, font) + } + +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch b/www-client/torbrowser/files/12.0/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch new file mode 100644 index 000000000000..33ff9a24351b --- /dev/null +++ b/www-client/torbrowser/files/12.0/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch @@ -0,0 +1,251 @@ +From 6147cea4de151dade922b3c2787016f70c222458 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Tue, 24 Apr 2012 17:21:45 -0700 +Subject: [PATCH 12/16] Randomize HTTP request order and pipeline depth. + +This is an experimental defense against +http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf + +See: +https://blog.torproject.org/blog/experimental-defense-website-traffic-fingerprinting + +This defense has been improved since that blog post to additionally randomize +the order and concurrency of non-pipelined HTTP requests. +--- + netwerk/protocol/http/nsHttpConnectionMgr.cpp | 133 ++++++++++++++++++++++++- + netwerk/protocol/http/nsHttpConnectionMgr.h | 5 + + 2 files changed, 133 insertions(+), 5 deletions(-) + +diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp +index 6e1099d..3eec5b3 100644 +--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp ++++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp +@@ -100,6 +100,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr() + mCT.Init(); + mAlternateProtocolHash.Init(16); + mSpdyPreferredHash.Init(); ++ ++ nsresult rv; ++ mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv); ++ if (NS_FAILED(rv)) { ++ mRandomGenerator = nsnull; ++ } + } + + nsHttpConnectionMgr::~nsHttpConnectionMgr() +@@ -353,8 +359,12 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline) + nsConnectionEntry *ent = mCT.Get(ci->HashKey()); + if (ent) { + // search for another request to pipeline... +- PRInt32 i, count = ent->mPendingQ.Length(); +- for (i=0; i<count; ++i) { ++ PRInt32 i, h, count = ent->mPendingQ.Length(); ++ PRInt32* ind = new PRInt32[count]; ++ ShuffleRequestOrder((PRUint32*)ind, (PRUint32)count); ++ ++ for (h=0; h<count; ++h) { ++ i = ind[h]; // random request sequence + nsHttpTransaction *trans = ent->mPendingQ[i]; + if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) { + pipeline->AddTransaction(trans); +@@ -365,6 +375,8 @@ + break; + } + } ++ ++ delete [] ind; + } + } + } +@@ -898,12 +908,17 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent) + + ProcessSpdyPendingQ(ent); + +- PRUint32 i, count = ent->mPendingQ.Length(); ++ PRUint32 h, i = 0, count = ent->mPendingQ.Length(); + if (count > 0) { + LOG((" pending-count=%u\n", count)); + nsHttpTransaction *trans = nsnull; + nsHttpConnection *conn = nsnull; +- for (i = 0; i < count; ++i) { ++ ++ PRUint32* ind = new PRUint32[count]; ++ ShuffleRequestOrder(ind, count); ++ ++ for (h=0; h<count; ++h) { ++ i = ind[h]; // random request sequence + trans = ent->mPendingQ[i]; + + // When this transaction has already established a half-open +@@ -927,6 +944,7 @@ + "something mutated pending queue from " + "GetConnection()"); + } ++ delete [] ind; + if (conn) { + LOG((" dispatching pending transaction...\n")); + +@@ -1011,6 +1026,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap + maxPersistConns = mMaxPersistConnsPerHost; + } + ++ // Fuzz maxConns for website fingerprinting attack ++ // We create a range of maxConns/5 up to 6*maxConns/5 ++ // because this function is called repeatedly, and we'll ++ // end up converging on a the high side of concurrent connections ++ // after a short while. ++ PRUint8 *bytes = nsnull; ++ nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); ++ NS_ENSURE_SUCCESS(rv, rv); ++ ++ bytes[0] = bytes[0] % (maxConns + 1); ++ maxConns = (maxConns/5) + bytes[0]; ++ NS_Free(bytes); ++ + // use >= just to be safe + return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) && + (persistCount >= maxPersistConns) ); +@@ -1227,7 +1255,7 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent, + + if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) { + LOG((" looking to build pipeline...\n")); +- if (BuildPipeline(ent, trans, &pipeline)) ++ if (BuildRandomizedPipeline(ent, trans, &pipeline)) + trans = pipeline; + } + +@@ -1300,6 +1328,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent, + return true; + } + ++ ++// Generate a shuffled request ordering sequence ++void ++nsHttpConnectionMgr::ShuffleRequestOrder(PRUint32 *ind, PRUint32 count) ++{ ++ PRUint32 i; ++ PRUint32 *rints; ++ ++ for (i=0; i<count; ++i) { ++ ind[i] = i; ++ } ++ nsresult rv = mRandomGenerator->GenerateRandomBytes(sizeof(PRUint32)*count, ++ (PRUint8**)&rints); ++ if (NS_FAILED(rv)) ++ return; // Leave unshuffled if error ++ ++ for (i=0; i < count; ++i) { ++ PRInt32 temp = ind[i]; ++ ind[i] = ind[rints[i]%count]; ++ ind[rints[i]%count] = temp; ++ } ++ NS_Free(rints); ++} ++ ++bool ++nsHttpConnectionMgr::BuildRandomizedPipeline(nsConnectionEntry *ent, ++ nsAHttpTransaction *firstTrans, ++ nsHttpPipeline **result) ++{ ++ if (mRandomGenerator == nsnull) ++ return BuildPipeline(ent, firstTrans, result); ++ if (mMaxPipelinedRequests < 2) ++ return PR_FALSE; ++ ++ nsresult rv; ++ PRUint8 *bytes = nsnull; ++ ++ nsHttpPipeline *pipeline = nsnull; ++ nsHttpTransaction *trans; ++ ++ PRUint32 i = 0, numAdded = 0, numAllowed = 0; ++ PRUint32 max = 0; ++ ++ while (i < ent->mPendingQ.Length()) { ++ if (ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING) ++ numAllowed++; ++ i++; ++ } ++ ++ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); ++ NS_ENSURE_SUCCESS(rv, rv); ++ // 4...12 ++ max = 4 + (bytes[0] % (mMaxPipelinedRequests + 1)); ++ NS_Free(bytes); ++ ++ while (numAllowed > 0) { ++ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); ++ NS_ENSURE_SUCCESS(rv, rv); ++ i = bytes[0] % ent->mPendingQ.Length(); ++ NS_Free(bytes); ++ ++ trans = ent->mPendingQ[i]; ++ ++ if (!(ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING)) ++ continue; ++ ++ if (numAdded == 0) { ++ pipeline = new nsHttpPipeline; ++ if (!pipeline) ++ return PR_FALSE; ++ pipeline->AddTransaction(firstTrans); ++ numAdded = 1; ++ } ++ pipeline->AddTransaction(trans); ++ ++ // remove transaction from pending queue ++ ent->mPendingQ.RemoveElementAt(i); ++ NS_RELEASE(trans); ++ ++ numAllowed--; ++ ++ if (++numAdded == max) ++ break; ++ } ++ ++ //fprintf(stderr, "Yay!!! pipelined %u/%u transactions\n", numAdded, max); ++ LOG((" pipelined %u/%u transactions\n", numAdded, max)); ++ ++ if (numAdded == 0) ++ return PR_FALSE; ++ ++ NS_ADDREF(*result = pipeline); ++ return PR_TRUE; ++} ++ + nsresult + nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans) + { +diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h +index a13da0f..59ee9b9 100644 +--- a/netwerk/protocol/http/nsHttpConnectionMgr.h ++++ b/netwerk/protocol/http/nsHttpConnectionMgr.h +@@ -54,6 +54,7 @@ + #include "nsIObserver.h" + #include "nsITimer.h" + #include "nsIX509Cert3.h" ++#include "nsIRandomGenerator.h" + + class nsHttpPipeline; + +@@ -317,6 +318,8 @@ private: + nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *, + PRUint8 caps, nsHttpConnection *); + bool BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **); ++ bool BuildRandomizedPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **); ++ void ShuffleRequestOrder(PRUint32 *, PRUint32); + nsresult ProcessNewTransaction(nsHttpTransaction *); + nsresult EnsureSocketThreadTargetIfOnline(); + void ClosePersistentConnections(nsConnectionEntry *ent); +@@ -409,6 +412,8 @@ private: + PRUint64 mTimeOfNextWakeUp; + // Timer for next pruning of dead connections. + nsCOMPtr<nsITimer> mTimer; ++ // Random number generator for reordering HTTP pipeline ++ nsCOMPtr<nsIRandomGenerator> mRandomGenerator; + + // + // the connection table +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0013-Rebrand-Firefox-to-TorBrowser.patch b/www-client/torbrowser/files/12.0/0013-Rebrand-Firefox-to-TorBrowser.patch new file mode 100644 index 000000000000..81ee4e2b8b4c --- /dev/null +++ b/www-client/torbrowser/files/12.0/0013-Rebrand-Firefox-to-TorBrowser.patch @@ -0,0 +1,50 @@ +From 6a588618b49d59512c118802911d6f95c610299f Mon Sep 17 00:00:00 2001 +From: Erinn Clark <erinn@torproject.org> +Date: Wed, 25 Apr 2012 09:14:00 -0300 +Subject: [PATCH 13/16] Rebrand Firefox to TorBrowser + +This patch does some basic renaming of Firefox to TorBrowser. The rest of the +branding is done by images and icons. +--- + browser/branding/official/configure.sh | 2 +- + browser/branding/official/locales/en-US/brand.dtd | 6 +++--- + .../official/locales/en-US/brand.properties | 6 +++--- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/browser/branding/official/configure.sh b/browser/branding/official/configure.sh +index 4d3d297..e9b3738 100644 +--- a/browser/branding/official/configure.sh ++++ b/browser/branding/official/configure.sh +@@ -1,2 +1,2 @@ +-MOZ_APP_DISPLAYNAME=Firefox ++MOZ_APP_DISPLAYNAME=TorBrowser + MOZ_UA_BUILDID=20100101 +diff --git a/browser/branding/official/locales/en-US/brand.dtd b/browser/branding/official/locales/en-US/brand.dtd +index 142d79b..c137e04 100644 +--- a/browser/branding/official/locales/en-US/brand.dtd ++++ b/browser/branding/official/locales/en-US/brand.dtd +@@ -1,4 +1,4 @@ +-<!ENTITY brandShortName "Firefox"> +-<!ENTITY brandFullName "Mozilla Firefox"> +-<!ENTITY vendorShortName "Mozilla"> ++<!ENTITY brandShortName "TorBrowser"> ++<!ENTITY brandFullName "Tor Browser"> ++<!ENTITY vendorShortName "Tor Project"> + <!ENTITY trademarkInfo.part1 "Firefox and the Firefox logos are trademarks of the Mozilla Foundation."> +diff --git a/browser/branding/official/locales/en-US/brand.properties b/browser/branding/official/locales/en-US/brand.properties +index 5f3ad54..62ac2fd 100644 +--- a/browser/branding/official/locales/en-US/brand.properties ++++ b/browser/branding/official/locales/en-US/brand.properties +@@ -1,6 +1,6 @@ +-brandShortName=Firefox +-brandFullName=Mozilla Firefox +-vendorShortName=Mozilla ++brandShortName=TorBrowser ++brandFullName=Tor Browser ++vendorShortName=Tor Project + + homePageSingleStartMain=Firefox Start, a fast home page with built-in search + homePageImport=Import your home page from %S +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0014-Make-Download-manager-memory-only.patch b/www-client/torbrowser/files/12.0/0014-Make-Download-manager-memory-only.patch new file mode 100644 index 000000000000..66346885b781 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0014-Make-Download-manager-memory-only.patch @@ -0,0 +1,57 @@ +From e01aaa410e0e8fabf75841ad6b975fc3ff89e154 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 25 Apr 2012 13:39:35 -0700 +Subject: [PATCH 14/16] Make Download manager memory only. + +Solves https://trac.torproject.org/projects/tor/ticket/4017. + +Yes, this is an ugly hack. We *could* send the observer notification from +Torbutton to tell the download manager to switch to memory, but then we have +to dance around and tell it again if the user switches in and out of private +browsing mode.. + +The right way to do this is with a pref. Maybe I'll get to that someday, if +this breaks enough times in conflict. +--- + toolkit/components/downloads/nsDownloadManager.cpp | 4 ++-- + toolkit/components/downloads/nsDownloadManager.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/toolkit/components/downloads/nsDownloadManager.cpp b/toolkit/components/downloads/nsDownloadManager.cpp +index 17c9dcb..62e0ad9 100644 +--- a/toolkit/components/downloads/nsDownloadManager.cpp ++++ b/toolkit/components/downloads/nsDownloadManager.cpp +@@ -2002,7 +2002,7 @@ nsDownloadManager::Observe(nsISupports *aSubject, + if (NS_LITERAL_STRING("memory").Equals(aData)) + return SwitchDatabaseTypeTo(DATABASE_MEMORY); + else if (NS_LITERAL_STRING("disk").Equals(aData)) +- return SwitchDatabaseTypeTo(DATABASE_DISK); ++ return SwitchDatabaseTypeTo(DATABASE_MEMORY); + } + else if (strcmp(aTopic, "alertclickcallback") == 0) { + nsCOMPtr<nsIDownloadManagerUI> dmui = +@@ -2079,7 +2079,7 @@ nsDownloadManager::OnLeavePrivateBrowsingMode() + (void)ResumeAllDownloads(false); + + // Switch back to the on-disk DB again +- (void)SwitchDatabaseTypeTo(DATABASE_DISK); ++ //(void)SwitchDatabaseTypeTo(DATABASE_DISK); + + mInPrivateBrowsing = false; + } +diff --git a/toolkit/components/downloads/nsDownloadManager.h b/toolkit/components/downloads/nsDownloadManager.h +index 54312e4..cb63b52 100644 +--- a/toolkit/components/downloads/nsDownloadManager.h ++++ b/toolkit/components/downloads/nsDownloadManager.h +@@ -90,7 +90,7 @@ public: + + virtual ~nsDownloadManager(); + nsDownloadManager() : +- mDBType(DATABASE_DISK) ++ mDBType(DATABASE_MEMORY) + , mInPrivateBrowsing(false) + #ifdef DOWNLOAD_SCANNER + , mScanner(nsnull) +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0015-Add-DDG-and-StartPage-to-Omnibox.patch b/www-client/torbrowser/files/12.0/0015-Add-DDG-and-StartPage-to-Omnibox.patch new file mode 100644 index 000000000000..e0740ae09cfd --- /dev/null +++ b/www-client/torbrowser/files/12.0/0015-Add-DDG-and-StartPage-to-Omnibox.patch @@ -0,0 +1,84 @@ +From db055738d6431057670e8f219616170ed3644a9e Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 25 Apr 2012 15:03:46 -0700 +Subject: [PATCH 15/16] Add DDG and StartPage to Omnibox. + +You mean there are search engines that don't require captchas if you don't +have a cookie? Holy crap. Get those in there now. +--- + browser/locales/en-US/searchplugins/duckduckgo.xml | 29 ++++++++++++++++++++ + browser/locales/en-US/searchplugins/list.txt | 2 + + browser/locales/en-US/searchplugins/startpage.xml | 11 +++++++ + 3 files changed, 42 insertions(+), 0 deletions(-) + create mode 100644 browser/locales/en-US/searchplugins/duckduckgo.xml + create mode 100644 browser/locales/en-US/searchplugins/startpage.xml + +diff --git a/browser/locales/en-US/searchplugins/duckduckgo.xml b/browser/locales/en-US/searchplugins/duckduckgo.xml +new file mode 100644 +index 0000000..4f00b4d +--- /dev/null ++++ b/browser/locales/en-US/searchplugins/duckduckgo.xml +@@ -0,0 +1,29 @@ ++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> ++<ShortName>DuckDuckGo</ShortName> ++<Description>Duck Duck Go</Description> ++<InputEncoding>UTF-8</InputEncoding> ++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAANcNAADXDQAAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAAJyDsJmlk8pf6+v3s/v7+++zr/fcnIOyzJyDsgCcg7CYAAAAA ++AAAAAAAAAAAAAAAAAAAAAAAAAAAnIOwBJyDscCcg7PZttJ7/7Pfs//////++xO7/S5GA/ycg7P8n ++IOz2JyDscCcg7AEAAAAAAAAAAAAAAAAnIOwBJyDstScg7P8nIOz/Y8p5/2fHZf9Yv0z/YcF2/1rB ++Uv8nIOz/JyDs/ycg7P8nIOy1JyDsAQAAAAAAAAAAJyDscCcg7P8nIOz/JyDs/4jQoP/p9+n///// ++/05X3v9LkYD/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAJyDsJicg7PYnIOz/JyDs/zUu7f/+/v// ++//////////89N+7/JyDs/yUo7f8nIOz/JyDs/ycg7P8nIOz2JyDsJicg7IAnIOz/JyDs/ycg7P9h ++XPH////////////t/P//GIr2/wfD+/8Gyfz/DKv5/yM57/8nIOz/JyDs/ycg7H8nIOyzJyDs/ycg ++7P8nIOz/jov1////////////Otz9/w3G/P8cWfH/JSvt/ycg7P8nIOz/JyDs/ycg7P8nIOyzJyDs ++5icg7P8nIOz/JyDs/7u5+f///////////27l/v8E0v3/BNL9/wTQ/f8Oofn/IT7v/ycg7P8nIOz/ ++JyDs5icg7OYnIOz/JyDs/ycg7P/p6P3/uWsC////////////5fr//6Po/f8Thfb/DKv5/w6f+f8n IOz/JyDs/ycg7OYnIOyzJyDs/ycg7P8nIOz/9/b+/////////////////7lrAv/V1Pv/JyDs/ycg ++7P8nIOz/JyDs/ycg7P8nIOyzJyDsgCcg7P8nIOz/JyDs/8/N+///////////////////////iIX1 ++/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDsfycg7CYnIOz2JyDs/ycg7P9FP+7/q6n4/+7u/f/n5v3/ ++fXn0/yoj7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7CYAAAAAJyDscCcg7P8nIOz/wsD6/+no/f/Y ++1/z/eHTz/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7HAAAAAAAAAAACcg7AEnIOy1JyDs/ycg ++7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs/ycg7LUnIOwBAAAAAAAAAAAAAAAAJyDs ++AScg7HAnIOz2JyDs/ycg7P8nIOz/JyDs/ycg7P8nIOz/JyDs9icg7HAnIOwBAAAAAAAAAAAAAAAA ++AAAAAAAAAAAAAAAAJyDsJicg7IAnIOyzJyDs5icg7OYnIOyzJyDsgCcg7CYAAAAAAAAAAAAAAAAA ++AAAA+B8AAPAPAADAAwAAwAMAAIABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAACAAQAAwAMAAMAD ++AADwDwAA+B8AAA==</Image> ++<Url type="text/html" method="POST" template="https://duckduckgo.com/html/"> ++ <Param name="q" value="{searchTerms}"/> ++</Url> ++<SearchForm>https://duckduckgo.com/html/</SearchForm> ++</SearchPlugin> +diff --git a/browser/locales/en-US/searchplugins/list.txt b/browser/locales/en-US/searchplugins/list.txt +index 2a1141a..0466f4e 100644 +--- a/browser/locales/en-US/searchplugins/list.txt ++++ b/browser/locales/en-US/searchplugins/list.txt +@@ -1,7 +1,9 @@ + amazondotcom + bing ++duckduckgo + eBay + google ++startpage + twitter + wikipedia + yahoo +diff --git a/browser/locales/en-US/searchplugins/startpage.xml b/browser/locales/en-US/searchplugins/startpage.xml +new file mode 100644 +index 0000000..1a310b1 +--- /dev/null ++++ b/browser/locales/en-US/searchplugins/startpage.xml +@@ -0,0 +1,11 @@ ++<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> ++<ShortName>Startpage</ShortName> ++<Description>Start Page</Description> ++<InputEncoding>UTF-8</InputEncoding> ++<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2jkj+9YtD/vWLQ/71i0P+9otD/vaLRP72i0T+9YtE/vWLRP72i0T+9otD/vaNRP72jUT+9otF/vaLRf73kkv+9Yc///WJP//1iT//9Yk///rAmf/94Mz/+sCa//aRTv/1iUH/9ok///aJP//2i0H/9otB//aJQv/2iUL/9otC//aNRP/2jUT/9o1E//aNRP/6wpv////////////96dr/95dQ//aNRP/2kET/9pBG//aQRv/2kEb/9pBG//aRR//3lEz/95BH//mueP/7xJ3/959g//efYf/4p23//vDm//3p2//3kEr/95FJ//aRSf/niFH/95FK//aRSv/2mE//95hS/vq4iP/////////////////81bj/95xZ//q4iP//////+bF+//eZT//njFT/PSqi/2xGjv/2mVD/951V/vedVv783cX///////vQrf/++PP///////748//+8uj///////m3gf/olFr/PSuj/w8Pt/9sSJD/951V//eeWf73oVv++8ul///////5sXf/+KRi//vRsf////////////3r3v/olF//Piyk/w8Pt/9sSJH/+J5Z//ieWv/3oV/++KZf/vihXP/97N7//vn0//zTs//6wJP/+bBy//q6iP/onW//Piyl/w8Pt/8fGbH/m2iB/+icY//4pGD/96hl/viqZf74pmD/+Kxr//3iy/////////n1//ivbP/onGj/Pi2m/w8Pt/8uJKz/fFeQ/x8Zsf8+Lqb/6J9r//ivbP74rm3++Klm//mpZv/5q2f/+bR9//m0e//poW7/Pi6n/w8Pt/9sTZj/+Ktp//ira/+rd4P/Dw+3/4xijv/5snH++LN1/vmvbf/5r23/+a5t//mvb//4r2//TTuk/w8Pt/8fGrL/6ah1//ivcP/4r3P/q3yI/w8Pt/+MZpP/+bN5/vm4ev75t3X/+bV1//m1df/5t3X/+Ld3/8qUhP98XZn/Hxqz/+mse//5t3f/2p+B/x8as/8PD7f/u4qK//m7fv76u4D++bl7//m3fP/5uXz/+bl8//m5fP/5t3z/+bl//x8as/9NPKf/fWCb/x8as/8PD7f/bVOh//q5f//6v4X++sGI/vm9g//5voX/+b6F//m9hf/6vYX/+r6F//nCh/+bepr/Hxu0/w8Pt/8PD7f/fWOh//q+hf/6wof/+saN/vrGjf75xIv/+ceL//nEi//5xIv/+sSL//rHi//6x43/+ceN/+m7kP+7lpj/6ruQ//rHkP/6x43/+seQ//rLlf76ypT++seR//rJkf/6yZH/+seR//rJkf/6yZH/+8mR//vJlP/7yZT/+smU//rJlP/6yZT/+8yV//rJlf/6zpn+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</Image> ++ ++<Url type="text/html" method="POST" template="https://startpage.com/do/search"> ++ <Param name="q" value="{searchTerms}"/> ++</Url> ++<SearchForm>https://startpage.com/do/search/</SearchForm> ++</SearchPlugin> +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch b/www-client/torbrowser/files/12.0/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch new file mode 100644 index 000000000000..5a08ed4ccef4 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0016-Adapt-Steven-Michaud-s-Mac-crashfix-patch-for-FF12.patch @@ -0,0 +1,544 @@ +From 262403fb627ca452bfbcaf06fd6ad965f156ed18 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Thu, 26 Apr 2012 10:54:24 -0700 +Subject: [PATCH 16/16] Adapt Steven Michaud's Mac crashfix patch for FF12. + +Source is: https://bugzilla.mozilla.org/show_bug.cgi?id=715885#c35 + +Some minor tweaks were needed to get it to apply to FF12 and to compile on +MacOS. +--- + widget/Makefile.in | 1 + + widget/cocoa/nsChildView.mm | 35 +++++++++++++-------- + widget/gtk2/nsDragService.cpp | 2 +- + widget/gtk2/nsWindow.cpp | 2 +- + widget/nsIDragService.idl | 4 +-- + widget/nsPIDragService.idl | 48 +++++++++++++++++++++++++++++ + widget/qt/nsDragService.h | 2 + + widget/windows/Makefile.in | 4 ++ + widget/windows/nsDragService.cpp | 13 +++++--- + widget/windows/nsDragService.h | 12 +++--- + widget/windows/nsNativeDragSource.cpp | 7 ++-- + widget/windows/nsNativeDragTarget.cpp | 28 ++++++++++------ + widget/windows/nsPIDragServiceWindows.idl | 46 +++++++++++++++++++++++++++ + widget/xpwidgets/nsBaseDragService.cpp | 16 +++++++++- + widget/xpwidgets/nsBaseDragService.h | 9 ++--- + 15 files changed, 180 insertions(+), 49 deletions(-) + create mode 100644 widget/nsPIDragService.idl + create mode 100644 widget/windows/nsPIDragServiceWindows.idl + +diff --git a/widget/Makefile.in b/widget/Makefile.in +index 4a3405b..4c105a4 100644 +--- a/widget/Makefile.in ++++ b/widget/Makefile.in +@@ -138,6 +138,7 @@ XPIDLSRCS = \ + nsIClipboardDragDropHooks.idl \ + nsIClipboardDragDropHookList.idl \ + nsIDragSession.idl \ ++ nsPIDragService.idl \ + nsIDragService.idl \ + nsIFormatConverter.idl \ + nsIClipboard.idl \ +diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm +index 7f738a1..0149ab1 100644 +--- a/widget/cocoa/nsChildView.mm ++++ b/widget/cocoa/nsChildView.mm +@@ -4566,11 +4566,12 @@ NSEvent* gLastDragMouseDownEvent = nil; + if (!dragService) { + dragService = do_GetService(kDragServiceContractID); + } ++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService); + + if (dragService) { + NSPoint pnt = [NSEvent mouseLocation]; + FlipCocoaScreenCoordinate(pnt); +- dragService->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y)); ++ dragServicePriv->DragMoved(NSToIntRound(pnt.x), NSToIntRound(pnt.y)); + } + } + +@@ -4591,11 +4592,13 @@ NSEvent* gLastDragMouseDownEvent = nil; + } + + if (mDragService) { +- // set the dragend point from the current mouse location +- nsDragService* dragService = static_cast<nsDragService *>(mDragService); +- NSPoint pnt = [NSEvent mouseLocation]; +- FlipCocoaScreenCoordinate(pnt); +- dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y))); ++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService); ++ if (dragServicePriv) { ++ // set the dragend point from the current mouse location ++ NSPoint pnt = [NSEvent mouseLocation]; ++ FlipCocoaScreenCoordinate(pnt); ++ dragServicePriv->SetDragEndPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)); ++ } + + // XXX: dropEffect should be updated per |operation|. + // As things stand though, |operation| isn't well handled within "our" +@@ -4606,13 +4609,19 @@ NSEvent* gLastDragMouseDownEvent = nil; + // value for NSDragOperationGeneric that is passed by other applications. + // All that said, NSDragOperationNone is still reliable. + if (operation == NSDragOperationNone) { +- nsCOMPtr<nsIDOMDataTransfer> dataTransfer; +- dragService->GetDataTransfer(getter_AddRefs(dataTransfer)); +- nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS = +- do_QueryInterface(dataTransfer); +- +- if (dataTransferNS) +- dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE); ++ nsCOMPtr<nsIDragSession> dragSession; ++ mDragService->GetCurrentSession(getter_AddRefs(dragSession)); ++ if (dragSession) { ++ nsCOMPtr<nsIDOMDataTransfer> dataTransfer; ++ dragSession->GetDataTransfer(getter_AddRefs(dataTransfer)); ++ if (dataTransfer) { ++ nsCOMPtr<nsIDOMNSDataTransfer> dataTransferNS = ++ do_QueryInterface(dataTransfer); ++ if (dataTransferNS) { ++ dataTransferNS->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE); ++ } ++ } ++ } + } + + mDragService->EndDragSession(true); +diff --git a/widget/gtk2/nsDragService.cpp b/widget/gtk2/nsDragService.cpp +index ca5a42c..876fd55 100644 +--- a/widget/gtk2/nsDragService.cpp ++++ b/widget/gtk2/nsDragService.cpp +@@ -1334,7 +1334,7 @@ nsDragService::SourceEndDragSession(GdkDragContext *aContext, + GdkDisplay* display = gdk_display_get_default(); + if (display) { + gdk_display_get_pointer(display, NULL, &x, &y, NULL); +- SetDragEndPoint(nsIntPoint(x, y)); ++ SetDragEndPoint(x, y); + } + + // Either the drag was aborted or the drop occurred outside the app. +diff --git a/widget/gtk2/nsWindow.cpp b/widget/gtk2/nsWindow.cpp +index 5e4afee..25c394b 100644 +--- a/widget/gtk2/nsWindow.cpp ++++ b/widget/gtk2/nsWindow.cpp +@@ -3698,7 +3698,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget, + if (display) { + // get the current cursor position + gdk_display_get_pointer(display, NULL, &x, &y, NULL); +- ((nsDragService *)dragService.get())->SetDragEndPoint(nsIntPoint(x, y)); ++ ((nsDragService *)dragService.get())->SetDragEndPoint(x, y); + } + dragService->EndDragSession(true); + +diff --git a/widget/nsIDragService.idl b/widget/nsIDragService.idl +index e42c578..ef8c46f 100644 +--- a/widget/nsIDragService.idl ++++ b/widget/nsIDragService.idl +@@ -48,7 +48,7 @@ interface nsIDOMDragEvent; + interface nsIDOMDataTransfer; + interface nsISelection; + +-[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052), builtinclass] ++[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)] + interface nsIDragService : nsISupports + { + const long DRAGDROP_ACTION_NONE = 0; +@@ -145,8 +145,6 @@ interface nsIDragService : nsISupports + */ + void suppress(); + void unsuppress(); +- +- [noscript] void dragMoved(in long aX, in long aY); + }; + + +diff --git a/widget/nsPIDragService.idl b/widget/nsPIDragService.idl +new file mode 100644 +index 0000000..93a144d +--- /dev/null ++++ b/widget/nsPIDragService.idl +@@ -0,0 +1,48 @@ ++/* ***** 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/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is mozilla.org code. ++ * ++ * The Initial Developer of the Original Code is ++ * The Mozilla Foundation. ++ * Portions created by the Initial Developer are Copyright (C) 2012 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Steven Michaud <smichaud@pobox.com> ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#include "nsISupports.idl" ++ ++[scriptable, uuid(FAD8C90B-8E1D-446A-9B6C-241486A85CBD)] ++interface nsPIDragService : nsISupports ++{ ++ void dragMoved(in long aX, in long aY); ++ ++ PRUint16 getInputSource(); ++ ++ void setDragEndPoint(in long aX, in long aY); ++}; +diff --git a/widget/qt/nsDragService.h b/widget/qt/nsDragService.h +index 5a3e5bb..50dcfac 100644 +--- a/widget/qt/nsDragService.h ++++ b/widget/qt/nsDragService.h +@@ -50,6 +50,8 @@ public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDRAGSERVICE + ++ NS_IMETHOD DragMoved(PRInt32 aX, PRInt32 aY); ++ + nsDragService(); + + private: +diff --git a/widget/windows/Makefile.in b/widget/windows/Makefile.in +index c9327f8..3298997 100644 +--- a/widget/windows/Makefile.in ++++ b/widget/windows/Makefile.in +@@ -119,6 +119,10 @@ ifdef MOZ_ENABLE_D3D10_LAYER + DEFINES += -DMOZ_ENABLE_D3D10_LAYER + endif + ++XPIDLSRCS += \ ++ nsPIDragServiceWindows.idl \ ++ $(NULL) ++ + SHARED_LIBRARY_LIBS = \ + ../xpwidgets/$(LIB_PREFIX)xpwidgets_s.$(LIB_SUFFIX) \ + $(NULL) +diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp +index 8c5df7e..1cf9995 100644 +--- a/widget/windows/nsDragService.cpp ++++ b/widget/windows/nsDragService.cpp +@@ -97,6 +97,8 @@ nsDragService::~nsDragService() + NS_IF_RELEASE(mDataObject); + } + ++NS_IMPL_ISUPPORTS_INHERITED1(nsDragService, nsBaseDragService, nsPIDragServiceWindows) ++ + bool + nsDragService::CreateDragImage(nsIDOMNode *aDOMNode, + nsIScriptableRegion *aRegion, +@@ -350,7 +352,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj, + POINT cpos; + cpos.x = GET_X_LPARAM(pos); + cpos.y = GET_Y_LPARAM(pos); +- SetDragEndPoint(nsIntPoint(cpos.x, cpos.y)); ++ SetDragEndPoint(cpos.x, cpos.y); + EndDragSession(true); + + mDoingDrag = false; +@@ -468,25 +470,26 @@ nsDragService::GetData(nsITransferable * aTransferable, PRUint32 anItem) + + //--------------------------------------------------------- + NS_IMETHODIMP +-nsDragService::SetIDataObject(IDataObject * aDataObj) ++nsDragService::SetIDataObject(nsISupports * aDataObj) + { ++ IDataObject *dataObj = (IDataObject*) aDataObj; + // When the native drag starts the DragService gets + // the IDataObject that is being dragged + NS_IF_RELEASE(mDataObject); +- mDataObject = aDataObj; ++ mDataObject = dataObj; + NS_IF_ADDREF(mDataObject); + + return NS_OK; + } + + //--------------------------------------------------------- +-void ++NS_IMETHODIMP + nsDragService::SetDroppedLocal() + { + // Sent from the native drag handler, letting us know + // a drop occurred within the application vs. outside of it. + mSentLocalDropEvent = true; +- return; ++ return NS_OK; + } + + //------------------------------------------------------------------------- +diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h +index 87d6cc9..04c8746 100644 +--- a/widget/windows/nsDragService.h ++++ b/widget/windows/nsDragService.h +@@ -39,6 +39,7 @@ + #define nsDragService_h__ + + #include "nsBaseDragService.h" ++#include "nsPIDragServiceWindows.h" + #include <windows.h> + #include <shlobj.h> + +@@ -52,12 +53,15 @@ class nsString; + * Native Win32 DragService wrapper + */ + +-class nsDragService : public nsBaseDragService ++class nsDragService : public nsBaseDragService, public nsPIDragServiceWindows + { + public: + nsDragService(); + virtual ~nsDragService(); +- ++ ++ NS_DECL_ISUPPORTS_INHERITED ++ NS_DECL_NSPIDRAGSERVICEWINDOWS ++ + // nsIDragService + NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode, + nsISupportsArray *anArrayTransferables, +@@ -71,13 +75,9 @@ public: + NS_IMETHOD EndDragSession(bool aDoneDrag); + + // native impl. +- NS_IMETHOD SetIDataObject(IDataObject * aDataObj); + NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj, + PRUint32 aActionType); + +- // A drop occurred within the application vs. outside of it. +- void SetDroppedLocal(); +- + protected: + nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj); + +diff --git a/widget/windows/nsNativeDragSource.cpp b/widget/windows/nsNativeDragSource.cpp +index e51101e..0fe6ffe 100644 +--- a/widget/windows/nsNativeDragSource.cpp ++++ b/widget/windows/nsNativeDragSource.cpp +@@ -42,7 +42,7 @@ + #include "nsIServiceManager.h" + #include "nsToolkit.h" + #include "nsWidgetsCID.h" +-#include "nsIDragService.h" ++#include "nsDragService.h" + + static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID); + +@@ -101,9 +101,10 @@ STDMETHODIMP + nsNativeDragSource::QueryContinueDrag(BOOL fEsc, DWORD grfKeyState) + { + nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID); +- if (dragService) { ++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(dragService); ++ if (dragServicePriv) { + DWORD pos = ::GetMessagePos(); +- dragService->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos)); ++ dragServicePriv->DragMoved(GET_X_LPARAM(pos), GET_Y_LPARAM(pos)); + } + + if (fEsc) { +diff --git a/widget/windows/nsNativeDragTarget.cpp b/widget/windows/nsNativeDragTarget.cpp +index cf6196b..82ad3c6 100644 +--- a/widget/windows/nsNativeDragTarget.cpp ++++ b/widget/windows/nsNativeDragTarget.cpp +@@ -209,7 +209,11 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT) + event.isControl = IsKeyDown(NS_VK_CONTROL); + event.isMeta = false; + event.isAlt = IsKeyDown(NS_VK_ALT); +- event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource(); ++ event.inputSource = 0; ++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService); ++ if (dragServicePriv) { ++ dragServicePriv->GetInputSource(&event.inputSource); ++ } + + mWindow->DispatchEvent(&event, status); + } +@@ -296,9 +300,8 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource, + // This cast is ok because in the constructor we created a + // the actual implementation we wanted, so we know this is + // a nsDragService. It should be a private interface, though. +- nsDragService * winDragService = +- static_cast<nsDragService *>(mDragService); +- winDragService->SetIDataObject(pIDataSource); ++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService); ++ winDragService->SetIDataObject((nsISupports*)pIDataSource); + + // Now process the native drag state and then dispatch the event + ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect); +@@ -436,8 +439,8 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData, + // This cast is ok because in the constructor we created a + // the actual implementation we wanted, so we know this is + // a nsDragService (but it should still be a private interface) +- nsDragService* winDragService = static_cast<nsDragService*>(mDragService); +- winDragService->SetIDataObject(pData); ++ nsCOMPtr<nsPIDragServiceWindows> winDragService = do_QueryInterface(mDragService); ++ winDragService->SetIDataObject((nsISupports*)pData); + + // NOTE: ProcessDrag spins the event loop which may destroy arbitrary objects. + // We use strong refs to prevent it from destroying these: +@@ -461,11 +464,14 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData, + // tell the drag service we're done with the session + // Use GetMessagePos to get the position of the mouse at the last message + // seen by the event loop. (Bug 489729) +- DWORD pos = ::GetMessagePos(); +- POINT cpos; +- cpos.x = GET_X_LPARAM(pos); +- cpos.y = GET_Y_LPARAM(pos); +- winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y)); ++ nsCOMPtr<nsPIDragService> dragServicePriv = do_QueryInterface(mDragService); ++ if (dragServicePriv) { ++ DWORD pos = ::GetMessagePos(); ++ POINT cpos; ++ cpos.x = GET_X_LPARAM(pos); ++ cpos.y = GET_Y_LPARAM(pos); ++ dragServicePriv->SetDragEndPoint(cpos.x, cpos.y); ++ } + serv->EndDragSession(true); + + // release the ref that was taken in DragEnter +diff --git a/widget/windows/nsPIDragServiceWindows.idl b/widget/windows/nsPIDragServiceWindows.idl +new file mode 100644 +index 0000000..c8a46dd +--- /dev/null ++++ b/widget/windows/nsPIDragServiceWindows.idl +@@ -0,0 +1,46 @@ ++/* ***** 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/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is mozilla.org code. ++ * ++ * The Initial Developer of the Original Code is ++ * The Mozilla Foundation. ++ * Portions created by the Initial Developer are Copyright (C) 2012 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Steven Michaud <smichaud@pobox.com> ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#include "nsISupports.idl" ++ ++[scriptable, uuid(6FC2117D-5EB4-441A-9C12-62A783BEBC0C)] ++interface nsPIDragServiceWindows : nsISupports ++{ ++ void setIDataObject(in nsISupports aDataObj); ++ ++ void setDroppedLocal(); ++}; +diff --git a/widget/xpwidgets/nsBaseDragService.cpp b/widget/xpwidgets/nsBaseDragService.cpp +index 342a036..87e28f7 100644 +--- a/widget/xpwidgets/nsBaseDragService.cpp ++++ b/widget/xpwidgets/nsBaseDragService.cpp +@@ -88,7 +88,7 @@ nsBaseDragService::~nsBaseDragService() + { + } + +-NS_IMPL_ISUPPORTS2(nsBaseDragService, nsIDragService, nsIDragSession) ++NS_IMPL_ISUPPORTS3(nsBaseDragService, nsIDragService, nsPIDragService, nsIDragSession) + + //--------------------------------------------------------- + NS_IMETHODIMP +@@ -436,6 +436,20 @@ nsBaseDragService::DragMoved(PRInt32 aX, PRInt32 aY) + return NS_OK; + } + ++NS_IMETHODIMP ++nsBaseDragService::SetDragEndPoint(PRInt32 aX, PRInt32 aY) ++{ ++ mEndDragPoint = nsIntPoint(aX, aY); ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsBaseDragService::GetInputSource(PRUint16* aInputSource) ++{ ++ *aInputSource = mInputSource; ++ return NS_OK; ++} ++ + static nsIPresShell* + GetPresShellForContent(nsIDOMNode* aDOMNode) + { +diff --git a/widget/xpwidgets/nsBaseDragService.h b/widget/xpwidgets/nsBaseDragService.h +index 290c0cb..2ceac2b 100644 +--- a/widget/xpwidgets/nsBaseDragService.h ++++ b/widget/xpwidgets/nsBaseDragService.h +@@ -39,6 +39,7 @@ + #define nsBaseDragService_h__ + + #include "nsIDragService.h" ++#include "nsPIDragService.h" + #include "nsIDragSession.h" + #include "nsITransferable.h" + #include "nsISupportsArray.h" +@@ -64,6 +65,7 @@ class nsICanvasElementExternal; + */ + + class nsBaseDragService : public nsIDragService, ++ public nsPIDragService, + public nsIDragSession + { + +@@ -74,14 +76,11 @@ public: + //nsISupports + NS_DECL_ISUPPORTS + +- //nsIDragSession and nsIDragService ++ //nsIDragSession, nsIDragService and nsPIDragService + NS_DECL_NSIDRAGSERVICE ++ NS_DECL_NSPIDRAGSERVICE + NS_DECL_NSIDRAGSESSION + +- void SetDragEndPoint(nsIntPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; } +- +- PRUint16 GetInputSource() { return mInputSource; } +- + protected: + + /** +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0017-Make-nsICacheService.EvictEntries-synchronous.patch b/www-client/torbrowser/files/12.0/0017-Make-nsICacheService.EvictEntries-synchronous.patch new file mode 100644 index 000000000000..5354027d7dfd --- /dev/null +++ b/www-client/torbrowser/files/12.0/0017-Make-nsICacheService.EvictEntries-synchronous.patch @@ -0,0 +1,44 @@ +From f7bdc9274aa6dc8efccc50d18dbb287225aa6c27 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Tue, 1 May 2012 15:02:03 -0700 +Subject: [PATCH 17/17] Make nsICacheService.EvictEntries synchronous + +This fixes a race condition that allows cache-based EverCookies to persist for +a brief time (on the order of minutes?) after cache clearing/"New Identity". + +https://trac.torproject.org/projects/tor/ticket/5715 +--- + netwerk/cache/nsCacheService.cpp | 15 +++++++++++++-- + 1 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/netwerk/cache/nsCacheService.cpp b/netwerk/cache/nsCacheService.cpp +index 015e49e..1ef0db1 100644 +--- a/netwerk/cache/nsCacheService.cpp ++++ b/netwerk/cache/nsCacheService.cpp +@@ -1415,10 +1415,21 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor) + return NS_OK; + } + +- + NS_IMETHODIMP nsCacheService::EvictEntries(nsCacheStoragePolicy storagePolicy) + { +- return EvictEntriesForClient(nsnull, storagePolicy); ++ NS_IMETHODIMP r; ++ r = EvictEntriesForClient(nsnull, storagePolicy); ++ ++ // XXX: Bloody hack until we get this notifier in FF14.0: ++ // https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsICacheListener#onCacheEntryDoomed%28%29 ++ if (storagePolicy == nsICache::STORE_ANYWHERE && ++ NS_IsMainThread() && gService && gService->mInitialized) { ++ nsCacheServiceAutoLock lock; ++ gService->DoomActiveEntries(); ++ gService->ClearDoomList(); ++ (void) SyncWithCacheIOThread(); ++ } ++ return r; + } + + NS_IMETHODIMP nsCacheService::GetCacheIOTarget(nsIEventTarget * *aCacheIOTarget) +-- +1.7.5.4 + diff --git a/www-client/torbrowser/files/12.0/0018-Prevent-WebSocket-DNS-leak.patch b/www-client/torbrowser/files/12.0/0018-Prevent-WebSocket-DNS-leak.patch new file mode 100644 index 000000000000..9b309872b9a4 --- /dev/null +++ b/www-client/torbrowser/files/12.0/0018-Prevent-WebSocket-DNS-leak.patch @@ -0,0 +1,132 @@ +From 93199734c06485660fb922c61f740191648a6dc6 Mon Sep 17 00:00:00 2001 +From: Mike Perry <mikeperry-git@torproject.org> +Date: Wed, 2 May 2012 17:44:39 -0700 +Subject: [PATCH 18/18] Prevent WebSocket DNS leak. + +This is due to an improper implementation of the WebSocket spec by Mozilla. + +"There MUST be no more than one connection in a CONNECTING state. If multiple +connections to the same IP address are attempted simultaneously, the client +MUST serialize them so that there is no more than one connection at a time +running through the following steps. + +If the client cannot determine the IP address of the remote host (for +example, because all communication is being done through a proxy server that +performs DNS queries itself), then the client MUST assume for the purposes of +this step that each host name refers to a distinct remote host," + +https://tools.ietf.org/html/rfc6455#page-15 + +They implmented the first paragraph, but not the second... + +While we're at it, we also prevent the DNS service from being used to look up +anything other than IP addresses if socks_remote_dns is set to true, so this +bug can't turn up in other components or due to 3rd party addons. +--- + netwerk/dns/nsDNSService2.cpp | 24 ++++++++++++++++++++++- + netwerk/dns/nsDNSService2.h | 1 + + netwerk/protocol/websocket/WebSocketChannel.cpp | 8 +++++- + 3 files changed, 30 insertions(+), 3 deletions(-) + +diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp +index 1bd5f38..eda0e48 100644 +--- a/netwerk/dns/nsDNSService2.cpp ++++ b/netwerk/dns/nsDNSService2.cpp +@@ -404,6 +404,7 @@ nsDNSService::Init() + bool enableIDN = true; + bool disableIPv6 = false; + bool disablePrefetch = false; ++ bool disableDNS = false; + int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT; + + nsAdoptingCString ipv4OnlyDomains; +@@ -427,6 +428,10 @@ nsDNSService::Init() + + // If a manual proxy is in use, disable prefetch implicitly + prefs->GetIntPref("network.proxy.type", &proxyType); ++ ++ // If the user wants remote DNS, we should fail any lookups that still ++ // make it here. ++ prefs->GetBoolPref("network.proxy.socks_remote_dns", &disableDNS); + } + + if (mFirstTime) { +@@ -444,7 +449,7 @@ nsDNSService::Init() + + // Monitor these to see if there is a change in proxy configuration + // If a manual proxy is in use, disable prefetch implicitly +- prefs->AddObserver("network.proxy.type", this, false); ++ prefs->AddObserver("network.proxy.", this, false); + } + } + +@@ -473,6 +478,7 @@ nsDNSService::Init() + mIDN = idn; + mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership + mDisableIPv6 = disableIPv6; ++ mDisableDNS = disableDNS; + + // Disable prefetching either by explicit preference or if a manual proxy is configured + mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL); +@@ -584,6 +590,14 @@ nsDNSService::AsyncResolve(const nsACString &hostname, + if (mDisablePrefetch && (flags & RESOLVE_SPECULATE)) + return NS_ERROR_DNS_LOOKUP_QUEUE_FULL; + ++ PRNetAddr tempAddr; ++ if (mDisableDNS) { ++ // Allow IP lookups through, but nothing else. ++ if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) { ++ return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED? ++ } ++ } ++ + res = mResolver; + idn = mIDN; + } +@@ -670,6 +684,14 @@ nsDNSService::Resolve(const nsACString &hostname, + MutexAutoLock lock(mLock); + res = mResolver; + idn = mIDN; ++ ++ PRNetAddr tempAddr; ++ if (mDisableDNS) { ++ // Allow IP lookups through, but nothing else. ++ if (PR_StringToNetAddr(hostname.BeginReading(), &tempAddr) != PR_SUCCESS) { ++ return NS_ERROR_UNKNOWN_PROXY_HOST; // XXX: NS_ERROR_NOT_IMPLEMENTED? ++ } ++ } + } + NS_ENSURE_TRUE(res, NS_ERROR_OFFLINE); + +diff --git a/netwerk/dns/nsDNSService2.h b/netwerk/dns/nsDNSService2.h +index 1749b41..3ec8eba 100644 +--- a/netwerk/dns/nsDNSService2.h ++++ b/netwerk/dns/nsDNSService2.h +@@ -70,4 +70,5 @@ private: + bool mDisableIPv6; + bool mDisablePrefetch; + bool mFirstTime; ++ bool mDisableDNS; + }; +diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp +index 22873d3..0875c12 100644 +--- a/netwerk/protocol/websocket/WebSocketChannel.cpp ++++ b/netwerk/protocol/websocket/WebSocketChannel.cpp +@@ -1875,8 +1875,12 @@ WebSocketChannel::ApplyForAdmission() + LOG(("WebSocketChannel::ApplyForAdmission: checking for concurrent open\n")); + nsCOMPtr<nsIThread> mainThread; + NS_GetMainThread(getter_AddRefs(mainThread)); +- dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest)); +- NS_ENSURE_SUCCESS(rv, rv); ++ rv = dns->AsyncResolve(hostName, 0, this, mainThread, getter_AddRefs(mDNSRequest)); ++ if (NS_FAILED(rv)) { ++ // Fall back to hostname on dispatch failure ++ mDNSRequest = nsnull; ++ OnLookupComplete(nsnull, nsnull, rv); ++ } + + return NS_OK; + } +-- +1.7.5.4 + diff --git a/www-client/torbrowser/metadata.xml b/www-client/torbrowser/metadata.xml new file mode 100644 index 000000000000..27d62a01a6a2 --- /dev/null +++ b/www-client/torbrowser/metadata.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+ <maintainer>
+ <email>hasufell@gentoo.org</email>
+ <name>Julian Ospald</name>
+ <description>Maintainer. Assign bugs to him</description>
+ </maintainer>
+ <maintainer>
+ <email>poncho@spahan.ch</email>
+ <name>Poncho</name>
+ <description>Proxy maintainer. CC him on bugs</description>
+ </maintainer>
+ <use>
+ <flag name="bindist">Disable official Firefox branding (icons, name) which
+ are not binary-redistributable according to upstream.</flag>
+ <flag name="custom-optimization">Fine-tune custom compiler
+ optimizations, setting this is not recommended.</flag>
+ <flag name="crashreporter">Enable crashreporter for mozilla upstream, debugging
+ symbols are not required for reporting crashes.</flag>
+ <flag name="ipc">Use inter-process communication between tabs and plugins.
+ Allows for greater stability in case of plugin crashes</flag>
+ <flag name="pgo">Add support for profile-guided optimization using gcc-4.5,
+ for faster binaries. This option will double the compile time.</flag>
+ <flag name="system-sqlite">Use the system-wide <pkg>dev-db/sqlite</pkg>
+ installation with secure-delete enabled</flag>
+ <flag name="webm">Use system <pkg>media-libs/libvpx</pkg> for HTML5 WebM
+ video support.</flag>
+ </use>
+</pkgmetadata>
diff --git a/www-client/torbrowser/torbrowser-12.0.ebuild b/www-client/torbrowser/torbrowser-12.0.ebuild new file mode 100644 index 000000000000..87250c588527 --- /dev/null +++ b/www-client/torbrowser/torbrowser-12.0.ebuild @@ -0,0 +1,291 @@ +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/www-client/torbrowser/torbrowser-12.0.ebuild,v 1.1 2012/05/12 22:24:39 hasufell Exp $ + +EAPI="3" +VIRTUALX_REQUIRED="pgo" +WANT_AUTOCONF="2.1" + +MY_PN="firefox" +# latest version of the torbrowser-bundle we use the profile-folder from +# https://www.torproject.org/dist/torbrowser/linux/ +TB_V="2.2.35-11" + +# Patch version +PATCH="${MY_PN}-12.0-patches-0.1" +# Upstream ftp release URI that's used by mozlinguas.eclass +# We don't use the http mirror because it deletes old tarballs. +MOZ_FTP_URI="ftp://ftp.mozilla.org/pub/${MY_PN}/releases/" + +inherit check-reqs flag-o-matic toolchain-funcs eutils gnome2-utils mozconfig-3 multilib pax-utils autotools python virtualx + +DESCRIPTION="Torbrowser without vidalia or tor, includes profile and extensions" +HOMEPAGE="https://www.torproject.org/projects/torbrowser.html.en" + +# may work on other arches, but untested +KEYWORDS="~amd64 ~x86" +SLOT="0" +# BSD license applies to torproject-related code like the patches +# GPL-2 and MIT applies to the extensions +# icons are under CCPL-Attribution-3.0 +LICENSE="|| ( MPL-1.1 GPL-2 LGPL-2.1 ) + BSD + GPL-2 + MIT + CCPL-Attribution-3.0" +IUSE="bindist +crashreporter +ipc pgo selinux system-sqlite +webm" + +SRC_URI="${SRC_URI} + http://dev.gentoo.org/~anarchy/mozilla/patchsets/${PATCH}.tar.xz + ${MOZ_FTP_URI}/${PV}/source/${MY_PN}-${PV}.source.tar.bz2 + amd64? ( https://www.torproject.org/dist/${PN}/linux/tor-browser-gnu-linux-x86_64-${TB_V}-dev-en-US.tar.gz ) + x86? ( https://www.torproject.org/dist/${PN}/linux/tor-browser-gnu-linux-i686-${TB_V}-dev-en-US.tar.gz )" + +ASM_DEPEND=">=dev-lang/yasm-1.1" + +# Mesa 7.10 needed for WebGL + bugfixes +RDEPEND=" + >=sys-devel/binutils-2.16.1 + >=dev-libs/nss-3.13.3 + >=dev-libs/nspr-4.9 + >=dev-libs/glib-2.26:2 + >=media-libs/mesa-7.10 + media-libs/libpng[apng] + virtual/libffi + system-sqlite? ( >=dev-db/sqlite-3.7.10[fts3,secure-delete,threadsafe,unlock-notify,debug=] ) + webm? ( >=media-libs/libvpx-1.0.0 + media-libs/alsa-lib ) + crashreporter? ( net-misc/curl ) + selinux? ( sec-policy/selinux-mozilla )" +# We don't use PYTHON_DEPEND/PYTHON_USE_WITH for some silly reason +DEPEND="${RDEPEND} + virtual/pkgconfig + pgo? ( + =dev-lang/python-2*[sqlite] + >=sys-devel/gcc-4.5 ) + webm? ( x86? ( ${ASM_DEPEND} ) + amd64? ( ${ASM_DEPEND} ) + virtual/opengl )" + +S="${WORKDIR}/mozilla-release" + +QA_PRESTRIPPED="usr/$(get_libdir)/${PN}/${MY_PN}/firefox" + +pkg_setup() { + moz_pkgsetup + + # Avoid PGO profiling problems due to enviroment leakage + # These should *always* be cleaned up anyway + unset DBUS_SESSION_BUS_ADDRESS \ + DISPLAY \ + ORBIT_SOCKETDIR \ + SESSION_MANAGER \ + XDG_SESSION_COOKIE \ + XAUTHORITY + + if ! use bindist; then + einfo + elog "You are enabling official branding. You may not redistribute this build" + elog "to any users on your network or the internet. Doing so puts yourself into" + elog "a legal problem with Mozilla Foundation" + elog "You can disable it by emerging ${PN} _with_ the bindist USE-flag" + fi + + if use pgo; then + einfo + ewarn "You will do a double build for profile guided optimization." + ewarn "This will result in your build taking at least twice as long as before." + fi + + # Ensure we have enough disk space to compile + if use pgo || use debug || use test ; then + CHECKREQS_DISK_BUILD="8G" + else + CHECKREQS_DISK_BUILD="4G" + fi + check-reqs_pkg_setup +} + +src_prepare() { + # Apply our patches + EPATCH_SUFFIX="patch" \ + EPATCH_FORCE="yes" \ + epatch "${WORKDIR}/firefox" + + # Torbrowser patches for firefox 12, check regularly/for every version-bump + # https://gitweb.torproject.org/torbrowser.git/history/HEAD:/src/current-patches + EPATCH_SUFFIX="patch" \ + EPATCH_FORCE="yes" \ + epatch "${FILESDIR}/${PV}" + + # Allow user to apply any additional patches without modifing ebuild + epatch_user + + # Enable gnomebreakpad + if use debug ; then + sed -i -e "s:GNOME_DISABLE_CRASH_DIALOG=1:GNOME_DISABLE_CRASH_DIALOG=0:g" \ + "${S}"/build/unix/run-mozilla.sh || die "sed failed!" + fi + + # Disable gnomevfs extension + sed -i -e "s:gnomevfs::" "${S}/"browser/confvars.sh \ + -e "s:gnomevfs::" "${S}/"xulrunner/confvars.sh \ + || die "Failed to remove gnomevfs extension" + + # Ensure that plugins dir is enabled as default + # and is different from firefox-location + sed -i -e "s:/usr/lib/mozilla/plugins:/usr/$(get_libdir)/${PN}/${MY_PN}/plugins:" \ + "${S}"/xpcom/io/nsAppFileLocationProvider.cpp || die "sed failed to replace plugin path!" + + # Fix sandbox violations during make clean, bug 372817 + sed -e "s:\(/no-such-file\):${T}\1:g" \ + -i "${S}"/config/rules.mk \ + -i "${S}"/js/src/config/rules.mk \ + -i "${S}"/nsprpub/configure{.in,} \ + || die + + #Fix compilation with curl-7.21.7 bug 376027 + sed -e '/#include <curl\/types.h>/d' \ + -i "${S}"/toolkit/crashreporter/google-breakpad/src/common/linux/http_upload.cc \ + -i "${S}"/toolkit/crashreporter/google-breakpad/src/common/linux/libcurl_wrapper.cc \ + -i "${S}"/config/system-headers \ + -i "${S}"/js/src/config/system-headers || die "Sed failed" + + eautoreconf +} + +src_configure() { + MOZILLA_FIVE_HOME="/usr/$(get_libdir)/${PN}/${MY_PN}" + MEXTENSIONS="default" + + #################################### + # + # mozconfig, CFLAGS and CXXFLAGS setup + # + #################################### + + mozconfig_init + mozconfig_config + + mozconfig_annotate '' --prefix="${EPREFIX}"/usr + mozconfig_annotate '' --libdir="${EPREFIX}"/usr/$(get_libdir)/${PN} + mozconfig_annotate '' --enable-extensions="${MEXTENSIONS}" + mozconfig_annotate '' --disable-gconf + mozconfig_annotate '' --disable-mailnews + mozconfig_annotate '' --enable-canvas + mozconfig_annotate '' --enable-safe-browsing + mozconfig_annotate '' --with-system-png + mozconfig_annotate '' --enable-system-ffi + mozconfig_annotate 'Missing features' --disable-system-cairo + + # Other ff-specific settings + mozconfig_annotate '' --with-default-mozilla-five-home=${MOZILLA_FIVE_HOME} + mozconfig_annotate '' --target="${CTARGET:-${CHOST}}" + + mozconfig_use_enable system-sqlite + + # Allow for a proper pgo build + if use pgo; then + echo "mk_add_options PROFILE_GEN_SCRIPT='\$(PYTHON) \$(OBJDIR)/_profile/pgo/profileserver.py'" >> "${S}"/.mozconfig + fi + + # Finalize and report settings + mozconfig_final + + if [[ $(gcc-major-version) -lt 4 ]]; then + append-cxxflags -fno-stack-protector + elif [[ $(gcc-major-version) -gt 4 || $(gcc-minor-version) -gt 3 ]]; then + if use amd64 || use x86; then + append-flags -mno-avx + fi + fi +} + +src_compile() { + if use pgo; then + addpredict /root + addpredict /etc/gconf + # Reset and cleanup environment variables used by GNOME/XDG + gnome2_environment_reset + + # Firefox tries to use dri stuff when it's run, see bug 380283 + shopt -s nullglob + cards=$(echo -n /dev/dri/card* | sed 's/ /:/g') + if test -n "${cards}"; then + # FOSS drivers are fine + addpredict "${cards}" + else + cards=$(echo -n /dev/ati/card* /dev/nvidiactl* | sed 's/ /:/g') + if test -n "${cards}"; then + # Binary drivers seem to cause access violations anyway, so + # let's use indirect rendering so that the device files aren't + # touched at all. See bug 394715. + export LIBGL_ALWAYS_INDIRECT=1 + addpredict "${cards}" + fi + fi + shopt -u nullglob + + CC="$(tc-getCC)" CXX="$(tc-getCXX)" LD="$(tc-getLD)" \ + MOZ_MAKE_FLAGS="${MAKEOPTS}" \ + Xemake -f client.mk profiledbuild || die "Xemake failed" + else + CC="$(tc-getCC)" CXX="$(tc-getCXX)" LD="$(tc-getLD)" \ + MOZ_MAKE_FLAGS="${MAKEOPTS}" \ + emake -f client.mk || die "emake failed" + fi +} + +src_install() { + MOZILLA_FIVE_HOME="/usr/$(get_libdir)/${PN}/${MY_PN}" + + # MOZ_BUILD_ROOT, and hence OBJ_DIR change depending on arch, compiler, pgo, etc. + local obj_dir="$(echo */config.log)" + obj_dir="${obj_dir%/*}" + cd "${S}/${obj_dir}" + + # Pax mark xpcshell for hardened support, only used for startupcache creation. + pax-mark m "${S}/${obj_dir}"/dist/bin/xpcshell + + MOZ_MAKE_FLAGS="${MAKEOPTS}" \ + emake DESTDIR="${D}" install || die "emake install failed" + + # remove default symlink in /usr/bin, because we add a proper wrapper-script later + rm "${ED}"/usr/bin/${MY_PN} || die "Failed to remove binary-symlink" + # we dont want development stuff for this kind of build, might as well + # conflict with other firefox-builds + rm -rf "${ED}"/usr/include "${ED}${MOZILLA_FIVE_HOME}"/{idl,include,lib,sdk} || \ + die "Failed to remove sdk and headers" + + # Required in order to use plugins and even run firefox on hardened. + pax-mark m "${ED}"${MOZILLA_FIVE_HOME}/{firefox,firefox-bin,plugin-container} + + # Plugins dir + keepdir /usr/$(get_libdir)/${PN}/${MY_PN}/plugins + + # Install pre-configured Torbrowser-profile + insinto /usr/share/${PN} + doins -r "${WORKDIR}"/tor-browser_en-US/Data/profile || die + + # create wrapper to start torbrowser + make_wrapper ${PN} "/usr/$(get_libdir)/${PN}/${MY_PN}/${MY_PN} -no-remote -profile ~/.${PN}/profile" + + newicon "${WORKDIR}"/tor-browser_en-US/App/Firefox/icons/mozicon128.png ${PN}.png + make_desktop_entry ${PN} "Torbrowser" ${PN} "Network;WebBrowser" + dodoc "${WORKDIR}"/tor-browser_en-US/Docs/changelog +} + +pkg_postinst() { + ewarn "This patched firefox build is _NOT_ recommended by TOR upstream but uses" + ewarn "the exact same patches (excluding Vidalia-patch). Use this only if you know" + ewarn "what you are doing!" + einfo "" + elog "Copy the folder contents from /usr/share/${PN}/profile into ~/.${PN}/profile and run '${PN}'." + einfo + elog "This profile folder includes pre-configuration recommended by upstream," + elog "as well as the extensions Torbutton, NoScript and HTTPS-Everywhere." + elog "If you want to start from scratch just create the directories '~/.${PN}/profile'." + einfo + elog "The update check when you first start ${PN} does not recognize this version." + einfo +} |