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