|
1 <?xml version="1.0" encoding="UTF-8"?> |
|
2 |
|
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://b2g-l10n/locale/aboutCertError.dtd"> |
|
13 %certerrorDTD; |
|
14 ]> |
|
15 |
|
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://global/skin/icons/warning-64.png"/> |
|
31 |
|
32 <script type="application/javascript"><![CDATA[ |
|
33 // Error url MUST be formatted like this: |
|
34 // about:certerror?e=error&u=url&d=desc |
|
35 |
|
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. |
|
41 |
|
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 ""; |
|
49 |
|
50 // parenthetical match is the second entry |
|
51 return decodeURIComponent(matches[1]); |
|
52 } |
|
53 |
|
54 function getDescription() |
|
55 { |
|
56 var url = document.documentURI; |
|
57 var desc = url.search(/d\=/); |
|
58 |
|
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 ""; |
|
63 |
|
64 return decodeURIComponent(url.slice(desc + 2)); |
|
65 } |
|
66 |
|
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); |
|
82 |
|
83 if (getCSSClass() == "expertBadCert") { |
|
84 toggle('technicalContent'); |
|
85 toggle('expertContent'); |
|
86 } |
|
87 |
|
88 var tech = document.getElementById("technicalContentText"); |
|
89 if (tech) |
|
90 tech.textContent = getDescription(); |
|
91 |
|
92 addDomainErrorLink(); |
|
93 } |
|
94 |
|
95 /* In the case of SSL error pages about domain mismatch, see if |
|
96 we can hyperlink the user to the correct site. We don't want |
|
97 to do this generically since it allows MitM attacks to redirect |
|
98 users to a site under attacker control, but in certain cases |
|
99 it is safe (and helpful!) to do so. Bug 402210 |
|
100 */ |
|
101 function addDomainErrorLink() { |
|
102 // Rather than textContent, we need to treat description as HTML |
|
103 var sd = document.getElementById("technicalContentText"); |
|
104 if (sd) { |
|
105 var desc = getDescription(); |
|
106 |
|
107 // sanitize description text - see bug 441169 |
|
108 |
|
109 // First, find the index of the <a> tag we care about, being careful not to |
|
110 // use an over-greedy regex |
|
111 var re = /<a id="cert_domain_link" title="([^"]+)">/; |
|
112 var result = re.exec(desc); |
|
113 if(!result) |
|
114 return; |
|
115 |
|
116 // Remove sd's existing children |
|
117 sd.textContent = ""; |
|
118 |
|
119 // Everything up to the link should be text content |
|
120 sd.appendChild(document.createTextNode(desc.slice(0, result.index))); |
|
121 |
|
122 // Now create the link itself |
|
123 var anchorEl = document.createElement("a"); |
|
124 anchorEl.setAttribute("id", "cert_domain_link"); |
|
125 anchorEl.setAttribute("title", result[1]); |
|
126 anchorEl.appendChild(document.createTextNode(result[1])); |
|
127 sd.appendChild(anchorEl); |
|
128 |
|
129 // Finally, append text for anything after the closing </a> |
|
130 sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length))); |
|
131 } |
|
132 |
|
133 var link = document.getElementById('cert_domain_link'); |
|
134 if (!link) |
|
135 return; |
|
136 |
|
137 var okHost = link.getAttribute("title"); |
|
138 var thisHost = document.location.hostname; |
|
139 var proto = document.location.protocol; |
|
140 |
|
141 // If okHost is a wildcard domain ("*.example.com") let's |
|
142 // use "www" instead. "*.example.com" isn't going to |
|
143 // get anyone anywhere useful. bug 432491 |
|
144 okHost = okHost.replace(/^\*\./, "www."); |
|
145 |
|
146 /* case #1: |
|
147 * example.com uses an invalid security certificate. |
|
148 * |
|
149 * The certificate is only valid for www.example.com |
|
150 * |
|
151 * Make sure to include the "." ahead of thisHost so that |
|
152 * a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com" |
|
153 * |
|
154 * We'd normally just use a RegExp here except that we lack a |
|
155 * library function to escape them properly (bug 248062), and |
|
156 * domain names are famous for having '.' characters in them, |
|
157 * which would allow spurious and possibly hostile matches. |
|
158 */ |
|
159 if (endsWith(okHost, "." + thisHost)) |
|
160 link.href = proto + okHost; |
|
161 |
|
162 /* case #2: |
|
163 * browser.garage.maemo.org uses an invalid security certificate. |
|
164 * |
|
165 * The certificate is only valid for garage.maemo.org |
|
166 */ |
|
167 if (endsWith(thisHost, "." + okHost)) |
|
168 link.href = proto + okHost; |
|
169 |
|
170 // If we set a link, meaning there's something helpful for |
|
171 // the user here, expand the section by default |
|
172 if (link.href && getCSSClass() != "expertBadCert") |
|
173 toggle("technicalContent"); |
|
174 } |
|
175 |
|
176 function endsWith(haystack, needle) { |
|
177 return haystack.slice(-needle.length) == needle; |
|
178 } |
|
179 |
|
180 function toggle(id) { |
|
181 var el = document.getElementById(id); |
|
182 if (el.getAttribute("collapsed")) |
|
183 el.setAttribute("collapsed", false); |
|
184 else |
|
185 el.setAttribute("collapsed", true); |
|
186 } |
|
187 ]]></script> |
|
188 </head> |
|
189 |
|
190 <body id="errorPage" class="certerror" dir="&locale.dir;"> |
|
191 |
|
192 <!-- Error Title --> |
|
193 <div id="errorTitle"> |
|
194 <h1 class="errorTitleText">&certerror.longpagetitle;</h1> |
|
195 </div> |
|
196 |
|
197 <!-- PAGE CONTAINER (for styling purposes only) --> |
|
198 <div id="errorPageContainer"> |
|
199 |
|
200 <!-- LONG CONTENT (the section most likely to require scrolling) --> |
|
201 <div id="errorLongContent"> |
|
202 <div id="introContent"> |
|
203 <p id="introContentP1">&certerror.introPara1;</p> |
|
204 </div> |
|
205 |
|
206 <!-- The following sections can be unhidden by default by setting the |
|
207 "browser.xul.error_pages.expert_bad_cert" pref to true --> |
|
208 <div id="technicalContent" collapsed="true"> |
|
209 <h2 onclick="toggle('technicalContent');" id="technicalContentHeading">&certerror.technical.heading;</h2> |
|
210 <p id="technicalContentText"/> |
|
211 </div> |
|
212 |
|
213 <div id="expertContent" collapsed="true"> |
|
214 <h2 onclick="toggle('expertContent');" id="expertContentHeading">&certerror.expert.heading;</h2> |
|
215 <div> |
|
216 <p>&certerror.expert.content;</p> |
|
217 <p>&certerror.expert.contentPara2;</p> |
|
218 <button id="temporaryExceptionButton">&certerror.addTemporaryException.label;</button> |
|
219 <button id="permanentExceptionButton">&certerror.addPermanentException.label;</button> |
|
220 </div> |
|
221 </div> |
|
222 </div> |
|
223 </div> |
|
224 |
|
225 <!-- |
|
226 - Note: It is important to run the script this way, instead of using |
|
227 - an onload handler. This is because error pages are loaded as |
|
228 - LOAD_BACKGROUND, which means that onload handlers will not be executed. |
|
229 --> |
|
230 <script type="application/javascript">initPage();</script> |
|
231 |
|
232 </body> |
|
233 </html> |