Back to index

lightning-sunbird  0.9+nobinonly
nsAboutRedirector.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* vim:set ts=4 sw=4 sts=4 et cindent: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Gagan Saksena (original author)
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsAboutProtocolHandler.h"
00041 #include "nsAboutRedirector.h"
00042 #include "nsNetUtil.h"
00043 #include "plstr.h"
00044 #include "nsIScriptSecurityManager.h"
00045 #include "nsAboutProtocolUtils.h"
00046 
00047 NS_IMPL_ISUPPORTS1(nsAboutRedirector, nsIAboutModule)
00048 
00049 struct RedirEntry {
00050     const char* id;
00051     const char* url;
00052     PRBool dropChromePrivs; // if PR_TRUE, the page will not have chrome privileges
00053 };
00054 
00055 /*
00056   Entries with dropChromePrivs == PR_FALSE will run with chrome
00057   privileges. This is potentially dangerous. Please use PR_TRUE
00058   as the third argument to each map item below unless your about:
00059   page really needs chrome privileges. Security review is required
00060   before adding new map entries with dropChromePrivs == PR_FALSE.
00061  */
00062 static RedirEntry kRedirMap[] = {
00063     { "credits", "http://www.mozilla.org/credits/", PR_TRUE },
00064     { "mozilla", "chrome://global/content/mozilla.xhtml", PR_TRUE },
00065     { "plugins", "chrome://global/content/plugins.html", PR_FALSE },
00066     { "config", "chrome://global/content/config.xul", PR_FALSE },
00067     { "logo", "chrome://global/content/logo.gif", PR_TRUE },
00068     { "buildconfig", "chrome://global/content/buildconfig.html", PR_TRUE },
00069     { "license", "chrome://global/content/license.html", PR_TRUE },
00070     { "licence", "chrome://global/content/license.html", PR_TRUE },
00071     { "about", "chrome://global/content/aboutAbout.html", PR_FALSE },
00072     { "neterror", "chrome://global/content/netError.xhtml", PR_TRUE }
00073 };
00074 static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
00075 
00076 NS_IMETHODIMP
00077 nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result)
00078 {
00079     NS_ENSURE_ARG_POINTER(aURI);
00080     NS_ASSERTION(result, "must not be null");
00081 
00082     nsresult rv;
00083 
00084     nsCAutoString path;
00085     rv = NS_GetAboutModuleName(aURI, path);
00086     if (NS_FAILED(rv))
00087         return rv;
00088 
00089     nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
00090     if (NS_FAILED(rv))
00091         return rv;
00092 
00093     for (int i=0; i<kRedirTotal; i++) 
00094     {
00095         if (!strcmp(path.get(), kRedirMap[i].id))
00096         {
00097             nsCOMPtr<nsIChannel> tempChannel;
00098             rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url),
00099                                        nsnull, nsnull, getter_AddRefs(tempChannel));
00100             if (NS_FAILED(rv))
00101                 return rv;
00102 
00103             tempChannel->SetOriginalURI(aURI);
00104 
00105             // Keep the page from getting unnecessary privileges unless it needs them
00106             if (kRedirMap[i].dropChromePrivs)
00107             {
00108                 nsCOMPtr<nsIScriptSecurityManager> securityManager = 
00109                          do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
00110                 if (NS_FAILED(rv))
00111                     return rv;
00112             
00113                 nsCOMPtr<nsIPrincipal> principal;
00114                 rv = securityManager->GetCodebasePrincipal(aURI, getter_AddRefs(principal));
00115                 if (NS_FAILED(rv))
00116                     return rv;
00117             
00118                 rv = tempChannel->SetOwner(principal);
00119                 if (NS_FAILED(rv))
00120                     return rv;
00121             }
00122 
00123             NS_ADDREF(*result = tempChannel);
00124             return rv;
00125         }
00126     }
00127 
00128     NS_ERROR("nsAboutRedirector called for unknown case");
00129     return NS_ERROR_ILLEGAL_VALUE;
00130 }
00131 
00132 NS_METHOD
00133 nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
00134 {
00135     nsAboutRedirector* about = new nsAboutRedirector();
00136     if (about == nsnull)
00137         return NS_ERROR_OUT_OF_MEMORY;
00138     NS_ADDREF(about);
00139     nsresult rv = about->QueryInterface(aIID, aResult);
00140     NS_RELEASE(about);
00141     return rv;
00142 }