summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfig/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh53
-rwxr-xr-xconfig/chroot_local-includes/etc/NetworkManager/dispatcher.d/20-time.sh17
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/restart-tor55
-rw-r--r--features/step_definitions/common_steps.rb2
4 files changed, 87 insertions, 40 deletions
diff --git a/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh b/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh
index f1c134c..d1037cd 100755
--- a/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh
+++ b/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh
@@ -5,12 +5,12 @@
# Run only when the interface is not "lo":
if [ $1 = "lo" ]; then
- exit 0
+ exit 0
fi
# Run whenever an interface gets "up", not otherwise:
if [ $2 != "up" ]; then
- exit 0
+ exit 0
fi
# Import tor_control_setconf(), TOR_LOG
@@ -35,26 +35,41 @@ rm -f "${TOR_LOG}"
# a HTTP proxy or allowed firewall ports won't get the sandboxing, but
# much better than nothing.
if [ "$(tails_netconf)" = "direct" ]; then
- tor_set_in_torrc Sandbox 1
+ tor_set_in_torrc Sandbox 1
fi
-# A SIGHUP should be enough but there's a bug in Tor. Details:
+# We would like Tor to be started during init time, even before the
+# network is up, and then send it a SIGHUP here to make it start
+# bootstrapping swiftly, but it doesn't work because of a bug in
+# Tor. Details:
# * https://trac.torproject.org/projects/tor/ticket/1247
# * https://tails.boum.org/bugs/tor_vs_networkmanager/
-restart-tor
-
+# To work around this we restart Tor, in various ways, not matter the
+# case below.
if [ "$(tails_netconf)" = "obstacle" ]; then
- # When using a bridge Tor reports TLS cert lifetime errors
- # (e.g. when the system clock is way off) with severity "info", but
- # when no bridge is used the severity is "warn". tordate/20-time.sh
- # depends on grepping these error messages, so we temporarily
- # increase Tor's logging severity.
- tor_control_setconf "Log=\"info file ${TOR_LOG}\""
-
- # Enable the transports we support. We cannot do this in general,
- # when bridge mode is not enabled, since we then use seccomp
- # sandboxing.
- tor_control_setconf 'ClientTransportPlugin="obfs2,obfs3,obfs4 exec /usr/bin/obfs4proxy managed"'
-
- /usr/local/sbin/tails-tor-launcher &
+ # We do not use retart-tor since it validates that bootstraping
+ # succeeds. That cannot happen until Tor Launcher has started
+ # (below) and the user is done configuring it.
+ service tor restart
+
+ # When using a bridge Tor reports TLS cert lifetime errors
+ # (e.g. when the system clock is way off) with severity "info", but
+ # when no bridge is used the severity is "warn". tordate/20-time.sh
+ # depends on grepping these error messages, so we temporarily
+ # increase Tor's logging severity.
+ tor_control_setconf "Log=\"info file ${TOR_LOG}\""
+
+ # Enable the transports we support. We cannot do this in general,
+ # when bridge mode is not enabled, since we then use seccomp
+ # sandboxing.
+ tor_control_setconf 'ClientTransportPlugin="obfs2,obfs3,obfs4 exec /usr/bin/obfs4proxy managed"'
+
+ /usr/local/sbin/tails-tor-launcher &
+
+ # Wait until the user has done the Tor Launcher configuration.
+ until [ "$(tor_control_getconf DisableNetwork)" = 0 ]; do
+ sleep 1
+ done
+else
+ ( restart-tor ) &
fi
diff --git a/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/20-time.sh b/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/20-time.sh
index 368e70d..4058f2a 100755
--- a/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/20-time.sh
+++ b/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/20-time.sh
@@ -70,7 +70,7 @@ has_only_unverified_consensus() {
wait_for_tor_consensus_helper() {
tries=0
- while ! has_consensus && [ $tries -lt 5 ]; do
+ while ! has_consensus && [ $tries -lt 10 ]; do
inotifywait -q -t 30 -e close_write -e moved_to ${TOR_DIR} || log "timeout"
tries=$(expr $tries + 1)
done
@@ -82,10 +82,6 @@ wait_for_tor_consensus_helper() {
wait_for_tor_consensus() {
log "Waiting for a Tor consensus file to contain a valid time interval"
if ! has_consensus && ! wait_for_tor_consensus_helper; then
- log "Unsuccessfully waited for Tor consensus, restarting Tor and retrying."
- restart-tor
- fi
- if ! has_consensus && ! wait_for_tor_consensus_helper; then
log "Unsuccessfully retried waiting for Tor consensus, aborting."
fi
if has_consensus; then
@@ -175,7 +171,7 @@ maybe_set_time_from_tor_consensus() {
date -us "${vmid}" 1>/dev/null
# Tor is unreliable with picking a circuit after time change
- restart-tor
+ service tor restart
}
tor_cert_valid_after() {
@@ -219,15 +215,6 @@ start_notification_helper() {
### Main
-# When the network is obstacled (e.g. we need a bridge) we wait until
-# Tor Launcher has unset DisableNetwork, since Tor's bootstrapping
-# won't start until then.
-if [ "$(tails_netconf)" = "obstacle" ]; then
- until [ "$(tor_control_getconf DisableNetwork)" = 0 ]; do
- sleep 1
- done
-fi
-
start_notification_helper
# Delegate time setting to other daemons if Tor connections work
diff --git a/config/chroot_local-includes/usr/local/sbin/restart-tor b/config/chroot_local-includes/usr/local/sbin/restart-tor
index 8950638..51b494e 100755
--- a/config/chroot_local-includes/usr/local/sbin/restart-tor
+++ b/config/chroot_local-includes/usr/local/sbin/restart-tor
@@ -2,13 +2,58 @@
set -e
+# Import try_for()
+. /usr/local/lib/tails-shell-library/common.sh
+
+# Import tor_bootstrap_progress()
+. /usr/local/lib/tails-shell-library/tor.sh
+
+# Import log()
+. /usr/local/lib/tails-shell-library/log.sh
+_LOG_TAG="$(basename $0)"
+
+# The Tor log is removed to ensure `tor_bootstrap_progress`'s output will be
+# accurate.
+clear_tor_log() {
+ rm -f /var/log/tor/log
+}
+
+clear_tor_log
service tor restart
-# The main point of this script is to make sure that if vidalia is
-# running, and Tor is restarted, then we also restart Vidalia. This is
-# because Vidalia doesn't re-connect to Tor automatically, so the user
-# has to restart it to be able to control Tor again. Also, any options
-# set by Vidalia will be lost since they weren't written to torrc.
+# There are two main points to this script:
+# * restarting Tor if bootstrapping stalls for more than 20 seconds
+# * making sure that if vidalia is running it is restarted if Tor is restarted.
+# This is needed because Vidalia doesn't re-connect to Tor automatically,
+# so the user has to restart it to be able to control Tor again. Also, any
+# options set by Vidalia will be lost since they weren't written to torrc.
+
+bootstrap_progress=0
+last_bootstrap_change=$(date +%s)
+
+maybe_restart_tor() {
+ local new_bootstrap_progress=$(tor_bootstrap_progress)
+ if [ $new_bootstrap_progress -eq 100 ]; then
+ log "Tor has successfully bootstrapped."
+ return 0
+ elif [ $new_bootstrap_progress -gt $bootstrap_progress ]; then
+ bootstrap_progress=$new_bootstrap_progress
+ last_bootstrap_change=$(date +%s)
+ return 1
+ elif [ $(expr $(date +%s) - $last_bootstrap_change) -ge 20 ]; then
+ log "Tor seems to have stalled while bootstrapping. Restarting Tor."
+ clear_tor_log
+ service tor restart
+ bootstrap_progress=0
+ last_bootstrap_change=$(date +%s)
+ return 1
+ else
+ return 1
+ fi
+}
+
+try_for 270 maybe_restart_tor
+
if pgrep "\<vidalia\>" >/dev/null; then
killall -SIGKILL vidalia
# Since Tor just restarted we wait for a while until the
diff --git a/features/step_definitions/common_steps.rb b/features/step_definitions/common_steps.rb
index 346839b..0b95714 100644
--- a/features/step_definitions/common_steps.rb
+++ b/features/step_definitions/common_steps.rb
@@ -65,7 +65,7 @@ def restore_background
@vm.execute("rm -f /var/log/tor/log")
@vm.execute("killall vidalia")
@vm.host_to_guest_time_sync
- @vm.execute("service tor start")
+ @vm.execute("restart-tor")
wait_until_tor_is_working
@vm.spawn("restart-vidalia")
end