aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-05-25 20:12:30 +0900
committerOphestra <cat@gensokyo.uk>2025-05-25 20:12:30 +0900
commit2ffca6984a03b2daa3bb114f70ea84e71439559a (patch)
tree8d536414115917e5c6d95e7e9e5aaa4151a0d71f
parentdde2516304ac6b0edc1dfc6650f37d32fa62642c (diff)
nix: use reverse-DNS style id as unique identifier
Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--nixos.nix145
-rw-r--r--options.nix13
-rw-r--r--test/configuration.nix33
-rw-r--r--test/sandbox/case/default.nix13
-rw-r--r--test/sandbox/configuration.nix8
5 files changed, 114 insertions, 98 deletions
diff --git a/nixos.nix b/nixos.nix
index 12b283a2..307355b2 100644
--- a/nixos.nix
+++ b/nixos.nix
@@ -8,12 +8,10 @@ packages:
let
inherit (lib)
+ lists
mkMerge
mkIf
mapAttrs
- mergeAttrsList
- imap1
- foldr
foldlAttrs
optional
optionals
@@ -30,6 +28,27 @@ in
imports = [ (import ./options.nix packages) ];
config = mkIf cfg.enable {
+ assertions = [
+ (
+ let
+ conflictingApps = foldlAttrs (
+ acc: id: app:
+ (
+ acc
+ ++ foldlAttrs (
+ acc': id': app':
+ if id == id' || app.shareUid && app'.shareUid || app.identity != app'.identity then acc' else acc' ++ [ id ]
+ ) [ ] cfg.apps
+ )
+ ) [ ] cfg.apps;
+ in
+ {
+ assertion = (lists.length conflictingApps) == 0;
+ message = "the following fortify apps have conflicting identities: " + (builtins.concatStringsSep ", " conflictingApps);
+ }
+ )
+ ];
+
security.wrappers.fsu = {
source = "${cfg.fsuPackage}/bin/fsu";
setuid = true;
@@ -49,22 +68,19 @@ in
home-manager =
let
privPackages = mapAttrs (username: fid: {
- home.packages =
- let
- # aid 0 is reserved
- wrappers = imap1 (
- aid: app:
+ home.packages = foldlAttrs (
+ acc: id: app:
+ [
+ (
let
extendDBusDefault = id: ext: {
filter = true;
talk = [ "org.freedesktop.Notifications" ] ++ ext.talk;
- own =
- (optionals (app.id != null) [
- "${id}.*"
- "org.mpris.MediaPlayer2.${id}.*"
- ])
- ++ ext.own;
+ own = [
+ "${id}.*"
+ "org.mpris.MediaPlayer2.${id}.*"
+ ] ++ ext.own;
inherit (ext) call broadcast;
};
@@ -78,7 +94,7 @@ in
};
in
{
- session_bus = if app.dbus.session != null then (app.dbus.session (extendDBusDefault app.id)) else (extendDBusDefault app.id default);
+ session_bus = if app.dbus.session != null then (app.dbus.session (extendDBusDefault id)) else (extendDBusDefault id default);
system_bus = app.dbus.system;
};
command = if app.command == null then app.name else app.command;
@@ -87,8 +103,6 @@ in
isGraphical = if app.gpu != null then app.gpu else app.capability.wayland || app.capability.x11;
conf = {
- inherit (app) id;
-
path =
if app.path == null then
pkgs.writeScript "${app.name}-start" ''
@@ -99,16 +113,15 @@ in
app.path;
args = if app.args == null then [ "${app.name}-start" ] else app.args;
- inherit enablements;
+ inherit id enablements;
inherit (dbusConfig) session_bus system_bus;
direct_wayland = app.insecureWayland;
- username = getsubname fid aid;
- data = getsubhome fid aid;
+ username = getsubname fid app.identity;
+ data = getsubhome fid app.identity;
- identity = aid;
- inherit (app) groups;
+ inherit (app) identity groups;
container = {
inherit (app)
@@ -188,10 +201,9 @@ in
pkgs.writeShellScriptBin app.name ''
exec fortify${if app.verbose then " -v" else ""} app ${pkgs.writeText "fortify-${app.name}.json" (builtins.toJSON conf)} $@
''
- ) cfg.apps;
- in
- foldr (
- app: acc:
+ )
+ ]
+ ++ (
let
pkg = if app.share != null then app.share else pkgs.${app.name};
copy = source: "[ -d '${source}' ] && cp -Lrv '${source}' $out/share || true";
@@ -211,30 +223,33 @@ in
fi
''
)
- ++ acc
- ) (wrappers ++ [ cfg.package ]) cfg.apps;
+ )
+ ++ acc
+ ) [ cfg.package ] cfg.apps;
}) cfg.users;
in
{
useUserPackages = false; # prevent users.users entries from being added
- users = foldlAttrs (
- acc: _: fid:
- mkMerge [
- (mergeAttrsList (
- # aid 0 is reserved
- imap1 (aid: app: {
- ${getsubname fid aid} = mkMerge [
- cfg.extraHomeConfig
- app.extraConfig
- { home.packages = app.packages; }
- ];
- }) cfg.apps
- ))
- { ${getsubname fid 0} = cfg.extraHomeConfig; }
+ users = mkMerge (
+ foldlAttrs (
+ acc: _: fid:
acc
- ]
- ) privPackages cfg.users;
+ ++ foldlAttrs (
+ acc': _: app:
+ acc'
+ ++ [
+ {
+ ${getsubname fid app.identity} = mkMerge [
+ cfg.extraHomeConfig
+ app.extraConfig
+ { home.packages = app.packages; }
+ ];
+ }
+ ]
+ ) [ { ${getsubname fid 0} = cfg.extraHomeConfig; } ] cfg.apps
+ ) [ privPackages ] cfg.users
+ );
};
users =
@@ -250,33 +265,27 @@ in
getgroup = fid: aid: { gid = getsubuid fid aid; };
in
{
- users = foldlAttrs (
- acc: _: fid:
- mkMerge [
- (mergeAttrsList (
- # aid 0 is reserved
- imap1 (aid: _: {
- ${getsubname fid aid} = getuser fid aid;
- }) cfg.apps
- ))
- { ${getsubname fid 0} = getuser fid 0; }
+ users = mkMerge (
+ foldlAttrs (
+ acc: _: fid:
acc
- ]
- ) { } cfg.users;
+ ++ foldlAttrs (
+ acc': _: app:
+ acc' ++ [ { ${getsubname fid app.identity} = getuser fid app.identity; } ]
+ ) [ { ${getsubname fid 0} = getuser fid 0; } ] cfg.apps
+ ) [ ] cfg.users
+ );
- groups = foldlAttrs (
- acc: _: fid:
- mkMerge [
- (mergeAttrsList (
- # aid 0 is reserved
- imap1 (aid: _: {
- ${getsubname fid aid} = getgroup fid aid;
- }) cfg.apps
- ))
- { ${getsubname fid 0} = getgroup fid 0; }
+ groups = mkMerge (
+ foldlAttrs (
+ acc: _: fid:
acc
- ]
- ) { } cfg.users;
+ ++ foldlAttrs (
+ acc': _: app:
+ acc' ++ [ { ${getsubname fid app.identity} = getgroup fid app.identity; } ]
+ ) [ { ${getsubname fid 0} = getgroup fid 0; } ] cfg.apps
+ ) [ ] cfg.users
+ );
};
};
}
diff --git a/options.nix b/options.nix
index c8747f2d..29c9a4f9 100644
--- a/options.nix
+++ b/options.nix
@@ -76,6 +76,7 @@ in
type =
let
inherit (types)
+ ints
str
bool
package
@@ -87,7 +88,7 @@ in
functionTo
;
in
- listOf (submodule {
+ attrsOf (submodule {
options = {
name = mkOption {
type = str;
@@ -98,13 +99,13 @@ in
verbose = mkEnableOption "launchers with verbose output";
- id = mkOption {
- type = nullOr str;
- default = null;
+ identity = mkOption {
+ type = ints.between 1 9999;
description = ''
- Freedesktop application ID.
+ Application identity. Identity 0 is reserved for system services.
'';
};
+ shareUid = mkEnableOption "sharing identity with another application";
packages = mkOption {
type = listOf package;
@@ -273,7 +274,7 @@ in
};
};
});
- default = [ ];
+ default = { };
description = ''
Declaratively configured fortify apps.
'';
diff --git a/test/configuration.nix b/test/configuration.nix
index 6b3090cb..0bee0b2e 100644
--- a/test/configuration.nix
+++ b/test/configuration.nix
@@ -99,9 +99,10 @@
home.stateVersion = "23.05";
};
- apps = [
- {
+ apps = {
+ "cat.gensokyo.extern.foot.noEnablements" = {
name = "ne-foot";
+ identity = 1;
verbose = true;
share = pkgs.foot;
packages = with pkgs; [
@@ -115,17 +116,21 @@
dbus = false;
pulse = false;
};
- }
- {
+ };
+
+ "cat.gensokyo.extern.foot.pulseaudio" = {
name = "pa-foot";
+ identity = 2;
verbose = true;
share = pkgs.foot;
packages = [ pkgs.foot ];
command = "foot";
capability.dbus = false;
- }
- {
+ };
+
+ "cat.gensokyo.extern.Alacritty.x11" = {
name = "x11-alacritty";
+ identity = 3;
verbose = true;
share = pkgs.alacritty;
packages = with pkgs; [
@@ -142,9 +147,11 @@
dbus = false;
pulse = false;
};
- }
- {
+ };
+
+ "cat.gensokyo.extern.foot.directWayland" = {
name = "da-foot";
+ identity = 4;
verbose = true;
insecureWayland = true;
share = pkgs.foot;
@@ -159,9 +166,11 @@
dbus = false;
pulse = false;
};
- }
- {
+ };
+
+ "cat.gensokyo.extern.strace.wantFail" = {
name = "strace-failure";
+ identity = 5;
verbose = true;
share = pkgs.strace;
command = "strace true";
@@ -171,7 +180,7 @@
dbus = false;
pulse = false;
};
- }
- ];
+ };
+ };
};
}
diff --git a/test/sandbox/case/default.nix b/test/sandbox/case/default.nix
index d860b1e5..21bdd4a0 100644
--- a/test/sandbox/case/default.nix
+++ b/test/sandbox/case/default.nix
@@ -24,7 +24,7 @@ let
};
callTestCase =
- path:
+ path: identity:
let
tc = import path {
inherit
@@ -36,6 +36,7 @@ let
in
{
name = "check-sandbox-${tc.name}";
+ inherit identity;
verbose = true;
inherit (tc)
tty
@@ -51,10 +52,12 @@ let
(toString (builtins.toFile "fortify-${tc.name}-want.json" (builtins.toJSON tc.want)))
];
};
+
+ testCaseName = name: "cat.gensokyo.fortify.test." + name;
in
{
- preset = callTestCase ./preset.nix;
- tty = callTestCase ./tty.nix;
- mapuid = callTestCase ./mapuid.nix;
- device = callTestCase ./device.nix;
+ ${testCaseName "preset"} = callTestCase ./preset.nix 1;
+ ${testCaseName "tty"} = callTestCase ./tty.nix 2;
+ ${testCaseName "mapuid"} = callTestCase ./mapuid.nix 3;
+ ${testCaseName "device"} = callTestCase ./device.nix 4;
}
diff --git a/test/sandbox/configuration.nix b/test/sandbox/configuration.nix
index 903b99a3..473e9d3c 100644
--- a/test/sandbox/configuration.nix
+++ b/test/sandbox/configuration.nix
@@ -6,7 +6,6 @@
}:
let
testProgram = pkgs.callPackage ./tool/package.nix { inherit (config.environment.fortify.package) version; };
- testCases = import ./case lib testProgram;
in
{
users.users = {
@@ -76,11 +75,6 @@ in
}
];
- apps = with testCases; [
- preset
- tty
- mapuid
- device
- ];
+ apps = import ./case lib testProgram;
};
}