richard pushed to branch tor-browser-115.5.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
9d6ca8ac
by Pier Angelo Vendrame at 2023-12-05T11:00:25+01:00
-
9e239230
by Pier Angelo Vendrame at 2023-12-05T11:08:42+01:00
-
6a649d7f
by Pier Angelo Vendrame at 2023-12-05T11:25:06+01:00
-
1ad1d839
by Pier Angelo Vendrame at 2023-12-05T13:48:35+01:00
-
fbd5b4bb
by Pier Angelo Vendrame at 2023-12-05T13:48:42+01:00
-
3649cc3f
by Pier Angelo Vendrame at 2023-12-05T18:48:25+01:00
14 changed files:
- docshell/base/nsAboutRedirector.cpp
- toolkit/components/tor-launcher/TorDomainIsolator.sys.mjs
- toolkit/components/tor-launcher/TorLauncherUtil.sys.mjs
- toolkit/components/tor-launcher/TorProcess.sys.mjs
- toolkit/components/tor-launcher/TorProvider.sys.mjs
- toolkit/components/torconnect/content/aboutTorConnect.css
- toolkit/components/torconnect/content/aboutTorConnect.xhtml → toolkit/components/torconnect/content/aboutTorConnect.html
- toolkit/components/torconnect/content/aboutTorConnect.js
- toolkit/themes/shared/onionPattern.svg → toolkit/components/torconnect/content/onion-pattern.svg
- toolkit/components/torconnect/jar.mn
- toolkit/modules/Moat.sys.mjs
- toolkit/themes/shared/minimal-toolkit.jar.inc.mn
- − toolkit/themes/shared/onionPattern.css
- − toolkit/themes/shared/onionPattern.inc.xhtml
Changes:
... | ... | @@ -169,7 +169,7 @@ static const RedirEntry kRedirMap[] = { |
169 | 169 | #endif
|
170 | 170 | {"telemetry", "chrome://global/content/aboutTelemetry.xhtml",
|
171 | 171 | nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::IS_SECURE_CHROME_UI},
|
172 | - {"torconnect", "chrome://global/content/torconnect/aboutTorConnect.xhtml",
|
|
172 | + {"torconnect", "chrome://global/content/torconnect/aboutTorConnect.html",
|
|
173 | 173 | nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
174 | 174 | nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
|
175 | 175 | nsIAboutModule::HIDE_FROM_ABOUTABOUT |
|
... | ... | @@ -475,9 +475,19 @@ class TorDomainIsolatorImpl { |
475 | 475 | * @returns {MozBrowser?} The browser the channel is associated to
|
476 | 476 | */
|
477 | 477 | #getBrowserForChannel(channel) {
|
478 | + const currentBrowser =
|
|
479 | + channel.loadInfo.browsingContext?.topChromeWindow?.browser;
|
|
480 | + if (
|
|
481 | + channel.loadInfo.browsingContext &&
|
|
482 | + currentBrowser?.browsingContext === channel.loadInfo.browsingContext
|
|
483 | + ) {
|
|
484 | + // Android has only one browser, and does not have the browsers property.
|
|
485 | + return currentBrowser;
|
|
486 | + }
|
|
478 | 487 | const browsers =
|
479 | 488 | channel.loadInfo.browsingContext?.topChromeWindow?.gBrowser?.browsers;
|
480 | 489 | if (!browsers || !channel.loadInfo.browsingContext?.browserId) {
|
490 | + logger.debug("Missing data to associate to a browser", channel.loadInfo);
|
|
481 | 491 | return null;
|
482 | 492 | }
|
483 | 493 | for (const browser of browsers) {
|
... | ... | @@ -325,6 +325,10 @@ class TorFile { |
325 | 325 | }
|
326 | 326 | |
327 | 327 | export const TorLauncherUtil = Object.freeze({
|
328 | + get isAndroid() {
|
|
329 | + return Services.appinfo.OS === "Android";
|
|
330 | + },
|
|
331 | + |
|
328 | 332 | get isMac() {
|
329 | 333 | return Services.appinfo.OS === "Darwin";
|
330 | 334 | },
|
... | ... | @@ -33,8 +33,6 @@ export class TorProcess { |
33 | 33 | #args = [];
|
34 | 34 | #subprocess = null;
|
35 | 35 | #status = TorProcessStatus.Unknown;
|
36 | - // Have we ever made a connection on the control port?
|
|
37 | - #didConnectToTorControlPort = false;
|
|
38 | 36 | |
39 | 37 | onExit = exitCode => {};
|
40 | 38 | |
... | ... | @@ -69,10 +67,6 @@ export class TorProcess { |
69 | 67 | }
|
70 | 68 | }
|
71 | 69 | |
72 | - get status() {
|
|
73 | - return this.#status;
|
|
74 | - }
|
|
75 | - |
|
76 | 70 | get isRunning() {
|
77 | 71 | return (
|
78 | 72 | this.#status === TorProcessStatus.Starting ||
|
... | ... | @@ -102,7 +96,6 @@ export class TorProcess { |
102 | 96 | }
|
103 | 97 | |
104 | 98 | this.#status = TorProcessStatus.Starting;
|
105 | - this.#didConnectToTorControlPort = false;
|
|
106 | 99 | |
107 | 100 | // useful for simulating slow tor daemon launch
|
108 | 101 | const kPrefTorDaemonLaunchDelay = "extensions.torlauncher.launch_delay";
|
... | ... | @@ -155,13 +148,6 @@ export class TorProcess { |
155 | 148 | this.#status = TorProcessStatus.Exited;
|
156 | 149 | }
|
157 | 150 | |
158 | - // The owner of the process can use this function to tell us that they
|
|
159 | - // successfully connected to the control port. This information will be used
|
|
160 | - // only to decide which text to show in the confirmation dialog if tor exits.
|
|
161 | - connectionWorked() {
|
|
162 | - this.#didConnectToTorControlPort = true;
|
|
163 | - }
|
|
164 | - |
|
165 | 151 | async #dumpStdout() {
|
166 | 152 | let string;
|
167 | 153 | while (
|
... | ... | @@ -201,20 +187,6 @@ export class TorProcess { |
201 | 187 | #processExitedUnexpectedly(exitCode) {
|
202 | 188 | this.#subprocess = null;
|
203 | 189 | this.#status = TorProcessStatus.Exited;
|
204 | - // FIXME: We can probably drop #didConnectToTorControlPort and use only one
|
|
205 | - // callback. Then we can let the provider actually distinguish between the
|
|
206 | - // cases.
|
|
207 | - if (!this.#didConnectToTorControlPort) {
|
|
208 | - logger.warn("Tor exited before we could connect to its control port.");
|
|
209 | - // tor might be misconfigured, because we could never connect to it.
|
|
210 | - // Two instances of Tor Browser trying to use the same port numbers is
|
|
211 | - // also a typical scenario for this.
|
|
212 | - // This might happen very early, before the browser UI is actually
|
|
213 | - // available. So, we will tell the process owner that the process exited,
|
|
214 | - // without trying to restart it.
|
|
215 | - this.onExit(exitCode);
|
|
216 | - return;
|
|
217 | - }
|
|
218 | 190 | logger.warn("Tor exited suddenly.");
|
219 | 191 | this.onExit(exitCode);
|
220 | 192 | }
|
... | ... | @@ -35,6 +35,15 @@ const logger = new ConsoleAPI({ |
35 | 35 | * @property {string=} host The host to connect for a TCP control port
|
36 | 36 | * @property {number=} port The port number to use for a TCP control port
|
37 | 37 | */
|
38 | +/**
|
|
39 | + * @typedef {object} SocksSettings An object that includes the proxy settings to
|
|
40 | + * be configured in the browser.
|
|
41 | + * @property {boolean=} transproxy If true, no proxy is configured
|
|
42 | + * @property {nsIFile=} ipcFile The nsIFile object with the path to a Unix
|
|
43 | + * socket to use for an IPC proxy
|
|
44 | + * @property {string=} host The host to connect for a TCP proxy
|
|
45 | + * @property {number=} port The port number to use for a TCP proxy
|
|
46 | + */
|
|
38 | 47 | /**
|
39 | 48 | * @typedef {object} LogEntry An object with a log message
|
40 | 49 | * @property {Date} date The date at which we received the message
|
... | ... | @@ -111,6 +120,13 @@ export class TorProvider { |
111 | 120 | */
|
112 | 121 | #torProcess = null;
|
113 | 122 | |
123 | + /**
|
|
124 | + * The settings for the SOCKS proxy.
|
|
125 | + *
|
|
126 | + * @type {SocksSettings?}
|
|
127 | + */
|
|
128 | + #socksSettings = null;
|
|
129 | + |
|
114 | 130 | /**
|
115 | 131 | * The logs we received over the control port.
|
116 | 132 | * We store a finite number of log entries which can be configured with
|
... | ... | @@ -165,8 +181,9 @@ export class TorProvider { |
165 | 181 | async init() {
|
166 | 182 | logger.debug("Initializing the Tor provider.");
|
167 | 183 | |
168 | - const socksSettings = TorLauncherUtil.getPreferredSocksConfiguration();
|
|
169 | - logger.debug("Requested SOCKS configuration", socksSettings);
|
|
184 | + // These settings might be customized in the following steps.
|
|
185 | + this.#socksSettings = TorLauncherUtil.getPreferredSocksConfiguration();
|
|
186 | + logger.debug("Requested SOCKS configuration", this.#socksSettings);
|
|
170 | 187 | |
171 | 188 | try {
|
172 | 189 | await this.#setControlPortConfiguration();
|
... | ... | @@ -175,11 +192,11 @@ export class TorProvider { |
175 | 192 | throw e;
|
176 | 193 | }
|
177 | 194 | |
178 | - if (socksSettings.transproxy) {
|
|
195 | + if (this.#socksSettings.transproxy) {
|
|
179 | 196 | logger.info("Transparent proxy required, not starting a Tor daemon.");
|
180 | 197 | } else if (this.ownsTorDaemon) {
|
181 | 198 | try {
|
182 | - await this.#startDaemon(socksSettings);
|
|
199 | + await this.#startDaemon();
|
|
183 | 200 | } catch (e) {
|
184 | 201 | logger.error("Failed to start the tor daemon", e);
|
185 | 202 | throw e;
|
... | ... | @@ -197,8 +214,7 @@ export class TorProvider { |
197 | 214 | throw e;
|
198 | 215 | }
|
199 | 216 | |
200 | - // We do not customize SOCKS settings, at least for now.
|
|
201 | - TorLauncherUtil.setProxyConfiguration(socksSettings);
|
|
217 | + TorLauncherUtil.setProxyConfiguration(this.#socksSettings);
|
|
202 | 218 | |
203 | 219 | logger.info("The Tor provider is ready.");
|
204 | 220 | |
... | ... | @@ -464,7 +480,7 @@ export class TorProvider { |
464 | 480 | |
465 | 481 | // Process management
|
466 | 482 | |
467 | - async #startDaemon(socksSettings) {
|
|
483 | + async #startDaemon() {
|
|
468 | 484 | // TorProcess should be instanced once, then always reused and restarted
|
469 | 485 | // only through the prompt it exposes when the controlled process dies.
|
470 | 486 | if (this.#torProcess) {
|
... | ... | @@ -476,7 +492,7 @@ export class TorProvider { |
476 | 492 | |
477 | 493 | this.#torProcess = new lazy.TorProcess(
|
478 | 494 | this.#controlPortSettings,
|
479 | - socksSettings
|
|
495 | + this.#socksSettings
|
|
480 | 496 | );
|
481 | 497 | // Use a closure instead of bind because we reassign #cancelConnection.
|
482 | 498 | // Also, we now assign an exit handler that cancels the first connection,
|
... | ... | @@ -619,7 +635,6 @@ export class TorProvider { |
619 | 635 | }
|
620 | 636 | this.#openControlPort()
|
621 | 637 | .then(controller => {
|
622 | - this.#torProcess?.connectionWorked();
|
|
623 | 638 | this.#cancelConnection = () => {};
|
624 | 639 | // The cancel function should have already called reject.
|
625 | 640 | if (!canceled) {
|
... | ... | @@ -10,6 +10,11 @@ |
10 | 10 | --onion-radius: 75px;
|
11 | 11 | }
|
12 | 12 | |
13 | +html {
|
|
14 | + width: 100%;
|
|
15 | + height: 100%;
|
|
16 | +}
|
|
17 | + |
|
13 | 18 | input[type="checkbox"]:focus, select:focus {
|
14 | 19 | outline: none!important;
|
15 | 20 | box-shadow: 0 0 0 3px var(--purple-30) !important;
|
... | ... | @@ -330,3 +335,166 @@ body { |
330 | 335 | background-image: url("chrome://global/content/torconnect/connection-location.svg");
|
331 | 336 | stroke: var(--warning-color);
|
332 | 337 | }
|
338 | + |
|
339 | +.onion-pattern-container {
|
|
340 | + flex: auto; /* grow to consume remaining space on the page */
|
|
341 | + display: flex;
|
|
342 | + margin: 0 auto;
|
|
343 | + width: 100%;
|
|
344 | + /* two onions tall, 4x the radius */
|
|
345 | + height: calc(4 * var(--onion-radius));
|
|
346 | + max-height: calc(4 * var(--onion-radius));
|
|
347 | + min-height: calc(4 * var(--onion-radius));
|
|
348 | + direction: ltr;
|
|
349 | +}
|
|
350 | + |
|
351 | +.onion-pattern-crop {
|
|
352 | + height: 100%;
|
|
353 | + width: 100%;
|
|
354 | + |
|
355 | + -moz-context-properties: fill;
|
|
356 | + fill: var(--onion-color, currentColor);
|
|
357 | + /* opacity of the entire div, not context-opacity */
|
|
358 | + opacity: var(--onion-opacity, 1);
|
|
359 | + |
|
360 | + background-image: url("chrome://global/content/torconnect/onion-pattern.svg");
|
|
361 | + background-repeat: repeat;
|
|
362 | + background-attachment: local;
|
|
363 | + background-position: center;
|
|
364 | + /* svg source is 6 onions wide and 2 onions tall */
|
|
365 | + background-size: calc(6 * 2 * var(--onion-radius)) calc(2 * 2 * var(--onion-radius));;
|
|
366 | +}
|
|
367 | + |
|
368 | +:root {
|
|
369 | + --android-dark-accents-buttons: #9059FF;
|
|
370 | + --android-dark-background-secondary: #E1E0E7;
|
|
371 | + --android-dark-text-primary: #FBFBFE;
|
|
372 | + --android-light-text-primary: #15141A;
|
|
373 | +}
|
|
374 | + |
|
375 | +[hidden=true] {
|
|
376 | + display: none !important;
|
|
377 | +}
|
|
378 | + |
|
379 | +body.android {
|
|
380 | + --onion-color: var(--android-dark-text-primary);
|
|
381 | + width: 100%;
|
|
382 | + height: 100%;
|
|
383 | + box-sizing: border-box;
|
|
384 | + margin: 0;
|
|
385 | + padding: 0 24px !important;
|
|
386 | + color: var(--onion-color);
|
|
387 | + background: linear-gradient(194deg, #692E9D -0.93%, #393270 48.91%);
|
|
388 | + font: menu;
|
|
389 | + font-size: 14px;
|
|
390 | + display: flex;
|
|
391 | +}
|
|
392 | + |
|
393 | +.android #connectPageContainer {
|
|
394 | + max-width: none;
|
|
395 | + display: flex;
|
|
396 | + flex-direction: column;
|
|
397 | + flex: 1;
|
|
398 | +}
|
|
399 | + |
|
400 | +.android #breadcrumbs {
|
|
401 | + display: none;
|
|
402 | +}
|
|
403 | + |
|
404 | +.android #text-container {
|
|
405 | + display: flex;
|
|
406 | + flex-direction: column;
|
|
407 | + flex: 1;
|
|
408 | +}
|
|
409 | + |
|
410 | +.android .title {
|
|
411 | + background-position: left 0;
|
|
412 | + background-repeat: no-repeat;
|
|
413 | + background-size: 40px;
|
|
414 | + padding-top: 64px;
|
|
415 | + font-size: 22px;
|
|
416 | + line-height: 28px;
|
|
417 | +}
|
|
418 | + |
|
419 | +.android h1 {
|
|
420 | + font-weight: normal;
|
|
421 | + font-size: 100%;
|
|
422 | + margin: 0 0 16px 0;
|
|
423 | +}
|
|
424 | + |
|
425 | +.android p {
|
|
426 | + margin: 0;
|
|
427 | + padding-bottom: 8px;
|
|
428 | + line-height: 20px;
|
|
429 | +}
|
|
430 | + |
|
431 | +.android #quickstartContainer {
|
|
432 | + margin-top: 24px;
|
|
433 | +}
|
|
434 | + |
|
435 | +.android .button-container {
|
|
436 | + display: flex;
|
|
437 | + flex: 1;
|
|
438 | + flex-direction: column;
|
|
439 | +}
|
|
440 | + |
|
441 | +.android #locationDropdown {
|
|
442 | + width: 100%;
|
|
443 | + max-width: none;
|
|
444 | + margin: 0;
|
|
445 | +}
|
|
446 | + |
|
447 | +.android select {
|
|
448 | + background: transparent;
|
|
449 | + border: none;
|
|
450 | + border-bottom: 1px solid var(--android-dark-text-primary);
|
|
451 | + color: var(--android-dark-text-primary);
|
|
452 | + display: block;
|
|
453 | + width: 100%;
|
|
454 | + margin-top: 10px;
|
|
455 | + padding: 8px;
|
|
456 | +}
|
|
457 | + |
|
458 | +.android #buttonPadding {
|
|
459 | + flex: 1;
|
|
460 | +}
|
|
461 | + |
|
462 | +.android #connectButtonContainer {
|
|
463 | + width: 100%;
|
|
464 | + padding-bottom: 18px;
|
|
465 | + display: grid;
|
|
466 | +}
|
|
467 | + |
|
468 | +/* Be sure not to match the togglee */
|
|
469 | +.android #connectButtonContainer button {
|
|
470 | + display: block;
|
|
471 | + width: 100%;
|
|
472 | + margin: 4px 0;
|
|
473 | + padding: 11px 30px;
|
|
474 | + font-size: 14px;
|
|
475 | + font-weight: 500;
|
|
476 | + border: none;
|
|
477 | + border-radius: 4px;
|
|
478 | +}
|
|
479 | + |
|
480 | +.android #connectButton, .android #tryBridgeButton, .android #configureButton.primary {
|
|
481 | + color: var(--android-dark-text-primary);
|
|
482 | + background-color: var(--android-dark-accents-buttons);
|
|
483 | +}
|
|
484 | + |
|
485 | +.android #configureButton {
|
|
486 | + order: 1;
|
|
487 | +}
|
|
488 | + |
|
489 | +.android #restartButton {
|
|
490 | + order: 2;
|
|
491 | +}
|
|
492 | + |
|
493 | +.android #restartButton, .android #cancelButton, .android #configureButton {
|
|
494 | + color: var(--android-light-text-primary);
|
|
495 | + background-color: var(--android-dark-background-secondary);
|
|
496 | +}
|
|
497 | + |
|
498 | +.android .onion-pattern-container {
|
|
499 | + display: none;
|
|
500 | +} |
1 | 1 | <!-- Copyright (c) 2021, The Tor Project, Inc. -->
|
2 | 2 | <!DOCTYPE html>
|
3 | -<html xmlns="http://www.w3.org/1999/xhtml">
|
|
3 | +<html>
|
|
4 | 4 | <head>
|
5 | 5 | <meta
|
6 | 6 | http-equiv="Content-Security-Policy"
|
7 | 7 | content="default-src chrome:; object-src 'none'"
|
8 | 8 | />
|
9 | - <link
|
|
10 | - rel="stylesheet"
|
|
11 | - href="chrome://global/skin/onionPattern.css"
|
|
12 | - type="text/css"
|
|
13 | - media="all"
|
|
14 | - />
|
|
9 | + <meta name="viewport" content="width=device-width">
|
|
15 | 10 | <link
|
16 | 11 | rel="stylesheet"
|
17 | 12 | href="chrome://global/content/torconnect/aboutTorConnect.css"
|
... | ... | @@ -21,64 +16,69 @@ |
21 | 16 | </head>
|
22 | 17 | <body>
|
23 | 18 | <div id="progressBar">
|
24 | - <div id="progressBackground" />
|
|
25 | - <div id="progressSolid" />
|
|
19 | + <div id="progressBackground"></div>
|
|
20 | + <div id="progressSolid"></div>
|
|
26 | 21 | </div>
|
27 | 22 | <div id="connectPageContainer" class="container">
|
28 | 23 | <div id="breadcrumbs" class="hidden">
|
29 | 24 | <span id="connect-to-tor" class="breadcrumb-item">
|
30 | - <span id="connect-to-tor-icon" class="breadcrumb-icon" />
|
|
31 | - <span class="breadcrumb-label" />
|
|
25 | + <span id="connect-to-tor-icon" class="breadcrumb-icon"></span>
|
|
26 | + <span class="breadcrumb-label"></span>
|
|
32 | 27 | </span>
|
33 | 28 | <span
|
34 | 29 | id="connection-assist-separator"
|
35 | 30 | class="breadcrumb-separator breadcrumb-icon"
|
36 | - />
|
|
31 | + ></span>
|
|
37 | 32 | <span id="connection-assist" class="breadcrumb-item">
|
38 | - <span id="connection-assist-icon" class="breadcrumb-icon" />
|
|
39 | - <span class="breadcrumb-label" />
|
|
33 | + <span id="connection-assist-icon" class="breadcrumb-icon"></span>
|
|
34 | + <span class="breadcrumb-label"></span>
|
|
40 | 35 | </span>
|
41 | 36 | <span
|
42 | 37 | id="try-bridge-separator"
|
43 | 38 | class="breadcrumb-separator breadcrumb-icon"
|
44 | - />
|
|
39 | + ></span>
|
|
45 | 40 | <span id="try-bridge" class="breadcrumb-item">
|
46 | - <span id="try-bridge-icon" class="breadcrumb-icon" />
|
|
47 | - <span class="breadcrumb-label" />
|
|
41 | + <span id="try-bridge-icon" class="breadcrumb-icon"></span>
|
|
42 | + <span class="breadcrumb-label"></span>
|
|
48 | 43 | </span>
|
49 | 44 | </div>
|
50 | 45 | <div id="text-container">
|
51 | 46 | <div class="title">
|
52 | - <h1 class="title-text" />
|
|
47 | + <h1 class="title-text"></h1>
|
|
53 | 48 | </div>
|
54 | 49 | <div id="connectLongContent">
|
55 | - <p id="connectLongContentText" />
|
|
50 | + <p id="connectLongContentText"></p>
|
|
56 | 51 | </div>
|
57 | 52 | <div id="connectShortDesc">
|
58 | - <p id="connectShortDescText" />
|
|
53 | + <p id="connectShortDescText"></p>
|
|
59 | 54 | </div>
|
60 | 55 | |
61 | 56 | <button id="viewLogButton"></button>
|
62 | 57 | |
63 | 58 | <div id="quickstartContainer">
|
64 | 59 | <input id="quickstartCheckbox" type="checkbox" />
|
65 | - <label id="quickstartCheckboxLabel" for="quickstartCheckbox" />
|
|
60 | + <label id="quickstartCheckboxLabel" for="quickstartCheckbox"></label>
|
|
66 | 61 | </div>
|
67 | 62 | |
68 | - <div id="connectButtonContainer" class="button-container">
|
|
69 | - <button id="restartButton" hidden="true"></button>
|
|
70 | - <button id="configureButton" hidden="true"></button>
|
|
71 | - <button id="cancelButton" hidden="true"></button>
|
|
72 | - <button id="connectButton" class="primary" hidden="true"></button>
|
|
73 | - <label id="locationDropdownLabel" for="countries" />
|
|
63 | + <div class="button-container">
|
|
64 | + <label id="locationDropdownLabel" for="countries"></label>
|
|
74 | 65 | <form id="locationDropdown" hidden="true">
|
75 | 66 | <select id="countries"></select>
|
76 | 67 | </form>
|
77 | - <button id="tryBridgeButton" class="primary" hidden="true"></button>
|
|
68 | + <span id="buttonPadding"></span>
|
|
69 | + <span id="connectButtonContainer">
|
|
70 | + <button id="restartButton" hidden="true"></button>
|
|
71 | + <button id="configureButton" hidden="true"></button>
|
|
72 | + <button id="cancelButton" hidden="true"></button>
|
|
73 | + <button id="connectButton" class="primary" hidden="true"></button>
|
|
74 | + <button id="tryBridgeButton" class="primary" hidden="true"></button>
|
|
75 | + </span>
|
|
78 | 76 | </div>
|
79 | 77 | </div>
|
80 | 78 | </div>
|
81 | -#include ../../../themes/shared/onionPattern.inc.xhtml
|
|
79 | + <div class="onion-pattern-container">
|
|
80 | + <div class="onion-pattern-crop"></div>
|
|
81 | + </div>
|
|
82 | + <script src="chrome://global/content/torconnect/aboutTorConnect.js"></script>
|
|
82 | 83 | </body>
|
83 | - <script src="chrome://global/content/torconnect/aboutTorConnect.js" />
|
|
84 | 84 | </html> |
... | ... | @@ -70,8 +70,8 @@ class AboutTorConnect { |
70 | 70 | connect: "button#connectButton",
|
71 | 71 | tryBridge: "button#tryBridgeButton",
|
72 | 72 | locationDropdownLabel: "#locationDropdownLabel",
|
73 | - locationDropdown: "form#locationDropdown",
|
|
74 | - locationDropdownSelect: "form#locationDropdown select",
|
|
73 | + locationDropdown: "#locationDropdown",
|
|
74 | + locationDropdownSelect: "#locationDropdown select",
|
|
75 | 75 | },
|
76 | 76 | });
|
77 | 77 | |
... | ... | @@ -666,6 +666,9 @@ class AboutTorConnect { |
666 | 666 | }
|
667 | 667 | |
668 | 668 | initElements(direction) {
|
669 | + const isAndroid = navigator.userAgent.indexOf("Android") !== -1;
|
|
670 | + document.body.classList.toggle("android", isAndroid);
|
|
671 | + |
|
669 | 672 | document.documentElement.setAttribute("dir", direction);
|
670 | 673 | |
671 | 674 | this.elements.connectToTorLink.addEventListener("click", event => {
|
... | ... | @@ -3,12 +3,13 @@ toolkit.jar: |
3 | 3 | content/global/torconnect/torConnectTitlebarStatus.js (content/torConnectTitlebarStatus.js)
|
4 | 4 | content/global/torconnect/torConnectTitlebarStatus.css (content/torConnectTitlebarStatus.css)
|
5 | 5 | content/global/torconnect/aboutTorConnect.css (content/aboutTorConnect.css)
|
6 | -* content/global/torconnect/aboutTorConnect.xhtml (content/aboutTorConnect.xhtml)
|
|
6 | + content/global/torconnect/aboutTorConnect.html (content/aboutTorConnect.html)
|
|
7 | 7 | content/global/torconnect/aboutTorConnect.js (content/aboutTorConnect.js)
|
8 | 8 | content/global/torconnect/arrow-right.svg (content/arrow-right.svg)
|
9 | 9 | content/global/torconnect/bridge.svg (content/bridge.svg)
|
10 | 10 | content/global/torconnect/connection-failure.svg (content/connection-failure.svg)
|
11 | 11 | content/global/torconnect/connection-location.svg (content/connection-location.svg)
|
12 | + content/global/torconnect/onion-pattern.svg (content/onion-pattern.svg)
|
|
12 | 13 | content/global/torconnect/tor-connect.svg (content/tor-connect.svg)
|
13 | 14 | content/global/torconnect/tor-not-connected-to-connected-animated.svg (content/tor-not-connected-to-connected-animated.svg)
|
14 | 15 | content/global/torconnect/tor-connect-broken.svg (content/tor-connect-broken.svg) |
... | ... | @@ -21,6 +21,56 @@ const TorLauncherPrefs = Object.freeze({ |
21 | 21 | moat_service: "extensions.torlauncher.moat_service",
|
22 | 22 | });
|
23 | 23 | |
24 | +function makeMeekCredentials(proxyType) {
|
|
25 | + // Construct the per-connection arguments.
|
|
26 | + let meekClientEscapedArgs = "";
|
|
27 | + const meekReflector = Services.prefs.getStringPref(
|
|
28 | + TorLauncherPrefs.bridgedb_reflector
|
|
29 | + );
|
|
30 | + |
|
31 | + // Escape aValue per section 3.5 of the PT specification:
|
|
32 | + // First the "<Key>=<Value>" formatted arguments MUST be escaped,
|
|
33 | + // such that all backslash, equal sign, and semicolon characters
|
|
34 | + // are escaped with a backslash.
|
|
35 | + const escapeArgValue = aValue =>
|
|
36 | + aValue
|
|
37 | + ? aValue
|
|
38 | + .replaceAll("\\", "\\\\")
|
|
39 | + .replaceAll("=", "\\=")
|
|
40 | + .replaceAll(";", "\\;")
|
|
41 | + : "";
|
|
42 | + |
|
43 | + if (meekReflector) {
|
|
44 | + meekClientEscapedArgs += "url=";
|
|
45 | + meekClientEscapedArgs += escapeArgValue(meekReflector);
|
|
46 | + }
|
|
47 | + const meekFront = Services.prefs.getStringPref(
|
|
48 | + TorLauncherPrefs.bridgedb_front
|
|
49 | + );
|
|
50 | + if (meekFront) {
|
|
51 | + if (meekClientEscapedArgs.length) {
|
|
52 | + meekClientEscapedArgs += ";";
|
|
53 | + }
|
|
54 | + meekClientEscapedArgs += "front=";
|
|
55 | + meekClientEscapedArgs += escapeArgValue(meekFront);
|
|
56 | + }
|
|
57 | + |
|
58 | + // socks5
|
|
59 | + if (proxyType === "socks") {
|
|
60 | + if (meekClientEscapedArgs.length <= 255) {
|
|
61 | + return [meekClientEscapedArgs, "\x00"];
|
|
62 | + } else {
|
|
63 | + return [
|
|
64 | + meekClientEscapedArgs.substring(0, 255),
|
|
65 | + meekClientEscapedArgs.substring(255),
|
|
66 | + ];
|
|
67 | + }
|
|
68 | + // socks4
|
|
69 | + } else {
|
|
70 | + return [meekClientEscapedArgs, undefined];
|
|
71 | + }
|
|
72 | +}
|
|
73 | + |
|
24 | 74 | //
|
25 | 75 | // Launches and controls the PT process lifetime
|
26 | 76 | //
|
... | ... | @@ -70,39 +120,6 @@ class MeekTransport { |
70 | 120 | proxy.pathToBinary = meekPath.path;
|
71 | 121 | }
|
72 | 122 | |
73 | - // Construct the per-connection arguments.
|
|
74 | - let meekClientEscapedArgs = "";
|
|
75 | - const meekReflector = Services.prefs.getStringPref(
|
|
76 | - TorLauncherPrefs.bridgedb_reflector
|
|
77 | - );
|
|
78 | - |
|
79 | - // Escape aValue per section 3.5 of the PT specification:
|
|
80 | - // First the "<Key>=<Value>" formatted arguments MUST be escaped,
|
|
81 | - // such that all backslash, equal sign, and semicolon characters
|
|
82 | - // are escaped with a backslash.
|
|
83 | - const escapeArgValue = aValue =>
|
|
84 | - aValue
|
|
85 | - ? aValue
|
|
86 | - .replaceAll("\\", "\\\\")
|
|
87 | - .replaceAll("=", "\\=")
|
|
88 | - .replaceAll(";", "\\;")
|
|
89 | - : "";
|
|
90 | - |
|
91 | - if (meekReflector) {
|
|
92 | - meekClientEscapedArgs += "url=";
|
|
93 | - meekClientEscapedArgs += escapeArgValue(meekReflector);
|
|
94 | - }
|
|
95 | - const meekFront = Services.prefs.getStringPref(
|
|
96 | - TorLauncherPrefs.bridgedb_front
|
|
97 | - );
|
|
98 | - if (meekFront) {
|
|
99 | - if (meekClientEscapedArgs.length) {
|
|
100 | - meekClientEscapedArgs += ";";
|
|
101 | - }
|
|
102 | - meekClientEscapedArgs += "front=";
|
|
103 | - meekClientEscapedArgs += escapeArgValue(meekFront);
|
|
104 | - }
|
|
105 | - |
|
106 | 123 | // Setup env and start meek process
|
107 | 124 | const ptStateDir = lazy.TorLauncherUtil.getTorFile("tordatadir", false);
|
108 | 125 | ptStateDir.append("pt_state"); // Match what tor uses.
|
... | ... | @@ -247,22 +264,9 @@ class MeekTransport { |
247 | 264 | this.#meekClientProcess = null;
|
248 | 265 | this.uninit();
|
249 | 266 | });
|
250 | - |
|
251 | - // socks5
|
|
252 | - if (this.proxyType === "socks") {
|
|
253 | - if (meekClientEscapedArgs.length <= 255) {
|
|
254 | - this.proxyUsername = meekClientEscapedArgs;
|
|
255 | - this.proxyPassword = "\x00";
|
|
256 | - } else {
|
|
257 | - this.proxyUsername = meekClientEscapedArgs.substring(0, 255);
|
|
258 | - this.proxyPassword = meekClientEscapedArgs.substring(255);
|
|
259 | - }
|
|
260 | - // socks4
|
|
261 | - } else {
|
|
262 | - this.proxyUsername = meekClientEscapedArgs;
|
|
263 | - this.proxyPassword = undefined;
|
|
264 | - }
|
|
265 | - |
|
267 | + [this.proxyUsername, this.proxyPassword] = makeMeekCredentials(
|
|
268 | + this.proxyType
|
|
269 | + );
|
|
266 | 270 | this.#inited = true;
|
267 | 271 | } catch (ex) {
|
268 | 272 | if (this.#meekClientProcess) {
|
... | ... | @@ -403,7 +407,7 @@ export class MoatRPC { |
403 | 407 | throw new Error("MoatRPC: Already initialized");
|
404 | 408 | }
|
405 | 409 | |
406 | - let meekTransport = new MeekTransport();
|
|
410 | + const meekTransport = new MeekTransport();
|
|
407 | 411 | await meekTransport.init();
|
408 | 412 | this.#meekTransport = meekTransport;
|
409 | 413 | this.#inited = true;
|
... | ... | @@ -47,7 +47,3 @@ toolkit.jar: |
47 | 47 | skin/classic/global/media/textrecognition.css (../../shared/media/textrecognition.css)
|
48 | 48 | |
49 | 49 | skin/classic/global/browser-colors.css (../../shared/browser-colors.css) |
50 | - |
|
51 | -# Tor customization
|
|
52 | - skin/classic/global/onionPattern.css (../../shared/onionPattern.css)
|
|
53 | - skin/classic/global/onionPattern.svg (../../shared/onionPattern.svg) |
1 | -/* Onion pattern */
|
|
2 | - |
|
3 | -.onion-pattern-container {
|
|
4 | - |
|
5 | - flex: auto; /* grow to consume remaining space on the page */
|
|
6 | - display: flex;
|
|
7 | - margin: 0 auto;
|
|
8 | - width: 100%;
|
|
9 | - /* two onions tall, 4x the radius */
|
|
10 | - height: calc(4 * var(--onion-radius));
|
|
11 | - max-height: calc(4 * var(--onion-radius));
|
|
12 | - min-height: calc(4 * var(--onion-radius));
|
|
13 | - direction: ltr;
|
|
14 | -}
|
|
15 | - |
|
16 | -.onion-pattern-crop {
|
|
17 | - height: 100%;
|
|
18 | - width: 100%;
|
|
19 | - |
|
20 | - -moz-context-properties: fill;
|
|
21 | - fill: var(--onion-color, currentColor);
|
|
22 | - /* opacity of the entire div, not context-opacity */
|
|
23 | - opacity: var(--onion-opacity, 1);
|
|
24 | - |
|
25 | - background-image: url("chrome://global/skin/onionPattern.svg");
|
|
26 | - background-repeat: repeat;
|
|
27 | - background-attachment: local;
|
|
28 | - background-position: center;
|
|
29 | - /* svg source is 6 onions wide and 2 onions tall */
|
|
30 | - background-size: calc(6 * 2 * var(--onion-radius)) calc(2 * 2 * var(--onion-radius));;
|
|
31 | -} |
1 | -<!--
|
|
2 | - Container div that holds onionPattern.svg
|
|
3 | - It is expected the includer of this xhtml file also includes onionPattern.css
|
|
4 | - and define the following vars:
|
|
5 | - onion-radius : radius of an onion
|
|
6 | - onion-color : the base color of the onion pattern
|
|
7 | - onion-opacity : the opacity of the entire repeating pattern
|
|
8 | --->
|
|
9 | - |
|
10 | -<div class="onion-pattern-container">
|
|
11 | - <div class="onion-pattern-crop"/>
|
|
12 | -</div> |
|
\ No newline at end of file |