richard pushed to branch tor-browser-115.2.1esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
de6b3303
by Henry Wilkes at 2023-09-19T01:24:50+00:00
-
1a422b66
by Henry Wilkes at 2023-09-19T01:24:50+00:00
-
7c864096
by Henry Wilkes at 2023-09-19T01:24:50+00:00
-
6662e2dd
by Henry Wilkes at 2023-09-19T01:24:50+00:00
-
d66b44eb
by Henry Wilkes at 2023-09-19T01:24:50+00:00
-
6f0199ab
by Henry Wilkes at 2023-09-19T01:24:50+00:00
10 changed files:
- browser/base/content/browser-siteIdentity.js
- browser/base/content/browser.js
- browser/components/onionservices/content/authPreferences.js
- browser/components/onionservices/content/authPrompt.js
- − browser/components/onionservices/content/authUtil.jsm
- browser/components/onionservices/jar.mn
- browser/components/torcircuit/content/torCircuitPanel.js
- browser/modules/TorStrings.jsm
- + browser/modules/TorUIUtils.sys.mjs
- browser/modules/moz.build
Changes:
... | ... | @@ -729,7 +729,15 @@ var gIdentityHandler = { |
729 | 729 | host = this._uri.specIgnoringRef;
|
730 | 730 | }
|
731 | 731 | |
732 | - return host;
|
|
732 | + // For tor browser we want to shorten onion addresses for the site identity
|
|
733 | + // panel (gIdentityHandler) to match the circuit display and the onion
|
|
734 | + // authorization panel.
|
|
735 | + // See tor-browser#42091 and tor-browser#41600.
|
|
736 | + // This will also shorten addresses for other consumers of this method,
|
|
737 | + // which includes the permissions panel (gPermissionPanel) and the
|
|
738 | + // protections panel (gProtectionsHandler), although the latter is hidden in
|
|
739 | + // tor browser.
|
|
740 | + return TorUIUtils.shortenOnionAddress(host);
|
|
733 | 741 | },
|
734 | 742 | |
735 | 743 | /**
|
... | ... | @@ -67,6 +67,7 @@ ChromeUtils.defineESModuleGetters(this, { |
67 | 67 | "resource:///modules/firefox-view-tabs-setup-manager.sys.mjs",
|
68 | 68 | TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs",
|
69 | 69 | TorDomainIsolator: "resource://gre/modules/TorDomainIsolator.sys.mjs",
|
70 | + TorUIUtils: "resource:///modules/TorUIUtils.sys.mjs",
|
|
70 | 71 | TranslationsParent: "resource://gre/actors/TranslationsParent.sys.mjs",
|
71 | 72 | UITour: "resource:///modules/UITour.sys.mjs",
|
72 | 73 | UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",
|
... | ... | @@ -42,10 +42,11 @@ const OnionServicesAuthPreferences = { |
42 | 42 | |
43 | 43 | elem = groupbox.querySelector(this.selector.learnMore);
|
44 | 44 | elem.setAttribute("value", TorStrings.onionServices.learnMore);
|
45 | - elem.setAttribute("href", TorStrings.onionServices.learnMoreURL);
|
|
46 | - if (TorStrings.onionServices.learnMoreURL.startsWith("about:")) {
|
|
47 | - elem.setAttribute("useoriginprincipal", "true");
|
|
48 | - }
|
|
45 | + elem.setAttribute(
|
|
46 | + "href",
|
|
47 | + "about:manual#onion-services_onion-service-authentication"
|
|
48 | + );
|
|
49 | + elem.setAttribute("useoriginprincipal", "true");
|
|
49 | 50 | |
50 | 51 | elem = groupbox.querySelector(this.selector.savedKeysButton);
|
51 | 52 | elem.setAttribute(
|
1 | -// Copyright (c) 2020, The Tor Project, Inc.
|
|
1 | +/* eslint-env mozilla/browser-window */
|
|
2 | 2 | |
3 | 3 | "use strict";
|
4 | 4 | |
5 | -/* globals gBrowser, PopupNotifications, Services, XPCOMUtils */
|
|
6 | - |
|
7 | -ChromeUtils.defineESModuleGetters(this, {
|
|
8 | - TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
9 | -});
|
|
10 | - |
|
11 | -XPCOMUtils.defineLazyModuleGetters(this, {
|
|
12 | - OnionAuthUtil: "chrome://browser/content/onionservices/authUtil.jsm",
|
|
13 | - CommonUtils: "resource://services-common/utils.js",
|
|
14 | - TorStrings: "resource:///modules/TorStrings.jsm",
|
|
15 | -});
|
|
16 | - |
|
17 | 5 | const OnionAuthPrompt = (function () {
|
6 | + // Only import to our internal scope, rather than the global scope of
|
|
7 | + // browser.xhtml.
|
|
8 | + const lazy = {};
|
|
9 | + ChromeUtils.defineESModuleGetters(lazy, {
|
|
10 | + TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
11 | + CommonUtils: "resource://services-common/utils.sys.mjs",
|
|
12 | + });
|
|
13 | + XPCOMUtils.defineLazyModuleGetters(lazy, {
|
|
14 | + TorStrings: "resource:///modules/TorStrings.jsm",
|
|
15 | + });
|
|
16 | + |
|
18 | 17 | // OnionServicesAuthPrompt objects run within the main/chrome process.
|
19 | 18 | // aReason is the topic passed within the observer notification that is
|
20 | 19 | // causing this auth prompt to be displayed.
|
... | ... | @@ -25,11 +24,16 @@ const OnionAuthPrompt = (function () { |
25 | 24 | this._onionHostname = aOnionName;
|
26 | 25 | }
|
27 | 26 | |
27 | + const topics = {
|
|
28 | + clientAuthMissing: "tor-onion-services-clientauth-missing",
|
|
29 | + clientAuthIncorrect: "tor-onion-services-clientauth-incorrect",
|
|
30 | + };
|
|
31 | + |
|
28 | 32 | OnionServicesAuthPrompt.prototype = {
|
29 | 33 | show(aWarningMessage) {
|
30 | 34 | let mainAction = {
|
31 | - label: TorStrings.onionServices.authPrompt.done,
|
|
32 | - accessKey: TorStrings.onionServices.authPrompt.doneAccessKey,
|
|
35 | + label: lazy.TorStrings.onionServices.authPrompt.done,
|
|
36 | + accessKey: lazy.TorStrings.onionServices.authPrompt.doneAccessKey,
|
|
33 | 37 | leaveOpen: true, // Callback is responsible for closing the notification.
|
34 | 38 | callback: this._onDone.bind(this),
|
35 | 39 | };
|
... | ... | @@ -68,9 +72,9 @@ const OnionAuthPrompt = (function () { |
68 | 72 | |
69 | 73 | this._prompt = PopupNotifications.show(
|
70 | 74 | this._browser,
|
71 | - OnionAuthUtil.domid.notification,
|
|
75 | + "tor-clientauth",
|
|
72 | 76 | "",
|
73 | - OnionAuthUtil.domid.anchor,
|
|
77 | + "tor-clientauth-notification-icon",
|
|
74 | 78 | mainAction,
|
75 | 79 | [cancelAction],
|
76 | 80 | options
|
... | ... | @@ -79,52 +83,38 @@ const OnionAuthPrompt = (function () { |
79 | 83 | |
80 | 84 | _onPromptShowing(aWarningMessage) {
|
81 | 85 | let xulDoc = this._browser.ownerDocument;
|
82 | - let descElem = xulDoc.getElementById(OnionAuthUtil.domid.description);
|
|
86 | + let descElem = xulDoc.getElementById("tor-clientauth-notification-desc");
|
|
83 | 87 | if (descElem) {
|
84 | 88 | // Handle replacement of the onion name within the localized
|
85 | 89 | // string ourselves so we can show the onion name as bold text.
|
86 | 90 | // We do this by splitting the localized string and creating
|
87 | 91 | // several HTML <span> elements.
|
88 | - while (descElem.firstChild) {
|
|
89 | - descElem.firstChild.remove();
|
|
90 | - }
|
|
92 | + const fmtString = lazy.TorStrings.onionServices.authPrompt.description;
|
|
93 | + const [prefix, suffix] = fmtString.split("%S");
|
|
91 | 94 | |
92 | - let fmtString = TorStrings.onionServices.authPrompt.description;
|
|
93 | - let prefix = "";
|
|
94 | - let suffix = "";
|
|
95 | - const kToReplace = "%S";
|
|
96 | - let idx = fmtString.indexOf(kToReplace);
|
|
97 | - if (idx < 0) {
|
|
98 | - prefix = fmtString;
|
|
99 | - } else {
|
|
100 | - prefix = fmtString.substring(0, idx);
|
|
101 | - suffix = fmtString.substring(idx + kToReplace.length);
|
|
102 | - }
|
|
95 | + const domainEl = xulDoc.createElement("span");
|
|
96 | + domainEl.id = "tor-clientauth-notification-onionname";
|
|
97 | + domainEl.textContent = TorUIUtils.shortenOnionAddress(
|
|
98 | + this._onionHostname
|
|
99 | + );
|
|
103 | 100 | |
104 | - const kHTMLNS = "http://www.w3.org/1999/xhtml";
|
|
105 | - let span = xulDoc.createElementNS(kHTMLNS, "span");
|
|
106 | - span.textContent = prefix;
|
|
107 | - descElem.appendChild(span);
|
|
108 | - span = xulDoc.createElementNS(kHTMLNS, "span");
|
|
109 | - span.id = OnionAuthUtil.domid.onionNameSpan;
|
|
110 | - span.textContent = this._onionHostname;
|
|
111 | - descElem.appendChild(span);
|
|
112 | - span = xulDoc.createElementNS(kHTMLNS, "span");
|
|
113 | - span.textContent = suffix;
|
|
114 | - descElem.appendChild(span);
|
|
101 | + descElem.replaceChildren(prefix, domainEl, suffix);
|
|
115 | 102 | }
|
116 | 103 | |
117 | 104 | // Set "Learn More" label and href.
|
118 | - let learnMoreElem = xulDoc.getElementById(OnionAuthUtil.domid.learnMore);
|
|
105 | + let learnMoreElem = xulDoc.getElementById(
|
|
106 | + "tor-clientauth-notification-learnmore"
|
|
107 | + );
|
|
119 | 108 | if (learnMoreElem) {
|
120 | - learnMoreElem.setAttribute("value", TorStrings.onionServices.learnMore);
|
|
109 | + learnMoreElem.setAttribute(
|
|
110 | + "value",
|
|
111 | + lazy.TorStrings.onionServices.learnMore
|
|
112 | + );
|
|
121 | 113 | learnMoreElem.setAttribute(
|
122 | 114 | "href",
|
123 | - TorStrings.onionServices.learnMoreURL
|
|
115 | + "about:manual#onion-services_onion-service-authentication"
|
|
124 | 116 | );
|
125 | - if (TorStrings.onionServices.learnMoreURL.startsWith("about:")) {
|
|
126 | - learnMoreElem.setAttribute("useoriginprincipal", "true");
|
|
127 | - }
|
|
117 | + learnMoreElem.setAttribute("useoriginprincipal", "true");
|
|
128 | 118 | }
|
129 | 119 | |
130 | 120 | this._showWarning(aWarningMessage);
|
... | ... | @@ -139,7 +129,7 @@ const OnionAuthPrompt = (function () { |
139 | 129 | if (keyElem) {
|
140 | 130 | keyElem.setAttribute(
|
141 | 131 | "placeholder",
|
142 | - TorStrings.onionServices.authPrompt.keyPlaceholder
|
|
132 | + lazy.TorStrings.onionServices.authPrompt.keyPlaceholder
|
|
143 | 133 | );
|
144 | 134 | this._boundOnKeyFieldKeyPress = this._onKeyFieldKeyPress.bind(this);
|
145 | 135 | this._boundOnKeyFieldInput = this._onKeyFieldInput.bind(this);
|
... | ... | @@ -186,14 +176,14 @@ const OnionAuthPrompt = (function () { |
186 | 176 | |
187 | 177 | const base64key = this._keyToBase64(keyElem.value);
|
188 | 178 | if (!base64key) {
|
189 | - this._showWarning(TorStrings.onionServices.authPrompt.invalidKey);
|
|
179 | + this._showWarning(lazy.TorStrings.onionServices.authPrompt.invalidKey);
|
|
190 | 180 | return;
|
191 | 181 | }
|
192 | 182 | |
193 | 183 | this._prompt.remove();
|
194 | 184 | |
195 | 185 | const controllerFailureMsg =
|
196 | - TorStrings.onionServices.authPrompt.failedToSetKey;
|
|
186 | + lazy.TorStrings.onionServices.authPrompt.failedToSetKey;
|
|
197 | 187 | try {
|
198 | 188 | // ^(subdomain.)*onionserviceid.onion$ (case-insensitive)
|
199 | 189 | const onionServiceIdRegExp =
|
... | ... | @@ -205,7 +195,7 @@ const OnionAuthPrompt = (function () { |
205 | 195 | |
206 | 196 | const checkboxElem = this._getCheckboxElement();
|
207 | 197 | const isPermanent = checkboxElem && checkboxElem.checked;
|
208 | - const provider = await TorProviderBuilder.build();
|
|
198 | + const provider = await lazy.TorProviderBuilder.build();
|
|
209 | 199 | await provider.onionAuthAdd(onionServiceId, base64key, isPermanent);
|
210 | 200 | // Success! Reload the page.
|
211 | 201 | this._browser.sendMessageToActor("Browser:Reload", {}, "BrowserTab");
|
... | ... | @@ -227,7 +217,7 @@ const OnionAuthPrompt = (function () { |
227 | 217 | // this authentication prompt.
|
228 | 218 | const failedURI = this._failedURI.spec;
|
229 | 219 | const errorCode =
|
230 | - this._reasonForPrompt === OnionAuthUtil.topic.clientAuthMissing
|
|
220 | + this._reasonForPrompt === topics.clientAuthMissing
|
|
231 | 221 | ? Cr.NS_ERROR_TOR_ONION_SVC_MISSING_CLIENT_AUTH
|
232 | 222 | : Cr.NS_ERROR_TOR_ONION_SVC_BAD_CLIENT_AUTH;
|
233 | 223 | const io =
|
... | ... | @@ -245,19 +235,17 @@ const OnionAuthPrompt = (function () { |
245 | 235 | |
246 | 236 | _getKeyElement() {
|
247 | 237 | let xulDoc = this._browser.ownerDocument;
|
248 | - return xulDoc.getElementById(OnionAuthUtil.domid.keyElement);
|
|
238 | + return xulDoc.getElementById("tor-clientauth-notification-key");
|
|
249 | 239 | },
|
250 | 240 | |
251 | 241 | _getCheckboxElement() {
|
252 | 242 | let xulDoc = this._browser.ownerDocument;
|
253 | - return xulDoc.getElementById(OnionAuthUtil.domid.checkboxElement);
|
|
243 | + return xulDoc.getElementById("tor-clientauth-persistkey-checkbox");
|
|
254 | 244 | },
|
255 | 245 | |
256 | 246 | _showWarning(aWarningMessage) {
|
257 | 247 | let xulDoc = this._browser.ownerDocument;
|
258 | - let warningElem = xulDoc.getElementById(
|
|
259 | - OnionAuthUtil.domid.warningElement
|
|
260 | - );
|
|
248 | + let warningElem = xulDoc.getElementById("tor-clientauth-warning");
|
|
261 | 249 | let keyElem = this._getKeyElement();
|
262 | 250 | if (warningElem) {
|
263 | 251 | if (aWarningMessage) {
|
... | ... | @@ -289,7 +277,7 @@ const OnionAuthPrompt = (function () { |
289 | 277 | // a tor onion-auth file (which uses lowercase).
|
290 | 278 | let rawKey;
|
291 | 279 | try {
|
292 | - rawKey = CommonUtils.decodeBase32(aKeyString.toUpperCase());
|
|
280 | + rawKey = lazy.CommonUtils.decodeBase32(aKeyString.toUpperCase());
|
|
293 | 281 | } catch (e) {}
|
294 | 282 | |
295 | 283 | if (rawKey) {
|
... | ... | @@ -313,24 +301,21 @@ const OnionAuthPrompt = (function () { |
313 | 301 | |
314 | 302 | let retval = {
|
315 | 303 | init() {
|
316 | - Services.obs.addObserver(this, OnionAuthUtil.topic.clientAuthMissing);
|
|
317 | - Services.obs.addObserver(this, OnionAuthUtil.topic.clientAuthIncorrect);
|
|
304 | + Services.obs.addObserver(this, topics.clientAuthMissing);
|
|
305 | + Services.obs.addObserver(this, topics.clientAuthIncorrect);
|
|
318 | 306 | },
|
319 | 307 | |
320 | 308 | uninit() {
|
321 | - Services.obs.removeObserver(this, OnionAuthUtil.topic.clientAuthMissing);
|
|
322 | - Services.obs.removeObserver(
|
|
323 | - this,
|
|
324 | - OnionAuthUtil.topic.clientAuthIncorrect
|
|
325 | - );
|
|
309 | + Services.obs.removeObserver(this, topics.clientAuthMissing);
|
|
310 | + Services.obs.removeObserver(this, topics.clientAuthIncorrect);
|
|
326 | 311 | },
|
327 | 312 | |
328 | 313 | // aSubject is the DOM Window or browser where the prompt should be shown.
|
329 | 314 | // aData contains the .onion name.
|
330 | 315 | observe(aSubject, aTopic, aData) {
|
331 | 316 | if (
|
332 | - aTopic != OnionAuthUtil.topic.clientAuthMissing &&
|
|
333 | - aTopic != OnionAuthUtil.topic.clientAuthIncorrect
|
|
317 | + aTopic != topics.clientAuthMissing &&
|
|
318 | + aTopic != topics.clientAuthIncorrect
|
|
334 | 319 | ) {
|
335 | 320 | return;
|
336 | 321 | }
|
1 | -// Copyright (c) 2020, The Tor Project, Inc.
|
|
2 | - |
|
3 | -"use strict";
|
|
4 | - |
|
5 | -var EXPORTED_SYMBOLS = ["OnionAuthUtil"];
|
|
6 | - |
|
7 | -const OnionAuthUtil = {
|
|
8 | - topic: {
|
|
9 | - clientAuthMissing: "tor-onion-services-clientauth-missing",
|
|
10 | - clientAuthIncorrect: "tor-onion-services-clientauth-incorrect",
|
|
11 | - },
|
|
12 | - message: {
|
|
13 | - authPromptCanceled: "Tor:OnionServicesAuthPromptCanceled",
|
|
14 | - },
|
|
15 | - domid: {
|
|
16 | - anchor: "tor-clientauth-notification-icon",
|
|
17 | - notification: "tor-clientauth",
|
|
18 | - description: "tor-clientauth-notification-desc",
|
|
19 | - learnMore: "tor-clientauth-notification-learnmore",
|
|
20 | - onionNameSpan: "tor-clientauth-notification-onionname",
|
|
21 | - keyElement: "tor-clientauth-notification-key",
|
|
22 | - warningElement: "tor-clientauth-warning",
|
|
23 | - checkboxElement: "tor-clientauth-persistkey-checkbox",
|
|
24 | - },
|
|
25 | -}; |
... | ... | @@ -2,7 +2,6 @@ browser.jar: |
2 | 2 | content/browser/onionservices/authPreferences.css (content/authPreferences.css)
|
3 | 3 | content/browser/onionservices/authPreferences.js (content/authPreferences.js)
|
4 | 4 | content/browser/onionservices/authPrompt.js (content/authPrompt.js)
|
5 | - content/browser/onionservices/authUtil.jsm (content/authUtil.jsm)
|
|
6 | 5 | content/browser/onionservices/netError/ (content/netError/*)
|
7 | 6 | content/browser/onionservices/onionservices.css (content/onionservices.css)
|
8 | 7 | content/browser/onionservices/savedKeysDialog.js (content/savedKeysDialog.js)
|
... | ... | @@ -408,21 +408,6 @@ var gTorCircuitPanel = { |
408 | 408 | return this._fallbackStringBundle.formatStringFromName(name, args);
|
409 | 409 | },
|
410 | 410 | |
411 | - /**
|
|
412 | - * Shorten the given address if it is an onion address.
|
|
413 | - *
|
|
414 | - * @param {string} address - The address to shorten.
|
|
415 | - *
|
|
416 | - * @returns {string} The shortened form of the address, or the address itself
|
|
417 | - * if it was not shortened.
|
|
418 | - */
|
|
419 | - _shortenOnionAddress(address) {
|
|
420 | - if (!address.endsWith(".onion") || address.length <= 22) {
|
|
421 | - return address;
|
|
422 | - }
|
|
423 | - return `${address.slice(0, 7)}…${address.slice(-12)}`;
|
|
424 | - },
|
|
425 | - |
|
426 | 411 | /**
|
427 | 412 | * Updates the circuit display in the panel to show the current browser data.
|
428 | 413 | */
|
... | ... | @@ -465,12 +450,12 @@ var gTorCircuitPanel = { |
465 | 450 | this._panelElements.heading.textContent = this._getString(
|
466 | 451 | "torbutton.circuit_display.heading",
|
467 | 452 | // Only shorten the onion domain if it has no alias.
|
468 | - [onionAlias ? domain : this._shortenOnionAddress(domain)]
|
|
453 | + [TorUIUtils.shortenOnionAddress(domain)]
|
|
469 | 454 | );
|
470 | 455 | |
471 | 456 | if (onionAlias) {
|
472 | 457 | this._panelElements.aliasLink.textContent =
|
473 | - this._shortenOnionAddress(onionAlias);
|
|
458 | + TorUIUtils.shortenOnionAddress(onionAlias);
|
|
474 | 459 | if (scheme === "http" || scheme === "https") {
|
475 | 460 | // We assume the same scheme as the current page for the alias, which we
|
476 | 461 | // expect to be either http or https.
|
... | ... | @@ -521,7 +506,8 @@ var gTorCircuitPanel = { |
521 | 506 | );
|
522 | 507 | |
523 | 508 | // Set the address that we want to copy.
|
524 | - this._panelElements.endItem.textContent = this._shortenOnionAddress(domain);
|
|
509 | + this._panelElements.endItem.textContent =
|
|
510 | + TorUIUtils.shortenOnionAddress(domain);
|
|
525 | 511 | |
526 | 512 | // Button description text, depending on whether our first node was a
|
527 | 513 | // bridge, or otherwise a guard.
|
... | ... | @@ -300,7 +300,6 @@ const Loader = { |
300 | 300 | |
301 | 301 | const retval = {
|
302 | 302 | learnMore: getString("learnMore", "Learn more"),
|
303 | - learnMoreURL: "about:manual#onion-services_onion-service-authentication",
|
|
304 | 303 | errorPage: {
|
305 | 304 | browser: getString("errorPage.browser", "Browser"),
|
306 | 305 | network: getString("errorPage.network", "Network"),
|
1 | +/**
|
|
2 | + * Common methods for tor UI components.
|
|
3 | + */
|
|
4 | +export const TorUIUtils = {
|
|
5 | + /**
|
|
6 | + * Shorten the given address if it is an onion address.
|
|
7 | + *
|
|
8 | + * @param {string} address - The address to shorten.
|
|
9 | + *
|
|
10 | + * @returns {string} The shortened form of the address, or the address itself
|
|
11 | + * if it was not shortened.
|
|
12 | + */
|
|
13 | + shortenOnionAddress(address) {
|
|
14 | + if (
|
|
15 | + // Only shorten ".onion" addresses.
|
|
16 | + !address.endsWith(".onion") ||
|
|
17 | + // That are not "onion" aliases.
|
|
18 | + address.endsWith(".tor.onion") ||
|
|
19 | + // And are long.
|
|
20 | + address.length <= 21
|
|
21 | + ) {
|
|
22 | + return address;
|
|
23 | + }
|
|
24 | + return `${address.slice(0, 6)}…${address.slice(-12)}`;
|
|
25 | + },
|
|
26 | +}; |
... | ... | @@ -152,6 +152,7 @@ EXTRA_JS_MODULES += [ |
152 | 152 | "TorConnect.sys.mjs",
|
153 | 153 | "TorSettings.sys.mjs",
|
154 | 154 | "TorStrings.jsm",
|
155 | + "TorUIUtils.sys.mjs",
|
|
155 | 156 | "TransientPrefs.jsm",
|
156 | 157 | "URILoadingHelper.sys.mjs",
|
157 | 158 | "webrtcUI.jsm",
|