security/manager/ssl/src/SharedSSLState.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "SharedSSLState.h"
     8 #include "nsClientAuthRemember.h"
     9 #include "nsComponentManagerUtils.h"
    10 #include "nsICertOverrideService.h"
    11 #include "nsIObserverService.h"
    12 #include "mozilla/Services.h"
    13 #include "nsThreadUtils.h"
    14 #include "nsCRT.h"
    15 #include "nsServiceManagerUtils.h"
    16 #include "nsRecentBadCerts.h"
    17 #include "PSMRunnable.h"
    18 #include "PublicSSL.h"
    19 #include "ssl.h"
    20 #include "nsNetCID.h"
    21 #include "mozilla/Atomics.h"
    22 #include "mozilla/unused.h"
    24 using mozilla::psm::SyncRunnableBase;
    25 using mozilla::Atomic;
    26 using mozilla::unused;
    28 namespace {
    30 static Atomic<bool> sCertOverrideSvcExists(false);
    31 static Atomic<bool> sCertDBExists(false);
    33 class MainThreadClearer : public SyncRunnableBase
    34 {
    35 public:
    36   MainThreadClearer() : mShouldClearSessionCache(false) {}
    38   void RunOnTargetThread() {
    39     // In some cases it's possible to cause PSM/NSS to initialize while XPCOM shutdown
    40     // is in progress. We want to avoid this, since they do not handle the situation well,
    41     // hence the flags to avoid instantiating the services if they don't already exist.
    43     bool certOverrideSvcExists = sCertOverrideSvcExists.exchange(false);
    44     if (certOverrideSvcExists) {
    45       sCertOverrideSvcExists = true;
    46       nsCOMPtr<nsICertOverrideService> icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID);
    47       if (icos) {
    48         icos->ClearValidityOverride(
    49           NS_LITERAL_CSTRING("all:temporary-certificates"),
    50           0);
    51       }
    52     }
    54     bool certDBExists = sCertDBExists.exchange(false);
    55     if (certDBExists) {
    56       sCertDBExists = true;
    57       nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
    58       if (certdb) {
    59         nsCOMPtr<nsIRecentBadCerts> badCerts;
    60         certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts));
    61         if (badCerts) {
    62           badCerts->ResetStoredCerts();
    63         }
    64       }
    65     }
    67     // This needs to be checked on the main thread to avoid racing with NSS
    68     // initialization.
    69     mShouldClearSessionCache = mozilla::psm::PrivateSSLState() &&
    70                                mozilla::psm::PrivateSSLState()->SocketCreated();
    71   }
    72   bool mShouldClearSessionCache;
    73 };
    75 } // anonymous namespace
    77 namespace mozilla {
    79 void ClearPrivateSSLState()
    80 {
    81   // This only works if it is called on the socket transport
    82   // service thread immediately after closing all private SSL
    83   // connections.
    84 #ifdef DEBUG
    85   nsresult rv;
    86   nsCOMPtr<nsIEventTarget> sts
    87     = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
    88   MOZ_ASSERT(NS_SUCCEEDED(rv));
    89   bool onSTSThread;
    90   rv = sts->IsOnCurrentThread(&onSTSThread);
    91   MOZ_ASSERT(NS_SUCCEEDED(rv) && onSTSThread);
    92 #endif
    94   RefPtr<MainThreadClearer> runnable = new MainThreadClearer;
    95   runnable->DispatchToMainThreadAndWait();
    97   // If NSS isn't initialized, this throws an assertion. We guard it by checking if
    98   // the session cache might even have anything worth clearing.
    99   if (runnable->mShouldClearSessionCache) {
   100     SSL_ClearSessionCache();
   101   }
   102 }
   104 namespace psm {
   106 namespace {
   107 class PrivateBrowsingObserver : public nsIObserver {
   108 public:
   109   NS_DECL_ISUPPORTS
   110   NS_DECL_NSIOBSERVER
   111   PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {}
   112   virtual ~PrivateBrowsingObserver() {}
   113 private:
   114   SharedSSLState* mOwner;
   115 };
   117 SharedSSLState* gPublicState;
   118 SharedSSLState* gPrivateState;
   119 } // anonymous namespace
   121 NS_IMPL_ISUPPORTS(PrivateBrowsingObserver, nsIObserver)
   123 NS_IMETHODIMP
   124 PrivateBrowsingObserver::Observe(nsISupports     *aSubject,
   125                                  const char      *aTopic,
   126                                  const char16_t *aData)
   127 {
   128   if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) {
   129     mOwner->ResetStoredData();
   130   }
   131   return NS_OK;
   132 }
   134 SharedSSLState::SharedSSLState()
   135 : mClientAuthRemember(new nsClientAuthRememberService)
   136 , mMutex("SharedSSLState::mMutex")
   137 , mSocketCreated(false)
   138 , mOCSPStaplingEnabled(false)
   139 {
   140   mIOLayerHelpers.Init();
   141   mClientAuthRemember->Init();
   142 }
   144 SharedSSLState::~SharedSSLState()
   145 {
   146 }
   148 void
   149 SharedSSLState::NotePrivateBrowsingStatus()
   150 {
   151   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
   152   mObserver = new PrivateBrowsingObserver(this);
   153   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
   154   obsSvc->AddObserver(mObserver, "last-pb-context-exited", false);
   155 }
   157 void
   158 SharedSSLState::ResetStoredData()
   159 {
   160   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
   161   mClientAuthRemember->ClearRememberedDecisions();
   162   mIOLayerHelpers.clearStoredData();
   163 }
   165 void
   166 SharedSSLState::NoteSocketCreated()
   167 {
   168   MutexAutoLock lock(mMutex);
   169   mSocketCreated = true;
   170 }
   172 bool
   173 SharedSSLState::SocketCreated()
   174 {
   175   MutexAutoLock lock(mMutex);
   176   return mSocketCreated;
   177 }
   179 /*static*/ void
   180 SharedSSLState::GlobalInit()
   181 {
   182   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
   183   gPublicState = new SharedSSLState();
   184   gPrivateState = new SharedSSLState();
   185   gPrivateState->NotePrivateBrowsingStatus();
   186 }
   188 /*static*/ void
   189 SharedSSLState::GlobalCleanup()
   190 {
   191   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
   193   if (gPrivateState) {
   194     gPrivateState->Cleanup();
   195     delete gPrivateState;
   196     gPrivateState = nullptr;
   197   }
   199   if (gPublicState) {
   200     gPublicState->Cleanup();
   201     delete gPublicState;
   202     gPublicState = nullptr;
   203   }
   204 }
   206 /*static*/ void
   207 SharedSSLState::NoteCertOverrideServiceInstantiated()
   208 {
   209   sCertOverrideSvcExists = true;
   210 }
   212 /*static*/ void
   213 SharedSSLState::NoteCertDBServiceInstantiated()
   214 {
   215   sCertDBExists = true;
   216 }
   218 void
   219 SharedSSLState::Cleanup()
   220 {
   221   mIOLayerHelpers.Cleanup();
   222 }
   224 SharedSSLState*
   225 PublicSSLState()
   226 {
   227   return gPublicState;
   228 }
   230 SharedSSLState*
   231 PrivateSSLState()
   232 {
   233   return gPrivateState;
   234 }
   236 } // namespace psm
   237 } // namespace mozilla

mercurial