diff --git a/nixos/modules/config/gnu.nix b/nixos/modules/config/gnu.nix index 5cc41ce8690f..f8c35b440d12 100644 --- a/nixos/modules/config/gnu.nix +++ b/nixos/modules/config/gnu.nix @@ -9,7 +9,8 @@ with lib; default = false; description = '' When enabled, GNU software is chosen by default whenever a there is - a choice between GNU and non-GNU software. + a choice between GNU and non-GNU software (e.g., GNU lsh + vs. OpenSSH). ''; }; }; @@ -32,6 +33,12 @@ with lib; boot.loader.grub.enable = !pkgs.stdenv.isArm; boot.loader.grub.version = 2; + # GNU lsh. + services.openssh.enable = false; + services.lshd.enable = true; + programs.ssh.startAgent = false; + services.xserver.startGnuPGAgent = true; + # TODO: GNU dico. # TODO: GNU Inetutils' inetd. # TODO: GNU Pies. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 10307b159cd4..eb89ff83e2ce 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -404,6 +404,7 @@ ./services/networking/softether.nix ./services/networking/spiped.nix ./services/networking/sslh.nix + ./services/networking/ssh/lshd.nix ./services/networking/ssh/sshd.nix ./services/networking/strongswan.nix ./services/networking/supplicant.nix diff --git a/nixos/modules/services/networking/ssh/lshd.nix b/nixos/modules/services/networking/ssh/lshd.nix new file mode 100644 index 000000000000..661a6a524631 --- /dev/null +++ b/nixos/modules/services/networking/ssh/lshd.nix @@ -0,0 +1,176 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + inherit (pkgs) lsh; + + cfg = config.services.lshd; + +in + +{ + + ###### interface + + options = { + + services.lshd = { + + enable = mkOption { + default = false; + description = '' + Whether to enable the GNU lshd SSH2 daemon, which allows + secure remote login. + ''; + }; + + portNumber = mkOption { + default = 22; + description = '' + The port on which to listen for connections. + ''; + }; + + interfaces = mkOption { + default = []; + description = '' + List of network interfaces where listening for connections. + When providing the empty list, `[]', lshd listens on all + network interfaces. + ''; + example = [ "localhost" "1.2.3.4:443" ]; + }; + + hostKey = mkOption { + default = "/etc/lsh/host-key"; + description = '' + Path to the server's private key. Note that this key must + have been created, e.g., using "lsh-keygen --server | + lsh-writekey --server", so that you can run lshd. + ''; + }; + + syslog = mkOption { + default = true; + description = ''Whether to enable syslog output.''; + }; + + passwordAuthentication = mkOption { + default = true; + description = ''Whether to enable password authentication.''; + }; + + publicKeyAuthentication = mkOption { + default = true; + description = ''Whether to enable public key authentication.''; + }; + + rootLogin = mkOption { + default = false; + description = ''Whether to enable remote root login.''; + }; + + loginShell = mkOption { + default = null; + description = '' + If non-null, override the default login shell with the + specified value. + ''; + example = "/nix/store/xyz-bash-10.0/bin/bash10"; + }; + + srpKeyExchange = mkOption { + default = false; + description = '' + Whether to enable SRP key exchange and user authentication. + ''; + }; + + tcpForwarding = mkOption { + default = true; + description = ''Whether to enable TCP/IP forwarding.''; + }; + + x11Forwarding = mkOption { + default = true; + description = ''Whether to enable X11 forwarding.''; + }; + + subsystems = mkOption { + description = '' + List of subsystem-path pairs, where the head of the pair + denotes the subsystem name, and the tail denotes the path to + an executable implementing it. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; + + systemd.services.lshd = { + description = "GNU lshd SSH2 daemon"; + + after = [ "network-interfaces.target" ]; + + wantedBy = [ "multi-user.target" ]; + + environment = { + LD_LIBRARY_PATH = config.system.nssModules.path; + }; + + preStart = '' + test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh + test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh + + if ! test -f /var/spool/lsh/yarrow-seed-file + then + # XXX: It would be nice to provide feedback to the + # user when this fails, so that they can retry it + # manually. + ${lsh}/bin/lsh-make-seed --sloppy \ + -o /var/spool/lsh/yarrow-seed-file + fi + + if ! test -f "${cfg.hostKey}" + then + ${lsh}/bin/lsh-keygen --server | \ + ${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}" + fi + ''; + + script = with cfg; '' + ${lsh}/sbin/lshd --daemonic \ + --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ + -p ${toString portNumber} \ + ${if interfaces == [] then "" + else (concatStrings (map (i: "--interface=\"${i}\"") + interfaces))} \ + -h "${hostKey}" \ + ${if !syslog then "--no-syslog" else ""} \ + ${if passwordAuthentication then "--password" else "--no-password" } \ + ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \ + ${if rootLogin then "--root-login" else "--no-root-login" } \ + ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \ + ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \ + ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \ + ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \ + --subsystems=${concatStringsSep "," + (map (pair: (head pair) + "=" + + (head (tail pair))) + subsystems)} + ''; + }; + + security.pam.services.lshd = {}; + }; +} diff --git a/pkgs/build-support/cc-wrapper/add-flags b/pkgs/build-support/cc-wrapper/add-flags.sh similarity index 100% rename from pkgs/build-support/cc-wrapper/add-flags rename to pkgs/build-support/cc-wrapper/add-flags.sh diff --git a/pkgs/build-support/cc-wrapper/add-hardening b/pkgs/build-support/cc-wrapper/add-hardening.sh similarity index 90% rename from pkgs/build-support/cc-wrapper/add-hardening rename to pkgs/build-support/cc-wrapper/add-hardening.sh index d5966136b9d5..60e62ffad608 100644 --- a/pkgs/build-support/cc-wrapper/add-hardening +++ b/pkgs/build-support/cc-wrapper/add-hardening.sh @@ -4,8 +4,12 @@ hardeningCFlags=() hardeningLDFlags=() hardeningDisable=${hardeningDisable:-""} -if [[ "$($LD -z 2>&1)" =~ "unknown option" ]]; then - hardeningDisable+=" bindnow relro" +if [[ -z "@ld_supports_bindnow@" ]]; then + hardeningDisable+=" bindnow" +fi + +if [[ -z "@ld_supports_relro@" ]]; then + hardeningDisable+=" relro" fi if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: Value of '$hardeningDisable': $hardeningDisable >&2; fi @@ -46,11 +50,11 @@ if [[ ! $hardeningDisable == "all" ]]; then ;; relro) if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling relro >&2; fi - hardeningLDFlags+=('-z relro') + hardeningLDFlags+=('-z' 'relro') ;; bindnow) if [[ -n "$NIX_DEBUG" ]]; then echo HARDENING: enabling bindnow >&2; fi - hardeningLDFlags+=('-z now') + hardeningLDFlags+=('-z' 'now') ;; *) echo "Hardening flag unknown: $flag" >&2 diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 14ece26f6af0..08ca8195b68b 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -237,8 +237,12 @@ stdenv.mkDerivation { cat $out/nix-support/setup-hook.tmp >> $out/nix-support/setup-hook rm $out/nix-support/setup-hook.tmp - substituteAll ${./add-flags} $out/nix-support/add-flags.sh - cp -p ${./add-hardening} $out/nix-support/add-hardening.sh + # some linkers on some platforms don't support -z + export ld_supports_bindnow=$([[ "$($ldPath/ld -z now 2>&1 || true)" =~ "un(known|recognized) option" ]]) + export ld_supports_relro=$([[ "$($ldPath/ld -z relro 2>&1 || true)" =~ "un(known|recognized) option" ]]) + + substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh + substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh cp -p ${./utils.sh} $out/nix-support/utils.sh '' + extraBuildCommands; diff --git a/pkgs/development/compilers/ccl/default.nix b/pkgs/development/compilers/ccl/default.nix index ee0153c13b0f..3e1784424e3c 100644 --- a/pkgs/development/compilers/ccl/default.nix +++ b/pkgs/development/compilers/ccl/default.nix @@ -5,7 +5,7 @@ let /* TODO: there are also MacOS, FreeBSD and Windows versions */ x86_64-linux = { arch = "linuxx86"; - sha256 = "07cny2qkzc624bzpdsy4iakcln0p7v5rhf8bv0vnh6rhpvnahrnq"; + sha256 = "0g6mkl207ri3ib9w85i9w0sv7srz784pbxidz0d95p6qkvg6shba"; runtime = "lx86cl64"; kernel = "linuxx8664"; }; diff --git a/pkgs/development/libraries/czmq/default.nix b/pkgs/development/libraries/czmq/default.nix index 69b64629bd83..3feac77896a4 100644 --- a/pkgs/development/libraries/czmq/default.nix +++ b/pkgs/development/libraries/czmq/default.nix @@ -15,6 +15,8 @@ stdenv.mkDerivation rec { # Needs to be propagated for the .pc file to work propagatedBuildInputs = [ zeromq ]; + NIX_CFLAGS_COMPILE = "-Wno-error=deprecated-declarations"; + meta = with stdenv.lib; { homepage = "http://czmq.zeromq.org/"; description = "High-level C Binding for ZeroMQ"; diff --git a/pkgs/tools/networking/lsh/default.nix b/pkgs/tools/networking/lsh/default.nix new file mode 100644 index 000000000000..5d788af1682e --- /dev/null +++ b/pkgs/tools/networking/lsh/default.nix @@ -0,0 +1,51 @@ +{ stdenv, fetchurl, gperf, guile, gmp, zlib, liboop, readline, gnum4, pam +, nettools, lsof, procps }: + +stdenv.mkDerivation rec { + name = "lsh-2.0.4"; + src = fetchurl { + url = "mirror://gnu/lsh/${name}.tar.gz"; + sha256 = "614b9d63e13ad3e162c82b6405d1f67713fc622a8bc11337e72949d613713091"; + }; + + patches = [ ./pam-service-name.patch ./lshd-no-root-login.patch ]; + + preConfigure = '' + # Patch `lsh-make-seed' so that it can gather enough entropy. + sed -i "src/lsh-make-seed.c" \ + -e "s|/usr/sbin/arp|${nettools}/sbin/arp|g ; + s|/usr/bin/netstat|${nettools}/bin/netstat|g ; + s|/usr/local/bin/lsof|${lsof}/bin/lsof|g ; + s|/bin/vmstat|${procps}/bin/vmstat|g ; + s|/bin/ps|${procps}/bin/sp|g ; + s|/usr/bin/w|${procps}/bin/w|g ; + s|/usr/bin/df|$(type -P df)|g ; + s|/usr/bin/ipcs|$(type -P ipcs)|g ; + s|/usr/bin/uptime|$(type -P uptime)|g" + + # Skip the `configure' script that checks whether /dev/ptmx & co. work as + # expected, because it relies on impurities (for instance, /dev/pts may + # be unavailable in chroots.) + export lsh_cv_sys_unix98_ptys=yes + ''; + + NIX_CFLAGS_COMPILE = "-std=gnu90"; + + buildInputs = [ gperf guile gmp zlib liboop readline gnum4 pam ]; + + meta = { + description = "GPL'd implementation of the SSH protocol"; + + longDescription = '' + lsh is a free implementation (in the GNU sense) of the ssh + version 2 protocol, currently being standardised by the IETF + SECSH working group. + ''; + + homepage = http://www.lysator.liu.se/~nisse/lsh/; + license = stdenv.lib.licenses.gpl2Plus; + + maintainers = [ ]; + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/pkgs/tools/networking/lsh/lshd-no-root-login.patch b/pkgs/tools/networking/lsh/lshd-no-root-login.patch new file mode 100644 index 000000000000..9dd81de3fbc1 --- /dev/null +++ b/pkgs/tools/networking/lsh/lshd-no-root-login.patch @@ -0,0 +1,16 @@ +Correctly handle the `--no-root-login' option. + +--- lsh-2.0.4/src/lshd.c 2006-05-01 13:47:44.000000000 +0200 ++++ lsh-2.0.4/src/lshd.c 2009-09-08 12:20:36.000000000 +0200 +@@ -758,6 +758,10 @@ main_argp_parser(int key, char *arg, str + self->allow_root = 1; + break; + ++ case OPT_NO_ROOT_LOGIN: ++ self->allow_root = 0; ++ break; ++ + case OPT_KERBEROS_PASSWD: + self->pw_helper = PATH_KERBEROS_HELPER; + break; + diff --git a/pkgs/tools/networking/lsh/pam-service-name.patch b/pkgs/tools/networking/lsh/pam-service-name.patch new file mode 100644 index 000000000000..6a6156855c51 --- /dev/null +++ b/pkgs/tools/networking/lsh/pam-service-name.patch @@ -0,0 +1,14 @@ +Tell `lsh-pam-checkpw', the PAM password helper program, to use a more +descriptive service name. + +--- lsh-2.0.4/src/lsh-pam-checkpw.c 2003-02-16 22:30:10.000000000 +0100 ++++ lsh-2.0.4/src/lsh-pam-checkpw.c 2008-11-28 16:16:58.000000000 +0100 +@@ -38,7 +38,7 @@ + #include + + #define PWD_MAXLEN 1024 +-#define SERVICE_NAME "other" ++#define SERVICE_NAME "lshd" + #define TIMEOUT 600 + + static int diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index cb52a44e5dbf..ab97dea8f3f5 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2456,6 +2456,10 @@ in lsb-release = callPackage ../os-specific/linux/lsb-release { }; + # lsh installs `bin/nettle-lfib-stream' and so does Nettle. Give the + # former a lower priority than Nettle. + lsh = lowPrio (callPackage ../tools/networking/lsh { }); + lshw = callPackage ../tools/system/lshw { }; lxc = callPackage ../os-specific/linux/lxc { }; diff --git a/pkgs/top-level/guile-2-test.nix b/pkgs/top-level/guile-2-test.nix index 70ec6c0dc0ce..9d2fbcbef5cc 100644 --- a/pkgs/top-level/guile-2-test.nix +++ b/pkgs/top-level/guile-2-test.nix @@ -56,6 +56,7 @@ in (mapTestOn { guile = linux; autogen = linux; + lsh = linux; mailutils = linux; mcron = linux; texmacs = linux; diff --git a/pkgs/top-level/release-small.nix b/pkgs/top-level/release-small.nix index 77efcc2e0211..2774ff66f576 100644 --- a/pkgs/top-level/release-small.nix +++ b/pkgs/top-level/release-small.nix @@ -88,6 +88,7 @@ with import ./release-lib.nix { inherit supportedSystems; }; libxml2 = all; libxslt = all; lout = linux; + lsh = linux; lsof = linux; ltrace = linux; lvm2 = linux;