summaryrefslogtreecommitdiffstats
path: root/config/chroot_local-includes/usr/local/sbin/unsafe-browser
blob: 81211f278447200fb09c131cb131bd7b2eaa6f10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/bin/sh

set -e
set -u

. gettext.sh
TEXTDOMAIN="tails"
export TEXTDOMAIN

# Import tor_is_working()
. /usr/local/lib/tails-shell-library/tor.sh

# Import the TBB_EXT variable, and guess_best_tor_browser_locale().
. /usr/local/lib/tails-shell-library/tor-browser.sh

# Import localized_tails_doc_page().
. /usr/local/lib/tails-shell-library/localization.sh

# Import try_cleanup_browser_chroot(), setup_browser_chroot(),
# configure_chroot_dns_servers(), configure_chroot_browser(),
# configure_chroot_browser(), set_chroot_browser_locale()
# set_chroot_browser_name(), set_chroot_browser_permissions()
# and run_browser_in_chroot().
. /usr/local/lib/tails-shell-library/chroot-browser.sh

error () {
    local cli_text="${CMD}: `gettext \"error:\"` ${@}"
    local dialog_text="<b><big>`gettext \"Error\"`</big></b>

${@}"
    echo "${cli_text}" >&2
    sudo -u "${SUDO_USER}" zenity --error --title "" --text "${dialog_text}"
    exit 1
}

verify_start () {
    # Make sure the user really wants to start the browser
    local dialog_msg="<b><big>`gettext \"Do you really want to launch the Unsafe Browser?\"`</big></b>

`gettext \"Network activity within the Unsafe Browser is <b>not anonymous</b>.\\nOnly use the Unsafe Browser if necessary, for example\\nif you have to login or register to activate your Internet connection.\"`"
    local launch="`gettext \"_Launch\"`"
    local exit="`gettext \"_Exit\"`"
    if ! sudo -u "${SUDO_USER}" \
         zenity --question --title "" --text "${dialog_msg}" --default-cancel \
         --ok-label "${launch}"  --cancel-label "${exit}"; then
        exit 0
    fi
}

show_start_notification () {
    local title="`gettext \"Starting the Unsafe Browser...\"`"
    local body="`gettext \"This may take a while, so please be patient.\"`"
    tails-notify-user "${title}" "${body}" 10000
}

show_shutdown_notification () {
    local title="`gettext \"Shutting down the Unsafe Browser...\"`"
    local body="`gettext \"This may take a while, and you may not restart the Unsafe Browser until it is properly shut down.\"`"
    tails-notify-user "${title}" "${body}" 10000
}

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
        echo "* Restarting Tor"
        restart-tor
        if ! systemctl --quiet is-active tor@default.service; then
            error "`gettext \"Failed to restart Tor.\"`"
        fi
    fi
}

# Main script:

CMD="$(basename "${0}")"
LOCK="/var/lock/${CMD}"
CONF_DIR="/var/lib/unsafe-browser"
COW="${CONF_DIR}/cow"
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}")"

# Prevent multiple instances of the script.
exec 9>"${LOCK}"
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.\"`"
    fi
    # Import the IP4_NAMESERVERS variable.
    eval "$(grep --extended-regexp "${NAMESERVERS_REGEX}" "${NM_ENV_FILE}")"
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
show_start_notification

echo "* Setting up chroot"
setup_chroot_for_browser "${CHROOT}" "${COW}" "${BROWSER_USER}" || \
    error "`gettext \"Failed to setup chroot.\"`"

echo "* Configuring chroot"
configure_chroot_browser "${CHROOT}" "${BROWSER_USER}" "${BROWSER_NAME}" \
    "${HUMAN_READABLE_NAME}" "${HOME_PAGE}" "${IP4_NAMESERVERS}" \
    "${TBB_EXT}"/langpack-*.xpi || \
        error "`gettext \"Failed to configure browser.\"`"

echo "* Starting Unsafe Browser"
run_browser_in_chroot "${CHROOT}" "${BROWSER_NAME}" "${BROWSER_USER}" \
    "${SUDO_USER}" || \
    error "`gettext \"Failed to run browser.\"`"

echo "* Exiting the Unsafe Browser"
show_shutdown_notification
maybe_restart_tor

exit 0