Commits:
-
e0edfde0
by Henry Wilkes at 2025-02-25T14:30:32+00:00
fixup! TB 27476: Implement about:torconnect captive portal within Tor Browser
TB 43502: Move about:torconnect methods to TorConnectParent.
-
163e2fae
by Henry Wilkes at 2025-02-25T14:30:32+00:00
fixup! TB 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection
TB 43502: Move about:torconnect methods to TorConnectParent.
-
1f7e489c
by Henry Wilkes at 2025-02-25T14:30:32+00:00
fixup! TB 40597: Implement TorSettings module
TB 43502: Remove about:torconnect specific methods from TorConnect
module.
9 changed files:
Changes:
browser/base/content/browser-init.js
| ... |
... |
@@ -980,14 +980,9 @@ var gBrowserInit = { |
|
980
|
980
|
|
|
981
|
981
|
// if using TorConnect, convert these uris to redirects
|
|
982
|
982
|
if (TorConnect.shouldShowTorConnect) {
|
|
983
|
|
- return Promise.resolve(uri).then(aUri => {
|
|
984
|
|
- if (aUri == null) {
|
|
985
|
|
- aUri = [];
|
|
986
|
|
- }
|
|
987
|
|
-
|
|
988
|
|
- aUri = TorConnect.getURIsToLoad(aUri);
|
|
989
|
|
- return aUri;
|
|
990
|
|
- });
|
|
|
983
|
+ return Promise.resolve(uri).then(aUri =>
|
|
|
984
|
+ TorConnectParent.getURIsToLoad(aUri ?? [])
|
|
|
985
|
+ );
|
|
991
|
986
|
}
|
|
992
|
987
|
return uri;
|
|
993
|
988
|
})());
|
browser/base/content/browser.js
| ... |
... |
@@ -86,6 +86,7 @@ ChromeUtils.defineESModuleGetters(this, { |
|
86
|
86
|
TorConnect: "resource://gre/modules/TorConnect.sys.mjs",
|
|
87
|
87
|
TorConnectStage: "resource://gre/modules/TorConnect.sys.mjs",
|
|
88
|
88
|
TorConnectTopics: "resource://gre/modules/TorConnect.sys.mjs",
|
|
|
89
|
+ TorConnectParent: "resource://gre/actors/TorConnectParent.sys.mjs",
|
|
89
|
90
|
TorDomainIsolator: "resource://gre/modules/TorDomainIsolator.sys.mjs",
|
|
90
|
91
|
TorUIUtils: "resource:///modules/TorUIUtils.sys.mjs",
|
|
91
|
92
|
TranslationsParent: "resource://gre/actors/TranslationsParent.sys.mjs",
|
browser/base/content/browser.js.globals
| ... |
... |
@@ -279,6 +279,7 @@ |
|
279
|
279
|
"TorConnect",
|
|
280
|
280
|
"TorConnectStage",
|
|
281
|
281
|
"TorConnectTopics",
|
|
|
282
|
+ "TorConnectParent",
|
|
282
|
283
|
"gTorConnectUrlbarButton",
|
|
283
|
284
|
"gTorConnectTitlebarStatus",
|
|
284
|
285
|
"OnionAuthPrompt",
|
browser/components/torpreferences/content/connectionPane.js
| ... |
... |
@@ -25,6 +25,10 @@ const { TorProviderBuilder, TorProviderTopics } = ChromeUtils.importESModule( |
|
25
|
25
|
const { InternetStatus, TorConnect, TorConnectTopics, TorConnectStage } =
|
|
26
|
26
|
ChromeUtils.importESModule("resource://gre/modules/TorConnect.sys.mjs");
|
|
27
|
27
|
|
|
|
28
|
+const { TorConnectParent } = ChromeUtils.importESModule(
|
|
|
29
|
+ "resource://gre/actors/TorConnectParent.sys.mjs"
|
|
|
30
|
+);
|
|
|
31
|
+
|
|
28
|
32
|
const { QRCode } = ChromeUtils.importESModule(
|
|
29
|
33
|
"resource://gre/modules/QRCode.sys.mjs"
|
|
30
|
34
|
);
|
| ... |
... |
@@ -2261,7 +2265,7 @@ const gBridgeSettings = { |
|
2261
|
2265
|
|
|
2262
|
2266
|
// Start Bootstrapping, which should use the configured bridges.
|
|
2263
|
2267
|
// NOTE: We do this regardless of any previous TorConnect Error.
|
|
2264
|
|
- TorConnect.openTorConnect({ beginBootstrapping: "hard" });
|
|
|
2268
|
+ TorConnectParent.open({ beginBootstrapping: "hard" });
|
|
2265
|
2269
|
});
|
|
2266
|
2270
|
},
|
|
2267
|
2271
|
// closedCallback should be called after gSubDialog has already
|
| ... |
... |
@@ -2374,7 +2378,7 @@ const gNetworkStatus = { |
|
2374
|
2378
|
"network-status-tor-connect-button"
|
|
2375
|
2379
|
);
|
|
2376
|
2380
|
this._torConnectButton.addEventListener("click", () => {
|
|
2377
|
|
- TorConnect.openTorConnect({ beginBootstrapping: "soft" });
|
|
|
2381
|
+ TorConnectParent.open({ beginBootstrapping: "soft" });
|
|
2378
|
2382
|
});
|
|
2379
|
2383
|
|
|
2380
|
2384
|
this._updateInternetStatus();
|
| ... |
... |
@@ -2513,7 +2517,10 @@ const gConnectionPane = (function () { |
|
2513
|
2517
|
TorStrings.settings.bridgeChooseForMe
|
|
2514
|
2518
|
);
|
|
2515
|
2519
|
chooseForMe.addEventListener("command", () => {
|
|
2516
|
|
- TorConnect.openTorConnect({
|
|
|
2520
|
+ if (!location.value) {
|
|
|
2521
|
+ return;
|
|
|
2522
|
+ }
|
|
|
2523
|
+ TorConnectParent.open({
|
|
2517
|
2524
|
beginBootstrapping: "hard",
|
|
2518
|
2525
|
regionCode: location.value,
|
|
2519
|
2526
|
});
|
browser/modules/URILoadingHelper.sys.mjs
| ... |
... |
@@ -12,6 +12,7 @@ ChromeUtils.defineESModuleGetters(lazy, { |
|
12
|
12
|
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
|
|
13
|
13
|
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
|
14
|
14
|
TorConnect: "resource://gre/modules/TorConnect.sys.mjs",
|
|
|
15
|
+ TorConnectParent: "resource://gre/actors/TorConnectParent.sys.mjs",
|
|
15
|
16
|
});
|
|
16
|
17
|
|
|
17
|
18
|
ChromeUtils.defineLazyGetter(lazy, "ReferrerInfo", () =>
|
| ... |
... |
@@ -445,7 +446,7 @@ export const URILoadingHelper = { |
|
445
|
446
|
(url === "about:newtab" &&
|
|
446
|
447
|
Services.prefs.getBoolPref("browser.newtabpage.enabled", false))
|
|
447
|
448
|
) {
|
|
448
|
|
- url = lazy.TorConnect.getRedirectURL(url);
|
|
|
449
|
+ url = lazy.TorConnectParent.getRedirectURL(url);
|
|
449
|
450
|
}
|
|
450
|
451
|
}
|
|
451
|
452
|
|
toolkit/components/torconnect/TorConnectChild.sys.mjs
| ... |
... |
@@ -55,8 +55,8 @@ export class TorConnectChild extends RemotePageChild { |
|
55
|
55
|
} else {
|
|
56
|
56
|
console.error(`Scheme is not allowed "${redirect}"`);
|
|
57
|
57
|
}
|
|
58
|
|
- } catch {
|
|
59
|
|
- console.error(`Invalid redirect URL "${redirect}"`);
|
|
|
58
|
+ } catch (e) {
|
|
|
59
|
+ console.error(`Invalid redirect URL "${redirect}"`, e);
|
|
60
|
60
|
}
|
|
61
|
61
|
|
|
62
|
62
|
// Replace the destination to prevent "about:torconnect" entering the
|
toolkit/components/torconnect/TorConnectParent.sys.mjs
| ... |
... |
@@ -9,7 +9,8 @@ import { |
|
9
|
9
|
const lazy = {};
|
|
10
|
10
|
|
|
11
|
11
|
ChromeUtils.defineESModuleGetters(lazy, {
|
|
12
|
|
- HomePage: "resource:///modules/HomePage.sys.jsm",
|
|
|
12
|
+ BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
|
|
13
|
+ HomePage: "resource:///modules/HomePage.sys.mjs",
|
|
13
|
14
|
});
|
|
14
|
15
|
|
|
15
|
16
|
/*
|
| ... |
... |
@@ -88,7 +89,9 @@ export class TorConnectParent extends JSWindowActorParent { |
|
88
|
89
|
return Promise.resolve(TorConnect.shouldShowTorConnect);
|
|
89
|
90
|
case "torconnect:home-page":
|
|
90
|
91
|
// If there are multiple home pages, just load the first one.
|
|
91
|
|
- return Promise.resolve(TorConnect.fixupURIs(lazy.HomePage.get())[0]);
|
|
|
92
|
+ return Promise.resolve(
|
|
|
93
|
+ TorConnectParent.fixupURIs(lazy.HomePage.get())[0]
|
|
|
94
|
+ );
|
|
92
|
95
|
case "torconnect:set-quickstart":
|
|
93
|
96
|
TorConnect.quickstart = message.data;
|
|
94
|
97
|
break;
|
| ... |
... |
@@ -134,4 +137,111 @@ export class TorConnectParent extends JSWindowActorParent { |
|
134
|
137
|
}
|
|
135
|
138
|
return undefined;
|
|
136
|
139
|
}
|
|
|
140
|
+
|
|
|
141
|
+ /**
|
|
|
142
|
+ * Open the "about:torconnect" tab.
|
|
|
143
|
+ *
|
|
|
144
|
+ * Bootstrapping can also be automatically triggered at the same time, if the
|
|
|
145
|
+ * current TorConnect stage allows for it.
|
|
|
146
|
+ *
|
|
|
147
|
+ * @param {object} [options] - extra options.
|
|
|
148
|
+ * @param {"soft"|"hard"} [options.beginBootstrapping] - Whether to try and
|
|
|
149
|
+ * begin bootstrapping. "soft" will only trigger the bootstrap if we are not
|
|
|
150
|
+ * `potentiallyBlocked`. "hard" will try begin the bootstrap regardless.
|
|
|
151
|
+ * @param {string} [options.regionCode] - A region to pass in for
|
|
|
152
|
+ * auto-bootstrapping.
|
|
|
153
|
+ */
|
|
|
154
|
+ static open(options) {
|
|
|
155
|
+ const win = lazy.BrowserWindowTracker.getTopWindow();
|
|
|
156
|
+ win.switchToTabHavingURI("about:torconnect", true, {
|
|
|
157
|
+ ignoreQueryString: true,
|
|
|
158
|
+ });
|
|
|
159
|
+
|
|
|
160
|
+ if (!options?.beginBootstrapping || !TorConnect.canBeginBootstrap) {
|
|
|
161
|
+ return;
|
|
|
162
|
+ }
|
|
|
163
|
+
|
|
|
164
|
+ if (options.beginBootstrapping === "hard") {
|
|
|
165
|
+ if (TorConnect.canBeginAutoBootstrap && !options.regionCode) {
|
|
|
166
|
+ // Treat as an addition startAgain request to first move back to the
|
|
|
167
|
+ // "Start" stage before bootstrapping.
|
|
|
168
|
+ TorConnect.startAgain();
|
|
|
169
|
+ }
|
|
|
170
|
+ } else if (TorConnect.potentiallyBlocked) {
|
|
|
171
|
+ // Do not trigger the bootstrap if we have ever had an error.
|
|
|
172
|
+ return;
|
|
|
173
|
+ }
|
|
|
174
|
+
|
|
|
175
|
+ TorConnect.beginBootstrapping(options.regionCode);
|
|
|
176
|
+ }
|
|
|
177
|
+
|
|
|
178
|
+ /**
|
|
|
179
|
+ * Convert the given url into an about:torconnect page that redirects to it.
|
|
|
180
|
+ *
|
|
|
181
|
+ * @param {string} url - The url to convert.
|
|
|
182
|
+ *
|
|
|
183
|
+ * @returns {string} - The about:torconnect url.
|
|
|
184
|
+ */
|
|
|
185
|
+ static getRedirectURL(url) {
|
|
|
186
|
+ return `about:torconnect?redirect=${encodeURIComponent(url)}`;
|
|
|
187
|
+ }
|
|
|
188
|
+
|
|
|
189
|
+ /**
|
|
|
190
|
+ * Convert the given object into a list of valid URIs.
|
|
|
191
|
+ *
|
|
|
192
|
+ * The object is either from the user's homepage preference (which may
|
|
|
193
|
+ * contain multiple domains separated by "|") or uris passed to the browser
|
|
|
194
|
+ * via command-line.
|
|
|
195
|
+ *
|
|
|
196
|
+ * @param {string|string[]} uriVariant - The string to extract uris from.
|
|
|
197
|
+ *
|
|
|
198
|
+ * @returns {string[]} - The array of uris found.
|
|
|
199
|
+ */
|
|
|
200
|
+ static fixupURIs(uriVariant) {
|
|
|
201
|
+ let uriArray;
|
|
|
202
|
+ if (typeof uriVariant === "string") {
|
|
|
203
|
+ uriArray = uriVariant.split("|");
|
|
|
204
|
+ } else if (
|
|
|
205
|
+ Array.isArray(uriVariant) &&
|
|
|
206
|
+ uriVariant.every(entry => typeof entry === "string")
|
|
|
207
|
+ ) {
|
|
|
208
|
+ uriArray = uriVariant;
|
|
|
209
|
+ } else {
|
|
|
210
|
+ // about:tor as safe fallback
|
|
|
211
|
+ console.error(`Received unknown variant '${JSON.stringify(uriVariant)}'`);
|
|
|
212
|
+ uriArray = ["about:tor"];
|
|
|
213
|
+ }
|
|
|
214
|
+
|
|
|
215
|
+ // Attempt to convert user-supplied string to a uri, fallback to
|
|
|
216
|
+ // about:tor if cannot convert to valid uri object
|
|
|
217
|
+ return uriArray.map(uriString => {
|
|
|
218
|
+ try {
|
|
|
219
|
+ return (
|
|
|
220
|
+ Services.uriFixup.getFixupURIInfo(
|
|
|
221
|
+ uriString,
|
|
|
222
|
+ Ci.nsIURIFixup.FIXUP_FLAG_NONE
|
|
|
223
|
+ ).preferredURI?.spec ?? "about:tor"
|
|
|
224
|
+ );
|
|
|
225
|
+ } catch (e) {
|
|
|
226
|
+ console.error(`Failed to parse ${uriString}`, e);
|
|
|
227
|
+ return "about:tor";
|
|
|
228
|
+ }
|
|
|
229
|
+ });
|
|
|
230
|
+ }
|
|
|
231
|
+
|
|
|
232
|
+ /**
|
|
|
233
|
+ * Replace startup URIs (home pages or command line) with about:torconnect
|
|
|
234
|
+ * URIs which redirect to them after bootstrapping.
|
|
|
235
|
+ *
|
|
|
236
|
+ * @param {string|string[]} uriVariant - The string to extract uris from.
|
|
|
237
|
+ *
|
|
|
238
|
+ * @returns {string[]} - The array or uris to use instead.
|
|
|
239
|
+ */
|
|
|
240
|
+ static getURIsToLoad(uriVariant) {
|
|
|
241
|
+ const uris = this.fixupURIs(uriVariant);
|
|
|
242
|
+ const localUriRx = /^(file:|moz-extension:)/;
|
|
|
243
|
+ return uris.map(uri =>
|
|
|
244
|
+ localUriRx.test(uri) ? uri : this.getRedirectURL(uri)
|
|
|
245
|
+ );
|
|
|
246
|
+ }
|
|
137
|
247
|
} |
toolkit/components/torconnect/content/torConnectUrlbarButton.js
| ... |
... |
@@ -105,7 +105,7 @@ var gTorConnectUrlbarButton = { |
|
105
|
105
|
* Begin the tor connection bootstrapping process.
|
|
106
|
106
|
*/
|
|
107
|
107
|
connect() {
|
|
108
|
|
- TorConnect.openTorConnect({ beginBootstrapping: "soft" });
|
|
|
108
|
+ TorConnectParent.open({ beginBootstrapping: "soft" });
|
|
109
|
109
|
},
|
|
110
|
110
|
|
|
111
|
111
|
/**
|
toolkit/modules/TorConnect.sys.mjs
| ... |
... |
@@ -7,7 +7,6 @@ import { setTimeout, clearTimeout } from "resource://gre/modules/Timer.sys.mjs"; |
|
7
|
7
|
const lazy = {};
|
|
8
|
8
|
|
|
9
|
9
|
ChromeUtils.defineESModuleGetters(lazy, {
|
|
10
|
|
- BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
|
11
|
10
|
MoatRPC: "resource://gre/modules/Moat.sys.mjs",
|
|
12
|
11
|
TorBootstrapRequest: "resource://gre/modules/TorBootstrapRequest.sys.mjs",
|
|
13
|
12
|
TorProviderTopics: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
| ... |
... |
@@ -1534,47 +1533,6 @@ export const TorConnect = { |
|
1534
|
1533
|
Further external commands and helper methods
|
|
1535
|
1534
|
*/
|
|
1536
|
1535
|
|
|
1537
|
|
- /**
|
|
1538
|
|
- * Open the "about:torconnect" tab.
|
|
1539
|
|
- *
|
|
1540
|
|
- * Bootstrapping or AutoBootstrapping can also be automatically triggered at
|
|
1541
|
|
- * the same time, if the current state allows for it.
|
|
1542
|
|
- *
|
|
1543
|
|
- * Bootstrapping will not be triggered if the connection is
|
|
1544
|
|
- * potentially blocked.
|
|
1545
|
|
- *
|
|
1546
|
|
- * @param {object} [options] - extra options.
|
|
1547
|
|
- * @property {"soft"|"hard"} [options.beginBootstrapping] - Whether to try and
|
|
1548
|
|
- * begin bootstrapping. "soft" will only trigger the bootstrap if we are not
|
|
1549
|
|
- * `potentiallyBlocked`. "hard" will try begin the bootstrap regardless.
|
|
1550
|
|
- * @property {string} [options.regionCode] - A region to pass in for
|
|
1551
|
|
- * auto-bootstrapping.
|
|
1552
|
|
- */
|
|
1553
|
|
- openTorConnect(options) {
|
|
1554
|
|
- // FIXME: Should we move this to the about:torconnect actor?
|
|
1555
|
|
- const win = lazy.BrowserWindowTracker.getTopWindow();
|
|
1556
|
|
- win.switchToTabHavingURI("about:torconnect", true, {
|
|
1557
|
|
- ignoreQueryString: true,
|
|
1558
|
|
- });
|
|
1559
|
|
-
|
|
1560
|
|
- if (!options?.beginBootstrapping || !this.canBeginBootstrap) {
|
|
1561
|
|
- return;
|
|
1562
|
|
- }
|
|
1563
|
|
-
|
|
1564
|
|
- if (options.beginBootstrapping === "hard") {
|
|
1565
|
|
- if (this.canBeginAutoBootstrap && !options.regionCode) {
|
|
1566
|
|
- // Treat as an addition startAgain request to first move back to the
|
|
1567
|
|
- // "Start" stage before bootstrapping.
|
|
1568
|
|
- this.startAgain();
|
|
1569
|
|
- }
|
|
1570
|
|
- } else if (this.potentiallyBlocked) {
|
|
1571
|
|
- // Do not trigger the bootstrap if we have ever had an error.
|
|
1572
|
|
- return;
|
|
1573
|
|
- }
|
|
1574
|
|
-
|
|
1575
|
|
- this.beginBootstrapping(options.regionCode);
|
|
1576
|
|
- },
|
|
1577
|
|
-
|
|
1578
|
1536
|
async getCountryCodes() {
|
|
1579
|
1537
|
// Difference with the getter: this is to be called by TorConnectParent, and
|
|
1580
|
1538
|
// downloads the country codes if they are not already in cache.
|
| ... |
... |
@@ -1592,64 +1550,4 @@ export const TorConnect = { |
|
1592
|
1550
|
}
|
|
1593
|
1551
|
return this._countryCodes;
|
|
1594
|
1552
|
},
|
|
1595
|
|
-
|
|
1596
|
|
- getRedirectURL(url) {
|
|
1597
|
|
- return `about:torconnect?redirect=${encodeURIComponent(url)}`;
|
|
1598
|
|
- },
|
|
1599
|
|
-
|
|
1600
|
|
- /**
|
|
1601
|
|
- * Convert the given object into a list of valid URIs.
|
|
1602
|
|
- *
|
|
1603
|
|
- * The object is either from the user's homepage preference (which may
|
|
1604
|
|
- * contain multiple domains separated by "|") or uris passed to the browser
|
|
1605
|
|
- * via command-line.
|
|
1606
|
|
- *
|
|
1607
|
|
- * @param {string|string[]} uriVariant - The string to extract uris from.
|
|
1608
|
|
- *
|
|
1609
|
|
- * @return {string[]} - The array of uris found.
|
|
1610
|
|
- */
|
|
1611
|
|
- fixupURIs(uriVariant) {
|
|
1612
|
|
- let uriArray;
|
|
1613
|
|
- if (typeof uriVariant === "string") {
|
|
1614
|
|
- uriArray = uriVariant.split("|");
|
|
1615
|
|
- } else if (
|
|
1616
|
|
- Array.isArray(uriVariant) &&
|
|
1617
|
|
- uriVariant.every(entry => typeof entry === "string")
|
|
1618
|
|
- ) {
|
|
1619
|
|
- uriArray = uriVariant;
|
|
1620
|
|
- } else {
|
|
1621
|
|
- // about:tor as safe fallback
|
|
1622
|
|
- lazy.logger.error(
|
|
1623
|
|
- `Received unknown variant '${JSON.stringify(uriVariant)}'`
|
|
1624
|
|
- );
|
|
1625
|
|
- uriArray = ["about:tor"];
|
|
1626
|
|
- }
|
|
1627
|
|
-
|
|
1628
|
|
- // Attempt to convert user-supplied string to a uri, fallback to
|
|
1629
|
|
- // about:tor if cannot convert to valid uri object
|
|
1630
|
|
- return uriArray.map(
|
|
1631
|
|
- uriString =>
|
|
1632
|
|
- Services.uriFixup.getFixupURIInfo(
|
|
1633
|
|
- uriString,
|
|
1634
|
|
- Ci.nsIURIFixup.FIXUP_FLAG_NONE
|
|
1635
|
|
- ).preferredURI?.spec ?? "about:tor"
|
|
1636
|
|
- );
|
|
1637
|
|
- },
|
|
1638
|
|
-
|
|
1639
|
|
- // called from browser.js on browser startup, passed in either the user's homepage(s)
|
|
1640
|
|
- // or uris passed via command-line; we want to replace them with about:torconnect uris
|
|
1641
|
|
- // which redirect after bootstrapping
|
|
1642
|
|
- getURIsToLoad(uriVariant) {
|
|
1643
|
|
- const uris = this.fixupURIs(uriVariant);
|
|
1644
|
|
- const localUriRx = /^(file:\/\/\/|moz-extension:)/;
|
|
1645
|
|
- lazy.logger.debug(
|
|
1646
|
|
- `Will load after bootstrap => [${uris
|
|
1647
|
|
- .filter(uri => !localUriRx.test(uri))
|
|
1648
|
|
- .join(", ")}]`
|
|
1649
|
|
- );
|
|
1650
|
|
-
|
|
1651
|
|
- return uris.map(uri =>
|
|
1652
|
|
- localUriRx.test(uri) ? uri : this.getRedirectURL(uri)
|
|
1653
|
|
- );
|
|
1654
|
|
- },
|
|
1655
|
1553
|
}; |
|