start-tor-browser 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. if uname -m | grep -q -e "x86_64" -e "amd64" -e "i[456]86" ; then
  87. if test -r /proc/cpuinfo && ! grep -q '^flags\s*:.* sse2' /proc/cpuinfo; then
  88. complain "Tor Browser requires a CPU with SSE2 support. Exiting."
  89. exit 1
  90. fi
  91. fi
  92. tbb_usage () {
  93. printf "\nTor Browser Script Options\n"
  94. printf " --verbose Display Tor and Firefox output in the terminal\n"
  95. printf " --log [file] Record Tor and Firefox output in file (default: tor-browser.log)\n"
  96. printf " --detach Detach from terminal and run Tor Browser in the background.\n"
  97. printf " --register-app Register Tor Browser as a desktop app for this user\n"
  98. printf " --unregister-app Unregister Tor Browser as a desktop app for this user\n"
  99. }
  100. log_output=0
  101. show_output=0
  102. detach=0
  103. show_usage=0
  104. register_desktop_app=0
  105. logfile=/dev/null
  106. while :
  107. do
  108. case "$1" in
  109. --detach)
  110. detach=1
  111. shift
  112. ;;
  113. -v | --verbose | -d | --debug)
  114. show_output=1
  115. verbose_arg="$2"
  116. shift
  117. ;;
  118. -h | "-?" | --help | -help)
  119. show_usage=1
  120. show_output=1
  121. shift
  122. ;;
  123. -l | --log)
  124. if [ -z "$2" -o "${2:0:1}" == "-" ]; then
  125. printf "Logging Tor Browser debug information to tor-browser.log\n"
  126. logfile="../tor-browser.log"
  127. elif [ "${2:0:1}" == "/" -o "${2:0:1}" == "~" ]; then
  128. printf "Logging Tor Browser debug information to %s\n" "$2"
  129. logfile="$2"
  130. shift
  131. else
  132. printf "Logging Tor Browser debug information to %s\n" "$2"
  133. logfile="../$2"
  134. shift
  135. fi
  136. log_output=1
  137. shift
  138. ;;
  139. --register-app)
  140. register_desktop_app=1
  141. show_output=1
  142. shift
  143. ;;
  144. --unregister-app)
  145. register_desktop_app=-1
  146. show_output=1
  147. shift
  148. ;;
  149. *) # No more options
  150. break
  151. ;;
  152. esac
  153. done
  154. # We can't detach and show output at the same time..
  155. if [ "$show_output" -eq 1 -a "$detach" -eq 1 ]; then
  156. detach=0
  157. fi
  158. if [ "$show_output" -eq 0 ]; then
  159. # If the user hasn't requested 'debug mode' or --help, close stdout and stderr,
  160. # to keep Firefox and the stuff loaded by/for it (including the
  161. # system's shared-library loader) from printing messages to
  162. # $HOME/.xsession-errors or other files. (Users wouldn't have seen
  163. # messages there anyway.)
  164. exec > "$logfile"
  165. exec 2> "$logfile"
  166. fi
  167. # If XAUTHORITY is unset, set it to its default value of $HOME/.Xauthority
  168. # before we change HOME below. (See xauth(1) and #1945.) XDM and KDM rely
  169. # on applications using this default value.
  170. if [ -z "$XAUTHORITY" ]; then
  171. XAUTHORITY=~/.Xauthority
  172. export XAUTHORITY
  173. fi
  174. # If this script is being run through a symlink, we need to know where
  175. # in the filesystem the script itself is, not where the symlink is.
  176. myname="$0"
  177. if [ -L "$myname" ]; then
  178. # XXX readlink is not POSIX, but is present in GNU coreutils
  179. # and on FreeBSD. Unfortunately, the -f option (which follows
  180. # a whole chain of symlinks until it reaches a non-symlink
  181. # path name) is a GNUism, so we have to have a fallback for
  182. # FreeBSD. Fortunately, FreeBSD has realpath instead;
  183. # unfortunately, that's also non-POSIX and is not present in
  184. # GNU coreutils.
  185. #
  186. # If this launcher were a C program, we could just use the
  187. # realpath function, which *is* POSIX. Too bad POSIX didn't
  188. # make that function accessible to shell scripts.
  189. # If realpath is available, use it; it Does The Right Thing.
  190. possibly_my_real_name="`realpath "$myname" 2>/dev/null`"
  191. if [ "$?" -eq 0 ]; then
  192. myname="$possibly_my_real_name"
  193. else
  194. # realpath is not available; hopefully readlink -f works.
  195. myname="`readlink -f "$myname" 2>/dev/null`"
  196. if [ "$?" -ne 0 ]; then
  197. # Ugh.
  198. complain "start-tor-browser cannot be run using a symlink on this operating system."
  199. fi
  200. fi
  201. fi
  202. # Try to be agnostic to where we're being started from, chdir to where
  203. # the script is.
  204. mydir="`dirname "$myname"`"
  205. test -d "$mydir" && cd "$mydir"
  206. # If ${PWD} results in a zero length string, we can try something else...
  207. if [ ! "${PWD}" ]; then
  208. # "hacking around some braindamage"
  209. PWD="`pwd`"
  210. surveysays="This system has a messed up shell.\n"
  211. fi
  212. # This is a fix for an ibus issue on some Linux systems. See #9353 for more
  213. # details. The symlink needs to be created before we change HOME.
  214. if [ ! -d ".config/ibus" ]; then
  215. mkdir -p .config/ibus
  216. ln -nsf ~/.config/ibus/bus .config/ibus
  217. fi
  218. # Fix up .desktop Icon and Exec Paths, and update the .desktop file from the
  219. # canonical version if it was changed by the updater.
  220. cp start-tor-browser.desktop ../
  221. sed -i -e "s,^Name=.*,Name=Tor Browser,g" ../start-tor-browser.desktop
  222. sed -i -e "s,^Icon=.*,Icon=$PWD/browser/chrome/icons/default/default128.png,g" ../start-tor-browser.desktop
  223. 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
  224. if [ "$register_desktop_app" -eq 1 ]; then
  225. mkdir -p "$HOME/.local/share/applications/"
  226. cp ../start-tor-browser.desktop "$HOME/.local/share/applications/"
  227. update-desktop-database "$HOME/.local/share/applications/"
  228. printf "Tor Browser has been registered as a desktop app for this user in ~/.local/share/applications/\n"
  229. exit 0
  230. fi
  231. if [ "$register_desktop_app" -eq -1 ]; then
  232. if [ -e "$HOME/.local/share/applications/start-tor-browser.desktop" ]; then
  233. rm -f "$HOME/.local/share/applications/start-tor-browser.desktop"
  234. update-desktop-database "$HOME/.local/share/applications/"
  235. printf "Tor Browser has been removed as a user desktop app (from ~/.local/share/applications/)\n"
  236. else
  237. printf "Tor Browser does not appear to be a desktop app (not present in ~/.local/share/applications/)\n"
  238. fi
  239. exit 0
  240. fi
  241. HOME="${PWD}"
  242. export HOME
  243. SYSARCHITECTURE=$(getconf LONG_BIT)
  244. TORARCHITECTURE=$(expr "$(file TorBrowser/Tor/tor)" : '.*ELF \([[:digit:]]*\)')
  245. if [ $SYSARCHITECTURE -ne $TORARCHITECTURE ]; then
  246. complain "Wrong architecture? 32-bit vs. 64-bit."
  247. exit 1
  248. fi
  249. [% IF c("var/asan") -%]
  250. # We need to disable LSan which is enabled by default now. Otherwise we'll get
  251. # a crash during shutdown: https://bugs.torproject.org/10599#comment:59
  252. ASAN_OPTIONS="detect_leaks=0"
  253. export ASAN_OPTIONS
  254. [% END -%]
  255. function setControlPortPasswd() {
  256. local ctrlPasswd=$1
  257. if test -z "$ctrlPasswd" -o "$ctrlPasswd" = $'\"secret\"' ; then
  258. unset TOR_CONTROL_PASSWD
  259. return
  260. fi
  261. if test "${ctrlPasswd:0:1}" = $'\"'; then # First 2 chars were '"
  262. printf "Using system Tor process.\n"
  263. export TOR_CONTROL_PASSWD
  264. else
  265. complain "There seems to have been a quoting problem with your \
  266. TOR_CONTROL_PASSWD environment variable."
  267. echo "The Tor ControlPort password should be given inside double"
  268. echo "quotes, inside single quotes. That is, if the ControlPort"
  269. echo 'password is “secret” (without curly quotes) then we must'
  270. echo "start this script after setting the environment variable"
  271. echo "exactly like this:"
  272. echo
  273. echo " \$ TOR_CONTROL_PASSWD='\"secret\"' $myname"
  274. fi
  275. }
  276. # Using a system-installed Tor process with Tor Browser:
  277. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  278. # The Tor ControlPort password should be given inside double quotes, inside
  279. # single quotes, i.e. if the ControlPort password is “secret” (without
  280. # curly quotes) then we must set the environment variable *exactly* like
  281. # this:
  282. #
  283. # TOR_CONTROL_PASSWD='"secret"'
  284. #
  285. # Yes, the variable MUST be double-quoted, then single-quoted, exactly as
  286. # shown. This is used by TorButton and Tor Launcher to authenticate to Tor's
  287. # ControlPort, and is necessary for using TB with a system-installed Tor.
  288. #
  289. # Additionally, if using a system-installed Tor, the following about:config
  290. # options should be set (values in <> mean they are the value taken from your
  291. # torrc):
  292. #
  293. # SETTING NAME VALUE
  294. # network.security.ports.banned [...],<SocksPort>,<ControlPort>
  295. # network.proxy.socks 127.0.0.1
  296. # network.proxy.socks_port <SocksPort>
  297. # extensions.torbutton.inserted_button true
  298. # extensions.torbutton.launch_warning false
  299. # extensions.torbutton.loglevel 2
  300. # extensions.torbutton.logmethod 0
  301. # extensions.torlauncher.control_port <ControlPort>
  302. # extensions.torlauncher.loglevel 2
  303. # extensions.torlauncher.logmethod 0
  304. # extensions.torlauncher.prompt_at_startup false
  305. # extensions.torlauncher.start_tor false
  306. #
  307. # where the '[...]' in the banned_ports option means "leave anything that was
  308. # already in the preference alone, just append the things specified after it".
  309. # Either set `TOR_CONTROL_PASSWD` before running ./start-tor-browser, or put
  310. # your password in the following line where the word “secret” is:
  311. setControlPortPasswd ${TOR_CONTROL_PASSWD:='"secret"'}
  312. # Set up custom bundled fonts. See fonts-conf(5).
  313. export FONTCONFIG_PATH="${HOME}/TorBrowser/Data/fontconfig"
  314. export FONTCONFIG_FILE="fonts.conf"
  315. cd "${HOME}"
  316. # We pass all additional command-line arguments we get to Firefox.
  317. #
  318. # The --class parameter was added to fix bug 11102.
  319. if [ "$show_usage" -eq 1 ]; then
  320. # Display Firefox help, then our help
  321. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  322. -profile TorBrowser/Data/Browser/profile.default --help 2>/dev/null
  323. tbb_usage
  324. elif [ "$detach" -eq 1 ] ; then
  325. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  326. -profile TorBrowser/Data/Browser/profile.default "${@}" > "$logfile" 2>&1 </dev/null &
  327. disown "$!"
  328. elif [ "$log_output" -eq 1 -a "$show_output" -eq 1 ]; then
  329. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  330. -profile TorBrowser/Data/Browser/profile.default "${@}" 2>&1 </dev/null | \
  331. tee "$logfile"
  332. elif [ "$show_output" -eq 1 ]; then
  333. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  334. -profile TorBrowser/Data/Browser/profile.default "${@}" < /dev/null
  335. else
  336. TOR_CONTROL_PASSWD=${TOR_CONTROL_PASSWD} ./firefox --class "Tor Browser" \
  337. -profile TorBrowser/Data/Browser/profile.default "${@}" > "$logfile" 2>&1 </dev/null
  338. fi
  339. exit $?