python312Packages.yoda: 2.0.1 -> 2.0.2
[NixPkgs.git] / pkgs / by-name / to / tor-browser / package.nix
blob6c4c6470865badbd1b1736230cf706b0e00029b3
1 { lib
2 , stdenv
3 , fetchurl
4 , makeDesktopItem
5 , copyDesktopItems
6 , makeWrapper
7 , writeText
8 , autoPatchelfHook
9 , patchelfUnstable # have to use patchelfUnstable to support --no-clobber-old-sections
10 , wrapGAppsHook3
11 , callPackage
13 , atk
14 , cairo
15 , dbus
16 , dbus-glib
17 , fontconfig
18 , freetype
19 , gdk-pixbuf
20 , glib
21 , gtk3
22 , libxcb
23 , libX11
24 , libXext
25 , libXrender
26 , libXt
27 , libXtst
28 , mesa
29 , pango
30 , pciutils
31 , zlib
33 , libnotifySupport ? stdenv.hostPlatform.isLinux
34 , libnotify
36 , waylandSupport ? stdenv.hostPlatform.isLinux
37 , libxkbcommon
38 , libdrm
39 , libGL
41 , mediaSupport ? true
42 , ffmpeg
44 , audioSupport ? mediaSupport
46 , pipewireSupport ? audioSupport
47 , pipewire
49 , pulseaudioSupport ? audioSupport
50 , libpulseaudio
51 , apulse
52 , alsa-lib
54 , libvaSupport ? mediaSupport
55 , libva
57 # Hardening
58 , graphene-hardened-malloc
59 # Whether to use graphene-hardened-malloc
60 , useHardenedMalloc ? null
62 # Whether to disable multiprocess support
63 , disableContentSandbox ? false
65 # Extra preferences
66 , extraPrefs ? ""
69 lib.warnIf (useHardenedMalloc != null)
70   "tor-browser: useHardenedMalloc is deprecated and enabling it can cause issues"
72 (let
73   libPath = lib.makeLibraryPath (
74     [
75       alsa-lib
76       atk
77       cairo
78       dbus
79       dbus-glib
80       fontconfig
81       freetype
82       gdk-pixbuf
83       glib
84       gtk3
85       libxcb
86       libX11
87       libXext
88       libXrender
89       libXt
90       libXtst
91       mesa # for libgbm
92       pango
93       pciutils
94       stdenv.cc.cc
95       stdenv.cc.libc
96       zlib
97     ] ++ lib.optionals libnotifySupport [ libnotify ]
98       ++ lib.optionals waylandSupport [ libxkbcommon libdrm libGL ]
99       ++ lib.optionals pipewireSupport [ pipewire ]
100       ++ lib.optionals pulseaudioSupport [ libpulseaudio ]
101       ++ lib.optionals libvaSupport [ libva ]
102       ++ lib.optionals mediaSupport [ ffmpeg ]
103   );
105   version = "14.0.3";
107   sources = {
108     x86_64-linux = fetchurl {
109       urls = [
110         "https://archive.torproject.org/tor-package-archive/torbrowser/${version}/tor-browser-linux-x86_64-${version}.tar.xz"
111         "https://dist.torproject.org/torbrowser/${version}/tor-browser-linux-x86_64-${version}.tar.xz"
112         "https://tor.eff.org/dist/torbrowser/${version}/tor-browser-linux-x86_64-${version}.tar.xz"
113         "https://tor.calyxinstitute.org/dist/torbrowser/${version}/tor-browser-linux-x86_64-${version}.tar.xz"
114       ];
115       hash = "sha256-WddDs5lQFZde8Qy/7nQhGTrrT9BiVswriqOpPVpgvwY=";
116     };
118     i686-linux = fetchurl {
119       urls = [
120         "https://archive.torproject.org/tor-package-archive/torbrowser/${version}/tor-browser-linux-i686-${version}.tar.xz"
121         "https://dist.torproject.org/torbrowser/${version}/tor-browser-linux-i686-${version}.tar.xz"
122         "https://tor.eff.org/dist/torbrowser/${version}/tor-browser-linux-i686-${version}.tar.xz"
123         "https://tor.calyxinstitute.org/dist/torbrowser/${version}/tor-browser-linux-i686-${version}.tar.xz"
124       ];
125       hash = "sha256-DsTJiZkw0g4ip/yAwQ9IomZHQ6RP0hFNEzVJ8/fEbyQ=";
126     };
127   };
129   distributionIni = writeText "distribution.ini" (lib.generators.toINI {} {
130     # Some light branding indicating this build uses our distro preferences
131     Global = {
132       id = "nixos";
133       version = "1.0";
134       about = "Tor Browser for NixOS";
135     };
136   });
138   policiesJson = writeText "policies.json" (builtins.toJSON {
139     policies.DisableAppUpdate = true;
140   });
142 stdenv.mkDerivation rec {
143   pname = "tor-browser";
144   inherit version;
146   src = sources.${stdenv.hostPlatform.system} or (throw "unsupported system: ${stdenv.hostPlatform.system}");
148   nativeBuildInputs = [
149     autoPatchelfHook
150     patchelfUnstable
151     copyDesktopItems
152     makeWrapper
153     wrapGAppsHook3
154   ];
155   buildInputs = [
156     gtk3
157     alsa-lib
158     dbus-glib
159     libXtst
160   ];
162   # Firefox uses "relrhack" to manually process relocations from a fixed offset
163   patchelfFlags = [ "--no-clobber-old-sections" ];
165   preferLocalBuild = true;
166   allowSubstitutes = false;
168   desktopItems = [(makeDesktopItem {
169     name = "torbrowser";
170     exec = "tor-browser %U";
171     icon = "tor-browser";
172     desktopName = "Tor Browser";
173     genericName = "Web Browser";
174     comment = meta.description;
175     categories = [ "Network" "WebBrowser" "Security" ];
176     mimeTypes = [
177       "text/html"
178       "text/xml"
179       "application/xhtml+xml"
180       "application/vnd.mozilla.xul+xml"
181       "x-scheme-handler/http"
182       "x-scheme-handler/https"
183     ];
184   })];
186   buildPhase = ''
187     runHook preBuild
189     # For convenience ...
190     TBB_IN_STORE=$out/share/tor-browser
192     # Unpack & enter
193     mkdir -p "$TBB_IN_STORE"
194     tar xf "$src" -C "$TBB_IN_STORE" --strip-components=2
195     pushd "$TBB_IN_STORE"
197     # Set ELF interpreter
198     autoPatchelf firefox.real TorBrowser/Tor
200     # firefox is a wrapper that checks for a more recent libstdc++ & appends it to the ld path
201     mv firefox.real firefox
203     # store state at `~/.tor browser` instead of relative to executable
204     touch "$TBB_IN_STORE/system-install"
206     # The final libPath.  Note, we could split this into firefoxLibPath
207     # and torLibPath for accuracy, but this is more convenient ...
208     libPath=${libPath}:$TBB_IN_STORE:$TBB_IN_STORE/TorBrowser/Tor
210     # apulse uses a non-standard library path.  For now special-case it.
211     ${lib.optionalString (audioSupport && !pulseaudioSupport) ''
212       libPath=${apulse}/lib/apulse:$libPath
213     ''}
215     # Fixup paths to pluggable transports.
216     substituteInPlace TorBrowser/Data/Tor/torrc-defaults \
217       --replace-fail './TorBrowser' "$TBB_IN_STORE/TorBrowser"
219     # Prepare for autoconfig.
220     #
221     # See https://developer.mozilla.org/en-US/Firefox/Enterprise_deployment
222     cat >defaults/pref/autoconfig.js <<EOF
223     //
224     pref("general.config.filename", "mozilla.cfg");
225     pref("general.config.obscure_value", 0);
226     EOF
228     # Hard-coded Firefox preferences.
229     cat >mozilla.cfg <<EOF
230     // First line must be a comment
232     // Reset pref that captures store paths.
233     clearPref("extensions.xpiState");
235     // Stop obnoxious first-run redirection.
236     lockPref("noscript.firstRunRedirection", false);
238     // User should never change these.  Locking prevents these
239     // values from being written to prefs.js, avoiding Store
240     // path capture.
241     lockPref("extensions.torlauncher.torrc-defaults_path", "$TBB_IN_STORE/TorBrowser/Data/Tor/torrc-defaults");
242     lockPref("extensions.torlauncher.tor_path", "$TBB_IN_STORE/TorBrowser/Tor/tor");
244     // Insist on using IPC for communicating with Tor
245     //
246     // Defaults to creating \$XDG_RUNTIME_DIR/Tor/{socks,control}.socket
247     lockPref("extensions.torlauncher.control_port_use_ipc", true);
248     lockPref("extensions.torlauncher.socks_port_use_ipc", true);
250     // Optionally disable multiprocess support.  We always set this to ensure that
251     // toggling the pref takes effect.
252     lockPref("browser.tabs.remote.autostart.2", ${if disableContentSandbox then "false" else "true"});
254     // Allow sandbox access to sound devices if using ALSA directly
255     ${if (audioSupport && !pulseaudioSupport) then ''
256       pref("security.sandbox.content.write_path_whitelist", "/dev/snd/");
257     '' else ''
258       clearPref("security.sandbox.content.write_path_whitelist");
259     ''}
261     ${lib.optionalString (extraPrefs != "") ''
262       ${extraPrefs}
263     ''}
264     EOF
266     # FONTCONFIG_FILE is required to make fontconfig read the TBB
267     # fonts.conf; upstream uses FONTCONFIG_PATH, but FC_DEBUG=1024
268     # indicates the system fonts.conf being used instead.
269     FONTCONFIG_FILE=$TBB_IN_STORE/fontconfig/fonts.conf
270     substituteInPlace "$FONTCONFIG_FILE" \
271       --replace-fail '<dir prefix="cwd">fonts</dir>' "<dir>$TBB_IN_STORE/fonts</dir>"
273     # Hard-code paths to geoip data files.  TBB resolves the geoip files
274     # relative to torrc-defaults_path but if we do not hard-code them
275     # here, these paths end up being written to the torrc in the user's
276     # state dir.
277     cat >>TorBrowser/Data/Tor/torrc-defaults <<EOF
278     GeoIPFile $TBB_IN_STORE/TorBrowser/Data/Tor/geoip
279     GeoIPv6File $TBB_IN_STORE/TorBrowser/Data/Tor/geoip6
280     EOF
282     mkdir -p $out/bin
284     makeWrapper "$TBB_IN_STORE/firefox" "$out/bin/tor-browser" \
285       --prefix LD_PRELOAD : "${lib.optionalString (useHardenedMalloc == true)
286         "${graphene-hardened-malloc}/lib/libhardened_malloc.so"}" \
287       --prefix LD_LIBRARY_PATH : "$libPath" \
288       --set FONTCONFIG_FILE "$FONTCONFIG_FILE" \
289       --set-default MOZ_ENABLE_WAYLAND 1
291     # Easier access to docs
292     mkdir -p $out/share/doc
293     ln -s $TBB_IN_STORE/TorBrowser/Docs $out/share/doc/tor-browser
295     # Install icons
296     for i in 16 32 48 64 128; do
297       mkdir -p $out/share/icons/hicolor/''${i}x''${i}/apps/
298       ln -s $out/share/tor-browser/browser/chrome/icons/default/default$i.png $out/share/icons/hicolor/''${i}x''${i}/apps/tor-browser.png
299     done
301     # Check installed apps
302     echo "Checking bundled Tor ..."
303     LD_LIBRARY_PATH=$libPath $TBB_IN_STORE/TorBrowser/Tor/tor --version >/dev/null
305     echo "Checking tor-browser wrapper ..."
306     $out/bin/tor-browser --version >/dev/null
308     runHook postBuild
309   '';
311   installPhase = ''
312     runHook preInstall
314     # Install distribution customizations
315     install -Dvm644 ${distributionIni} $out/share/tor-browser/distribution/distribution.ini
316     install -Dvm644 ${policiesJson} $out/share/tor-browser/distribution/policies.json
318     runHook postInstall
319   '';
321   passthru = {
322     inherit sources;
323     updateScript = callPackage ./update.nix {
324       inherit pname version meta;
325     };
326   };
328   meta = with lib; {
329     description = "Privacy-focused browser routing traffic through the Tor network";
330     mainProgram = "tor-browser";
331     homepage = "https://www.torproject.org/";
332     changelog = "https://gitweb.torproject.org/builders/tor-browser-build.git/plain/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt?h=maint-${version}";
333     platforms = attrNames sources;
334     maintainers = with maintainers; [ felschr panicgh joachifm hax404 ];
335     # MPL2.0+, GPL+, &c.  While it's not entirely clear whether
336     # the compound is "libre" in a strict sense (some components place certain
337     # restrictions on redistribution), it's free enough for our purposes.
338     license = with licenses; [ mpl20 lgpl21Plus lgpl3Plus free ];
339     sourceProvenance = with sourceTypes; [ binaryNativeCode ];
340   };