start-tor-browser 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. #!/usr/bin/env bash
  2. #
  3. # GNU/Linux does not really require something like RelativeLink.c
  4. # However, we do want to have the same look and feel with similar features.
  5. #
  6. # Copyright 2017 The Tor Project. See LICENSE for licensing information.
  7. complain_dialog_title="Tor Browser"
  8. # First, make sure DISPLAY is set. If it isn't, we're hosed; scream
  9. # at stderr and die.
  10. if [ "x$DISPLAY" = "x" ]; then
  11. echo "$complain_dialog_title must be run within the X Window System." >&2
  12. echo "Exiting." >&2
  13. exit 1
  14. fi
  15. # Second, make sure this script wasn't started as 'sh start-tor-browser' or
  16. # similar.
  17. if [ "x$BASH" = "x" ]; then
  18. echo "$complain_dialog_title should be started as './start-tor-browser'"
  19. echo "Exiting." >&2
  20. exit 1;
  21. fi
  22. # Do not (try to) connect to the session manager
  23. unset SESSION_MANAGER
  24. # Complain about an error, by any means necessary.
  25. # Usage: complain message
  26. # message must not begin with a dash.
  27. complain () {
  28. # Trim leading newlines, to avoid breaking formatting in some dialogs.
  29. complain_message="`echo "$1" | sed '/./,$!d'`"
  30. # If we're being run in debug/verbose mode, complain to stderr.
  31. if [ "$show_output" -eq 1 ]; then
  32. echo "$complain_message" >&2
  33. return
  34. fi
  35. # Otherwise, we're being run by a GUI program of some sort;
  36. # try to pop up a message in the GUI in the nicest way
  37. # possible.
  38. #
  39. # In mksh, non-existent commands return 127; I'll assume all
  40. # other shells set the same exit code if they can't run a
  41. # command. (xmessage returns 1 if the user clicks the WM
  42. # close button, so we do need to look at the exact exit code,
  43. # not just assume the command failed to display a message if
  44. # it returns non-zero.)
  45. # First, try zenity.
  46. zenity --error \
  47. --title="$complain_dialog_title" \
  48. --text="$complain_message"
  49. if [ "$?" -ne 127 ]; then
  50. return
  51. fi
  52. # Try kdialog.
  53. kdialog --title "$complain_dialog_title" \
  54. --error "$complain_message"
  55. if [ "$?" -ne 127 ]; then
  56. return
  57. fi
  58. # Try xmessage.
  59. xmessage -title "$complain_dialog_title" \
  60. -center \
  61. -buttons OK \
  62. -default OK \
  63. -xrm '*message.scrollVertical: Never' \
  64. "$complain_message"
  65. if [ "$?" -ne 127 ]; then
  66. return
  67. fi
  68. # Try gxmessage. This one isn't installed by default on
  69. # Debian with the default GNOME installation, so it seems to
  70. # be the least likely program to have available, but it might
  71. # be used by one of the 'lightweight' Gtk-based desktop
  72. # environments.
  73. gxmessage -title "$complain_dialog_title" \
  74. -center \
  75. -buttons GTK_STOCK_OK \
  76. -default OK \
  77. "$complain_message"
  78. if [ "$?" -ne 127 ]; then
  79. return
  80. fi
  81. }
  82. if [ "`id -u`" -eq 0 ]; then
  83. complain "The Tor Browser Bundle should not be run as root. Exiting."
  84. exit 1
  85. fi
  86. tbb_usage () {
  87. printf "\nTor Browser Script Options\n"
  88. printf " --verbose Display Tor and Firefox output in the terminal\n"
  89. printf " --log [file] Record Tor and Firefox output in file (default: tor-browser.log)\n"
  90. printf " --detach Detach from terminal and run Tor Browser in the background.\n"
  91. printf " --register-app Register Tor Browser as a desktop app for this user\n"
  92. printf " --unregister-app Unregister Tor Browser as a desktop app for this user\n"
  93. }
  94. log_output=0
  95. show_output=0
  96. detach=0
  97. show_usage=0
  98. register_desktop_app=0
  99. logfile=/dev/null
  100. while :
  101. do
  102. case "$1" in
  103. --detach)
  104. detach=1
  105. shift
  106. ;;
  107. -v | --verbose | -d | --debug)
  108. show_output=1
  109. verbose_arg="$2"
  110. shift
  111. ;;
  112. -h | "-?" | --help | -help)
  113. show_usage=1
  114. show_output=1
  115. shift
  116. ;;
  117. -l | --log)
  118. if [ -z "$2" -o "${2:0:1}" == "-" ]; then
  119. printf "Logging Tor Browser debug information to tor-browser.log\n"
  120. logfile="../tor-browser.log"
  121. elif [ "${2:0:1}" == "/" -o "${2:0:1}" == "~" ]; then
  122. printf "Logging Tor Browser debug information to %s\n" "$2"
  123. logfile="$2"
  124. shift
  125. else
  126. printf "Logging Tor Browser debug information to %s\n" "$2"
  127. logfile="../$2"
  128. shift
  129. fi
  130. log_output=1
  131. shift
  132. ;;
  133. --register-app)
  134. register_desktop_app=1
  135. show_output=1
  136. shift
  137. ;;
  138. --unregister-app)
  139. register_desktop_app=-1
  140. show_output=1
  141. shift
  142. ;;
  143. *) # No more options
  144. break
  145. ;;
  146. esac
  147. done
  148. # We can't detach and show output at the same time..
  149. if [ "$show_output" -eq 1 -a "$detach" -eq 1 ]; then
  150. detach=0
  151. fi
  152. if [ "$show_output" -eq 0 ]; then
  153. # If the user hasn't requested 'debug mode' or --help, close stdout and stderr,
  154. # to keep Firefox and the stuff loaded by/for it (including the
  155. # system's shared-library loader) from printing messages to
  156. # $HOME/.xsession-errors or other files. (Users wouldn't have seen
  157. # messages there anyway.)
  158. exec > "$logfile"
  159. exec 2> "$logfile"
  160. fi
  161. # If XAUTHORITY is unset, set it to its default value of $HOME/.Xauthority
  162. # before we change HOME below. (See xauth(1) and #1945.) XDM and KDM rely
  163. # on applications using this default value.
  164. if [ -z "$XAUTHORITY" ]; then
  165. XAUTHORITY=~/.Xauthority
  166. export XAUTHORITY
  167. fi
  168. # If this script is being run through a symlink, we need to know where
  169. # in the filesystem the script itself is, not where the symlink is.
  170. myname="$0"
  171. if [ -L "$myname" ]; then
  172. # XXX readlink is not POSIX, but is present in GNU coreutils
  173. # and on FreeBSD. Unfortunately, the -f option (which follows
  174. # a whole chain of symlinks until it reaches a non-symlink
  175. # path name) is a GNUism, so we have to have a fallback for
  176. # FreeBSD. Fortunately, FreeBSD has realpath instead;
  177. # unfortunately, that's also non-POSIX and is not present in
  178. # GNU coreutils.
  179. #
  180. # If this launcher were a C program, we could just use the
  181. # realpath function, which *is* POSIX. Too bad POSIX didn't
  182. # make that function accessible to shell scripts.
  183. # If realpath is available, use it; it Does The Right Thing.
  184. possibly_my_real_name="`realpath "$myname" 2>/dev/null`"
  185. if [ "$?" -eq 0 ]; then
  186. myname="$possibly_my_real_name"
  187. else
  188. # realpath is not available; hopefully readlink -f works.
  189. myname="`readlink -f "$myname" 2>/dev/null`"
  190. if [ "$?" -ne 0 ]; then
  191. # Ugh.
  192. complain "start-tor-browser cannot be run using a symlink on this operating system."
  193. fi
  194. fi
  195. fi
  196. # Try to be agnostic to where we're being started from, chdir to where
  197. # the script is.
  198. mydir="`dirname "$myname"`"
  199. test -d "$mydir" && cd "$mydir"
  200. # If ${PWD} results in a zero length string, we can try something else...
  201. if [ ! "${PWD}" ]; then
  202. # "hacking around some braindamage"
  203. PWD="`pwd`"
  204. surveysays="This system has a messed up shell.\n"
  205. fi
  206. # This is a fix for an ibus issue on some Linux systems. See #9353 for more
  207. # details. The symlink needs to be created before we change HOME.
  208. if [ ! -d ".config/ibus" ]; then
  209. mkdir -p .config/ibus
  210. ln -nsf ~/.config/ibus/bus .config/ibus
  211. fi
  212. # Fix up .desktop Icon and Exec Paths, and update the .desktop file from the
  213. # canonical version if it was changed by the updater.
  214. cp start-tor-browser.desktop ../
  215. sed -i -e "s,^Name=.*,Name=Tor Browser,g" ../start-tor-browser.desktop
  216. sed -i -e "s,^Icon=.*,Icon=$PWD/browser/icons/mozicon128.png,g" ../start-tor-browser.desktop
  217. sed -i -e "s,^Exec=.*,Exec=sh -c '\"$PWD/start-tor-browser\" --detach || ([ ! -x \"$PWD/start-tor-browser\" ] \&\& \"\$(dirname \"\$*\")\"/Browser/start-tor-browser --detach)' dummy %k,g" ../start-tor-browser.desktop
  218. if [ "$register_desktop_app" -eq 1 ]; then
  219. mkdir -p "$HOME/.local/share/applications/"
  220. cp ../start-tor-browser.desktop "$HOME/.local/share/applications/"
  221. update-desktop-database "$HOME/.local/share/applications/"
  222. printf "Tor Browser has been registered as a desktop app for this user in ~/.local/share/applications/\n"
  223. exit 0
  224. fi
  225. if [ "$register_desktop_app" -eq -1 ]; then
  226. if [ -e "$HOME/.local/share/applications/start-tor-browser.desktop" ]; then
  227. rm -f "$HOME/.local/share/applications/start-tor-browser.desktop"
  228. update-desktop-database "$HOME/.local/share/applications/"
  229. printf "Tor Browser has been removed as a user desktop app (from ~/.local/share/applications/)\n"
  230. else
  231. printf "Tor Browser does not appear to be a desktop app (not present in ~/.local/share/applications/)\n"
  232. fi
  233. exit 0
  234. fi
  235. HOME="${PWD}"
  236. export HOME
  237. SYSARCHITECTURE=$(getconf LONG_BIT)
  238. TORARCHITECTURE=$(expr "$(file TorBrowser/Tor/tor)" : '.*ELF \([[:digit:]]*\)')
  239. if [ $SYSARCHITECTURE -ne $TORARCHITECTURE ]; then
  240. complain "Wrong architecture? 32-bit vs. 64-bit."
  241. exit 1
  242. fi
  243. LD_LIBRARY_PATH="${HOME}/TorBrowser/Tor/"
  244. export LD_LIBRARY_PATH
  245. [% IF ! c("var/release") %]
  246. export SELFRANDO_write_layout_file=
  247. [% END %]
  248. [% IF c("var/asan") -%]
  249. # We need to disable LSan which is enabled by default now. Otherwise we'll get
  250. # a crash during shutdown: https://bugs.torproject.org/10599#comment:59
  251. ASAN_OPTIONS="detect_leaks=0"
  252. export ASAN_OPTIONS
  253. [% END -%]
  254. function setControlPortPasswd() {
  255. local ctrlPasswd=$1
  256. if test -z "$ctrlPasswd" -o "$ctrlPasswd" = $'\"secret\"' ; then
  257. unset TOR_CONTROL_PASSWD
  258. return
  259. fi
  260. if test "${ctrlPasswd:0:1}" = $'\"'; then # First 2 chars were '"
  261. printf "Using system Tor process.\n"
  262. export TOR_CONTROL_PASSWD
  263. else
  264. complain "There seems to have been a quoting problem with your \
  265. TOR_CONTROL_PASSWD environment variable."
  266. cat <<EOF
  267. The Tor ControlPort password should be given inside double quotes, inside single
  268. quotes, i.e. if the ControlPort password is “secret” (without curly quotes) then
  269. we must start this script after setting the environment variable exactly like
  270. this:
  271. \$ TOR_CONTROL_PASSWD='"secret"' $myname
  272. EOF
  273. fi
  274. }
  275. # Using a system-installed Tor process with Tor Browser:
  276. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  277. # The Tor ControlPort password should be given inside double quotes, inside
  278. # single quotes, i.e. if the ControlPort password is “secret” (without
  279. # curly quotes) then we must set the environment variable *exactly* like
  280. # this:
  281. #
  282. # TOR_CONTROL_PASSWD='"secret"'
  283. #
  284. # Yes, the variable MUST be double-quoted, then single-quoted, exactly as
  285. # shown. This is used by TorButton and Tor Launcher to authenticate to Tor's
  286. # ControlPort, and is necessary for using TB with a system-installed Tor.
  287. #
  288. # Additionally, if using a system-installed Tor, the following about:config
  289. # options should be set (values in <> mean they are the value taken from your
  290. # torrc):
  291. #
  292. # SETTING NAME VALUE
  293. # network.security.ports.banned [...],<SocksPort>,<ControlPort>
  294. # network.proxy.socks 127.0.0.1
  295. # network.proxy.socks_port <SocksPort>
  296. # extensions.torbutton.inserted_button true
  297. # extensions.torbutton.launch_warning false
  298. # extensions.torbutton.loglevel 2
  299. # extensions.torbutton.logmethod 0
  300. # extensions.torlauncher.control_port <ControlPort>
  301. # extensions.torlauncher.loglevel 2
  302. # extensions.torlauncher.logmethod 0
  303. # extensions.torlauncher.prompt_at_startup false
  304. # extensions.torlauncher.start_tor false
  305. #
  306. # where the '[...]' in the banned_ports option means "leave anything that was
  307. # already in the preference alone, just append the things specified after it".
  308. # Either set `TOR_CONTROL_PASSWD` before running ./start-tor-browser, or put
  309. # your password in the following line where the word “secret” is:
  310. setControlPortPasswd ${TOR_CONTROL_PASSWD:='"secret"'}
  311. # Set up custom bundled fonts. See fonts-conf(5).
  312. export FONTCONFIG_PATH="${HOME}/TorBrowser/Data/fontconfig"
  313. export FONTCONFIG_FILE="fonts.conf"
  314. cd "${HOME}"
  315. # We pass all additional command-line arguments we get to Firefox.
  316. #
  317. # The --class parameter was added to fix bug 11102.
  318. if [ "$show_usage" -eq 1 ]; then
  319. # Display Firefox help, then our help
  320. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  321. -profile TorBrowser/Data/Browser/profile.default --help 2>/dev/null
  322. tbb_usage
  323. elif [ "$detach" -eq 1 ] ; then
  324. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  325. -profile TorBrowser/Data/Browser/profile.default "${@}" > "$logfile" 2>&1 </dev/null &
  326. disown "$!"
  327. elif [ "$log_output" -eq 1 -a "$show_output" -eq 1 ]; then
  328. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  329. -profile TorBrowser/Data/Browser/profile.default "${@}" 2>&1 </dev/null | \
  330. tee "$logfile"
  331. elif [ "$show_output" -eq 1 ]; then
  332. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  333. -profile TorBrowser/Data/Browser/profile.default "${@}" < /dev/null
  334. else
  335. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  336. -profile TorBrowser/Data/Browser/profile.default "${@}" > "$logfile" 2>&1 </dev/null
  337. fi
  338. exit $?