10-tbb 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #!/bin/sh
  2. set -e
  3. set -u
  4. echo "Install the Tor Browser"
  5. # Import the TBB_INSTALL, TBB_PROFILE, TBB_EXT and
  6. # TOR_LAUNCHER_INSTALL variables, which contains the paths we will
  7. # split TBB's actual browser (binaries etc), user data and extension
  8. # into. While this differs from how the TBB organizes the files, the
  9. # end result will be the same, and it's practical since when creating
  10. # a new browser profile we can simply copy the profile directory
  11. # without duplicating all extensions.
  12. . /usr/local/lib/tails-shell-library/tor-browser.sh
  13. download_and_verify_files() {
  14. local base_url bundles destination apt_proxy
  15. base_url="${1}"
  16. bundles="${2}"
  17. destination="${3}"
  18. # Use the builder's caching APT proxy, if any
  19. apt_proxy="$(apt-config --format '%v' dump Acquire::http::Proxy)"
  20. if [ -n "${apt_proxy}" ]; then
  21. export HTTP_PROXY="${apt_proxy}"
  22. export http_proxy="${apt_proxy}"
  23. export HTTPS_PROXY="${apt_proxy}"
  24. export https_proxy="${apt_proxy}"
  25. fi
  26. echo "${bundles}" | while read expected_sha256 tarball; do
  27. (
  28. cd "${destination}"
  29. echo "Fetching ${base_url}/${tarball} ..."
  30. curl --remote-name "${base_url}/${tarball}"
  31. )
  32. actual_sha256="$(sha256sum "${destination}/${tarball}" | cut -d' ' -f1)"
  33. if [ "${actual_sha256}" != "${expected_sha256}" ]; then
  34. echo "SHA256 mismatch for ${tarball}" >&2
  35. exit 1
  36. fi
  37. done
  38. }
  39. install_tor_browser() {
  40. local bundle destination tmp prep torlauncher_xpi_path torlauncher_version
  41. bundle="${1}"
  42. destination="${2}"
  43. tmp="$(mktemp -d)"
  44. tar -xf "${bundle}" -C "${tmp}" tor-browser_en-US
  45. prep="${tmp}"/tor-browser_en-US/Browser
  46. # Enable our myspell/hunspell dictionaries. TBB only provides the
  47. # one for en-US, but Debian's seems more comprehensive, so we'll
  48. # only use Debian's dictionaries.
  49. rm -f "${prep}"/dictionaries/*
  50. for f in /usr/share/hunspell/*.aff /usr/share/hunspell/*.dic; do
  51. ln -s "${f}" "${prep}"/dictionaries/
  52. done
  53. # Let's use the libstdc++ that the Tor Browser is intended to be used with,
  54. # instead of the system one.
  55. cp "${prep}"/TorBrowser/Tor/libstdc++.so.6 "${prep}"
  56. # We don't need the Tor binary, the shared libraries Tor needs
  57. # (but Firefox doesn't) and documentation shipped in the TBB.
  58. rm -r "${prep}"/TorBrowser/Tor "${prep}"/TorBrowser/Docs
  59. # We don't want tor-launcher to be part of the regular browser
  60. # profile but we want to keep it as a standalone application
  61. # when Tails is started in "bridge mode".
  62. torlauncher_xpi_path="${prep}/TorBrowser/Data/Browser/profile.default/extensions/tor-launcher@torproject.org.xpi"
  63. 7z x -o"${TOR_LAUNCHER_INSTALL}" "${torlauncher_xpi_path}"
  64. torlauncher_version="$(sed -n \
  65. 's,^ <em:version>\([0-9\.]\+\)</em:version>,\1,p' \
  66. "${TOR_LAUNCHER_INSTALL}/install.rdf")"
  67. cat > "${TOR_LAUNCHER_INSTALL}/application.ini" << EOF
  68. [App]
  69. Vendor=TorProject
  70. Name=TorLauncher
  71. Version=${torlauncher_version}
  72. BuildID=$(date +%Y%m%d)
  73. ID=tor-launcher@torproject.org
  74. [Gecko]
  75. MinVersion=$(get_firefox_version "${prep}/application.ini")
  76. MaxVersion=*.*.*
  77. [Shell]
  78. Icon=icon.png
  79. EOF
  80. chmod -R a+rX "${TOR_LAUNCHER_INSTALL}"
  81. rm "${torlauncher_xpi_path}"
  82. # The Tor Browser will fail, complaining about an incomplete profile,
  83. # unless there's a readable TorBrowser/Data/Browser/Caches
  84. # in the directory where the firefox executable is located.
  85. mkdir -p "${prep}"/TorBrowser/Data/Browser/Caches
  86. mv "${prep}" "${destination}"
  87. rm -r "${tmp}"
  88. }
  89. install_langpacks_from_bundles() {
  90. local bundles_dir destination
  91. bundles_dir="${1}"
  92. destination="${2}"
  93. for tarball in "${bundles_dir}"/tor-browser-*.tar.xz; do
  94. locale="$(echo "${tarball}" | sed "s@^.*/tor-browser-.*_\(.*\)\.tar\.xz@\1@")"
  95. if [ "${locale}" = en-US ]; then
  96. continue
  97. fi
  98. xpi="tor-browser_${locale}/Browser/TorBrowser/Data/Browser/profile.default/extensions/langpack-${locale}@firefox.mozilla.org.xpi"
  99. (
  100. cd "${bundles_dir}"
  101. tar -xf "${tarball}" "${xpi}"
  102. mv "${xpi}" "${destination}"
  103. )
  104. done
  105. }
  106. get_firefox_version() {
  107. # The application.ini file
  108. local appini
  109. appini="${1}"
  110. sed -n 's/^Version=\(.*\)$/\1/p' "${appini}"
  111. }
  112. # Create and install a fake iceweasel package so we can install our
  113. # desired Debian-packaged Iceweasel addons
  114. install_fake_iceweasel_pkg() {
  115. local fake_version tmp
  116. fake_version="${1}"
  117. tmp="$(mktemp -d)"
  118. apt-get install --yes equivs
  119. cat > "${tmp}"/iceweasel.control << EOF
  120. Section: web
  121. Priority: optional
  122. Homepage: https://tails.boum.org/
  123. Standards-Version: 3.6.2
  124. Package: iceweasel
  125. Version: ${fake_version}
  126. Maintainer: Tails developers <amnesia@boum.org>
  127. Architecture: all
  128. Description: (Fake) Iceweasel
  129. Make it possible to install Debian's Iceweasel addons without having to
  130. install a real Iceweasel.
  131. EOF
  132. (
  133. cd "${tmp}"
  134. equivs-build "${tmp}"/iceweasel.control
  135. dpkg -i "${tmp}"/iceweasel_"${fake_version}"_all.deb
  136. )
  137. rm -R "${tmp}"
  138. }
  139. install_debian_extensions() {
  140. local destination
  141. destination="${1}"
  142. shift
  143. apt-get install --yes "${@}"
  144. ln -s /usr/share/xul-ext/adblock-plus/ \
  145. "${destination}"/'{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'
  146. }
  147. create_default_profile() {
  148. local tbb_profile extensions_dir destination
  149. tbb_profile="${1}"
  150. tbb_extensions_dir="${2}"
  151. destination="${3}"
  152. rsync -a --exclude bookmarks.html --exclude extensions \
  153. "${tbb_profile}"/ "${destination}"/
  154. # Remove TBB's default bridges
  155. sed -i '/extensions\.torlauncher\.default_bridge\./d' "${destination}"/preferences/extension-overrides.js
  156. mkdir -p "${destination}"/extensions
  157. for ext in "${tbb_extensions_dir}"/*; do
  158. ln -s "${ext}" "${destination}"/extensions/
  159. done
  160. }
  161. TBB_SHA256SUMS_FILE=/usr/share/tails/tbb-sha256sums.txt
  162. TBB_TARBALLS="$(grep "\<tor-browser-linux32-.*\.tar.xz$" "${TBB_SHA256SUMS_FILE}")"
  163. # We'll use the en-US bundle as our basis; only langpacks will be
  164. # installed from the other bundles.
  165. MAIN_TARBALL="$(echo "${TBB_TARBALLS}" | grep -o "tor-browser-linux32-.*_en-US.tar.xz")"
  166. TBB_DIST_URL_FILE=/usr/share/tails/tbb-dist-url.txt
  167. TBB_TARBALLS_BASE_URL="$(cat "${TBB_DIST_URL_FILE}")"
  168. # The Debian Iceweasel extensions we want to install and make
  169. # available in the Tor Browser.
  170. DEBIAN_EXT_PKGS="xul-ext-adblock-plus"
  171. TMP="$(mktemp -d)"
  172. download_and_verify_files "${TBB_TARBALLS_BASE_URL}" "${TBB_TARBALLS}" "${TMP}"
  173. install_tor_browser "${TMP}/${MAIN_TARBALL}" "${TBB_INSTALL}"
  174. mkdir -p "${TBB_EXT}"
  175. install_langpacks_from_bundles "${TMP}" "${TBB_EXT}"
  176. rm -r "${TMP}"
  177. # Let's put all the extensions from TBB in the global extensions
  178. # directory...
  179. mv "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions/* "${TBB_EXT}"
  180. rmdir "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default/extensions
  181. # ... and then install a few Iceweasel extension by using a fake
  182. # Iceweasel equivs package to satisfy the dependencies.
  183. FIREFOX_VERSION=$(get_firefox_version "${TBB_INSTALL}"/application.ini)
  184. FAKE_ICEWEASEL_VERSION=${FIREFOX_VERSION}+fake1
  185. install_fake_iceweasel_pkg "${FAKE_ICEWEASEL_VERSION}"
  186. install_debian_extensions "${TBB_EXT}" ${DEBIAN_EXT_PKGS}
  187. mkdir -p "${TBB_PROFILE}"
  188. create_default_profile "${TBB_INSTALL}"/TorBrowser/Data/Browser/profile.default "${TBB_EXT}" "${TBB_PROFILE}"
  189. # Create a copy of the Firefox binary, for use e.g. by Tor Launcher.
  190. # It won't be subject to AppArmor confinement.
  191. cp -a "${TBB_INSTALL}/firefox" "${TBB_INSTALL}/firefox-unconfined"
  192. chown -R root:root "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
  193. chmod -R a+rX "${TBB_INSTALL}" "${TBB_PROFILE}" "${TBB_EXT}"
  194. # Make the Tor Browser into the system's default web browser
  195. update-alternatives --install /usr/bin/x-www-browser x-www-browser /usr/local/bin/tor-browser 99
  196. update-alternatives --install /usr/bin/gnome-www-browser gnome-www-browser /usr/local/bin/tor-browser 99
  197. sed -i 's/\<iceweasel\.desktop\>/tor-browser.desktop/' /etc/gnome/defaults.list