unsafe-browser 4.57 KB
Newer Older
1
#!/bin/sh
2 3 4

SQUASH=/live/image/live/filesystem.squashfs
ROFS=/live/rofs
5 6 7
CONF_DIR=/var/lib/unsafe-browser
COW=${CONF_DIR}/cow
CHROOT=${CONF_DIR}/chroot
8 9 10 11 12 13 14
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 () {
15 16 17
    # Break down the chroot and kill all of its processes
    local counter=0
    local ret=0
18 19 20
    while [ "${counter}" -le 10 ] && \
          pgrep -u ${CLEARNET_USER} 1>/dev/null 2>&1; do
        pkill -u ${CLEARNET_USER} 1>/dev/null 2>&1
21
        ret=${?}
22
        sleep 1
23
        counter=$((${counter}+1))
24
    done
25 26
    [ ${ret} -eq 0 ] || pkill -9 -u ${CLEARNET_USER} 1>/dev/null 2>&1
    for mnt in ${CHROOT}/dev ${CHROOT}/proc ${CHROOT} ${COW} ${ROFS}; do
27
        counter=0
28 29
        while [ "${counter}" -le 10 ] && mountpoint -q ${mnt} 2>/dev/null; do
            umount ${mnt} 2>/dev/null
30
            sleep 1
31
            counter=$((${counter}+1))
32 33
        done
    done
34
    rmdir ${ROFS} ${COW} ${CHROOT} 2>/dev/null
35 36 37
}

error () {
38
    local cli_text="${0}: error: ${@}"
Tails developers's avatar
Tails developers committed
39
    local dialog_text="${@}
40 41

Unsafe Browser will exit now."
42 43
    echo "${cli_text}" >&2
    zenity --error --title "" --text "${dialog_text}"
44 45 46 47
    exit 1
}

warning () {
48 49 50
    local text="${@}"
    echo "${0}: warning: ${text}" >&2
    zenity --warning --title "" --text "${text}"
51 52
}

53 54 55
verify_start () {
    # Make sure the user really wants to start the browser
    local dialog_msg="<b>Do you really want to launch the Unsafe Browser?</b>
56

57
All activity within the Unsafe Browser will <b>not</b> 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."
58 59 60 61
    if ! zenity --question --title "" --text "${dialog_msg}"; then
        exit 0
    fi
}
62

63 64 65 66
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.
67 68 69
    trap cleanup INT
    trap cleanup EXIT

70 71 72 73 74 75 76 77 78 79 80
    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 "Failed to setup chroot"
}

configure_chroot () {
    # Set the chroot's DNS servers to those obtained through DHCP
    rm -f ${CHROOT}/etc/resolv.conf
81
    for NS in ${IP4_NAMESERVERS}; do
82 83 84 85 86
        echo "nameserver ${NS}" >> ${CHROOT}/etc/resolv.conf
    done
    chmod a+r ${CHROOT}/etc/resolv.conf

    # Disable problematic Iceweasel addons and proxying in the chroot
87
    chroot ${CHROOT} apt-get remove --yes ${OFFENDING_ADDONS} 1>/dev/null 2>&1
88 89 90 91 92 93 94 95
    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
}

start_browser_in_chroot () {
    # Start Iceweasel in the chroot
96
    sudo -u ${SUDO_USER} xhost +SI:localuser:${CLEARNET_USER} 2>/dev/null
97
    chroot ${CHROOT} sudo -u ${CLEARNET_USER} iceweasel -DISPLAY=:0.0
98
    sudo -u ${SUDO_USER} xhost -SI:localuser:${CLEARNET_USER} 2>/dev/null
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
}

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
114 115 116
        service tor restart 2>/dev/null
        until nc -z localhost 9051 2>/dev/null; do sleep 1; done
        /etc/NetworkManager/dispatcher.d/60-vidalia.sh clearnet up 2>/dev/null
117 118
    fi
}
119

120
# Get the DNS servers that was obtained from NetworkManager, if any...
121 122 123 124 125 126 127 128
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.
129 130
if [ -z "${IP4_NAMESERVERS}" ]; then
    error "No DNS server was obtained through DHCP or manually configured in NetworkManager."
131 132
fi

133 134 135 136 137
verify_start
setup_chroot
configure_chroot
start_browser_in_chroot
maybe_restart_tor
138 139

exit 0