|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* vim:set ts=4 sw=4 sts=4 et cindent: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "nsAboutRedirector.h" |
|
8 #include "nsNetUtil.h" |
|
9 #include "nsAboutProtocolUtils.h" |
|
10 #include "mozilla/ArrayUtils.h" |
|
11 |
|
12 NS_IMPL_ISUPPORTS(nsAboutRedirector, nsIAboutModule) |
|
13 |
|
14 struct RedirEntry { |
|
15 const char* id; |
|
16 const char* url; |
|
17 uint32_t flags; |
|
18 }; |
|
19 |
|
20 /* |
|
21 Entries which do not have URI_SAFE_FOR_UNTRUSTED_CONTENT will run with chrome |
|
22 privileges. This is potentially dangerous. Please use |
|
23 URI_SAFE_FOR_UNTRUSTED_CONTENT in the third argument to each map item below |
|
24 unless your about: page really needs chrome privileges. Security review is |
|
25 required before adding new map entries without |
|
26 URI_SAFE_FOR_UNTRUSTED_CONTENT. Also note, however, that adding |
|
27 URI_SAFE_FOR_UNTRUSTED_CONTENT will allow random web sites to link to that |
|
28 URI. Perhaps we should separate the two concepts out... |
|
29 */ |
|
30 static RedirEntry kRedirMap[] = { |
|
31 { "", "chrome://global/content/about.xhtml", |
|
32 nsIAboutModule::ALLOW_SCRIPT }, |
|
33 { "about", "chrome://global/content/aboutAbout.xhtml", 0 }, |
|
34 { "credits", "http://www.mozilla.org/credits/", |
|
35 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, |
|
36 { "mozilla", "chrome://global/content/mozilla.xhtml", |
|
37 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, |
|
38 { "plugins", "chrome://global/content/plugins.html", 0 }, |
|
39 { "config", "chrome://global/content/config.xul", 0 }, |
|
40 #ifdef MOZ_CRASHREPORTER |
|
41 { "crashes", "chrome://global/content/crashes.xhtml", 0 }, |
|
42 #endif |
|
43 { "logo", "chrome://branding/content/about.png", |
|
44 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT}, |
|
45 { "buildconfig", "chrome://global/content/buildconfig.html", |
|
46 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, |
|
47 { "license", "chrome://global/content/license.html", |
|
48 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, |
|
49 { "neterror", "chrome://global/content/netError.xhtml", |
|
50 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
51 nsIAboutModule::ALLOW_SCRIPT | |
|
52 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
53 { "compartments", "chrome://global/content/aboutCompartments.xhtml", |
|
54 nsIAboutModule::ALLOW_SCRIPT | |
|
55 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
56 { "memory", "chrome://global/content/aboutMemory.xhtml", |
|
57 nsIAboutModule::ALLOW_SCRIPT }, |
|
58 { "addons", "chrome://mozapps/content/extensions/extensions.xul", |
|
59 nsIAboutModule::ALLOW_SCRIPT }, |
|
60 { "newaddon", "chrome://mozapps/content/extensions/newaddon.xul", |
|
61 nsIAboutModule::ALLOW_SCRIPT | |
|
62 nsIAboutModule::HIDE_FROM_ABOUTABOUT }, |
|
63 { "support", "chrome://global/content/aboutSupport.xhtml", |
|
64 nsIAboutModule::ALLOW_SCRIPT }, |
|
65 { "telemetry", "chrome://global/content/aboutTelemetry.xhtml", |
|
66 nsIAboutModule::ALLOW_SCRIPT }, |
|
67 { "networking", "chrome://global/content/aboutNetworking.xhtml", |
|
68 nsIAboutModule::ALLOW_SCRIPT }, |
|
69 { "webrtc", "chrome://global/content/aboutWebrtc.xhtml", |
|
70 nsIAboutModule::ALLOW_SCRIPT }, |
|
71 // about:srcdoc is unresolvable by specification. It is included here |
|
72 // because the security manager would disallow srcdoc iframes otherwise. |
|
73 { "srcdoc", "about:blank", |
|
74 nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | |
|
75 nsIAboutModule::HIDE_FROM_ABOUTABOUT } |
|
76 }; |
|
77 static const int kRedirTotal = mozilla::ArrayLength(kRedirMap); |
|
78 |
|
79 NS_IMETHODIMP |
|
80 nsAboutRedirector::NewChannel(nsIURI *aURI, nsIChannel **result) |
|
81 { |
|
82 NS_ENSURE_ARG_POINTER(aURI); |
|
83 NS_ASSERTION(result, "must not be null"); |
|
84 |
|
85 nsresult rv; |
|
86 |
|
87 nsAutoCString path; |
|
88 rv = NS_GetAboutModuleName(aURI, path); |
|
89 if (NS_FAILED(rv)) |
|
90 return rv; |
|
91 |
|
92 nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv); |
|
93 if (NS_FAILED(rv)) |
|
94 return rv; |
|
95 |
|
96 for (int i=0; i<kRedirTotal; i++) |
|
97 { |
|
98 if (!strcmp(path.get(), kRedirMap[i].id)) |
|
99 { |
|
100 nsCOMPtr<nsIChannel> tempChannel; |
|
101 rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), |
|
102 nullptr, nullptr, getter_AddRefs(tempChannel)); |
|
103 if (NS_FAILED(rv)) |
|
104 return rv; |
|
105 |
|
106 tempChannel->SetOriginalURI(aURI); |
|
107 |
|
108 NS_ADDREF(*result = tempChannel); |
|
109 return rv; |
|
110 } |
|
111 } |
|
112 |
|
113 NS_ERROR("nsAboutRedirector called for unknown case"); |
|
114 return NS_ERROR_ILLEGAL_VALUE; |
|
115 } |
|
116 |
|
117 NS_IMETHODIMP |
|
118 nsAboutRedirector::GetURIFlags(nsIURI *aURI, uint32_t *result) |
|
119 { |
|
120 NS_ENSURE_ARG_POINTER(aURI); |
|
121 |
|
122 nsAutoCString name; |
|
123 nsresult rv = NS_GetAboutModuleName(aURI, name); |
|
124 NS_ENSURE_SUCCESS(rv, rv); |
|
125 |
|
126 for (int i=0; i < kRedirTotal; i++) |
|
127 { |
|
128 if (name.EqualsASCII(kRedirMap[i].id)) |
|
129 { |
|
130 *result = kRedirMap[i].flags; |
|
131 return NS_OK; |
|
132 } |
|
133 } |
|
134 |
|
135 NS_ERROR("nsAboutRedirector called for unknown case"); |
|
136 return NS_ERROR_ILLEGAL_VALUE; |
|
137 } |
|
138 |
|
139 nsresult |
|
140 nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) |
|
141 { |
|
142 nsAboutRedirector* about = new nsAboutRedirector(); |
|
143 if (about == nullptr) |
|
144 return NS_ERROR_OUT_OF_MEMORY; |
|
145 NS_ADDREF(about); |
|
146 nsresult rv = about->QueryInterface(aIID, aResult); |
|
147 NS_RELEASE(about); |
|
148 return rv; |
|
149 } |