Move the safe vs unsafe about: distinction out of the security manager and into

nsIAboutModule implementations.  Bug 337746, r=dveditz, sr=darin
This commit is contained in:
bzbarsky%mit.edu 2006-06-19 21:02:12 +00:00
parent 31fbfa9477
commit 9509962b32
21 changed files with 556 additions and 242 deletions

View File

@ -1201,25 +1201,6 @@ nsScriptSecurityManager::GetBaseURIScheme(nsIURI* aURI,
rv = uri->GetScheme(aScheme); rv = uri->GetScheme(aScheme);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
//-- if aURI is an about uri, distinguish 'safe' and 'unsafe' about URIs
if(aScheme.EqualsLiteral("about"))
{
nsCAutoString path;
rv = NS_GetAboutModuleName(uri, path);
NS_ENSURE_SUCCESS(rv, rv);
if (path.EqualsLiteral("blank") ||
path.EqualsLiteral("mozilla") ||
path.EqualsLiteral("logo") ||
path.EqualsLiteral("license") ||
path.EqualsLiteral("licence") ||
path.EqualsLiteral("credits") ||
path.EqualsLiteral("neterror"))
{
aScheme = NS_LITERAL_CSTRING("about safe");
return NS_OK;
}
}
return NS_OK; return NS_OK;
} }
@ -1334,8 +1315,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
{ "news", AllowProtocol }, { "news", AllowProtocol },
{ "javascript", AllowProtocol }, { "javascript", AllowProtocol },
{ "ftp", AllowProtocol }, { "ftp", AllowProtocol },
{ "about safe", AllowProtocol }, { "moz-safe-about", AllowProtocol },
{ "about", ChromeProtocol }, { "about", DenyProtocol },
{ "mailto", AllowProtocol }, { "mailto", AllowProtocol },
{ "aim", AllowProtocol }, { "aim", AllowProtocol },
{ "data", AllowProtocol }, { "data", AllowProtocol },
@ -1365,6 +1346,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
case PrefControlled: case PrefControlled:
{ {
// resource: and chrome: are equivalent, securitywise // resource: and chrome: are equivalent, securitywise
// That's bogus!! Fix this. But watch out for
// the view-source stylesheet?
if (sourceScheme.EqualsLiteral("chrome") || if (sourceScheme.EqualsLiteral("chrome") ||
sourceScheme.EqualsLiteral("resource")) sourceScheme.EqualsLiteral("resource"))
return NS_OK; return NS_OK;
@ -1390,6 +1373,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
if (aFlags & nsIScriptSecurityManager::ALLOW_CHROME) if (aFlags & nsIScriptSecurityManager::ALLOW_CHROME)
return NS_OK; return NS_OK;
// resource: and chrome: are equivalent, securitywise // resource: and chrome: are equivalent, securitywise
// That's bogus!! Fix this. But watch out for
// the view-source stylesheet?
if (sourceScheme.EqualsLiteral("chrome") || if (sourceScheme.EqualsLiteral("chrome") ||
sourceScheme.EqualsLiteral("resource")) sourceScheme.EqualsLiteral("resource"))
return NS_OK; return NS_OK;

View File

@ -61,6 +61,10 @@ AboutHandler.prototype =
var ext_channel = ioService.newChannelFromURI(ext_uri); var ext_channel = ioService.newChannelFromURI(ext_uri);
return ext_channel; return ext_channel;
} }
getURIFlags : function safeForUntrustedContent(aURI) {
return 0;
}
}; };

View File

@ -621,6 +621,13 @@ nsMetricsService::NewChannel(nsIURI *uri, nsIChannel **result)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsMetricsService::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsMetricsService::OnStartRequest(nsIRequest *request, nsISupports *context) nsMetricsService::OnStartRequest(nsIRequest *request, nsISupports *context)
{ {

View File

@ -63,3 +63,6 @@ class AboutPython:
#channel.contentType = "text/html" #channel.contentType = "text/html"
channel.contentStream = istream channel.contentStream = istream
return channel return channel
def getURIFlags(self, aURI):
return 0;

View File

@ -77,6 +77,7 @@ CPPSRCS = \
nsRequestObserverProxy.cpp \ nsRequestObserverProxy.cpp \
nsSimpleStreamListener.cpp \ nsSimpleStreamListener.cpp \
nsSimpleURI.cpp \ nsSimpleURI.cpp \
nsSimpleNestedURI.cpp \
nsStandardURL.cpp \ nsStandardURL.cpp \
nsSocketTransport2.cpp \ nsSocketTransport2.cpp \
nsSocketTransportService2.cpp \ nsSocketTransportService2.cpp \

View File

@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Boris Zbarsky <bzbarsky@mit.edu> (Original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 "nsSimpleNestedURI.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsNetUtil.h"
NS_IMPL_ISUPPORTS_INHERITED1(nsSimpleNestedURI, nsSimpleURI, nsINestedURI)
nsSimpleNestedURI::nsSimpleNestedURI(nsIURI* innerURI)
: nsSimpleURI(nsnull),
mInnerURI(innerURI)
{
NS_ASSERTION(innerURI, "Must have inner URI");
NS_TryToSetImmutable(innerURI);
}
// nsISerializable
NS_IMETHODIMP
nsSimpleNestedURI::Read(nsIObjectInputStream* aStream)
{
nsresult rv = nsSimpleURI::Read(aStream);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(!mMutable, "How did that happen?");
rv = aStream->ReadObject(PR_TRUE, getter_AddRefs(mInnerURI));
if (NS_FAILED(rv)) return rv;
NS_TryToSetImmutable(mInnerURI);
return rv;
}
NS_IMETHODIMP
nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream)
{
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(mInnerURI);
if (!serializable) {
// We can't serialize ourselves
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv = nsSimpleURI::Write(aStream);
if (NS_FAILED(rv)) return rv;
rv = aStream->WriteCompoundObject(mInnerURI, NS_GET_IID(nsIURI),
PR_TRUE);
return rv;
}
// nsINestedURI
NS_IMETHODIMP
nsSimpleNestedURI::GetInnerURI(nsIURI** uri)
{
NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
return NS_EnsureSafeToReturn(mInnerURI, uri);
}
NS_IMETHODIMP
nsSimpleNestedURI::GetInnermostURI(nsIURI** uri)
{
return NS_ImplGetInnermostURI(this, uri);
}
// nsIURI overrides
NS_IMETHODIMP
nsSimpleNestedURI::Equals(nsIURI* other, PRBool *result)
{
*result = PR_FALSE;
NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
if (other) {
PRBool correctScheme;
nsresult rv = other->SchemeIs(mScheme.get(), &correctScheme);
NS_ENSURE_SUCCESS(rv, rv);
if (correctScheme) {
nsCOMPtr<nsINestedURI> nest = do_QueryInterface(other);
if (nest) {
nsCOMPtr<nsIURI> otherInner;
rv = nest->GetInnerURI(getter_AddRefs(otherInner));
NS_ENSURE_SUCCESS(rv, rv);
return otherInner->Equals(mInnerURI, result);
}
}
}
return NS_OK;
}
/* virtual */ nsSimpleURI*
nsSimpleNestedURI::StartClone()
{
NS_ENSURE_TRUE(mInnerURI, nsnull);
nsCOMPtr<nsIURI> innerClone;
nsresult rv = mInnerURI->Clone(getter_AddRefs(innerClone));
if (NS_FAILED(rv)) {
return nsnull;
}
nsSimpleNestedURI* url = new nsSimpleNestedURI(innerClone);
if (url) {
url->SetMutable(PR_FALSE);
}
return url;
}
// nsIClassInfo overrides
NS_IMETHODIMP
nsSimpleNestedURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
static NS_DEFINE_CID(kSimpleNestedURICID, NS_SIMPLENESTEDURI_CID);
*aClassIDNoAlloc = kSimpleNestedURICID;
return NS_OK;
}

View File

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* the Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Boris Zbarsky <bzbarsky@mit.edu> (Original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 ***** */
/**
* URI class to be used for cases when a simple URI actually resolves to some
* other sort of URI, with the latter being what's loaded when the load
* happens. All objects of this class should always be immutable, so that the
* inner URI and this URI don't get out of sync. The Clone() implementation
* will guarantee this for the clone, but it's up to the protocol handlers
* creating these URIs to ensure that in the first place. The innerURI passed
* to this URI will be set immutable if possible.
*/
#ifndef nsSimpleNestedURI_h__
#define nsSimpleNestedURI_h__
#include "nsCOMPtr.h"
#include "nsSimpleURI.h"
#include "nsINestedURI.h"
class nsSimpleNestedURI : public nsSimpleURI,
public nsINestedURI
{
public:
// To be used by deserialization only. Leaves this object in an
// uninitialized state that will throw on most accesses.
nsSimpleNestedURI()
: nsSimpleURI(nsnull)
{
}
// Constructor that should generally be used when constructing an object of
// this class with |operator new|.
nsSimpleNestedURI(nsIURI* innerURI);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSINESTEDURI
// Overrides for various methods nsSimpleURI implements follow.
// nsIURI overrides
NS_IMETHOD Equals(nsIURI* other, PRBool *result);
virtual nsSimpleURI* StartClone();
// nsISerializable overrides
NS_IMETHOD Read(nsIObjectInputStream* aStream);
NS_IMETHOD Write(nsIObjectOutputStream* aStream);
// Override the nsIClassInfo method GetClassIDNoAlloc to make sure our
// nsISerializable impl works right.
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc);
protected:
nsCOMPtr<nsIURI> mInnerURI;
};
#endif /* nsSimpleNestedURI_h__ */

View File

@ -113,6 +113,16 @@
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \ {0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
} }
// component inheriting from the simple URI component and also
// implementing nsINestedURI.
#define NS_SIMPLENESTEDURI_CID \
{ /* 56388dad-287b-4240-a785-85c394012503 */ \
0x56388dad, \
0x287b, \
0x4240, \
{ 0xa7, 0x85, 0x85, 0xc3, 0x94, 0x01, 0x25, 0x03 } \
}
// component implementing nsIStandardURL, nsIURI, nsIURL, nsISerializable, // component implementing nsIStandardURL, nsIURI, nsIURL, nsISerializable,
// and nsIClassInfo. // and nsIClassInfo.
#define NS_STANDARDURL_CLASSNAME \ #define NS_STANDARDURL_CLASSNAME \
@ -601,6 +611,30 @@
{0xae, 0xa8, 0x8f, 0xcc, 0x07, 0x93, 0xe9, 0x7f} \ {0xae, 0xa8, 0x8f, 0xcc, 0x07, 0x93, 0xe9, 0x7f} \
} }
/******************************************************************************
* netwerk/protocol/about/ classes
*/
#define NS_ABOUTPROTOCOLHANDLER_CLASSNAME \
"About Protocol Handler"
#define NS_ABOUTPROTOCOLHANDLER_CID \
{ /* 9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3 */ \
0x9e3b6c90, \
0x2f75, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
#define NS_SAFEABOUTPROTOCOLHANDLER_CLASSNAME \
"Safe About Protocol Handler"
#define NS_SAFEABOUTPROTOCOLHANDLER_CID \
{ /* 1423e739-782c-4081-b5d8-fe6fba68c0ef */ \
0x1423e739, \
0x782c, \
0x4081, \
{0xb5, 0xd8, 0xfe, 0x6f, 0xba, 0x68, 0xc0, 0xef} \
}
/****************************************************************************** /******************************************************************************
* netwerk/dns/ classes * netwerk/dns/ classes
*/ */

View File

@ -47,6 +47,7 @@
#include "nsSocketProviderService.h" #include "nsSocketProviderService.h"
#include "nscore.h" #include "nscore.h"
#include "nsSimpleURI.h" #include "nsSimpleURI.h"
#include "nsSimpleNestedURI.h"
#include "nsLoadGroup.h" #include "nsLoadGroup.h"
#include "nsStreamLoader.h" #include "nsStreamLoader.h"
#include "nsUnicharStreamLoader.h" #include "nsUnicharStreamLoader.h"
@ -173,6 +174,8 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCookieService, nsCookieService::GetSi
// about:blank is mandatory // about:blank is mandatory
#include "nsAboutProtocolHandler.h" #include "nsAboutProtocolHandler.h"
#include "nsAboutBlank.h" #include "nsAboutBlank.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeAboutProtocolHandler)
#ifdef NECKO_PROTOCOL_about #ifdef NECKO_PROTOCOL_about
// about // about
@ -227,7 +230,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsGopherHandler)
#ifdef NECKO_PROTOCOL_viewsource #ifdef NECKO_PROTOCOL_viewsource
#include "nsViewSourceHandler.h" #include "nsViewSourceHandler.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceHandler) NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceURI)
#endif #endif
#ifdef NECKO_PROTOCOL_data #ifdef NECKO_PROTOCOL_data
@ -251,6 +253,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandardURL)
NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsSimpleURI) NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsSimpleURI)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleNestedURI)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#include "nsIDNService.h" #include "nsIDNService.h"
@ -650,6 +654,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_SIMPLEURI_CID, NS_SIMPLEURI_CID,
NS_SIMPLEURI_CONTRACTID, NS_SIMPLEURI_CONTRACTID,
nsSimpleURIConstructor }, nsSimpleURIConstructor },
{ "Simple Nested URI",
NS_SIMPLENESTEDURI_CID,
nsnull,
nsSimpleNestedURIConstructor },
{ NS_ASYNCSTREAMCOPIER_CLASSNAME, { NS_ASYNCSTREAMCOPIER_CLASSNAME,
NS_ASYNCSTREAMCOPIER_CID, NS_ASYNCSTREAMCOPIER_CID,
NS_ASYNCSTREAMCOPIER_CONTRACTID, NS_ASYNCSTREAMCOPIER_CONTRACTID,
@ -974,10 +982,15 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
#endif #endif
// from netwerk/protocol/about (about:blank is mandatory): // from netwerk/protocol/about (about:blank is mandatory):
{ "About Protocol Handler", { NS_ABOUTPROTOCOLHANDLER_CLASSNAME,
NS_ABOUTPROTOCOLHANDLER_CID, NS_ABOUTPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about", NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "about",
nsAboutProtocolHandler::Create nsAboutProtocolHandlerConstructor
},
{ NS_SAFEABOUTPROTOCOLHANDLER_CLASSNAME,
NS_SAFEABOUTPROTOCOLHANDLER_CID,
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "safe-about",
nsSafeAboutProtocolHandlerConstructor
}, },
{ "about:blank", { "about:blank",
NS_ABOUT_BLANK_MODULE_CID, NS_ABOUT_BLANK_MODULE_CID,
@ -1109,11 +1122,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source", NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source",
nsViewSourceHandlerConstructor nsViewSourceHandlerConstructor
}, },
{ "The ViewSource URI",
NS_VIEWSOURCEURI_CID,
nsnull,
nsViewSourceURIConstructor
},
#endif #endif
#if defined(XP_WIN) && !defined(WINCE) #if defined(XP_WIN) && !defined(WINCE)

View File

@ -40,7 +40,7 @@
interface nsIURI; interface nsIURI;
interface nsIChannel; interface nsIChannel;
[scriptable, uuid(692303c0-2f83-11d3-8cd0-0060b0fc14a3)] [scriptable, uuid(9575693c-60d9-4332-b6b8-6c29289339cb)]
interface nsIAboutModule : nsISupports interface nsIAboutModule : nsISupports
{ {
/** /**
@ -49,6 +49,21 @@ interface nsIAboutModule : nsISupports
* @param aURI the uri of the new channel * @param aURI the uri of the new channel
*/ */
nsIChannel newChannel(in nsIURI aURI); nsIChannel newChannel(in nsIURI aURI);
/**
* A flag that indicates whether a URI is safe for untrusted
* content. If it is, web pages and so forth will be allowed to
* link to this about: URI. Otherwise, only chrome will be able
* to link to it.
*/
const unsigned long URI_SAFE_FOR_UNTRUSTED_CONTENT = (1 << 0);
/**
* A method to get the flags that apply to a given about: URI. The URI
* passed in is guaranteed to be one of the URIs that this module
* registered to deal with.
*/
unsigned long getURIFlags(in nsIURI aURI);
}; };
%{C++ %{C++

View File

@ -63,6 +63,8 @@ CPPSRCS = \
nsAboutRedirector.cpp \ nsAboutRedirector.cpp \
$(NULL) $(NULL)
LOCAL_INCLUDES=-I$(srcdir)/../../../base/src
# we don't want the shared lib, but we want to force the creation of a # we don't want the shared lib, but we want to force the creation of a
# static lib. # static lib.
FORCE_STATIC_LIB = 1 FORCE_STATIC_LIB = 1

View File

@ -66,6 +66,13 @@ nsAboutBlank::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv; return rv;
} }
NS_IMETHODIMP
nsAboutBlank::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT;
return NS_OK;
}
NS_METHOD NS_METHOD
nsAboutBlank::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) nsAboutBlank::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{ {

View File

@ -157,6 +157,13 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv; return rv;
} }
NS_IMETHODIMP
nsAboutBloat::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_METHOD NS_METHOD
nsAboutBloat::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) nsAboutBloat::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{ {

View File

@ -139,6 +139,12 @@ nsAboutCache::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv; return rv;
} }
NS_IMETHODIMP
nsAboutCache::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsAboutCache::VisitDevice(const char *deviceID, nsAboutCache::VisitDevice(const char *deviceID,

View File

@ -129,6 +129,13 @@ nsAboutCacheEntry::NewChannel(nsIURI *uri, nsIChannel **result)
NS_LITERAL_CSTRING("utf-8")); NS_LITERAL_CSTRING("utf-8"));
} }
NS_IMETHODIMP
nsAboutCacheEntry::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsAboutCacheEntry // nsAboutCacheEntry

View File

@ -48,45 +48,15 @@
#include "nsNetCID.h" #include "nsNetCID.h"
#include "nsAboutProtocolUtils.h" #include "nsAboutProtocolUtils.h"
#include "nsNetError.h" #include "nsNetError.h"
#include "nsNetUtil.h"
#include "nsSimpleNestedURI.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
nsAboutProtocolHandler::nsAboutProtocolHandler()
{
}
nsresult
nsAboutProtocolHandler::Init()
{
return NS_OK;
}
nsAboutProtocolHandler::~nsAboutProtocolHandler()
{
}
NS_IMPL_ISUPPORTS1(nsAboutProtocolHandler, nsIProtocolHandler) NS_IMPL_ISUPPORTS1(nsAboutProtocolHandler, nsIProtocolHandler)
NS_METHOD
nsAboutProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsAboutProtocolHandler* ph = new nsAboutProtocolHandler();
if (ph == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(ph);
nsresult rv = ph->Init();
if (NS_SUCCEEDED(rv)) {
rv = ph->QueryInterface(aIID, aResult);
}
NS_RELEASE(ph);
return rv;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsIProtocolHandler methods: // nsIProtocolHandler methods:
@ -117,36 +87,67 @@ nsAboutProtocolHandler::NewURI(const nsACString &aSpec,
nsIURI *aBaseURI, nsIURI *aBaseURI,
nsIURI **result) nsIURI **result)
{ {
*result = nsnull;
nsresult rv; nsresult rv;
nsIURI* url; // Use a simple URI to parse out some stuff first
rv = CallCreateInstance(kSimpleURICID, &url); nsCOMPtr<nsIURI> url = do_CreateInstance(kSimpleURICID, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = url->SetSpec(aSpec); rv = url->SetSpec(aSpec);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv; return rv;
} }
*result = url; // Unfortunately, people create random about: URIs that don't correspond to
return rv; // about: modules... Since those URIs will never open a channel, might as
// well consider them unsafe for better perf, and just in case.
PRBool isSafe = PR_FALSE;
nsCOMPtr<nsIAboutModule> aboutMod;
rv = GetModuleForURI(url, getter_AddRefs(aboutMod));
if (NS_SUCCEEDED(rv)) {
// The standard return case
PRUint32 flags;
rv = aboutMod->GetURIFlags(url, &flags);
NS_ENSURE_SUCCESS(rv, rv);
isSafe =
((flags & nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT) != 0);
}
if (isSafe) {
// We need to indicate that this baby is safe. Use an inner
// URI that no one but the security manager will see.
nsCOMPtr<nsIURI> inner;
rv = NS_NewURI(getter_AddRefs(inner), "moz-safe-about:x");
NS_ENSURE_SUCCESS(rv, rv);
nsSimpleNestedURI* outer = new nsSimpleNestedURI(inner);
NS_ENSURE_TRUE(outer, NS_ERROR_OUT_OF_MEMORY);
// Take a ref to it in the COMPtr we plan to return
url = outer;
rv = outer->SetSpec(aSpec);
NS_ENSURE_SUCCESS(rv, rv);
}
// We don't want to allow mutation, since it would allow safe and
// unsafe URIs to change into each other...
NS_TryToSetImmutable(url);
url.swap(*result);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{ {
NS_ENSURE_ARG_POINTER(uri); NS_ENSURE_ARG_POINTER(uri);
// about:what you ask? // about:what you ask?
nsresult rv; nsCOMPtr<nsIAboutModule> aboutMod;
nsCAutoString contractID; nsresult rv = GetModuleForURI(uri, getter_AddRefs(aboutMod));
rv = NS_GetAboutModuleName(uri, contractID);
if (NS_FAILED(rv)) return rv;
// look up a handler to deal with "what"
contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0);
nsCOMPtr<nsIAboutModule> aboutMod(do_GetService(contractID.get(), &rv));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
// The standard return case: // The standard return case:
return aboutMod->NewChannel(uri, result); return aboutMod->NewChannel(uri, result);
@ -170,4 +171,87 @@ nsAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_ret
*_retval = PR_FALSE; *_retval = PR_FALSE;
return NS_OK; return NS_OK;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* static */
nsresult
nsAboutProtocolHandler::GetModuleForURI(nsIURI* uri, nsIAboutModule** module)
{
NS_PRECONDITION(uri, "Must have URI");
nsresult rv;
nsCAutoString contractID;
rv = NS_GetAboutModuleName(uri, contractID);
if (NS_FAILED(rv)) return rv;
// look up a handler to deal with "what"
contractID.Insert(NS_LITERAL_CSTRING(NS_ABOUT_MODULE_CONTRACTID_PREFIX), 0);
return CallGetService(contractID.get(), module);
}
////////////////////////////////////////////////////////////////////////////////
// Safe about protocol handler impl
NS_IMPL_ISUPPORTS1(nsSafeAboutProtocolHandler, nsIProtocolHandler)
// nsIProtocolHandler methods:
NS_IMETHODIMP
nsSafeAboutProtocolHandler::GetScheme(nsACString &result)
{
result.AssignLiteral("moz-safe-about");
return NS_OK;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::GetDefaultPort(PRInt32 *result)
{
*result = -1; // no port for moz-safe-about: URLs
return NS_OK;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::GetProtocolFlags(PRUint32 *result)
{
*result = URI_NORELATIVE | URI_NOAUTH;
return NS_OK;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::NewURI(const nsACString &aSpec,
const char *aCharset, // ignore charset info
nsIURI *aBaseURI,
nsIURI **result)
{
nsresult rv;
nsCOMPtr<nsIURI> url = do_CreateInstance(kSimpleURICID, &rv);
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec(aSpec);
if (NS_FAILED(rv)) {
return rv;
}
NS_TryToSetImmutable(url);
*result = nsnull;
url.swap(*result);
return rv;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
{
*result = nsnull;
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsSafeAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
{
// don't override anything.
*_retval = PR_FALSE;
return NS_OK;
}

View File

@ -41,14 +41,7 @@
#include "nsIProtocolHandler.h" #include "nsIProtocolHandler.h"
class nsCString; class nsCString;
class nsIAboutModule;
#define NS_ABOUTPROTOCOLHANDLER_CID \
{ /* 9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3 */ \
0x9e3b6c90, \
0x2f75, \
0x11d3, \
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsAboutProtocolHandler : public nsIProtocolHandler class nsAboutProtocolHandler : public nsIProtocolHandler
{ {
@ -59,13 +52,27 @@ public:
NS_DECL_NSIPROTOCOLHANDLER NS_DECL_NSIPROTOCOLHANDLER
// nsAboutProtocolHandler methods: // nsAboutProtocolHandler methods:
nsAboutProtocolHandler(); nsAboutProtocolHandler() {}
virtual ~nsAboutProtocolHandler(); virtual ~nsAboutProtocolHandler() {}
static NS_METHOD protected:
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); static nsresult GetModuleForURI(nsIURI* uri, nsIAboutModule** module);
nsresult Init();
}; };
class nsSafeAboutProtocolHandler : public nsIProtocolHandler
{
public:
NS_DECL_ISUPPORTS
// nsIProtocolHandler methods:
NS_DECL_NSIPROTOCOLHANDLER
// nsSafeAboutProtocolHandler methods:
nsSafeAboutProtocolHandler() {}
private:
~nsSafeAboutProtocolHandler() {}
};
#endif /* nsAboutProtocolHandler_h___ */ #endif /* nsAboutProtocolHandler_h___ */

View File

@ -43,6 +43,7 @@
#include "plstr.h" #include "plstr.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsAboutProtocolUtils.h" #include "nsAboutProtocolUtils.h"
#include "nsSimpleNestedURI.h"
NS_IMPL_ISUPPORTS1(nsAboutRedirector, nsIAboutModule) NS_IMPL_ISUPPORTS1(nsAboutRedirector, nsIAboutModule)
@ -129,6 +130,29 @@ nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result)
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
} }
NS_IMETHODIMP
nsAboutRedirector::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
NS_ENSURE_ARG_POINTER(aURI);
nsCAutoString name;
nsresult rv = NS_GetAboutModuleName(aURI, name);
NS_ENSURE_SUCCESS(rv, rv);
for (int i=0; i < kRedirTotal; i++)
{
if (name.EqualsASCII(kRedirMap[i].id))
{
*result = kRedirMap[i].dropChromePrivs ?
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT : 0;
return NS_OK;
}
}
NS_ERROR("nsAboutRedirector called for unknown case");
return NS_ERROR_ILLEGAL_VALUE;
}
NS_METHOD NS_METHOD
nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{ {

View File

@ -41,9 +41,7 @@
#include "nsViewSourceHandler.h" #include "nsViewSourceHandler.h"
#include "nsViewSourceChannel.h" #include "nsViewSourceChannel.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIObjectInputStream.h" #include "nsSimpleNestedURI.h"
#include "nsIObjectOutputStream.h"
#include "nsIProgrammingLanguage.h"
#define VIEW_SOURCE "view-source" #define VIEW_SOURCE "view-source"
@ -96,8 +94,6 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
NS_TryToSetImmutable(innerURI);
nsCAutoString asciiSpec; nsCAutoString asciiSpec;
rv = innerURI->GetAsciiSpec(asciiSpec); rv = innerURI->GetAsciiSpec(asciiSpec);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
@ -107,8 +103,9 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
asciiSpec.Insert(VIEW_SOURCE ":", 0); asciiSpec.Insert(VIEW_SOURCE ":", 0);
// We can't swap() from an nsRefPtr<nsViewSourceURI> to an nsIURI**, sadly. // We can't swap() from an nsRefPtr<nsSimpleNestedURI> to an nsIURI**,
nsViewSourceURI* ourURI = new nsViewSourceURI(innerURI); // sadly.
nsSimpleNestedURI* ourURI = new nsSimpleNestedURI(innerURI);
nsCOMPtr<nsIURI> uri = ourURI; nsCOMPtr<nsIURI> uri = ourURI;
if (!uri) if (!uri)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@ -118,7 +115,7 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec,
return rv; return rv;
// Make the URI immutable so it's impossible to get it out of sync // Make the URI immutable so it's impossible to get it out of sync
// with mInnerURI. // with its inner URI.
ourURI->SetMutable(PR_FALSE); ourURI->SetMutable(PR_FALSE);
uri.swap(*aResult); uri.swap(*aResult);
@ -151,98 +148,3 @@ nsViewSourceHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval
*_retval = PR_FALSE; *_retval = PR_FALSE;
return NS_OK; return NS_OK;
} }
///////////////////////////////////////////////////////////////
// nsViewSourceURI implementation
static NS_DEFINE_CID(kViewSourceURICID, NS_VIEWSOURCEURI_CID);
NS_IMPL_ISUPPORTS_INHERITED1(nsViewSourceURI, nsSimpleURI, nsINestedURI)
// nsISerializable
NS_IMETHODIMP
nsViewSourceURI::Read(nsIObjectInputStream* aStream)
{
nsresult rv = nsSimpleURI::Read(aStream);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(!mMutable, "How did that happen?");
// Our mPath is going to be ASCII; see nsViewSourceHandler::NewURI. So
// just using NS_NewURI with no charset is ok.
rv = NS_NewURI(getter_AddRefs(mInnerURI), mPath);
if (NS_FAILED(rv)) return rv;
NS_TryToSetImmutable(mInnerURI);
return rv;
}
// nsINestedURI
NS_IMETHODIMP
nsViewSourceURI::GetInnerURI(nsIURI** uri)
{
return NS_EnsureSafeToReturn(mInnerURI, uri);
}
NS_IMETHODIMP
nsViewSourceURI::GetInnermostURI(nsIURI** uri)
{
return NS_ImplGetInnermostURI(this, uri);
}
// nsIURI overrides
NS_IMETHODIMP
nsViewSourceURI::Equals(nsIURI* other, PRBool *result)
{
if (other) {
PRBool correctScheme;
nsresult rv = other->SchemeIs(VIEW_SOURCE, &correctScheme);
NS_ENSURE_SUCCESS(rv, rv);
if (correctScheme) {
nsCOMPtr<nsINestedURI> nest = do_QueryInterface(other);
if (nest) {
nsCOMPtr<nsIURI> otherInner;
rv = nest->GetInnerURI(getter_AddRefs(otherInner));
NS_ENSURE_SUCCESS(rv, rv);
return otherInner->Equals(mInnerURI, result);
}
}
}
*result = PR_FALSE;
return NS_OK;
}
/* virtual */ nsSimpleURI*
nsViewSourceURI::StartClone()
{
nsCOMPtr<nsIURI> innerClone;
nsresult rv = mInnerURI->Clone(getter_AddRefs(innerClone));
if (NS_FAILED(rv)) {
return nsnull;
}
NS_TryToSetImmutable(innerClone);
nsViewSourceURI* url = new nsViewSourceURI(innerClone);
if (url) {
url->SetMutable(PR_FALSE);
}
return url;
}
// nsIClassInfo overrides
NS_IMETHODIMP
nsViewSourceURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{
*aClassIDNoAlloc = kViewSourceURICID;
return NS_OK;
}

View File

@ -40,9 +40,6 @@
#define nsViewSourceHandler_h___ #define nsViewSourceHandler_h___
#include "nsIProtocolHandler.h" #include "nsIProtocolHandler.h"
#include "nsCOMPtr.h"
#include "nsSimpleURI.h"
#include "nsINestedURI.h"
class nsViewSourceHandler : public nsIProtocolHandler class nsViewSourceHandler : public nsIProtocolHandler
{ {
@ -51,50 +48,4 @@ public:
NS_DECL_NSIPROTOCOLHANDLER NS_DECL_NSIPROTOCOLHANDLER
}; };
#define NS_VIEWSOURCEURI_CID \
{ /* 2545766f-3a27-4fd1-8e88-b0886d346242 */ \
0x2545766f, \
0x3a27, \
0x4fd1, \
{ 0x8e, 0x88, 0xb0, 0x88, 0x6d, 0x34, 0x62, 0x42 } \
}
class nsViewSourceURI : public nsSimpleURI,
public nsINestedURI
{
public:
nsViewSourceURI(nsIURI* innerURI)
: nsSimpleURI(nsnull),
mInnerURI(innerURI)
{
NS_ASSERTION(innerURI, "Must have inner URI");
}
// To be used by deserialization only
nsViewSourceURI()
: nsSimpleURI(nsnull)
{
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSINESTEDURI
// Overrides for various methods nsSimpleURI implements follow.
// nsIURI overrides
NS_IMETHOD Equals(nsIURI* other, PRBool *result);
virtual nsSimpleURI* StartClone();
// nsISerializable overrides -- we can use the same Write(), but we
// need a different Read().
NS_IMETHOD Read(nsIObjectInputStream* aStream);
// Override the nsIClassInfo method GetClassIDNoAlloc to make sure our
// nsISerializable impl works right.
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc);
protected:
nsCOMPtr<nsIURI> mInnerURI;
};
#endif /* !defined( nsViewSourceHandler_h___ ) */ #endif /* !defined( nsViewSourceHandler_h___ ) */

View File

@ -77,6 +77,13 @@ nsAbout::NewChannel(nsIURI *aURI, nsIChannel **result)
return rv; return rv;
} }
NS_IMETHODIMP
nsAbout::GetURIFlags(nsIURI *aURI, PRUint32 *result)
{
*result = 0;
return NS_OK;
}
NS_METHOD NS_METHOD
nsAbout::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) nsAbout::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{ {