10-tbb 9.34 KB
Newer Older
1
2
3
4
5
6
#!/bin/sh

set -eu

echo "Install the Tor Browser"

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Import the TBB_INSTALL, TBB_PROFILE and TBB_EXT 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.
. /usr/local/lib/tails-shell-library/tor-browser.sh

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} ..."
            curl --remote-name "${base_url}/${tarball}"
        )
        actual_sha256="$(sha256sum "${destination}/${tarball}" | cut -d' ' -f1)"
        if [ "${actual_sha256}" != "${expected_sha256}" ]; then
            echo "SHA256 mismatch for ${tarball}" >&2
            exit 1
        fi
    done
}

44
install_tor_browser() {
45
    local bundle destination tmp prep torbutton_xpi_path torlauncher_xpi_path torlauncher_version
46
47
48
49
50
    bundle="${1}"
    destination="${2}"

    tmp="$(mktemp -d)"
    tar -xf "${bundle}" -C "${tmp}" tor-browser_en-US
51
    prep="${tmp}"/tor-browser_en-US/Browser
52
53
54
55

    # 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.
56
    rm -f "${prep}"/dictionaries/*
57
    for f in /usr/share/hunspell/*.aff /usr/share/hunspell/*.dic; do
Tails developers's avatar
Tails developers committed
58
        ln -s "${f}" "${prep}"/dictionaries/
59
60
    done

61
62
63
64
65
66
    # The libstdc++6 package in Wheezy is too old, so we need the
    # bundled one.
    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.
67
68
    rm -r "${prep}"/TorBrowser/Tor "${prep}"/TorBrowser/Docs

69
    # We don't want tor-launcher to be part of the regular browser
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
    # 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"
    7z x -o'/usr/share/tor-launcher-standalone' "${torlauncher_xpi_path}"
    torlauncher_version="$(sed -n \
        's,^        <em:version>\([0-9\.]\+\)</em:version>,\1,p' \
        '/usr/share/tor-launcher-standalone/install.rdf')"
    cat > '/usr/share/tor-launcher-standalone/application.ini' << EOF
[App]
Vendor=TorProject
Name=TorLauncher
Version=${torlauncher_version}
BuildID=$(date +%Y%m%d)
ID=tor-launcher@torproject.org

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

[Shell]
Icon=icon.png
EOF
    chmod -R a+rX '/usr/share/tor-launcher-standalone'
    rm "${torlauncher_xpi_path}"
94
95
96
97

    # Remove TBB's torbutton since the "Tor test" will fail and about:tor
    # will report an error. We'll install our own Torbutton later, which
    # has the extensions.torbutton.test_enabled boolean pref as a workaround.
98
99
100
101
102
103
104
105
    torbutton_xpi_path="${prep}/TorBrowser/Data/Browser/profile.default/extensions/torbutton@torproject.org.xpi"
    TORBUTTON_BUNDLED_VERSION="$(7z e -so ${torbutton_xpi_path} install.rdf | \
        sed -n 's,^        <em:version>\([0-9\.]\+\)</em:version>,\1,p')"
    if [ -z "${TORBUTTON_BUNDLED_VERSION}" ]; then
        echo "Couldn't extract Torbutton's bundled version" >&2
        exit 1
    fi
    rm "${torbutton_xpi_path}"
106
107

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

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

    rm -r "${tmp}"
}

117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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
}

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
get_firefox_version() {
    # The application.ini file
    local appini
    appini="${1}"
    sed -n 's/^Version=\(.*\)$/\1/p' "${appini}"
}

# Create and install a fake iceweasel package so we can install our
# desired Debian-packaged Iceweasel addons
install_fake_iceweasel_pkg() {
    local fake_version tmp
    fake_version="${1}"
    tmp="$(mktemp -d)"
    apt-get install --yes equivs
    cat > "${tmp}"/iceweasel.control << EOF
Section: web
Priority: optional
Homepage: https://tails.boum.org/
Standards-Version: 3.6.2

Package: iceweasel
Version: ${fake_version}
Maintainer: Tails developers <amnesia@boum.org>
Architecture: all
Description: (Fake) Iceweasel
 Make it possible to install Debian's Iceweasel addons without having to
 install a real Iceweasel.
EOF
    (
        cd "${tmp}"
        equivs-build "${tmp}"/iceweasel.control
        dpkg -i "${tmp}"/iceweasel_"${fake_version}"_all.deb
    )
    rm -R "${tmp}"
}

install_debian_extensions() {
173
174
    local destination
    destination="${1}"
175
    shift
176
    apt-get install --yes "${@}"
177
178
179
180
181
182
    ln -s /usr/share/xul-ext/adblock-plus/ \
          "${destination}"/'{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'
    ln -s /usr/share/xul-ext/torbutton/ \
          "${destination}"/torbutton@torproject.org
}

183
create_default_profile() {
184
185
186
    local tbb_profile extensions_dir destination
    tbb_profile="${1}"
    tbb_extensions_dir="${2}"
187
188
189
    destination="${3}"

    rsync -a --exclude bookmarks.html --exclude extensions \
190
          "${tbb_profile}"/ "${destination}"/
191
192
193
194
195

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

    mkdir -p "${destination}"/extensions
196
    for ext in "${tbb_extensions_dir}"/*; do
197
198
199
200
        ln -s "${ext}" "${destination}"/extensions/
    done
}

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

Tails developers's avatar
Tails developers committed
204
205
# We'll use the en-US bundle as our basis; only langpacks will be
# installed from the other bundles.
Tails developers's avatar
Tails developers committed
206
MAIN_TARBALL="$(echo "${TBB_TARBALLS}" | grep -o "tor-browser-linux32-.*_en-US.tar.xz")"
207
VERSION="$(echo "${MAIN_TARBALL}" | sed 's/tor-browser-linux32-\(.*\)_en-US.tar.xz/\1/')"
Tails developers's avatar
Tails developers committed
208
TBB_DIST_URL_FILE=/usr/share/tails/tbb-dist-url.txt
Tails developers's avatar
Tails developers committed
209
TBB_TARBALLS_BASE_URL="$(cat "${TBB_DIST_URL_FILE}")/${VERSION}"
210

211
212
# The Debian Iceweasel extensions we want to install and make
# available in the Tor Browser.
Tails developers's avatar
Tails developers committed
213
DEBIAN_EXT_PKGS="xul-ext-adblock-plus xul-ext-torbutton"
214

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

Tails developers's avatar
Tails developers committed
218
install_tor_browser "${TMP}/${MAIN_TARBALL}" "${TBB_INSTALL}"
219

220
221
mkdir -p "${TBB_EXT}"
install_langpacks_from_bundles "${TMP}" "${TBB_EXT}"
222

223
224
rm -r "${TMP}"

Tails developers's avatar
Tails developers committed
225
# Let's put all the extensions from TBB in the global extensions
226
# directory...
227
228
mv "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions/* "${TBB_EXT}"
rmdir "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions
229

230
231
# ... and then install a few Iceweasel extension by using a fake
# Iceweasel equivs package to satisfy the dependencies.
232
FIREFOX_VERSION=$(get_firefox_version "${TBB_INSTALL}"/application.ini)
233
234
FAKE_ICEWEASEL_VERSION=${FIREFOX_VERSION}+fake1
install_fake_iceweasel_pkg "${FAKE_ICEWEASEL_VERSION}"
235
install_debian_extensions "${TBB_EXT}" ${DEBIAN_EXT_PKGS}
236

237
238
239
240
241
242
243
244
245
# Make sure that we have installed a Torbutton based on the same
# version as the one bundled with the Tor Browser
TORBUTTON_VERSION="$(dpkg -s xul-ext-torbutton | \
    sed -n 's/^Version: \(.*\)-[0-9]\+$/\1/p')"
if [ "${TORBUTTON_VERSION}" != "${TORBUTTON_BUNDLED_VERSION}" ]; then
    echo "We have installed a Torbutton based on version '${TORBUTTON_VERSION}' but the version bundled with the Tor Browser is version '${TORBUTTON_BUNDLED_VERSION}'" >&2
    exit 1
fi

246
mkdir -p "${TBB_PROFILE}"
247
create_default_profile "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default "${TBB_EXT}" "${TBB_PROFILE}"
248

249
250
251
252
# 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"

253
254
chown -R root:root "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
chmod -R a+rX "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
255

Tails developers's avatar
Tails developers committed
256
# Make the Tor Browser into the system's default web browser
257
258
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
259
sed -i 's/\<iceweasel\.desktop\>/tor-browser.desktop/' /etc/gnome/defaults.list