10-tbb 11.6 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
16
17
# Import install_fake_package
. /usr/local/lib/tails-shell-library/build.sh
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

download_and_verify_files() {
    local base_url bundles destination apt_proxy
    base_url="${1}"
    bundles="${2}"
    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

    echo "${bundles}" | while read expected_sha256 tarball; do
        (
            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 torlauncher_xpi_path torlauncher_version
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
    rm -f "${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
74
    # Let's use the libstdc++ that the Tor Browser is intended to be used with,
    # instead of the system one.
75
76
77
78
    cp "${prep}"/TorBrowser/Tor/libstdc++.so.6 "${prep}"

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

81
    # We don't want tor-launcher to be part of the regular browser
82
83
84
    # profile but we want to keep it as a standalone application
    # when Tails is started in "bridge mode".
    torlauncher_xpi_path="${prep}/TorBrowser/Data/Browser/profile.default/extensions/tor-launcher@torproject.org.xpi"
85
    7z x -o"${TOR_LAUNCHER_INSTALL}" "${torlauncher_xpi_path}"
86
87
    torlauncher_version="$(sed -n \
        's,^        <em:version>\([0-9\.]\+\)</em:version>,\1,p' \
88
        "${TOR_LAUNCHER_INSTALL}/install.rdf")"
89
    SOURCE_DATE_YYYYMMDD=$(date --utc --date="@$SOURCE_DATE_EPOCH" '+%Y%m%d')
90
    cat > "${TOR_LAUNCHER_INSTALL}/application.ini" << EOF
91
92
93
94
[App]
Vendor=TorProject
Name=TorLauncher
Version=${torlauncher_version}
95
BuildID=${SOURCE_DATE_YYYYMMDD}
96
97
98
99
100
101
102
103
104
ID=tor-launcher@torproject.org

[Gecko]
MinVersion=$(get_firefox_version "${prep}/application.ini")
MaxVersion=*.*.*

[Shell]
Icon=icon.png
EOF
105
    chmod -R a+rX "${TOR_LAUNCHER_INSTALL}"
106
    rm "${torlauncher_xpi_path}"
107
108

    # The Tor Browser will fail, complaining about an incomplete profile,
109
    # unless there's a readable TorBrowser/Data/Browser/Caches
110
    # in the directory where the firefox executable is located.
111
112
113
    mkdir -p "${prep}"/TorBrowser/Data/Browser/Caches

    mv "${prep}" "${destination}"
114
115
116
117

    rm -r "${tmp}"
}

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# TBB works around the lack of code signing for its extensions by
# hacking in exceptions. We do the same!
apply_extension_code_signing_hacks () {
    local destination tmp
    destination="${1}"

    tmp="$(mktemp -d)"
    (
        cd "${tmp}"
        7z x -tzip "${TBB_INSTALL}/omni.ja" \
           modules/addons/XPIProvider.jsm \
           chrome/toolkit/content/mozapps/extensions/extensions.js
        patch -p1 <<EOF
diff -Naur a/chrome/toolkit/content/mozapps/extensions/extensions.js b/chrome/toolkit/content/mozapps/extensions/extensions.js
--- a/chrome/toolkit/content/mozapps/extensions/extensions.js 2000-01-01 00:00:00.000000000 +0000
+++ b/chrome/toolkit/content/mozapps/extensions/extensions.js 2000-01-01 00:00:00.000000000 +0000
@@ -282,7 +282,9 @@
   // they aren't the correct type for signing.
   if (aAddon.id == "torbutton@torproject.org" ||
       aAddon.id == "tor-launcher@torproject.org" ||
-      aAddon.id == "https-everywhere-eff@eff.org") {
+      aAddon.id == "https-everywhere-eff@eff.org" ||
+      aAddon.id == "branding@amnesia.boum.org" ||
+      aAddon.id == "uBlock0@raymondhill.net") {
     return true;
   }
   return aAddon.isCorrectlySigned !== false;
diff -Naur a/modules/addons/XPIProvider.jsm b/modules/addons/XPIProvider.jsm
--- a/modules/addons/XPIProvider.jsm 2000-01-01 00:00:00.000000000 +0000
+++ b/modules/addons/XPIProvider.jsm 2000-01-01 00:00:00.000000000 +0000
@@ -749,7 +749,9 @@
   if (aAddon.id == "torbutton@torproject.org" ||
       aAddon.id == "tor-launcher@torproject.org" ||
       aAddon.id == "https-everywhere-eff@eff.org" ||
-      aAddon.id == "meek-http-helper@bamsoftware.com") {
+      aAddon.id == "meek-http-helper@bamsoftware.com" ||
+      aAddon.id == "branding@amnesia.boum.org" ||
+      aAddon.id == "uBlock0@raymondhill.net") {
     return true;
   }
EOF
        7z u -tzip "${TBB_INSTALL}/omni.ja" \
           modules/addons/XPIProvider.jsm \
           chrome/toolkit/content/mozapps/extensions/extensions.js

        7z x -tzip "${TBB_INSTALL}/browser/omni.ja" \
           components/nsBrowserGlue.js
        patch -p1 <<EOF
diff -Naur x/components/nsBrowserGlue.js y/components/nsBrowserGlue.js
--- a/components/nsBrowserGlue.js 2000-01-01 00:00:00.000000000 +0000
+++ b/components/nsBrowserGlue.js 2000-01-01 00:00:00.000000000 +0000
@@ -1122,7 +1122,9 @@
           if ((addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) &&
               !(addon.id == "torbutton@torproject.org" ||
                 addon.id == "tor-launcher@torproject.org" ||
-                addon.id == "https-everywhere-eff@eff.org")) {
+                addon.id == "https-everywhere-eff@eff.org" ||
+                addon.id == "branding@amnesia.boum.org" ||
+                addon.id == "uBlock0@raymondhill.net")) {
             this._notifyUnsignedAddonsDisabled();
             break;
           }
EOF
        7z u -tzip "${TBB_INSTALL}/browser/omni.ja" \
           components/nsBrowserGlue.js
        # These binaries are generated from the above modified files
        # so we have to remove them. This will have a performance
        # impact that probably is unnoticeable for humans, but TBB 7.5
        # won't ship any of these binaries any way, so we'll converge.
        7z d -tzip "${TBB_INSTALL}/omni.ja" \
           jsloader/resource/gre/modules/addons/XPIProvider.jsm
        7z d -tzip "${TBB_INSTALL}/browser/omni.ja" \
           jsloader/resource/app/components/nsBrowserGlue.js
    )
}

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
install_langpacks_from_bundles() {
    local bundles_dir destination
    bundles_dir="${1}"
    destination="${2}"

    for tarball in "${bundles_dir}"/tor-browser-*.tar.xz; do
        locale="$(echo "${tarball}" | sed "s@^.*/tor-browser-.*_\(.*\)\.tar\.xz@\1@")"
        if [ "${locale}" = en-US ]; then
            continue
        fi
        xpi="tor-browser_${locale}/Browser/TorBrowser/Data/Browser/profile.default/extensions/langpack-${locale}@firefox.mozilla.org.xpi"
        (
            cd "${bundles_dir}"
            tar -xf "${tarball}" "${xpi}"
            mv "${xpi}" "${destination}"
        )
    done
}

213
214
215
216
217
218
219
220
get_firefox_version() {
    # The application.ini file
    local appini
    appini="${1}"
    sed -n 's/^Version=\(.*\)$/\1/p' "${appini}"
}

install_debian_extensions() {
221
222
    local destination
    destination="${1}"
223
    shift
224
    apt-get install --yes "${@}"
spriver's avatar
spriver committed
225
226
    ln -s /usr/share/xul-ext/ublock-origin/ \
          "${destination}"/'uBlock0@raymondhill.net'
227
228
}

229
create_default_profile() {
230
231
232
    local tbb_profile extensions_dir destination
    tbb_profile="${1}"
    tbb_extensions_dir="${2}"
233
234
235
    destination="${3}"

    rsync -a --exclude bookmarks.html --exclude extensions \
236
          "${tbb_profile}"/ "${destination}"/
237
238
239
240
241

    # Remove TBB's default bridges
    sed -i '/extensions\.torlauncher\.default_bridge\./d' "${destination}"/preferences/extension-overrides.js

    mkdir -p "${destination}"/extensions
242
    for ext in "${tbb_extensions_dir}"/*; do
243
244
245
246
        ln -s "${ext}" "${destination}"/extensions/
    done
}

Tails developers's avatar
Tails developers committed
247
TBB_SHA256SUMS_FILE=/usr/share/tails/tbb-sha256sums.txt
248
TBB_TARBALLS="$(grep "\<tor-browser-linux64-.*\.tar.xz$" "${TBB_SHA256SUMS_FILE}")"
249

Tails developers's avatar
Tails developers committed
250
251
# We'll use the en-US bundle as our basis; only langpacks will be
# installed from the other bundles.
252
253
254
255
256
257
258
259
MAIN_TARBALL="$(echo "${TBB_TARBALLS}" | grep -o "tor-browser-linux64-.*_en-US.tar.xz" || :)"
NIGHTLY_BUILD=
if [ -z "${MAIN_TARBALL}" ] && [ "$(echo $TBB_TARBALLS | awk '{ print $2 }')" = 'tor-browser-linux64-tbb-nightly_ALL.tar.xz' ]; then
    # Except for TBB nightly builds; then there is only one bundle
    # containing all langpacks
    MAIN_TARBALL='tor-browser-linux64-tbb-nightly_ALL.tar.xz'
    NIGHTLY_BUILD=yes
fi
Tails developers's avatar
Tails developers committed
260
TBB_DIST_URL_FILE=/usr/share/tails/tbb-dist-url.txt
261
TBB_TARBALLS_BASE_URL="$(cat "${TBB_DIST_URL_FILE}")"
262

263
264
# The Debian Iceweasel extensions we want to install and make
# available in the Tor Browser.
spriver's avatar
spriver committed
265
DEBIAN_EXT_PKGS="xul-ext-ublock-origin"
266

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

Tails developers's avatar
Tails developers committed
270
install_tor_browser "${TMP}/${MAIN_TARBALL}" "${TBB_INSTALL}"
271
apply_extension_code_signing_hacks "${TBB_INSTALL}"
272

273
mkdir -p "${TBB_EXT}"
274
275
276
if [ "${NIGHTLY_BUILD}" != yes ]; then
    install_langpacks_from_bundles "${TMP}" "${TBB_EXT}"
fi
277

278
279
rm -r "${TMP}"

Tails developers's avatar
Tails developers committed
280
# Let's put all the extensions from TBB in the global extensions
281
# directory...
282
283
mv "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions/* "${TBB_EXT}"
rmdir "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions
284

285
286
# ... and then install a few Iceweasel extension by using a fake
# Iceweasel equivs package to satisfy the dependencies.
287
FIREFOX_VERSION=$(get_firefox_version "${TBB_INSTALL}"/application.ini)
288
FAKE_ICEWEASEL_VERSION=${FIREFOX_VERSION}+fake1
289
install_fake_package iceweasel "${FAKE_ICEWEASEL_VERSION}" web
290
install_debian_extensions "${TBB_EXT}" ${DEBIAN_EXT_PKGS}
291

292
mkdir -p "${TBB_PROFILE}"
293
create_default_profile "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default "${TBB_EXT}" "${TBB_PROFILE}"
294

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

299
300
chown -R root:root "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
chmod -R a+rX "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
301

Tails developers's avatar
Tails developers committed
302
# Make the Tor Browser into the system's default web browser
303
304
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
305
sed 's/\<firefox-esr\.desktop\>/tor-browser.desktop/' \
306
307
308
    /usr/share/applications/gnome-mimeapps.list \
    > /etc/xdg/gnome-mimeapps.list
chmod 644 /etc/xdg/gnome-mimeapps.list