зеркало из https://github.com/mozilla/gecko-dev.git
Bug 595305 - Factor cookie third-party URI code into separate API. r=bent, a=betaN+
This commit is contained in:
Родитель
49745c22d6
Коммит
f90d6cec5d
|
@ -328,4 +328,8 @@
|
|||
#define NS_PLUGINDOCUMENT_CID \
|
||||
{ 0xf96f5ec9, 0x755b, 0x447e, { 0xb1, 0xf3, 0x71, 0x7d, 0x1a, 0x84, 0xbb, 0x41 } }
|
||||
|
||||
// {08c6cc8b-cfb0-421d-b1f7-683ff2989681}
|
||||
#define THIRDPARTYUTIL_CID \
|
||||
{0x08c6cc8b, 0xcfb0, 0x421d, {0xb1, 0xf7, 0x68, 0x3f, 0xf2, 0x98, 0x96, 0x81}}
|
||||
|
||||
#endif /* nsContentCID_h__ */
|
||||
|
|
|
@ -148,6 +148,7 @@ CPPSRCS = \
|
|||
nsFileDataProtocolHandler.cpp \
|
||||
nsFrameMessageManager.cpp \
|
||||
nsInProcessTabChildGlobal.cpp \
|
||||
ThirdPartyUtil.cpp \
|
||||
$(NULL)
|
||||
|
||||
GQI_SRCS = contentbase.gqi
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is third party utility code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Witte (dwitte@mozilla.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ThirdPartyUtil.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ThirdPartyUtil, mozIThirdPartyUtil)
|
||||
|
||||
nsresult
|
||||
ThirdPartyUtil::Init()
|
||||
{
|
||||
NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsresult rv;
|
||||
mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
|
||||
// "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing
|
||||
// dot may be present (and will be stripped). If aHostURI is an IP address,
|
||||
// an alias such as 'localhost', an eTLD such as 'co.uk', or the empty string,
|
||||
// aBaseDomain will be the exact host. The result of this function should only
|
||||
// be used in exact string comparisons, since substring comparisons will not
|
||||
// be valid for the special cases elided above.
|
||||
nsresult
|
||||
ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
|
||||
nsCString& aBaseDomain)
|
||||
{
|
||||
// Get the base domain. this will fail if the host contains a leading dot,
|
||||
// more than one trailing dot, or is otherwise malformed.
|
||||
nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain);
|
||||
if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
// aHostURI is either an IP address, an alias such as 'localhost', an eTLD
|
||||
// such as 'co.uk', or the empty string. Uses the normalized host in such
|
||||
// cases.
|
||||
rv = aHostURI->GetAsciiHost(aBaseDomain);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// aHostURI (and thus aBaseDomain) may contain a trailing dot; if so, trim it.
|
||||
if (!aBaseDomain.IsEmpty() && aBaseDomain.Last() == '.')
|
||||
aBaseDomain.Truncate(aBaseDomain.Length() - 1);
|
||||
|
||||
// Reject any URIs without a host that aren't file:// URIs. This makes it the
|
||||
// only way we can get a base domain consisting of the empty string, which
|
||||
// means we can safely perform foreign tests on such URIs where "not foreign"
|
||||
// means "the involved URIs are all file://".
|
||||
if (aBaseDomain.IsEmpty()) {
|
||||
PRBool isFileURI = PR_FALSE;
|
||||
aHostURI->SchemeIs("file", &isFileURI);
|
||||
NS_ENSURE_TRUE(isFileURI, NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Determine if aFirstDomain is a different base domain to aSecondURI; or, if
|
||||
// the concept of base domain does not apply, determine if the two hosts are not
|
||||
// string-identical.
|
||||
nsresult
|
||||
ThirdPartyUtil::IsThirdPartyInternal(const nsCString& aFirstDomain,
|
||||
nsIURI* aSecondURI,
|
||||
PRBool* aResult)
|
||||
{
|
||||
NS_ASSERTION(aSecondURI, "null URI!");
|
||||
|
||||
// Get the base domain for aSecondURI.
|
||||
nsCString secondDomain;
|
||||
nsresult rv = GetBaseDomain(aSecondURI, secondDomain);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Check strict equality.
|
||||
*aResult = aFirstDomain != secondDomain;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the URI associated with a window.
|
||||
already_AddRefed<nsIURI>
|
||||
ThirdPartyUtil::GetURIFromWindow(nsIDOMWindow* aWin)
|
||||
{
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(aWin);
|
||||
NS_ENSURE_TRUE(scriptObjPrin, NULL);
|
||||
|
||||
nsIPrincipal* prin = scriptObjPrin->GetPrincipal();
|
||||
NS_ENSURE_TRUE(prin, NULL);
|
||||
|
||||
nsCOMPtr<nsIURI> result;
|
||||
prin->GetURI(getter_AddRefs(result));
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
// Determine if aFirstURI is third party with respect to aSecondURI. See docs
|
||||
// for mozIThirdPartyUtil.
|
||||
NS_IMETHODIMP
|
||||
ThirdPartyUtil::IsThirdPartyURI(nsIURI* aFirstURI,
|
||||
nsIURI* aSecondURI,
|
||||
PRBool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aFirstURI);
|
||||
NS_ENSURE_ARG(aSecondURI);
|
||||
NS_ASSERTION(aResult, "null outparam pointer");
|
||||
|
||||
nsCString firstHost;
|
||||
nsresult rv = GetBaseDomain(aFirstURI, firstHost);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return IsThirdPartyInternal(firstHost, aSecondURI, aResult);
|
||||
}
|
||||
|
||||
// Determine if any URI of the window hierarchy of aWindow is foreign with
|
||||
// respect to aSecondURI. See docs for mozIThirdPartyUtil.
|
||||
NS_IMETHODIMP
|
||||
ThirdPartyUtil::IsThirdPartyWindow(nsIDOMWindow* aWindow,
|
||||
nsIURI* aURI,
|
||||
PRBool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aWindow);
|
||||
NS_ASSERTION(aResult, "null outparam pointer");
|
||||
|
||||
PRBool result;
|
||||
|
||||
// Get the URI of the window, and its base domain.
|
||||
nsCOMPtr<nsIURI> currentURI = GetURIFromWindow(aWindow);
|
||||
NS_ENSURE_TRUE(currentURI, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsCString bottomDomain;
|
||||
nsresult rv = GetBaseDomain(currentURI, bottomDomain);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (aURI) {
|
||||
// Determine whether aURI is foreign with respect to currentURI.
|
||||
rv = IsThirdPartyInternal(bottomDomain, aURI, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (result) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> current = aWindow, parent;
|
||||
nsCOMPtr<nsIURI> parentURI;
|
||||
do {
|
||||
rv = current->GetParent(getter_AddRefs(parent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (SameCOMIdentity(parent, current)) {
|
||||
// We're at the topmost content window. We already know the answer.
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
parentURI = GetURIFromWindow(parent);
|
||||
NS_ENSURE_TRUE(parentURI, NS_ERROR_INVALID_ARG);
|
||||
|
||||
rv = IsThirdPartyInternal(bottomDomain, parentURI, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (result) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
current = parent;
|
||||
currentURI = parentURI;
|
||||
} while (1);
|
||||
|
||||
NS_NOTREACHED("should've returned");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Determine if the URI associated with aChannel or any URI of the window
|
||||
// hierarchy associated with the channel is foreign with respect to aSecondURI.
|
||||
// See docs for mozIThirdPartyUtil.
|
||||
NS_IMETHODIMP
|
||||
ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
|
||||
nsIURI* aURI,
|
||||
PRBool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aChannel);
|
||||
NS_ASSERTION(aResult, "null outparam pointer");
|
||||
|
||||
nsresult rv;
|
||||
PRBool doForce = false;
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
|
||||
do_QueryInterface(aChannel);
|
||||
if (httpChannelInternal) {
|
||||
rv = httpChannelInternal->GetForceAllowThirdPartyCookie(&doForce);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If aURI was not supplied, and we're forcing, then we're by definition
|
||||
// not foreign. If aURI was supplied, we still want to check whether it's
|
||||
// foreign with respect to the channel URI. (The forcing only applies to
|
||||
// whatever window hierarchy exists above the channel.)
|
||||
if (doForce && !aURI) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtain the URI from the channel, and its base domain.
|
||||
nsCOMPtr<nsIURI> channelURI;
|
||||
aChannel->GetURI(getter_AddRefs(channelURI));
|
||||
NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsCString channelDomain;
|
||||
rv = GetBaseDomain(channelURI, channelDomain);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (aURI) {
|
||||
// Determine whether aURI is foreign with respect to channelURI.
|
||||
PRBool result;
|
||||
rv = IsThirdPartyInternal(channelDomain, aURI, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// If it's foreign, or we're forcing, we're done.
|
||||
if (result || doForce) {
|
||||
*aResult = result;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the associated window and its parent window.
|
||||
nsCOMPtr<nsILoadContext> ctx;
|
||||
NS_QueryNotificationCallbacks(aChannel, ctx);
|
||||
if (!ctx) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// If there is no window, the consumer kicking off the load didn't provide one
|
||||
// to the channel. This is limited to loads of certain types of resources. If
|
||||
// those loads require cookies, the forceAllowThirdPartyCookie property should
|
||||
// be set on the channel.
|
||||
nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
|
||||
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
|
||||
if (!ourWin) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
ourWin->GetParent(getter_AddRefs(parentWin));
|
||||
NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (SameCOMIdentity(ourWin, parentWin)) {
|
||||
// Check whether this is the document channel for this window (representing
|
||||
// a load of a new page). This covers the case of a freshly kicked-off load
|
||||
// (e.g. the user typing something in the location bar, or clicking on a
|
||||
// bookmark), where the window's URI hasn't yet been set, and will be bogus.
|
||||
// This is a bit of a nasty hack, but we will hopefully flag these channels
|
||||
// better later.
|
||||
nsLoadFlags flags;
|
||||
rv = aChannel->GetLoadFlags(&flags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
|
||||
// We only need to compare aURI to the channel URI -- the window's will be
|
||||
// bogus. We already know the answer.
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the window hierarchy. This covers most cases for an ordinary page
|
||||
// load from the location bar.
|
||||
return IsThirdPartyWindow(ourWin, channelURI, aResult);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is third party utility code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Witte (dwitte@mozilla.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef ThirdPartyUtil_h__
|
||||
#define ThirdPartyUtil_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIChannel;
|
||||
class nsIDOMWindow;
|
||||
|
||||
class ThirdPartyUtil : public mozIThirdPartyUtil
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZITHIRDPARTYUTIL
|
||||
|
||||
nsresult Init();
|
||||
|
||||
private:
|
||||
nsresult GetBaseDomain(nsIURI* aHostURI, nsCString& aBaseDomain);
|
||||
nsresult IsThirdPartyInternal(const nsCString& aFirstDomain,
|
||||
nsIURI* aSecondURI, PRBool* aResult);
|
||||
static already_AddRefed<nsIURI> GetURIFromWindow(nsIDOMWindow* aWin);
|
||||
|
||||
nsCOMPtr<nsIEffectiveTLDService> mTLDService;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -97,6 +97,7 @@
|
|||
#include "nsXULPopupManager.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIContentUtils.h"
|
||||
#include "ThirdPartyUtil.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
#include "nsIEventListenerService.h"
|
||||
|
@ -331,6 +332,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(IndexedDatabaseManager,
|
|||
defined(android)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAccelerometerSystem)
|
||||
#endif
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ThirdPartyUtil, Init)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -883,6 +885,7 @@ NS_DEFINE_NAMED_CID(NS_PRINCIPAL_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_SYSTEMPRINCIPAL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NULLPRINCIPAL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SECURITYNAMESET_CID);
|
||||
NS_DEFINE_NAMED_CID(THIRDPARTYUTIL_CID);
|
||||
|
||||
#if defined(XP_UNIX) || \
|
||||
defined(_WINDOWS) || \
|
||||
|
@ -1039,6 +1042,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
|||
defined(android)
|
||||
{ &kNS_ACCELEROMETER_CID, false, NULL, nsAccelerometerSystemConstructor },
|
||||
#endif
|
||||
{ &kTHIRDPARTYUTIL_CID, false, NULL, ThirdPartyUtilConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -1184,6 +1188,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
|||
defined(android)
|
||||
{ NS_ACCELEROMETER_CONTRACTID, &kNS_ACCELEROMETER_CID },
|
||||
#endif
|
||||
{ THIRDPARTYUTIL_CONTRACTID, &kTHIRDPARTYUTIL_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ XPIDLSRCS = \
|
|||
nsIURIWithPrincipal.idl \
|
||||
nsIURIClassifier.idl \
|
||||
nsIRedirectResultListener.idl \
|
||||
mozIThirdPartyUtil.idl \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_TOOLKIT_SEARCH
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is third party utility code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Witte (dwitte@mozilla.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIDOMWindow;
|
||||
interface nsIChannel;
|
||||
|
||||
/**
|
||||
* Utility functions for determining whether a given URI, channel, or window
|
||||
* hierarchy is third party with respect to a known URI.
|
||||
*/
|
||||
[scriptable, uuid(55385caa-1b94-4376-a34c-b47c51ef0837)]
|
||||
interface mozIThirdPartyUtil : nsISupports
|
||||
{
|
||||
/**
|
||||
* isThirdPartyURI
|
||||
*
|
||||
* Determine whether two URIs are third party with respect to each other.
|
||||
* This is determined by computing the base domain for both URIs. If they can
|
||||
* be determined, and the base domains match, the request is defined as first
|
||||
* party. If it cannot be determined because one or both URIs do not have a
|
||||
* base domain (for instance, in the case of IP addresses, host aliases such
|
||||
* as 'localhost', or a file:// URI), an exact string comparison on host is
|
||||
* performed.
|
||||
*
|
||||
* For example, the URI "http://mail.google.com/" is not third party with
|
||||
* respect to "http://images.google.com/", but "http://mail.yahoo.com/" and
|
||||
* "http://192.168.1.1/" are.
|
||||
*
|
||||
* @return true if aFirstURI is third party with respect to aSecondURI.
|
||||
*
|
||||
* @throws if either URI is null, has a malformed host, or has an empty host
|
||||
* and is not a file:// URI.
|
||||
*/
|
||||
boolean isThirdPartyURI(in nsIURI aFirstURI, in nsIURI aSecondURI);
|
||||
|
||||
/**
|
||||
* isThirdPartyWindow
|
||||
*
|
||||
* Determine whether the given window hierarchy is third party. This is done
|
||||
* as follows:
|
||||
*
|
||||
* 1) Obtain the URI of the principal associated with 'aWindow'. Call this the
|
||||
* 'bottom URI'.
|
||||
* 2) If 'aURI' is provided, determine if it is third party with respect to
|
||||
* the bottom URI. If so, return.
|
||||
* 3) Find the same-type parent window, if there is one, and its URI.
|
||||
* Determine whether it is third party with respect to the bottom URI. If
|
||||
* so, return.
|
||||
*
|
||||
* Therefore, each level in the window hierarchy is tested. (This means that
|
||||
* nested iframes with different base domains, even though the bottommost and
|
||||
* topmost URIs might be equal, will be considered third party.)
|
||||
*
|
||||
* @param aWindow
|
||||
* The bottommost window in the hierarchy.
|
||||
* @param aURI
|
||||
* A URI to test against. If null, the URI of the principal
|
||||
* associated with 'aWindow' will be used.
|
||||
*
|
||||
* For example, if 'aURI' is "http://mail.google.com/", 'aWindow' has a URI
|
||||
* of "http://google.com/", and its parent is the topmost content window with
|
||||
* a URI of "http://mozilla.com", the result will be true.
|
||||
*
|
||||
* @return true if 'aURI' is third party with respect to any of the URIs
|
||||
* associated with aWindow and its same-type parents.
|
||||
*
|
||||
* @throws if aWindow is null; the same-type parent of any window in the
|
||||
* hierarchy cannot be determined; or the URI associated with any
|
||||
* window in the hierarchy is null, has a malformed host, or has an
|
||||
* empty host and is not a file:// URI.
|
||||
*
|
||||
* @see isThirdPartyURI
|
||||
*/
|
||||
boolean isThirdPartyWindow(in nsIDOMWindow aWindow, [optional] in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* isThirdPartyChannel
|
||||
*
|
||||
* Determine whether the given channel and its content window hierarchy is
|
||||
* third party. This is done as follows:
|
||||
*
|
||||
* 1) If 'aChannel' is an nsIHttpChannel and has the
|
||||
* 'forceAllowThirdPartyCookie' property set, then:
|
||||
* a) If 'aURI' is null, return false.
|
||||
* b) Otherwise, find the URI of the channel, determine whether it is
|
||||
* foreign with respect to 'aURI', and return.
|
||||
* 2) Find the URI of the channel and determine whether it is third party with
|
||||
* respect to the URI of the channel. If so, return.
|
||||
* 3) Obtain the bottommost nsIDOMWindow, and its same-type parent if it
|
||||
* exists, from the channel's notification callbacks. Then:
|
||||
* a) If the parent is the same as the bottommost window, and the channel
|
||||
* has the LOAD_DOCUMENT_URI flag set, return false. This represents the
|
||||
* case where a toplevel load is occurring and the window's URI has not
|
||||
* yet been updated. (We have already checked that 'aURI' is not foreign
|
||||
* with respect to the channel URI.)
|
||||
* b) Otherwise, return the result of isThirdPartyWindow with arguments
|
||||
* of the channel's bottommost window and the channel URI, respectively.
|
||||
*
|
||||
* Therefore, both the channel's URI and each level in the window hierarchy
|
||||
* associated with the channel is tested.
|
||||
*
|
||||
* @param aChannel
|
||||
* The channel associated with the load.
|
||||
* @param aURI
|
||||
* A URI to test against. If null, the URI of the channel will be used.
|
||||
*
|
||||
* For example, if 'aURI' is "http://mail.google.com/", 'aChannel' has a URI
|
||||
* of "http://google.com/", and its parent is the topmost content window with
|
||||
* a URI of "http://mozilla.com", the result will be true.
|
||||
*
|
||||
* @return true if aURI is third party with respect to the channel URI or any
|
||||
* of the URIs associated with the same-type window hierarchy of the
|
||||
* channel.
|
||||
*
|
||||
* @throws if 'aChannel' is null; the channel has no notification callbacks or
|
||||
* an associated window; or isThirdPartyWindow throws.
|
||||
*
|
||||
* @see isThirdPartyWindow
|
||||
*/
|
||||
boolean isThirdPartyChannel(in nsIChannel aChannel, [optional] in nsIURI aURI);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
/**
|
||||
* The mozIThirdPartyUtil implementation is an XPCOM service registered
|
||||
* under the ContractID:
|
||||
*/
|
||||
#define THIRDPARTYUTIL_CONTRACTID "@mozilla.org/thirdpartyutil;1"
|
||||
%}
|
||||
|
|
@ -39,10 +39,22 @@
|
|||
#include "mozilla/net/CookieServiceChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
// Behavior pref constants
|
||||
static const PRInt32 BEHAVIOR_ACCEPT = 0;
|
||||
static const PRInt32 BEHAVIOR_REJECTFOREIGN = 1;
|
||||
static const PRInt32 BEHAVIOR_REJECT = 2;
|
||||
|
||||
// Pref string constants
|
||||
static const char kPrefCookieBehavior[] = "network.cookie.cookieBehavior";
|
||||
static const char kPrefThirdPartySession[] =
|
||||
"network.cookie.thirdparty.sessionOnly";
|
||||
|
||||
static CookieServiceChild *gCookieService;
|
||||
|
||||
CookieServiceChild*
|
||||
|
@ -55,9 +67,11 @@ CookieServiceChild::GetSingleton()
|
|||
return gCookieService;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(CookieServiceChild, nsICookieService)
|
||||
NS_IMPL_ISUPPORTS2(CookieServiceChild, nsICookieService, nsIObserver)
|
||||
|
||||
CookieServiceChild::CookieServiceChild()
|
||||
: mCookieBehavior(BEHAVIOR_ACCEPT)
|
||||
, mThirdPartySession(false)
|
||||
{
|
||||
NS_ASSERTION(IsNeckoChild(), "not a child process");
|
||||
|
||||
|
@ -68,9 +82,15 @@ CookieServiceChild::CookieServiceChild()
|
|||
NeckoChild::InitNeckoChild();
|
||||
gNeckoChild->SendPCookieServiceConstructor(this);
|
||||
|
||||
mPermissionService = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
|
||||
if (!mPermissionService)
|
||||
NS_WARNING("couldn't get nsICookiePermission in child");
|
||||
// Init our prefs and observer.
|
||||
nsCOMPtr<nsIPrefBranch2> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
NS_WARN_IF_FALSE(prefBranch, "no prefservice");
|
||||
if (prefBranch) {
|
||||
prefBranch->AddObserver(kPrefCookieBehavior, this, PR_TRUE);
|
||||
prefBranch->AddObserver(kPrefThirdPartySession, this, PR_TRUE);
|
||||
PrefChanged(prefBranch);
|
||||
}
|
||||
}
|
||||
|
||||
CookieServiceChild::~CookieServiceChild()
|
||||
|
@ -78,6 +98,30 @@ CookieServiceChild::~CookieServiceChild()
|
|||
gCookieService = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
CookieServiceChild::PrefChanged(nsIPrefBranch *aPrefBranch)
|
||||
{
|
||||
PRInt32 val;
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookieBehavior, &val)))
|
||||
mCookieBehavior =
|
||||
val >= BEHAVIOR_ACCEPT && val <= BEHAVIOR_REJECT ? val : BEHAVIOR_ACCEPT;
|
||||
|
||||
PRBool boolval;
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval)))
|
||||
mThirdPartySession = !!boolval;
|
||||
|
||||
if (!mThirdPartyUtil && RequireThirdPartyCheck()) {
|
||||
mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
NS_ASSERTION(mThirdPartyUtil, "require ThirdPartyUtil service");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CookieServiceChild::RequireThirdPartyCheck()
|
||||
{
|
||||
return mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mThirdPartySession;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CookieServiceChild::GetCookieStringInternal(nsIURI *aHostURI,
|
||||
nsIChannel *aChannel,
|
||||
|
@ -89,18 +133,14 @@ CookieServiceChild::GetCookieStringInternal(nsIURI *aHostURI,
|
|||
|
||||
*aCookieString = NULL;
|
||||
|
||||
// Determine the originating URI. Failure is acceptable.
|
||||
nsCOMPtr<nsIURI> originatingURI;
|
||||
if (!mPermissionService) {
|
||||
NS_WARNING("nsICookiePermission unavailable! Cookie may be rejected");
|
||||
mPermissionService->GetOriginatingURI(aChannel,
|
||||
getter_AddRefs(originatingURI));
|
||||
}
|
||||
// Determine whether the request is foreign. Failure is acceptable.
|
||||
PRBool isForeign = true;
|
||||
if (RequireThirdPartyCheck())
|
||||
mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
|
||||
|
||||
// Synchronously call the parent.
|
||||
nsCAutoString result;
|
||||
SendGetCookieString(IPC::URI(aHostURI), IPC::URI(originatingURI),
|
||||
aFromHttp, &result);
|
||||
SendGetCookieString(IPC::URI(aHostURI), !!isForeign, aFromHttp, &result);
|
||||
if (!result.IsEmpty())
|
||||
*aCookieString = ToNewCString(result);
|
||||
|
||||
|
@ -117,13 +157,10 @@ CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
|
|||
NS_ENSURE_ARG(aHostURI);
|
||||
NS_ENSURE_ARG_POINTER(aCookieString);
|
||||
|
||||
// Determine the originating URI. Failure is acceptable.
|
||||
nsCOMPtr<nsIURI> originatingURI;
|
||||
if (!mPermissionService) {
|
||||
NS_WARNING("nsICookiePermission unavailable! Cookie may be rejected");
|
||||
mPermissionService->GetOriginatingURI(aChannel,
|
||||
getter_AddRefs(originatingURI));
|
||||
}
|
||||
// Determine whether the request is foreign. Failure is acceptable.
|
||||
PRBool isForeign = true;
|
||||
if (RequireThirdPartyCheck())
|
||||
mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
|
||||
|
||||
nsDependentCString cookieString(aCookieString);
|
||||
nsDependentCString serverTime;
|
||||
|
@ -131,11 +168,25 @@ CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
|
|||
serverTime.Rebind(aServerTime);
|
||||
|
||||
// Synchronously call the parent.
|
||||
SendSetCookieString(IPC::URI(aHostURI), IPC::URI(originatingURI),
|
||||
SendSetCookieString(IPC::URI(aHostURI), !!isForeign,
|
||||
cookieString, serverTime, aFromHttp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CookieServiceChild::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
NS_ASSERTION(strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0,
|
||||
"not a pref change topic!");
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject);
|
||||
if (prefBranch)
|
||||
PrefChanged(prefBranch);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CookieServiceChild::GetCookieString(nsIURI *aHostURI,
|
||||
nsIChannel *aChannel,
|
||||
|
|
|
@ -41,17 +41,21 @@
|
|||
|
||||
#include "mozilla/net/PCookieServiceChild.h"
|
||||
#include "nsICookieService.h"
|
||||
#include "nsICookiePermission.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class CookieServiceChild : public PCookieServiceChild
|
||||
, public nsICookieService
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICOOKIESERVICE
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
CookieServiceChild();
|
||||
virtual ~CookieServiceChild();
|
||||
|
@ -77,7 +81,13 @@ protected:
|
|||
const char *aServerTime,
|
||||
bool aFromHttp);
|
||||
|
||||
nsCOMPtr<nsICookiePermission> mPermissionService;
|
||||
void PrefChanged(nsIPrefBranch *aPrefBranch);
|
||||
|
||||
bool RequireThirdPartyCheck();
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> mThirdPartyUtil;
|
||||
PRUint8 mCookieBehavior;
|
||||
bool mThirdPartySession;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -61,28 +61,27 @@ CookieServiceParent::~CookieServiceParent()
|
|||
|
||||
bool
|
||||
CookieServiceParent::RecvGetCookieString(const IPC::URI& aHost,
|
||||
const IPC::URI& aOriginating,
|
||||
const bool& aIsForeign,
|
||||
const bool& aFromHttp,
|
||||
nsCString* aResult)
|
||||
{
|
||||
if (!mCookieService)
|
||||
return true;
|
||||
|
||||
// Deserialize URIs. Having a host URI is mandatory and should always be
|
||||
// Deserialize URI. Having a host URI is mandatory and should always be
|
||||
// provided by the child; thus we consider failure fatal.
|
||||
nsCOMPtr<nsIURI> hostURI(aHost);
|
||||
nsCOMPtr<nsIURI> originatingURI(aOriginating);
|
||||
if (!hostURI)
|
||||
return false;
|
||||
|
||||
mCookieService->GetCookieStringInternal(hostURI, originatingURI,
|
||||
mCookieService->GetCookieStringInternal(hostURI, aIsForeign,
|
||||
aFromHttp, *aResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CookieServiceParent::RecvSetCookieString(const IPC::URI& aHost,
|
||||
const IPC::URI& aOriginating,
|
||||
const bool& aIsForeign,
|
||||
const nsCString& aCookieString,
|
||||
const nsCString& aServerTime,
|
||||
const bool& aFromHttp)
|
||||
|
@ -90,14 +89,13 @@ CookieServiceParent::RecvSetCookieString(const IPC::URI& aHost,
|
|||
if (!mCookieService)
|
||||
return true;
|
||||
|
||||
// Deserialize URIs. Having a host URI is mandatory and should always be
|
||||
// Deserialize URI. Having a host URI is mandatory and should always be
|
||||
// provided by the child; thus we consider failure fatal.
|
||||
nsCOMPtr<nsIURI> hostURI(aHost);
|
||||
nsCOMPtr<nsIURI> originatingURI(aOriginating);
|
||||
if (!hostURI)
|
||||
return false;
|
||||
|
||||
mCookieService->SetCookieStringInternal(hostURI, originatingURI,
|
||||
mCookieService->SetCookieStringInternal(hostURI, aIsForeign,
|
||||
aCookieString, aServerTime,
|
||||
aFromHttp);
|
||||
return true;
|
||||
|
|
|
@ -55,12 +55,12 @@ public:
|
|||
|
||||
protected:
|
||||
virtual bool RecvGetCookieString(const IPC::URI& aHost,
|
||||
const IPC::URI& aOriginating,
|
||||
const bool& aIsForeign,
|
||||
const bool& aFromHttp,
|
||||
nsCString* aResult);
|
||||
|
||||
virtual bool RecvSetCookieString(const IPC::URI& aHost,
|
||||
const IPC::URI& aOriginating,
|
||||
const bool& aIsForeign,
|
||||
const nsCString& aCookieString,
|
||||
const nsCString& aServerTime,
|
||||
const bool& aFromHttp);
|
||||
|
|
|
@ -73,15 +73,12 @@ parent:
|
|||
*
|
||||
* @param host
|
||||
* Same as the 'aURI' argument to nsICookieService.getCookieString.
|
||||
* @param originating
|
||||
* The originating URI associated with the request. This is used
|
||||
* to determine whether the request is first or third party, for
|
||||
* purposes of allowing access to cookies. This should be obtained
|
||||
* from nsICookiePermission.getOriginatingURI. This parameter may
|
||||
* be null; in this case, the request is assumed to be third party
|
||||
* and may be rejected depending on user preferences. In
|
||||
* nsICookieService.getCookieString, this argument is determined
|
||||
* from the aChannel argument.
|
||||
* @param isForeign
|
||||
* True if the the request is third party, for purposes of allowing
|
||||
* access to cookies. This should be obtained from
|
||||
* mozIThirdPartyUtil.isThirdPartyChannel. Third party requests may be
|
||||
* rejected depending on user preferences; if those checks are
|
||||
* disabled, this parameter is ignored.
|
||||
* @param fromHttp
|
||||
* Whether the result is for an HTTP request header. This should be
|
||||
* true for nsICookieService.getCookieStringFromHttp calls, false
|
||||
|
@ -89,12 +86,12 @@ parent:
|
|||
*
|
||||
* @see nsICookieService.getCookieString
|
||||
* @see nsICookieService.getCookieStringFromHttp
|
||||
* @see nsICookiePermission.getOriginatingURI
|
||||
* @see mozIThirdPartyUtil.isThirdPartyChannel
|
||||
*
|
||||
* @return the resulting cookie string.
|
||||
*/
|
||||
sync GetCookieString(URI host,
|
||||
URI originating,
|
||||
bool isForeign,
|
||||
bool fromHttp)
|
||||
returns (nsCString result);
|
||||
|
||||
|
@ -103,13 +100,12 @@ parent:
|
|||
*
|
||||
* @param host
|
||||
* Same as the 'aURI' argument to nsICookieService.setCookieString.
|
||||
* @param originating
|
||||
* The originating URI associated with the request. This is used
|
||||
* to determine whether the request is first or third party, for
|
||||
* purposes of allowing access to cookies. This should be obtained
|
||||
* from nsICookiePermission.getOriginatingURI. This parameter may
|
||||
* be null; in this case, the request is assumed to be third party
|
||||
* and may be rejected depending on user preferences.
|
||||
* @param isForeign
|
||||
* True if the the request is third party, for purposes of allowing
|
||||
* access to cookies. This should be obtained from
|
||||
* mozIThirdPartyUtil.isThirdPartyChannel. Third party requests may be
|
||||
* rejected depending on user preferences; if those checks are
|
||||
* disabled, this parameter is ignored.
|
||||
* @param cookieString
|
||||
* Same as the 'aCookie' argument to nsICookieService.setCookieString.
|
||||
* @param serverTime
|
||||
|
@ -123,10 +119,10 @@ parent:
|
|||
*
|
||||
* @see nsICookieService.setCookieString
|
||||
* @see nsICookieService.setCookieStringFromHttp
|
||||
* @see nsICookiePermission.getOriginatingURI
|
||||
* @see mozIThirdPartyUtil.isThirdPartyChannel
|
||||
*/
|
||||
SetCookieString(URI host,
|
||||
URI originating,
|
||||
bool isForeign,
|
||||
nsCString cookieString,
|
||||
nsCString serverTime,
|
||||
bool fromHttp);
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "nsILineInputStream.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIIDNService.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
@ -1096,11 +1097,13 @@ nsCookieService::GetCookieStringCommon(nsIURI *aHostURI,
|
|||
NS_ENSURE_ARG(aHostURI);
|
||||
NS_ENSURE_ARG(aCookie);
|
||||
|
||||
nsCOMPtr<nsIURI> originatingURI;
|
||||
GetOriginatingURI(aChannel, getter_AddRefs(originatingURI));
|
||||
// Determine whether the request is foreign. Failure is acceptable.
|
||||
PRBool isForeign = true;
|
||||
if (RequireThirdPartyCheck())
|
||||
mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
|
||||
|
||||
nsCAutoString result;
|
||||
GetCookieStringInternal(aHostURI, originatingURI, aHttpBound, result);
|
||||
GetCookieStringInternal(aHostURI, isForeign, aHttpBound, result);
|
||||
*aCookie = result.IsEmpty() ? nsnull : ToNewCString(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1136,19 +1139,21 @@ nsCookieService::SetCookieStringCommon(nsIURI *aHostURI,
|
|||
NS_ENSURE_ARG(aHostURI);
|
||||
NS_ENSURE_ARG(aCookieHeader);
|
||||
|
||||
nsCOMPtr<nsIURI> originatingURI;
|
||||
GetOriginatingURI(aChannel, getter_AddRefs(originatingURI));
|
||||
// Determine whether the request is foreign. Failure is acceptable.
|
||||
PRBool isForeign = true;
|
||||
if (RequireThirdPartyCheck())
|
||||
mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
|
||||
|
||||
nsDependentCString cookieString(aCookieHeader);
|
||||
nsDependentCString serverTime(aServerTime ? aServerTime : "");
|
||||
SetCookieStringInternal(aHostURI, originatingURI, cookieString,
|
||||
SetCookieStringInternal(aHostURI, isForeign, cookieString,
|
||||
serverTime, aFromHttp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
|
||||
nsIURI *aOriginatingURI,
|
||||
bool aIsForeign,
|
||||
const nsCString &aCookieHeader,
|
||||
const nsCString &aServerTime,
|
||||
PRBool aFromHttp)
|
||||
|
@ -1170,7 +1175,7 @@ nsCookieService::SetCookieStringInternal(nsIURI *aHostURI,
|
|||
}
|
||||
|
||||
// check default prefs
|
||||
CookieStatus cookieStatus = CheckPrefs(aHostURI, aOriginatingURI, baseDomain,
|
||||
CookieStatus cookieStatus = CheckPrefs(aHostURI, aIsForeign, baseDomain,
|
||||
requireHostMatch, aCookieHeader.get());
|
||||
// fire a notification if cookie was rejected (but not if there was an error)
|
||||
switch (cookieStatus) {
|
||||
|
@ -1251,6 +1256,12 @@ nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch)
|
|||
PRBool boolval;
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetBoolPref(kPrefThirdPartySession, &boolval)))
|
||||
mThirdPartySession = boolval;
|
||||
|
||||
// Lazily instantiate the third party service if necessary.
|
||||
if (!mThirdPartyUtil && RequireThirdPartyCheck()) {
|
||||
mThirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
NS_ABORT_IF_FALSE(mThirdPartyUtil, "require ThirdPartyUtil service");
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -1884,7 +1895,7 @@ public:
|
|||
|
||||
void
|
||||
nsCookieService::GetCookieStringInternal(nsIURI *aHostURI,
|
||||
nsIURI *aOriginatingURI,
|
||||
bool aIsForeign,
|
||||
PRBool aHttpBound,
|
||||
nsCString &aCookieString)
|
||||
{
|
||||
|
@ -1911,7 +1922,7 @@ nsCookieService::GetCookieStringInternal(nsIURI *aHostURI,
|
|||
}
|
||||
|
||||
// check default prefs
|
||||
CookieStatus cookieStatus = CheckPrefs(aHostURI, aOriginatingURI, baseDomain,
|
||||
CookieStatus cookieStatus = CheckPrefs(aHostURI, aIsForeign, baseDomain,
|
||||
requireHostMatch, nsnull);
|
||||
// for GetCookie(), we don't fire rejection notifications.
|
||||
switch (cookieStatus) {
|
||||
|
@ -2593,52 +2604,16 @@ static inline PRBool IsSubdomainOf(const nsCString &a, const nsCString &b)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCookieService::IsForeign(const nsCString &aBaseDomain,
|
||||
PRBool aRequireHostMatch,
|
||||
nsIURI *aFirstURI)
|
||||
bool
|
||||
nsCookieService::RequireThirdPartyCheck()
|
||||
{
|
||||
nsCAutoString firstHost;
|
||||
if (NS_FAILED(aFirstURI->GetAsciiHost(firstHost))) {
|
||||
// assume foreign
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// trim any trailing dot
|
||||
if (!firstHost.IsEmpty() && firstHost.Last() == '.')
|
||||
firstHost.Truncate(firstHost.Length() - 1);
|
||||
|
||||
// check whether the host is either an IP address, an alias such as
|
||||
// 'localhost', an eTLD such as 'co.uk', or the empty string. in these
|
||||
// cases, require an exact string match for the domain. note that the base
|
||||
// domain parameter will be equivalent to the host in this case.
|
||||
if (aRequireHostMatch)
|
||||
return !firstHost.Equals(aBaseDomain);
|
||||
|
||||
// ensure the originating domain is also derived from the host's base domain.
|
||||
return !IsSubdomainOf(firstHost, aBaseDomain);
|
||||
}
|
||||
|
||||
void
|
||||
nsCookieService::GetOriginatingURI(nsIChannel *aChannel,
|
||||
nsIURI **aURI)
|
||||
{
|
||||
// Determine the originating URI. We only need to do this if we're
|
||||
// rejecting or altering the lifetime of third-party cookies.
|
||||
if (mCookieBehavior != BEHAVIOR_REJECTFOREIGN && !mThirdPartySession)
|
||||
return;
|
||||
|
||||
if (!mPermissionService) {
|
||||
NS_WARNING("nsICookiePermission unavailable! Cookie may be rejected");
|
||||
return;
|
||||
}
|
||||
|
||||
mPermissionService->GetOriginatingURI(aChannel, aURI);
|
||||
// 'true' iff we need to perform a third party test.
|
||||
return mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mThirdPartySession;
|
||||
}
|
||||
|
||||
CookieStatus
|
||||
nsCookieService::CheckPrefs(nsIURI *aHostURI,
|
||||
nsIURI *aOriginatingURI,
|
||||
bool aIsForeign,
|
||||
const nsCString &aBaseDomain,
|
||||
PRBool aRequireHostMatch,
|
||||
const char *aCookieHeader)
|
||||
|
@ -2679,16 +2654,13 @@ nsCookieService::CheckPrefs(nsIURI *aHostURI,
|
|||
return STATUS_REJECTED;
|
||||
}
|
||||
|
||||
if (mCookieBehavior == BEHAVIOR_REJECTFOREIGN || mThirdPartySession) {
|
||||
if (RequireThirdPartyCheck() && aIsForeign) {
|
||||
// check if cookie is foreign
|
||||
if (!aOriginatingURI ||
|
||||
IsForeign(aBaseDomain, aRequireHostMatch, aOriginatingURI)) {
|
||||
if (mCookieBehavior == BEHAVIOR_ACCEPT && mThirdPartySession)
|
||||
return STATUS_ACCEPT_SESSION;
|
||||
if (mCookieBehavior == BEHAVIOR_ACCEPT && mThirdPartySession)
|
||||
return STATUS_ACCEPT_SESSION;
|
||||
|
||||
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party");
|
||||
return STATUS_REJECTED;
|
||||
}
|
||||
COOKIE_LOGFAILURE(aCookieHeader ? SET_COOKIE : GET_COOKIE, aHostURI, aCookieHeader, "context is third party");
|
||||
return STATUS_REJECTED;
|
||||
}
|
||||
|
||||
// if nothing has complained, accept cookie
|
||||
|
|
|
@ -68,6 +68,7 @@ class nsIChannel;
|
|||
class mozIStorageService;
|
||||
class mozIStorageStatementCallback;
|
||||
class mozIStorageCompletionCallback;
|
||||
class mozIThirdPartyUtil;
|
||||
class ReadCookieDBListener;
|
||||
|
||||
struct nsCookieAttributes;
|
||||
|
@ -229,9 +230,9 @@ class nsCookieService : public nsICookieService
|
|||
nsresult GetBaseDomain(nsIURI *aHostURI, nsCString &aBaseDomain, PRBool &aRequireHostMatch);
|
||||
nsresult GetBaseDomainFromHost(const nsACString &aHost, nsCString &aBaseDomain);
|
||||
nsresult GetCookieStringCommon(nsIURI *aHostURI, nsIChannel *aChannel, bool aHttpBound, char** aCookie);
|
||||
void GetCookieStringInternal(nsIURI *aHostURI, nsIURI *aOriginatingURI, PRBool aHttpBound, nsCString &aCookie);
|
||||
void GetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, PRBool aHttpBound, nsCString &aCookie);
|
||||
nsresult SetCookieStringCommon(nsIURI *aHostURI, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, bool aFromHttp);
|
||||
void SetCookieStringInternal(nsIURI *aHostURI, nsIURI *aOriginatingURI, const nsCString &aCookieHeader, const nsCString &aServerTime, PRBool aFromHttp);
|
||||
void SetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, const nsCString &aCookieHeader, const nsCString &aServerTime, PRBool aFromHttp);
|
||||
PRBool SetCookieInternal(nsIURI *aHostURI, const nsCString& aBaseDomain, PRBool aRequireHostMatch, CookieStatus aStatus, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp);
|
||||
void AddInternal(const nsCString& aBaseDomain, nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
|
||||
void RemoveCookieFromList(const nsListIter &aIter, mozIStorageBindingParamsArray *aParamsArray = NULL);
|
||||
|
@ -239,9 +240,8 @@ class nsCookieService : public nsICookieService
|
|||
void UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed, mozIStorageBindingParamsArray *aParamsArray);
|
||||
static PRBool GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, PRBool &aEqualsFound);
|
||||
static PRBool ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie);
|
||||
PRBool IsForeign(const nsCString &aBaseDomain, PRBool aRequireHostMatch, nsIURI *aFirstURI);
|
||||
void GetOriginatingURI(nsIChannel *aChannel, nsIURI **aURI);
|
||||
CookieStatus CheckPrefs(nsIURI *aHostURI, nsIURI *aOriginatingURI, const nsCString &aBaseDomain, PRBool aRequireHostMatch, const char *aCookieHeader);
|
||||
bool RequireThirdPartyCheck();
|
||||
CookieStatus CheckPrefs(nsIURI *aHostURI, bool aIsForeign, const nsCString &aBaseDomain, PRBool aRequireHostMatch, const char *aCookieHeader);
|
||||
PRBool CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, PRBool aRequireHostMatch);
|
||||
static PRBool CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
|
||||
static PRBool GetExpiry(nsCookieAttributes &aCookie, PRInt64 aServerTime, PRInt64 aCurrentTime);
|
||||
|
@ -256,6 +256,7 @@ class nsCookieService : public nsICookieService
|
|||
// cached members.
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
nsCOMPtr<nsICookiePermission> mPermissionService;
|
||||
nsCOMPtr<mozIThirdPartyUtil> mThirdPartyUtil;
|
||||
nsCOMPtr<nsIEffectiveTLDService> mTLDService;
|
||||
nsCOMPtr<nsIIDNService> mIDNService;
|
||||
nsCOMPtr<mozIStorageService> mStorageService;
|
||||
|
|
|
@ -142,6 +142,8 @@ interface nsICookiePermission : nsISupports
|
|||
* the channel for the load trying to get or set cookies
|
||||
*
|
||||
* @return the originating URI.
|
||||
*
|
||||
* @status DEPRECATED -- use mozIThirdPartyUtil instead.
|
||||
*/
|
||||
nsIURI getOriginatingURI(in nsIChannel aChannel);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче