lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Download
Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
tbb-commits@lists.torproject.org

  • 1 participants
  • 18632 discussions
[Git][tpo/applications/torbrowser-launcher][main] Add script to tag new release (#13)
by boklm (@boklm) 15 Jan '24

15 Jan '24
boklm pushed to branch main at The Tor Project / Applications / torbrowser-launcher Commits: 899ea231 by Nicolas Vigier at 2024-01-12T11:13:05+01:00 Add script to tag new release (#13) - - - - - 1 changed file: - + git-tag_release.sh Changes: ===================================== git-tag_release.sh ===================================== @@ -0,0 +1,6 @@ +#!/bin/sh +# Make a signed git tag for the current commit, for a new release +set -e +VERSION=$(cat share/torbrowser-launcher/version) +git tag -s --message="torbrowser-launcher version $VERSION" v$VERSION +echo "Created git tag v$VERSION" View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/torbrowser-launcher] Pushed new tag v0.3.7
by boklm (@boklm) 12 Jan '24

12 Jan '24
boklm pushed new tag v0.3.7 at The Tor Project / Applications / torbrowser-launcher -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/tree/v… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/torbrowser-launcher][main] Version bump to 0.3.7 and update changelog
by boklm (@boklm) 12 Jan '24

12 Jan '24
boklm pushed to branch main at The Tor Project / Applications / torbrowser-launcher Commits: e4bb9790 by Nicolas Vigier at 2024-01-11T20:00:16+01:00 Version bump to 0.3.7 and update changelog - - - - - 3 changed files: - CHANGELOG.md - share/metainfo/org.torproject.torbrowser-launcher.metainfo.xml - share/torbrowser-launcher/version Changes: ===================================== CHANGELOG.md ===================================== @@ -1,5 +1,19 @@ # Tor Browser Launcher Changelog +## 0.3.7 + +* Use Tor Browser 13.0 new filenames +* Adapt AppArmor profile for Tor Browser 13.0 +* Set the TORBROWSER_LAUNCHER environment variable to make it easier + for Tor Browser to see that it is being run by torbrowser-launcher +* Use a proper rDNS ID in AppStream metainfo +* Update to latest version of the Tor Browser OpenPGP signing key +* Remove some unused code to fix a warning +* Add dbus-glib to the rpm package dependencies +* Maintenance of torbrowser-launcher has been handed to Tor Project, + and the git repository moved to + https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ + ## 0.3.6 * Tor Browser 12.0 no longer uses locales, so the download URL and local path have changed ===================================== share/metainfo/org.torproject.torbrowser-launcher.metainfo.xml ===================================== @@ -31,6 +31,7 @@ <update_contact>boklm(a)torproject.org</update_contact> <content_rating type="oars-1.1"/> <releases> + <release version="0.3.7" date="2024-01-12"/> <release version="0.3.6" date="2022-12-13"/> </releases> </component> ===================================== share/torbrowser-launcher/version ===================================== @@ -1 +1 @@ -0.3.6 +0.3.7 View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/torbrowser-launcher][main] Remove gnupg_import_ok_pattern from torbrowser_launcher/common.py (#12)
by boklm (@boklm) 11 Jan '24

11 Jan '24
boklm pushed to branch main at The Tor Project / Applications / torbrowser-launcher Commits: 10a13e3f by Nicolas Vigier at 2024-01-11T13:33:31+01:00 Remove gnupg_import_ok_pattern from torbrowser_launcher/common.py (#12) According to https://github.com/torproject/torbrowser-launcher/pull/716 the definition of `gnupg_import_ok_pattern` in `torbrowser_launcher/common.py` is causing some warnings. But it looks like it is not being used since 83fa1d38c44f16a76dd98407e321b9cc9b5b5743, so we can remove it. Thanks to meator for reporting the issue. - - - - - 1 changed file: - torbrowser_launcher/common.py Changes: ===================================== torbrowser_launcher/common.py ===================================== @@ -41,15 +41,6 @@ SHARE = os.getenv("TBL_SHARE", sys.prefix + "/share") + "/torbrowser-launcher" gettext.install("torbrowser-launcher") -# We're looking for output which: -# -# 1. The first portion must be `[GNUPG:] IMPORT_OK` -# 2. The second must be an integer between [0, 15], inclusive -# 3. The third must be an uppercased hex-encoded 160-bit fingerprint -gnupg_import_ok_pattern = re.compile( - b"(\[GNUPG\:\]) (IMPORT_OK) ([0-9]|[1]?[0-5]) ([A-F0-9]{40})" -) - class Common(object): def __init__(self, tbl_version): View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/firefox-android][firefox-android-115.2.1-13.0-1] 10 commits: fixup! Bug 1823316 - Use 'Snackbar' themed Dialog to notify on making app full-screen
by ma1 (@ma1) 11 Jan '24

11 Jan '24
ma1 pushed to branch firefox-android-115.2.1-13.0-1 at The Tor Project / Applications / firefox-android Commits: 753c937e by hackademix at 2024-01-11T16:53:03+01:00 fixup! Bug 1823316 - Use &#39;Snackbar&#39; themed Dialog to notify on making app full-screen Fix tor-browser#42355 backporting regression. - - - - - 0cd27910 by t-p-white at 2024-01-11T16:53:04+01:00 Bug 1864549 - Fix for IllegalStateException in full screen notification dialog - - - - - a7cafd1b by Alexandru2909 at 2024-01-11T16:53:04+01:00 Bug 1810776 - Move DismissedTabBackground into its own file - - - - - e40a62ad by DreVla at 2024-01-11T16:53:05+01:00 Bug 1828493 - Apply purple overlay on list item when in multi-select When having the list layout for tabs tray and entering multi-select mode, the selected list items should have a purple non opaque overlay on the thumbnail, as it was before in the XML implementation. - - - - - b4e5ab52 by Alexandru2909 at 2024-01-11T16:53:05+01:00 Bug 1810776 - Add SwipeToDismiss to composed tabs tray - - - - - 20a18e5b by Noah Bond at 2024-01-11T16:53:05+01:00 Bug 1815579 - Improve performance of image loading in tab items - - - - - a07ec0d9 by Noah Bond at 2024-01-11T16:53:06+01:00 Bug 1840896 - Remove `rememberSaveable` since bitmaps are not serializable - - - - - a860d4a3 by Noah Bond at 2024-01-11T16:53:06+01:00 Bug 1844967 - Improve performance of tab thumbnail loading in Compose - - - - - 0481dabe by Matthew Tighe at 2024-01-11T16:53:07+01:00 Bug 1721904 - update thumbnail caching on app open - - - - - 3400c111 by hackademix at 2024-01-11T16:53:07+01:00 Bug 42191: Temporary StrictMode relaxation to clear the thumbnail cache. - - - - - 30 changed files: - android-components/components/browser/state/src/main/java/mozilla/components/browser/state/action/BrowserAction.kt - android-components/components/browser/state/src/main/java/mozilla/components/browser/state/reducer/ContentStateReducer.kt - android-components/components/browser/tabstray/src/main/java/mozilla/components/browser/tabstray/TabViewHolder.kt - android-components/components/browser/tabstray/src/test/java/mozilla/components/browser/tabstray/DefaultTabViewHolderTest.kt - android-components/components/browser/thumbnails/src/main/java/mozilla/components/browser/thumbnails/ThumbnailsMiddleware.kt - android-components/components/browser/thumbnails/src/main/java/mozilla/components/browser/thumbnails/storage/ThumbnailStorage.kt - android-components/components/browser/thumbnails/src/main/java/mozilla/components/browser/thumbnails/utils/ThumbnailDiskCache.kt - android-components/components/browser/thumbnails/src/test/java/mozilla/components/browser/thumbnails/ThumbnailsMiddlewareTest.kt - android-components/components/browser/thumbnails/src/test/java/mozilla/components/browser/thumbnails/loader/ThumbnailLoaderTest.kt - android-components/components/browser/thumbnails/src/test/java/mozilla/components/browser/thumbnails/storage/ThumbnailStorageTest.kt - android-components/components/browser/thumbnails/src/test/java/mozilla/components/browser/thumbnails/utils/ThumbnailDiskCacheTest.kt - android-components/components/concept/base/src/main/java/mozilla/components/concept/base/images/ImageRequest.kt - android-components/components/feature/prompts/src/main/java/mozilla/components/feature/prompts/dialog/FullScreenNotificationDialog.kt - fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt - fenix/app/src/main/java/org/mozilla/fenix/browser/TabPreview.kt - fenix/app/src/main/java/org/mozilla/fenix/browser/ToolbarGestureHandler.kt - + fenix/app/src/main/java/org/mozilla/fenix/compose/SwipeToDismiss.kt - + fenix/app/src/main/java/org/mozilla/fenix/compose/TabThumbnail.kt - fenix/app/src/main/java/org/mozilla/fenix/compose/ThumbnailCard.kt - + fenix/app/src/main/java/org/mozilla/fenix/compose/ThumbnailImage.kt - fenix/app/src/main/java/org/mozilla/fenix/compose/list/ListItem.kt - + fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/DismissedTabBackground.kt - fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabGridItem.kt - fenix/app/src/main/java/org/mozilla/fenix/compose/tabstray/TabListItem.kt - fenix/app/src/main/java/org/mozilla/fenix/home/collections/CollectionItem.kt - fenix/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTab.kt - fenix/app/src/main/java/org/mozilla/fenix/home/recentsyncedtabs/view/RecentSyncedTabViewHolder.kt - fenix/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabViewHolder.kt - fenix/app/src/main/java/org/mozilla/fenix/home/recenttabs/view/RecentTabs.kt - fenix/app/src/main/java/org/mozilla/fenix/tabstray/TabsTray.kt The diff was not included because it is too large. View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/da… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/firefox-android/-/compare/da… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.6.0esr-13.5-1] fixup! Bug 40597: Implement TorSettings module
by Pier Angelo Vendrame (@pierov) 11 Jan '24

11 Jan '24
Pier Angelo Vendrame pushed to branch tor-browser-115.6.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: 0c55a36a by Pier Angelo Vendrame at 2024-01-09T18:39:07+01:00 fixup! Bug 40597: Implement TorSettings module Bug 42348: Do not use TorSettings.defaultSettings as a starting point for the settings object we receive from Moat. Also, removed the TODO about proxy and firewall, since Moat is not going to send them for now, but throw when we do not receive bridge settings. - - - - - 1 changed file: - toolkit/modules/Moat.sys.mjs Changes: ===================================== toolkit/modules/Moat.sys.mjs ===================================== @@ -2,10 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { - TorSettings, - TorBridgeSource, -} from "resource://gre/modules/TorSettings.sys.mjs"; +import { TorBridgeSource } from "resource://gre/modules/TorSettings.sys.mjs"; const lazy = {}; @@ -204,68 +201,52 @@ export class MoatRPC { // Convert received settings object to format used by TorSettings module // In the event of error, just return null #fixupSettings(settings) { - try { - let retval = TorSettings.defaultSettings(); - if ("bridges" in settings) { - retval.bridges.enabled = true; - switch (settings.bridges.source) { - case "builtin": - retval.bridges.source = TorBridgeSource.BuiltIn; - retval.bridges.builtin_type = settings.bridges.type; - // Tor Browser will periodically update the built-in bridge strings list using the - // circumvention_builtin() function, so we can ignore the bridge strings we have received here; - // BridgeDB only returns a subset of the available built-in bridges through the circumvention_settings() - // function which is fine for our 3rd parties, but we're better off ignoring them in Tor Browser, otherwise - // we get in a weird situation of needing to update our built-in bridges in a piece-meal fashion which - // seems over-complicated/error-prone - break; - case "bridgedb": - retval.bridges.source = TorBridgeSource.BridgeDB; - if (settings.bridges.bridge_strings) { - retval.bridges.bridge_strings = settings.bridges.bridge_strings; - retval.bridges.disabled_strings = []; - } else { - throw new Error( - "MoatRPC::_fixupSettings(): Received no bridge-strings for BridgeDB bridge source" - ); - } - break; - default: - throw new Error( - `MoatRPC::_fixupSettings(): Unexpected bridge source '${settings.bridges.source}'` - ); + if (!("bridges" in settings)) { + throw new Error("Expected to find `bridges` in the settings object."); + } + const retval = { + bridges: { + enabled: true, + }, + }; + switch (settings.bridges.source) { + case "builtin": + retval.bridges.source = TorBridgeSource.BuiltIn; + retval.bridges.builtin_type = settings.bridges.type; + // TorSettings will ignore strings for built-in bridges, and use the + // ones it already knows, instead. + break; + case "bridgedb": + retval.bridges.source = TorBridgeSource.BridgeDB; + if (settings.bridges.bridge_strings) { + retval.bridges.bridge_strings = settings.bridges.bridge_strings; + } else { + throw new Error( + "Received no bridge-strings for BridgeDB bridge source" + ); } - } - if ("proxy" in settings) { - // TODO: populate proxy settings - } - if ("firewall" in settings) { - // TODO: populate firewall settings - } - return retval; - } catch (ex) { - console.log(ex.message); - return null; + break; + default: + throw new Error( + `Unexpected bridge source '${settings.bridges.source}'` + ); } + return retval; } // Converts a list of settings objects received from BridgeDB to a list of settings objects // understood by the TorSettings module // In the event of error, returns and empty list #fixupSettingsList(settingsList) { - try { - let retval = []; - for (let settings of settingsList) { - settings = this.#fixupSettings(settings); - if (settings != null) { - retval.push(settings); - } + const retval = []; + for (const settings of settingsList) { + try { + retval.push(this.#fixupSettings(settings)); + } catch (ex) { + console.log(ex); } - return retval; - } catch (ex) { - console.log(ex.message); - return []; } + return retval; } // Request tor settings for the user optionally based on their location (derived View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/0c55a36… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/0c55a36… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser][tor-browser-115.6.0esr-13.5-1] fixup! Bug 40597: Implement TorSettings module
by Pier Angelo Vendrame (@pierov) 11 Jan '24

11 Jan '24
Pier Angelo Vendrame pushed to branch tor-browser-115.6.0esr-13.5-1 at The Tor Project / Applications / Tor Browser Commits: da0f3108 by Pier Angelo Vendrame at 2024-01-09T18:38:42+01:00 fixup! Bug 40597: Implement TorSettings module Bug 42358: Extract the domain fronting request functionality form MoatRPC. - - - - - 3 changed files: - + toolkit/modules/DomainFrontedRequests.sys.mjs - toolkit/modules/Moat.sys.mjs - toolkit/modules/moz.build Changes: ===================================== toolkit/modules/DomainFrontedRequests.sys.mjs ===================================== @@ -0,0 +1,525 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + EventDispatcher: "resource://gre/modules/Messaging.sys.mjs", + Subprocess: "resource://gre/modules/Subprocess.sys.mjs", + TorLauncherUtil: "resource://gre/modules/TorLauncherUtil.sys.mjs", + TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs", + TorSettings: "resource://gre/modules/TorSettings.sys.mjs", +}); + +/** + * The meek pluggable transport takes the reflector URL and front domain as + * proxy credentials, which can be prepared with this function. + * + * @param {string} proxyType The proxy type (socks for socks5 or socks4) + * @param {string} reflector The URL of the service hosted by the CDN + * @param {string} front The domain to use as a front + * @returns {string[]} An array containing [username, password] + */ +function makeMeekCredentials(proxyType, reflector, front) { + // Construct the per-connection arguments. + let meekClientEscapedArgs = ""; + + // Escape aValue per section 3.5 of the PT specification: + // First the "<Key>=<Value>" formatted arguments MUST be escaped, + // such that all backslash, equal sign, and semicolon characters + // are escaped with a backslash. + const escapeArgValue = aValue => + aValue + ? aValue + .replaceAll("\\", "\\\\") + .replaceAll("=", "\\=") + .replaceAll(";", "\\;") + : ""; + + if (reflector) { + meekClientEscapedArgs += "url="; + meekClientEscapedArgs += escapeArgValue(reflector); + } + + if (front) { + if (meekClientEscapedArgs.length) { + meekClientEscapedArgs += ";"; + } + meekClientEscapedArgs += "front="; + meekClientEscapedArgs += escapeArgValue(front); + } + + // socks5 + if (proxyType === "socks") { + if (meekClientEscapedArgs.length <= 255) { + return [meekClientEscapedArgs, "\x00"]; + } + return [ + meekClientEscapedArgs.substring(0, 255), + meekClientEscapedArgs.substring(255), + ]; + } else if (proxyType === "socks4") { + return [meekClientEscapedArgs, undefined]; + } + throw new Error(`Unsupported proxy type ${proxyType}.`); +} + +/** + * Subprocess-based implementation to launch and control a PT process. + */ +class MeekTransport { + // These members are used by consumers to setup the proxy to do requests over + // meek. They are passed to newProxyInfoWithAuth. + proxyType = null; + proxyAddress = null; + proxyPort = 0; + proxyUsername = null; + proxyPassword = null; + + #inited = false; + #meekClientProcess = null; + + // launches the meekprocess + async init(reflector, front) { + // ensure we haven't already init'd + if (this.#inited) { + throw new Error("MeekTransport: Already initialized"); + } + + try { + // figure out which pluggable transport to use + const supportedTransports = ["meek", "meek_lite"]; + const provider = await lazy.TorProviderBuilder.build(); + const proxy = (await provider.getPluggableTransports()).find( + pt => + pt.type === "exec" && + supportedTransports.some(t => pt.transports.includes(t)) + ); + if (!proxy) { + throw new Error("No supported transport found."); + } + + const meekTransport = proxy.transports.find(t => + supportedTransports.includes(t) + ); + // Convert meek client path to absolute path if necessary + const meekWorkDir = lazy.TorLauncherUtil.getTorFile( + "pt-startup-dir", + false + ); + if (lazy.TorLauncherUtil.isPathRelative(proxy.pathToBinary)) { + const meekPath = meekWorkDir.clone(); + meekPath.appendRelativePath(proxy.pathToBinary); + proxy.pathToBinary = meekPath.path; + } + + // Setup env and start meek process + const ptStateDir = lazy.TorLauncherUtil.getTorFile("tordatadir", false); + ptStateDir.append("pt_state"); // Match what tor uses. + + const envAdditions = { + TOR_PT_MANAGED_TRANSPORT_VER: "1", + TOR_PT_STATE_LOCATION: ptStateDir.path, + TOR_PT_EXIT_ON_STDIN_CLOSE: "1", + TOR_PT_CLIENT_TRANSPORTS: meekTransport, + }; + if (lazy.TorSettings.proxy.enabled) { + envAdditions.TOR_PT_PROXY = lazy.TorSettings.proxy.uri; + } + + const opts = { + command: proxy.pathToBinary, + arguments: proxy.options.split(/s+/), + workdir: meekWorkDir.path, + environmentAppend: true, + environment: envAdditions, + stderr: "pipe", + }; + + // Launch meek client + this.#meekClientProcess = await lazy.Subprocess.call(opts); + + // Callback chain for reading stderr + const stderrLogger = async () => { + while (this.#meekClientProcess) { + const errString = await this.#meekClientProcess.stderr.readString(); + if (errString) { + console.log(`MeekTransport: stderr => ${errString}`); + } + } + }; + stderrLogger(); + + // Read pt's stdout until terminal (CMETHODS DONE) is reached + // returns array of lines for parsing + const getInitLines = async (stdout = "") => { + stdout += await this.#meekClientProcess.stdout.readString(); + + // look for the final message + const CMETHODS_DONE = "CMETHODS DONE"; + let endIndex = stdout.lastIndexOf(CMETHODS_DONE); + if (endIndex !== -1) { + endIndex += CMETHODS_DONE.length; + return stdout.substring(0, endIndex).split("\n"); + } + return getInitLines(stdout); + }; + + // read our lines from pt's stdout + const meekInitLines = await getInitLines(); + // tokenize our pt lines + const meekInitTokens = meekInitLines.map(line => { + const tokens = line.split(" "); + return { + keyword: tokens[0], + args: tokens.slice(1), + }; + }); + + // parse our pt tokens + for (const { keyword, args } of meekInitTokens) { + const argsJoined = args.join(" "); + let keywordError = false; + switch (keyword) { + case "VERSION": { + if (args.length !== 1 || args[0] !== "1") { + keywordError = true; + } + break; + } + case "PROXY": { + if (args.length !== 1 || args[0] !== "DONE") { + keywordError = true; + } + break; + } + case "CMETHOD": { + if (args.length !== 3) { + keywordError = true; + break; + } + const transport = args[0]; + const proxyType = args[1]; + const addrPortString = args[2]; + const addrPort = addrPortString.split(":"); + + if (transport !== meekTransport) { + throw new Error( + `MeekTransport: Expected ${meekTransport} but found ${transport}` + ); + } + if (!["socks4", "socks4a", "socks5"].includes(proxyType)) { + throw new Error( + `MeekTransport: Invalid proxy type => ${proxyType}` + ); + } + if (addrPort.length !== 2) { + throw new Error( + `MeekTransport: Invalid proxy address => ${addrPortString}` + ); + } + const addr = addrPort[0]; + const port = parseInt(addrPort[1]); + if (port < 1 || port > 65535) { + throw new Error(`MeekTransport: Invalid proxy port => ${port}`); + } + + // convert proxy type to strings used by protocol-proxy-servce + this.proxyType = proxyType === "socks5" ? "socks" : "socks4"; + this.proxyAddress = addr; + this.proxyPort = port; + + break; + } + // terminal + case "CMETHODS": { + if (args.length !== 1 || args[0] !== "DONE") { + keywordError = true; + } + break; + } + // errors (all fall through): + case "VERSION-ERROR": + case "ENV-ERROR": + case "PROXY-ERROR": + case "CMETHOD-ERROR": + throw new Error(`MeekTransport: ${keyword} => '${argsJoined}'`); + } + if (keywordError) { + throw new Error( + `MeekTransport: Invalid ${keyword} keyword args => '${argsJoined}'` + ); + } + } + + // register callback to cleanup on process exit + this.#meekClientProcess.wait().then(exitObj => { + this.#meekClientProcess = null; + this.uninit(); + }); + [this.proxyUsername, this.proxyPassword] = makeMeekCredentials( + this.proxyType, + reflector, + front + ); + this.#inited = true; + } catch (ex) { + if (this.#meekClientProcess) { + this.#meekClientProcess.kill(); + this.#meekClientProcess = null; + } + throw ex; + } + } + + async uninit() { + this.#inited = false; + + await this.#meekClientProcess?.kill(); + this.#meekClientProcess = null; + this.proxyType = null; + this.proxyAddress = null; + this.proxyPort = 0; + this.proxyUsername = null; + this.proxyPassword = null; + } +} + +/** + * Android implementation of the Meek process. + * + * GeckoView does not provide the subprocess module, so we have to use the + * EventDispatcher, and have a Java handler start and stop the proxy process. + */ +class MeekTransportAndroid { + // These members are used by consumers to setup the proxy to do requests over + // meek. They are passed to newProxyInfoWithAuth. + proxyType = null; + proxyAddress = null; + proxyPort = 0; + proxyUsername = null; + proxyPassword = null; + + /** + * An id for process this instance is linked to. + * + * Since we do not restrict the transport to be a singleton, we need a handle to + * identify the process we want to stop when the transport owner is done. + * We use a counter incremented on the Java side for now. + * + * This number must be a positive integer (i.e., 0 is an invalid handler). + * + * @type {number} + */ + #id = 0; + + async init(reflector, front) { + // ensure we haven't already init'd + if (this.#id) { + throw new Error("MeekTransport: Already initialized"); + } + const details = await lazy.EventDispatcher.instance.sendRequestForResult({ + type: "GeckoView:Tor:StartMeek", + }); + this.#id = details.id; + this.proxyType = "socks"; + this.proxyAddress = details.address; + this.proxyPort = details.port; + [this.proxyUsername, this.proxyPassword] = makeMeekCredentials( + this.proxyType, + reflector, + front + ); + } + + async uninit() { + lazy.EventDispatcher.instance.sendRequest({ + type: "GeckoView:Tor:StopMeek", + id: this.#id, + }); + this.#id = 0; + this.proxyType = null; + this.proxyAddress = null; + this.proxyPort = 0; + this.proxyUsername = null; + this.proxyPassword = null; + } +} + +/** + * Callback object to promisify the XPCOM request. + */ +class ResponseListener { + #response = ""; + #responsePromise; + #resolve; + #reject; + constructor() { + this.#response = ""; + // we need this promise here because await nsIHttpChannel::asyncOpen does + // not return only once the request is complete, it seems to return + // after it begins, so we have to get the result from this listener object. + // This promise is only resolved once onStopRequest is called + this.#responsePromise = new Promise((resolve, reject) => { + this.#resolve = resolve; + this.#reject = reject; + }); + } + + // callers wait on this for final response + response() { + return this.#responsePromise; + } + + // noop + onStartRequest(request) {} + + // resolve or reject our Promise + onStopRequest(request, status) { + try { + if (!Components.isSuccessCode(status)) { + const errorMessage = + lazy.TorLauncherUtil.getLocalizedStringForError(status); + this.#reject(new Error(errorMessage)); + } + if (request.responseStatus !== 200) { + this.#reject(new Error(request.responseStatusText)); + } + } catch (err) { + this.#reject(err); + } + this.#resolve(this.#response); + } + + // read response data + onDataAvailable(request, stream, offset, length) { + const scriptableStream = Cc[ + "@mozilla.org/scriptableinputstream;1" + ].createInstance(Ci.nsIScriptableInputStream); + scriptableStream.init(stream); + this.#response += scriptableStream.read(length); + } +} + +// constructs the json objects and sends the request over moat +export class DomainFrontRequestBuilder { + #inited = false; + #meekTransport = null; + + get inited() { + return this.#inited; + } + + async init(reflector, front) { + if (this.#inited) { + throw new Error("MoatRPC: Already initialized"); + } + + const meekTransport = + Services.appinfo.OS === "Android" + ? new MeekTransportAndroid() + : new MeekTransport(); + await meekTransport.init(reflector, front); + this.#meekTransport = meekTransport; + this.#inited = true; + } + + async uninit() { + await this.#meekTransport?.uninit(); + this.#meekTransport = null; + this.#inited = false; + } + + buildHttpHandler(uriString) { + if (!this.#inited) { + throw new Error("MoatRPC: Not initialized"); + } + + const { proxyType, proxyAddress, proxyPort, proxyUsername, proxyPassword } = + this.#meekTransport; + + const proxyPS = Cc[ + "@mozilla.org/network/protocol-proxy-service;1" + ].getService(Ci.nsIProtocolProxyService); + const flags = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST; + const noTimeout = 0xffffffff; // UINT32_MAX + const proxyInfo = proxyPS.newProxyInfoWithAuth( + proxyType, + proxyAddress, + proxyPort, + proxyUsername, + proxyPassword, + undefined, + undefined, + flags, + noTimeout, + undefined + ); + + const uri = Services.io.newURI(uriString); + // There does not seem to be a way to directly create an nsILoadInfo from + // JavaScript, so we create a throw away non-proxied channel to get one. + const secFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL; + const loadInfo = Services.io.newChannelFromURI( + uri, + undefined, + Services.scriptSecurityManager.getSystemPrincipal(), + undefined, + secFlags, + Ci.nsIContentPolicy.TYPE_OTHER + ).loadInfo; + + const httpHandler = Services.io + .getProtocolHandler("http") + .QueryInterface(Ci.nsIHttpProtocolHandler); + const ch = httpHandler + .newProxiedChannel(uri, proxyInfo, 0, undefined, loadInfo) + .QueryInterface(Ci.nsIHttpChannel); + + // remove all headers except for 'Host" + const headers = []; + ch.visitRequestHeaders({ + visitHeader: (key, val) => { + if (key !== "Host") { + headers.push(key); + } + }, + }); + headers.forEach(key => ch.setRequestHeader(key, "", false)); + + return ch; + } + + /** + * Make a POST request with a JSON body. + * + * @param {string} url The URL to load + * @param {object} args The arguments to send to the procedure. It will be + * serialized to JSON by this function and then set as POST body + * @returns {Promise<object>} A promise with the parsed response + */ + async buildPostRequest(url, args) { + const ch = this.buildHttpHandler(url); + + const argsJson = JSON.stringify(args); + const inStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + inStream.setData(argsJson, argsJson.length); + const upChannel = ch.QueryInterface(Ci.nsIUploadChannel); + const contentType = "application/vnd.api+json"; + upChannel.setUploadStream(inStream, contentType, argsJson.length); + ch.requestMethod = "POST"; + + // Make request + const listener = new ResponseListener(); + await ch.asyncOpen(listener, ch); + + // wait for response + const responseJSON = await listener.response(); + + // parse that JSON + return JSON.parse(responseJSON); + } +} ===================================== toolkit/modules/Moat.sys.mjs ===================================== @@ -10,10 +10,8 @@ import { const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { - EventDispatcher: "resource://gre/modules/Messaging.sys.mjs", - Subprocess: "resource://gre/modules/Subprocess.sys.mjs", - TorLauncherUtil: "resource://gre/modules/TorLauncherUtil.sys.mjs", - TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs", + DomainFrontRequestBuilder: + "resource://gre/modules/DomainFrontedRequests.sys.mjs", }); const TorLauncherPrefs = Object.freeze({ @@ -22,372 +20,9 @@ const TorLauncherPrefs = Object.freeze({ moat_service: "extensions.torlauncher.moat_service", }); -function makeMeekCredentials(proxyType) { - // Construct the per-connection arguments. - let meekClientEscapedArgs = ""; - const meekReflector = Services.prefs.getStringPref( - TorLauncherPrefs.bridgedb_reflector - ); - - // Escape aValue per section 3.5 of the PT specification: - // First the "<Key>=<Value>" formatted arguments MUST be escaped, - // such that all backslash, equal sign, and semicolon characters - // are escaped with a backslash. - const escapeArgValue = aValue => - aValue - ? aValue - .replaceAll("\\", "\\\\") - .replaceAll("=", "\\=") - .replaceAll(";", "\\;") - : ""; - - if (meekReflector) { - meekClientEscapedArgs += "url="; - meekClientEscapedArgs += escapeArgValue(meekReflector); - } - const meekFront = Services.prefs.getStringPref( - TorLauncherPrefs.bridgedb_front - ); - if (meekFront) { - if (meekClientEscapedArgs.length) { - meekClientEscapedArgs += ";"; - } - meekClientEscapedArgs += "front="; - meekClientEscapedArgs += escapeArgValue(meekFront); - } - - // socks5 - if (proxyType === "socks") { - if (meekClientEscapedArgs.length <= 255) { - return [meekClientEscapedArgs, "\x00"]; - } else { - return [ - meekClientEscapedArgs.substring(0, 255), - meekClientEscapedArgs.substring(255), - ]; - } - // socks4 - } else { - return [meekClientEscapedArgs, undefined]; - } -} - -// -// Launches and controls the PT process lifetime -// -class MeekTransport { - // These members are used by consumers to setup the proxy to do requests over - // meek. They are passed to newProxyInfoWithAuth. - proxyType = null; - proxyAddress = null; - proxyPort = 0; - proxyUsername = null; - proxyPassword = null; - - #inited = false; - #meekClientProcess = null; - - // launches the meekprocess - async init() { - // ensure we haven't already init'd - if (this.#inited) { - throw new Error("MeekTransport: Already initialized"); - } - - try { - // figure out which pluggable transport to use - const supportedTransports = ["meek", "meek_lite"]; - const provider = await lazy.TorProviderBuilder.build(); - const proxy = (await provider.getPluggableTransports()).find( - pt => - pt.type === "exec" && - supportedTransports.some(t => pt.transports.includes(t)) - ); - if (!proxy) { - throw new Error("No supported transport found."); - } - - const meekTransport = proxy.transports.find(t => - supportedTransports.includes(t) - ); - // Convert meek client path to absolute path if necessary - const meekWorkDir = lazy.TorLauncherUtil.getTorFile( - "pt-startup-dir", - false - ); - if (lazy.TorLauncherUtil.isPathRelative(proxy.pathToBinary)) { - const meekPath = meekWorkDir.clone(); - meekPath.appendRelativePath(proxy.pathToBinary); - proxy.pathToBinary = meekPath.path; - } - - // Setup env and start meek process - const ptStateDir = lazy.TorLauncherUtil.getTorFile("tordatadir", false); - ptStateDir.append("pt_state"); // Match what tor uses. - - const envAdditions = { - TOR_PT_MANAGED_TRANSPORT_VER: "1", - TOR_PT_STATE_LOCATION: ptStateDir.path, - TOR_PT_EXIT_ON_STDIN_CLOSE: "1", - TOR_PT_CLIENT_TRANSPORTS: meekTransport, - }; - if (TorSettings.proxy.enabled) { - envAdditions.TOR_PT_PROXY = TorSettings.proxy.uri; - } - - const opts = { - command: proxy.pathToBinary, - arguments: proxy.options.split(/s+/), - workdir: meekWorkDir.path, - environmentAppend: true, - environment: envAdditions, - stderr: "pipe", - }; - - // Launch meek client - this.#meekClientProcess = await lazy.Subprocess.call(opts); - - // Callback chain for reading stderr - const stderrLogger = async () => { - while (this.#meekClientProcess) { - const errString = await this.#meekClientProcess.stderr.readString(); - if (errString) { - console.log(`MeekTransport: stderr => ${errString}`); - } - } - }; - stderrLogger(); - - // Read pt's stdout until terminal (CMETHODS DONE) is reached - // returns array of lines for parsing - const getInitLines = async (stdout = "") => { - stdout += await this.#meekClientProcess.stdout.readString(); - - // look for the final message - const CMETHODS_DONE = "CMETHODS DONE"; - let endIndex = stdout.lastIndexOf(CMETHODS_DONE); - if (endIndex != -1) { - endIndex += CMETHODS_DONE.length; - return stdout.substring(0, endIndex).split("\n"); - } - return getInitLines(stdout); - }; - - // read our lines from pt's stdout - const meekInitLines = await getInitLines(); - // tokenize our pt lines - const meekInitTokens = meekInitLines.map(line => { - const tokens = line.split(" "); - return { - keyword: tokens[0], - args: tokens.slice(1), - }; - }); - - // parse our pt tokens - for (const { keyword, args } of meekInitTokens) { - const argsJoined = args.join(" "); - let keywordError = false; - switch (keyword) { - case "VERSION": { - if (args.length != 1 || args[0] !== "1") { - keywordError = true; - } - break; - } - case "PROXY": { - if (args.length != 1 || args[0] !== "DONE") { - keywordError = true; - } - break; - } - case "CMETHOD": { - if (args.length != 3) { - keywordError = true; - break; - } - const transport = args[0]; - const proxyType = args[1]; - const addrPortString = args[2]; - const addrPort = addrPortString.split(":"); - - if (transport !== meekTransport) { - throw new Error( - `MeekTransport: Expected ${meekTransport} but found ${transport}` - ); - } - if (!["socks4", "socks4a", "socks5"].includes(proxyType)) { - throw new Error( - `MeekTransport: Invalid proxy type => ${proxyType}` - ); - } - if (addrPort.length != 2) { - throw new Error( - `MeekTransport: Invalid proxy address => ${addrPortString}` - ); - } - const addr = addrPort[0]; - const port = parseInt(addrPort[1]); - if (port < 1 || port > 65535) { - throw new Error(`MeekTransport: Invalid proxy port => ${port}`); - } - - // convert proxy type to strings used by protocol-proxy-servce - this.proxyType = proxyType === "socks5" ? "socks" : "socks4"; - this.proxyAddress = addr; - this.proxyPort = port; - - break; - } - // terminal - case "CMETHODS": { - if (args.length != 1 || args[0] !== "DONE") { - keywordError = true; - } - break; - } - // errors (all fall through): - case "VERSION-ERROR": - case "ENV-ERROR": - case "PROXY-ERROR": - case "CMETHOD-ERROR": - throw new Error(`MeekTransport: ${keyword} => '${argsJoined}'`); - } - if (keywordError) { - throw new Error( - `MeekTransport: Invalid ${keyword} keyword args => '${argsJoined}'` - ); - } - } - - // register callback to cleanup on process exit - this.#meekClientProcess.wait().then(exitObj => { - this.#meekClientProcess = null; - this.uninit(); - }); - [this.proxyUsername, this.proxyPassword] = makeMeekCredentials( - this.proxyType - ); - this.#inited = true; - } catch (ex) { - if (this.#meekClientProcess) { - this.#meekClientProcess.kill(); - this.#meekClientProcess = null; - } - throw ex; - } - } - - async uninit() { - this.#inited = false; - - await this.#meekClientProcess?.kill(); - this.#meekClientProcess = null; - this.proxyType = null; - this.proxyAddress = null; - this.proxyPort = 0; - this.proxyUsername = null; - this.proxyPassword = null; - } -} - -class MeekTransportAndroid { - // These members are used by consumers to setup the proxy to do requests over - // meek. They are passed to newProxyInfoWithAuth. - proxyType = null; - proxyAddress = null; - proxyPort = 0; - proxyUsername = null; - proxyPassword = null; - - #id = 0; - - async init() { - // ensure we haven't already init'd - if (this.#id) { - throw new Error("MeekTransport: Already initialized"); - } - const details = await lazy.EventDispatcher.instance.sendRequestForResult({ - type: "GeckoView:Tor:StartMeek", - }); - this.#id = details.id; - this.proxyType = "socks"; - this.proxyAddress = details.address; - this.proxyPort = details.port; - [this.proxyUsername, this.proxyPassword] = makeMeekCredentials( - this.proxyType - ); - } - - async uninit() { - lazy.EventDispatcher.instance.sendRequest({ - type: "GeckoView:Tor:StopMeek", - id: this.#id, - }); - this.#id = 0; - this.proxyType = null; - this.proxyAddress = null; - this.proxyPort = 0; - this.proxyUsername = null; - this.proxyPassword = null; - } -} - -// -// Callback object with a cached promise for the returned Moat data -// -class MoatResponseListener { - #response = ""; - #responsePromise; - #resolve; - #reject; - constructor() { - this.#response = ""; - // we need this promise here because await nsIHttpChannel::asyncOpen does - // not return only once the request is complete, it seems to return - // after it begins, so we have to get the result from this listener object. - // This promise is only resolved once onStopRequest is called - this.#responsePromise = new Promise((resolve, reject) => { - this.#resolve = resolve; - this.#reject = reject; - }); - } - - // callers wait on this for final response - response() { - return this.#responsePromise; - } - - // noop - onStartRequest(request) {} - - // resolve or reject our Promise - onStopRequest(request, status) { - try { - if (!Components.isSuccessCode(status)) { - const errorMessage = - lazy.TorLauncherUtil.getLocalizedStringForError(status); - this.#reject(new Error(errorMessage)); - } - if (request.responseStatus != 200) { - this.#reject(new Error(request.responseStatusText)); - } - } catch (err) { - this.#reject(err); - } - this.#resolve(this.#response); - } - - // read response data - onDataAvailable(request, stream, offset, length) { - const scriptableStream = Cc[ - "@mozilla.org/scriptableinputstream;1" - ].createInstance(Ci.nsIScriptableInputStream); - scriptableStream.init(stream); - this.#response += scriptableStream.read(length); - } -} - +/** + * A special response listener that collects the received headers. + */ class InternetTestResponseListener { #promise; #resolve; @@ -436,129 +71,45 @@ class InternetTestResponseListener { } } -// constructs the json objects and sends the request over moat +/** + * Constructs JSON objects and sends requests over Moat. + * The documentation about the JSON schemas to use are available at + * https://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/blob/main/doc/moa…. + */ export class MoatRPC { - #inited = false; - #meekTransport = null; - - get inited() { - return this.#inited; - } + #requestBuilder = null; async init() { - if (this.#inited) { - throw new Error("MoatRPC: Already initialized"); + if (this.#requestBuilder !== null) { + return; } - const meekTransport = - Services.appinfo.OS === "Android" - ? new MeekTransportAndroid() - : new MeekTransport(); - await meekTransport.init(); - this.#meekTransport = meekTransport; - this.#inited = true; + const reflector = Services.prefs.getStringPref( + TorLauncherPrefs.bridgedb_reflector + ); + const front = Services.prefs.getStringPref(TorLauncherPrefs.bridgedb_front); + const builder = new lazy.DomainFrontRequestBuilder(); + await builder.init(reflector, front); + this.#requestBuilder = builder; } async uninit() { - await this.#meekTransport?.uninit(); - this.#meekTransport = null; - this.#inited = false; - } - - #makeHttpHandler(uriString) { - if (!this.#inited) { - throw new Error("MoatRPC: Not initialized"); - } - - const { proxyType, proxyAddress, proxyPort, proxyUsername, proxyPassword } = - this.#meekTransport; - - const proxyPS = Cc[ - "@mozilla.org/network/protocol-proxy-service;1" - ].getService(Ci.nsIProtocolProxyService); - const flags = Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST; - const noTimeout = 0xffffffff; // UINT32_MAX - const proxyInfo = proxyPS.newProxyInfoWithAuth( - proxyType, - proxyAddress, - proxyPort, - proxyUsername, - proxyPassword, - undefined, - undefined, - flags, - noTimeout, - undefined - ); - - const uri = Services.io.newURI(uriString); - // There does not seem to be a way to directly create an nsILoadInfo from - // JavaScript, so we create a throw away non-proxied channel to get one. - const secFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL; - const loadInfo = Services.io.newChannelFromURI( - uri, - undefined, - Services.scriptSecurityManager.getSystemPrincipal(), - undefined, - secFlags, - Ci.nsIContentPolicy.TYPE_OTHER - ).loadInfo; - - const httpHandler = Services.io - .getProtocolHandler("http") - .QueryInterface(Ci.nsIHttpProtocolHandler); - const ch = httpHandler - .newProxiedChannel(uri, proxyInfo, 0, undefined, loadInfo) - .QueryInterface(Ci.nsIHttpChannel); - - // remove all headers except for 'Host" - const headers = []; - ch.visitRequestHeaders({ - visitHeader: (key, val) => { - if (key !== "Host") { - headers.push(key); - } - }, - }); - headers.forEach(key => ch.setRequestHeader(key, "", false)); - - return ch; + await this.#requestBuilder?.uninit(); + this.#requestBuilder = null; } async #makeRequest(procedure, args) { const procedureURIString = `${Services.prefs.getStringPref( TorLauncherPrefs.moat_service )}/${procedure}`; - const ch = this.#makeHttpHandler(procedureURIString); - - // Arrange for the POST data to be sent. - const argsJson = JSON.stringify(args); - - const inStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( - Ci.nsIStringInputStream - ); - inStream.setData(argsJson, argsJson.length); - const upChannel = ch.QueryInterface(Ci.nsIUploadChannel); - const contentType = "application/vnd.api+json"; - upChannel.setUploadStream(inStream, contentType, argsJson.length); - ch.requestMethod = "POST"; - - // Make request - const listener = new MoatResponseListener(); - await ch.asyncOpen(listener, ch); - - // wait for response - const responseJSON = await listener.response(); - - // parse that JSON - return JSON.parse(responseJSON); + return this.#requestBuilder.buildPostRequest(procedureURIString, args); } async testInternetConnection() { const uri = `${Services.prefs.getStringPref( TorLauncherPrefs.moat_service )}/circumvention/countries`; - const ch = this.#makeHttpHandler(uri); + const ch = this.#requestBuilder.buildHttpHandler(uri); ch.requestMethod = "HEAD"; const listener = new InternetTestResponseListener(); @@ -566,10 +117,6 @@ export class MoatRPC { return listener.status; } - // - // Moat APIs - // - // Receive a CAPTCHA challenge, takes the following parameters: // - transports: array of transport strings available to us eg: ["obfs4", "meek"] // ===================================== toolkit/modules/moz.build ===================================== @@ -166,6 +166,7 @@ EXTRA_JS_MODULES += [ "DateTimePickerPanel.sys.mjs", "DeferredTask.sys.mjs", "Deprecated.sys.mjs", + "DomainFrontedRequests.sys.mjs", "DragDropFilter.sys.mjs", "E10SUtils.sys.mjs", "EventEmitter.sys.mjs", View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/da0f310… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/da0f310… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser-build][maint-13.0] Bug 41063: Run "file $keyring" in tools/keyring/list-all-keyrings
by richard (@richard) 11 Jan '24

11 Jan '24
richard pushed to branch maint-13.0 at The Tor Project / Applications / tor-browser-build Commits: aa5571de by Nicolas Vigier at 2024-01-11T15:30:06+00:00 Bug 41063: Run &quot;file $keyring&quot; in tools/keyring/list-all-keyrings (cherry picked from commit 0fe87b4a9c5645157297106da33991d4e5a7dc3c) - - - - - 1 changed file: - tools/keyring/list-all-keyrings Changes: ===================================== tools/keyring/list-all-keyrings ===================================== @@ -6,5 +6,6 @@ set -e cd $(dirname "$0")/../.. for keyring in ./keyring/*.gpg do + file "$keyring" gpg --no-auto-check-trustdb --list-options show-unusable-subkeys,show-keyring --no-default-keyring --list-keys --keyring "$keyring" done View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/a… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/a… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/tor-browser-build][main] Bug 41063: Run "file $keyring" in tools/keyring/list-all-keyrings
by richard (@richard) 11 Jan '24

11 Jan '24
richard pushed to branch main at The Tor Project / Applications / tor-browser-build Commits: 0fe87b4a by Nicolas Vigier at 2024-01-11T10:47:16+01:00 Bug 41063: Run &quot;file $keyring&quot; in tools/keyring/list-all-keyrings - - - - - 1 changed file: - tools/keyring/list-all-keyrings Changes: ===================================== tools/keyring/list-all-keyrings ===================================== @@ -6,5 +6,6 @@ set -e cd $(dirname "$0")/../.. for keyring in ./keyring/*.gpg do + file "$keyring" gpg --no-auto-check-trustdb --list-options show-unusable-subkeys,show-keyring --no-default-keyring --list-keys --keyring "$keyring" done View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/0… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser-build/-/commit/0… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
[Git][tpo/applications/torbrowser-launcher][main] Depend on dbus-glib
by boklm (@boklm) 11 Jan '24

11 Jan '24
boklm pushed to branch main at The Tor Project / Applications / torbrowser-launcher Commits: 961da39f by Vecna at 2024-01-11T09:57:30+00:00 Depend on dbus-glib - - - - - 1 changed file: - build_rpm.sh Changes: ===================================== build_rpm.sh ===================================== @@ -6,7 +6,7 @@ VERSION=$(cat share/torbrowser-launcher/version) rm -r build dist # build binary package -python3 setup.py bdist_rpm --requires="python3-qt5, python3-gpg, python3-requests, python3-pysocks, python3-packaging, gnupg2" +python3 setup.py bdist_rpm --requires="python3-qt5, python3-gpg, python3-requests, python3-pysocks, python3-packaging, gnupg2, dbus-glib" # install it echo "" View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/commit… You're receiving this email because of your account on gitlab.torproject.org.
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • ...
  • 1864
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.