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