mirror of
https://github.com/LnL7/nix-darwin.git
synced 2025-03-31 04:04:45 +00:00
Merge 5776f9bf3d
into 53d0f0ed11
This commit is contained in:
commit
18d402a9ef
6 changed files with 185 additions and 10 deletions
|
@ -8,6 +8,7 @@
|
||||||
./security/pki
|
./security/pki
|
||||||
./security/sandbox
|
./security/sandbox
|
||||||
./security/sudo.nix
|
./security/sudo.nix
|
||||||
|
./security/wrappers
|
||||||
./system
|
./system
|
||||||
./system/base.nix
|
./system/base.nix
|
||||||
./system/checks.nix
|
./system/checks.nix
|
||||||
|
|
176
modules/security/wrappers/default.nix
Normal file
176
modules/security/wrappers/default.nix
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.security;
|
||||||
|
|
||||||
|
parentWrapperDir = dirOf cfg.wrapperDir;
|
||||||
|
|
||||||
|
wrapperType = lib.types.submodule ({ name, config, ... }: {
|
||||||
|
options = with lib; {
|
||||||
|
source = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
description = "The absolute path to the program to be wrapped.";
|
||||||
|
};
|
||||||
|
program = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = name;
|
||||||
|
description = "The name of the wrapper program. Defaults to the attribute name.";
|
||||||
|
};
|
||||||
|
owner = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The owner of the wrapper program.";
|
||||||
|
};
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The group of the wrapper program.";
|
||||||
|
};
|
||||||
|
permissions = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "u+rx,g+x,o+x";
|
||||||
|
description = "The permissions to set on the wrapper.";
|
||||||
|
};
|
||||||
|
setuid = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to add the setuid bit to the wrapper program.";
|
||||||
|
};
|
||||||
|
setgid = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to add the setgid bit to the wrapper program.";
|
||||||
|
};
|
||||||
|
# codesign = mkOption {
|
||||||
|
# type = types.bool;
|
||||||
|
# default = false;
|
||||||
|
# description = "Whether to codesign the wrapper program.";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
mkWrappedPrograms =
|
||||||
|
builtins.map
|
||||||
|
(opts: mkWrapper opts)
|
||||||
|
(builtins.attrValues cfg.wrappers);
|
||||||
|
|
||||||
|
mkWrapper =
|
||||||
|
{ program
|
||||||
|
, source
|
||||||
|
, owner
|
||||||
|
, group
|
||||||
|
, permissions
|
||||||
|
, setuid
|
||||||
|
, setgid
|
||||||
|
, codesign ? false
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
codesigned = if codesign
|
||||||
|
then ''
|
||||||
|
# codesign ${source} to "$wrapperDir/${program}" INSTEAD OF the next line
|
||||||
|
cp ${source} "$wrapperDir/${program}"
|
||||||
|
''
|
||||||
|
else ''
|
||||||
|
cp ${source} "$wrapperDir/${program}"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
''
|
||||||
|
${codesigned}
|
||||||
|
|
||||||
|
# Prevent races
|
||||||
|
chmod 0000 "$wrapperDir/${program}"
|
||||||
|
chown ${owner}:${group} "$wrapperDir/${program}"
|
||||||
|
|
||||||
|
chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" "$wrapperDir/${program}"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# probably not necessary since these options never existed in nix-darwin?
|
||||||
|
imports = [
|
||||||
|
(lib.mkRemovedOptionModule [ "security" "setuidOwners" ] "Use security.wrappers instead")
|
||||||
|
(lib.mkRemovedOptionModule [ "security" "setuidPrograms" ] "Use security.wrappers instead")
|
||||||
|
];
|
||||||
|
|
||||||
|
meta.maintainers = [
|
||||||
|
lib.maintainers.samasaur or "samasaur"
|
||||||
|
];
|
||||||
|
|
||||||
|
###### interface
|
||||||
|
options.security = {
|
||||||
|
wrappers = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf wrapperType;
|
||||||
|
default = {};
|
||||||
|
example = lib.literalExpression
|
||||||
|
''
|
||||||
|
{
|
||||||
|
# a setuid root program
|
||||||
|
doas =
|
||||||
|
{ setuid = true;
|
||||||
|
owner = "root";
|
||||||
|
group = "wheel";
|
||||||
|
source = "''${pkgs.doas}/bin/doas";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# a setgid program
|
||||||
|
locate =
|
||||||
|
{ setgid = true;
|
||||||
|
owner = "root";
|
||||||
|
group = "mlocate";
|
||||||
|
source = "''${pkgs.locate}/bin/locate";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
This option effectively allows adding setuid/setgid bits and/or changing
|
||||||
|
file ownership and permissions without directly modifying it. This works
|
||||||
|
by creating a wrapper program under the {option}`security.wrapperDir`
|
||||||
|
directory, which is then added to the shell `PATH`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
wrapperDir = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/run/wrappers/bin";
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
This option defines the path to the wrapper programs. It
|
||||||
|
should not be overridden.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# codesignIdentity = lib.mkOption {
|
||||||
|
# type = lib.types.str;
|
||||||
|
# default = "-";
|
||||||
|
# description = "Identity to use for codesigning.";
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
config = {
|
||||||
|
environment.extraInit = ''
|
||||||
|
# Wrappers override other bin directories.
|
||||||
|
export PATH="${cfg.wrapperDir}:$PATH"
|
||||||
|
'';
|
||||||
|
|
||||||
|
system.activationScripts.wrappers.text = ''
|
||||||
|
echo "setting up wrappers..." >&2
|
||||||
|
if ! test -e /run/wrappers; then mkdir /run/wrappers; fi
|
||||||
|
|
||||||
|
# We want to place the tmpdirs for the wrappers to the parent dir.
|
||||||
|
wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX)
|
||||||
|
chmod a+rx "$wrapperDir"
|
||||||
|
|
||||||
|
${builtins.concatStringsSep "\n" mkWrappedPrograms}
|
||||||
|
|
||||||
|
if test -L ${cfg.wrapperDir}; then
|
||||||
|
# Atomically replace the symlink
|
||||||
|
# See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
|
||||||
|
old=$(readlink -f ${cfg.wrapperDir})
|
||||||
|
ln --symbolic --force --no-dereference "$wrapperDir" ${cfg.wrapperDir}-tmp
|
||||||
|
mv --no-target-directory ${cfg.wrapperDir}-tmp ${cfg.wrapperDir}
|
||||||
|
rm --force --recursive "$old"
|
||||||
|
else
|
||||||
|
# For initial setup
|
||||||
|
ln --symbolic "$wrapperDir" ${cfg.wrapperDir}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
${config.system.activationScripts.etcChecks.text}
|
${config.system.activationScripts.etcChecks.text}
|
||||||
${config.system.activationScripts.etc.text}
|
${config.system.activationScripts.etc.text}
|
||||||
${config.system.activationScripts.keyboard.text}
|
${config.system.activationScripts.keyboard.text}
|
||||||
|
${config.system.activationScripts.wrappers.text}
|
||||||
'';
|
'';
|
||||||
serviceConfig.RunAtLoad = true;
|
serviceConfig.RunAtLoad = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,16 +86,11 @@ in
|
||||||
serviceConfig.RunAtLoad = true;
|
serviceConfig.RunAtLoad = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# We need this to run every reboot as /run gets nuked so we can't put this
|
security.wrappers.karabiner_session_monitor = {
|
||||||
# inside the preActivation script as it only gets run on darwin-rebuild switch.
|
setuid = true;
|
||||||
launchd.daemons.setsuid_karabiner_session_monitor = {
|
owner = "root";
|
||||||
script = ''
|
group = "wheel";
|
||||||
rm -rf /run/wrappers
|
source = "${pkgs.karabiner-elements}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor";
|
||||||
mkdir -p /run/wrappers/bin
|
|
||||||
install -m4555 "${cfg.package}/Library/Application Support/org.pqrs/Karabiner-Elements/bin/karabiner_session_monitor" /run/wrappers/bin
|
|
||||||
'';
|
|
||||||
serviceConfig.RunAtLoad = true;
|
|
||||||
serviceConfig.KeepAlive.SuccessfulExit = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
launchd.user.agents.karabiner_session_monitor = {
|
launchd.user.agents.karabiner_session_monitor = {
|
||||||
|
|
|
@ -96,6 +96,7 @@ in
|
||||||
${cfg.activationScripts.keyboard.text}
|
${cfg.activationScripts.keyboard.text}
|
||||||
${cfg.activationScripts.fonts.text}
|
${cfg.activationScripts.fonts.text}
|
||||||
${cfg.activationScripts.nvram.text}
|
${cfg.activationScripts.nvram.text}
|
||||||
|
${cfg.activationScripts.wrappers.text}
|
||||||
|
|
||||||
${cfg.activationScripts.postActivation.text}
|
${cfg.activationScripts.postActivation.text}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ with lib;
|
||||||
env_path=$(bash -c 'source ${config.system.build.setEnvironment}; echo $PATH')
|
env_path=$(bash -c 'source ${config.system.build.setEnvironment}; echo $PATH')
|
||||||
|
|
||||||
test "$env_path" = "${builtins.concatStringsSep ":" [
|
test "$env_path" = "${builtins.concatStringsSep ":" [
|
||||||
|
"/run/wrappers/bin"
|
||||||
"beforePath"
|
"beforePath"
|
||||||
"myPath"
|
"myPath"
|
||||||
"beforeProfile/bin"
|
"beforeProfile/bin"
|
||||||
|
|
Loading…
Add table
Reference in a new issue