Merge mozilla-central into mozilla-inbound

This commit is contained in:
Ehsan Akhgari 2012-12-13 16:01:29 -05:00
Родитель 948e2b61cf 44f2db652e
Коммит b1cdb90cb6
27 изменённых файлов: 718 добавлений и 216 удалений

Просмотреть файл

@ -439,11 +439,6 @@ PrivateBrowsingService.prototype = {
this._unload(); this._unload();
break; break;
case "private-browsing": case "private-browsing":
// clear all auth tokens
let sdr = Cc["@mozilla.org/security/sdr;1"].
getService(Ci.nsISecretDecoderRing);
sdr.logoutAndTeardown();
if (!this._inPrivateBrowsing) { if (!this._inPrivateBrowsing) {
// Clear the error console // Clear the error console
let consoleService = Cc["@mozilla.org/consoleservice;1"]. let consoleService = Cc["@mozilla.org/consoleservice;1"].

Просмотреть файл

@ -73,3 +73,4 @@ MOZ_EXTENSION_MANAGER=1
MOZ_APP_STATIC_INI=1 MOZ_APP_STATIC_INI=1
MOZ_WEBAPP_RUNTIME=1 MOZ_WEBAPP_RUNTIME=1
MOZ_MEDIA_NAVIGATOR=1 MOZ_MEDIA_NAVIGATOR=1
MOZ_PER_WINDOW_PRIVATE_BROWSING=1

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -23,15 +23,7 @@
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include "mozilla/PublicSSL.h"
// XXX: There is no good header file to put these in. :(
namespace mozilla { namespace psm {
void InitializeSSLServerCertVerificationThreads();
void StopSSLServerCertVerificationThreads();
} } // namespace mozilla::psm
using namespace mozilla; using namespace mozilla;
using namespace mozilla::net; using namespace mozilla::net;
@ -470,6 +462,7 @@ nsSocketTransportService::Init()
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService(); nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) { if (obsSvc) {
obsSvc->AddObserver(this, "profile-initial-state", false); obsSvc->AddObserver(this, "profile-initial-state", false);
obsSvc->AddObserver(this, "last-pb-context-exited", false);
} }
mInitialized = true; mInitialized = true;
@ -517,6 +510,7 @@ nsSocketTransportService::Shutdown()
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService(); nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) { if (obsSvc) {
obsSvc->RemoveObserver(this, "profile-initial-state"); obsSvc->RemoveObserver(this, "profile-initial-state");
obsSvc->RemoveObserver(this, "last-pb-context-exited");
} }
mozilla::net::NetworkActivityMonitor::Shutdown(); mozilla::net::NetworkActivityMonitor::Shutdown();
@ -884,9 +878,42 @@ nsSocketTransportService::Observe(nsISupports *subject,
return net::NetworkActivityMonitor::Init(blipInterval); 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; return NS_OK;
} }
void
nsSocketTransportService::ClosePrivateConnections()
{
// Must be called on the socket thread.
#ifdef DEBUG
bool onSTSThread;
IsOnCurrentThread(&onSTSThread);
MOZ_ASSERT(onSTSThread);
#endif
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 NS_IMETHODIMP
nsSocketTransportService::GetSendBufferSize(int32_t *value) nsSocketTransportService::GetSendBufferSize(int32_t *value)
{ {

Просмотреть файл

@ -190,6 +190,8 @@ private:
void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data, void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data,
SocketContext *context, bool aActive); SocketContext *context, bool aActive);
void ClosePrivateConnections();
}; };
extern nsSocketTransportService *gSocketTransportService; extern nsSocketTransportService *gSocketTransportService;

Просмотреть файл

@ -88,8 +88,11 @@ function initExceptionDialog() {
// returns true if found and global status could be set // returns true if found and global status could be set
function findRecentBadCert(uri) { function findRecentBadCert(uri) {
try { try {
var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"] var certDB = Components.classes["@mozilla.org/security/x509certdb;1"]
.getService(Components.interfaces.nsIRecentBadCertsService); .getService(Components.interfaces.nsIX509CertDB);
if (!certDB)
return false;
var recentCertsSvc = certDB.getRecentBadCertsService(inPrivateBrowsingMode());
if (!recentCertsSvc) if (!recentCertsSvc)
return false; return false;

Просмотреть файл

@ -20,9 +20,8 @@ interface nsISSLStatus;
* The implementation will decide how many entries it will hold, * The implementation will decide how many entries it will hold,
* the number is expected to be small. * the number is expected to be small.
*/ */
[scriptable, uuid(a5ae8b05-a76e-408f-b0ba-02a831265749)] [scriptable, uuid(0fed7784-d152-44d6-95a7-67a59024de0f)]
interface nsIRecentBadCertsService : nsISupports { interface nsIRecentBadCerts : nsISupports {
/** /**
* Retrieve the recently seen bad ssl status for the given hostname:port. * Retrieve the recently seen bad ssl status for the given hostname:port.
* If no SSL cert was recently seen for the given hostname:port, return null. * If no SSL cert was recently seen for the given hostname:port, return null.
@ -43,4 +42,9 @@ interface nsIRecentBadCertsService : nsISupports {
*/ */
void addBadCert(in AString aHostNameWithPort, void addBadCert(in AString aHostNameWithPort,
in nsISSLStatus aStatus); in nsISSLStatus aStatus);
/**
* Clear all stored cert data.
*/
void resetStoredCerts();
}; };

Просмотреть файл

@ -12,6 +12,7 @@ interface nsIX509Cert3;
interface nsIFile; interface nsIFile;
interface nsIInterfaceRequestor; interface nsIInterfaceRequestor;
interface nsIZipReader; interface nsIZipReader;
interface nsIRecentBadCerts;
%{C++ %{C++
#define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1" #define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1"
@ -29,7 +30,7 @@ interface nsIOpenSignedJARFileCallback : nsISupports
* This represents a service to access and manipulate * This represents a service to access and manipulate
* X.509 certificates stored in a database. * X.509 certificates stored in a database.
*/ */
[scriptable, uuid(735d0363-e219-4387-b5c6-72e800c3ea0b)] [scriptable, uuid(a18df2a5-84a9-46cd-9140-3fdb3879d9ff)]
interface nsIX509CertDB : nsISupports { interface nsIX509CertDB : nsISupports {
/** /**
@ -264,6 +265,16 @@ interface nsIX509CertDB : nsISupports {
*/ */
nsIX509Cert constructX509FromBase64(in string base64); nsIX509Cert constructX509FromBase64(in string base64);
/*
* Obtain a reference to the appropriate service for recent
* bad certificates. May only be called on the main thread.
*
* @param isPrivate True if the service for certs for private connections
* is desired, false otherwise.
* @return The requested service.
*/
nsIRecentBadCerts getRecentBadCerts(in boolean isPrivate);
/** /**
* Verifies the signature on the given JAR file to verify that it has a * Verifies the signature on the given JAR file to verify that it has a
* valid signature. To be considered valid, there must be exactly one * valid signature. To be considered valid, there must be exactly one

Просмотреть файл

@ -74,6 +74,7 @@ CPPSRCS = \
PSMRunnable.cpp \ PSMRunnable.cpp \
nsNSSVersion.cpp \ nsNSSVersion.cpp \
nsCertificatePrincipal.cpp \ nsCertificatePrincipal.cpp \
SharedSSLState.cpp \
$(NULL) $(NULL)
ifdef MOZ_XUL ifdef MOZ_XUL
@ -82,7 +83,6 @@ endif
CSRCS += md4.c CSRCS += md4.c
EXTRA_DEPS = $(NSS_DEP_LIBS) EXTRA_DEPS = $(NSS_DEP_LIBS)
DEFINES += \ DEFINES += \
@ -97,5 +97,11 @@ EXPORTS += \
ScopedNSSTypes.h \ ScopedNSSTypes.h \
$(NULL) $(NULL)
EXPORTS_NAMESPACES = mozilla
EXPORTS_mozilla += \
PublicSSL.h \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

Просмотреть файл

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

Просмотреть файл

@ -112,6 +112,7 @@
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "PSMRunnable.h" #include "PSMRunnable.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "ssl.h" #include "ssl.h"
#include "secerr.h" #include "secerr.h"
@ -238,13 +239,15 @@ class CertErrorRunnable : public SyncRunnableBase
uint32_t collectedErrors, uint32_t collectedErrors,
PRErrorCode errorCodeTrust, PRErrorCode errorCodeTrust,
PRErrorCode errorCodeMismatch, PRErrorCode errorCodeMismatch,
PRErrorCode errorCodeExpired) PRErrorCode errorCodeExpired,
uint32_t providerFlags)
: mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject), : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject),
mDefaultErrorCodeToReport(defaultErrorCodeToReport), mDefaultErrorCodeToReport(defaultErrorCodeToReport),
mCollectedErrors(collectedErrors), mCollectedErrors(collectedErrors),
mErrorCodeTrust(errorCodeTrust), mErrorCodeTrust(errorCodeTrust),
mErrorCodeMismatch(errorCodeMismatch), mErrorCodeMismatch(errorCodeMismatch),
mErrorCodeExpired(errorCodeExpired) mErrorCodeExpired(errorCodeExpired),
mProviderFlags(providerFlags)
{ {
} }
@ -261,6 +264,7 @@ private:
const PRErrorCode mErrorCodeTrust; const PRErrorCode mErrorCodeTrust;
const PRErrorCode mErrorCodeMismatch; const PRErrorCode mErrorCodeMismatch;
const PRErrorCode mErrorCodeExpired; const PRErrorCode mErrorCodeExpired;
const uint32_t mProviderFlags;
}; };
SSLServerCertVerificationResult * SSLServerCertVerificationResult *
@ -296,12 +300,8 @@ CertErrorRunnable::CheckCertOverrides()
if (NS_SUCCEEDED(nsrv)) { if (NS_SUCCEEDED(nsrv)) {
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface( nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
uint32_t flags = 0;
if (sslSocketControl) {
sslSocketControl->GetProviderFlags(&flags);
}
nsrv = stss->IsStsHost(mInfoObject->GetHostName(), nsrv = stss->IsStsHost(mInfoObject->GetHostName(),
flags, mProviderFlags,
&strictTransportSecurityEnabled); &strictTransportSecurityEnabled);
} }
if (NS_FAILED(nsrv)) { if (NS_FAILED(nsrv)) {
@ -371,8 +371,12 @@ CertErrorRunnable::CheckCertOverrides()
} }
} }
nsCOMPtr<nsIRecentBadCertsService> recentBadCertsService = nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
do_GetService(NS_RECENTBADCERTS_CONTRACTID); nsCOMPtr<nsIRecentBadCerts> recentBadCertsService;
if (certdb) {
bool isPrivate = mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE;
certdb->GetRecentBadCerts(isPrivate, getter_AddRefs(recentBadCertsService));
}
if (recentBadCertsService) { if (recentBadCertsService) {
NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString); NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString);
@ -418,7 +422,8 @@ CertErrorRunnable *
CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
TransportSecurityInfo * infoObject, TransportSecurityInfo * infoObject,
CERTCertificate * cert, CERTCertificate * cert,
const void * fdForLogging) const void * fdForLogging,
uint32_t providerFlags)
{ {
MOZ_ASSERT(infoObject); MOZ_ASSERT(infoObject);
MOZ_ASSERT(cert); MOZ_ASSERT(cert);
@ -567,7 +572,8 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
static_cast<nsIX509Cert*>(nssCert.get()), static_cast<nsIX509Cert*>(nssCert.get()),
infoObject, defaultErrorCodeToReport, infoObject, defaultErrorCodeToReport,
collected_errors, errorCodeTrust, collected_errors, errorCodeTrust,
errorCodeMismatch, errorCodeExpired); errorCodeMismatch, errorCodeExpired,
providerFlags);
} }
// When doing async cert processing, we dispatch one of these runnables to the // When doing async cert processing, we dispatch one of these runnables to the
@ -607,25 +613,29 @@ public:
// Must be called only on the socket transport thread // Must be called only on the socket transport thread
static SECStatus Dispatch(const void * fdForLogging, static SECStatus Dispatch(const void * fdForLogging,
TransportSecurityInfo * infoObject, TransportSecurityInfo * infoObject,
CERTCertificate * serverCert); CERTCertificate * serverCert,
uint32_t providerFlags);
private: private:
NS_DECL_NSIRUNNABLE NS_DECL_NSIRUNNABLE
// Must be called only on the socket transport thread // Must be called only on the socket transport thread
SSLServerCertVerificationJob(const void * fdForLogging, SSLServerCertVerificationJob(const void * fdForLogging,
TransportSecurityInfo * infoObject, TransportSecurityInfo * infoObject,
CERTCertificate * cert); CERTCertificate * cert,
uint32_t providerFlags);
const void * const mFdForLogging; const void * const mFdForLogging;
const RefPtr<TransportSecurityInfo> mInfoObject; const RefPtr<TransportSecurityInfo> mInfoObject;
const ScopedCERTCertificate mCert; const ScopedCERTCertificate mCert;
const uint32_t mProviderFlags;
}; };
SSLServerCertVerificationJob::SSLServerCertVerificationJob( SSLServerCertVerificationJob::SSLServerCertVerificationJob(
const void * fdForLogging, TransportSecurityInfo * infoObject, const void * fdForLogging, TransportSecurityInfo * infoObject,
CERTCertificate * cert) CERTCertificate * cert, uint32_t providerFlags)
: mFdForLogging(fdForLogging) : mFdForLogging(fdForLogging)
, mInfoObject(infoObject) , mInfoObject(infoObject)
, mCert(CERT_DupCertificate(cert)) , mCert(CERT_DupCertificate(cert))
, mProviderFlags(providerFlags)
{ {
} }
@ -825,7 +835,8 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo *infoObject,
} }
SECStatus SECStatus
AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert,
uint32_t providerFlags)
{ {
if (cert->serialNumber.data && if (cert->serialNumber.data &&
cert->issuerName && cert->issuerName &&
@ -911,37 +922,41 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert)
} }
nsCOMPtr<nsINSSComponent> nssComponent; nsCOMPtr<nsINSSComponent> nssComponent;
for (CERTCertListNode *node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList);
node = CERT_LIST_NEXT(node)) {
if (node->cert->slot) { // We want to avoid storing any intermediate cert information when browsing
// This cert was found on a token, no need to remember it in the temp db. // in private, transient contexts.
continue; if (!(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) {
} for (CERTCertListNode *node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList);
node = CERT_LIST_NEXT(node)) {
if (node->cert->isperm) { if (node->cert->slot) {
// We don't need to remember certs already stored in perm db. // This cert was found on a token, no need to remember it in the temp db.
continue; continue;
}
if (node->cert == cert) {
// We don't want to remember the server cert,
// the code that cares for displaying page info does this already.
continue;
}
// We have found a signer cert that we want to remember.
char* nickname = nsNSSCertificate::defaultServerNickname(node->cert);
if (nickname && *nickname) {
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
if (slot) {
PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE,
nickname, false);
} }
if (node->cert->isperm) {
// We don't need to remember certs already stored in perm db.
continue;
}
if (node->cert == cert) {
// We don't want to remember the server cert,
// the code that cares for displaying page info does this already.
continue;
}
// We have found a signer cert that we want to remember.
char* nickname = nsNSSCertificate::defaultServerNickname(node->cert);
if (nickname && *nickname) {
ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
if (slot) {
PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE,
nickname, false);
}
}
PR_FREEIF(nickname);
} }
PR_FREEIF(nickname);
} }
// The connection may get terminated, for example, if the server requires // The connection may get terminated, for example, if the server requires
@ -977,7 +992,8 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert)
/*static*/ SECStatus /*static*/ SECStatus
SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, SSLServerCertVerificationJob::Dispatch(const void * fdForLogging,
TransportSecurityInfo * infoObject, TransportSecurityInfo * infoObject,
CERTCertificate * serverCert) CERTCertificate * serverCert,
uint32_t providerFlags)
{ {
// Runs on the socket transport thread // Runs on the socket transport thread
if (!infoObject || !serverCert) { if (!infoObject || !serverCert) {
@ -987,7 +1003,8 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging,
} }
RefPtr<SSLServerCertVerificationJob> job( RefPtr<SSLServerCertVerificationJob> job(
new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert)); new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert,
providerFlags));
nsresult nrv; nsresult nrv;
if (!gCertVerificationThreadPool) { if (!gCertVerificationThreadPool) {
@ -1031,7 +1048,7 @@ SSLServerCertVerificationJob::Run()
// Reset the error code here so we can detect if AuthCertificate fails to // Reset the error code here so we can detect if AuthCertificate fails to
// set the error code if/when it fails. // set the error code if/when it fails.
PR_SetError(0, 0); PR_SetError(0, 0);
SECStatus rv = AuthCertificate(mInfoObject, mCert); SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags);
if (rv == SECSuccess) { if (rv == SECSuccess) {
RefPtr<SSLServerCertVerificationResult> restart( RefPtr<SSLServerCertVerificationResult> restart(
new SSLServerCertVerificationResult(mInfoObject, 0)); new SSLServerCertVerificationResult(mInfoObject, 0));
@ -1042,7 +1059,7 @@ SSLServerCertVerificationJob::Run()
error = PR_GetError(); error = PR_GetError();
if (error != 0) { if (error != 0) {
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable( RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
error, mInfoObject, mCert, mFdForLogging)); error, mInfoObject, mCert, mFdForLogging, mProviderFlags));
if (!runnable) { if (!runnable) {
// CreateCertErrorRunnable set a new error code // CreateCertErrorRunnable set a new error code
error = PR_GetError(); error = PR_GetError();
@ -1135,15 +1152,20 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
PR_SetError(PR_UNKNOWN_ERROR, 0); PR_SetError(PR_UNKNOWN_ERROR, 0);
return SECFailure; return SECFailure;
} }
uint32_t providerFlags = 0;
socketInfo->GetProviderFlags(&providerFlags);
if (onSTSThread) { if (onSTSThread) {
// We *must* do certificate verification on a background thread because // We *must* do certificate verification on a background thread because
// we need the socket transport thread to be free for our OCSP requests, // we need the socket transport thread to be free for our OCSP requests,
// and we *want* to do certificate verification on a background thread // and we *want* to do certificate verification on a background thread
// because of the performance benefits of doing so. // because of the performance benefits of doing so.
socketInfo->SetCertVerificationWaiting(); socketInfo->SetCertVerificationWaiting();
SECStatus rv = SSLServerCertVerificationJob::Dispatch( SECStatus rv = SSLServerCertVerificationJob::Dispatch(
static_cast<const void *>(fd), socketInfo, serverCert); static_cast<const void *>(fd), socketInfo, serverCert,
providerFlags);
return rv; return rv;
} }
@ -1151,7 +1173,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
// thread doing the network I/O may not interrupt its network I/O on receipt // thread doing the network I/O may not interrupt its network I/O on receipt
// of our SSLServerCertVerificationResult event, and/or it might not even be // of our SSLServerCertVerificationResult event, and/or it might not even be
// a non-blocking socket. // a non-blocking socket.
SECStatus rv = AuthCertificate(socketInfo, serverCert); SECStatus rv = AuthCertificate(socketInfo, serverCert, providerFlags);
if (rv == SECSuccess) { if (rv == SECSuccess) {
return SECSuccess; return SECSuccess;
} }
@ -1160,7 +1182,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
if (error != 0) { if (error != 0) {
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable( RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
error, socketInfo, serverCert, error, socketInfo, serverCert,
static_cast<const void *>(fd))); static_cast<const void *>(fd), providerFlags));
if (!runnable) { if (!runnable) {
// CreateCertErrorRunnable sets a new error code when it fails // CreateCertErrorRunnable sets a new error code when it fails
error = PR_GetError(); error = PR_GetError();

Просмотреть файл

@ -0,0 +1,230 @@
/* -*- 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/. */
#include "SharedSSLState.h"
#include "nsClientAuthRemember.h"
#include "nsComponentManagerUtils.h"
#include "nsICertOverrideService.h"
#include "nsIObserverService.h"
#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"
#include "nsNetCID.h"
#include "mozilla/unused.h"
using mozilla::psm::SyncRunnableBase;
using mozilla::unused;
namespace {
static PRInt32 sCertOverrideSvcExists = 0;
static PRInt32 sCertDBExists = 0;
class MainThreadClearer : public SyncRunnableBase
{
public:
MainThreadClearer() : mShouldClearSessionCache(false) {}
void RunOnTargetThread() {
// In some cases it's possible to cause PSM/NSS to initialize while XPCOM shutdown
// is in progress. We want to avoid this, since they do not handle the situation well,
// hence the flags to avoid instantiating the services if they don't already exist.
bool certOverrideSvcExists = (bool)PR_ATOMIC_SET(&sCertOverrideSvcExists, 0);
if (certOverrideSvcExists) {
unused << PR_ATOMIC_SET(&sCertOverrideSvcExists, 1);
nsCOMPtr<nsICertOverrideService> icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID);
if (icos) {
icos->ClearValidityOverride(
NS_LITERAL_CSTRING("all:temporary-certificates"),
0);
}
}
bool certDBExists = (bool)PR_ATOMIC_SET(&sCertDBExists, 0);
if (certDBExists) {
unused << PR_ATOMIC_SET(&sCertDBExists, 1);
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb) {
nsCOMPtr<nsIRecentBadCerts> badCerts;
certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts));
if (badCerts) {
badCerts->ResetStoredCerts();
}
}
}
// This needs to be checked on the main thread to avoid racing with NSS
// initialization.
mShouldClearSessionCache = mozilla::psm::PrivateSSLState() &&
mozilla::psm::PrivateSSLState()->SocketCreated();
}
bool mShouldClearSessionCache;
};
} // anonymous namespace
namespace mozilla {
void ClearPrivateSSLState()
{
// This only works if it is called on the socket transport
// service thread immediately after closing all private SSL
// connections.
#ifdef DEBUG
nsresult rv;
nsCOMPtr<nsIEventTarget> sts
= do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
MOZ_ASSERT(NS_SUCCEEDED(rv));
bool onSTSThread;
rv = sts->IsOnCurrentThread(&onSTSThread);
MOZ_ASSERT(NS_SUCCEEDED(rv) && onSTSThread);
#endif
RefPtr<MainThreadClearer> runnable = new MainThreadClearer;
runnable->DispatchToMainThreadAndWait();
// If NSS isn't initialized, this throws an assertion. We guard it by checking if
// the session cache might even have anything worth clearing.
if (runnable->mShouldClearSessionCache) {
SSL_ClearSessionCache();
}
}
namespace psm {
namespace {
class PrivateBrowsingObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {}
virtual ~PrivateBrowsingObserver() {}
private:
SharedSSLState* mOwner;
};
SharedSSLState* gPublicState;
SharedSSLState* gPrivateState;
} // anonymous namespace
NS_IMPL_ISUPPORTS1(PrivateBrowsingObserver, nsIObserver)
NS_IMETHODIMP
PrivateBrowsingObserver::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) {
mOwner->ResetStoredData();
}
return NS_OK;
}
SharedSSLState::SharedSSLState()
: mClientAuthRemember(new nsClientAuthRememberService)
, mMutex("SharedSSLState::mMutex")
, mSocketCreated(false)
{
mIOLayerHelpers.Init();
mClientAuthRemember->Init();
}
SharedSSLState::~SharedSSLState()
{
}
void
SharedSSLState::NotePrivateBrowsingStatus()
{
MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
mObserver = new PrivateBrowsingObserver(this);
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
obsSvc->AddObserver(mObserver, "last-pb-context-exited", false);
}
void
SharedSSLState::ResetStoredData()
{
MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
mClientAuthRemember->ClearRememberedDecisions();
mIOLayerHelpers.clearStoredData();
}
void
SharedSSLState::NoteSocketCreated()
{
MutexAutoLock lock(mMutex);
mSocketCreated = true;
}
bool
SharedSSLState::SocketCreated()
{
MutexAutoLock lock(mMutex);
return mSocketCreated;
}
/*static*/ void
SharedSSLState::GlobalInit()
{
MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
gPublicState = new SharedSSLState();
gPrivateState = new SharedSSLState();
gPrivateState->NotePrivateBrowsingStatus();
}
/*static*/ void
SharedSSLState::GlobalCleanup()
{
MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
gPrivateState->Cleanup();
delete gPrivateState;
gPrivateState = nullptr;
gPublicState->Cleanup();
delete gPublicState;
gPublicState = nullptr;
}
/*static*/ void
SharedSSLState::NoteCertOverrideServiceInstantiated()
{
unused << PR_ATOMIC_SET(&sCertOverrideSvcExists, 1);
}
/*static*/ void
SharedSSLState::NoteCertDBServiceInstantiated()
{
unused << PR_ATOMIC_SET(&sCertDBExists, 1);
}
void
SharedSSLState::Cleanup()
{
mIOLayerHelpers.Cleanup();
}
SharedSSLState*
PublicSSLState()
{
return gPublicState;
}
SharedSSLState*
PrivateSSLState()
{
return gPrivateState;
}
} // namespace psm
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,66 @@
/* -*- 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 SharedSSLState_h
#define SharedSSLState_h
#include "mozilla/RefPtr.h"
#include "nsNSSIOLayer.h"
class nsClientAuthRememberService;
class nsIObserver;
namespace mozilla {
namespace psm {
class SharedSSLState {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState)
SharedSSLState();
~SharedSSLState();
static void GlobalInit();
static void GlobalCleanup();
nsClientAuthRememberService* GetClientAuthRememberService() {
return mClientAuthRemember;
}
nsSSLIOLayerHelpers& IOLayerHelpers() {
return mIOLayerHelpers;
}
// Main-thread only
void ResetStoredData();
void NotePrivateBrowsingStatus();
// The following methods may be called from any thread
bool SocketCreated();
void NoteSocketCreated();
static void NoteCertOverrideServiceInstantiated();
static void NoteCertDBServiceInstantiated();
private:
void Cleanup();
nsCOMPtr<nsIObserver> mObserver;
RefPtr<nsClientAuthRememberService> mClientAuthRemember;
nsSSLIOLayerHelpers mIOLayerHelpers;
// True if any sockets have been created that use this shared data.
// Requires synchronization between the socket and main threads for
// reading/writing.
Mutex mMutex;
bool mSocketCreated;
};
SharedSSLState* PublicSSLState();
SharedSSLState* PrivateSSLState();
} // namespace psm
} // namespace mozilla
#endif

Просмотреть файл

@ -19,6 +19,7 @@
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsStringBuffer.h" #include "nsStringBuffer.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "nspr.h" #include "nspr.h"
#include "pk11pub.h" #include "pk11pub.h"
@ -27,6 +28,7 @@
#include "ssl.h" // For SSL_ClearSessionCache #include "ssl.h" // For SSL_ClearSessionCache
using namespace mozilla; using namespace mozilla;
using mozilla::psm::SharedSSLState;
static const char kCertOverrideFileName[] = "cert_override.txt"; static const char kCertOverrideFileName[] = "cert_override.txt";
@ -128,6 +130,7 @@ nsCertOverrideService::Init()
Observe(nullptr, "profile-do-change", nullptr); Observe(nullptr, "profile-do-change", nullptr);
} }
SharedSSLState::NoteCertOverrideServiceInstantiated();
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -21,8 +21,10 @@
#include "pk11pub.h" #include "pk11pub.h"
#include "certdb.h" #include "certdb.h"
#include "sechash.h" #include "sechash.h"
#include "SharedSSLState.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::psm;
NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService, NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService,
nsIObserver, nsIObserver,
@ -80,6 +82,16 @@ void nsClientAuthRememberService::ClearRememberedDecisions()
RemoveAllFromMemory(); RemoveAllFromMemory();
} }
void nsClientAuthRememberService::ClearAllRememberedDecisions()
{
RefPtr<nsClientAuthRememberService> svc =
PublicSSLState()->GetClientAuthRememberService();
svc->ClearRememberedDecisions();
svc = PrivateSSLState()->GetClientAuthRememberService();
svc->ClearRememberedDecisions();
}
void void
nsClientAuthRememberService::RemoveAllFromMemory() nsClientAuthRememberService::RemoveAllFromMemory()
{ {

Просмотреть файл

@ -128,6 +128,7 @@ public:
nsACString & aCertDBKey, bool *_retval); nsACString & aCertDBKey, bool *_retval);
void ClearRememberedDecisions(); void ClearRememberedDecisions();
static void ClearAllRememberedDecisions();
protected: protected:
mozilla::ReentrantMonitor monitor; mozilla::ReentrantMonitor monitor;

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "nsIHttpChannelInternal.h" #include "nsIHttpChannelInternal.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "SharedSSLState.h"
#include "ssl.h" #include "ssl.h"
#include "sslproto.h" #include "sslproto.h"
@ -841,7 +842,8 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
// If the handshake completed, then we know the site is TLS tolerant (if this // If the handshake completed, then we know the site is TLS tolerant (if this
// was a TLS connection). // was a TLS connection).
nsSSLIOLayerHelpers::rememberTolerantSite(infoObject); nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers();
ioLayerHelpers.rememberTolerantSite(infoObject);
if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength, if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength,
&encryptBits, &signer, nullptr)) { &encryptBits, &signer, nullptr)) {
@ -859,7 +861,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess
|| !siteSupportsSafeRenego) { || !siteSupportsSafeRenego) {
bool wantWarning = (nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746() > 0); bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0);
nsCOMPtr<nsIConsoleService> console; nsCOMPtr<nsIConsoleService> console;
if (infoObject && wantWarning) { if (infoObject && wantWarning) {
@ -875,7 +877,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
console->LogStringMessage(msg.get()); console->LogStringMessage(msg.get());
} }
} }
if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) { if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) {
secStatus = nsIWebProgressListener::STATE_IS_BROKEN; secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
} }
} }

Просмотреть файл

@ -31,6 +31,9 @@
#include "nsIPrompt.h" #include "nsIPrompt.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "nsIObserverService.h"
#include "nsRecentBadCerts.h"
#include "SharedSSLState.h"
#include "nspr.h" #include "nspr.h"
#include "certdb.h" #include "certdb.h"
@ -43,6 +46,7 @@
#include "plbase64.h" #include "plbase64.h"
using namespace mozilla; using namespace mozilla;
using mozilla::psm::SharedSSLState;
#ifdef PR_LOGGING #ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog; extern PRLogModuleInfo* gPIPNSSLog;
@ -54,7 +58,9 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2) NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2)
nsNSSCertificateDB::nsNSSCertificateDB() nsNSSCertificateDB::nsNSSCertificateDB()
: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock")
{ {
SharedSSLState::NoteCertDBServiceInstantiated();
} }
nsNSSCertificateDB::~nsNSSCertificateDB() nsNSSCertificateDB::~nsNSSCertificateDB()
@ -1644,3 +1650,21 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval)
NS_ADDREF(*_retval); NS_ADDREF(*_retval);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result)
{
MutexAutoLock lock(mBadCertsLock);
if (isPrivate) {
if (!mPrivateRecentBadCerts) {
mPrivateRecentBadCerts = new nsRecentBadCerts;
}
NS_ADDREF(*result = mPrivateRecentBadCerts);
} else {
if (!mPublicRecentBadCerts) {
mPublicRecentBadCerts = new nsRecentBadCerts;
}
NS_ADDREF(*result = mPublicRecentBadCerts);
}
return NS_OK;
}

Просмотреть файл

@ -7,10 +7,13 @@
#include "nsIX509CertDB.h" #include "nsIX509CertDB.h"
#include "nsIX509CertDB2.h" #include "nsIX509CertDB2.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Mutex.h"
#include "certt.h" #include "certt.h"
class nsCString; class nsCString;
class nsIArray; class nsIArray;
class nsRecentBadCerts;
class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2
{ {
@ -48,6 +51,10 @@ private:
uint32_t length); uint32_t length);
nsresult handleCACertDownload(nsIArray *x509Certs, nsresult handleCACertDownload(nsIArray *x509Certs,
nsIInterfaceRequestor *ctx); nsIInterfaceRequestor *ctx);
mozilla::Mutex mBadCertsLock;
mozilla::RefPtr<nsRecentBadCerts> mPublicRecentBadCerts;
mozilla::RefPtr<nsRecentBadCerts> mPrivateRecentBadCerts;
}; };
#define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \ #define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \

Просмотреть файл

@ -60,6 +60,7 @@
#include "nsSmartCardEvent.h" #include "nsSmartCardEvent.h"
#include "nsIKeyModule.h" #include "nsIKeyModule.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "nss.h" #include "nss.h"
#include "pk11func.h" #include "pk11func.h"
@ -400,7 +401,7 @@ nsNSSComponent::~nsNSSComponent()
// All cleanup code requiring services needs to happen in xpcom_shutdown // All cleanup code requiring services needs to happen in xpcom_shutdown
ShutdownNSS(); ShutdownNSS();
nsSSLIOLayerHelpers::Cleanup(); SharedSSLState::GlobalCleanup();
RememberCertErrorsTable::Cleanup(); RememberCertErrorsTable::Cleanup();
--mInstanceCount; --mInstanceCount;
delete mShutdownObjectList; delete mShutdownObjectList;
@ -1860,9 +1861,6 @@ nsNSSComponent::ShutdownNSS()
ShutdownSmartCardThreads(); ShutdownSmartCardThreads();
SSL_ClearSessionCache(); SSL_ClearSessionCache();
if (mClientAuthRememberService) {
mClientAuthRememberService->ClearRememberedDecisions();
}
UnloadLoadableRoots(); UnloadLoadableRoots();
CleanupIdentityInfo(); CleanupIdentityInfo();
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n")); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n"));
@ -1933,27 +1931,8 @@ nsNSSComponent::Init()
} }
RememberCertErrorsTable::Init(); RememberCertErrorsTable::Init();
nsSSLIOLayerHelpers::Init(); SharedSSLState::GlobalInit();
char *unrestricted_hosts=nullptr;
mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
if (unrestricted_hosts) {
nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts));
nsMemory::Free(unrestricted_hosts);
unrestricted_hosts=nullptr;
}
bool enabled = false;
mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled);
int32_t warnLevel = 1;
mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel);
nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel);
mClientAuthRememberService = new nsClientAuthRememberService;
if (mClientAuthRememberService)
mClientAuthRememberService->Init();
createBackgroundThreads(); createBackgroundThreads();
if (!mCertVerificationThread) if (!mCertVerificationThread)
{ {
@ -2271,20 +2250,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
mPrefBranch->GetBoolPref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", &enabled); mPrefBranch->GetBoolPref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", &enabled);
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION, SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
enabled ? SSL_RENEGOTIATE_UNRESTRICTED : SSL_RENEGOTIATE_REQUIRES_XTN); enabled ? SSL_RENEGOTIATE_UNRESTRICTED : SSL_RENEGOTIATE_REQUIRES_XTN);
} else if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) {
char *unrestricted_hosts=nullptr;
mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
if (unrestricted_hosts) {
nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts));
nsMemory::Free(unrestricted_hosts);
}
} else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) {
mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled);
} else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) {
int32_t warnLevel = 1;
mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel);
nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel);
#ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8 #ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8
} else if (prefName.Equals("security.ssl.enable_false_start")) { } else if (prefName.Equals("security.ssl.enable_false_start")) {
mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled); mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled);
@ -2387,9 +2352,7 @@ nsresult nsNSSComponent::LogoutAuthenticatedPK11()
0); 0);
} }
if (mClientAuthRememberService) { nsClientAuthRememberService::ClearAllRememberedDecisions();
mClientAuthRememberService->ClearRememberedDecisions();
}
return mShutdownObjectList->doPK11Logout(); return mShutdownObjectList->doPK11Logout();
} }
@ -2568,14 +2531,6 @@ nsNSSComponent::DoProfileChangeNetRestore()
mIsNetworkDown = false; mIsNetworkDown = false;
} }
NS_IMETHODIMP
nsNSSComponent::GetClientAuthRememberService(nsClientAuthRememberService **cars)
{
NS_ENSURE_ARG_POINTER(cars);
NS_IF_ADDREF(*cars = mClientAuthRememberService);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsNSSComponent::IsNSSInitialized(bool *initialized) nsNSSComponent::IsNSSInitialized(bool *initialized)
{ {

Просмотреть файл

@ -154,8 +154,6 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0; NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0;
NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars) = 0;
NS_IMETHOD EnsureIdentityInfoLoaded() = 0; NS_IMETHOD EnsureIdentityInfoLoaded() = 0;
NS_IMETHOD IsNSSInitialized(bool *initialized) = 0; NS_IMETHOD IsNSSInitialized(bool *initialized) = 0;
@ -259,7 +257,6 @@ public:
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module); NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module);
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token); NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token);
NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token); NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token);
NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars);
NS_IMETHOD EnsureIdentityInfoLoaded(); NS_IMETHOD EnsureIdentityInfoLoaded();
NS_IMETHOD IsNSSInitialized(bool *initialized); NS_IMETHOD IsNSSInitialized(bool *initialized);
@ -327,7 +324,6 @@ private:
nsCertVerificationThread *mCertVerificationThread; nsCertVerificationThread *mCertVerificationThread;
nsNSSHttpInterface mHttpForNSS; nsNSSHttpInterface mHttpForNSS;
mozilla::RefPtr<nsClientAuthRememberService> mClientAuthRememberService;
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParam; mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParam;
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParamLocalOnly; mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParamLocalOnly;

Просмотреть файл

@ -28,6 +28,8 @@
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "PSMRunnable.h" #include "PSMRunnable.h"
#include "ScopedNSSTypes.h" #include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "mozilla/Preferences.h"
#include "ssl.h" #include "ssl.h"
#include "secerr.h" #include "secerr.h"
@ -63,9 +65,10 @@ typedef enum {ASK, AUTO} SSM_UserCertChoice;
extern PRLogModuleInfo* gPIPNSSLog; extern PRLogModuleInfo* gPIPNSSLog;
#endif #endif
nsNSSSocketInfo::nsNSSSocketInfo(uint32_t providerFlags) nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
: mFd(nullptr), : mFd(nullptr),
mCertVerificationState(before_cert_verification), mCertVerificationState(before_cert_verification),
mSharedState(aState),
mForSTARTTLS(false), mForSTARTTLS(false),
mSSL3Enabled(false), mSSL3Enabled(false),
mTLSEnabled(false), mTLSEnabled(false),
@ -457,6 +460,11 @@ void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow)
mAllowTLSIntoleranceTimeout = aAllow; mAllowTLSIntoleranceTimeout = aAllow;
} }
SharedSSLState& nsNSSSocketInfo::SharedState()
{
return mSharedState;
}
bool nsNSSSocketInfo::HandshakeTimeout() bool nsNSSSocketInfo::HandshakeTimeout()
{ {
if (!mAllowTLSIntoleranceTimeout) if (!mAllowTLSIntoleranceTimeout)
@ -914,7 +922,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading,
if (!wantRetry // no decision yet if (!wantRetry // no decision yet
&& isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase())) && isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase()))
{ {
wantRetry = nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers();
wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo);
} }
} }
@ -942,8 +951,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading,
if (!wantRetry // no decision yet if (!wantRetry // no decision yet
&& !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament && !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament
{ {
wantRetry = nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers();
nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo);
} }
} }
} }
@ -1031,12 +1040,16 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags)
bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false; bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false;
PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity; PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity;
PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods; PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods;
Mutex *nsSSLIOLayerHelpers::mutex = nullptr;
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr; nsSSLIOLayerHelpers::nsSSLIOLayerHelpers()
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr; : mutex(nullptr)
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nullptr; , mTLSIntolerantSites(nullptr)
bool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = false; , mTLSTolerantSites(nullptr)
int32_t nsSSLIOLayerHelpers::mWarnLevelMissingRFC5746 = 1; , mRenegoUnrestrictedSites(nullptr)
, mTreatUnsafeNegotiationAsBroken(false)
, mWarnLevelMissingRFC5746(1)
{
}
static int _PSM_InvalidInt(void) static int _PSM_InvalidInt(void)
{ {
@ -1190,6 +1203,53 @@ static int64_t PSMAvailable64(void)
return -1; return -1;
} }
namespace {
class PrefObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {}
virtual ~PrefObserver() {}
private:
nsSSLIOLayerHelpers* mOwner;
};
} // namespace anonymous
NS_IMPL_THREADSAFE_ISUPPORTS1(PrefObserver, nsIObserver)
NS_IMETHODIMP
PrefObserver::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *someData)
{
if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
NS_ConvertUTF16toUTF8 prefName(someData);
if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) {
nsCString unrestricted_hosts;
Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
if (!unrestricted_hosts.IsEmpty()) {
mOwner->setRenegoUnrestrictedSites(unrestricted_hosts);
}
} else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) {
bool enabled;
Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
mOwner->setTreatUnsafeNegotiationAsBroken(enabled);
} else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) {
int32_t warnLevel = 1;
Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel);
mOwner->setWarnLevelMissingRFC5746(warnLevel);
}
}
return NS_OK;
}
nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers()
{
Preferences::RemoveObserver(mPrefObserver, "security.ssl.renego_unrestricted_hosts");
Preferences::RemoveObserver(mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken");
Preferences::RemoveObserver(mPrefObserver, "security.ssl.warn_missing_rfc5746");
}
nsresult nsSSLIOLayerHelpers::Init() nsresult nsSSLIOLayerHelpers::Init()
{ {
if (!nsSSLIOLayerInitialized) { if (!nsSSLIOLayerInitialized) {
@ -1244,23 +1304,50 @@ nsresult nsSSLIOLayerHelpers::Init()
mRenegoUnrestrictedSites = new nsTHashtable<nsCStringHashKey>(); mRenegoUnrestrictedSites = new nsTHashtable<nsCStringHashKey>();
mRenegoUnrestrictedSites->Init(1); mRenegoUnrestrictedSites->Init(1);
mTreatUnsafeNegotiationAsBroken = false; nsCString unrestricted_hosts;
Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
if (!unrestricted_hosts.IsEmpty()) {
setRenegoUnrestrictedSites(unrestricted_hosts);
}
bool enabled = false;
Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
setTreatUnsafeNegotiationAsBroken(enabled);
int32_t warnLevel = 1;
Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel);
setWarnLevelMissingRFC5746(warnLevel);
mPrefObserver = new PrefObserver(this);
Preferences::AddStrongObserver(mPrefObserver,
"security.ssl.renego_unrestricted_hosts");
Preferences::AddStrongObserver(mPrefObserver,
"security.ssl.treat_unsafe_negotiation_as_broken");
Preferences::AddStrongObserver(mPrefObserver,
"security.ssl.warn_missing_rfc5746");
return NS_OK; return NS_OK;
} }
void nsSSLIOLayerHelpers::clearStoredData()
{
mRenegoUnrestrictedSites->Clear();
mTLSTolerantSites->Clear();
mTLSIntolerantSites->Clear();
}
void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str) void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str)
{ {
MutexAutoLock lock(*mutex); MutexAutoLock lock(*mutex);
// Remember intolerant site only if it is not known as tolerant // Remember intolerant site only if it is not known as tolerant
if (!mTLSTolerantSites->Contains(str)) if (!mTLSTolerantSites->Contains(str))
nsSSLIOLayerHelpers::mTLSIntolerantSites->PutEntry(str); mTLSIntolerantSites->PutEntry(str);
} }
void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str) void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str)
{ {
MutexAutoLock lock(*mutex); MutexAutoLock lock(*mutex);
nsSSLIOLayerHelpers::mTLSIntolerantSites->RemoveEntry(str); mTLSIntolerantSites->RemoveEntry(str);
} }
bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str) bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str)
@ -1923,6 +2010,7 @@ void ClientAuthDataRunnable::RunOnTargetThread()
SSM_UserCertChoice certChoice; SSM_UserCertChoice certChoice;
int32_t NumberOfCerts = 0; int32_t NumberOfCerts = 0;
void * wincx = mSocketInfo; void * wincx = mSocketInfo;
nsresult rv;
/* create caNameStrings */ /* create caNameStrings */
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@ -2024,19 +2112,14 @@ void ClientAuthDataRunnable::RunOnTargetThread()
nsXPIDLCString hostname; nsXPIDLCString hostname;
mSocketInfo->GetHostName(getter_Copies(hostname)); mSocketInfo->GetHostName(getter_Copies(hostname));
nsresult rv; RefPtr<nsClientAuthRememberService> cars =
NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID); mSocketInfo->SharedState().GetClientAuthRememberService();
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv));
RefPtr<nsClientAuthRememberService> cars;
if (nssComponent) {
nssComponent->GetClientAuthRememberService(byRef(cars));
}
bool hasRemembered = false; bool hasRemembered = false;
nsCString rememberedDBKey; nsCString rememberedDBKey;
if (cars) { if (cars) {
bool found; bool found;
nsresult rv = cars->HasRememberedDecision(hostname, mServerCert, rv = cars->HasRememberedDecision(hostname, mServerCert,
rememberedDBKey, &found); rememberedDBKey, &found);
if (NS_SUCCEEDED(rv) && found) { if (NS_SUCCEEDED(rv) && found) {
hasRemembered = true; hasRemembered = true;
@ -2219,9 +2302,9 @@ if (!hasRemembered)
} }
/* Throw up the client auth dialog and get back the index of the selected cert */ /* Throw up the client auth dialog and get back the index of the selected cert */
rv = getNSSDialogs((void**)&dialogs, nsresult rv = getNSSDialogs((void**)&dialogs,
NS_GET_IID(nsIClientAuthDialogs), NS_GET_IID(nsIClientAuthDialogs),
NS_CLIENTAUTHDIALOGS_CONTRACTID); NS_CLIENTAUTHDIALOGS_CONTRACTID);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
@ -2365,7 +2448,7 @@ loser:
static nsresult static nsresult
nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
const char *proxyHost, const char *host, int32_t port, const char *proxyHost, const char *host, int32_t port,
bool anonymousLoad, nsNSSSocketInfo *infoObject) nsNSSSocketInfo *infoObject)
{ {
nsNSSShutDownPreventionLock locker; nsNSSShutDownPreventionLock locker;
if (forSTARTTLS || proxyHost) { if (forSTARTTLS || proxyHost) {
@ -2380,7 +2463,7 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
nsAutoCString key; nsAutoCString key;
key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port); key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port);
if (nsSSLIOLayerHelpers::isKnownAsIntolerantSite(key)) { if (infoObject->SharedState().IOLayerHelpers().isKnownAsIntolerantSite(key)) {
if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false)) if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -2407,8 +2490,9 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) { if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(nsDependentCString(host))) { nsSSLIOLayerHelpers& ioHelpers = infoObject->SharedState().IOLayerHelpers();
if (ioHelpers.isRenegoUnrestrictedSite(nsDependentCString(host))) {
if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) { if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -2417,20 +2501,23 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
} }
} }
// Set the Peer ID so that SSL proxy connections work properly. // Set the Peer ID so that SSL proxy connections work properly and to
char *peerId; // separate anonymous and/or private browsing connections.
if (anonymousLoad) { // See bug #466080. Separate the caches. uint32_t flags = infoObject->GetProviderFlags();
peerId = PR_smprintf("anon:%s:%d", host, port); nsAutoCString peerId;
} else { if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
peerId = PR_smprintf("%s:%d", host, port); peerId.Append("anon:");
} }
if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
if (SECSuccess != SSL_SetSockPeerID(fd, peerId)) { peerId.Append("private:");
PR_smprintf_free(peerId); }
peerId.Append(host);
peerId.Append(':');
peerId.AppendInt(port);
if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
PR_smprintf_free(peerId);
return NS_OK; return NS_OK;
} }
@ -2450,7 +2537,9 @@ nsSSLIOLayerAddToSocket(int32_t family,
nsresult rv; nsresult rv;
PRStatus stat; PRStatus stat;
nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(providerFlags); SharedSSLState* sharedState =
providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState();
nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags);
if (!infoObject) return NS_ERROR_FAILURE; if (!infoObject) return NS_ERROR_FAILURE;
NS_ADDREF(infoObject); NS_ADDREF(infoObject);
@ -2458,7 +2547,6 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetHostName(host); infoObject->SetHostName(host);
infoObject->SetPort(port); infoObject->SetPort(port);
bool anonymousLoad = providerFlags & nsISocketProvider::ANONYMOUS_CONNECT;
PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host); PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host);
if (!sslSock) { if (!sslSock) {
NS_ASSERTION(false, "NSS: Error importing socket"); NS_ASSERTION(false, "NSS: Error importing socket");
@ -2467,8 +2555,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetFileDescPtr(sslSock); infoObject->SetFileDescPtr(sslSock);
rv = nsSSLIOLayerSetOptions(sslSock, rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
forSTARTTLS, proxyHost, host, port, anonymousLoad,
infoObject); infoObject);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
@ -2497,6 +2584,8 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetHandshakePending(false); infoObject->SetHandshakePending(false);
} }
infoObject->SharedState().NoteSocketCreated();
return NS_OK; return NS_OK;
loser: loser:
NS_IF_RELEASE(infoObject); NS_IF_RELEASE(infoObject);

Просмотреть файл

@ -15,12 +15,20 @@
#include "nsTHashtable.h" #include "nsTHashtable.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
namespace mozilla {
namespace psm {
class SharedSSLState;
}
}
class nsIObserver;
class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo,
public nsISSLSocketControl, public nsISSLSocketControl,
public nsIClientAuthUserDecision public nsIClientAuthUserDecision
{ {
public: public:
nsNSSSocketInfo(uint32_t providerFlags); nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSISSLSOCKETCONTROL NS_DECL_NSISSLSOCKETCONTROL
@ -55,7 +63,11 @@ public:
bool GetJoined() { return mJoined; } bool GetJoined() { return mJoined; }
void SetSentClientCert() { mSentClientCert = true; } void SetSentClientCert() { mSentClientCert = true; }
uint32_t GetProviderFlags() const { return mProviderFlags; }
mozilla::psm::SharedSSLState& SharedState();
// XXX: These are only used on for diagnostic purposes // XXX: These are only used on for diagnostic purposes
enum CertVerificationState { enum CertVerificationState {
before_cert_verification, before_cert_verification,
@ -83,6 +95,7 @@ private:
CertVerificationState mCertVerificationState; CertVerificationState mCertVerificationState;
mozilla::psm::SharedSSLState& mSharedState;
bool mForSTARTTLS; bool mForSTARTTLS;
bool mSSL3Enabled; bool mSSL3Enabled;
bool mTLSEnabled; bool mTLSEnabled;
@ -109,37 +122,44 @@ private:
class nsSSLIOLayerHelpers class nsSSLIOLayerHelpers
{ {
public: public:
static nsresult Init(); nsSSLIOLayerHelpers();
static void Cleanup(); ~nsSSLIOLayerHelpers();
nsresult Init();
void Cleanup();
static bool nsSSLIOLayerInitialized; static bool nsSSLIOLayerInitialized;
static PRDescIdentity nsSSLIOLayerIdentity; static PRDescIdentity nsSSLIOLayerIdentity;
static PRIOMethods nsSSLIOLayerMethods; static PRIOMethods nsSSLIOLayerMethods;
static mozilla::Mutex *mutex; mozilla::Mutex *mutex;
static nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites; nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites;
static nsTHashtable<nsCStringHashKey> *mTLSTolerantSites; nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
static nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites; nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites;
static bool mTreatUnsafeNegotiationAsBroken; bool mTreatUnsafeNegotiationAsBroken;
static int32_t mWarnLevelMissingRFC5746; int32_t mWarnLevelMissingRFC5746;
static void setTreatUnsafeNegotiationAsBroken(bool broken); void setTreatUnsafeNegotiationAsBroken(bool broken);
static bool treatUnsafeNegotiationAsBroken(); bool treatUnsafeNegotiationAsBroken();
static void setWarnLevelMissingRFC5746(int32_t level); void setWarnLevelMissingRFC5746(int32_t level);
static int32_t getWarnLevelMissingRFC5746(); int32_t getWarnLevelMissingRFC5746();
static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key); static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key);
static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo);
static void rememberTolerantSite(nsNSSSocketInfo *socketInfo); void rememberTolerantSite(nsNSSSocketInfo *socketInfo);
static void addIntolerantSite(const nsCString &str); void addIntolerantSite(const nsCString &str);
static void removeIntolerantSite(const nsCString &str); void removeIntolerantSite(const nsCString &str);
static bool isKnownAsIntolerantSite(const nsCString &str); bool isKnownAsIntolerantSite(const nsCString &str);
static void setRenegoUnrestrictedSites(const nsCString &str); void setRenegoUnrestrictedSites(const nsCString &str);
static bool isRenegoUnrestrictedSite(const nsCString &str); bool isRenegoUnrestrictedSite(const nsCString &str);
void clearStoredData();
private:
nsCOMPtr<nsIObserver> mPrefObserver;
}; };
nsresult nsSSLIOLayerNewSocket(int32_t family, nsresult nsSSLIOLayerNewSocket(int32_t family,

Просмотреть файл

@ -38,7 +38,6 @@
#include "nsDataSignatureVerifier.h" #include "nsDataSignatureVerifier.h"
#include "nsCertOverrideService.h" #include "nsCertOverrideService.h"
#include "nsRandomGenerator.h" #include "nsRandomGenerator.h"
#include "nsRecentBadCerts.h"
#include "nsSSLStatus.h" #include "nsSSLStatus.h"
#include "TransportSecurityInfo.h" #include "TransportSecurityInfo.h"
#include "NSSErrorsService.h" #include "NSSErrorsService.h"
@ -204,7 +203,6 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsRecentBadCertsService, Init)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo)
@ -243,7 +241,6 @@ NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID);
NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID); NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID);
NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID); NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID);
NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID); NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID);
NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID);
NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID); NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID);
NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID); NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID); NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID);
@ -281,7 +278,6 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = {
{ &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor }, { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor },
{ &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor }, { &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor },
{ &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor }, { &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor },
{ &kNS_RECENTBADCERTS_CID, false, nullptr, nsRecentBadCertsServiceConstructor },
{ &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor }, { &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor },
{ &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor }, { &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor },
{ &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor }, { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor },
@ -324,7 +320,6 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = {
{ NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID }, { NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID },
{ NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID }, { NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID },
{ NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID }, { NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID },
{ NS_RECENTBADCERTS_CONTRACTID, &kNS_RECENTBADCERTS_CID },
{ nullptr } { nullptr }
}; };

Просмотреть файл

@ -6,7 +6,9 @@
#include "nsRecentBadCerts.h" #include "nsRecentBadCerts.h"
#include "nsIX509Cert.h" #include "nsIX509Cert.h"
#include "nsIObserverService.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "nsSSLStatus.h" #include "nsSSLStatus.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsNSSCertificate.h" #include "nsNSSCertificate.h"
@ -20,28 +22,22 @@
using namespace mozilla; using namespace mozilla;
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService, NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts,
nsIRecentBadCertsService) nsIRecentBadCerts)
nsRecentBadCertsService::nsRecentBadCertsService() nsRecentBadCerts::nsRecentBadCerts()
:monitor("nsRecentBadCertsService.monitor") :monitor("nsRecentBadCerts.monitor")
,mNextStorePosition(0) ,mNextStorePosition(0)
{ {
} }
nsRecentBadCertsService::~nsRecentBadCertsService() nsRecentBadCerts::~nsRecentBadCerts()
{ {
} }
nsresult
nsRecentBadCertsService::Init()
{
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort,
nsISSLStatus **aStatus) nsISSLStatus **aStatus)
{ {
NS_ENSURE_ARG_POINTER(aStatus); NS_ENSURE_ARG_POINTER(aStatus);
if (!aHostNameWithPort.Length()) if (!aHostNameWithPort.Length())
@ -101,7 +97,7 @@ nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort,
} }
NS_IMETHODIMP NS_IMETHODIMP
nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort,
nsISSLStatus *aStatus) nsISSLStatus *aStatus)
{ {
NS_ENSURE_ARG(aStatus); NS_ENSURE_ARG(aStatus);
@ -146,3 +142,13 @@ nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsRecentBadCerts::ResetStoredCerts()
{
for (size_t i = 0; i < const_recently_seen_list_size; ++i) {
RecentBadCert &entry = mCerts[i];
entry.Clear();
}
return NS_OK;
}

Просмотреть файл

@ -54,16 +54,14 @@ private:
RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE; RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE;
}; };
class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIRECENTBADCERTSSERVICE NS_DECL_NSIRECENTBADCERTS
nsRecentBadCertsService(); nsRecentBadCerts();
~nsRecentBadCertsService(); ~nsRecentBadCerts();
nsresult Init();
protected: protected:
mozilla::ReentrantMonitor monitor; mozilla::ReentrantMonitor monitor;