зеркало из https://github.com/mozilla/pjs.git
bug 265135: put internal referrers on channels to fix xpinstall whitelisting the right way. r=darin,sr=jst
This commit is contained in:
Родитель
120535f45d
Коммит
29050563b3
|
@ -257,7 +257,6 @@ nsDocShell::nsDocShell():
|
|||
mEODForCurrentDocument(PR_FALSE),
|
||||
mURIResultedInDocument(PR_FALSE),
|
||||
mIsBeingDestroyed(PR_FALSE),
|
||||
mUseExternalProtocolHandler(PR_FALSE),
|
||||
mDisallowPopupWindows(PR_FALSE),
|
||||
mValidateOrigin(PR_TRUE), // validate frame origins by default
|
||||
mIsExecutingOnLoadHandler(PR_FALSE),
|
||||
|
@ -3092,13 +3091,6 @@ nsDocShell::Create()
|
|||
|
||||
PRBool tmpbool;
|
||||
|
||||
// i don't want to read this pref in every time we load a url
|
||||
// so read it in once here and be done with it...
|
||||
rv = mPrefs->GetBoolPref("network.protocols.useSystemDefaults",
|
||||
&tmpbool);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mUseExternalProtocolHandler = tmpbool;
|
||||
|
||||
rv = mPrefs->GetBoolPref("browser.block.target_new_window", &tmpbool);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mDisallowPopupWindows = tmpbool;
|
||||
|
@ -5091,40 +5083,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
nsCOMPtr<nsIDocShell> targetDocShell;
|
||||
nsAutoString name(aWindowTarget);
|
||||
|
||||
//
|
||||
// This is a hack for Shrimp :-(
|
||||
//
|
||||
// if the load cmd is a user click....and we are supposed to try using
|
||||
// external default protocol handlers....then try to see if we have one for
|
||||
// this protocol
|
||||
//
|
||||
// See bug #52182
|
||||
//
|
||||
if (mUseExternalProtocolHandler && aLoadType == LOAD_LINK) {
|
||||
// don't do it for javascript urls!
|
||||
// _main is an IE target which should be case-insensitive but isn't
|
||||
// see bug 217886 for details
|
||||
if (!bIsJavascript &&
|
||||
(name.LowerCaseEqualsLiteral("_content") || name.EqualsLiteral("_main") ||
|
||||
name.LowerCaseEqualsLiteral("_blank")))
|
||||
{
|
||||
nsCOMPtr<nsIExternalProtocolService> extProtService;
|
||||
nsCAutoString urlScheme;
|
||||
|
||||
extProtService = do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID);
|
||||
if (extProtService) {
|
||||
PRBool haveHandler = PR_FALSE;
|
||||
aURI->GetScheme(urlScheme);
|
||||
|
||||
extProtService->ExternalProtocolHandlerExists(urlScheme.get(),
|
||||
&haveHandler);
|
||||
if (haveHandler) {
|
||||
return extProtService->LoadUrl(aURI);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This is a hack to prevent top-level windows from ever being
|
||||
// created. It really doesn't belong here, but until there is a
|
||||
|
@ -5526,6 +5484,14 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProperties> props(do_QueryInterface(channel));
|
||||
if (props)
|
||||
{
|
||||
// save true referrer for those who need it (e.g. xpinstall whitelisting)
|
||||
// Currently only http and ftp channels support this.
|
||||
props->Set("docshell.internalReferrer", aReferrerURI);
|
||||
}
|
||||
|
||||
//
|
||||
// If this is a HTTP channel, then set up the HTTP specific information
|
||||
// (ie. POST data, referrer, ...)
|
||||
|
|
|
@ -355,13 +355,6 @@ protected:
|
|||
|
||||
PRPackedBool mIsBeingDestroyed;
|
||||
|
||||
// used to keep track of whether user click links should be handle
|
||||
// by us or immediately kicked out to an external
|
||||
// application. mscott: eventually i'm going to try to fold this
|
||||
// up into the uriloader where it belongs but i haven't figured
|
||||
// out how to do that yet.
|
||||
PRPackedBool mUseExternalProtocolHandler;
|
||||
|
||||
// Disallow popping up new windows with target=
|
||||
PRPackedBool mDisallowPopupWindows;
|
||||
|
||||
|
|
|
@ -116,6 +116,15 @@ NS_INTERFACE_MAP_BEGIN(nsFTPChannel)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICacheListener)
|
||||
if (aIID.Equals(NS_GET_IID(nsIProperties))) {
|
||||
if (!mProperties) {
|
||||
mProperties =
|
||||
do_CreateInstance(NS_PROPERTIES_CONTRACTID, (nsIChannel *) this);
|
||||
NS_ENSURE_STATE(mProperties);
|
||||
}
|
||||
return mProperties->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
else
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
|
|
@ -144,7 +144,8 @@ protected:
|
|||
PRPackedBool mCanceled;
|
||||
|
||||
nsCOMPtr<nsIIOService> mIOService;
|
||||
|
||||
nsCOMPtr<nsISupports> mProperties;
|
||||
|
||||
nsCOMPtr<nsICacheSession> mCacheSession;
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||
nsCOMPtr<nsIProxyInfo> mProxyInfo;
|
||||
|
|
|
@ -1844,6 +1844,26 @@ nsHttpChannel::SetupReplacementChannel(nsIURI *newURI,
|
|||
resumableChannel->ResumeAt(mStartPos, mEntityID);
|
||||
}
|
||||
|
||||
// transfer any properties
|
||||
if (mProperties) {
|
||||
nsCOMPtr<nsIProperties> oldProps = do_QueryInterface(mProperties);
|
||||
nsCOMPtr<nsIProperties> newProps = do_QueryInterface(newChannel);
|
||||
if (newProps) {
|
||||
PRUint32 count;
|
||||
char **keys;
|
||||
if (NS_SUCCEEDED(oldProps->GetKeys(&count, &keys))) {
|
||||
nsCOMPtr<nsISupports> val;
|
||||
for (PRUint32 i=0; i<count; ++i) {
|
||||
oldProps->Get(keys[i],
|
||||
NS_GET_IID(nsISupports),
|
||||
getter_AddRefs(val));
|
||||
newProps->Set(keys[i], val);
|
||||
}
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2770,6 +2790,15 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIResumableChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
|
||||
if (aIID.Equals(NS_GET_IID(nsIProperties))) {
|
||||
if (!mProperties) {
|
||||
mProperties =
|
||||
do_CreateInstance(NS_PROPERTIES_CONTRACTID, (nsIChannel *) this);
|
||||
NS_ENSURE_STATE(mProperties);
|
||||
}
|
||||
return mProperties->QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
else
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
|
|
@ -216,6 +216,8 @@ private:
|
|||
|
||||
nsCString mContentTypeHint;
|
||||
nsCString mContentCharsetHint;
|
||||
|
||||
nsCOMPtr<nsISupports> mProperties;
|
||||
|
||||
// cache specific data
|
||||
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
|
||||
|
|
|
@ -390,6 +390,17 @@ InputTestConsumer::OnStartRequest(nsIRequest *request, nsISupports* context)
|
|||
LOG(("\tChannel Owner: %x\n", owner.get()));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProperties> props = do_QueryInterface(request);
|
||||
if (props) {
|
||||
nsCOMPtr<nsIURI> foo;
|
||||
props->Get("test.foo", NS_GET_IID(nsIURI), getter_AddRefs(foo));
|
||||
if (foo) {
|
||||
nsCAutoString spec;
|
||||
foo->GetSpec(spec);
|
||||
LOG(("\ttest.foo: %s\n", spec.get()));
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannelInt(do_QueryInterface(request));
|
||||
if (httpChannelInt) {
|
||||
PRUint32 majorVer, minorVer;
|
||||
|
@ -612,6 +623,12 @@ nsresult StartLoadingURL(const char* aUrlString)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProperties> props = do_QueryInterface(pChannel);
|
||||
if (props) {
|
||||
if (NS_SUCCEEDED(props->Set("test.foo", pURL)))
|
||||
LOG(("set prop 'test.foo'\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
You may optionally add/set other headers on this
|
||||
request object. This is done by QI for the specific
|
||||
|
|
|
@ -67,7 +67,7 @@ nsProperties::Get(const char* prop, const nsIID & uuid, void* *result)
|
|||
if (!nsProperties_HashBase::Get(prop, getter_AddRefs(value))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return value->QueryInterface(uuid, result);
|
||||
return (value) ? value->QueryInterface(uuid, result) : NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -146,36 +146,23 @@ nsInstallTrigger::HandleContent(const char * aContentType,
|
|||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
// XXX: if only the owner weren't always null this is what I'd want to do
|
||||
|
||||
// Get the owner of the channel to perform permission checks.
|
||||
//
|
||||
// It's OK if owner is null, this means it was a top level
|
||||
// load and we want to allow installs in that case.
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsCOMPtr<nsIURI> ownerURI;
|
||||
|
||||
channel->GetOwner( getter_AddRefs( owner ) );
|
||||
if ( owner )
|
||||
{
|
||||
principal = do_QueryInterface( owner );
|
||||
if ( principal )
|
||||
{
|
||||
principal->GetURI( getter_AddRefs( ownerURI ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Save the referrer if any, for permission checks
|
||||
static const char kReferrerProperty[] = "docshell.internalReferrer";
|
||||
PRBool useReferrer = PR_FALSE;
|
||||
nsCOMPtr<nsIURI> referringURI;
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
|
||||
if ( httpChannel )
|
||||
{
|
||||
httpChannel->GetReferrer(getter_AddRefs(referringURI));
|
||||
}
|
||||
nsCOMPtr<nsIProperties> channelprops(do_QueryInterface(channel));
|
||||
|
||||
if (channelprops &&
|
||||
NS_SUCCEEDED(channelprops->Has(kReferrerProperty, &useReferrer)) &&
|
||||
useReferrer)
|
||||
{
|
||||
// channel may have the property but set to null. In that case we know
|
||||
// it was a typed URL or bookmark and can bypass site whitelisting, as
|
||||
// opposed to not knowing the origin and going with the fallback plan.
|
||||
channelprops->Get(kReferrerProperty,
|
||||
NS_GET_IID(nsIURI),
|
||||
getter_AddRefs(referringURI));
|
||||
}
|
||||
|
||||
// Cancel the current request. nsXPInstallManager restarts the download
|
||||
// under its control (shared codepath with InstallTrigger)
|
||||
|
@ -198,14 +185,15 @@ nsInstallTrigger::HandleContent(const char * aContentType,
|
|||
// going to honor this request based on PermissionManager settings
|
||||
PRBool enabled = PR_FALSE;
|
||||
|
||||
if ( referringURI )
|
||||
if ( useReferrer )
|
||||
{
|
||||
// easiest and most common case: base decision on http referrer
|
||||
// easiest and most common case: base decision on the page that
|
||||
// contained the link
|
||||
//
|
||||
// NOTE: the XPI itself may be from elsewhere; the user can decide if
|
||||
// they trust the actual source when they get the install confirmation
|
||||
// dialog. The decision we're making here is whether the triggering
|
||||
// site is one which is allowed to annoy the user with modal dialogs
|
||||
// site is one which is allowed to annoy the user with modal dialogs.
|
||||
|
||||
enabled = AllowInstall( referringURI );
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче