Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 <?xml version="1.0" encoding="UTF-8"?>
3 <!DOCTYPE html [
4 <!ENTITY % htmlDTD
5 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
6 "DTD/xhtml1-strict.dtd">
7 %htmlDTD;
8 <!ENTITY % globalDTD
9 SYSTEM "chrome://global/locale/global.dtd">
10 %globalDTD;
11 <!ENTITY % certerrorDTD
12 SYSTEM "chrome://browser/locale/aboutCertError.dtd">
13 %certerrorDTD;
14 ]>
16 <!-- This Source Code Form is subject to the terms of the Mozilla Public
17 - License, v. 2.0. If a copy of the MPL was not distributed with this
18 - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
19 <html xmlns="http://www.w3.org/1999/xhtml">
20 <head>
21 <title>&certerror.pagetitle;</title>
22 <meta name="viewport" content="width=device-width; user-scalable=false" />
23 <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
24 <!-- This page currently uses the same favicon as neterror.xhtml.
25 If the location of the favicon is changed for both pages, the
26 FAVICON_ERRORPAGE_URL symbol in toolkit/components/places/src/nsFaviconService.h
27 should be updated. If this page starts using a different favicon
28 than neterrorm nsFaviconService->SetAndLoadFaviconForPage
29 should be updated to ignore this one as well. -->
30 <link rel="icon" type="image/png" id="favicon" sizes="64x64" href="chrome://browser/skin/images/certerror-warning.png"/>
32 <script type="application/javascript"><![CDATA[
33 // Error url MUST be formatted like this:
34 // about:certerror?e=error&u=url&d=desc
36 // Note that this file uses document.documentURI to get
37 // the URL (with the format from above). This is because
38 // document.location.href gets the current URI off the docshell,
39 // which is the URL displayed in the location bar, i.e.
40 // the URI that the user attempted to load.
42 function getCSSClass()
43 {
44 var url = document.documentURI;
45 var matches = url.match(/s\=([^&]+)\&/);
46 // s is optional, if no match just return nothing
47 if (!matches || matches.length < 2)
48 return "";
50 // parenthetical match is the second entry
51 return decodeURIComponent(matches[1]);
52 }
54 function getDescription()
55 {
56 var url = document.documentURI;
57 var desc = url.search(/d\=/);
59 // desc == -1 if not found; if so, return an empty string
60 // instead of what would turn out to be portions of the URI
61 if (desc == -1)
62 return "";
64 return decodeURIComponent(url.slice(desc + 2));
65 }
67 function initPage()
68 {
69 // Replace the "#1" string in the intro with the hostname. Trickier
70 // than it might seem since we want to preserve the <b> tags, but
71 // not allow for any injection by just using innerHTML. Instead,
72 // just find the right target text node.
73 var intro = document.getElementById('introContentP1');
74 function replaceWithHost(node) {
75 if (node.textContent == "#1")
76 node.textContent = location.host;
77 else
78 for(var i = 0; i < node.childNodes.length; i++)
79 replaceWithHost(node.childNodes[i]);
80 };
81 replaceWithHost(intro);
83 if (getCSSClass() == "expertBadCert") {
84 toggle('technicalContent');
85 toggle('expertContent');
86 }
88 // Disallow overrides if this is a Strict-Transport-Security
89 // host and the cert is bad (STS Spec section 7.3) or if the
90 // certerror is in a frame (bug 633691).
91 if (getCSSClass() == "badStsCert" || window != top)
92 document.getElementById("expertContent").setAttribute("hidden", "true");
94 var tech = document.getElementById("technicalContentText");
95 if (tech)
96 tech.textContent = getDescription();
98 addDomainErrorLink();
99 }
101 /* In the case of SSL error pages about domain mismatch, see if
102 we can hyperlink the user to the correct site. We don't want
103 to do this generically since it allows MitM attacks to redirect
104 users to a site under attacker control, but in certain cases
105 it is safe (and helpful!) to do so. Bug 402210
106 */
107 function addDomainErrorLink() {
108 // Rather than textContent, we need to treat description as HTML
109 var sd = document.getElementById("technicalContentText");
110 if (sd) {
111 var desc = getDescription();
113 // sanitize description text - see bug 441169
115 // First, find the index of the <a> tag we care about, being careful not to
116 // use an over-greedy regex
117 var re = /<a id="cert_domain_link" title="([^"]+)">/;
118 var result = re.exec(desc);
119 if(!result)
120 return;
122 // Remove sd's existing children
123 sd.textContent = "";
125 // Everything up to the link should be text content
126 sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
128 // Now create the link itself
129 var anchorEl = document.createElement("a");
130 anchorEl.setAttribute("id", "cert_domain_link");
131 anchorEl.setAttribute("title", result[1]);
132 anchorEl.appendChild(document.createTextNode(result[1]));
133 sd.appendChild(anchorEl);
135 // Finally, append text for anything after the closing </a>
136 sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length)));
137 }
139 var link = document.getElementById('cert_domain_link');
140 if (!link)
141 return;
143 var okHost = link.getAttribute("title");
144 var thisHost = document.location.hostname;
145 var proto = document.location.protocol;
147 // If okHost is a wildcard domain ("*.example.com") let's
148 // use "www" instead. "*.example.com" isn't going to
149 // get anyone anywhere useful. bug 432491
150 okHost = okHost.replace(/^\*\./, "www.");
152 /* case #1:
153 * example.com uses an invalid security certificate.
154 *
155 * The certificate is only valid for www.example.com
156 *
157 * Make sure to include the "." ahead of thisHost so that
158 * a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
159 *
160 * We'd normally just use a RegExp here except that we lack a
161 * library function to escape them properly (bug 248062), and
162 * domain names are famous for having '.' characters in them,
163 * which would allow spurious and possibly hostile matches.
164 */
165 if (endsWith(okHost, "." + thisHost))
166 link.href = proto + okHost;
168 /* case #2:
169 * browser.garage.maemo.org uses an invalid security certificate.
170 *
171 * The certificate is only valid for garage.maemo.org
172 */
173 if (endsWith(thisHost, "." + okHost))
174 link.href = proto + okHost;
176 // If we set a link, meaning there's something helpful for
177 // the user here, expand the section by default
178 if (link.href && getCSSClass() != "expertBadCert")
179 toggle("technicalContent");
180 }
182 function endsWith(haystack, needle) {
183 return haystack.slice(-needle.length) == needle;
184 }
186 function toggle(id) {
187 var el = document.getElementById(id);
188 if (el.hasAttribute("collapsed"))
189 el.removeAttribute("collapsed");
190 else
191 el.setAttribute("collapsed", true);
192 }
193 ]]></script>
194 </head>
196 <body id="errorPage" class="certerror" dir="&locale.dir;">
198 <!-- PAGE CONTAINER (for styling purposes only) -->
199 <div id="errorPageContainer">
201 <!-- Error Title -->
202 <div id="errorTitle">
203 <h1 class="errorTitleText">&certerror.longpagetitle;</h1>
204 </div>
206 <!-- LONG CONTENT (the section most likely to require scrolling) -->
207 <div id="errorLongContent">
208 <div id="introContent">
209 <p id="introContentP1">&certerror.introPara1;</p>
210 </div>
212 <div id="whatShouldIDoContent">
213 <h2>&certerror.whatShouldIDo.heading;</h2>
214 <div id="whatShouldIDoContentText">
215 <p>&certerror.whatShouldIDo.content;</p>
216 <button id="getMeOutOfHereButton">&certerror.getMeOutOfHere.label;</button>
217 </div>
218 </div>
220 <!-- The following sections can be unhidden by default by setting the
221 "browser.xul.error_pages.expert_bad_cert" pref to true -->
222 <div id="technicalContent" collapsed="true">
223 <h2 class="expander" onclick="toggle('technicalContent');" id="technicalContentHeading">&certerror.technical.heading;</h2>
224 <p id="technicalContentText"/>
225 </div>
227 <div id="expertContent" collapsed="true">
228 <h2 class="expander" onclick="toggle('expertContent');" id="expertContentHeading">&certerror.expert.heading;</h2>
229 <div>
230 <p>&certerror.expert.content;</p>
231 <p>&certerror.expert.contentPara2;</p>
232 <button id="temporaryExceptionButton">&certerror.addTemporaryException.label;</button>
233 <button id="permanentExceptionButton">&certerror.addPermanentException.label;</button>
234 </div>
235 </div>
236 </div>
237 </div>
239 <!--
240 - Note: It is important to run the script this way, instead of using
241 - an onload handler. This is because error pages are loaded as
242 - LOAD_BACKGROUND, which means that onload handlers will not be executed.
243 -->
244 <script type="application/javascript">initPage();</script>
246 </body>
247 </html>