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 |