···11getVersion() {
22 local dir="$1"
33 rev=
44- if [ -e "$dir/.git" ]; then
44+ gitDir="$dir/.git"
55+ if [ -e "$gitDir" ]; then
56 if [ -z "$(type -P git)" ]; then
67 echo "warning: Git not found; cannot figure out revision of $dir" >&2
78 return
89 fi
910 cd "$dir"
1010- rev=$(git rev-parse --short HEAD)
1111- if git describe --always --dirty | grep -q dirty; then
1111+ rev=$(git --git-dir="$gitDir" rev-parse --short HEAD)
1212+ if git --git-dir="$gitDir" describe --always --dirty | grep -q dirty; then
1213 rev+=M
1314 fi
1415 fi
+46-7
nixos/modules/services/misc/geoipupdate.nix
···2233let
44 cfg = config.services.geoipupdate;
55+ inherit (builtins) isAttrs isString isInt isList typeOf hashString;
56in
67{
78 imports = [
···2728 };
28292930 settings = lib.mkOption {
3131+ example = lib.literalExpression ''
3232+ {
3333+ AccountID = 200001;
3434+ DatabaseDirectory = "/var/lib/GeoIP";
3535+ LicenseKey = { _secret = "/run/keys/maxmind_license_key"; };
3636+ Proxy = "10.0.0.10:8888";
3737+ ProxyUserPassword = { _secret = "/run/keys/proxy_pass"; };
3838+ }
3939+ '';
3040 description = ''
3141 <productname>geoipupdate</productname> configuration
3242 options. See
3343 <link xlink:href="https://github.com/maxmind/geoipupdate/blob/main/doc/GeoIP.conf.md" />
3444 for a full list of available options.
4545+4646+ Settings containing secret data should be set to an
4747+ attribute set containing the attribute
4848+ <literal>_secret</literal> - a string pointing to a file
4949+ containing the value the option should be set to. See the
5050+ example to get a better picture of this: in the resulting
5151+ <filename>GeoIP.conf</filename> file, the
5252+ <literal>ProxyUserPassword</literal> key will be set to the
5353+ contents of the
5454+ <filename>/run/keys/proxy_pass</filename> file.
3555 '';
3656 type = lib.types.submodule {
3757 freeformType =
···6585 };
66866787 LicenseKey = lib.mkOption {
6868- type = lib.types.path;
8888+ type = with lib.types; either path (attrsOf path);
6989 description = ''
7070- A file containing the <productname>MaxMind</productname>
7171- license key.
9090+ A file containing the
9191+ <productname>MaxMind</productname> license key.
9292+9393+ Always handled as a secret whether the value is
9494+ wrapped in a <literal>{ _secret = ...; }</literal>
9595+ attrset or not (refer to <xref
9696+ linkend="opt-services.geoipupdate.settings" /> for
9797+ details).
7298 '';
9999+ apply = x: if isAttrs x then x else { _secret = x; };
73100 };
7410175102 DatabaseDirectory = lib.mkOption {
···102129 systemd.services.geoipupdate-create-db-dir = {
103130 serviceConfig.Type = "oneshot";
104131 script = ''
132132+ set -o errexit -o pipefail -o nounset -o errtrace
133133+ shopt -s inherit_errexit
134134+105135 mkdir -p ${cfg.settings.DatabaseDirectory}
106136 chmod 0755 ${cfg.settings.DatabaseDirectory}
107137 '';
···115145 "network-online.target"
116146 "nss-lookup.target"
117147 ];
148148+ path = [ pkgs.replace-secret ];
118149 wants = [ "network-online.target" ];
119150 startAt = cfg.interval;
120151 serviceConfig = {
121152 ExecStartPre =
122153 let
154154+ isSecret = v: isAttrs v && v ? _secret && isString v._secret;
123155 geoipupdateKeyValue = lib.generators.toKeyValue {
124156 mkKeyValue = lib.flip lib.generators.mkKeyValueDefault " " rec {
125125- mkValueString = v: with builtins;
157157+ mkValueString = v:
126158 if isInt v then toString v
127159 else if isString v then v
128160 else if true == v then "1"
129161 else if false == v then "0"
130162 else if isList v then lib.concatMapStringsSep " " mkValueString v
163163+ else if isSecret v then hashString "sha256" v._secret
131164 else throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty {}) v}";
132165 };
133166 };
167167+ secretPaths = lib.catAttrs "_secret" (lib.collect isSecret cfg.settings);
168168+ mkSecretReplacement = file: ''
169169+ replace-secret ${lib.escapeShellArgs [ (hashString "sha256" file) file "/run/geoipupdate/GeoIP.conf" ]}
170170+ '';
171171+ secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
134172135173 geoipupdateConf = pkgs.writeText "geoipupdate.conf" (geoipupdateKeyValue cfg.settings);
136174137175 script = ''
176176+ set -o errexit -o pipefail -o nounset -o errtrace
177177+ shopt -s inherit_errexit
178178+138179 chown geoip "${cfg.settings.DatabaseDirectory}"
139180140181 cp ${geoipupdateConf} /run/geoipupdate/GeoIP.conf
141141- ${pkgs.replace-secret}/bin/replace-secret '${cfg.settings.LicenseKey}' \
142142- '${cfg.settings.LicenseKey}' \
143143- /run/geoipupdate/GeoIP.conf
182182+ ${secretReplacements}
144183 '';
145184 in
146185 "+${pkgs.writeShellScript "start-pre-full-privileges" script}";
+79-84
nixos/modules/services/monitoring/parsedmarc.nix
···33let
44 cfg = config.services.parsedmarc;
55 opt = options.services.parsedmarc;
66- ini = pkgs.formats.ini {};
66+ isSecret = v: isAttrs v && v ? _secret && isString v._secret;
77+ ini = pkgs.formats.ini {
88+ mkKeyValue = lib.flip lib.generators.mkKeyValueDefault "=" rec {
99+ mkValueString = v:
1010+ if isInt v then toString v
1111+ else if isString v then v
1212+ else if true == v then "True"
1313+ else if false == v then "False"
1414+ else if isSecret v then hashString "sha256" v._secret
1515+ else throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty {}) v}";
1616+ };
1717+ };
1818+ inherit (builtins) elem isAttrs isString isInt isList typeOf hashString;
719in
820{
921 options.services.parsedmarc = {
···107119 };
108120109121 settings = lib.mkOption {
122122+ example = lib.literalExpression ''
123123+ {
124124+ imap = {
125125+ host = "imap.example.com";
126126+ user = "alice@example.com";
127127+ password = { _secret = "/run/keys/imap_password" };
128128+ watch = true;
129129+ };
130130+ splunk_hec = {
131131+ url = "https://splunkhec.example.com";
132132+ token = { _secret = "/run/keys/splunk_token" };
133133+ index = "email";
134134+ };
135135+ }
136136+ '';
110137 description = ''
111138 Configuration parameters to set in
112139 <filename>parsedmarc.ini</filename>. For a full list of
113140 available parameters, see
114141 <link xlink:href="https://domainaware.github.io/parsedmarc/#configuration-file" />.
142142+143143+ Settings containing secret data should be set to an attribute
144144+ set containing the attribute <literal>_secret</literal> - a
145145+ string pointing to a file containing the value the option
146146+ should be set to. See the example to get a better picture of
147147+ this: in the resulting <filename>parsedmarc.ini</filename>
148148+ file, the <literal>splunk_hec.token</literal> key will be set
149149+ to the contents of the
150150+ <filename>/run/keys/splunk_token</filename> file.
115151 '';
116152117153 type = lib.types.submodule {
···170206 };
171207172208 password = lib.mkOption {
173173- type = with lib.types; nullOr path;
209209+ type = with lib.types; nullOr (either path (attrsOf path));
174210 default = null;
175211 description = ''
176176- The path to a file containing the IMAP server password.
212212+ The IMAP server password.
213213+214214+ Always handled as a secret whether the value is
215215+ wrapped in a <literal>{ _secret = ...; }</literal>
216216+ attrset or not (refer to <xref
217217+ linkend="opt-services.parsedmarc.settings" /> for
218218+ details).
177219 '';
220220+ apply = x: if isAttrs x || x == null then x else { _secret = x; };
178221 };
179222180223 watch = lib.mkOption {
···228271 };
229272230273 password = lib.mkOption {
231231- type = with lib.types; nullOr path;
274274+ type = with lib.types; nullOr (either path (attrsOf path));
232275 default = null;
233276 description = ''
234234- The path to a file containing the SMTP server password.
277277+ The SMTP server password.
278278+279279+ Always handled as a secret whether the value is
280280+ wrapped in a <literal>{ _secret = ...; }</literal>
281281+ attrset or not (refer to <xref
282282+ linkend="opt-services.parsedmarc.settings" /> for
283283+ details).
235284 '';
285285+ apply = x: if isAttrs x || x == null then x else { _secret = x; };
236286 };
237287238288 from = lib.mkOption {
···274324 };
275325276326 password = lib.mkOption {
277277- type = with lib.types; nullOr path;
327327+ type = with lib.types; nullOr (either path (attrsOf path));
278328 default = null;
279329 description = ''
280280- The path to a file containing the password to use when
281281- connecting to Elasticsearch, if required.
330330+ The password to use when connecting to Elasticsearch,
331331+ if required.
332332+333333+ Always handled as a secret whether the value is
334334+ wrapped in a <literal>{ _secret = ...; }</literal>
335335+ attrset or not (refer to <xref
336336+ linkend="opt-services.parsedmarc.settings" /> for
337337+ details).
282338 '';
339339+ apply = x: if isAttrs x || x == null then x else { _secret = x; };
283340 };
284341285342 ssl = lib.mkOption {
···299356 '';
300357 };
301358 };
302302-303303- kafka = {
304304- hosts = lib.mkOption {
305305- default = [];
306306- type = with lib.types; listOf str;
307307- apply = x: if x == [] then null else lib.concatStringsSep "," x;
308308- description = ''
309309- A list of Apache Kafka hosts to publish parsed reports
310310- to.
311311- '';
312312- };
313313-314314- user = lib.mkOption {
315315- type = with lib.types; nullOr str;
316316- default = null;
317317- description = ''
318318- Username to use when connecting to Kafka, if
319319- required.
320320- '';
321321- };
322322-323323- password = lib.mkOption {
324324- type = with lib.types; nullOr path;
325325- default = null;
326326- description = ''
327327- The path to a file containing the password to use when
328328- connecting to Kafka, if required.
329329- '';
330330- };
331331-332332- ssl = lib.mkOption {
333333- type = with lib.types; nullOr bool;
334334- default = null;
335335- description = ''
336336- Whether to use an encrypted SSL/TLS connection.
337337- '';
338338- };
339339-340340- aggregate_topic = lib.mkOption {
341341- type = with lib.types; nullOr str;
342342- default = null;
343343- example = "aggregate";
344344- description = ''
345345- The Kafka topic to publish aggregate reports on.
346346- '';
347347- };
348348-349349- forensic_topic = lib.mkOption {
350350- type = with lib.types; nullOr str;
351351- default = null;
352352- example = "forensic";
353353- description = ''
354354- The Kafka topic to publish forensic reports on.
355355- '';
356356- };
357357- };
358358-359359 };
360360361361 };
···404404 enable = cfg.provision.grafana.datasource || cfg.provision.grafana.dashboard;
405405 datasources =
406406 let
407407- pkgVer = lib.getVersion config.services.elasticsearch.package;
408408- esVersion =
409409- if lib.versionOlder pkgVer "7" then
410410- "60"
411411- else if lib.versionOlder pkgVer "8" then
412412- "70"
413413- else
414414- throw "When provisioning parsedmarc grafana datasources: unknown Elasticsearch version.";
407407+ esVersion = lib.getVersion config.services.elasticsearch.package;
415408 in
416409 lib.mkIf cfg.provision.grafana.datasource [
417410 {
418411 name = "dmarc-ag";
419412 type = "elasticsearch";
420413 access = "proxy";
421421- url = "localhost:9200";
414414+ url = "http://localhost:9200";
422415 jsonData = {
423416 timeField = "date_range";
424417 inherit esVersion;
···428421 name = "dmarc-fo";
429422 type = "elasticsearch";
430423 access = "proxy";
431431- url = "localhost:9200";
424424+ url = "http://localhost:9200";
432425 jsonData = {
433426 timeField = "date_range";
434427 inherit esVersion;
···467460 # lists, empty attrsets and null. This makes it possible to
468461 # list interesting options in `settings` without them always
469462 # ending up in the resulting config.
470470- filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! builtins.elem v [ null [] {} ])) cfg.settings;
463463+ filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! elem v [ null [] {} ])) cfg.settings;
464464+465465+ # Extract secrets (attributes set to an attrset with a
466466+ # "_secret" key) from the settings and generate the commands
467467+ # to run to perform the secret replacements.
468468+ secretPaths = lib.catAttrs "_secret" (lib.collect isSecret filteredConfig);
471469 parsedmarcConfig = ini.generate "parsedmarc.ini" filteredConfig;
472472- mkSecretReplacement = file:
473473- lib.optionalString (file != null) ''
474474- replace-secret '${file}' '${file}' /run/parsedmarc/parsedmarc.ini
475475- '';
470470+ mkSecretReplacement = file: ''
471471+ replace-secret ${lib.escapeShellArgs [ (hashString "sha256" file) file "/run/parsedmarc/parsedmarc.ini" ]}
472472+ '';
473473+ secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
476474 in
477475 {
478476 wantedBy = [ "multi-user.target" ];
···487485 umask u=rwx,g=,o=
488486 cp ${parsedmarcConfig} /run/parsedmarc/parsedmarc.ini
489487 chown parsedmarc:parsedmarc /run/parsedmarc/parsedmarc.ini
490490- ${mkSecretReplacement cfg.settings.smtp.password}
491491- ${mkSecretReplacement cfg.settings.imap.password}
492492- ${mkSecretReplacement cfg.settings.elasticsearch.password}
493493- ${mkSecretReplacement cfg.settings.kafka.password}
488488+ ${secretReplacements}
494489 '' + lib.optionalString cfg.provision.localMail.enable ''
495490 openssl rand -hex 64 >/run/parsedmarc/dmarc_user_passwd
496491 replace-secret '@imap-password@' '/run/parsedmarc/dmarc_user_passwd' /run/parsedmarc/parsedmarc.ini
···4599459946004600 boofuzz= callPackage ../tools/security/boofuzz { };
4601460146024602+ briar-desktop = callPackage ../applications/networking/instant-messengers/briar-desktop { };
46034603+46024604 bsdbuild = callPackage ../development/tools/misc/bsdbuild { };
4603460546044606 bsdiff = callPackage ../tools/compression/bsdiff { };
···14440144421444114443 inherit (beam.interpreters)
1444214444 erlang erlangR25 erlangR24 erlangR23 erlangR22 erlangR21
1444314443- erlang_odbc erlang_javac erlang_odbc_javac erlang_basho_R16B02
1444514445+ erlang_odbc erlang_javac erlang_odbc_javac
1444414446 elixir elixir_1_13 elixir_1_12 elixir_1_11 elixir_1_10 elixir_1_9
1444514447 elixir_ls;
1444614448···1613616138 nwjs-sdk = callPackage ../development/tools/nwjs {
1613716139 sdk = true;
1613816140 };
1614116141+1614216142+ nrf5-sdk = callPackage ../development/libraries/nrf5-sdk { };
16139161431614016144 nrfutil = callPackage ../development/tools/misc/nrfutil { };
1614116145···20927209312092820932 sphinx = with python3Packages; toPythonApplication sphinx;
20929209332093420934+ # A variation of sphinx that is only suitable for offline use as it excludes
2093520935+ # pyopenssl, which is broken on aarch64-darwin.
2093620936+ # https://github.com/NixOS/nixpkgs/issues/175875
2093720937+ sphinx_offline =
2093820938+ if !(stdenv.buildPlatform.isDarwin && stdenv.buildPlatform.isAarch64)
2093920939+ then sphinx
2094020940+ else
2094120941+ sphinx.override (o: {
2094220942+ requests = pkgsBuildTarget.python3Packages.requests.override (o: {
2094320943+ urllib3 = pkgsBuildTarget.python3Packages.urllib3.overrideAttrs (o: {
2094420944+ # urllib3 adds the optional pyopenssl to propagatedBuildInputs
2094520945+ # pkgs/development/python-modules/urllib3/default.nix
2094620946+ propagatedBuildInputs = [];
2094720947+ });
2094820948+ });
2094920949+ });
2095020950+2093020951 sphinx-autobuild = with python3Packages; toPythonApplication sphinx-autobuild;
20931209522093220953 sphinx-serve = with python3Packages; toPythonApplication sphinx-serve;
···26987270082698827009 # Git with SVN support, but without GUI.
2698927010 gitSVN = lowPrio (git.override { svnSupport = true; });
2701127011+2701227012+ git-autofixup = perlPackages.GitAutofixup;
26990270132699127014 git-doc = lib.addMetaAttrs {
2699227015 description = "Additional documentation for Git";
-9
pkgs/top-level/beam-packages.nix
···9292 odbcSupport = true;
9393 };
94949595- # Basho fork, using custom builder.
9696- erlang_basho_R16B02 =
9797- lib.callErlang ../development/interpreters/erlang/R16B02-basho.nix {
9898- autoconf = buildPackages.autoconf269;
9999- inherit wxSupport;
100100- };
101101- erlang_basho_R16B02_odbc =
102102- erlang_basho_R16B02.override { odbcSupport = true; };
103103-10495 # Other Beam languages. These are built with `beam.interpreters.erlang`. To
10596 # access for example elixir built with different version of Erlang, use
10697 # `beam.packages.erlangR24.elixir`.
+7-5
pkgs/top-level/haskell-packages.nix
···4949 # Use this rather than `rec { ... }` below for sake of overlays.
5050 inherit (pkgs.haskell) compiler packages;
51515252+ sphinx = buildPackages.sphinx_offline;
5353+5254in {
5355 lib = haskellLibUncomposable;
5456···9799 packages.ghc8102Binary
98100 else
99101 packages.ghc865Binary;
100100- inherit (buildPackages.python3Packages) sphinx;
102102+ inherit sphinx;
101103 buildTargetLlvmPackages = pkgsBuildTarget.llvmPackages_7;
102104 llvmPackages = pkgs.llvmPackages_7;
103105 };
···110112 packages.ghc8107BinaryMinimal
111113 else
112114 packages.ghc8107Binary;
113113- inherit (buildPackages.python3Packages) sphinx;
115115+ inherit sphinx;
114116 # Need to use apple's patched xattr until
115117 # https://github.com/xattr/xattr/issues/44 and
116118 # https://github.com/xattr/xattr/issues/55 are solved.
···126128 packages.ghc8107BinaryMinimal
127129 else
128130 packages.ghc8107Binary;
129129- inherit (buildPackages.python3Packages) sphinx;
131131+ inherit sphinx;
130132 inherit (buildPackages.darwin) autoSignDarwinBinariesHook xattr;
131133 buildTargetLlvmPackages = pkgsBuildTarget.llvmPackages_12;
132134 llvmPackages = pkgs.llvmPackages_12;
···138140 packages.ghc8107BinaryMinimal
139141 else
140142 packages.ghc8107Binary;
141141- inherit (buildPackages.python3Packages) sphinx;
143143+ inherit sphinx;
142144 # Need to use apple's patched xattr until
143145 # https://github.com/xattr/xattr/issues/44 and
144146 # https://github.com/xattr/xattr/issues/55 are solved.
···148150 };
149151 ghcHEAD = callPackage ../development/compilers/ghc/head.nix {
150152 bootPkgs = packages.ghc8107Binary;
151151- inherit (buildPackages.python3Packages) sphinx;
153153+ inherit sphinx;
152154 # Need to use apple's patched xattr until
153155 # https://github.com/xattr/xattr/issues/44 and
154156 # https://github.com/xattr/xattr/issues/55 are solved.