From dcd8a3a0536cf4dfa3521672648737d4f89d30b1 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Mon, 19 Jun 2006 21:02:12 +0000 Subject: [PATCH] Move the safe vs unsafe about: distinction out of the security manager and into nsIAboutModule implementations. Bug 337746, r=dveditz, sr=darin git-svn-id: svn://10.0.0.236/trunk@200348 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/src/nsScriptSecurityManager.cpp | 27 +-- .../srcfiles/disableAboutConfig.js.in | 4 + .../metrics/src/nsMetricsService.cpp | 7 + .../python/xpcom/components/pyabout.py | 3 + mozilla/netwerk/base/src/Makefile.in | 1 + .../netwerk/base/src/nsSimpleNestedURI.cpp | 161 ++++++++++++++++ mozilla/netwerk/base/src/nsSimpleNestedURI.h | 92 +++++++++ mozilla/netwerk/build/nsNetCID.h | 34 ++++ mozilla/netwerk/build/nsNetModule.cpp | 24 ++- .../protocol/about/public/nsIAboutModule.idl | 17 +- .../netwerk/protocol/about/src/Makefile.in | 2 + .../protocol/about/src/nsAboutBlank.cpp | 7 + .../protocol/about/src/nsAboutBloat.cpp | 7 + .../protocol/about/src/nsAboutCache.cpp | 6 + .../protocol/about/src/nsAboutCacheEntry.cpp | 7 + .../about/src/nsAboutProtocolHandler.cpp | 176 +++++++++++++----- .../about/src/nsAboutProtocolHandler.h | 35 ++-- .../protocol/about/src/nsAboutRedirector.cpp | 24 +++ .../viewsource/src/nsViewSourceHandler.cpp | 108 +---------- .../viewsource/src/nsViewSourceHandler.h | 49 ----- mozilla/xpfe/appshell/src/nsAbout.cpp | 7 + 21 files changed, 556 insertions(+), 242 deletions(-) create mode 100644 mozilla/netwerk/base/src/nsSimpleNestedURI.cpp create mode 100644 mozilla/netwerk/base/src/nsSimpleNestedURI.h diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 4b76da9df62..ac375c33fb9 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -1201,25 +1201,6 @@ nsScriptSecurityManager::GetBaseURIScheme(nsIURI* aURI, rv = uri->GetScheme(aScheme); 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; } @@ -1334,8 +1315,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, { "news", AllowProtocol }, { "javascript", AllowProtocol }, { "ftp", AllowProtocol }, - { "about safe", AllowProtocol }, - { "about", ChromeProtocol }, + { "moz-safe-about", AllowProtocol }, + { "about", DenyProtocol }, { "mailto", AllowProtocol }, { "aim", AllowProtocol }, { "data", AllowProtocol }, @@ -1365,6 +1346,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, case PrefControlled: { // resource: and chrome: are equivalent, securitywise + // That's bogus!! Fix this. But watch out for + // the view-source stylesheet? if (sourceScheme.EqualsLiteral("chrome") || sourceScheme.EqualsLiteral("resource")) return NS_OK; @@ -1390,6 +1373,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, if (aFlags & nsIScriptSecurityManager::ALLOW_CHROME) return NS_OK; // resource: and chrome: are equivalent, securitywise + // That's bogus!! Fix this. But watch out for + // the view-source stylesheet? if (sourceScheme.EqualsLiteral("chrome") || sourceScheme.EqualsLiteral("resource")) return NS_OK; diff --git a/mozilla/extensions/cck/browser/resources/content/cckwizard/srcfiles/disableAboutConfig.js.in b/mozilla/extensions/cck/browser/resources/content/cckwizard/srcfiles/disableAboutConfig.js.in index eee953d613f..460b6c11fa6 100644 --- a/mozilla/extensions/cck/browser/resources/content/cckwizard/srcfiles/disableAboutConfig.js.in +++ b/mozilla/extensions/cck/browser/resources/content/cckwizard/srcfiles/disableAboutConfig.js.in @@ -61,6 +61,10 @@ AboutHandler.prototype = var ext_channel = ioService.newChannelFromURI(ext_uri); return ext_channel; } + + getURIFlags : function safeForUntrustedContent(aURI) { + return 0; + } }; diff --git a/mozilla/extensions/metrics/src/nsMetricsService.cpp b/mozilla/extensions/metrics/src/nsMetricsService.cpp index ec55abec8c7..4dc56be666e 100644 --- a/mozilla/extensions/metrics/src/nsMetricsService.cpp +++ b/mozilla/extensions/metrics/src/nsMetricsService.cpp @@ -621,6 +621,13 @@ nsMetricsService::NewChannel(nsIURI *uri, nsIChannel **result) return NS_OK; } +NS_IMETHODIMP +nsMetricsService::GetURIFlags(nsIURI *aURI, PRUint32 *result) +{ + *result = 0; + return NS_OK; +} + NS_IMETHODIMP nsMetricsService::OnStartRequest(nsIRequest *request, nsISupports *context) { diff --git a/mozilla/extensions/python/xpcom/components/pyabout.py b/mozilla/extensions/python/xpcom/components/pyabout.py index a7b7925f9ec..c9b0fe48c64 100644 --- a/mozilla/extensions/python/xpcom/components/pyabout.py +++ b/mozilla/extensions/python/xpcom/components/pyabout.py @@ -63,3 +63,6 @@ class AboutPython: #channel.contentType = "text/html" channel.contentStream = istream return channel + + def getURIFlags(self, aURI): + return 0; diff --git a/mozilla/netwerk/base/src/Makefile.in b/mozilla/netwerk/base/src/Makefile.in index b5657ff9b42..9eb81e7256a 100644 --- a/mozilla/netwerk/base/src/Makefile.in +++ b/mozilla/netwerk/base/src/Makefile.in @@ -77,6 +77,7 @@ CPPSRCS = \ nsRequestObserverProxy.cpp \ nsSimpleStreamListener.cpp \ nsSimpleURI.cpp \ + nsSimpleNestedURI.cpp \ nsStandardURL.cpp \ nsSocketTransport2.cpp \ nsSocketTransportService2.cpp \ diff --git a/mozilla/netwerk/base/src/nsSimpleNestedURI.cpp b/mozilla/netwerk/base/src/nsSimpleNestedURI.cpp new file mode 100644 index 00000000000..bcefbd07522 --- /dev/null +++ b/mozilla/netwerk/base/src/nsSimpleNestedURI.cpp @@ -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 (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 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 nest = do_QueryInterface(other); + if (nest) { + nsCOMPtr 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 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; +} diff --git a/mozilla/netwerk/base/src/nsSimpleNestedURI.h b/mozilla/netwerk/base/src/nsSimpleNestedURI.h new file mode 100644 index 00000000000..07b1a30eac3 --- /dev/null +++ b/mozilla/netwerk/base/src/nsSimpleNestedURI.h @@ -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 (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 mInnerURI; +}; + +#endif /* nsSimpleNestedURI_h__ */ diff --git a/mozilla/netwerk/build/nsNetCID.h b/mozilla/netwerk/build/nsNetCID.h index 6f4905aaa65..85a0358cf7f 100644 --- a/mozilla/netwerk/build/nsNetCID.h +++ b/mozilla/netwerk/build/nsNetCID.h @@ -113,6 +113,16 @@ {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, // and nsIClassInfo. #define NS_STANDARDURL_CLASSNAME \ @@ -601,6 +611,30 @@ {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 */ diff --git a/mozilla/netwerk/build/nsNetModule.cpp b/mozilla/netwerk/build/nsNetModule.cpp index 3b0cba65eb5..e2511bcd419 100644 --- a/mozilla/netwerk/build/nsNetModule.cpp +++ b/mozilla/netwerk/build/nsNetModule.cpp @@ -47,6 +47,7 @@ #include "nsSocketProviderService.h" #include "nscore.h" #include "nsSimpleURI.h" +#include "nsSimpleNestedURI.h" #include "nsLoadGroup.h" #include "nsStreamLoader.h" #include "nsUnicharStreamLoader.h" @@ -173,6 +174,8 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsCookieService, nsCookieService::GetSi // about:blank is mandatory #include "nsAboutProtocolHandler.h" #include "nsAboutBlank.h" +NS_GENERIC_FACTORY_CONSTRUCTOR(nsAboutProtocolHandler) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafeAboutProtocolHandler) #ifdef NECKO_PROTOCOL_about // about @@ -227,7 +230,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsGopherHandler) #ifdef NECKO_PROTOCOL_viewsource #include "nsViewSourceHandler.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceHandler) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceURI) #endif #ifdef NECKO_PROTOCOL_data @@ -251,6 +253,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandardURL) NS_GENERIC_AGGREGATED_CONSTRUCTOR(nsSimpleURI) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleNestedURI) + /////////////////////////////////////////////////////////////////////////////// #include "nsIDNService.h" @@ -650,6 +654,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = { NS_SIMPLEURI_CID, NS_SIMPLEURI_CONTRACTID, nsSimpleURIConstructor }, + { "Simple Nested URI", + NS_SIMPLENESTEDURI_CID, + nsnull, + nsSimpleNestedURIConstructor }, { NS_ASYNCSTREAMCOPIER_CLASSNAME, NS_ASYNCSTREAMCOPIER_CID, NS_ASYNCSTREAMCOPIER_CONTRACTID, @@ -974,10 +982,15 @@ static const nsModuleComponentInfo gNetModuleInfo[] = { #endif // from netwerk/protocol/about (about:blank is mandatory): - { "About Protocol Handler", + { NS_ABOUTPROTOCOLHANDLER_CLASSNAME, NS_ABOUTPROTOCOLHANDLER_CID, 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", NS_ABOUT_BLANK_MODULE_CID, @@ -1109,11 +1122,6 @@ static const nsModuleComponentInfo gNetModuleInfo[] = { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source", nsViewSourceHandlerConstructor }, - { "The ViewSource URI", - NS_VIEWSOURCEURI_CID, - nsnull, - nsViewSourceURIConstructor - }, #endif #if defined(XP_WIN) && !defined(WINCE) diff --git a/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl b/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl index 53c496e7edc..498077a9619 100644 --- a/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl +++ b/mozilla/netwerk/protocol/about/public/nsIAboutModule.idl @@ -40,7 +40,7 @@ interface nsIURI; interface nsIChannel; -[scriptable, uuid(692303c0-2f83-11d3-8cd0-0060b0fc14a3)] +[scriptable, uuid(9575693c-60d9-4332-b6b8-6c29289339cb)] interface nsIAboutModule : nsISupports { /** @@ -49,6 +49,21 @@ interface nsIAboutModule : nsISupports * @param aURI the uri of the new channel */ 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++ diff --git a/mozilla/netwerk/protocol/about/src/Makefile.in b/mozilla/netwerk/protocol/about/src/Makefile.in index ea3f2876291..af80fcee84d 100644 --- a/mozilla/netwerk/protocol/about/src/Makefile.in +++ b/mozilla/netwerk/protocol/about/src/Makefile.in @@ -63,6 +63,8 @@ CPPSRCS = \ nsAboutRedirector.cpp \ $(NULL) +LOCAL_INCLUDES=-I$(srcdir)/../../../base/src + # we don't want the shared lib, but we want to force the creation of a # static lib. FORCE_STATIC_LIB = 1 diff --git a/mozilla/netwerk/protocol/about/src/nsAboutBlank.cpp b/mozilla/netwerk/protocol/about/src/nsAboutBlank.cpp index 47fdc3ec188..6c803963901 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutBlank.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutBlank.cpp @@ -66,6 +66,13 @@ nsAboutBlank::NewChannel(nsIURI *aURI, nsIChannel **result) return rv; } +NS_IMETHODIMP +nsAboutBlank::GetURIFlags(nsIURI *aURI, PRUint32 *result) +{ + *result = nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT; + return NS_OK; +} + NS_METHOD nsAboutBlank::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) { diff --git a/mozilla/netwerk/protocol/about/src/nsAboutBloat.cpp b/mozilla/netwerk/protocol/about/src/nsAboutBloat.cpp index 840bba90f8c..11d3a17e6e9 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutBloat.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutBloat.cpp @@ -157,6 +157,13 @@ nsAboutBloat::NewChannel(nsIURI *aURI, nsIChannel **result) return rv; } +NS_IMETHODIMP +nsAboutBloat::GetURIFlags(nsIURI *aURI, PRUint32 *result) +{ + *result = 0; + return NS_OK; +} + NS_METHOD nsAboutBloat::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) { diff --git a/mozilla/netwerk/protocol/about/src/nsAboutCache.cpp b/mozilla/netwerk/protocol/about/src/nsAboutCache.cpp index a1ff2ced20a..a69a75f957f 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutCache.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutCache.cpp @@ -139,6 +139,12 @@ nsAboutCache::NewChannel(nsIURI *aURI, nsIChannel **result) return rv; } +NS_IMETHODIMP +nsAboutCache::GetURIFlags(nsIURI *aURI, PRUint32 *result) +{ + *result = 0; + return NS_OK; +} NS_IMETHODIMP nsAboutCache::VisitDevice(const char *deviceID, diff --git a/mozilla/netwerk/protocol/about/src/nsAboutCacheEntry.cpp b/mozilla/netwerk/protocol/about/src/nsAboutCacheEntry.cpp index f03180a4bd1..335f21496c8 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutCacheEntry.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutCacheEntry.cpp @@ -129,6 +129,13 @@ nsAboutCacheEntry::NewChannel(nsIURI *uri, nsIChannel **result) NS_LITERAL_CSTRING("utf-8")); } +NS_IMETHODIMP +nsAboutCacheEntry::GetURIFlags(nsIURI *aURI, PRUint32 *result) +{ + *result = 0; + return NS_OK; +} + //----------------------------------------------------------------------------- // nsAboutCacheEntry diff --git a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp index 06055891d53..104e62f52b2 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.cpp @@ -48,45 +48,15 @@ #include "nsNetCID.h" #include "nsAboutProtocolUtils.h" #include "nsNetError.h" +#include "nsNetUtil.h" +#include "nsSimpleNestedURI.h" static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); //////////////////////////////////////////////////////////////////////////////// -nsAboutProtocolHandler::nsAboutProtocolHandler() -{ -} - -nsresult -nsAboutProtocolHandler::Init() -{ - return NS_OK; -} - -nsAboutProtocolHandler::~nsAboutProtocolHandler() -{ -} - 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: @@ -117,36 +87,67 @@ nsAboutProtocolHandler::NewURI(const nsACString &aSpec, nsIURI *aBaseURI, nsIURI **result) { + *result = nsnull; nsresult rv; - nsIURI* url; - rv = CallCreateInstance(kSimpleURICID, &url); + // Use a simple URI to parse out some stuff first + nsCOMPtr url = do_CreateInstance(kSimpleURICID, &rv); if (NS_FAILED(rv)) return rv; rv = url->SetSpec(aSpec); if (NS_FAILED(rv)) { - NS_RELEASE(url); return rv; } - *result = url; - return rv; + // Unfortunately, people create random about: URIs that don't correspond to + // 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 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 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 nsAboutProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) { NS_ENSURE_ARG_POINTER(uri); + // about:what you ask? - 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); - - nsCOMPtr aboutMod(do_GetService(contractID.get(), &rv)); + nsCOMPtr aboutMod; + nsresult rv = GetModuleForURI(uri, getter_AddRefs(aboutMod)); if (NS_SUCCEEDED(rv)) { // The standard return case: return aboutMod->NewChannel(uri, result); @@ -170,4 +171,87 @@ nsAboutProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_ret *_retval = PR_FALSE; 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 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; +} diff --git a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h index 516258152eb..80dd4f4640d 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h +++ b/mozilla/netwerk/protocol/about/src/nsAboutProtocolHandler.h @@ -41,14 +41,7 @@ #include "nsIProtocolHandler.h" class nsCString; - -#define NS_ABOUTPROTOCOLHANDLER_CID \ -{ /* 9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3 */ \ - 0x9e3b6c90, \ - 0x2f75, \ - 0x11d3, \ - {0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \ -} +class nsIAboutModule; class nsAboutProtocolHandler : public nsIProtocolHandler { @@ -59,13 +52,27 @@ public: NS_DECL_NSIPROTOCOLHANDLER // nsAboutProtocolHandler methods: - nsAboutProtocolHandler(); - virtual ~nsAboutProtocolHandler(); + nsAboutProtocolHandler() {} + virtual ~nsAboutProtocolHandler() {} - static NS_METHOD - Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); - - nsresult Init(); +protected: + static nsresult GetModuleForURI(nsIURI* uri, nsIAboutModule** module); }; +class nsSafeAboutProtocolHandler : public nsIProtocolHandler +{ +public: + NS_DECL_ISUPPORTS + + // nsIProtocolHandler methods: + NS_DECL_NSIPROTOCOLHANDLER + + // nsSafeAboutProtocolHandler methods: + nsSafeAboutProtocolHandler() {} + +private: + ~nsSafeAboutProtocolHandler() {} +}; + + #endif /* nsAboutProtocolHandler_h___ */ diff --git a/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp b/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp index 75abe9a95a3..41363da8d02 100644 --- a/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp +++ b/mozilla/netwerk/protocol/about/src/nsAboutRedirector.cpp @@ -43,6 +43,7 @@ #include "plstr.h" #include "nsIScriptSecurityManager.h" #include "nsAboutProtocolUtils.h" +#include "nsSimpleNestedURI.h" NS_IMPL_ISUPPORTS1(nsAboutRedirector, nsIAboutModule) @@ -129,6 +130,29 @@ nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result) 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 nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) { diff --git a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.cpp b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.cpp index d88a75051bc..f4550fbd886 100644 --- a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.cpp +++ b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.cpp @@ -41,9 +41,7 @@ #include "nsViewSourceHandler.h" #include "nsViewSourceChannel.h" #include "nsNetUtil.h" -#include "nsIObjectInputStream.h" -#include "nsIObjectOutputStream.h" -#include "nsIProgrammingLanguage.h" +#include "nsSimpleNestedURI.h" #define VIEW_SOURCE "view-source" @@ -96,8 +94,6 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec, if (NS_FAILED(rv)) return rv; - NS_TryToSetImmutable(innerURI); - nsCAutoString asciiSpec; rv = innerURI->GetAsciiSpec(asciiSpec); if (NS_FAILED(rv)) @@ -107,8 +103,9 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec, asciiSpec.Insert(VIEW_SOURCE ":", 0); - // We can't swap() from an nsRefPtr to an nsIURI**, sadly. - nsViewSourceURI* ourURI = new nsViewSourceURI(innerURI); + // We can't swap() from an nsRefPtr to an nsIURI**, + // sadly. + nsSimpleNestedURI* ourURI = new nsSimpleNestedURI(innerURI); nsCOMPtr uri = ourURI; if (!uri) return NS_ERROR_OUT_OF_MEMORY; @@ -118,7 +115,7 @@ nsViewSourceHandler::NewURI(const nsACString &aSpec, return rv; // Make the URI immutable so it's impossible to get it out of sync - // with mInnerURI. + // with its inner URI. ourURI->SetMutable(PR_FALSE); uri.swap(*aResult); @@ -151,98 +148,3 @@ nsViewSourceHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval *_retval = PR_FALSE; 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 nest = do_QueryInterface(other); - if (nest) { - nsCOMPtr 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 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; -} diff --git a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.h b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.h index 31b7e898924..92823510136 100644 --- a/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.h +++ b/mozilla/netwerk/protocol/viewsource/src/nsViewSourceHandler.h @@ -40,9 +40,6 @@ #define nsViewSourceHandler_h___ #include "nsIProtocolHandler.h" -#include "nsCOMPtr.h" -#include "nsSimpleURI.h" -#include "nsINestedURI.h" class nsViewSourceHandler : public nsIProtocolHandler { @@ -51,50 +48,4 @@ public: 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 mInnerURI; -}; - #endif /* !defined( nsViewSourceHandler_h___ ) */ diff --git a/mozilla/xpfe/appshell/src/nsAbout.cpp b/mozilla/xpfe/appshell/src/nsAbout.cpp index 7ec470795f3..f7c18397cb3 100644 --- a/mozilla/xpfe/appshell/src/nsAbout.cpp +++ b/mozilla/xpfe/appshell/src/nsAbout.cpp @@ -77,6 +77,13 @@ nsAbout::NewChannel(nsIURI *aURI, nsIChannel **result) return rv; } +NS_IMETHODIMP +nsAbout::GetURIFlags(nsIURI *aURI, PRUint32 *result) +{ + *result = 0; + return NS_OK; +} + NS_METHOD nsAbout::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) {