LCOV - code coverage report
Current view: top level - extensions/cookie - nsCookiePermission.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 32 96 33.3 %
Date: 2017-07-14 16:53:18 Functions: 6 9 66.7 %
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 sw=2 et: */
       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 "nsCookiePermission.h"
       8             : 
       9             : #include "mozIThirdPartyUtil.h"
      10             : #include "nsICookie2.h"
      11             : #include "nsIServiceManager.h"
      12             : #include "nsICookieManager2.h"
      13             : #include "nsNetUtil.h"
      14             : #include "nsIInterfaceRequestorUtils.h"
      15             : #include "nsIProtocolHandler.h"
      16             : #include "nsIURI.h"
      17             : #include "nsIPrefService.h"
      18             : #include "nsIPrefBranch.h"
      19             : #include "nsIChannel.h"
      20             : #include "nsIHttpChannelInternal.h"
      21             : #include "nsIDOMWindow.h"
      22             : #include "nsIPrincipal.h"
      23             : #include "nsString.h"
      24             : #include "nsCRT.h"
      25             : #include "nsILoadContext.h"
      26             : #include "nsIScriptObjectPrincipal.h"
      27             : #include "nsNetCID.h"
      28             : #include "prtime.h"
      29             : 
      30             : /****************************************************************
      31             :  ************************ nsCookiePermission ********************
      32             :  ****************************************************************/
      33             : 
      34             : // values for mCookiesLifetimePolicy
      35             : // 0 == accept normally
      36             : // 1 == ask before accepting, no more supported, treated like ACCEPT_NORMALLY (Bug 606655).
      37             : // 2 == downgrade to session
      38             : // 3 == limit lifetime to N days
      39             : static const uint32_t ACCEPT_NORMALLY = 0;
      40             : static const uint32_t ASK_BEFORE_ACCEPT = 1;
      41             : static const uint32_t ACCEPT_SESSION = 2;
      42             : static const uint32_t ACCEPT_FOR_N_DAYS = 3;
      43             : 
      44             : static const bool kDefaultPolicy = true;
      45             : static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
      46             : static const char kCookiesLifetimeDays[] = "network.cookie.lifetime.days";
      47             : 
      48             : static const char kCookiesPrefsMigrated[] = "network.cookie.prefsMigrated";
      49             : // obsolete pref names for migration
      50             : static const char kCookiesLifetimeEnabled[] = "network.cookie.lifetime.enabled";
      51             : static const char kCookiesLifetimeBehavior[] = "network.cookie.lifetime.behavior";
      52             : 
      53             : static const char kPermissionType[] = "cookie";
      54             : 
      55          21 : NS_IMPL_ISUPPORTS(nsCookiePermission,
      56             :                   nsICookiePermission,
      57             :                   nsIObserver)
      58             : 
      59             : bool
      60           1 : nsCookiePermission::Init()
      61             : {
      62             :   // Initialize nsIPermissionManager and fetch relevant prefs. This is only
      63             :   // required for some methods on nsICookiePermission, so it should be done
      64             :   // lazily.
      65             :   nsresult rv;
      66           1 :   mPermMgr = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
      67           1 :   if (NS_FAILED(rv)) return false;
      68           1 :   mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID, &rv);
      69           1 :   if (NS_FAILED(rv)) return false;
      70             : 
      71             :   // failure to access the pref service is non-fatal...
      72             :   nsCOMPtr<nsIPrefBranch> prefBranch =
      73           2 :       do_GetService(NS_PREFSERVICE_CONTRACTID);
      74           1 :   if (prefBranch) {
      75           1 :     prefBranch->AddObserver(kCookiesLifetimePolicy, this, false);
      76           1 :     prefBranch->AddObserver(kCookiesLifetimeDays, this, false);
      77           1 :     PrefChanged(prefBranch, nullptr);
      78             : 
      79             :     // migration code for original cookie prefs
      80             :     bool migrated;
      81           1 :     rv = prefBranch->GetBoolPref(kCookiesPrefsMigrated, &migrated);
      82           1 :     if (NS_FAILED(rv) || !migrated) {
      83           0 :       bool lifetimeEnabled = false;
      84           0 :       prefBranch->GetBoolPref(kCookiesLifetimeEnabled, &lifetimeEnabled);
      85             : 
      86             :       // if they're limiting lifetime, use the appropriate limited lifetime pref
      87           0 :       if (lifetimeEnabled) {
      88             :         int32_t lifetimeBehavior;
      89           0 :         prefBranch->GetIntPref(kCookiesLifetimeBehavior, &lifetimeBehavior);
      90           0 :         if (lifetimeBehavior)
      91           0 :           prefBranch->SetIntPref(kCookiesLifetimePolicy, ACCEPT_FOR_N_DAYS);
      92             :         else
      93           0 :           prefBranch->SetIntPref(kCookiesLifetimePolicy, ACCEPT_SESSION);
      94             :       }
      95           0 :       prefBranch->SetBoolPref(kCookiesPrefsMigrated, true);
      96             :     }
      97             :   }
      98             : 
      99           1 :   return true;
     100             : }
     101             : 
     102             : void
     103           1 : nsCookiePermission::PrefChanged(nsIPrefBranch *aPrefBranch,
     104             :                                 const char    *aPref)
     105             : {
     106             :   int32_t val;
     107             : 
     108             : #define PREF_CHANGED(_P) (!aPref || !strcmp(aPref, _P))
     109             : 
     110           2 :   if (PREF_CHANGED(kCookiesLifetimePolicy) &&
     111           1 :       NS_SUCCEEDED(aPrefBranch->GetIntPref(kCookiesLifetimePolicy, &val))) {
     112           1 :     if (val != static_cast<int32_t>(ACCEPT_SESSION) && val != static_cast<int32_t>(ACCEPT_FOR_N_DAYS)) {
     113           1 :       val = ACCEPT_NORMALLY;
     114             :     }
     115           1 :     mCookiesLifetimePolicy = val;
     116             :   }
     117             : 
     118           2 :   if (PREF_CHANGED(kCookiesLifetimeDays) &&
     119           1 :       NS_SUCCEEDED(aPrefBranch->GetIntPref(kCookiesLifetimeDays, &val)))
     120             :     // save cookie lifetime in seconds instead of days
     121           1 :     mCookiesLifetimeSec = (int64_t)val * 24 * 60 * 60;
     122           1 : }
     123             : 
     124             : NS_IMETHODIMP
     125           0 : nsCookiePermission::SetAccess(nsIURI         *aURI,
     126             :                               nsCookieAccess  aAccess)
     127             : {
     128             :   // Lazily initialize ourselves
     129           0 :   if (!EnsureInitialized())
     130           0 :     return NS_ERROR_UNEXPECTED;
     131             : 
     132             :   //
     133             :   // NOTE: nsCookieAccess values conveniently match up with
     134             :   //       the permission codes used by nsIPermissionManager.
     135             :   //       this is nice because it avoids conversion code.
     136             :   //
     137           0 :   return mPermMgr->Add(aURI, kPermissionType, aAccess,
     138           0 :                        nsIPermissionManager::EXPIRE_NEVER, 0);
     139             : }
     140             : 
     141             : NS_IMETHODIMP
     142           6 : nsCookiePermission::CanAccess(nsIURI         *aURI,
     143             :                               nsIChannel     *aChannel,
     144             :                               nsCookieAccess *aResult)
     145             : {
     146             :   // Check this protocol doesn't allow cookies
     147             :   bool hasFlags;
     148             :   nsresult rv =
     149             :     NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FORBIDS_COOKIE_ACCESS,
     150           6 :                         &hasFlags);
     151           6 :   if (NS_FAILED(rv) || hasFlags) {
     152           0 :     *aResult = ACCESS_DENY;
     153           0 :     return NS_OK;
     154             :   }
     155             : 
     156             :   // Lazily initialize ourselves
     157           6 :   if (!EnsureInitialized())
     158           0 :     return NS_ERROR_UNEXPECTED;
     159             : 
     160             :   // finally, check with permission manager...
     161           6 :   rv = mPermMgr->TestPermission(aURI, kPermissionType, (uint32_t *) aResult);
     162           6 :   if (NS_SUCCEEDED(rv)) {
     163           6 :     if (*aResult == nsICookiePermission::ACCESS_SESSION) {
     164           0 :       *aResult = nsICookiePermission::ACCESS_ALLOW;
     165             :     }
     166             :   }
     167             : 
     168           6 :   return rv;
     169             : }
     170             : 
     171             : NS_IMETHODIMP
     172           0 : nsCookiePermission::CanSetCookie(nsIURI     *aURI,
     173             :                                  nsIChannel *aChannel,
     174             :                                  nsICookie2 *aCookie,
     175             :                                  bool       *aIsSession,
     176             :                                  int64_t    *aExpiry,
     177             :                                  bool       *aResult)
     178             : {
     179           0 :   NS_ASSERTION(aURI, "null uri");
     180             : 
     181           0 :   *aResult = kDefaultPolicy;
     182             : 
     183             :   // Lazily initialize ourselves
     184           0 :   if (!EnsureInitialized())
     185           0 :     return NS_ERROR_UNEXPECTED;
     186             : 
     187             :   uint32_t perm;
     188           0 :   mPermMgr->TestPermission(aURI, kPermissionType, &perm);
     189           0 :   bool isThirdParty = false;
     190           0 :   switch (perm) {
     191             :   case nsICookiePermission::ACCESS_SESSION:
     192           0 :     *aIsSession = true;
     193             :     MOZ_FALLTHROUGH;
     194             : 
     195             :   case nsICookiePermission::ACCESS_ALLOW:
     196           0 :     *aResult = true;
     197           0 :     break;
     198             : 
     199             :   case nsICookiePermission::ACCESS_DENY:
     200           0 :     *aResult = false;
     201           0 :     break;
     202             : 
     203             :   case nsICookiePermission::ACCESS_ALLOW_FIRST_PARTY_ONLY:
     204           0 :     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aURI, &isThirdParty);
     205             :     // If it's third party, we can't set the cookie
     206           0 :     if (isThirdParty)
     207           0 :       *aResult = false;
     208           0 :     break;
     209             : 
     210             :   case nsICookiePermission::ACCESS_LIMIT_THIRD_PARTY:
     211           0 :     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aURI, &isThirdParty);
     212             :     // If it's third party, check whether cookies are already set
     213           0 :     if (isThirdParty) {
     214             :       nsresult rv;
     215           0 :       nsCOMPtr<nsICookieManager2> cookieManager = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv);
     216           0 :       if (NS_FAILED(rv)) {
     217           0 :         *aResult = false;
     218           0 :         break;
     219             :       }
     220           0 :       uint32_t priorCookieCount = 0;
     221           0 :       nsAutoCString hostFromURI;
     222           0 :       aURI->GetHost(hostFromURI);
     223           0 :       cookieManager->CountCookiesFromHost(hostFromURI, &priorCookieCount);
     224           0 :       *aResult = priorCookieCount != 0;
     225             :     }
     226           0 :     break;
     227             : 
     228             :   default:
     229             :     // the permission manager has nothing to say about this cookie -
     230             :     // so, we apply the default prefs to it.
     231           0 :     NS_ASSERTION(perm == nsIPermissionManager::UNKNOWN_ACTION, "unknown permission");
     232             : 
     233             :     // now we need to figure out what type of accept policy we're dealing with
     234             :     // if we accept cookies normally, just bail and return
     235           0 :     if (mCookiesLifetimePolicy == ACCEPT_NORMALLY) {
     236           0 :       *aResult = true;
     237           0 :       return NS_OK;
     238             :     }
     239             : 
     240             :     // declare this here since it'll be used in all of the remaining cases
     241           0 :     int64_t currentTime = PR_Now() / PR_USEC_PER_SEC;
     242           0 :     int64_t delta = *aExpiry - currentTime;
     243             : 
     244             :     // We are accepting the cookie, but,
     245             :     // if it's not a session cookie, we may have to limit its lifetime.
     246           0 :     if (!*aIsSession && delta > 0) {
     247           0 :       if (mCookiesLifetimePolicy == ACCEPT_SESSION) {
     248             :         // limit lifetime to session
     249           0 :         *aIsSession = true;
     250           0 :       } else if (delta > mCookiesLifetimeSec) {
     251             :         // limit lifetime to specified time
     252           0 :         *aExpiry = currentTime + mCookiesLifetimeSec;
     253             :       }
     254             :     }
     255             :   }
     256             : 
     257           0 :   return NS_OK;
     258             : }
     259             : 
     260             : NS_IMETHODIMP
     261           0 : nsCookiePermission::Observe(nsISupports     *aSubject,
     262             :                             const char      *aTopic,
     263             :                             const char16_t *aData)
     264             : {
     265           0 :   nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject);
     266           0 :   NS_ASSERTION(!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic),
     267             :                "unexpected topic - we only deal with pref changes!");
     268             : 
     269           0 :   if (prefBranch)
     270           0 :     PrefChanged(prefBranch, NS_LossyConvertUTF16toASCII(aData).get());
     271           0 :   return NS_OK;
     272             : }

Generated by: LCOV version 1.13