diff --git a/README.md b/README.md index 34d80a6..e46bed5 100644 --- a/README.md +++ b/README.md @@ -148,4 +148,4 @@ Inspired by: [hjem](https://github.com/nix-community/hjem), [owl4ce](https://git ## License -MIT — use freely, credits appreciated. \ No newline at end of file +MIT — use freely, credits appreciated. diff --git a/flake.lock b/flake.lock index b0b6275..831d1a8 100644 --- a/flake.lock +++ b/flake.lock @@ -308,11 +308,32 @@ "nixos-24-05": "nixos-24-05", "nixpkgs": "nixpkgs", "nixpkgs-unstable": "nixpkgs-unstable", + "rustlock": "rustlock", "sops-nix": "sops-nix", "systems": "systems_3", "zen-browser": "zen-browser" } }, + "rustlock": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1782663473, + "narHash": "sha256-wPpiuL3EVvNb3+9QgRGtopZXbebb9uUs3Slwuigvh8w=", + "owner": "JorySeverijnse", + "repo": "rustlock", + "rev": "76039750623825172fbee93adae8bb48d4ad36ad", + "type": "github" + }, + "original": { + "owner": "JorySeverijnse", + "repo": "rustlock", + "type": "github" + } + }, "sops-nix": { "inputs": { "nixpkgs": [ diff --git a/flake.nix b/flake.nix index 70bf5a4..3d5c9eb 100644 --- a/flake.nix +++ b/flake.nix @@ -104,6 +104,11 @@ inputs.nixpkgs.follows = "nixpkgs"; }; + rustlock = { + url = "github:JorySeverijnse/rustlock"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-index-db = { url = "github:Mic92/nix-index-database"; inputs.nixpkgs.follows = "nixpkgs"; @@ -129,4 +134,4 @@ inputs.nixpkgs.follows = "nixos-24-05"; }; }; -} \ No newline at end of file +} diff --git a/home/packages/wayland/niri/_binds.nix b/home/packages/wayland/niri/_binds.nix index 8eaeec2..d50aa96 100644 --- a/home/packages/wayland/niri/_binds.nix +++ b/home/packages/wayland/niri/_binds.nix @@ -43,7 +43,7 @@ "Mod+B".spawn._args = ["zen"]; "Mod+Return".spawn._args = ["alacritty"]; "Mod+Q".close-window = {}; - "Mod+Shift+P".spawn._args = ["rofi-powermenu"]; + "Mod+Shift+P".spawn._args = ["rustlock" "--screenshots" "--clock" "--effect-blur" "7x5" "--effect-vignette" "0.5:0.5"]; "Mod+S".switch-preset-column-width = {}; "Mod+F".fullscreen-window = {}; "Mod+1".set-column-width = "25%"; diff --git a/home/terminal/software/git.nix b/home/terminal/software/git.nix index c3c036e..c11b1dc 100644 --- a/home/terminal/software/git.nix +++ b/home/terminal/software/git.nix @@ -10,34 +10,34 @@ # Hook that auto-generates a Conventional Commit message from staged diff prepareCommitMsg = pkgs.writeShellScript "prepare-commit-msg" '' - # Only run if there are staged changes - if git diff --cached --quiet 2>/dev/null; then - exit 0 - fi + # Only run if there are staged changes + if git diff --cached --quiet 2>/dev/null; then + exit 0 + fi - echo "Generating commit message from staged changes..." >&2 + echo "Generating commit message from staged changes..." >&2 - # Generate Conventional Commit message using opencode run - git diff --cached | timeout 30 ${pkgs.opencode}/bin/opencode run \ - -m opencode/north-mini-code-free \ - "You are an expert software engineer writing professional Git commit messages. + # Generate Conventional Commit message using opencode run + git diff --cached | timeout 30 ${pkgs.opencode}/bin/opencode run \ + -m opencode/north-mini-code-free \ + "You are an expert software engineer writing professional Git commit messages. -Create a clean Conventional Commit for the provided diff. + Create a clean Conventional Commit for the provided diff. -Rules: -- Format: type(optional scope): imperative description -- Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore -- First line: maximum 72 characters, starts with capital letter, imperative present tense -- If relevant, add a blank line followed by a short body explaining the motivation and key changes -- Be concise and professional. No emojis, no markdown. + Rules: + - Format: type(optional scope): imperative description + - Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore + - First line: maximum 72 characters, starts with capital letter, imperative present tense + - If relevant, add a blank line followed by a short body explaining the motivation and key changes + - Be concise and professional. No emojis, no markdown. -Output ONLY the commit message. Do not add any extra text, quotes, or explanations." \ - 2>/dev/null > "$1" + Output ONLY the commit message. Do not add any extra text, quotes, or explanations." \ + 2>/dev/null > "$1" - # Fallback if generation failed or timed out - if [ ! -s "$1" ]; then - echo "chore: auto-generated commit message" > "$1" - fi + # Fallback if generation failed or timed out + if [ ! -s "$1" ]; then + echo "chore: auto-generated commit message" > "$1" + fi ''; in { users.users.someone.packages = with pkgs; [ diff --git a/hosts/aesthetic/default.nix b/hosts/aesthetic/default.nix index be48dc2..8b4adb6 100644 --- a/hosts/aesthetic/default.nix +++ b/hosts/aesthetic/default.nix @@ -1,8 +1,8 @@ { config, - inputs, lib, pkgs, + inputs, ... }: { imports = [ @@ -172,19 +172,40 @@ sops = { defaultSopsFile = ./../../secrets/secrets.yaml; secrets = { - gitea_laptop = { owner = "someone"; group = "users"; mode = "0400"; }; - github_laptop = { owner = "someone"; group = "users"; mode = "0400"; }; - hetzner_server = { owner = "someone"; group = "users"; mode = "0400"; }; + gitea_laptop = { + owner = "someone"; + group = "users"; + mode = "0400"; + }; + github_laptop = { + owner = "someone"; + group = "users"; + mode = "0400"; + }; + hetzner_server = { + owner = "someone"; + group = "users"; + mode = "0400"; + }; }; }; nixpkgs.config.allowUnfree = true; nixpkgs.overlays = [ - (self: super: { + (_self: super: { cisco-secure-client = super.callPackage ../../pkgs/cisco-secure-client {}; }) ]; - environment.systemPackages = [pkgs.cryptsetup pkgs.age pkgs.nixd pkgs.apparmor-parser pkgs.xdg-desktop-portal-wlr]; + security.pam.services.rustlock.text = "auth include login"; + + environment.systemPackages = with pkgs; [ + cryptsetup + age + nixd + apparmor-parser + xdg-desktop-portal-wlr + inputs.rustlock.packages.${pkgs.stdenv.hostPlatform.system}.default + ]; } diff --git a/hosts/aesthetic/disko-config.nix b/hosts/aesthetic/disko-config.nix index 55aa2a3..3ec0415 100644 --- a/hosts/aesthetic/disko-config.nix +++ b/hosts/aesthetic/disko-config.nix @@ -29,4 +29,4 @@ }; }; }; -} \ No newline at end of file +} diff --git a/hosts/default.nix b/hosts/default.nix index b2207e6..132f3ae 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -5,7 +5,6 @@ }: let # shorten paths inherit (inputs.nixpkgs.lib) nixosSystem; - lib = inputs.nixpkgs.lib; # Server uses its own pinned 24.05 nixpkgs (kept isolated from the laptop's unstable) nixosSystem24 = inputs.nixos-24-05.lib.nixosSystem; unstablePkgs = import inputs.nixpkgs-unstable {system = "x86_64-linux";}; @@ -60,7 +59,7 @@ in { ++ sharedModules ++ [ "${mod}/services/location.nix" - ({ config, ... }: { + ({...}: { boot.loader.limine.bootMode = "uefi"; }) ]; @@ -74,7 +73,7 @@ in { ++ sharedModules ++ [ "${mod}/services/location.nix" - ({ config, ... }: { + ({...}: { boot.loader.limine.bootMode = "bios"; boot.loader.limine.biosDevice = "/dev/nvme0n1"; }) diff --git a/pkgs/cisco-secure-client/default.nix b/pkgs/cisco-secure-client/default.nix index 6f8804c..adf0e8d 100644 --- a/pkgs/cisco-secure-client/default.nix +++ b/pkgs/cisco-secure-client/default.nix @@ -1,8 +1,18 @@ -{ lib, stdenv, fetchurl, dpkg, makeWrapper, patchelf -, coreutils, systemd, glib, zlib, xz, curl, libxml2 -}: - -let +{ + lib, + stdenv, + fetchurl, + dpkg, + makeWrapper, + patchelf, + coreutils, + systemd, + glib, + zlib, + xz, + curl, + libxml2, +}: let version = "5.1.17.3394"; # libxml2's "out" output has lib/libxml2.so.16 libxml2_out = libxml2.out; @@ -10,117 +20,130 @@ let # System library RPATH for all bundled ELF binaries (cisco's own lib dir is # appended during fixupPhase via $out) sysRpath = lib.makeLibraryPath [ - systemd glib zlib xz stdenv.cc.cc.lib curl libxml2_out + systemd + glib + zlib + xz + stdenv.cc.cc.lib + curl + libxml2_out ]; -in stdenv.mkDerivation { - pname = "cisco-secure-client"; - inherit version; +in + stdenv.mkDerivation { + pname = "cisco-secure-client"; + inherit version; - src = fetchurl { - url = "https://archive.org/download/cisco-secure-client-linux64-${version}/cisco-secure-client-linux64-${version}-predeploy-deb-k9.tgz"; - sha256 = "5c4cafb4694e64cbf041481f5df3d70389399926f8aa2a469d480c0555b58c2c"; - }; - - nativeBuildInputs = [ dpkg makeWrapper patchelf ]; - - buildInputs = [ - systemd glib zlib xz stdenv.cc.cc.lib curl libxml2_out - ]; - - dontStrip = true; - dontAutoPatchelf = true; - - unpackPhase = '' - tar xzf "$src" - DEB_FILE=$(ls cisco-secure-client-vpn-cli_*_amd64.deb 2>/dev/null || true) - if [ -z "$DEB_FILE" ]; then - DEB_FILE=$(ls cisco-secure-client-vpn_*_amd64.deb 2>/dev/null || true) - fi - if [ -z "$DEB_FILE" ]; then - echo "ERROR: No .deb file found" - exit 1 - fi - dpkg-deb -x "$DEB_FILE" . - ''; - - installPhase = '' - runHook preInstall - mkdir -p "$out" - cp -r opt/* "$out/" - runHook postInstall - ''; - - # fixupPhase: patchelf corrupts Cisco's embedded code signatures on ALL - # shipped ELF binaries and .so plugins. We skip patchelf entirely and - # instead rely on LD_LIBRARY_PATH wrappers for system library resolution. - # The binaries' original RPATH of /opt/cisco/secureclient/lib resolves - # correctly at runtime via the /opt/cisco/secureclient -> store symlink. - fixupPhase = '' - runHook preFixup - - # Fix absolute symlinks — the deb assumes install under /opt/cisco/secureclient/ - # but nix puts it in the store. Convert to relative symlinks. - for link in $(find "$out" -type l); do - target=$(readlink "$link") - if echo "$target" | grep -q "^/opt/"; then - rel=$(basename "$target") - ln -sf "$rel" "$link" - fi - done - - for f in "$out"/cisco/secureclient/bin/* "$out"/cisco/secureclient/lib/*.so*; do - chmod +x "$f" 2>/dev/null || true - done - - # Create libxml2.so.2 symlink (SONAME mismatch: Cisco wants .2, nixpkgs provides .16) - libxml2_so=$(find ${libxml2_out}/lib -name "libxml2.so.16*" 2>/dev/null | head -1) - if [ -n "$libxml2_so" ]; then - ln -sf "$libxml2_so" "$out/cisco/secureclient/lib/libxml2.so.2" - fi - - # NO patchelf on Cisco ELFs — their embedded code signatures are - # verified at runtime (especially plugins loaded by vpnagentd). - # All ELFs keep their original RPATH /opt/cisco/secureclient/lib - # which resolves via the tmpfiles symlink. - # System libs are provided via LD_LIBRARY_PATH in wrappers below. - - ldPath="$out/cisco/secureclient/lib:${sysRpath}" - - # Wrap vpn CLI — wrapProgram renames the original to .vpn-wrapped - wrapProgram "$out/cisco/secureclient/bin/vpn" \ - --prefix LD_LIBRARY_PATH : "$ldPath" \ - --prefix PATH : ${lib.makeBinPath [ coreutils ]} - - # Create $out/bin/ wrappers for all user-facing executables - mkdir -p "$out/bin" - - makeWrapper "$out/cisco/secureclient/bin/vpn" "$out/bin/vpn" \ - --prefix LD_LIBRARY_PATH : "$ldPath" \ - --prefix PATH : ${lib.makeBinPath [ coreutils ]} - - makeWrapper "$out/cisco/secureclient/bin/vpnagentd" "$out/bin/vpnagentd" \ - --prefix LD_LIBRARY_PATH : "$ldPath" \ - --prefix PATH : ${lib.makeBinPath [ coreutils ]} - - for cli in acinstallhelper manifesttool_vpn vpndownloader-cli; do - if [ -f "$out/cisco/secureclient/bin/$cli" ]; then - makeWrapper "$out/cisco/secureclient/bin/$cli" "$out/bin/$cli" \ - --prefix LD_LIBRARY_PATH : "$ldPath" - fi - done - - runHook postFixup - ''; - - meta = with lib; { - description = "Cisco Secure Client (AnyConnect successor) VPN client"; - homepage = "https://www.cisco.com/site/us/en/products/security/secure-client/index.html"; - sourceProvenance = with sourceTypes; [ binaryNativeCode ]; - license = { - name = "Cisco Secure Client EULA — proprietary, not redistributable"; - url = "https://www.cisco.com/c/en/us/products/security/secure-client/eula.html"; + src = fetchurl { + url = "https://archive.org/download/cisco-secure-client-linux64-${version}/cisco-secure-client-linux64-${version}-predeploy-deb-k9.tgz"; + sha256 = "5c4cafb4694e64cbf041481f5df3d70389399926f8aa2a469d480c0555b58c2c"; }; - platforms = [ "x86_64-linux" ]; - maintainers = [ ]; - }; -} + + nativeBuildInputs = [dpkg makeWrapper patchelf]; + + buildInputs = [ + systemd + glib + zlib + xz + stdenv.cc.cc.lib + curl + libxml2_out + ]; + + dontStrip = true; + dontAutoPatchelf = true; + + unpackPhase = '' + tar xzf "$src" + DEB_FILE=$(ls cisco-secure-client-vpn-cli_*_amd64.deb 2>/dev/null || true) + if [ -z "$DEB_FILE" ]; then + DEB_FILE=$(ls cisco-secure-client-vpn_*_amd64.deb 2>/dev/null || true) + fi + if [ -z "$DEB_FILE" ]; then + echo "ERROR: No .deb file found" + exit 1 + fi + dpkg-deb -x "$DEB_FILE" . + ''; + + installPhase = '' + runHook preInstall + mkdir -p "$out" + cp -r opt/* "$out/" + runHook postInstall + ''; + + # fixupPhase: patchelf corrupts Cisco's embedded code signatures on ALL + # shipped ELF binaries and .so plugins. We skip patchelf entirely and + # instead rely on LD_LIBRARY_PATH wrappers for system library resolution. + # The binaries' original RPATH of /opt/cisco/secureclient/lib resolves + # correctly at runtime via the /opt/cisco/secureclient -> store symlink. + fixupPhase = '' + runHook preFixup + + # Fix absolute symlinks — the deb assumes install under /opt/cisco/secureclient/ + # but nix puts it in the store. Convert to relative symlinks. + for link in $(find "$out" -type l); do + target=$(readlink "$link") + if echo "$target" | grep -q "^/opt/"; then + rel=$(basename "$target") + ln -sf "$rel" "$link" + fi + done + + for f in "$out"/cisco/secureclient/bin/* "$out"/cisco/secureclient/lib/*.so*; do + chmod +x "$f" 2>/dev/null || true + done + + # Create libxml2.so.2 symlink (SONAME mismatch: Cisco wants .2, nixpkgs provides .16) + libxml2_so=$(find ${libxml2_out}/lib -name "libxml2.so.16*" 2>/dev/null | head -1) + if [ -n "$libxml2_so" ]; then + ln -sf "$libxml2_so" "$out/cisco/secureclient/lib/libxml2.so.2" + fi + + # NO patchelf on Cisco ELFs — their embedded code signatures are + # verified at runtime (especially plugins loaded by vpnagentd). + # All ELFs keep their original RPATH /opt/cisco/secureclient/lib + # which resolves via the tmpfiles symlink. + # System libs are provided via LD_LIBRARY_PATH in wrappers below. + + ldPath="$out/cisco/secureclient/lib:${sysRpath}" + + # Wrap vpn CLI — wrapProgram renames the original to .vpn-wrapped + wrapProgram "$out/cisco/secureclient/bin/vpn" \ + --prefix LD_LIBRARY_PATH : "$ldPath" \ + --prefix PATH : ${lib.makeBinPath [coreutils]} + + # Create $out/bin/ wrappers for all user-facing executables + mkdir -p "$out/bin" + + makeWrapper "$out/cisco/secureclient/bin/vpn" "$out/bin/vpn" \ + --prefix LD_LIBRARY_PATH : "$ldPath" \ + --prefix PATH : ${lib.makeBinPath [coreutils]} + + makeWrapper "$out/cisco/secureclient/bin/vpnagentd" "$out/bin/vpnagentd" \ + --prefix LD_LIBRARY_PATH : "$ldPath" \ + --prefix PATH : ${lib.makeBinPath [coreutils]} + + for cli in acinstallhelper manifesttool_vpn vpndownloader-cli; do + if [ -f "$out/cisco/secureclient/bin/$cli" ]; then + makeWrapper "$out/cisco/secureclient/bin/$cli" "$out/bin/$cli" \ + --prefix LD_LIBRARY_PATH : "$ldPath" + fi + done + + runHook postFixup + ''; + + meta = with lib; { + description = "Cisco Secure Client (AnyConnect successor) VPN client"; + homepage = "https://www.cisco.com/site/us/en/products/security/secure-client/index.html"; + sourceProvenance = with sourceTypes; [binaryNativeCode]; + license = { + name = "Cisco Secure Client EULA — proprietary, not redistributable"; + url = "https://www.cisco.com/c/en/us/products/security/secure-client/eula.html"; + }; + platforms = ["x86_64-linux"]; + maintainers = []; + }; + } diff --git a/servers/hetzner/hosts/hetzner/default.nix b/servers/hetzner/hosts/hetzner/default.nix index 0984966..b61b465 100644 --- a/servers/hetzner/hosts/hetzner/default.nix +++ b/servers/hetzner/hosts/hetzner/default.nix @@ -22,5 +22,11 @@ ../../modules/services/backup.nix ]; + # Only 4GB RAM — limit nix builds to one core at a time to avoid OOM + nix.settings = { + cores = 1; + max-jobs = 1; + }; + system.stateVersion = "24.05"; } diff --git a/servers/hetzner/hosts/hetzner/hardware.nix b/servers/hetzner/hosts/hetzner/hardware.nix index 3e8987d..bb41dd5 100644 --- a/servers/hetzner/hosts/hetzner/hardware.nix +++ b/servers/hetzner/hosts/hetzner/hardware.nix @@ -17,7 +17,7 @@ swapDevices = [ { device = "/swap"; - size = 2048; + size = 8192; } ]; diff --git a/statix.toml b/statix.toml index 519e4d3..9528602 100644 --- a/statix.toml +++ b/statix.toml @@ -1 +1 @@ -disabled = ["empty_pattern"] +disabled = ["empty_pattern", "repeated_keys"] diff --git a/system/hardware/fingerprint.nix b/system/hardware/fingerprint.nix index 082e786..7ddb47f 100644 --- a/system/hardware/fingerprint.nix +++ b/system/hardware/fingerprint.nix @@ -1,5 +1,8 @@ -{ config, lib, pkgs, ... }: - +{ + config, + lib, + ... +}: # Fingerprint scanner configuration # # Enable on laptops with a fingerprint reader: @@ -10,7 +13,6 @@ # hardware.fingerprint.todDriver = pkgs.libfprint-2-tod1-goodix; # # Reference: https://wiki.nixos.org/wiki/Fingerprint_scanner - let cfg = config.hardware.fingerprint; in { diff --git a/work/cisco.nix b/work/cisco.nix index 2cd292a..fa0889e 100644 --- a/work/cisco.nix +++ b/work/cisco.nix @@ -1,5 +1,9 @@ -{ config, lib, pkgs, self, ... }: - +{ + config, + lib, + pkgs, + ... +}: # Cisco Secure Client (proprietary VPN client, successor to AnyConnect) # # Package: pkgs/cisco-secure-client — fetches the Linux pre-deployment .tgz @@ -11,14 +15,15 @@ # }); # # Reference: https://github.com/NixOS/nixpkgs/issues/265443 - let cfg = config.work.cisco; in { options.work.cisco = { - enable = lib.mkEnableOption "Cisco Secure Client" // { - default = false; - }; + enable = + lib.mkEnableOption "Cisco Secure Client" + // { + default = false; + }; package = lib.mkOption { description = "cisco-secure-client package to use"; @@ -41,14 +46,14 @@ in { ]; # Load the tun module required by the VPN client - boot.kernelModules = [ "tun" ]; + boot.kernelModules = ["tun"]; systemd.services.cisco-vpnagentd = { description = "Cisco Secure Client VPN Agent Daemon"; # vpnagentd daemonizes itself; tracked via PID file. - after = [ "network-online.target" "NetworkManager.service" ]; - wants = [ "network-online.target" ]; - wantedBy = [ "multi-user.target" ]; + after = ["network-online.target" "NetworkManager.service"]; + wants = ["network-online.target"]; + wantedBy = ["multi-user.target"]; serviceConfig = { Type = "forking"; @@ -81,7 +86,7 @@ in { "CAP_CHOWN" "CAP_FOWNER" ]; - DeviceAllow = [ "/dev/net/tun rw" ]; + DeviceAllow = ["/dev/net/tun rw"]; PrivateTmp = true; ProtectSystem = "full"; ProtectHome = false; diff --git a/work/default.nix b/work/default.nix index 26c7a5a..094a107 100644 --- a/work/default.nix +++ b/work/default.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: { +{...}: { imports = [ ./overlay.nix ./cisco.nix diff --git a/work/himmelblau.nix b/work/himmelblau.nix index 01258ea..9692eac 100644 --- a/work/himmelblau.nix +++ b/work/himmelblau.nix @@ -1,5 +1,10 @@ -{ config, lib, pkgs, inputs, ... }: - +{ + config, + lib, + pkgs, + inputs, + ... +}: # Himmelblau: Microsoft Entra ID authentication for Linux # # Authenticates Linux users against the digistate.nl Entra ID tenant. @@ -14,7 +19,6 @@ # References: # - https://himmelblau-idm.org/docs/ # - https://github.com/himmelblau-idm/himmelblau - let cfg = config.work.himmelblau; in { @@ -23,16 +27,18 @@ in { ]; options.work.himmelblau = { - enable = lib.mkEnableOption "Himmelblau Entra ID authentication" // { - default = false; - }; + enable = + lib.mkEnableOption "Himmelblau Entra ID authentication" + // { + default = false; + }; }; config = lib.mkIf cfg.enable { services.himmelblau = { enable = true; settings = { - domain = [ "digistate.nl" ]; + domain = ["digistate.nl"]; # Uncomment and set to Entra ID group Object IDs or names to # restrict which users can authenticate: # pam_allow_groups = [ "ENTRA-GROUP-GUID-HERE" ]; diff --git a/work/mdatp.nix b/work/mdatp.nix index a81e021..96f4f09 100644 --- a/work/mdatp.nix +++ b/work/mdatp.nix @@ -1,10 +1,13 @@ -{ config, lib, pkgs, inputs, ... }: - +{ + config, + lib, + inputs, + ... +}: # Microsoft Defender for Endpoint # # References: # - https://github.com/epetousis/nix-mdatp - let cfg = config.work.mdatp; in { diff --git a/work/overlay.nix b/work/overlay.nix index 2f577a0..6affa87 100644 --- a/work/overlay.nix +++ b/work/overlay.nix @@ -1,9 +1,8 @@ -{ config, lib, pkgs, ... }: -{ +{...}: { # Overlay to add cisco-secure-client to pkgs nixpkgs.overlays = [ - (self: super: { + (_self: super: { cisco-secure-client = super.callPackage ./pkgs/cisco-secure-client {}; }) ]; -} \ No newline at end of file +}