10-tbb 14.8 KB
Newer Older
1 2
#!/bin/sh

3 4
set -e
set -u
5 6 7

echo "Install the Tor Browser"

8 9 10 11 12 13 14
# Import the TBB_INSTALL, TBB_PROFILE, TBB_EXT and
# TOR_LAUNCHER_INSTALL variables, which contains the paths we will
# split TBB's actual browser (binaries etc), user data and extension
# into. While this differs from how the TBB organizes the files, the
# end result will be the same, and it's practical since when creating
# a new browser profile we can simply copy the profile directory
# without duplicating all extensions.
15
. /usr/local/lib/tails-shell-library/tor-browser.sh
intrigeri's avatar
intrigeri committed
16
# Import install_fake_package and strip_nondeterminism_wrapper
17
. /usr/local/lib/tails-shell-library/build.sh
18 19

download_and_verify_files() {
20
    local base_url target_files destination apt_proxy
21
    base_url="${1}"
22
    target_files="${2}"
23 24 25 26 27 28 29 30 31 32 33
    destination="${3}"

    # Use the builder's caching APT proxy, if any
    apt_proxy="$(apt-config --format '%v' dump Acquire::http::Proxy)"
    if [ -n "${apt_proxy}" ]; then
        export HTTP_PROXY="${apt_proxy}"
        export http_proxy="${apt_proxy}"
        export HTTPS_PROXY="${apt_proxy}"
        export https_proxy="${apt_proxy}"
    fi

34
    echo "${target_files}" | while read expected_sha256 tarball; do
35 36 37
        (
            cd "${destination}"
            echo "Fetching ${base_url}/${tarball} ..."
38
            curl --retry 20 --remote-name "${base_url}/${tarball}"
39 40 41 42 43 44 45 46 47
        )
        actual_sha256="$(sha256sum "${destination}/${tarball}" | cut -d' ' -f1)"
        if [ "${actual_sha256}" != "${expected_sha256}" ]; then
            echo "SHA256 mismatch for ${tarball}" >&2
            exit 1
        fi
    done
}

48
install_tor_browser() {
49
    local bundle destination tmp prep
50 51 52 53
    bundle="${1}"
    destination="${2}"

    tmp="$(mktemp -d)"
54 55 56 57 58 59 60 61 62 63
    tar -xf "${bundle}" -C "${tmp}"
    if [ -d "${tmp}"/tor-browser_en-US ]; then
        prep="${tmp}"/tor-browser_en-US/Browser
    elif [ -d "${tmp}"/tor-browser ]; then
        # TBB nightly builds
        prep="${tmp}"/tor-browser/Browser
    else
        echo "The main bundle's top level directory is wrong" >&2
        exit 1
    fi
64 65 66 67

    # Enable our myspell/hunspell dictionaries. TBB only provides the
    # one for en-US, but Debian's seems more comprehensive, so we'll
    # only use Debian's dictionaries.
68
    mkdir "${prep}"/dictionaries
69
    for f in /usr/share/hunspell/*.aff /usr/share/hunspell/*.dic; do
Tails developers's avatar
Tails developers committed
70
        ln -s "${f}" "${prep}"/dictionaries/
71 72
    done

intrigeri's avatar
intrigeri committed
73
    # Let's use the libstdc++ that the Tor Browser is intended to be used with,
74 75 76
    # instead of the system one, whenever ours is too old.
    # For details see projects/firefox/abicheck.cc in
    # https://git.torproject.org/builders/tor-browser-build.git
77
    cp "${prep}"/TorBrowser/Tor/libstdc++/libstdc++.so.6 "${prep}"
78 79 80

    # We don't need the Tor binary, the shared libraries Tor needs
    # (but Firefox doesn't) and documentation shipped in the TBB.
81 82
    rm -r "${prep}"/TorBrowser/Tor "${prep}"/TorBrowser/Docs

83 84 85 86 87 88 89 90
    # The Tor Browser will fail, complaining about an incomplete profile,
    # unless there's a readable TorBrowser/Data/Browser/Caches
    # in the directory where the firefox executable is located.
    mkdir -p "${prep}"/TorBrowser/Data/Browser/Caches

    # Otherwise the "General" section in the preferences is not displayed.
    install -d -m 0755 "${prep}"/TorBrowser/UpdateInfo

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
    # Apply 10.0-build2 → 10.0-build3 changes:
    (
        local tmp
        tmp="$(mktemp -d)"
        cd "${tmp}"
        7z x -tzip "${prep}/browser/omni.ja"
        # Any $ in the below in-line patch must be escaped!
        patch -p1 <<EOF
commit fb9428098b5b85eed400daa6e0010ac63faf8848 (tag: tor-browser-78.3.0esr-10.0-2-build2, origin/tor-browser-78.3.0esr-10.0-2)
Author: Matthew Finkel <sysrqb@torproject.org>
Date:   Sat Sep 19 17:03:53 2020 +0000

    Revert "fixup! TB4: Tor Browser's Firefox preference overrides."
    
    This reverts commit c386fb3312237fd6c0d123ba9aaad662f8740e56.
    
    We continue using the old webextensions storage backend due to #40137.

diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index bac98ce06540..7e29c788b720 100644
--- a/defaults/preferences/000-tor-browser.js
+++ b/defaults/preferences/000-tor-browser.js
@@ -286,6 +286,8 @@ pref("extensions.htmlaboutaddons.recommendations.enabled", false);
 pref("extensions.legacy.exceptions", "{972ce4c6-7e08-4474-a285-3208198ce6fd},torbutton@torproject.org");
 // Bug 26114: Allow NoScript to access addons.mozilla.org etc.
 pref("extensions.webextensions.restrictedDomains", "");
+// Bug 31396: Disable indexedDB WebExtension storage backend.
+pref("extensions.webextensions.ExtensionStorageIDB.enabled", false);
 // Bug 28896: Make sure our bundled WebExtensions are running in Private Browsing Mode
 pref("extensions.allowPrivateBrowsingByDefault", true);
 
EOF
        touch --date="@${TBB_TIMESTAMP:?}" defaults/preferences/000-tor-browser.js
        rm "${prep}/browser/omni.ja"
        7z a -mtc=off -tzip "${prep}/browser/omni.ja" *
        rm -r "${tmp}"
    )
    
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    mv "${prep}" "${destination}"
    rm -r "${tmp}"
}

# Install Tor Launcher as a standalone XUL application.
install_tor_launcher() {
    local tbb_install destination tmp
    tbb_install="${1}"
    destination="${2}"

    tmp="$(mktemp -d)"
    7z x -o"${tmp}" "${tbb_install}/browser/omni.ja"
    mv "${tmp}/chrome/torlauncher/" "${destination}"
    # Tor Launcher is a system add-on but can be converted to
    # something that works as a XUL standalone application by just
    # moving things around:
145
    mkdir "${destination}/chrome"
146
    for x in content locale skin; do
intrigeri's avatar
intrigeri committed
147
        mv "${destination}/${x}" "${destination}/chrome/"
148 149 150 151 152 153 154 155 156 157 158 159 160 161
    done
    mkdir -p "${destination}"/defaults/preferences
    cp "${tmp}/defaults/preferences/torlauncher-prefs.js" \
       "${destination}/defaults/preferences/prefs.js"
    # ... and then we extract only the Tor Launcher parts from the
    # manifest, and adapt to how we moved files around above:
    grep torlauncher "${tmp}/chrome//chrome.manifest" \
        | sed --regexp-extended \
              -e 's@^(content|locale|skin) (torlauncher.*) torlauncher/(.*)$@\1 \2 chrome/\3@' \
              -e 's@^(component) (\S+) torlauncher/(.+)$@\1 \2 \3@' \
              -e 's@^(resource torlauncher) .*$@\1 ./@' \
        > "${destination}/chrome.manifest"
    cp "${destination}/chrome/skin/default48.png" "${destination}/icon.png"
    cat > "${destination}/application.ini" << EOF
162 163 164
[App]
Vendor=TorProject
Name=TorLauncher
165 166
Version=$(get_firefox_version "${tbb_install}/application.ini")
BuildID=$(date --utc --date="@$SOURCE_DATE_EPOCH" '+%Y%m%d')
167 168 169
ID=tor-launcher@torproject.org

[Gecko]
170
MinVersion=$(get_firefox_version "${tbb_install}/application.ini")
171 172 173 174 175
MaxVersion=*.*.*

[Shell]
Icon=icon.png
EOF
176
    chmod -R a+rX "${destination}"
177 178 179
    rm -r "${tmp}"
}

anonym's avatar
anonym committed
180 181
embed_extensions_in_omni_ja () {
    local tbb_install tbb_timestamp tmp
182
    tbb_install="${1}"
183
    tbb_timestamp="${2}"
184

185 186 187
    tmp="$(mktemp -d)"
    (
        cd "${tmp}"
188
        7z x -tzip "${tbb_install}/omni.ja"
189 190
        cp -a '/usr/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}/uBlock0@raymondhill.net' chrome/torbutton/content/extensions/
        find chrome/torbutton/content/extensions/ -exec touch --date="@${tbb_timestamp}" '{}' \;
191 192
        rm "${tbb_install}/omni.ja"
        7z a -mtc=off -tzip "${tbb_install}/omni.ja" *
193 194 195 196 197
    )
    rm -r "${tmp}"
    tmp="$(mktemp -d)"
    (
        cd "${tmp}"
198
        7z x -tzip "${tbb_install}/browser/omni.ja"
199
        # Any $ in the below in-line patch must be escaped!
200
        patch -p1 <<EOF
201
diff -Naur browser-omni.orig/modules/BrowserGlue.jsm browser-omni/modules/BrowserGlue.jsm
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
--- browser-omni.orig/modules/BrowserGlue.jsm	2020-09-11 19:25:00.000000000 +0200
+++ browser-omni/modules/BrowserGlue.jsm	2020-09-19 11:44:17.439692582 +0200
@@ -1367,6 +1367,29 @@
       }
     })();
 
+    (async () => {
+      const UBLOCK_ORIGIN_ID = "uBlock0@raymondhill.net";
+      const UBLOCK_ORIGIN_BUILTIN_URL =
+        "resource://torbutton/content/extensions/uBlock0@raymondhill.net/";
+      try {
+        const resolvedURI = Services.io.newURI(
+          resProto.resolveURI(Services.io.newURI(UBLOCK_ORIGIN_BUILTIN_URL))
+        );
+        const extensionData = new ExtensionData(resolvedURI);
+        const manifest = await extensionData.loadManifest();
+
+        await AddonManager.maybeInstallBuiltinAddon(
+          UBLOCK_ORIGIN_ID,
+          manifest.version,
+          UBLOCK_ORIGIN_BUILTIN_URL
+        );
+      } catch (e) {
+        const log = Log.repository.getLogger("uBlockOriginBuiltinLoader");
+        log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()));
+        log.error("Could not install uBlock Origin extension", e);
+      }
+    })();
+
     if (AppConstants.MOZ_NORMANDY) {
       Normandy.init();
     }
234
EOF
235
        touch --date="@${tbb_timestamp}" modules/BrowserGlue.jsm
236 237
        rm "${tbb_install}/browser/omni.ja"
        7z a -mtc=off -tzip "${tbb_install}/browser/omni.ja" *
238
    )
239
    rm -r "${tmp}"
240 241
}

242
apply_prefs_hacks() {
243 244
    local tbb_install tmp tbb_timestamp
    tbb_install="${1}"
245
    tbb_timestamp="${2}"
246 247 248 249 250 251

    tmp="$(mktemp -d)"
    (
        cd "${tmp}"
        7z x -tzip "${tbb_install}/browser/omni.ja"
        # Remove TBB's Tor Launcher settings since we don't enable it in
segfault's avatar
segfault committed
252 253 254 255 256 257
        # our Tor Browser.
        sed -i '/extensions\.torlauncher\./d' defaults/preferences/000-tor-browser.js
        # Display the Stop/Reload button: our test suite currently depends on it
        perl -pi -E \
            's/^(pref\("browser\.uiCustomization\.state",.*\\"loop-button\\")/$1,\\"stop-reload-button\\"/' \
            defaults/preferences/000-tor-browser.js
258

segfault's avatar
segfault committed
259 260 261 262 263 264
        # Append our custom prefs
        cat /usr/share/tails/tor-browser-prefs.js \
            >> defaults/preferences/000-tor-browser.js
        touch --date="@${tbb_timestamp}" defaults/preferences/000-tor-browser.js
            rm "${tbb_install}/browser/omni.ja"
            7z a -mtc=off -tzip "${tbb_install}/browser/omni.ja" *
265 266 267 268
    )
    rm -r "${tmp}"
}

269 270 271 272 273 274 275 276 277 278 279 280 281
disable_update_checks() {
    local tbb_install
    tbb_install="${1}"
    mkdir -p "${tbb_install}/distribution"
    cat > "${tbb_install}/distribution/policies.json" <<EOF
{
  "policies": {
    "DisableAppUpdate": true
  }
}
EOF
}

282
strip_nondeterminism () {
283
    local tbb_install tbb_timestamp
284
    tbb_install="${1}"
285 286
    tbb_timestamp="${2}"

287 288 289 290 291 292
    for archive in "${tbb_install}/omni.ja" "${tbb_install}/browser/omni.ja"; do
        strip_nondeterminism_wrapper --type zip --timestamp "${tbb_timestamp}" \
                                     "${archive}" 2>/dev/null
    done
}

293 294 295
install_langpacks() {
    local langpacks_tarball destination tmp
    langpacks_tarball="${1}"
296 297
    destination="${2}"

298 299 300 301 302 303 304
    tmp="$(mktemp -d)"

    tar --directory="${tmp}" -xf "${langpacks_tarball}"
    for xpi in "${tmp}"/*.xpi; do
        locale="$(basename "${xpi}" .xpi)"
        dest_basename="langpack-${locale}@firefox.mozilla.org.xpi"
        [ "${locale}" = en-US ] || mv "${xpi}" "${destination}/${dest_basename}"
305
    done
306 307

    rm -r "${tmp}"
308 309
}

310 311 312 313 314 315 316 317
get_firefox_version() {
    # The application.ini file
    local appini
    appini="${1}"
    sed -n 's/^Version=\(.*\)$/\1/p' "${appini}"
}

install_debian_extensions() {
anonym's avatar
anonym committed
318
    local destination timestamp fake_firefox_version firefox_version
319
    destination="${1}"
anonym's avatar
anonym committed
320 321 322 323 324 325 326 327 328
    timestamp="${2}"

    # Install a fake firefox equivs package to satisfy the
    # dependencies for the extensions we are about to install.
    firefox_version=$(get_firefox_version "${destination}"/application.ini)
    fake_firefox_version=${firefox_version}+fake1
    install_fake_package firefox "${fake_firefox_version}" web

    apt-get install --yes webext-ublock-origin
329
    patch -p1 < /usr/share/tails/uBlock-disable-autoUpdate.diff
anonym's avatar
anonym committed
330 331 332 333 334 335 336 337 338

    # Apply the same hack for our extension as the Tor Browser does
    # for HTTPS-Everywhere in order to bypass the mandatory extension
    # signature check, which we lack since we install our extensions
    # from Debian ...
    embed_extensions_in_omni_ja "${destination}" "${timestamp}"
    # ... and then remove the packages we just installed, since we
    # don't need them outside of omni.ja.
    apt purge --yes firefox webext-ublock-origin
339 340
}

341
create_default_profile() {
342 343 344
    local tbb_profile extensions_dir destination
    tbb_profile="${1}"
    tbb_extensions_dir="${2}"
345 346
    destination="${3}"

347
    rsync -a --exclude extensions \
348
          "${tbb_profile}"/ "${destination}"/
349 350

    mkdir -p "${destination}"/extensions
351
    for ext in "${tbb_extensions_dir}"/*; do
352 353 354 355
        ln -s "${ext}" "${destination}"/extensions/
    done
}

356 357 358 359
# For consistency we'll set timestamps of files we modify to the
# same one used by the Tor Browser instead of SOURCE_DATE_EPOCH.
TBB_TIMESTAMP="$(date --date='2000-01-01 00:00:00' +%s)"

Tails developers's avatar
Tails developers committed
360
TBB_SHA256SUMS_FILE=/usr/share/tails/tbb-sha256sums.txt
anonym's avatar
anonym committed
361 362
TBB_DIST_URL_FILE=/usr/share/tails/tbb-dist-url.txt
TBB_TARBALLS_BASE_URL="$(cat "${TBB_DIST_URL_FILE}")"
363
TBB_TARBALLS="$(grep "\<tor-browser-linux64-.*\.tar.xz$" "${TBB_SHA256SUMS_FILE}")"
364

365
# We'll use the en-US bundle as our basis
anonym's avatar
anonym committed
366
MAIN_TARBALL="$(echo "${TBB_TARBALLS}" | grep -o "tor-browser-linux64-.*_en-US\.tar\.xz")"
367
NIGHTLY_BUILD=
368
if echo "${TBB_TARBALLS}" | grep --quiet 'tor-browser-linux64-tbb-nightly'; then
369 370
    NIGHTLY_BUILD=yes
fi
371 372

TMP="$(mktemp -d)"
Tails developers's avatar
Tails developers committed
373
download_and_verify_files "${TBB_TARBALLS_BASE_URL}" "${TBB_TARBALLS}" "${TMP}"
374

Tails developers's avatar
Tails developers committed
375
install_tor_browser "${TMP}/${MAIN_TARBALL}" "${TBB_INSTALL}"
376
apply_prefs_hacks "${TBB_INSTALL}" "${TBB_TIMESTAMP}"
anonym's avatar
anonym committed
377
install_debian_extensions "${TBB_INSTALL}" "${TBB_TIMESTAMP}"
378
disable_update_checks "${TBB_INSTALL}"
379
strip_nondeterminism "${TBB_INSTALL}" "${TBB_TIMESTAMP}"
380
install_tor_launcher "${TBB_INSTALL}" "${TOR_LAUNCHER_INSTALL}"
381

382
mkdir -p "${TBB_EXT}"
383
if [ "${NIGHTLY_BUILD}" != yes ]; then
384 385
    LANGPACKS_TARBALL="$(echo "${TBB_TARBALLS}" | grep -o "langpacks-tor-browser-linux64-.*\.tar\.xz")"
    install_langpacks "${TMP}/${LANGPACKS_TARBALL}" "${TBB_EXT}"
386
fi
387

388 389
rm -r "${TMP}"

Tails developers's avatar
Tails developers committed
390
# Let's put all the extensions from TBB in the global extensions
391
# directory...
392 393
mv "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions/* "${TBB_EXT}"
rmdir "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions
394

395
mkdir -p "${TBB_PROFILE}"
396
create_default_profile "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default "${TBB_EXT}" "${TBB_PROFILE}"
397

398 399
# Create a copy of the Firefox binary, for use e.g. by Tor Launcher.
# It won't be subject to AppArmor confinement.
400
cp -a "${TBB_INSTALL}/firefox.real" "${TBB_INSTALL}/firefox-unconfined"
401

402 403
chown -R root:root "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
chmod -R a+rX "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
404

Tails developers's avatar
Tails developers committed
405
# Make the Tor Browser into the system's default web browser
406 407
update-alternatives --install /usr/bin/x-www-browser x-www-browser /usr/local/bin/tor-browser 99
update-alternatives --install /usr/bin/gnome-www-browser gnome-www-browser /usr/local/bin/tor-browser 99
408
sed 's/\<firefox-esr\.desktop\>/tor-browser.desktop/' \
409 410 411
    /usr/share/applications/gnome-mimeapps.list \
    > /etc/xdg/gnome-mimeapps.list
chmod 644 /etc/xdg/gnome-mimeapps.list