summaryrefslogtreecommitdiffstats
path: root/config/chroot_local-includes/usr/local
diff options
context:
space:
mode:
authorintrigeri <intrigeri@boum.org>2015-03-03 10:25:45 +0000
committerintrigeri <intrigeri@boum.org>2015-03-03 10:25:45 +0000
commit131d8f78a3cbd86f0fdba929e72130b80070c134 (patch)
tree7edd2164003fac96d2a25201ffe3e642b3f7b15b /config/chroot_local-includes/usr/local
parent9e7aa97db078177c8f36d227a22b8a79da5096b6 (diff)
parent5ec5f06708514a494044e40a175e8d80fa446e5a (diff)
Merge remote-tracking branch 'origin/master' into faq/7926-apt-get-upgradefaq/7926-apt-get-upgrade
Diffstat (limited to 'config/chroot_local-includes/usr/local')
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/connect-socks2
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/electrum35
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/git2
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/gpgApplet4
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/tails-add-bookmark-for-persistent-directory7
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/tails-security-check8
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/tails-virt-notify-user2
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/totem2
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/wget8
-rwxr-xr-xconfig/chroot_local-includes/usr/local/bin/whois2
-rwxr-xr-xconfig/chroot_local-includes/usr/local/lib/add-GNOME-bookmarks28
-rwxr-xr-xconfig/chroot_local-includes/usr/local/lib/create-tor-browser-directories15
-rw-r--r--config/chroot_local-includes/usr/local/lib/tails-shell-library/chroot-browser.sh259
-rw-r--r--config/chroot_local-includes/usr/local/lib/tails-shell-library/common.sh34
-rw-r--r--config/chroot_local-includes/usr/local/lib/tails-shell-library/i2p.sh32
-rw-r--r--config/chroot_local-includes/usr/local/lib/tails-shell-library/localization.sh26
-rw-r--r--config/chroot_local-includes/usr/local/lib/tails-shell-library/tails-greeter.sh (renamed from config/chroot_local-includes/usr/local/lib/tails-shell-library/tails_greeter.sh)13
-rw-r--r--config/chroot_local-includes/usr/local/lib/tails-shell-library/tor-browser.sh32
-rwxr-xr-xconfig/chroot_local-includes/usr/local/lib/tails-shell-library/tor.sh8
-rw-r--r--config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py13
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/do_not_ever_run_me6
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/i2p-browser400
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/tails-debugging-info2
-rw-r--r--config/chroot_local-includes/usr/local/sbin/tails-i2p14
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/tails-spoof-mac25
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/unsafe-browser278
26 files changed, 660 insertions, 597 deletions
diff --git a/config/chroot_local-includes/usr/local/bin/connect-socks b/config/chroot_local-includes/usr/local/bin/connect-socks
index fc39517..663e8fa 100755
--- a/config/chroot_local-includes/usr/local/bin/connect-socks
+++ b/config/chroot_local-includes/usr/local/bin/connect-socks
@@ -1,4 +1,4 @@
#!/bin/sh
SOCKS5_USER="${SOCKS5_USER:-}" \
SOCKS5_PASSWORD="${SOCKS5_PASSWORD:-}" \
- connect-proxy -s $*
+ connect-proxy -s "$@"
diff --git a/config/chroot_local-includes/usr/local/bin/electrum b/config/chroot_local-includes/usr/local/bin/electrum
new file mode 100755
index 0000000..a0299c4
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/bin/electrum
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+. gettext.sh
+TEXTDOMAIN="tails"
+export TEXTDOMAIN
+
+CONF_DIR="${HOME}"/.electrum
+
+electrum_config_is_persistent() {
+ [ "$(findmnt --noheadings --output SOURCE --target "${CONF_DIR}")" = "/dev/mapper/TailsData_unlocked[/electrum]" ]
+}
+
+verify_start () {
+ local dialog_msg="<b><big>`gettext \"Persistence is disabled for Electrum\"`</big></b>
+
+`gettext \"When you reboot Tails, all of Electrum's data will be lost, including your Bitcoin wallet. It is strongly recommended to only run Electrum when its persistence feature is activated.\"`
+
+`gettext \"Do you want to start Electrum anyway?\"`
+"
+ local launch="`gettext \"_Launch\"`"
+ local exit="`gettext \"_Exit\"`"
+ # Since zenity can't set the default button to cancel, we switch the
+ # labels and interpret the return value as its negation.
+ if zenity --question --title "" --ok-label "${exit}" \
+ --cancel-label "${launch}" --text "${dialog_msg}"; then
+ return 1
+ fi
+}
+
+if ! electrum_config_is_persistent; then
+ verify_start || exit 0
+fi
+
+exec /usr/bin/electrum "${@}"
+
diff --git a/config/chroot_local-includes/usr/local/bin/git b/config/chroot_local-includes/usr/local/bin/git
new file mode 100755
index 0000000..3e8a790
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/bin/git
@@ -0,0 +1,2 @@
+#!/bin/sh
+TSOCKS_CONF_FILE=/etc/tor/tor-tsocks-git.conf exec /usr/bin/tsocks.distrib /usr/bin/git "$@"
diff --git a/config/chroot_local-includes/usr/local/bin/gpgApplet b/config/chroot_local-includes/usr/local/bin/gpgApplet
index c8b6cfd..4777738 100755
--- a/config/chroot_local-includes/usr/local/bin/gpgApplet
+++ b/config/chroot_local-includes/usr/local/bin/gpgApplet
@@ -151,9 +151,9 @@ b) the "Artistic License" which comes with Perl.
'wrap-license' => 1,
'website' => 'https://tails.boum.org/',
)});
- $menu->append($mexit);
- $menu->append(Gtk2::SeparatorMenuItem->new);
$menu->append($mabout);
+ $menu->append(Gtk2::SeparatorMenuItem->new);
+ $menu->append($mexit);
$icon->signal_connect('popup-menu', sub {
my $ticon = shift;
diff --git a/config/chroot_local-includes/usr/local/bin/tails-add-bookmark-for-persistent-directory b/config/chroot_local-includes/usr/local/bin/tails-add-bookmark-for-persistent-directory
deleted file mode 100755
index c652f76..0000000
--- a/config/chroot_local-includes/usr/local/bin/tails-add-bookmark-for-persistent-directory
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-PERSISTENT_DIRECTORY="${HOME}/Persistent"
-
-if mountpoint -q "$PERSISTENT_DIRECTORY" 2>/dev/null ; then
- echo "file://$PERSISTENT_DIRECTORY" >> "${HOME}/.gtk-bookmarks"
-fi
diff --git a/config/chroot_local-includes/usr/local/bin/tails-security-check b/config/chroot_local-includes/usr/local/bin/tails-security-check
index 6611623..2d80e5e 100755
--- a/config/chroot_local-includes/usr/local/bin/tails-security-check
+++ b/config/chroot_local-includes/usr/local/bin/tails-security-check
@@ -46,9 +46,15 @@ use XML::Atom::Feed;
use IO::Socket::SSL;
use Net::SSLeay;
BEGIN {
+ my $cafile = $ENV{HTTPS_CA_FILE};
+ $cafile //= '/usr/local/etc/ssl/certs/tails.boum.org-CA.pem';
+ assert(-e $cafile);
+ assert(-f $cafile);
+ assert(-r $cafile);
+ assert(-s $cafile);
IO::Socket::SSL::set_ctx_defaults(
verify_mode => Net::SSLeay->VERIFY_PEER(),
- ca_file => '/etc/ssl/certs/UTN_USERFirst_Hardware_Root_CA.pem',
+ ca_file => $cafile,
);
}
use LWP::UserAgent; # needs to be *after* IO::Socket::SSL's initialization
diff --git a/config/chroot_local-includes/usr/local/bin/tails-virt-notify-user b/config/chroot_local-includes/usr/local/bin/tails-virt-notify-user
index 32f4fc7..ef61683 100755
--- a/config/chroot_local-includes/usr/local/bin/tails-virt-notify-user
+++ b/config/chroot_local-includes/usr/local/bin/tails-virt-notify-user
@@ -54,7 +54,7 @@ my $summary = gettext("Warning: virtual machine detected!");
my $body =
gettext("Both the host operating system and the virtualization software are able to monitor what you are doing in Tails.")
. " "
- . gettext("<a href='file:///usr/share/doc/tails/website/doc/advanced_topics/virtualization.en.html'>Learn more...</a>")
+ . gettext("<a href='file:///usr/share/doc/tails/website/doc/advanced_topics/virtualization.en.html#security'>Learn more...</a>")
. " "; # Workaround: else the last line of the notification is not displayed
$notify->create(summary => $summary,
diff --git a/config/chroot_local-includes/usr/local/bin/totem b/config/chroot_local-includes/usr/local/bin/totem
new file mode 100755
index 0000000..cb72b21
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/bin/totem
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec torsocks /usr/bin/totem "$@"
diff --git a/config/chroot_local-includes/usr/local/bin/wget b/config/chroot_local-includes/usr/local/bin/wget
new file mode 100755
index 0000000..0d94b53
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/bin/wget
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+unset http_proxy
+unset HTTP_PROXY
+unset https_proxy
+unset HTTPS_PROXY
+
+exec torsocks /usr/bin/wget "$@"
diff --git a/config/chroot_local-includes/usr/local/bin/whois b/config/chroot_local-includes/usr/local/bin/whois
index f125f17..0bfe673 100755
--- a/config/chroot_local-includes/usr/local/bin/whois
+++ b/config/chroot_local-includes/usr/local/bin/whois
@@ -1,2 +1,2 @@
#!/bin/sh
-exec torify /usr/bin/whois $*
+exec torsocks /usr/bin/whois "$@"
diff --git a/config/chroot_local-includes/usr/local/lib/add-GNOME-bookmarks b/config/chroot_local-includes/usr/local/lib/add-GNOME-bookmarks
new file mode 100755
index 0000000..77bf41f
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/lib/add-GNOME-bookmarks
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -eu
+
+. /usr/local/lib/tails-shell-library/tails-greeter.sh
+
+add_gtk_bookmark_for() {
+ local target
+ target=$(echo "$1" | sed 's, ,%20,g')
+
+ if [ $# -ge 2 ]; then
+ title="$2"
+ echo "file://$target $title" >> "${HOME}/.gtk-bookmarks"
+ else
+ echo "file://$target" >> "${HOME}/.gtk-bookmarks"
+ fi
+}
+
+add_gtk_bookmark_for "${HOME}/Tor Browser"
+
+if persistence_is_enabled_for "${HOME}/Persistent" ; then
+ add_gtk_bookmark_for "${HOME}/Persistent"
+
+ if persistence_is_enabled_read_write ; then
+ add_gtk_bookmark_for "${HOME}/Persistent/Tor Browser" \
+ "Tor Browser (persistent)"
+ fi
+fi
diff --git a/config/chroot_local-includes/usr/local/lib/create-tor-browser-directories b/config/chroot_local-includes/usr/local/lib/create-tor-browser-directories
new file mode 100755
index 0000000..e1fe2c3
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/lib/create-tor-browser-directories
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -eu
+
+TOR_BROWSER_AMNESIAC_DIR='/home/amnesia/Tor Browser'
+TOR_BROWSER_PERSISTENT_DIR='/home/amnesia/Persistent/Tor Browser'
+
+. /usr/local/lib/tails-shell-library/tails-greeter.sh
+
+install -d -o amnesia -g amnesia -m 0700 "$TOR_BROWSER_AMNESIAC_DIR"
+
+if persistence_is_enabled_for "${HOME}/Persistent" && \
+ persistence_is_enabled_read_write ; then
+ install -d -o amnesia -g amnesia -m 0700 "$TOR_BROWSER_PERSISTENT_DIR"
+fi
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/chroot-browser.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/chroot-browser.sh
new file mode 100644
index 0000000..1b889db
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/chroot-browser.sh
@@ -0,0 +1,259 @@
+#!/bin/sh
+
+# This shell library is meant to be used with `set -e`.
+
+if [ "$(whoami)" != "root" ]; then
+ echo "This library is useless for non-root users. Exiting..." >&2
+ exit 1
+fi
+
+# Import the TBB_INSTALL, TBB_PROFILE and TBB_EXT variables, and
+# configure_xulrunner_app_locale().
+. /usr/local/lib/tails-shell-library/tor-browser.sh
+
+# Import windows_camouflage_is_enabled()
+. /usr/local/lib/tails-shell-library/tails-greeter.sh
+
+# Import try_for().
+. /usr/local/lib/tails-shell-library/common.sh
+
+# Break down the chroot and kill all of its processes
+try_cleanup_browser_chroot () {
+ local chroot="${1}"
+ local cow="${2}"
+ local user="${3}"
+ try_for 10 "pkill -u ${user} 1>/dev/null 2>&1" 0.1 || \
+ pkill -9 -u "${user}" || :
+ for mnt in "${chroot}/dev" "${chroot}/proc" "${chroot}" "${cow}"; do
+ try_for 10 "umount ${mnt} 2>/dev/null" 0.1
+ done
+ rmdir "${cow}" "${chroot}"
+}
+
+# Setup a chroot on a clean aufs "fork" of the root filesystem.
+setup_chroot_for_browser () {
+ local chroot="${1}"
+ local cow="${2}"
+ local user="${3}"
+
+ # FIXME: When LXC matures to the point where it becomes a viable option
+ # for creating isolated jails, the chroot can be used as its rootfs.
+
+ local cleanup_cmd="try_cleanup_browser_chroot \"${chroot}\" \"${cow}\" \"${user}\""
+ trap "${cleanup_cmd}" INT EXIT
+
+ local rootfs_dir
+ local rootfs_dirs_path="/lib/live/mount/rootfs"
+ local tails_module_path="/lib/live/mount/medium/live/Tails.module"
+ local aufs_dirs=
+
+ # We have to pay attention to the order we stack the filesystems;
+ # newest must be first, and remember that the .module file lists
+ # oldest first, newest last.
+ while read rootfs_dir; do
+ rootfs_dir="${rootfs_dirs_path}/${rootfs_dir}"
+ mountpoint -q "${rootfs_dir}" && \
+ aufs_dirs="${rootfs_dir}=rr+wh:${aufs_dirs}"
+ done < "${tails_module_path}"
+ # But our copy-on-write dir must be at the very top.
+ aufs_dirs="${cow}=rw:${aufs_dirs}"
+
+ mkdir -p "${cow}" "${chroot}" && \
+ mount -t tmpfs tmpfs "${cow}" && \
+ mount -t aufs -o "noatime,noxino,dirs=${aufs_dirs}" aufs "${chroot}" && \
+ mount -t proc proc "${chroot}/proc" && \
+ mount --bind "/dev" "${chroot}/dev" || \
+ return 1
+
+ # Workaround for #6110
+ chmod -t "${cow}"
+}
+
+browser_conf_dir () {
+ local browser_name="${1}"
+ local browser_user="${2}"
+ echo "/home/${browser_user}/.${browser_name}"
+}
+
+browser_profile_dir () {
+ local conf_dir="$(browser_conf_dir "${@}")"
+ echo "${conf_dir}/profile.default"
+}
+
+chroot_browser_conf_dir () {
+ local chroot="${1}"; shift
+ echo "${chroot}/$(browser_conf_dir "${@}")"
+}
+
+chroot_browser_profile_dir () {
+ local conf_dir="$(chroot_browser_conf_dir "${@}")"
+ echo "${conf_dir}/profile.default"
+}
+
+# Set the chroot's DNS servers (IPv4 only)
+configure_chroot_dns_servers () {
+ local chroot="${1}" ; shift
+ local ip4_nameservers="${@}"
+
+ rm -f "${chroot}/etc/resolv.conf"
+ for ns in ${ip4_nameservers}; do
+ echo "nameserver ${ns}" >> "${chroot}/etc/resolv.conf"
+ done
+ chmod a+r "${chroot}/etc/resolv.conf"
+}
+
+set_chroot_browser_permissions () {
+ local chroot="${1}"
+ local browser_name="${2}"
+ local browser_user="${3}"
+ local browser_conf="$(chroot_browser_conf_dir "${chroot}" "${browser_name}" "${browser_user}")"
+ chown -R "${browser_user}:${browser_user}" "${browser_conf}"
+}
+
+configure_chroot_browser_profile () {
+ local chroot="${1}" ; shift
+ local browser_name="${1}" ; shift
+ local browser_user="${1}" ; shift
+ local home_page="${1}" ; shift
+ # Now $@ is a list of paths (that must be valid after chrooting)
+ # to extensions to enable.
+
+ # Prevent sudo from complaining about failing to resolve the 'amnesia' host
+ echo "127.0.0.1 localhost amnesia" > "${chroot}/etc/hosts"
+
+ # Create a fresh browser profile for the clearnet user
+ local browser_profile="$(chroot_browser_profile_dir "${chroot}" "${browser_name}" "${browser_user}")"
+ local browser_ext="${browser_profile}/extensions"
+ mkdir -p "${browser_profile}" "${browser_ext}"
+
+ # Select extensions to enable
+ local extension
+ while [ -n "${*}" ]; do
+ extension="${1}" ; shift
+ ln -s "${extension}" "${browser_ext}"
+ done
+
+ # Set preferences
+ local browser_prefs="${browser_profile}/preferences/prefs.js"
+ mkdir -p "$(dirname "${browser_prefs}")"
+ cp "/usr/share/tails/${browser_name}/prefs.js" "${browser_prefs}"
+
+ # Set browser home page to something that explains what's going on
+ if [ -n "${home_page}" ]; then
+ echo 'user_pref("browser.startup.homepage", "'"${home_page}"'");' >> \
+ "${browser_prefs}"
+ fi
+
+ # Customize the GUI
+ local browser_chrome="${browser_profile}/chrome/userChrome.css"
+ mkdir -p "$(dirname "${browser_chrome}")"
+ cp "/usr/share/tails/${browser_name}/userChrome.css" "${browser_chrome}"
+
+ # Remove all bookmarks
+ rm "${chroot}/${TBB_PROFILE}/bookmarks.html"
+
+ # Set an appropriate theme, except if we're using Windows
+ # camouflage.
+ if ! windows_camouflage_is_enabled; then
+ cat "/usr/share/tails/${browser_name}/theme.js" >> "${browser_prefs}"
+ else
+ # The tails-activate-win8-theme script requires that the
+ # browser profile is writable by the user running the script.
+ set_chroot_browser_permissions "${chroot}" "${browser_user}"
+ # The camouflage activation script requires a dbus server for
+ # properly configuring GNOME, so we start one in the chroot
+ chroot "${chroot}" sudo -H -u "${browser_user}" sh -c 'eval `dbus-launch --auto-syntax`; tails-activate-win8-theme' || :
+ fi
+}
+
+set_chroot_browser_locale () {
+ local chroot="${1}"
+ local browser_name="${2}"
+ local browser_user="${3}"
+ local locale="${4}"
+ local browser_profile="$(chroot_browser_profile_dir "${chroot}" "${browser_name}" "${browser_user}")"
+ configure_xulrunner_app_locale "${browser_profile}" "${locale}"
+}
+
+# Must be called after configure_chroot_browser_profile(), since it
+# depends on which extensions are installed in the profile.
+set_chroot_browser_name () {
+ local chroot="${1}"
+ local human_readable_name="${2}"
+ local browser_name="${3}"
+ local browser_user="${4}"
+ local locale="${5}"
+ local ext_dir="${chroot}/${TBB_EXT}"
+ local browser_profile_ext_dir="$(chroot_browser_profile_dir "${chroot}" "${browser_name}" "${browser_user}")/extensions"
+
+ # If Torbutton is installed in the browser profile, it will decide
+ # the browser name.
+ if [ -e "${browser_profile_ext_dir}/torbutton@torproject.org" ]; then
+ local torbutton_locale_dir="${ext_dir}/torbutton/chrome/locale/${locale}"
+ if [ ! -d "${torbutton_locale_dir}" ]; then
+ # Surprisingly, the default locale is en, not en-US
+ torbutton_locale_dir="${chroot}/usr/share/xul-ext/torbutton/chrome/locale/en"
+ fi
+ sed -i "s/<"'!'"ENTITY\s\+brand\(Full\|Short\)Name.*$/<"'!'"ENTITY brand\1Name \"${human_readable_name}\">/" "${torbutton_locale_dir}/brand.dtd"
+ # Since Torbutton decides the name, we don't have to mess with
+ # with the browser's own branding, which will save time and
+ # memory.
+ return
+ fi
+
+ local pack top rest
+ if [ "${locale}" != "en-US" ]; then
+ pack="${ext_dir}/langpack-${locale}@firefox.mozilla.org.xpi"
+ top="browser/chrome"
+ rest="${locale}/locale"
+ else
+ pack="${chroot}/${TBB_INSTALL}/browser/omni.ja"
+ top="chrome"
+ rest="en-US/locale"
+ fi
+ local tmp="$(mktemp -d)"
+ local branding="${top}/${rest}/branding/brand.dtd"
+ 7z x -o"${tmp}" "${pack}" "${branding}"
+ sed -i "s/<"'!'"ENTITY\s\+brand\(Full\|Short\)Name.*$/<"'!'"ENTITY brand\1Name \"${human_readable_name}\">/" "${tmp}/${branding}"
+ (cd ${tmp} ; 7z u -tzip "${pack}" .)
+ chmod a+r "${pack}"
+ rm -Rf "${tmp}"
+}
+
+configure_chroot_browser () {
+ local chroot="${1}" ; shift
+ local browser_user="${1}" ; shift
+ local browser_name="${1}" ; shift
+ local human_readable_name="${1}" ; shift
+ local home_page="${1}" ; shift
+ local dns_servers="${1}" ; shift
+ # Now $@ is a list of paths (that must be valid after chrooting)
+ # to extensions to enable.
+ local best_locale="$(guess_best_tor_browser_locale)"
+
+ configure_chroot_dns_servers "${chroot}" "${dns_servers}"
+ configure_chroot_browser_profile "${chroot}" "${browser_name}" \
+ "${browser_user}" "${home_page}" "${@}"
+ set_chroot_browser_locale "${chroot}" "${browser_name}" "${browser_user}" \
+ "${best_locale}"
+ set_chroot_browser_name "${chroot}" "${human_readable_name}" \
+ "${browser_name}" "${browser_user}" "${best_locale}"
+ set_chroot_browser_permissions "${chroot}" "${browser_name}" \
+ "${browser_user}"
+}
+
+# Start the browser in the chroot
+run_browser_in_chroot () {
+ local chroot="${1}"
+ local browser_name="${2}"
+ local chroot_user="${3}"
+ local local_user="${4}"
+ local profile="$(browser_profile_dir ${browser_name} ${chroot_user})"
+
+ sudo -u "${local_user}" xhost "+SI:localuser:${chroot_user}"
+ chroot "${chroot}" sudo -u "${chroot_user}" /bin/sh -c \
+ ". /usr/local/lib/tails-shell-library/tor-browser.sh && \
+ exec_firefox -DISPLAY=:0.0 \
+ -profile '${profile}'"
+ sudo -u "${local_user}" xhost "-SI:localuser:${chroot_user}"
+}
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/common.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/common.sh
index f490a16..dda1888 100644
--- a/config/chroot_local-includes/usr/local/lib/tails-shell-library/common.sh
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/common.sh
@@ -1,5 +1,11 @@
#!/bin/sh
+# Run `check_expr` until `timeout` seconds has passed, and sleep
+# `delay` (optional, defaults to 1) seconds in between the calls.
+# Note that execution isn't aborted exactly after `timeout`
+# seconds. In the worst case (the timeout happens right after we check
+# if the timeout has happened) we'll wait in total: `timeout` seconds +
+# `delay` seconds + the time needed for `check_expr`.
wait_until() {
local timeout check_expr delay timeout_at
timeout="${1}"
@@ -14,3 +20,31 @@ wait_until() {
done
return 0
}
+
+# Just an alias. The second argument (wait_until()'s check_expr) is
+# the "try code block". Just like in `wait_until()`, the timeout isn't
+# very accurate.
+try_for() {
+ wait_until "${@}"
+}
+
+# Sets the `value` of a `key` in a simple configuration `file`. With
+# "simple" you should think something like a the shell environment as
+# output by the `env` command. Hence this is only useful for
+# configuration files that have no structure (e.g. sections with
+# semantic meaning, like the namespace secions in .gitconfig), allow
+# only one assignment per line, and a fixed/static assignment operator
+# (`op`, which defaults to '=', but other examples would be " = " or
+# torrc's " "). If the key already exists its value is updated in
+# place, otherwise it's added at the end.
+set_simple_config_key() {
+ local key="${1}"
+ local value="${2}"
+ local file="${3}"
+ local op="${4:-=}"
+ if grep -q "^${key}${op}" "${file}"; then
+ sed -i -n "s/^${key}${op}.*$/${key}${op}${value}/p" "${file}"
+ else
+ echo "${key}${op}${value}" >> "${file}"
+ fi
+}
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/i2p.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/i2p.sh
index 62e9511..f12393d 100644
--- a/config/chroot_local-includes/usr/local/lib/tails-shell-library/i2p.sh
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/i2p.sh
@@ -1,13 +1,24 @@
#!/bin/sh
+# Import set_simple_config_key().
+. /usr/local/lib/tails-shell-library/common.sh
+
+# Import language_code_from_locale().
+. /usr/local/lib/tails-shell-library/localization.sh
+
+I2P_DEFAULT_CONFIG="/usr/share/i2p"
I2P_CONFIG="/var/lib/i2p/i2p-config"
I2P_TUNNEL_CONFIG="${I2P_CONFIG}/i2ptunnel.config"
+i2p_is_enabled() {
+ grep -qw "i2p" /proc/cmdline
+}
+
i2p_eep_proxy_address() {
- # We retrieve the host and port number from the I2P profile This
+ # We retrieve the host and port number from the I2P profile. This
# shouldn't be anywhere other than 127.0.0.1:4444 but in case
# someone modifies the hook scripts or the default changes in I2P,
- # this check should still work
+ # this check should still work.
local listen_host listen_port
listen_host=$(awk -F= '/^tunnel\.0\.interface/{print $2}' \
"${I2P_TUNNEL_CONFIG}")
@@ -27,3 +38,20 @@ i2p_router_console_address() {
i2p_router_console_is_ready() {
netstat -4nlp | grep -qwF "$(i2p_router_console_address)"
}
+
+set_best_i2p_router_console_lang() {
+ # We will use the detected language even if I2P doesn't support it; it
+ # will default to English in that case.
+ local lang="$(language_code_from_locale "${LANG}")"
+ # We first try to set it in an existing "live" config, even though
+ # the effect will only appear after a restart.
+ local config
+ for config in "${I2P_CONFIG}/router.config" \
+ "${I2P_DEFAULT_CONFIG}/router.config"; do
+ if [ -e "${config}" ]; then
+ set_simple_config_key "routerconsole.lang" "${lang}" "${config}"
+ return 0
+ fi
+ done
+ return 1
+}
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/localization.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/localization.sh
new file mode 100644
index 0000000..df7dd7c
--- /dev/null
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/localization.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# Extracts the language part of a given locale, e.g. "en_US.UTF-8"
+# yields "en". Often $LANG will be passed as the argument.
+language_code_from_locale () {
+ echo "${1}" | sed "s,\(_\|\.\).*$,,"
+}
+
+# Prints the path to the localized (according to the environment's
+# LANG) version of `page` in the local copy of Tails' website. `page`
+# should specify only the name of the page, not the language code (of
+# course!) or the ".html" extension. If a localized page doesn't exist
+# the default is the English version.
+localized_tails_doc_page () {
+ local page="${1}"
+ local lang_code="$(language_code_from_locale "${LANG}")"
+ local try_page
+ for locale in "${lang_code}" "en"; do
+ try_page="${page}.${locale}.html"
+ if [ -r "${try_page}" ]; then
+ echo "${try_page}"
+ return 0
+ fi
+ done
+ return 1
+}
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/tails_greeter.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/tails-greeter.sh
index 7ff6694..9c301f1 100644
--- a/config/chroot_local-includes/usr/local/lib/tails-shell-library/tails_greeter.sh
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/tails-greeter.sh
@@ -14,12 +14,25 @@ persistence_is_enabled() {
[ "$(_get_tg_setting "${PERSISTENCE_STATE}" TAILS_PERSISTENCE_ENABLED)" = true ]
}
+persistence_is_enabled_for() {
+ persistence_is_enabled && mountpoint -q "$1" 2>/dev/null
+}
+
+persistence_is_enabled_read_write() {
+ persistence_is_enabled && \
+ [ "$(_get_tg_setting "${PERSISTENCE_STATE}" TAILS_PERSISTENCE_READONLY)" != true ]
+}
+
mac_spoof_is_enabled() {
# Only return false when explicitly told so to increase failure
# safety.
[ "$(_get_tg_setting "${PHYSICAL_SECURITY_SETTINGS}" TAILS_MACSPOOF_ENABLED)" != false ]
}
+windows_camouflage_is_enabled() {
+ [ -e /var/lib/gdm3/tails.camouflage ]
+}
+
tails_netconf() {
_get_tg_setting "${PHYSICAL_SECURITY_SETTINGS}" TAILS_NETCONF
}
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor-browser.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor-browser.sh
index 93fe389..ee3c0cf 100644
--- a/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor-browser.sh
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor-browser.sh
@@ -11,20 +11,34 @@ exec_firefox() {
exec "${TBB_INSTALL}"/firefox "${@}"
}
+exec_unconfined_firefox() {
+ LD_LIBRARY_PATH="${TBB_INSTALL}"
+ export LD_LIBRARY_PATH
+ exec "${TBB_INSTALL}"/firefox-unconfined "${@}"
+}
+
guess_best_tor_browser_locale() {
- local long_locale short_locale
+ local long_locale short_locale similar_locale
long_locale="$(echo ${LANG} | sed -e 's/\..*$//' -e 's/_/-/')"
short_locale="$(echo ${long_locale} | cut -d"-" -f1)"
if [ -e "${TBB_EXT}/langpack-${long_locale}@firefox.mozilla.org.xpi" ]; then
- echo ${long_locale}
- elif ls -1 "${TBB_EXT}" | grep -q "^langpack-${short_locale}\(-[A-Z]\+\)\?@firefox.mozilla.org.xpi$"; then
- # If we use locale xx-YY and there is no langpack for xx nor
- # xx-YY but there is one for xx-ZZ, then Firefox is smart
- # enough to use the xx-ZZ langpack if we set the locale to xx.
- echo ${short_locale}
- else
- echo en-US
+ echo "${long_locale}"
+ return
+ elif [ -e "${TBB_EXT}/langpack-${short_locale}@firefox.mozilla.org.xpi" ]; then
+ echo "${short_locale}"
+ return
fi
+ # If we use locale xx-YY and there is no langpack for xx-YY nor xx
+ # there may be a similar locale xx-ZZ that we should use instead.
+ similar_locale="$(ls -1 "${TBB_EXT}" | \
+ sed -n "s,^langpack-\(${short_locale}-[A-Z]\+\)@firefox.mozilla.org.xpi$,\1,p" | \
+ head -n 1)" || :
+ if [ -n "${similar_locale}" ]; then
+ echo "${similar_locale}"
+ return
+ fi
+
+ echo 'en-US'
}
guess_best_tor_launcher_locale() {
diff --git a/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor.sh b/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor.sh
index 6139a45..d797c50 100755
--- a/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor.sh
+++ b/config/chroot_local-includes/usr/local/lib/tails-shell-library/tor.sh
@@ -34,8 +34,12 @@ tor_control_setconf() {
}
tor_bootstrap_progress() {
- grep -o "\[notice\] Bootstrapped [[:digit:]]\+%:" ${TOR_LOG} | \
- tail -n1 | sed "s|\[notice\] Bootstrapped \([[:digit:]]\+\)%:|\1|"
+ RES=$(grep -o "\[notice\] Bootstrapped [[:digit:]]\+%:" ${TOR_LOG} | \
+ tail -n1 | sed "s|\[notice\] Bootstrapped \([[:digit:]]\+\)%:|\1|")
+ if [ -z "$RES" ] ; then
+ RES=0
+ fi
+ echo -n "$RES"
}
# Potential Tor bug: it seems like using this version makes Tor get
diff --git a/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py b/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py
index 8778ddd..77a5309 100644
--- a/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py
+++ b/config/chroot_local-includes/usr/local/sbin/autotest_remote_shell.py
@@ -19,16 +19,15 @@ def mk_switch_user_fn(uid, gid):
return switch_user
def run_cmd_as_user(cmd, user):
- env = environ.copy()
pwd_user = getpwnam(user)
switch_user_fn = mk_switch_user_fn(pwd_user.pw_uid,
pwd_user.pw_gid)
- env['USER'] = user
- env['LOGNAME'] = user
- env['USERNAME'] = user
- env['HOME'] = pwd_user.pw_dir
- env['MAIL'] = "/var/mail/" + user
- env['PWD'] = env['HOME']
+ # We try to create an environment identical to what's expected
+ # inside Tails for the user by logging in (via `su`) as the user and
+ # extracting the environment.
+ pipe = Popen('su -c env ' + user, stdout=PIPE, shell=True)
+ env_data = pipe.communicate()[0]
+ env = dict((line.split('=', 1) for line in env_data.splitlines()))
env['DISPLAY'] = ':0.0'
try:
env['XAUTHORITY'] = glob("/var/run/gdm3/auth-for-amnesia-*/database")[0]
diff --git a/config/chroot_local-includes/usr/local/sbin/do_not_ever_run_me b/config/chroot_local-includes/usr/local/sbin/do_not_ever_run_me
index 9dc1751..60c2d16 100755
--- a/config/chroot_local-includes/usr/local/sbin/do_not_ever_run_me
+++ b/config/chroot_local-includes/usr/local/sbin/do_not_ever_run_me
@@ -37,9 +37,3 @@ $IP6T -F
$IP6T -P INPUT ACCEPT
$IP6T -P FORWARD ACCEPT
$IP6T -P OUTPUT ACCEPT
-
-echo "You might want to unset http_proxy and HTTP_PROXY environment variables as well:"
-echo " unset http_proxy"
-echo " unset https_proxy"
-echo " unset HTTP_PROXY"
-echo " unset HTTPS_PROXY"
diff --git a/config/chroot_local-includes/usr/local/sbin/i2p-browser b/config/chroot_local-includes/usr/local/sbin/i2p-browser
index 1ccbb04..5a494a0 100755
--- a/config/chroot_local-includes/usr/local/sbin/i2p-browser
+++ b/config/chroot_local-includes/usr/local/sbin/i2p-browser
@@ -2,60 +2,21 @@
set -e
-# This isn't very useful without I2P...
-grep -qw "i2p" /proc/cmdline || exit 0
-
-CMD=$(basename ${0})
-LOCK=/var/lock/${CMD}
-
-. gettext.sh
-TEXTDOMAIN="tails"
-export TEXTDOMAIN
-
-. /usr/local/lib/tails-shell-library/i2p.sh
-
-CONF_DIR=/var/lib/i2p-browser
-COW=${CONF_DIR}/cow
-CHROOT=${CONF_DIR}/chroot
-BROWSER_USER=i2pbrowser
-TBB_PREFS="/etc/tor-browser/profile/preferences"
-START_PAGE="http://127.0.0.1:7657"
-
-# Import the TBB_INSTALL, TBB_EXT and TBB_PROFILE variables, and
-# exec_firefox(), configure_xulrunner_app_locale() and
-# guess_best_tor_browser_locale()
+# Import the TBB_EXT variable, and guess_best_tor_browser_locale().
. /usr/local/lib/tails-shell-library/tor-browser.sh
-NOSCRIPT="${TBB_EXT}/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
-TORBUTTON="${TBB_EXT}/torbutton@torproject.org"
-NAME="`gettext \"I2P Browser\"`"
+# Import windows_camouflage_is_enabled()
+. /usr/local/lib/tails-shell-library/tor-browser.sh
-if [ -e /var/lib/gdm3/tails.camouflage ]; then
- CAMOUFLAGE=yes
-fi
+# Import try_cleanup_browser_chroot(), setup_browser_chroot(),
+# configure_chroot_dns_servers(), configure_chroot_browser(),
+# configure_chroot_browser(), set_chroot_browser_locale()
+# set_chroot_torbutton_browser_name(), set_chroot_browser_permissions()
+# and run_browser_in_chroot().
+. /usr/local/lib/tails-shell-library/chroot-browser.sh
-cleanup () {
- # Break down the chroot and kill all of its processes
- local counter=0
- local ret=0
- while [ "${counter}" -le 10 ] && \
- pgrep -u ${BROWSER_USER} 1>/dev/null 2>&1; do
- pkill -u ${BROWSER_USER} 1>/dev/null 2>&1
- ret=${?}
- sleep 1
- counter=$((${counter}+1))
- done
- [ ${ret} -eq 0 ] || pkill -9 -u ${BROWSER_USER} 1>/dev/null 2>&1
- for mnt in ${CHROOT}/dev ${CHROOT}/proc ${CHROOT} ${COW}; do
- counter=0
- while [ "${counter}" -le 10 ] && mountpoint -q ${mnt} 2>/dev/null; do
- umount ${mnt} 2>/dev/null
- sleep 1
- counter=$((${counter}+1))
- done
- done
- rmdir ${COW} ${CHROOT} 2>/dev/null
-}
+# Import i2p_router_console_is_ready() and i2p_is_enabled().
+. /usr/local/lib/tails-shell-library/i2p.sh
error () {
local cli_text="${CMD}: `gettext \"error:\"` ${@}"
@@ -63,7 +24,7 @@ error () {
${@}"
echo "${cli_text}" >&2
- sudo -u ${SUDO_USER} zenity --error --title "" --text "${dialog_text}"
+ sudo -u "${SUDO_USER}" zenity --error --title "" --text "${dialog_text}"
exit 1
}
@@ -76,7 +37,7 @@ verify_start () {
local exit="`gettext \"_Exit\"`"
# Since zenity can't set the default button to cancel, we switch the
# labels and interpret the return value as its negation.
- if sudo -u ${SUDO_USER} zenity --question --title "" --ok-label "${exit}" \
+ if sudo -u "${SUDO_USER}" zenity --question --title "" --ok-label "${exit}" \
--cancel-label "${launch}" --text "${dialog_msg}"; then
exit 0
fi
@@ -88,285 +49,20 @@ show_start_notification () {
tails-notify-user "${title}" "${body}" 10000
}
-setup_chroot () {
- # Setup a chroot on an aufs "fork" of the filesystem.
- # FIXME: When LXC matures to the point where it becomes a viable option
- # for creating isolated jails, the chroot can be used as its rootfs.
- echo "* Setting up chroot"
-
- trap cleanup INT
- trap cleanup EXIT
-
- local rootfs_dir
- local rootfs_dirs_path=/lib/live/mount/rootfs
- local tails_module_path=/lib/live/mount/medium/live/Tails.module
- local aufs_dirs=
-
- # We have to pay attention to the order we stack the filesystems;
- # newest must be first, and remember that the .module file lists
- # oldest first, newest last.
- while read rootfs_dir; do
- rootfs_dir="${rootfs_dirs_path}/${rootfs_dir}"
- mountpoint -q "${rootfs_dir}" && \
- aufs_dirs="${rootfs_dir}=rr+wh:${aufs_dirs}"
- done < "${tails_module_path}"
- # But our copy-on-write dir must be at the very top.
- aufs_dirs="${COW}=rw:${aufs_dirs}"
-
- mkdir -p ${COW} ${CHROOT} && \
- mount -t tmpfs tmpfs ${COW} && \
- mount -t aufs -o "noatime,noxino,dirs=${aufs_dirs}" aufs ${CHROOT} && \
- mount -t proc proc ${CHROOT}/proc && \
- mount --bind /dev ${CHROOT}/dev || \
- error "`gettext \"Failed to setup chroot.\"`"
-
- # Workaround for todo/buggy_aufs_vs_unsafe-browser
- chmod -t ${COW}
-}
-
-set_chroot_browser_name () {
- NAME="${1}"
- LOCALE="${2}"
- EXT_DIR=${CHROOT}/"${TBB_EXT}"
- BRANDING=branding/brand.dtd
- if [ "${LOCALE}" != en-US ]; then
- PACK="${EXT_DIR}/langpack-${LOCALE}@firefox.mozilla.org.xpi"
- TOP=browser/chrome
- REST=${LOCALE}/locale
- else
- PACK="${CHROOT}/${TBB_INSTALL}/browser/omni.ja"
- TOP=chrome
- REST=en-US/locale
- fi
- TMP=$(mktemp -d)
- # Non-zero exit code due to non-standard ZIP archive.
- # The following steps will fail soon if the extraction failed anyway.
- unzip -d "${TMP}" "${PACK}" || true
- sed -i "s/<"'!'"ENTITY\s\+brand\(Full\|Short\)Name.*$/<"'!'"ENTITY brand\1Name \"${NAME}\">/" "${TMP}/${TOP}/${REST}/${BRANDING}"
- rm "${PACK}"
- (cd $TMP ; 7z a -tzip "${PACK}" .)
- chmod a+r "${PACK}"
- rm -Rf "${TMP}"
-}
-
-configure_chroot () {
- echo "* Configuring chroot"
-
- # Prevent sudo from complaining about failing to resolve the 'amnesia' host
- echo "127.0.0.1 localhost amnesia" > ${CHROOT}/etc/hosts
-
- # Keep the NoScript and TorButton addons
- chroot ${CHROOT} dpkg -l 'xul-ext*' |grep -v 'noscript\|torbutton' \
- | awk '/^ii/{print $2}' | xargs -r chroot ${CHROOT} dpkg --remove
-
- # Create a fresh Tor Browser profile for the i2pbrowser user
- BROWSER_PROFILE="${CHROOT}/home/${BROWSER_USER}/.tor-browser/profile.default"
- BROWSER_EXT="${BROWSER_PROFILE}/extensions"
- mkdir -p "${BROWSER_EXT}"
- ln -s "${NOSCRIPT}" "${BROWSER_EXT}"
- # TorButton forces the Browser name to Tor Browser. This hack is to undo that and set it to I2P Browser
- # to try to prevent user confusion.
- TMP=$(mktemp -d)
- cp -a /usr/share/xul-ext/torbutton/ $TMP
- for LANGPACK in $(ls ${TBB_PROFILE}/extensions/langpack-*.xpi); do
- ln -s "${LANGPACK}" "${BROWSER_EXT}"
- done
- find $TMP/torbutton -name 'brand.dtd' -print0 | \
- xargs -0 -r sed -i "s/<"'!'"ENTITY\s\+brand\(Full\|Short\)Name.*$/<"'!'"ENTITY brand\1Name \"${NAME}\">/"
- cd $TMP/torbutton && 7z a -tzip "${BROWSER_EXT}/torbutton@torproject.org.xpi" .
- rm -r $TMP
- BROWSER_PREF_DIR="${BROWSER_PROFILE}/preferences"
- BROWSER_PREFS="${BROWSER_PREF_DIR}/prefs.js"
- mkdir -p "${BROWSER_PREF_DIR}"
+copy_extra_tbb_prefs () {
+ local chroot="${1}"
+ local browser_name="${2}"
+ local browser_user="${3}"
+ local tbb_prefs="/etc/tor-browser/profile/preferences"
+ local browser_prefs_dir="${chroot}/home/${browser_user}/.${browser_name}/profile.default/preferences"
+ mkdir -p "${browser_prefs_dir}"
# Selectively copy the TBB prefs we want
- sed '/\(security\|update\|download\|spell\|noscript\|torbrowser\|torbutton\)/!d' $TBB_PREFS/0000tails.js > \
- ${BROWSER_PREF_DIR}/0000tails.js
- sed '/\(capability\|noscript\|torbutton\)/!d' ${TBB_PREFS}/extension-overrides.js > \
- ${BROWSER_PREF_DIR}/extension-overrides.js
-
- # Localization
- BEST_LOCALE="$(guess_best_tor_browser_locale)"
- configure_xulrunner_app_locale "${BROWSER_PROFILE}" "${BEST_LOCALE}"
-
- # Prevent File -> Print or CTRL+P from causing the browser to hang
- # for several minutes while trying to communicate with CUPS, since
- # access to port 631 isn't allowed through.
- echo 'user_pref("print.postscript.cups.enabled", false);' >> \
- ${BROWSER_PREFS}
-
- # Set the name (e.g. window title) of the browser
- set_chroot_browser_name "`gettext \"I2P Browser\"`" "${BEST_LOCALE}"
-
- # Set start page to the router console
- echo 'user_pref("browser.startup.homepage", "'${START_PAGE}'");' >> \
- ${BROWSER_PREFS}
-
-
- # Disable searching from the URL bar
- echo 'user_pref("keyword.enabled", false);' >> \
- ${BROWSER_PREFS}
- # Hide "Get Addons" in Add-ons manager
- echo 'user_pref("extensions.getAddons.showPane", false);' >> \
- ${BROWSER_PREFS}
- # add the I2P proxy to all protocols
- cat > "${BROWSER_PREF_DIR}/i2p.js" << EOF
-user_pref("extensions.torbutton.http_port", 4444);
-user_pref("extensions.torbutton.http_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.https_port", 4444);
-user_pref("extensions.torbutton.https_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.custom.ftp_port", 4444);
-user_pref("extensions.torbutton.custom.ftp_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.custom.http_port", 4444);
-user_pref("extensions.torbutton.custom.http_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.custom.https_port", 4444);
-user_pref("extensions.torbutton.custom.https_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.ftp_port", 4444);
-user_pref("extensions.torbutton.ftp_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.gopher_port", 4444);
-user_pref("extensions.torbutton.gopher_proxy", "127.0.0.1");
-user_pref("extensions.torbutton.inserted_button", true);
-user_pref("extensions.torbutton.settings_method", "custom");
-user_pref("network.proxy.ftp", "127.0.0.1");
-user_pref("network.proxy.ftp_port", 4444);
-user_pref("network.proxy.http", "127.0.0.1");
-user_pref("network.proxy.http_port", 4444);
-user_pref("network.proxy.no_proxies_on", "127.0.0.1");
-user_pref("network.proxy.ssl", "127.0.0.1");
-user_pref("network.proxy.ssl_port", 4444);
-EOF
- # Hide options in the I2P Browser.
- # It would be good to implement the ability to persist the browser profile in the
- # future. At that point, the Bookmark functionality could be restored.
- BROWSER_CHROME="${BROWSER_PROFILE}/chrome/userChrome.css"
- mkdir -p "$(dirname "${BROWSER_CHROME}")"
- cat > ${BROWSER_CHROME} << EOF
-/* Required, do not remove */
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-/* Hide access to the bookmarks to try to prevent "data loss" due to users
- * adding bookmarks even though the profile is destroyed at browser close.
- * Keyboard shortcuts still work, but this makes it harder to 'accidentally'
- * lose bookmarks.
- *
- * Note that any of the selectors that start with 'app' apply to the menu that
- * is used if the main menu is hidden. Any that start with 'wrapper' are
- * buttons that are normally visible within the 'customize toolbar' option. The
- * others are probably self-explanatory.
- */
-
-/* Remove the History and Bookmarks menus and buttons */
-#appmenu_bookmarks,
-#appmenu_history,
-#bookmarks,
-#bookmarks-menu-button,
-#bookmarksMenu,
-#history,
-#history-menu,
-#history-menu-button,
-#wrapper-history-button,
-#wrapper-bookmarks-button,
-
-/* Hide the sidebar menu (underneath View) since the default sidebars consist
- * of history and bookmarks. Also disable the bookmark toolbar.
- */
-#toggle_PersonalToolbar,
-#viewSidebarMenuMenu,
-
-/* Remove the "Star button" and "History Dropdown arrow" from the URL bar
- * since neither history nor bookmarks are saved.
- */
-#star-button,
-[anonid="historydropmarker"],
-
-/* Remove bookmark options from the context menus */
-#context-bookmarkframe,
-#context-bookmarklink,
-#context-bookmarkpage,
-
-/* Hide the option for emailing links since it's doomed to failure
- * without a configured email client.
- */
-menuitem[command="Browser:SendLink"],
-
-/* Hide Print options */
-/*
-#menu_printSetup,
-#menu_printPreview,
-#menu_print,
-#menu_print + menuseparator,
-[command="cmd_print"],
-*/
-
-/* Hide the sync functionality which won't work with I2P */
-#BrowserPreferences radio[pane="paneSync"],
-#sync-button,
-#sync-menu-button,
-#sync-setup,
-#sync-setup-appmenu,
-#sync-status-button,
-#sync-syncnowitem-appmenu,
-#wrapper-sync-button,
-
-/* Without I2P search engines defined, the search bar is useless.
- * Since there are no I2P search engines added to Tails (yet),
- * let's hide it and the Update Pane in Firefox's Preferences.
- */
-#search-container,
-#updateTab,
-
-/* Hide options in the Help menu that lead to disallowed resources on the
- * Internet.
- */
-#appmenu_feedbackPage,
-#appmenu_gettingStarted,
-#appmenu_openHelp,
-#feedbackPage,
-#gettingStarted,
-#menu_HelpPopup_reportPhishingtoolmenu,
-#menu_openHelp,
-
-/* Hide TorBrowser Health Report and its configuration option */
-#appmenu_healthReport,
-#dataChoicesTab,
-#healthReport
-
-/* Now the actual hiding */
-{display: none !important}
-EOF
- rm -rf ${BROWSER_EXT}/branding@amnesia.boum.org
-
- # Remove all bookmarks
- rm -f "${CHROOT}/${TBB_PROFILE}/bookmarks.html"
- rm -f ${BROWSER_PROFILE}/bookmarks.html
- rm -f ${BROWSER_PROFILE}/places.sqlite
-
- chown -R ${BROWSER_USER}:${BROWSER_USER} "${CHROOT}/home/${BROWSER_USER}/.tor-browser"
-
- # Change the theme when not using Windows camouflage
- if [ -z "${CAMOUFLAGE}" ]; then
- cat >> ${BROWSER_PREFS} <<EOF
-user_pref("lightweightThemes.isThemeSelected", true);
-user_pref("lightweightThemes.usedThemes", "[{\"id\":\"1\",\"name\":\"I2P Browser\",\"headerURL\":\"file:///usr/share/pixmaps/red_dot.png\",\"footerURL\":\"file:///usr/share/pixmaps/red_dot.png\",\"textcolor\":\"#FFFFFF\",\"accentcolor\":\"#66ABEB\",\"updateDate\":0,\"installDate\":0}]");
-EOF
- else
- # The camouflage activation script requires a dbus server for
- # properly configuring GNOME, so we start one in the chroot
- chroot ${CHROOT} sudo -H -u ${BROWSER_USER} sh -c 'eval `dbus-launch --auto-syntax`; tails-activate-win8-theme' || :
- fi
-
-}
-
-run_browser_in_chroot () {
- # Start Iceweasel in the chroot
- echo "* Starting I2P Browser"
-
- sudo -u ${SUDO_USER} xhost +SI:localuser:${BROWSER_USER} 2>/dev/null
- chroot ${CHROOT} sudo -u ${BROWSER_USER} /bin/sh -c \
- ". /usr/local/lib/tails-shell-library/tor-browser.sh && \
- exec_firefox -DISPLAY=:0.0 \
- -profile /home/${BROWSER_USER}/.tor-browser/profile.default"
- sudo -u ${SUDO_USER} xhost -SI:localuser:${BROWSER_USER} 2>/dev/null
+ sed '/\(security\|update\|download\|spell\|noscript\|torbrowser\|torbutton\)/!d' "${tbb_prefs}/0000tails.js" > \
+ "${browser_prefs_dir}/0000tails.js"
+ sed '/\(capability\|noscript\|torbutton\)/!d' "${tbb_prefs}/extension-overrides.js" > \
+ "${browser_prefs_dir}/extension-overrides.js"
+ chown -R "${browser_user}:${browser_user}" "${browser_prefs_dir}"
}
show_shutdown_notification () {
@@ -375,8 +71,31 @@ show_shutdown_notification () {
tails-notify-user "${title}" "${body}" 10000
}
+# Main script:
+
+# This isn't very useful without I2P...
+i2p_is_enabled || exit 0
+
+CMD="$(basename "${0}")"
+LOCK="/var/lock/${CMD}"
+
+. gettext.sh
+TEXTDOMAIN="tails"
+export TEXTDOMAIN
+
+CONF_DIR="/var/lib/i2p-browser"
+COW="${CONF_DIR}/cow"
+CHROOT="${CONF_DIR}/chroot"
+BROWSER_NAME="i2p-browser"
+BROWSER_USER="i2pbrowser"
+HOME_PAGE="http://127.0.0.1:7657"
+NOSCRIPT_EXT_XPI="${TBB_EXT}/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
+TORBUTTON_EXT_DIR="${TBB_EXT}/torbutton@torproject.org"
+HUMAN_READABLE_NAME="`gettext \"I2P Browser\"`"
+IP4_NAMESERVERS="0.0.0.0"
+
# Prevent multiple instances of the script.
-exec 9>${LOCK}
+exec 9>"${LOCK}"
if ! flock -x -n 9; then
error "`gettext \"Another I2P Browser is currently running, or being cleaned up. Please retry in a while.\"`"
fi
@@ -385,9 +104,24 @@ if ! i2p_router_console_is_ready; then
verify_start
fi
show_start_notification
-setup_chroot
-configure_chroot
-run_browser_in_chroot
+
+echo "* Setting up chroot"
+setup_chroot_for_browser "${CHROOT}" "${COW}" "${BROWSER_USER}" || \
+ error "`gettext \"Failed to setup chroot.\"`"
+
+echo "* Configuring chroot"
+configure_chroot_browser "${CHROOT}" "${BROWSER_USER}" "${BROWSER_NAME}" \
+ "${HUMAN_READABLE_NAME}" "${HOME_PAGE}" "${IP4_NAMESERVERS}" \
+ "${TBB_EXT}"/langpack-*.xpi "${NOSCRIPT_EXT_XPI}" "${TORBUTTON_EXT_DIR}" && \
+ copy_extra_tbb_prefs "${CHROOT}" "${BROWSER_NAME}" "${BROWSER_USER}" || \
+ error "`gettext \"Failed to configure browser.\"`"
+
+echo "* Starting I2P Browser"
+run_browser_in_chroot "${CHROOT}" "${BROWSER_NAME}" "${BROWSER_USER}" \
+ "${SUDO_USER}" || \
+ error "`gettext \"Failed to run browser.\"`"
+
+echo "* Exiting the I2P Browser"
show_shutdown_notification
exit 0
diff --git a/config/chroot_local-includes/usr/local/sbin/tails-debugging-info b/config/chroot_local-includes/usr/local/sbin/tails-debugging-info
index 396862f..4ae2fdb 100755
--- a/config/chroot_local-includes/usr/local/sbin/tails-debugging-info
+++ b/config/chroot_local-includes/usr/local/sbin/tails-debugging-info
@@ -17,6 +17,7 @@ debug_command /usr/sbin/dmidecode -s system-product-name
debug_command /usr/sbin/dmidecode -s system-version
debug_command "/bin/dmesg"
debug_command "/bin/lsmod"
+debug_command "/bin/mount"
debug_command "/usr/bin/lspci"
debug_command grep spoof-mac: /var/log/messages
@@ -35,3 +36,4 @@ debug_file "/var/log/live/config.log"
debug_file "/var/lib/gdm3/tails.persistence"
debug_file "/var/lib/live/config/tails.physical_security"
debug_file "/live/persistence/TailsData_unlocked/persistence.conf"
+debug_file "/live/persistence/TailsData_unlocked/live-additional-software.conf"
diff --git a/config/chroot_local-includes/usr/local/sbin/tails-i2p b/config/chroot_local-includes/usr/local/sbin/tails-i2p
index a70739c..0745220 100644
--- a/config/chroot_local-includes/usr/local/sbin/tails-i2p
+++ b/config/chroot_local-includes/usr/local/sbin/tails-i2p
@@ -16,7 +16,8 @@ set -u
# Import wait_until()
. /usr/local/lib/tails-shell-library/common.sh
-# Import i2p_has_bootstrapped() and i2p_router_console_is_ready()
+# Import i2p_has_bootstrapped(), i2p_router_console_is_ready() and
+# set_best_i2p_router_console_lang().
. /usr/local/lib/tails-shell-library/i2p.sh
I2P_STARTUP_TIMEOUT=60
@@ -62,7 +63,16 @@ notify_bootstrap_success() {
case "${1}" in
start|restart)
- service i2p restart
+ # Stop I2P before setting the router console language in case
+ # it pushes any updated options on quit.
+ if service i2p status; then
+ service i2p stop
+ fi
+ # Get LANG, since we may run this from an environment that
+ # doesn't have it set.
+ . /etc/default/locale
+ set_best_i2p_router_console_lang
+ service i2p start
wait_until_i2p_router_console_is_ready || startup_failure
notify_router_console_success
wait_until_i2p_has_bootstrapped || bootstrap_failure
diff --git a/config/chroot_local-includes/usr/local/sbin/tails-spoof-mac b/config/chroot_local-includes/usr/local/sbin/tails-spoof-mac
index df354a8..e09f010 100755
--- a/config/chroot_local-includes/usr/local/sbin/tails-spoof-mac
+++ b/config/chroot_local-includes/usr/local/sbin/tails-spoof-mac
@@ -8,14 +8,22 @@ set -e
. /usr/local/lib/tails-shell-library/hardware.sh
. /usr/local/lib/tails-shell-library/log.sh
-. /usr/local/lib/tails-shell-library/tails_greeter.sh
+. /usr/local/lib/tails-shell-library/tails-greeter.sh
. /usr/bin/gettext.sh
TEXTDOMAIN="tails"
export TEXTDOMAIN
show_notification() {
- until pgrep gnome-panel >/dev/null; do
+ # We must wait until all the facilities necessary for showing the
+ # notification to the Live user is available to prevent it from
+ # getting lost.
+ # Note: We pgrep for notification-daemon's full command because
+ # otherwise pgrep will look at the process name, which seems to be
+ # cropped to 15 chars, i.e. "notification-da". Also, we probably
+ # do not want to get mixed up with "gdu-notification-daemon".
+ until pgrep gnome-panel >/dev/null && \
+ pgrep --full /usr/lib/notification-daemon/notification-daemon >/dev/null; do
sleep 1
done
/usr/local/sbin/tails-notify-user "${1}" "${2}" 0
@@ -55,8 +63,8 @@ mac_spoof_panic() {
echo "blacklist ${module}" >> /etc/modprobe.d/"${module}"-blacklist.conf
unload_module_and_rev_deps "${module}" || :
if nic_exists "${nic}"; then
- service network-manager stop
log "Failed to unload module ${module} of NIC ${nic}. Stopping NetworkManager."
+ service network-manager stop
notify_panic_failure "${nic}" "${nic_name}" &
else
log "Successfully unloaded module ${module} of NIC ${nic}."
@@ -68,7 +76,7 @@ spoof_mac() {
local msg
if ! msg=$(macchanger -e "${1}" 2>&1); then
log "macchanger failed for NIC ${1}, returned ${?} and said: ${msg}"
- exit 1
+ return 1
fi
}
@@ -95,7 +103,12 @@ OLD_MAC="$(get_current_mac_of_nic "${NIC}")"
# real MAC address at each occasion but actually leaking the real MAC
# address will be more serious in practice.
for i in 1 2 3; do
- spoof_mac "${NIC}" || :
+ if ! spoof_mac "${NIC}"; then
+ # If our MAC spoofing primitive fails, we fail safe by forcing
+ # us to enter into panic mode.
+ unset NEW_MAC
+ break
+ fi
NEW_MAC="$(get_current_mac_of_nic "${NIC}")"
if [ "${OLD_MAC}" != "${NEW_MAC}" ]; then
break
@@ -113,8 +126,8 @@ then
# If mac_spoof_panic() fails we're quite screwed, so we kill
# NetworkManager without notification to do our best to
# prevent a MAC address leak.
- service network-manager stop
log "Panic mode failed for NIC ${NIC}. Killing NetworkManager."
+ service network-manager stop
fi
exit 1
fi
diff --git a/config/chroot_local-includes/usr/local/sbin/unsafe-browser b/config/chroot_local-includes/usr/local/sbin/unsafe-browser
index ff73341..7c6da22 100755
--- a/config/chroot_local-includes/usr/local/sbin/unsafe-browser
+++ b/config/chroot_local-includes/usr/local/sbin/unsafe-browser
@@ -2,60 +2,21 @@
set -e
-CMD=$(basename ${0})
-LOCK=/var/lock/${CMD}
-
-. gettext.sh
-TEXTDOMAIN="tails"
-export TEXTDOMAIN
-
-CONF_DIR=/var/lib/unsafe-browser
-COW=${CONF_DIR}/cow
-CHROOT=${CONF_DIR}/chroot
-CLEARNET_USER=clearnet
-
# Import tor_is_working()
. /usr/local/lib/tails-shell-library/tor.sh
-# Import the TBB_INSTALL, TBB_EXT and TBB_PROFILE variables, and
-# exec_firefox(), configure_xulrunner_app_locale() and
-# guess_best_tor_browser_locale()
+# Import the TBB_EXT variable, and guess_best_tor_browser_locale().
. /usr/local/lib/tails-shell-library/tor-browser.sh
-WARNING_PAGE='/usr/share/doc/tails/website/misc/unsafe_browser_warning'
-LANG_CODE="$(echo ${LANG} | head -c 2)"
-if [ -r "${WARNING_PAGE}.${LANG_CODE}.html" ]; then
- START_PAGE="${WARNING_PAGE}.${LANG_CODE}.html"
-else
- START_PAGE="${WARNING_PAGE}.en.html"
-fi
+# Import localized_tails_doc_page().
+. /usr/local/lib/tails-shell-library/localization.sh
-if [ -e /var/lib/gdm3/tails.camouflage ]; then
- CAMOUFLAGE=yes
-fi
-
-cleanup () {
- # Break down the chroot and kill all of its processes
- local counter=0
- local ret=0
- while [ "${counter}" -le 10 ] && \
- pgrep -u ${CLEARNET_USER} 1>/dev/null 2>&1; do
- pkill -u ${CLEARNET_USER} 1>/dev/null 2>&1
- ret=${?}
- sleep 1
- counter=$((${counter}+1))
- done
- [ ${ret} -eq 0 ] || pkill -9 -u ${CLEARNET_USER} 1>/dev/null 2>&1
- for mnt in ${CHROOT}/dev ${CHROOT}/proc ${CHROOT} ${COW}; do
- counter=0
- while [ "${counter}" -le 10 ] && mountpoint -q ${mnt} 2>/dev/null; do
- umount ${mnt} 2>/dev/null
- sleep 1
- counter=$((${counter}+1))
- done
- done
- rmdir ${COW} ${CHROOT} 2>/dev/null
-}
+# Import try_cleanup_browser_chroot(), setup_browser_chroot(),
+# configure_chroot_dns_servers(), configure_chroot_browser(),
+# configure_chroot_browser(), set_chroot_browser_locale()
+# set_chroot_browser_name(), set_chroot_browser_permissions()
+# and run_browser_in_chroot().
+. /usr/local/lib/tails-shell-library/chroot-browser.sh
error () {
local cli_text="${CMD}: `gettext \"error:\"` ${@}"
@@ -63,7 +24,7 @@ error () {
${@}"
echo "${cli_text}" >&2
- sudo -u ${SUDO_USER} zenity --error --title "" --text "${dialog_text}"
+ sudo -u "${SUDO_USER}" zenity --error --title "" --text "${dialog_text}"
exit 1
}
@@ -76,7 +37,7 @@ verify_start () {
local exit="`gettext \"_Exit\"`"
# Since zenity can't set the default button to cancel, we switch the
# labels and interpret the return value as its negation.
- if sudo -u ${SUDO_USER} zenity --question --title "" --ok-label "${exit}" \
+ if sudo -u "${SUDO_USER}" zenity --question --title "" --ok-label "${exit}" \
--cancel-label "${launch}" --text "${dialog_msg}"; then
exit 0
fi
@@ -88,165 +49,6 @@ show_start_notification () {
tails-notify-user "${title}" "${body}" 10000
}
-setup_chroot () {
- # Setup a chroot on an aufs "fork" of the filesystem.
- # FIXME: When LXC matures to the point where it becomes a viable option
- # for creating isolated jails, the chroot can be used as its rootfs.
- echo "* Setting up chroot"
-
- trap cleanup INT
- trap cleanup EXIT
-
- local rootfs_dir
- local rootfs_dirs_path=/lib/live/mount/rootfs
- local tails_module_path=/lib/live/mount/medium/live/Tails.module
- local aufs_dirs=
-
- # We have to pay attention to the order we stack the filesystems;
- # newest must be first, and remember that the .module file lists
- # oldest first, newest last.
- while read rootfs_dir; do
- rootfs_dir="${rootfs_dirs_path}/${rootfs_dir}"
- mountpoint -q "${rootfs_dir}" && \
- aufs_dirs="${rootfs_dir}=rr+wh:${aufs_dirs}"
- done < "${tails_module_path}"
- # But our copy-on-write dir must be at the very top.
- aufs_dirs="${COW}=rw:${aufs_dirs}"
-
- mkdir -p ${COW} ${CHROOT} && \
- mount -t tmpfs tmpfs ${COW} && \
- mount -t aufs -o "noatime,noxino,dirs=${aufs_dirs}" aufs ${CHROOT} && \
- mount -t proc proc ${CHROOT}/proc && \
- mount --bind /dev ${CHROOT}/dev || \
- error "`gettext \"Failed to setup chroot.\"`"
-
- # Workaround for todo/buggy_aufs_vs_unsafe-browser
- chmod -t ${COW}
-}
-
-set_chroot_browser_name () {
- NAME="${1}"
- LOCALE="${2}"
- EXT_DIR=${CHROOT}/"${TBB_EXT}"
- BRANDING=branding/brand.dtd
- if [ "${LOCALE}" != en-US ]; then
- PACK="${EXT_DIR}/langpack-${LOCALE}@firefox.mozilla.org.xpi"
- TOP=browser/chrome
- REST=${LOCALE}/locale
- else
- PACK="${CHROOT}/${TBB_INSTALL}/browser/omni.ja"
- TOP=chrome
- REST=en-US/locale
- fi
- TMP=$(mktemp -d)
- # Non-zero exit code due to non-standard ZIP archive.
- # The following steps will fail soon if the extraction failed anyway.
- unzip -d "${TMP}" "${PACK}" || true
- sed -i "s/<"'!'"ENTITY\s\+brand\(Full\|Short\)Name.*$/<"'!'"ENTITY brand\1Name \"${NAME}\">/" "${TMP}/${TOP}/${REST}/${BRANDING}"
- rm "${PACK}"
- (cd $TMP ; 7z a -tzip "${PACK}" .)
- chmod a+r "${PACK}"
- rm -Rf "${TMP}"
-}
-
-configure_chroot () {
- echo "* Configuring chroot"
-
- # Set the chroot's DNS servers to those obtained through DHCP
- rm -f ${CHROOT}/etc/resolv.conf
- for NS in ${IP4_NAMESERVERS}; do
- echo "nameserver ${NS}" >> ${CHROOT}/etc/resolv.conf
- done
- chmod a+r ${CHROOT}/etc/resolv.conf
-
- # Remove all addons: some adds proxying, which we don't
- # want; some may change the fingerprint compared to a standard
- # Firefox install. Note: We cannot use apt-get since we don't ship its
- # lists (#6531). Too bad, APT supports globbing, while dkpg does not.
- dpkg -l 'xul-ext-*' | /bin/grep '^ii' | awk '{print $2}' | \
- xargs chroot ${CHROOT} dpkg --remove
-
- # Create a fresh browser profile for the clearnet user
- CLEARNET_PROFILE="${CHROOT}"/home/clearnet/.tor-browser/profile.default
-
- CLEARNET_EXT="${CLEARNET_PROFILE}"/extensions
- mkdir -p "${CLEARNET_EXT}"
- cp -Pr "${TBB_PROFILE}"/extensions/langpack-*.xpi "${CLEARNET_EXT}"
-
- CLEARNET_PREFS="${CLEARNET_PROFILE}"/preferences/prefs.js
- mkdir -p "$(dirname "${CLEARNET_PREFS}")"
-
- # Localization
- BEST_LOCALE="$(guess_best_tor_browser_locale)"
- configure_xulrunner_app_locale "${CLEARNET_PROFILE}" "${BEST_LOCALE}"
-
- # Disable proxying in the chroot
- echo 'pref("network.proxy.type", 0);' >> "${CLEARNET_PREFS}"
- echo 'pref("network.proxy.socks_remote_dns", false);' >> "${CLEARNET_PREFS}"
-
- # Prevent File -> Print or CTRL+P from causing the browser to hang
- # for several minutes while trying to communicate with CUPS, since
- # access to port 631 isn't allowed through.
- echo 'pref("print.postscript.cups.enabled", false);' >> "${CLEARNET_PREFS}"
- # Hide "Get Addons" in Add-ons manager
- echo 'user_pref("extensions.getAddons.showPane", false);' >> "${CLEARNET_PREFS}"
-
- # Set the name (e.g. window title) of the browser
- set_chroot_browser_name "`gettext \"Unsafe Browser\"`" "${BEST_LOCALE}"
-
- # Set start page to something that explains what's going on
- echo 'user_pref("browser.startup.homepage", "'${START_PAGE}'");' >> \
- "${CLEARNET_PREFS}"
- BROWSER_CHROME="${CLEARNET_PROFILE}/chrome/userChrome.css"
- mkdir -p "$(dirname "${BROWSER_CHROME}")"
- cat > ${BROWSER_CHROME} << EOF
-/* Required, do not remove */
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-/* Hide TorBrowser Health Report and its configuration option */
-#appmenu_healthReport,
-#dataChoicesTab,
-#healthReport
-
-{display: none !important}
-EOF
-
- # Remove all bookmarks
- rm -f ${CHROOT}/"${TBB_PROFILE}"/bookmarks.html
- rm -f ${CLEARNET_PROFILE}/bookmarks.html
- rm -f ${CLEARNET_PROFILE}/places.sqlite
-
- chown -R clearnet:clearnet ${CHROOT}/home/clearnet/.tor-browser
-
- # Set a scary theme (except if we're using Windows
- # camouflage). Note that the tails-activate-win8-theme script that
- # we may run below requires that the browser profile is writable
- # by the user running the script (i.e. clearnet).
- if [ -z "${CAMOUFLAGE}" ]; then
- cat >> "${CLEARNET_PREFS}" <<EOF
-pref("lightweightThemes.isThemeSelected", true);
-pref("lightweightThemes.usedThemes", "[{\"id\":\"1\",\"name\":\"Unsafe Browser\",\"headerURL\":\"file:///usr/share/pixmaps/red_dot.png\",\"footerURL\":\"file:///usr/share/pixmaps/red_dot.png\",\"textcolor\":\"#FFFFFF\",\"accentcolor\":\"#CC0000\",\"updateDate\":0,\"installDate\":0}]");
-EOF
- else
- # The camouflage activation script requires a dbus server for
- # properly configuring GNOME, so we start one in the chroot
- chroot ${CHROOT} sudo -H -u clearnet sh -c 'eval `dbus-launch --auto-syntax`; tails-activate-win8-theme' || :
- fi
-
-}
-
-run_browser_in_chroot () {
- # Start the browser in the chroot
- echo "* Starting Unsafe Browser"
-
- sudo -u ${SUDO_USER} xhost +SI:localuser:${CLEARNET_USER} 2>/dev/null
- chroot ${CHROOT} sudo -u ${CLEARNET_USER} /bin/sh -c \
- '. /usr/local/lib/tails-shell-library/tor-browser.sh && \
- exec_firefox -DISPLAY=:0.0 \
- -profile /home/clearnet/.tor-browser/profile.default'
- sudo -u ${SUDO_USER} xhost -SI:localuser:${CLEARNET_USER} 2>/dev/null
-}
-
show_shutdown_notification () {
local title="`gettext \"Shutting down the Unsafe Browser...\"`"
local body="`gettext \"This may take a while, and you may not restart the Unsafe Browser until it is properly shut down.\"`"
@@ -260,22 +62,50 @@ maybe_restart_tor () {
if ! tor_is_working; then
echo "* Restarting Tor"
restart-tor
- if ! service tor status >/dev/null; then
+ if ! service tor status; then
error "`gettext \"Failed to restart Tor.\"`"
fi
fi
}
+# Main script:
+
+CMD="$(basename "${0}")"
+LOCK="/var/lock/${CMD}"
+
+. gettext.sh
+TEXTDOMAIN="tails"
+export TEXTDOMAIN
+
+CONF_DIR="/var/lib/unsafe-browser"
+COW="${CONF_DIR}/cow"
+CHROOT="${CONF_DIR}/chroot"
+BROWSER_NAME="unsafe-browser"
+BROWSER_USER="clearnet"
+HUMAN_READABLE_NAME="`gettext \"Unsafe Browser\"`"
+NM_ENV_FILE="/var/lib/NetworkManager/env"
+WARNING_PAGE='/usr/share/doc/tails/website/misc/unsafe_browser_warning'
+HOME_PAGE="$(localized_tails_doc_page "${WARNING_PAGE}")"
+
# Prevent multiple instances of the script.
-exec 9>${LOCK}
+exec 9>"${LOCK}"
if ! flock -x -n 9; then
error "`gettext \"Another Unsafe Browser is currently running, or being cleaned up. Please retry in a while.\"`"
fi
# Get the DNS servers that was obtained from NetworkManager, if any...
-NM_ENV=/var/lib/NetworkManager/env
-if [ -r "${NM_ENV}" ]; then
- . ${NM_ENV}
+if [ -r "${NM_ENV_FILE}" ]; then
+ # We also check that the file we are gonna *source* doesn't
+ # contain any unexpected data, like (potentially malicious) shell
+ # script. Note that while the regex used for deciding IP addresses
+ # is far from perfect, it serves our purpose here.
+ IP4_REGEX='[0-9]{1,3}(\.[0-9]{1,3}){3}'
+ NAMESERVERS_REGEX="^IP4_NAMESERVERS=\"(${IP4_REGEX}( ${IP4_REGEX})*)?\"$"
+ if grep --extended-regexp -qv "${NAMESERVERS_REGEX}" "${NM_ENV_FILE}"; then
+ error "`gettext \"NetworkManager passed us garbage data when trying to deduce the clearnet DNS server.\"`"
+ fi
+ # Import the IP4_NAMESERVERS variable.
+ eval "$(grep --extended-regexp "${NAMESERVERS_REGEX}" "${NM_ENV_FILE}")"
fi
# ... otherwise fail.
# FIXME: Or would it make sense to fallback to Google's DNS or OpenDNS?
@@ -287,9 +117,23 @@ fi
verify_start
show_start_notification
-setup_chroot
-configure_chroot
-run_browser_in_chroot
+
+echo "* Setting up chroot"
+setup_chroot_for_browser "${CHROOT}" "${COW}" "${BROWSER_USER}" || \
+ error "`gettext \"Failed to setup chroot.\"`"
+
+echo "* Configuring chroot"
+configure_chroot_browser "${CHROOT}" "${BROWSER_USER}" "${BROWSER_NAME}" \
+ "${HUMAN_READABLE_NAME}" "${HOME_PAGE}" "${IP4_NAMESERVERS}" \
+ "${TBB_EXT}"/langpack-*.xpi || \
+ error "`gettext \"Failed to configure browser.\"`"
+
+echo "* Starting Unsafe Browser"
+run_browser_in_chroot "${CHROOT}" "${BROWSER_NAME}" "${BROWSER_USER}" \
+ "${SUDO_USER}" || \
+ error "`gettext \"Failed to run browser.\"`"
+
+echo "* Exiting the Unsafe Browser"
show_shutdown_notification
maybe_restart_tor