{ config, lib, pkgs, ... }: with lib; let portSpec = name: '' port ${name} type pipe protocol e reliable true command ${pkgs.openssh}/bin/ssh -x -o batchmode=yes ${name} ''; sysSpec = name: '' system ${name} time Any port ${name} chat "" protocol e ''; permissions = set: name: let commands = set."${name}"; in '' MACHINE=${name} COMMANDS=${concatStringsSep ":" commands} ''; in { options = { services.uucp = { enable = mkOption { type = types.bool; default = false; description = '' If enabled we set up an account accesible via uucp over ssh ''; }; nodeName = mkOption { type = types.str; default = "nixos"; description = "uucp node name"; }; sshUser = mkOption { type = types.attrs; default = {}; description = "Overrides for the local uucp linux-user"; }; sshConfig = mkOption { type = types.str; default = ""; description = "~uucp/.ssh/config"; }; remoteNodes = mkOption { type = types.attrsOf (types.listOf types.str); default = {}; description = '' Ports to set up Names will probably need to be configured in sshConfig Values are permitted commands ''; }; spoolDir = mkOption { type = types.path; default = "/var/spool/uucp"; description = "Spool directory"; }; lockDir = mkOption { type = types.path; default = "/var/spool/uucp"; description = "Lock directory"; }; pubDir = mkOption { type = types.path; default = "/var/spool/uucppublic"; description = "Public directory"; }; logFile = mkOption { type = types.path; default = "/var/log/uucp"; description = "Log file"; }; statFile = mkOption { type = types.path; default = "/var/log/uucp.stat"; description = "Statistics file"; }; debugFile = mkOption { type = types.path; default = "/var/log/uucp.debug"; description = "Debug file"; }; extraConfig = mkOption { type = types.string; default = ""; description = "Extra configuration to append verbatim to `/etc/uucp/config'"; }; }; }; config = mkIf config.services.uucp.enable { environment.etc."uucp/config" = { text = '' hostname ${config.services.uucp.nodeName} spool ${config.services.uucp.spoolDir} lockdir ${config.services.uucp.lockDir} pubdir ${config.services.uucp.pubDir} logfile ${config.services.uucp.logFile} statfile ${config.services.uucp.statFile} debugfile ${config.services.uucp.debugFile} ${config.services.uucp.extraConfig} ''; }; users.users."uucp" = { name = "uucp"; isSystemUser = true; isNormalUser = false; createHome = true; home = config.services.uucp.spoolDir; description = "User for uucp over ssh"; useDefaultShell = true; } // config.services.uucp.sshUser; system.activationScripts."uucp-sshconfig" = '' mkdir -p ${config.users.users."uucp".home}/.ssh chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.users.users."uucp".home}/.ssh chmod 700 ${config.users.users."uucp".home}/.ssh ln -fs ${builtins.toFile "ssh-config" config.services.uucp.sshConfig} ${config.users.users."uucp".home}/.ssh/config ''; system.activationScripts."uucp-logs" = '' touch ${config.services.uucp.logFile} chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.services.uucp.logFile} chmod 644 ${config.services.uucp.logFile} touch ${config.services.uucp.statFile} chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.services.uucp.statFile} chmod 644 ${config.services.uucp.statFile} touch ${config.services.uucp.debugFile} chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.services.uucp.debugFile} chmod 644 ${config.services.uucp.debugFile} ''; environment.etc."uucp/port" = { text = '' port ssh type stdin protocol e '' + concatStringsSep "\n" (map portSpec (builtins.attrNames config.services.uucp.remoteNodes)); }; environment.etc."uucp/sys" = { text = concatStringsSep "\n" (map sysSpec (builtins.attrNames config.services.uucp.remoteNodes)); }; environment.etc."uucp/Permissions" = { text = concatStringsSep "\n" (map (permissions config.services.uucp.remoteNodes) (builtins.attrNames config.services.uucp.remoteNodes)); }; security.setuidOwners = map (p: {program = p; owner = "root"; group = "root"; setuid = true; setgid = false;}) ["uucico" "uuxqt" "cu" "uucp" "uuname" "uustat" "uux"]; nixpkgs.config.packageOverrides = pkgs: with pkgs; { uucp = stdenv.lib.overrideDerivation uucp (oldAttrs: { configureFlags = "--with-newconfigdir=/etc/uucp"; }); rmail = stdenv.mkDerivation { name = "rmail"; src = pkgs.writeScript "rmail" '' #!${pkgs.stdenv.shell} # Dummy UUCP rmail command for postfix/qmail systems IFS=" " read junk from junk junk junk junk junk junk junk relay case "$from" in *[@!]*) ;; *) from="$from@$relay";; esac exec /var/setuid-wrappers/sendmail -i -f "$from" -- "$@" ''; builder = pkgs.writeScript "builder" '' #!${stdenv.shell} ln -s ${src} $out ''; }; }; environment.systemPackages = with pkgs; [ uucp ]; }; }