#!/bin/sh
set -e
set -u
echo "Install the Tor Browser"
# 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.
. /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
}
install_tor_browser() {
local bundle destination tmp prep torlauncher_xpi_path torlauncher_version
bundle="${1}"
destination="${2}"
tmp="$(mktemp -d)"
tar -xf "${bundle}" -C "${tmp}" tor-browser_en-US
prep="${tmp}"/tor-browser_en-US/Browser
# 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.
rm -f "${prep}"/dictionaries/*
for f in /usr/share/hunspell/*.aff /usr/share/hunspell/*.dic; do
ln -s "${f}" "${prep}"/dictionaries/
done
# Let's use the libstdc++ that the Tor Browser is intended to be used with,
# instead of the system 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.
rm -r "${prep}"/TorBrowser/Tor "${prep}"/TorBrowser/Docs
# We don't want tor-launcher to be part of the regular browser
# 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"${TOR_LAUNCHER_INSTALL}" "${torlauncher_xpi_path}"
torlauncher_version="$(sed -n \
's,^ \([0-9\.]\+\),\1,p' \
"${TOR_LAUNCHER_INSTALL}/install.rdf")"
cat > "${TOR_LAUNCHER_INSTALL}/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 "${TOR_LAUNCHER_INSTALL}"
rm "${torlauncher_xpi_path}"
# 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
mv "${prep}" "${destination}"
rm -r "${tmp}"
}
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
}
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
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() {
local destination
destination="${1}"
shift
apt-get install --yes "${@}"
ln -s /usr/share/xul-ext/adblock-plus/ \
"${destination}"/'{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'
}
create_default_profile() {
local tbb_profile extensions_dir destination
tbb_profile="${1}"
tbb_extensions_dir="${2}"
destination="${3}"
rsync -a --exclude bookmarks.html --exclude extensions \
"${tbb_profile}"/ "${destination}"/
# Remove TBB's default bridges
sed -i '/extensions\.torlauncher\.default_bridge\./d' "${destination}"/preferences/extension-overrides.js
mkdir -p "${destination}"/extensions
for ext in "${tbb_extensions_dir}"/*; do
ln -s "${ext}" "${destination}"/extensions/
done
}
TBB_SHA256SUMS_FILE=/usr/share/tails/tbb-sha256sums.txt
TBB_TARBALLS="$(grep "\/tor-browser.desktop/' /etc/gnome/defaults.list