summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoranonym <anonym@riseup.net>2015-03-26 15:39:13 +0100
committeranonym <anonym@riseup.net>2015-03-26 15:39:13 +0100
commitcc8eecaa5761bdd4bf708410b7a695c3c372dd94 (patch)
tree3707f5535a2125c580b45b3a4ad0a083453828d4
parent1910babb646a6603c63e67513fa9650421055219 (diff)
PoC for per network persistent entry guards.
This of course depends on making Tor's data dir persistent (#5462). For testing purposes of this PoC we'll have to manually enable that by editing the persistence configuration file. Expect trouble with time syncing if testing this.
-rwxr-xr-xconfig/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-save-env22
-rwxr-xr-xconfig/chroot_local-includes/etc/NetworkManager/dispatcher.d/10-tor.sh39
-rwxr-xr-xconfig/chroot_local-includes/usr/local/lib/tails-shell-library/tor.sh1
-rwxr-xr-xconfig/chroot_local-includes/usr/local/sbin/unsafe-browser38
4 files changed, 72 insertions, 28 deletions
diff --git a/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-save-env b/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-save-env
index 268bcdb..fb6e131 100755
--- a/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-save-env
+++ b/config/chroot_local-includes/etc/NetworkManager/dispatcher.d/00-save-env
@@ -1,9 +1,9 @@
#!/bin/sh
-# This information is needed by the Unsafe Browser.
+DEVICE="${1}"
# Run only when the interface is not "lo":
-if [ $1 = "lo" ]; then
+if [ "${DEVICE}" = "lo" ]; then
exit 0
fi
@@ -12,4 +12,20 @@ if [ $2 != "up" ]; then
exit 0
fi
-echo "IP4_NAMESERVERS=\"${IP4_NAMESERVERS}\"" > /var/lib/NetworkManager/env
+ENV_FILE="var/lib/NetworkManager/env.${DEVICE} "
+rm -f "${ENV_FILE}"
+
+# The DNS servers are needed by the Unsafe Browser.
+echo "IP4_NAMESERVERS=\"${IP4_NAMESERVERS}\"" >> "${ENV_FILE}"
+
+# The MAC address of the gateway (if any) is needed by 10-tor.sh when
+# down, since IP4_ADDRESS_* isn't set by NetworkManager on down.
+GATEWAY_IP4ADDR="$(echo ${IP4_ADDRESS_0} | cut -d' ' -f2)"
+if [ "${GATEWAY_IP4ADDR}" != "0.0.0.0" ]; then
+ GATEWAY_MACADDR="$(arping -f -I "${DEVICE}" "${GATEWAY_IP4ADDR}" | \
+ sed --regexp-extended -n \
+ "s,^Unicast reply from \S+ \[([^]]+)\].*$,\1,p")"
+else
+ GATEWAY_MACADDR=""
+fi
+echo "GATEWAY_MACADDR=\"${GATEWAY_MACADDR}\"" >> "${ENV_FILE}"
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 c8fede2..1cf6d1d 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
@@ -1,31 +1,52 @@
#!/bin/sh
+DEVICE="${1}"
+STATE="${2}"
+
# We don't start Tor automatically so *this* is the time
# when it is supposed to start.
# Run only when the interface is not "lo":
-if [ $1 = "lo" ]; then
- exit 0
-fi
-
-# Run whenever an interface gets "up", not otherwise:
-if [ $2 != "up" ]; then
+if [ "${DEVICE}" = "lo" ]; then
exit 0
fi
-# Import tor_control_setconf(), TOR_LOG
+# Import tor_control_setconf(), TOR_LOG, TOR_DIR, TOR_STATE_FILE
. /usr/local/lib/tails-shell-library/tor.sh
-# Import tails_netconf()
+# Import tails_netconf(), persistence_is_enabled_for()
. /usr/local/lib/tails-shell-library/tails-greeter.sh
# It's safest that Tor is not running when messing with its logs.
-service tor stop
+if service tor status; then
+ service tor stop
+fi
# We depend on grepping stuff from the Tor log (especially for
# tordate/20-time.sh), so deleting it seems like a Good Thing(TM).
rm -f "${TOR_LOG}"
+# Now we'll deal with persistent Tor entry guards, restoring them (if
+# any) on 'up' and saving them (if any) on 'down'. We save/restore
+# them per network, identified by the MAC address of the gateway. If
+# no gateway is used, then we use random entry guards.
+if persistence_is_enabled_for "${TOR_DIR}"; then
+ # Import GATEWAY_MACADDR that was set by 00-save-end.sh.
+ . "/var/lib/NetworkManager/env.${DEVICE}"
+ SAVED_TOR_STATE_FILE="${TOR_STATE_FILE}.${GATEWAY_MACADDR}"
+ if [ "${STATE}" = up ]; then
+ rm -f "${TOR_STATE_FILE}"
+ if [ -n "${GATEWAY_MACADDR}" ] && [ -e "${SAVED_TOR_STATE_FILE}" ]; then
+ cp -f "${SAVED_TOR_STATE_FILE}" "${TOR_STATE_FILE}"
+ fi
+ elif [ "${STATE}" = down ]; then
+ if [ -n "${GATEWAY_MACADDR}" ] && [ -e "${TOR_STATE_FILE}" ]; then
+ cp -f "${TOR_STATE_FILE}" "${SAVED_TOR_STATE_FILE}"
+ fi
+ exit 0
+ fi
+fi
+
# The Tor syscall sandbox is not compatible with managed proxies.
# We could possibly detect whether the user has configured any such
# thing via Tor Launcher later (e.g. in 60-tor-ready.sh),
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 d797c50..0e48e06 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
@@ -5,6 +5,7 @@ TOR_LOG=/var/log/tor/log
TOR_DIR=/var/lib/tor
TOR_DESCRIPTORS=${TOR_DIR}/cached-microdescs
NEW_TOR_DESCRIPTORS=${TOR_DESCRIPTORS}.new
+TOR_STATE_FILE=${TOR_DIR}/state
get_tor_control_port() {
sed -n 's/^ControlPort[[:space:]]\+\([[:digit:]]\+\)/\1/p' "${TOR_RC}"
diff --git a/config/chroot_local-includes/usr/local/sbin/unsafe-browser b/config/chroot_local-includes/usr/local/sbin/unsafe-browser
index 7c6da22..7f8dae1 100755
--- a/config/chroot_local-includes/usr/local/sbin/unsafe-browser
+++ b/config/chroot_local-includes/usr/local/sbin/unsafe-browser
@@ -83,7 +83,6 @@ 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}")"
@@ -93,25 +92,32 @@ 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...
-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.\"`"
+# Get the DNS servers that was obtained from NetworkManager, if any.
+# 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})*)?\"$"
+ALL_IP4_NAMESERVERS=""
+for env_file in /var/lib/NetworkManager/env.*; do
+ if [ -r "${env_file}" ]; then
+ 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}")"
+ if [ -n "${IP4_NAMESERVERS}" ]; then
+ ALL_IP4_NAMESERVERS="${ALL_IP4_NAMESERVERS} ${IP4_NAMESERVERS}"
+ fi
+ unset IP4_NAMESERVERS
fi
- # Import the IP4_NAMESERVERS variable.
- eval "$(grep --extended-regexp "${NAMESERVERS_REGEX}" "${NM_ENV_FILE}")"
-fi
+done
# ... otherwise fail.
# FIXME: Or would it make sense to fallback to Google's DNS or OpenDNS?
# Some stupid captive portals may allow DNS to any host, but chances are
# that only the portal's DNS would forward to the login page.
-if [ -z "${IP4_NAMESERVERS}" ]; then
+if [ -z "${ALL_IP4_NAMESERVERS}" ]; then
error "`gettext \"No DNS server was obtained through DHCP or manually configured in NetworkManager.\"`"
fi
@@ -124,7 +130,7 @@ setup_chroot_for_browser "${CHROOT}" "${COW}" "${BROWSER_USER}" || \
echo "* Configuring chroot"
configure_chroot_browser "${CHROOT}" "${BROWSER_USER}" "${BROWSER_NAME}" \
- "${HUMAN_READABLE_NAME}" "${HOME_PAGE}" "${IP4_NAMESERVERS}" \
+ "${HUMAN_READABLE_NAME}" "${HOME_PAGE}" "${ALL_IP4_NAMESERVERS}" \
"${TBB_EXT}"/langpack-*.xpi || \
error "`gettext \"Failed to configure browser.\"`"