1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.programs.ydotool;
9in
10{
11 meta = {
12 maintainers = with lib.maintainers; [ quantenzitrone ];
13 };
14
15 options.programs.ydotool = {
16 enable = lib.mkEnableOption ''
17 ydotoold system service and {command}`ydotool` for members of
18 {option}`programs.ydotool.group`.
19 '';
20 group = lib.mkOption {
21 type = lib.types.str;
22 default = "ydotool";
23 description = ''
24 Group which users must be in to use {command}`ydotool`.
25 '';
26 };
27 };
28
29 config =
30 let
31 runtimeDirectory = "ydotoold";
32 in
33 lib.mkIf cfg.enable {
34 users.groups."${config.programs.ydotool.group}" = { };
35
36 systemd.services.ydotoold = {
37 description = "ydotoold - backend for ydotool";
38 wantedBy = [ "multi-user.target" ];
39 partOf = [ "multi-user.target" ];
40 serviceConfig = {
41 Group = config.programs.ydotool.group;
42 RuntimeDirectory = runtimeDirectory;
43 RuntimeDirectoryMode = "0750";
44 ExecStart = "${lib.getExe' pkgs.ydotool "ydotoold"} --socket-path=${config.environment.variables.YDOTOOL_SOCKET} --socket-perm=0660";
45
46 # hardening
47
48 ## allow access to uinput
49 DeviceAllow = [ "/dev/uinput" ];
50 DevicePolicy = "closed";
51
52 ## allow creation of unix sockets
53 RestrictAddressFamilies = [ "AF_UNIX" ];
54
55 CapabilityBoundingSet = "";
56 IPAddressDeny = "any";
57 LockPersonality = true;
58 MemoryDenyWriteExecute = true;
59 NoNewPrivileges = true;
60 PrivateNetwork = true;
61 PrivateTmp = true;
62 PrivateUsers = true;
63 ProcSubset = "pid";
64 ProtectClock = true;
65 ProtectControlGroups = true;
66 ProtectHome = true;
67 ProtectHostname = true;
68 ProtectKernelLogs = true;
69 ProtectKernelModules = true;
70 ProtectKernelTunables = true;
71 ProtectProc = "invisible";
72 ProtectSystem = "strict";
73 RestrictNamespaces = true;
74 RestrictRealtime = true;
75 RestrictSUIDSGID = true;
76 SystemCallArchitectures = "native";
77 SystemCallFilter = [
78 "@system-service"
79 "~@privileged"
80 "~@resources"
81 ];
82 UMask = "0077";
83
84 # -> systemd-analyze security score 0.7 SAFE 😀
85 };
86 };
87
88 environment.variables = {
89 YDOTOOL_SOCKET = "/run/${runtimeDirectory}/socket";
90 };
91 environment.systemPackages = with pkgs; [ ydotool ];
92 };
93}