Bug 769288 - Part 5: Close private socket connections when the lsat private browsing instance dies. r=bsmith,mcmanus

This commit is contained in:
Josh Matthews 2012-12-07 17:50:43 -05:00
parent c02c3d11da
commit 51df8e7acf
14 changed files with 113 additions and 50 deletions

View File

@ -15,6 +15,7 @@ public:
: mCondition(NS_OK)
, mPollFlags(0)
, mPollTimeout(UINT16_MAX)
, mIsPrivate(false)
{}
//
@ -42,6 +43,8 @@ public:
//
uint16_t mPollTimeout;
bool mIsPrivate;
//
// called to service a socket
//

View File

@ -2206,6 +2206,7 @@ NS_IMETHODIMP
nsSocketTransport::SetConnectionFlags(uint32_t value)
{
mConnectionFlags = value;
mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE;
return NS_OK;
}

View File

@ -23,15 +23,7 @@
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
#include "mozilla/Likely.h"
// XXX: There is no good header file to put these in. :(
namespace mozilla { namespace psm {
void InitializeSSLServerCertVerificationThreads();
void StopSSLServerCertVerificationThreads();
} } // namespace mozilla::psm
#include "mozilla/PublicSSL.h"
using namespace mozilla;
@ -469,6 +461,7 @@ nsSocketTransportService::Init()
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) {
obsSvc->AddObserver(this, "profile-initial-state", false);
obsSvc->AddObserver(this, "last-pb-context-exited", false);
}
mInitialized = true;
@ -516,6 +509,7 @@ nsSocketTransportService::Shutdown()
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) {
obsSvc->RemoveObserver(this, "profile-initial-state");
obsSvc->RemoveObserver(this, "last-pb-context-exited");
}
mozilla::net::NetworkActivityMonitor::Shutdown();
@ -883,9 +877,35 @@ nsSocketTransportService::Observe(nsISupports *subject,
return net::NetworkActivityMonitor::Init(blipInterval);
}
if (!strcmp(topic, "last-pb-context-exited")) {
nsCOMPtr<nsIRunnable> ev =
NS_NewRunnableMethod(this,
&nsSocketTransportService::ClosePrivateConnections);
nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
void
nsSocketTransportService::ClosePrivateConnections()
{
for (int32_t i = mActiveCount - 1; i >= 0; --i) {
if (mActiveList[i].mHandler->mIsPrivate) {
DetachSocket(mActiveList, &mActiveList[i]);
}
}
for (int32_t i = mIdleCount - 1; i >= 0; --i) {
if (mIdleList[i].mHandler->mIsPrivate) {
DetachSocket(mIdleList, &mIdleList[i]);
}
}
mozilla::ClearPrivateSSLState();
}
NS_IMETHODIMP
nsSocketTransportService::GetSendBufferSize(int32_t *value)
{

View File

@ -183,6 +183,8 @@ private:
void ProbeMaxCount();
#endif
bool mProbedMaxCount;
void ClosePrivateConnections();
};
extern nsSocketTransportService *gSocketTransportService;

View File

@ -98,5 +98,11 @@ EXPORTS += \
ScopedNSSTypes.h \
$(NULL)
EXPORTS_NAMESPACES = mozilla
EXPORTS_mozilla += \
PublicSSL.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_SSL_h
#define mozilla_SSL_h
namespace mozilla {
void ClearPrivateSSLState();
namespace psm {
void InitializeSSLServerCertVerificationThreads();
void StopSSLServerCertVerificationThreads();
} //namespace psm
} // namespace mozilla
#endif

View File

@ -12,8 +12,50 @@
#include "mozilla/Services.h"
#include "nsThreadUtils.h"
#include "nsCRT.h"
#include "nsServiceManagerUtils.h"
#include "nsRecentBadCerts.h"
#include "PSMRunnable.h"
#include "PublicSSL.h"
#include "ssl.h"
using mozilla::psm::SyncRunnableBase;
namespace {
class CertOverrideClearer : public SyncRunnableBase
{
public:
void RunOnTargetThread() {
nsCOMPtr<nsICertOverrideService> icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID);
if (icos) {
icos->ClearValidityOverride(
NS_LITERAL_CSTRING("all:temporary-certificates"),
0);
}
}
};
} // anonymous namespace
namespace mozilla {
void ClearPrivateSSLState()
{
SSL_ClearSessionCache();
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb) {
nsCOMPtr<nsIRecentBadCerts> badCerts;
certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts));
if (badCerts) {
badCerts->ResetStoredCerts();
}
}
RefPtr<CertOverrideClearer> runnable = new CertOverrideClearer;
runnable->DispatchToMainThreadAndWait();
}
namespace psm {
namespace {

View File

@ -11,8 +11,6 @@
#include "nsNSSIOLayer.h"
class nsClientAuthRememberService;
class nsIRecentBadCertsService;
class nsICertOverrideService;
class nsIObserver;
namespace mozilla {

View File

@ -124,7 +124,6 @@ nsCertOverrideService::Init()
if (observerService) {
observerService->AddObserver(this, "profile-before-change", true);
observerService->AddObserver(this, "profile-do-change", true);
observerService->AddObserver(this, "last-pb-context-exited", true);
// simulate a profile change so we read the current profile's settings file
Observe(nullptr, "profile-do-change", nullptr);
}
@ -169,10 +168,6 @@ nsCertOverrideService::Observe(nsISupports *,
}
Read();
} else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) {
ClearValidityOverride(
NS_LITERAL_CSTRING("all:temporary-certificates"),
0);
}
return NS_OK;

View File

@ -56,6 +56,7 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2)
nsNSSCertificateDB::nsNSSCertificateDB()
: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock")
{
}
@ -1650,11 +1651,10 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval)
NS_IMETHODIMP
nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result)
{
MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread");
MutexAutoLock lock(mBadCertsLock);
if (isPrivate) {
if (!mPrivateRecentBadCerts) {
mPrivateRecentBadCerts = new nsRecentBadCerts;
mPrivateRecentBadCerts->InitPrivateBrowsingObserver();
}
NS_ADDREF(*result = mPrivateRecentBadCerts);
} else {

View File

@ -8,6 +8,7 @@
#include "nsIX509CertDB.h"
#include "nsIX509CertDB2.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Mutex.h"
#include "certt.h"
class nsCString;
@ -16,6 +17,7 @@ class nsRecentBadCerts;
class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2
{
typedef mozilla::Mutex Mutex;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIX509CERTDB
@ -51,6 +53,7 @@ private:
nsresult handleCACertDownload(nsIArray *x509Certs,
nsIInterfaceRequestor *ctx);
Mutex mBadCertsLock;
mozilla::RefPtr<nsRecentBadCerts> mPublicRecentBadCerts;
mozilla::RefPtr<nsRecentBadCerts> mPrivateRecentBadCerts;
};

View File

@ -2138,7 +2138,6 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen)
#define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto"
#define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change"
#define PROFILE_DO_CHANGE_TOPIC "profile-do-change"
#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited"
NS_IMETHODIMP
nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
@ -2286,9 +2285,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n"));
DoProfileChangeNetRestore();
}
else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) {
SSL_ClearSessionCache();
}
return NS_OK;
}
@ -2388,7 +2384,6 @@ nsNSSComponent::RegisterObservers()
observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false);
observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false);
observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false);
observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false);
}
return NS_OK;
}
@ -2414,7 +2409,6 @@ nsNSSComponent::DeregisterObservers()
observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC);
observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC);
observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC);
observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC);
}
return NS_OK;
}

View File

@ -22,9 +22,8 @@
using namespace mozilla;
NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts,
nsIRecentBadCerts,
nsIObserver)
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts,
nsIRecentBadCerts)
nsRecentBadCerts::nsRecentBadCerts()
:monitor("nsRecentBadCerts.monitor")
@ -36,24 +35,6 @@ nsRecentBadCerts::~nsRecentBadCerts()
{
}
void
nsRecentBadCerts::InitPrivateBrowsingObserver()
{
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
obsSvc->AddObserver(this, "last-pb-context-exited", false);
}
NS_IMETHODIMP
nsRecentBadCerts::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) {
ResetStoredCerts();
}
return NS_OK;
}
NS_IMETHODIMP
nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort,
nsISSLStatus **aStatus)

View File

@ -11,7 +11,6 @@
#include "mozilla/ReentrantMonitor.h"
#include "nsIRecentBadCertsService.h"
#include "nsIObserver.h"
#include "nsTHashtable.h"
#include "nsString.h"
#include "cert.h"
@ -56,18 +55,14 @@ private:
};
class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts
, public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIRECENTBADCERTS
NS_DECL_NSIOBSERVER
nsRecentBadCerts();
~nsRecentBadCerts();
void InitPrivateBrowsingObserver();
protected:
mozilla::ReentrantMonitor monitor;