#!/bin/sh
CMD=$(basename ${0})
. gettext.sh
TEXTDOMAIN=${CMD}
export TEXTDOMAIN
SQUASH=/live/image/live/filesystem.squashfs
ROFS=/live/rofs
CONF_DIR=/var/lib/unsafe-browser
COW=${CONF_DIR}/cow
CHROOT=${CONF_DIR}/chroot
CLEARNET_USER=clearnet
OFFENDING_ADDONS="xul-ext-foxyproxy-standard xul-ext-torbutton"
TOR_DIR=/var/lib/tor
TOR_DESCRIPTORS=${TOR_DIR}/cached-descriptors
TOR_WORKING=""
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} ${ROFS}; 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 ${ROFS} ${COW} ${CHROOT} 2>/dev/null
}
error () {
local cli_text="${CMD}: `gettext \"error\"`: ${@}"
local dialog_text="${@}
`gettext \"Unsafe Browser will exit now.\"`"
echo "${cli_text}" >&2
zenity --error --title "" --text "${dialog_text}"
exit 1
}
warning () {
local text="${@}"
echo "${CMD}: `gettext \"warning\"`: ${text}" >&2
zenity --warning --title "" --text "${text}"
}
verify_start () {
# Make sure the user really wants to start the browser
local dialog_msg="`gettext \"Do you really want to launch the Unsafe Browser?\"`
`gettext \"All activity within the Unsafe Browser will not be anonymous. Only use the the Unsafe Browser if necessary, for example if you have to login or register in order to activate your Internet connection.\"`"
if ! zenity --question --title "" --text "${dialog_msg}"; then
exit 0
fi
}
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.
trap cleanup INT
trap cleanup EXIT
mkdir -p ${ROFS} ${COW} ${CHROOT} && \
mount -t squashfs -o loop ${SQUASH} ${ROFS} && \
mount -t tmpfs tmpfs ${COW} && \
mount -t aufs -o noatime,noxino,dirs=${COW}=rw:${ROFS}=rr+wh aufs ${CHROOT} && \
mount -t proc proc ${CHROOT}/proc && \
mount --bind /dev ${CHROOT}/dev || \
error "`gettext \"Failed to setup chroot.\"`"
}
configure_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
# Disable problematic Iceweasel addons and proxying in the chroot
chroot ${CHROOT} apt-get remove --yes ${OFFENDING_ADDONS} 1>/dev/null 2>&1
sed -i '/^pref("network.proxy.type",/d' \
${CHROOT}/etc/iceweasel/pref/iceweasel.js
echo 'pref("network.proxy.type", 0);' >> \
${CHROOT}/etc/iceweasel/pref/iceweasel.js
# Set a scary theme (except if we're using Windows camouflage
if grep -qwv winxp /proc/cmdline; then
echo '
user_pref("lightweightThemes.isThemeSelected", true);
user_pref("lightweightThemes.persisted.footerURL", false);
user_pref("lightweightThemes.persisted.headerURL", false);
user_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\":\"#FFFF00\",\"accentcolor\":\"#CC0000\",\"updateDate\":0,\"installDate\":0}]");' >> ${CHROOT}/etc/iceweasel/profile/user.js
fi
}
start_browser_in_chroot () {
# Start Iceweasel in the chroot
sudo -u ${SUDO_USER} xhost +SI:localuser:${CLEARNET_USER} 2>/dev/null
chroot ${CHROOT} sudo -u ${CLEARNET_USER} iceweasel -DISPLAY=:0.0
sudo -u ${SUDO_USER} xhost -SI:localuser:${CLEARNET_USER} 2>/dev/null
}
tor_is_working() {
# FIXME: the approach is stolen from is_tor_working() in the 20-time
# NM hook -- we should move things like this to a shell script library
# FIXME: how to determine this reliably? this approach doesn't work
# if $TOR_DIR is persistent.
[ -e $TOR_DESCRIPTORS ]
}
maybe_restart_tor () {
# Restart Tor if it's not working (a captive portal may have prevented
# Tor from bootstrapping, and a restart is the fastest way to get
# wheels turning)
if ! tor_is_working; then
if ! service tor restart 2>/dev/null; then
error "`gettext \"Failed to restart Tor.\"`"
fi
local counter=0
until [ "${counter}" -ge 10 ] || nc -z localhost 9051 2>/dev/null; do
sleep 1
counter=$((${counter}+1))
done
/etc/NetworkManager/dispatcher.d/60-vidalia.sh clearnet up 2>/dev/null
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}
fi
# ... 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
error "`gettext \"No DNS server was obtained through DHCP or manually configured in NetworkManager.\"`"
fi
verify_start
setup_chroot
configure_chroot
start_browser_in_chroot
maybe_restart_tor
exit 0