LCOV - code coverage report
Current view: top level - security/manager/ssl - SharedSSLState.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 24 84 28.6 %
Date: 2017-07-14 16:53:18 Functions: 9 24 37.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       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 "PSMRunnable.h"
      17             : #include "PublicSSL.h"
      18             : #include "ssl.h"
      19             : #include "nsNetCID.h"
      20             : #include "mozilla/Atomics.h"
      21             : #include "mozilla/Unused.h"
      22             : 
      23             : using mozilla::psm::SyncRunnableBase;
      24             : using mozilla::Atomic;
      25             : using mozilla::Unused;
      26             : 
      27             : namespace {
      28             : 
      29             : static Atomic<bool> sCertOverrideSvcExists(false);
      30             : 
      31           0 : class MainThreadClearer : public SyncRunnableBase
      32             : {
      33             : public:
      34           0 :   MainThreadClearer() : mShouldClearSessionCache(false) {}
      35             : 
      36           0 :   void RunOnTargetThread() {
      37             :     // In some cases it's possible to cause PSM/NSS to initialize while XPCOM shutdown
      38             :     // is in progress. We want to avoid this, since they do not handle the situation well,
      39             :     // hence the flags to avoid instantiating the services if they don't already exist.
      40             : 
      41           0 :     bool certOverrideSvcExists = sCertOverrideSvcExists.exchange(false);
      42           0 :     if (certOverrideSvcExists) {
      43           0 :       sCertOverrideSvcExists = true;
      44           0 :       nsCOMPtr<nsICertOverrideService> icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID);
      45           0 :       if (icos) {
      46           0 :         icos->ClearValidityOverride(
      47           0 :           NS_LITERAL_CSTRING("all:temporary-certificates"),
      48           0 :           0);
      49             :       }
      50             :     }
      51             : 
      52             :     // This needs to be checked on the main thread to avoid racing with NSS
      53             :     // initialization.
      54           0 :     mShouldClearSessionCache = mozilla::psm::PrivateSSLState() &&
      55           0 :                                mozilla::psm::PrivateSSLState()->SocketCreated();
      56           0 :   }
      57             :   bool mShouldClearSessionCache;
      58             : };
      59             : 
      60             : } // namespace
      61             : 
      62             : namespace mozilla {
      63             : 
      64           0 : void ClearPrivateSSLState()
      65             : {
      66             :   // This only works if it is called on the socket transport
      67             :   // service thread immediately after closing all private SSL
      68             :   // connections.
      69             : #ifdef DEBUG
      70             :   nsresult rv;
      71             :   nsCOMPtr<nsIEventTarget> sts
      72           0 :     = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
      73           0 :   MOZ_ASSERT(NS_SUCCEEDED(rv));
      74             :   bool onSTSThread;
      75           0 :   rv = sts->IsOnCurrentThread(&onSTSThread);
      76           0 :   MOZ_ASSERT(NS_SUCCEEDED(rv) && onSTSThread);
      77             : #endif
      78             : 
      79           0 :   RefPtr<MainThreadClearer> runnable = new MainThreadClearer;
      80           0 :   runnable->DispatchToMainThreadAndWait();
      81             : 
      82             :   // If NSS isn't initialized, this throws an assertion. We guard it by checking if
      83             :   // the session cache might even have anything worth clearing.
      84           0 :   if (runnable->mShouldClearSessionCache) {
      85           0 :     SSL_ClearSessionCache();
      86             :   }
      87           0 : }
      88             : 
      89             : namespace psm {
      90             : 
      91             : namespace {
      92             : class PrivateBrowsingObserver : public nsIObserver {
      93             : public:
      94             :   NS_DECL_ISUPPORTS
      95             :   NS_DECL_NSIOBSERVER
      96           1 :   explicit PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {}
      97             : protected:
      98           0 :   virtual ~PrivateBrowsingObserver() {}
      99             : private:
     100             :   SharedSSLState* mOwner;
     101             : };
     102             : 
     103             : SharedSSLState* gPublicState;
     104             : SharedSSLState* gPrivateState;
     105             : } // namespace
     106             : 
     107           5 : NS_IMPL_ISUPPORTS(PrivateBrowsingObserver, nsIObserver)
     108             : 
     109             : NS_IMETHODIMP
     110           0 : PrivateBrowsingObserver::Observe(nsISupports     *aSubject,
     111             :                                  const char      *aTopic,
     112             :                                  const char16_t *aData)
     113             : {
     114           0 :   if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) {
     115           0 :     mOwner->ResetStoredData();
     116             :   }
     117           0 :   return NS_OK;
     118             : }
     119             : 
     120           2 : SharedSSLState::SharedSSLState()
     121           2 : : mClientAuthRemember(new nsClientAuthRememberService)
     122             : , mMutex("SharedSSLState::mMutex")
     123             : , mSocketCreated(false)
     124             : , mOCSPStaplingEnabled(false)
     125           4 : , mOCSPMustStapleEnabled(false)
     126             : {
     127           2 :   mIOLayerHelpers.Init();
     128           2 :   mClientAuthRemember->Init();
     129           2 : }
     130             : 
     131           0 : SharedSSLState::~SharedSSLState()
     132             : {
     133           0 : }
     134             : 
     135             : void
     136           1 : SharedSSLState::NotePrivateBrowsingStatus()
     137             : {
     138           1 :   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
     139           1 :   mObserver = new PrivateBrowsingObserver(this);
     140           2 :   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
     141           1 :   obsSvc->AddObserver(mObserver, "last-pb-context-exited", false);
     142           1 : }
     143             : 
     144             : void
     145           0 : SharedSSLState::ResetStoredData()
     146             : {
     147           0 :   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
     148           0 :   mClientAuthRemember->ClearRememberedDecisions();
     149           0 :   mIOLayerHelpers.clearStoredData();
     150           0 : }
     151             : 
     152             : void
     153           0 : SharedSSLState::NoteSocketCreated()
     154             : {
     155           0 :   MutexAutoLock lock(mMutex);
     156           0 :   mSocketCreated = true;
     157           0 : }
     158             : 
     159             : bool
     160           0 : SharedSSLState::SocketCreated()
     161             : {
     162           0 :   MutexAutoLock lock(mMutex);
     163           0 :   return mSocketCreated;
     164             : }
     165             : 
     166             : /*static*/ void
     167           1 : SharedSSLState::GlobalInit()
     168             : {
     169           1 :   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
     170           1 :   gPublicState = new SharedSSLState();
     171           1 :   gPrivateState = new SharedSSLState();
     172           1 :   gPrivateState->NotePrivateBrowsingStatus();
     173           1 : }
     174             : 
     175             : /*static*/ void
     176           0 : SharedSSLState::GlobalCleanup()
     177             : {
     178           0 :   MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
     179             : 
     180           0 :   if (gPrivateState) {
     181           0 :     gPrivateState->Cleanup();
     182           0 :     delete gPrivateState;
     183           0 :     gPrivateState = nullptr;
     184             :   }
     185             : 
     186           0 :   if (gPublicState) {
     187           0 :     gPublicState->Cleanup();
     188           0 :     delete gPublicState;
     189           0 :     gPublicState = nullptr;
     190             :   }
     191           0 : }
     192             : 
     193             : /*static*/ void
     194           0 : SharedSSLState::NoteCertOverrideServiceInstantiated()
     195             : {
     196           0 :   sCertOverrideSvcExists = true;
     197           0 : }
     198             : 
     199             : void
     200           0 : SharedSSLState::Cleanup()
     201             : {
     202           0 :   mIOLayerHelpers.Cleanup();
     203           0 : }
     204             : 
     205             : SharedSSLState*
     206           3 : PublicSSLState()
     207             : {
     208           3 :   return gPublicState;
     209             : }
     210             : 
     211             : SharedSSLState*
     212           3 : PrivateSSLState()
     213             : {
     214           3 :   return gPrivateState;
     215             : }
     216             : 
     217             : } // namespace psm
     218             : } // namespace mozilla

Generated by: LCOV version 1.13